authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-03-12 17:32:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-03-12 17:32:32-04:00
log62486c35a483d759b29fa5da235da66590bde6d7
tree9325e41870f70db4d044345eaafd565a800adaf9
parent5734b7a37a75b927ca31e52ad915d7de125993d9
signaturelock-open Commit is signed but in an unrecognized format.

ability to build musl from source

bundles musl 1.1.21 See #514

1801 files changed, 75395 insertions(+), 289 deletions(-)

CMakeLists.txt+2082-279
......@@ -808,6 +808,1807 @@ set(ZIG_C_HEADER_FILES
808808 "xtestintrin.h"
809809)
810810
811set(ZIG_MUSL_SRC_FILES
812 "musl/src/aio/aio.c"
813 "musl/src/aio/aio_suspend.c"
814 "musl/src/aio/lio_listio.c"
815 "musl/src/complex/__cexp.c"
816 "musl/src/complex/__cexpf.c"
817 "musl/src/complex/cabs.c"
818 "musl/src/complex/cabsf.c"
819 "musl/src/complex/cabsl.c"
820 "musl/src/complex/cacos.c"
821 "musl/src/complex/cacosf.c"
822 "musl/src/complex/cacosh.c"
823 "musl/src/complex/cacoshf.c"
824 "musl/src/complex/cacoshl.c"
825 "musl/src/complex/cacosl.c"
826 "musl/src/complex/carg.c"
827 "musl/src/complex/cargf.c"
828 "musl/src/complex/cargl.c"
829 "musl/src/complex/casin.c"
830 "musl/src/complex/casinf.c"
831 "musl/src/complex/casinh.c"
832 "musl/src/complex/casinhf.c"
833 "musl/src/complex/casinhl.c"
834 "musl/src/complex/casinl.c"
835 "musl/src/complex/catan.c"
836 "musl/src/complex/catanf.c"
837 "musl/src/complex/catanh.c"
838 "musl/src/complex/catanhf.c"
839 "musl/src/complex/catanhl.c"
840 "musl/src/complex/catanl.c"
841 "musl/src/complex/ccos.c"
842 "musl/src/complex/ccosf.c"
843 "musl/src/complex/ccosh.c"
844 "musl/src/complex/ccoshf.c"
845 "musl/src/complex/ccoshl.c"
846 "musl/src/complex/ccosl.c"
847 "musl/src/complex/cexp.c"
848 "musl/src/complex/cexpf.c"
849 "musl/src/complex/cexpl.c"
850 "musl/src/complex/cimag.c"
851 "musl/src/complex/cimagf.c"
852 "musl/src/complex/cimagl.c"
853 "musl/src/complex/clog.c"
854 "musl/src/complex/clogf.c"
855 "musl/src/complex/clogl.c"
856 "musl/src/complex/conj.c"
857 "musl/src/complex/conjf.c"
858 "musl/src/complex/conjl.c"
859 "musl/src/complex/cpow.c"
860 "musl/src/complex/cpowf.c"
861 "musl/src/complex/cpowl.c"
862 "musl/src/complex/cproj.c"
863 "musl/src/complex/cprojf.c"
864 "musl/src/complex/cprojl.c"
865 "musl/src/complex/creal.c"
866 "musl/src/complex/crealf.c"
867 "musl/src/complex/creall.c"
868 "musl/src/complex/csin.c"
869 "musl/src/complex/csinf.c"
870 "musl/src/complex/csinh.c"
871 "musl/src/complex/csinhf.c"
872 "musl/src/complex/csinhl.c"
873 "musl/src/complex/csinl.c"
874 "musl/src/complex/csqrt.c"
875 "musl/src/complex/csqrtf.c"
876 "musl/src/complex/csqrtl.c"
877 "musl/src/complex/ctan.c"
878 "musl/src/complex/ctanf.c"
879 "musl/src/complex/ctanh.c"
880 "musl/src/complex/ctanhf.c"
881 "musl/src/complex/ctanhl.c"
882 "musl/src/complex/ctanl.c"
883 "musl/src/conf/confstr.c"
884 "musl/src/conf/fpathconf.c"
885 "musl/src/conf/legacy.c"
886 "musl/src/conf/pathconf.c"
887 "musl/src/conf/sysconf.c"
888 "musl/src/crypt/crypt.c"
889 "musl/src/crypt/crypt_blowfish.c"
890 "musl/src/crypt/crypt_des.c"
891 "musl/src/crypt/crypt_des.h"
892 "musl/src/crypt/crypt_md5.c"
893 "musl/src/crypt/crypt_r.c"
894 "musl/src/crypt/crypt_sha256.c"
895 "musl/src/crypt/crypt_sha512.c"
896 "musl/src/crypt/encrypt.c"
897 "musl/src/ctype/__ctype_b_loc.c"
898 "musl/src/ctype/__ctype_get_mb_cur_max.c"
899 "musl/src/ctype/__ctype_tolower_loc.c"
900 "musl/src/ctype/__ctype_toupper_loc.c"
901 "musl/src/ctype/alpha.h"
902 "musl/src/ctype/isalnum.c"
903 "musl/src/ctype/isalpha.c"
904 "musl/src/ctype/isascii.c"
905 "musl/src/ctype/isblank.c"
906 "musl/src/ctype/iscntrl.c"
907 "musl/src/ctype/isdigit.c"
908 "musl/src/ctype/isgraph.c"
909 "musl/src/ctype/islower.c"
910 "musl/src/ctype/isprint.c"
911 "musl/src/ctype/ispunct.c"
912 "musl/src/ctype/isspace.c"
913 "musl/src/ctype/isupper.c"
914 "musl/src/ctype/iswalnum.c"
915 "musl/src/ctype/iswalpha.c"
916 "musl/src/ctype/iswblank.c"
917 "musl/src/ctype/iswcntrl.c"
918 "musl/src/ctype/iswctype.c"
919 "musl/src/ctype/iswdigit.c"
920 "musl/src/ctype/iswgraph.c"
921 "musl/src/ctype/iswlower.c"
922 "musl/src/ctype/iswprint.c"
923 "musl/src/ctype/iswpunct.c"
924 "musl/src/ctype/iswspace.c"
925 "musl/src/ctype/iswupper.c"
926 "musl/src/ctype/iswxdigit.c"
927 "musl/src/ctype/isxdigit.c"
928 "musl/src/ctype/nonspacing.h"
929 "musl/src/ctype/punct.h"
930 "musl/src/ctype/toascii.c"
931 "musl/src/ctype/tolower.c"
932 "musl/src/ctype/toupper.c"
933 "musl/src/ctype/towctrans.c"
934 "musl/src/ctype/wcswidth.c"
935 "musl/src/ctype/wctrans.c"
936 "musl/src/ctype/wcwidth.c"
937 "musl/src/ctype/wide.h"
938 "musl/src/dirent/__dirent.h"
939 "musl/src/dirent/alphasort.c"
940 "musl/src/dirent/closedir.c"
941 "musl/src/dirent/dirfd.c"
942 "musl/src/dirent/fdopendir.c"
943 "musl/src/dirent/opendir.c"
944 "musl/src/dirent/readdir.c"
945 "musl/src/dirent/readdir_r.c"
946 "musl/src/dirent/rewinddir.c"
947 "musl/src/dirent/scandir.c"
948 "musl/src/dirent/seekdir.c"
949 "musl/src/dirent/telldir.c"
950 "musl/src/dirent/versionsort.c"
951 "musl/src/env/__environ.c"
952 "musl/src/env/__init_tls.c"
953 "musl/src/env/__libc_start_main.c"
954 "musl/src/env/__reset_tls.c"
955 "musl/src/env/__stack_chk_fail.c"
956 "musl/src/env/clearenv.c"
957 "musl/src/env/getenv.c"
958 "musl/src/env/putenv.c"
959 "musl/src/env/setenv.c"
960 "musl/src/env/unsetenv.c"
961 "musl/src/errno/__errno_location.c"
962 "musl/src/errno/__strerror.h"
963 "musl/src/errno/strerror.c"
964 "musl/src/exit/_Exit.c"
965 "musl/src/exit/abort.c"
966 "musl/src/exit/arm/__aeabi_atexit.c"
967 "musl/src/exit/assert.c"
968 "musl/src/exit/at_quick_exit.c"
969 "musl/src/exit/atexit.c"
970 "musl/src/exit/exit.c"
971 "musl/src/exit/quick_exit.c"
972 "musl/src/fcntl/creat.c"
973 "musl/src/fcntl/fcntl.c"
974 "musl/src/fcntl/open.c"
975 "musl/src/fcntl/openat.c"
976 "musl/src/fcntl/posix_fadvise.c"
977 "musl/src/fcntl/posix_fallocate.c"
978 "musl/src/fenv/__flt_rounds.c"
979 "musl/src/fenv/aarch64/fenv.s"
980 "musl/src/fenv/arm/fenv-hf.S"
981 "musl/src/fenv/arm/fenv.c"
982 "musl/src/fenv/fegetexceptflag.c"
983 "musl/src/fenv/feholdexcept.c"
984 "musl/src/fenv/fenv.c"
985 "musl/src/fenv/fesetexceptflag.c"
986 "musl/src/fenv/fesetround.c"
987 "musl/src/fenv/feupdateenv.c"
988 "musl/src/fenv/i386/fenv.s"
989 "musl/src/fenv/m68k/fenv.c"
990 "musl/src/fenv/mips/fenv-sf.c"
991 "musl/src/fenv/mips/fenv.S"
992 "musl/src/fenv/mips64/fenv-sf.c"
993 "musl/src/fenv/mips64/fenv.S"
994 "musl/src/fenv/mipsn32/fenv-sf.c"
995 "musl/src/fenv/mipsn32/fenv.S"
996 "musl/src/fenv/powerpc/fenv-sf.c"
997 "musl/src/fenv/powerpc/fenv.S"
998 "musl/src/fenv/powerpc64/fenv.c"
999 "musl/src/fenv/s390x/fenv.c"
1000 "musl/src/fenv/sh/fenv-nofpu.c"
1001 "musl/src/fenv/sh/fenv.S"
1002 "musl/src/fenv/x32/fenv.s"
1003 "musl/src/fenv/x86_64/fenv.s"
1004 "musl/src/include/arpa/inet.h"
1005 "musl/src/include/crypt.h"
1006 "musl/src/include/errno.h"
1007 "musl/src/include/features.h"
1008 "musl/src/include/langinfo.h"
1009 "musl/src/include/pthread.h"
1010 "musl/src/include/resolv.h"
1011 "musl/src/include/signal.h"
1012 "musl/src/include/stdio.h"
1013 "musl/src/include/stdlib.h"
1014 "musl/src/include/string.h"
1015 "musl/src/include/sys/auxv.h"
1016 "musl/src/include/sys/mman.h"
1017 "musl/src/include/sys/sysinfo.h"
1018 "musl/src/include/sys/time.h"
1019 "musl/src/include/time.h"
1020 "musl/src/include/unistd.h"
1021 "musl/src/internal/aarch64/syscall.s"
1022 "musl/src/internal/arm/syscall.s"
1023 "musl/src/internal/atomic.h"
1024 "musl/src/internal/dynlink.h"
1025 "musl/src/internal/fdpic_crt.h"
1026 "musl/src/internal/floatscan.c"
1027 "musl/src/internal/floatscan.h"
1028 "musl/src/internal/futex.h"
1029 "musl/src/internal/i386/syscall.s"
1030 "musl/src/internal/intscan.c"
1031 "musl/src/internal/intscan.h"
1032 "musl/src/internal/ksigaction.h"
1033 "musl/src/internal/libc.c"
1034 "musl/src/internal/libc.h"
1035 "musl/src/internal/libm.h"
1036 "musl/src/internal/locale_impl.h"
1037 "musl/src/internal/lock.h"
1038 "musl/src/internal/m68k/syscall.s"
1039 "musl/src/internal/malloc_impl.h"
1040 "musl/src/internal/microblaze/syscall.s"
1041 "musl/src/internal/mips/syscall.s"
1042 "musl/src/internal/mips64/syscall.s"
1043 "musl/src/internal/mipsn32/syscall.s"
1044 "musl/src/internal/or1k/syscall.s"
1045 "musl/src/internal/powerpc/syscall.s"
1046 "musl/src/internal/powerpc64/syscall.s"
1047 "musl/src/internal/procfdname.c"
1048 "musl/src/internal/pthread_impl.h"
1049 "musl/src/internal/s390x/syscall.s"
1050 "musl/src/internal/sh/__shcall.c"
1051 "musl/src/internal/sh/syscall.s"
1052 "musl/src/internal/shgetc.c"
1053 "musl/src/internal/shgetc.h"
1054 "musl/src/internal/stdio_impl.h"
1055 "musl/src/internal/syscall.c"
1056 "musl/src/internal/syscall.h"
1057 "musl/src/internal/syscall_ret.c"
1058 "musl/src/internal/vdso.c"
1059 "musl/src/internal/version.c"
1060 "musl/src/internal/version.h"
1061 "musl/src/internal/x32/syscall.s"
1062 "musl/src/internal/x86_64/syscall.s"
1063 "musl/src/ipc/ftok.c"
1064 "musl/src/ipc/ipc.h"
1065 "musl/src/ipc/msgctl.c"
1066 "musl/src/ipc/msgget.c"
1067 "musl/src/ipc/msgrcv.c"
1068 "musl/src/ipc/msgsnd.c"
1069 "musl/src/ipc/semctl.c"
1070 "musl/src/ipc/semget.c"
1071 "musl/src/ipc/semop.c"
1072 "musl/src/ipc/semtimedop.c"
1073 "musl/src/ipc/shmat.c"
1074 "musl/src/ipc/shmctl.c"
1075 "musl/src/ipc/shmdt.c"
1076 "musl/src/ipc/shmget.c"
1077 "musl/src/ldso/__dlsym.c"
1078 "musl/src/ldso/aarch64/dlsym.s"
1079 "musl/src/ldso/aarch64/tlsdesc.s"
1080 "musl/src/ldso/arm/dlsym.s"
1081 "musl/src/ldso/arm/find_exidx.c"
1082 "musl/src/ldso/arm/tlsdesc.S"
1083 "musl/src/ldso/dl_iterate_phdr.c"
1084 "musl/src/ldso/dladdr.c"
1085 "musl/src/ldso/dlclose.c"
1086 "musl/src/ldso/dlerror.c"
1087 "musl/src/ldso/dlinfo.c"
1088 "musl/src/ldso/dlopen.c"
1089 "musl/src/ldso/dlsym.c"
1090 "musl/src/ldso/i386/dlsym.s"
1091 "musl/src/ldso/i386/tlsdesc.s"
1092 "musl/src/ldso/m68k/dlsym.s"
1093 "musl/src/ldso/microblaze/dlsym.s"
1094 "musl/src/ldso/mips/dlsym.s"
1095 "musl/src/ldso/mips64/dlsym.s"
1096 "musl/src/ldso/mipsn32/dlsym.s"
1097 "musl/src/ldso/or1k/dlsym.s"
1098 "musl/src/ldso/powerpc/dlsym.s"
1099 "musl/src/ldso/powerpc64/dlsym.s"
1100 "musl/src/ldso/s390x/dlsym.s"
1101 "musl/src/ldso/sh/dlsym.s"
1102 "musl/src/ldso/tlsdesc.c"
1103 "musl/src/ldso/x32/dlsym.s"
1104 "musl/src/ldso/x86_64/dlsym.s"
1105 "musl/src/ldso/x86_64/tlsdesc.s"
1106 "musl/src/legacy/cuserid.c"
1107 "musl/src/legacy/daemon.c"
1108 "musl/src/legacy/err.c"
1109 "musl/src/legacy/euidaccess.c"
1110 "musl/src/legacy/ftw.c"
1111 "musl/src/legacy/futimes.c"
1112 "musl/src/legacy/getdtablesize.c"
1113 "musl/src/legacy/getloadavg.c"
1114 "musl/src/legacy/getpagesize.c"
1115 "musl/src/legacy/getpass.c"
1116 "musl/src/legacy/getusershell.c"
1117 "musl/src/legacy/isastream.c"
1118 "musl/src/legacy/lutimes.c"
1119 "musl/src/legacy/ulimit.c"
1120 "musl/src/legacy/utmpx.c"
1121 "musl/src/legacy/valloc.c"
1122 "musl/src/linux/adjtime.c"
1123 "musl/src/linux/adjtimex.c"
1124 "musl/src/linux/arch_prctl.c"
1125 "musl/src/linux/brk.c"
1126 "musl/src/linux/cache.c"
1127 "musl/src/linux/cap.c"
1128 "musl/src/linux/chroot.c"
1129 "musl/src/linux/clock_adjtime.c"
1130 "musl/src/linux/clone.c"
1131 "musl/src/linux/epoll.c"
1132 "musl/src/linux/eventfd.c"
1133 "musl/src/linux/fallocate.c"
1134 "musl/src/linux/fanotify.c"
1135 "musl/src/linux/flock.c"
1136 "musl/src/linux/getdents.c"
1137 "musl/src/linux/getrandom.c"
1138 "musl/src/linux/inotify.c"
1139 "musl/src/linux/ioperm.c"
1140 "musl/src/linux/iopl.c"
1141 "musl/src/linux/klogctl.c"
1142 "musl/src/linux/memfd_create.c"
1143 "musl/src/linux/mlock2.c"
1144 "musl/src/linux/module.c"
1145 "musl/src/linux/mount.c"
1146 "musl/src/linux/name_to_handle_at.c"
1147 "musl/src/linux/open_by_handle_at.c"
1148 "musl/src/linux/personality.c"
1149 "musl/src/linux/pivot_root.c"
1150 "musl/src/linux/ppoll.c"
1151 "musl/src/linux/prctl.c"
1152 "musl/src/linux/prlimit.c"
1153 "musl/src/linux/process_vm.c"
1154 "musl/src/linux/ptrace.c"
1155 "musl/src/linux/quotactl.c"
1156 "musl/src/linux/readahead.c"
1157 "musl/src/linux/reboot.c"
1158 "musl/src/linux/remap_file_pages.c"
1159 "musl/src/linux/sbrk.c"
1160 "musl/src/linux/sendfile.c"
1161 "musl/src/linux/setfsgid.c"
1162 "musl/src/linux/setfsuid.c"
1163 "musl/src/linux/setgroups.c"
1164 "musl/src/linux/sethostname.c"
1165 "musl/src/linux/setns.c"
1166 "musl/src/linux/settimeofday.c"
1167 "musl/src/linux/signalfd.c"
1168 "musl/src/linux/splice.c"
1169 "musl/src/linux/stime.c"
1170 "musl/src/linux/swap.c"
1171 "musl/src/linux/sync_file_range.c"
1172 "musl/src/linux/syncfs.c"
1173 "musl/src/linux/sysinfo.c"
1174 "musl/src/linux/tee.c"
1175 "musl/src/linux/timerfd.c"
1176 "musl/src/linux/unshare.c"
1177 "musl/src/linux/utimes.c"
1178 "musl/src/linux/vhangup.c"
1179 "musl/src/linux/vmsplice.c"
1180 "musl/src/linux/wait3.c"
1181 "musl/src/linux/wait4.c"
1182 "musl/src/linux/x32/sysinfo.c"
1183 "musl/src/linux/xattr.c"
1184 "musl/src/locale/__lctrans.c"
1185 "musl/src/locale/__mo_lookup.c"
1186 "musl/src/locale/big5.h"
1187 "musl/src/locale/bind_textdomain_codeset.c"
1188 "musl/src/locale/c_locale.c"
1189 "musl/src/locale/catclose.c"
1190 "musl/src/locale/catgets.c"
1191 "musl/src/locale/catopen.c"
1192 "musl/src/locale/codepages.h"
1193 "musl/src/locale/dcngettext.c"
1194 "musl/src/locale/duplocale.c"
1195 "musl/src/locale/freelocale.c"
1196 "musl/src/locale/gb18030.h"
1197 "musl/src/locale/hkscs.h"
1198 "musl/src/locale/iconv.c"
1199 "musl/src/locale/iconv_close.c"
1200 "musl/src/locale/jis0208.h"
1201 "musl/src/locale/ksc.h"
1202 "musl/src/locale/langinfo.c"
1203 "musl/src/locale/legacychars.h"
1204 "musl/src/locale/locale_map.c"
1205 "musl/src/locale/localeconv.c"
1206 "musl/src/locale/newlocale.c"
1207 "musl/src/locale/pleval.c"
1208 "musl/src/locale/pleval.h"
1209 "musl/src/locale/revjis.h"
1210 "musl/src/locale/setlocale.c"
1211 "musl/src/locale/strcoll.c"
1212 "musl/src/locale/strfmon.c"
1213 "musl/src/locale/strxfrm.c"
1214 "musl/src/locale/textdomain.c"
1215 "musl/src/locale/uselocale.c"
1216 "musl/src/locale/wcscoll.c"
1217 "musl/src/locale/wcsxfrm.c"
1218 "musl/src/malloc/DESIGN"
1219 "musl/src/malloc/aligned_alloc.c"
1220 "musl/src/malloc/expand_heap.c"
1221 "musl/src/malloc/lite_malloc.c"
1222 "musl/src/malloc/malloc.c"
1223 "musl/src/malloc/malloc_usable_size.c"
1224 "musl/src/malloc/memalign.c"
1225 "musl/src/malloc/posix_memalign.c"
1226 "musl/src/math/__cos.c"
1227 "musl/src/math/__cosdf.c"
1228 "musl/src/math/__cosl.c"
1229 "musl/src/math/__expo2.c"
1230 "musl/src/math/__expo2f.c"
1231 "musl/src/math/__fpclassify.c"
1232 "musl/src/math/__fpclassifyf.c"
1233 "musl/src/math/__fpclassifyl.c"
1234 "musl/src/math/__invtrigl.c"
1235 "musl/src/math/__invtrigl.h"
1236 "musl/src/math/__polevll.c"
1237 "musl/src/math/__rem_pio2.c"
1238 "musl/src/math/__rem_pio2_large.c"
1239 "musl/src/math/__rem_pio2f.c"
1240 "musl/src/math/__rem_pio2l.c"
1241 "musl/src/math/__signbit.c"
1242 "musl/src/math/__signbitf.c"
1243 "musl/src/math/__signbitl.c"
1244 "musl/src/math/__sin.c"
1245 "musl/src/math/__sindf.c"
1246 "musl/src/math/__sinl.c"
1247 "musl/src/math/__tan.c"
1248 "musl/src/math/__tandf.c"
1249 "musl/src/math/__tanl.c"
1250 "musl/src/math/aarch64/ceil.c"
1251 "musl/src/math/aarch64/ceilf.c"
1252 "musl/src/math/aarch64/fabs.c"
1253 "musl/src/math/aarch64/fabsf.c"
1254 "musl/src/math/aarch64/floor.c"
1255 "musl/src/math/aarch64/floorf.c"
1256 "musl/src/math/aarch64/fma.c"
1257 "musl/src/math/aarch64/fmaf.c"
1258 "musl/src/math/aarch64/fmax.c"
1259 "musl/src/math/aarch64/fmaxf.c"
1260 "musl/src/math/aarch64/fmin.c"
1261 "musl/src/math/aarch64/fminf.c"
1262 "musl/src/math/aarch64/llrint.c"
1263 "musl/src/math/aarch64/llrintf.c"
1264 "musl/src/math/aarch64/llround.c"
1265 "musl/src/math/aarch64/llroundf.c"
1266 "musl/src/math/aarch64/lrint.c"
1267 "musl/src/math/aarch64/lrintf.c"
1268 "musl/src/math/aarch64/lround.c"
1269 "musl/src/math/aarch64/lroundf.c"
1270 "musl/src/math/aarch64/nearbyint.c"
1271 "musl/src/math/aarch64/nearbyintf.c"
1272 "musl/src/math/aarch64/rint.c"
1273 "musl/src/math/aarch64/rintf.c"
1274 "musl/src/math/aarch64/round.c"
1275 "musl/src/math/aarch64/roundf.c"
1276 "musl/src/math/aarch64/sqrt.c"
1277 "musl/src/math/aarch64/sqrtf.c"
1278 "musl/src/math/aarch64/trunc.c"
1279 "musl/src/math/aarch64/truncf.c"
1280 "musl/src/math/acos.c"
1281 "musl/src/math/acosf.c"
1282 "musl/src/math/acosh.c"
1283 "musl/src/math/acoshf.c"
1284 "musl/src/math/acoshl.c"
1285 "musl/src/math/acosl.c"
1286 "musl/src/math/arm/fabs.c"
1287 "musl/src/math/arm/fabsf.c"
1288 "musl/src/math/arm/fma.c"
1289 "musl/src/math/arm/fmaf.c"
1290 "musl/src/math/arm/sqrt.c"
1291 "musl/src/math/arm/sqrtf.c"
1292 "musl/src/math/asin.c"
1293 "musl/src/math/asinf.c"
1294 "musl/src/math/asinh.c"
1295 "musl/src/math/asinhf.c"
1296 "musl/src/math/asinhl.c"
1297 "musl/src/math/asinl.c"
1298 "musl/src/math/atan.c"
1299 "musl/src/math/atan2.c"
1300 "musl/src/math/atan2f.c"
1301 "musl/src/math/atan2l.c"
1302 "musl/src/math/atanf.c"
1303 "musl/src/math/atanh.c"
1304 "musl/src/math/atanhf.c"
1305 "musl/src/math/atanhl.c"
1306 "musl/src/math/atanl.c"
1307 "musl/src/math/cbrt.c"
1308 "musl/src/math/cbrtf.c"
1309 "musl/src/math/cbrtl.c"
1310 "musl/src/math/ceil.c"
1311 "musl/src/math/ceilf.c"
1312 "musl/src/math/ceill.c"
1313 "musl/src/math/copysign.c"
1314 "musl/src/math/copysignf.c"
1315 "musl/src/math/copysignl.c"
1316 "musl/src/math/cos.c"
1317 "musl/src/math/cosf.c"
1318 "musl/src/math/cosh.c"
1319 "musl/src/math/coshf.c"
1320 "musl/src/math/coshl.c"
1321 "musl/src/math/cosl.c"
1322 "musl/src/math/erf.c"
1323 "musl/src/math/erff.c"
1324 "musl/src/math/erfl.c"
1325 "musl/src/math/exp.c"
1326 "musl/src/math/exp10.c"
1327 "musl/src/math/exp10f.c"
1328 "musl/src/math/exp10l.c"
1329 "musl/src/math/exp2.c"
1330 "musl/src/math/exp2f.c"
1331 "musl/src/math/exp2l.c"
1332 "musl/src/math/expf.c"
1333 "musl/src/math/expl.c"
1334 "musl/src/math/expm1.c"
1335 "musl/src/math/expm1f.c"
1336 "musl/src/math/expm1l.c"
1337 "musl/src/math/fabs.c"
1338 "musl/src/math/fabsf.c"
1339 "musl/src/math/fabsl.c"
1340 "musl/src/math/fdim.c"
1341 "musl/src/math/fdimf.c"
1342 "musl/src/math/fdiml.c"
1343 "musl/src/math/finite.c"
1344 "musl/src/math/finitef.c"
1345 "musl/src/math/floor.c"
1346 "musl/src/math/floorf.c"
1347 "musl/src/math/floorl.c"
1348 "musl/src/math/fma.c"
1349 "musl/src/math/fmaf.c"
1350 "musl/src/math/fmal.c"
1351 "musl/src/math/fmax.c"
1352 "musl/src/math/fmaxf.c"
1353 "musl/src/math/fmaxl.c"
1354 "musl/src/math/fmin.c"
1355 "musl/src/math/fminf.c"
1356 "musl/src/math/fminl.c"
1357 "musl/src/math/fmod.c"
1358 "musl/src/math/fmodf.c"
1359 "musl/src/math/fmodl.c"
1360 "musl/src/math/frexp.c"
1361 "musl/src/math/frexpf.c"
1362 "musl/src/math/frexpl.c"
1363 "musl/src/math/hypot.c"
1364 "musl/src/math/hypotf.c"
1365 "musl/src/math/hypotl.c"
1366 "musl/src/math/i386/__invtrigl.s"
1367 "musl/src/math/i386/acos.s"
1368 "musl/src/math/i386/acosf.s"
1369 "musl/src/math/i386/acosl.s"
1370 "musl/src/math/i386/asin.s"
1371 "musl/src/math/i386/asinf.s"
1372 "musl/src/math/i386/asinl.s"
1373 "musl/src/math/i386/atan.s"
1374 "musl/src/math/i386/atan2.s"
1375 "musl/src/math/i386/atan2f.s"
1376 "musl/src/math/i386/atan2l.s"
1377 "musl/src/math/i386/atanf.s"
1378 "musl/src/math/i386/atanl.s"
1379 "musl/src/math/i386/ceil.s"
1380 "musl/src/math/i386/ceilf.s"
1381 "musl/src/math/i386/ceill.s"
1382 "musl/src/math/i386/exp.s"
1383 "musl/src/math/i386/exp2.s"
1384 "musl/src/math/i386/exp2f.s"
1385 "musl/src/math/i386/exp2l.s"
1386 "musl/src/math/i386/expf.s"
1387 "musl/src/math/i386/expl.s"
1388 "musl/src/math/i386/expm1.s"
1389 "musl/src/math/i386/expm1f.s"
1390 "musl/src/math/i386/expm1l.s"
1391 "musl/src/math/i386/fabs.s"
1392 "musl/src/math/i386/fabsf.s"
1393 "musl/src/math/i386/fabsl.s"
1394 "musl/src/math/i386/floor.s"
1395 "musl/src/math/i386/floorf.s"
1396 "musl/src/math/i386/floorl.s"
1397 "musl/src/math/i386/fmod.s"
1398 "musl/src/math/i386/fmodf.s"
1399 "musl/src/math/i386/fmodl.s"
1400 "musl/src/math/i386/hypot.s"
1401 "musl/src/math/i386/hypotf.s"
1402 "musl/src/math/i386/ldexp.s"
1403 "musl/src/math/i386/ldexpf.s"
1404 "musl/src/math/i386/ldexpl.s"
1405 "musl/src/math/i386/llrint.s"
1406 "musl/src/math/i386/llrintf.s"
1407 "musl/src/math/i386/llrintl.s"
1408 "musl/src/math/i386/log.s"
1409 "musl/src/math/i386/log10.s"
1410 "musl/src/math/i386/log10f.s"
1411 "musl/src/math/i386/log10l.s"
1412 "musl/src/math/i386/log1p.s"
1413 "musl/src/math/i386/log1pf.s"
1414 "musl/src/math/i386/log1pl.s"
1415 "musl/src/math/i386/log2.s"
1416 "musl/src/math/i386/log2f.s"
1417 "musl/src/math/i386/log2l.s"
1418 "musl/src/math/i386/logf.s"
1419 "musl/src/math/i386/logl.s"
1420 "musl/src/math/i386/lrint.s"
1421 "musl/src/math/i386/lrintf.s"
1422 "musl/src/math/i386/lrintl.s"
1423 "musl/src/math/i386/remainder.s"
1424 "musl/src/math/i386/remainderf.s"
1425 "musl/src/math/i386/remainderl.s"
1426 "musl/src/math/i386/remquo.s"
1427 "musl/src/math/i386/remquof.s"
1428 "musl/src/math/i386/remquol.s"
1429 "musl/src/math/i386/rint.s"
1430 "musl/src/math/i386/rintf.s"
1431 "musl/src/math/i386/rintl.s"
1432 "musl/src/math/i386/scalbln.s"
1433 "musl/src/math/i386/scalblnf.s"
1434 "musl/src/math/i386/scalblnl.s"
1435 "musl/src/math/i386/scalbn.s"
1436 "musl/src/math/i386/scalbnf.s"
1437 "musl/src/math/i386/scalbnl.s"
1438 "musl/src/math/i386/sqrt.s"
1439 "musl/src/math/i386/sqrtf.s"
1440 "musl/src/math/i386/sqrtl.s"
1441 "musl/src/math/i386/trunc.s"
1442 "musl/src/math/i386/truncf.s"
1443 "musl/src/math/i386/truncl.s"
1444 "musl/src/math/ilogb.c"
1445 "musl/src/math/ilogbf.c"
1446 "musl/src/math/ilogbl.c"
1447 "musl/src/math/j0.c"
1448 "musl/src/math/j0f.c"
1449 "musl/src/math/j1.c"
1450 "musl/src/math/j1f.c"
1451 "musl/src/math/jn.c"
1452 "musl/src/math/jnf.c"
1453 "musl/src/math/ldexp.c"
1454 "musl/src/math/ldexpf.c"
1455 "musl/src/math/ldexpl.c"
1456 "musl/src/math/lgamma.c"
1457 "musl/src/math/lgamma_r.c"
1458 "musl/src/math/lgammaf.c"
1459 "musl/src/math/lgammaf_r.c"
1460 "musl/src/math/lgammal.c"
1461 "musl/src/math/llrint.c"
1462 "musl/src/math/llrintf.c"
1463 "musl/src/math/llrintl.c"
1464 "musl/src/math/llround.c"
1465 "musl/src/math/llroundf.c"
1466 "musl/src/math/llroundl.c"
1467 "musl/src/math/log.c"
1468 "musl/src/math/log10.c"
1469 "musl/src/math/log10f.c"
1470 "musl/src/math/log10l.c"
1471 "musl/src/math/log1p.c"
1472 "musl/src/math/log1pf.c"
1473 "musl/src/math/log1pl.c"
1474 "musl/src/math/log2.c"
1475 "musl/src/math/log2f.c"
1476 "musl/src/math/log2l.c"
1477 "musl/src/math/logb.c"
1478 "musl/src/math/logbf.c"
1479 "musl/src/math/logbl.c"
1480 "musl/src/math/logf.c"
1481 "musl/src/math/logl.c"
1482 "musl/src/math/lrint.c"
1483 "musl/src/math/lrintf.c"
1484 "musl/src/math/lrintl.c"
1485 "musl/src/math/lround.c"
1486 "musl/src/math/lroundf.c"
1487 "musl/src/math/lroundl.c"
1488 "musl/src/math/modf.c"
1489 "musl/src/math/modff.c"
1490 "musl/src/math/modfl.c"
1491 "musl/src/math/nan.c"
1492 "musl/src/math/nanf.c"
1493 "musl/src/math/nanl.c"
1494 "musl/src/math/nearbyint.c"
1495 "musl/src/math/nearbyintf.c"
1496 "musl/src/math/nearbyintl.c"
1497 "musl/src/math/nextafter.c"
1498 "musl/src/math/nextafterf.c"
1499 "musl/src/math/nextafterl.c"
1500 "musl/src/math/nexttoward.c"
1501 "musl/src/math/nexttowardf.c"
1502 "musl/src/math/nexttowardl.c"
1503 "musl/src/math/pow.c"
1504 "musl/src/math/powerpc/fabs.c"
1505 "musl/src/math/powerpc/fabsf.c"
1506 "musl/src/math/powerpc/fma.c"
1507 "musl/src/math/powerpc/fmaf.c"
1508 "musl/src/math/powerpc/sqrt.c"
1509 "musl/src/math/powerpc/sqrtf.c"
1510 "musl/src/math/powerpc64/ceil.c"
1511 "musl/src/math/powerpc64/ceilf.c"
1512 "musl/src/math/powerpc64/fabs.c"
1513 "musl/src/math/powerpc64/fabsf.c"
1514 "musl/src/math/powerpc64/floor.c"
1515 "musl/src/math/powerpc64/floorf.c"
1516 "musl/src/math/powerpc64/fma.c"
1517 "musl/src/math/powerpc64/fmaf.c"
1518 "musl/src/math/powerpc64/fmax.c"
1519 "musl/src/math/powerpc64/fmaxf.c"
1520 "musl/src/math/powerpc64/fmin.c"
1521 "musl/src/math/powerpc64/fminf.c"
1522 "musl/src/math/powerpc64/lrint.c"
1523 "musl/src/math/powerpc64/lrintf.c"
1524 "musl/src/math/powerpc64/lround.c"
1525 "musl/src/math/powerpc64/lroundf.c"
1526 "musl/src/math/powerpc64/round.c"
1527 "musl/src/math/powerpc64/roundf.c"
1528 "musl/src/math/powerpc64/sqrt.c"
1529 "musl/src/math/powerpc64/sqrtf.c"
1530 "musl/src/math/powerpc64/trunc.c"
1531 "musl/src/math/powerpc64/truncf.c"
1532 "musl/src/math/powf.c"
1533 "musl/src/math/powl.c"
1534 "musl/src/math/remainder.c"
1535 "musl/src/math/remainderf.c"
1536 "musl/src/math/remainderl.c"
1537 "musl/src/math/remquo.c"
1538 "musl/src/math/remquof.c"
1539 "musl/src/math/remquol.c"
1540 "musl/src/math/rint.c"
1541 "musl/src/math/rintf.c"
1542 "musl/src/math/rintl.c"
1543 "musl/src/math/round.c"
1544 "musl/src/math/roundf.c"
1545 "musl/src/math/roundl.c"
1546 "musl/src/math/s390x/ceil.c"
1547 "musl/src/math/s390x/ceilf.c"
1548 "musl/src/math/s390x/ceill.c"
1549 "musl/src/math/s390x/fabs.c"
1550 "musl/src/math/s390x/fabsf.c"
1551 "musl/src/math/s390x/fabsl.c"
1552 "musl/src/math/s390x/floor.c"
1553 "musl/src/math/s390x/floorf.c"
1554 "musl/src/math/s390x/floorl.c"
1555 "musl/src/math/s390x/fma.c"
1556 "musl/src/math/s390x/fmaf.c"
1557 "musl/src/math/s390x/nearbyint.c"
1558 "musl/src/math/s390x/nearbyintf.c"
1559 "musl/src/math/s390x/nearbyintl.c"
1560 "musl/src/math/s390x/rint.c"
1561 "musl/src/math/s390x/rintf.c"
1562 "musl/src/math/s390x/rintl.c"
1563 "musl/src/math/s390x/round.c"
1564 "musl/src/math/s390x/roundf.c"
1565 "musl/src/math/s390x/roundl.c"
1566 "musl/src/math/s390x/sqrt.c"
1567 "musl/src/math/s390x/sqrtf.c"
1568 "musl/src/math/s390x/sqrtl.c"
1569 "musl/src/math/s390x/trunc.c"
1570 "musl/src/math/s390x/truncf.c"
1571 "musl/src/math/s390x/truncl.c"
1572 "musl/src/math/scalb.c"
1573 "musl/src/math/scalbf.c"
1574 "musl/src/math/scalbln.c"
1575 "musl/src/math/scalblnf.c"
1576 "musl/src/math/scalblnl.c"
1577 "musl/src/math/scalbn.c"
1578 "musl/src/math/scalbnf.c"
1579 "musl/src/math/scalbnl.c"
1580 "musl/src/math/signgam.c"
1581 "musl/src/math/significand.c"
1582 "musl/src/math/significandf.c"
1583 "musl/src/math/sin.c"
1584 "musl/src/math/sincos.c"
1585 "musl/src/math/sincosf.c"
1586 "musl/src/math/sincosl.c"
1587 "musl/src/math/sinf.c"
1588 "musl/src/math/sinh.c"
1589 "musl/src/math/sinhf.c"
1590 "musl/src/math/sinhl.c"
1591 "musl/src/math/sinl.c"
1592 "musl/src/math/sqrt.c"
1593 "musl/src/math/sqrtf.c"
1594 "musl/src/math/sqrtl.c"
1595 "musl/src/math/tan.c"
1596 "musl/src/math/tanf.c"
1597 "musl/src/math/tanh.c"
1598 "musl/src/math/tanhf.c"
1599 "musl/src/math/tanhl.c"
1600 "musl/src/math/tanl.c"
1601 "musl/src/math/tgamma.c"
1602 "musl/src/math/tgammaf.c"
1603 "musl/src/math/tgammal.c"
1604 "musl/src/math/trunc.c"
1605 "musl/src/math/truncf.c"
1606 "musl/src/math/truncl.c"
1607 "musl/src/math/x32/__invtrigl.s"
1608 "musl/src/math/x32/acosl.s"
1609 "musl/src/math/x32/asinl.s"
1610 "musl/src/math/x32/atan2l.s"
1611 "musl/src/math/x32/atanl.s"
1612 "musl/src/math/x32/ceill.s"
1613 "musl/src/math/x32/exp2l.s"
1614 "musl/src/math/x32/expl.s"
1615 "musl/src/math/x32/expm1l.s"
1616 "musl/src/math/x32/fabs.s"
1617 "musl/src/math/x32/fabsf.s"
1618 "musl/src/math/x32/fabsl.s"
1619 "musl/src/math/x32/floorl.s"
1620 "musl/src/math/x32/fma.c"
1621 "musl/src/math/x32/fmaf.c"
1622 "musl/src/math/x32/fmodl.s"
1623 "musl/src/math/x32/llrint.s"
1624 "musl/src/math/x32/llrintf.s"
1625 "musl/src/math/x32/llrintl.s"
1626 "musl/src/math/x32/log10l.s"
1627 "musl/src/math/x32/log1pl.s"
1628 "musl/src/math/x32/log2l.s"
1629 "musl/src/math/x32/logl.s"
1630 "musl/src/math/x32/lrint.s"
1631 "musl/src/math/x32/lrintf.s"
1632 "musl/src/math/x32/lrintl.s"
1633 "musl/src/math/x32/remainderl.s"
1634 "musl/src/math/x32/rintl.s"
1635 "musl/src/math/x32/sqrt.s"
1636 "musl/src/math/x32/sqrtf.s"
1637 "musl/src/math/x32/sqrtl.s"
1638 "musl/src/math/x32/truncl.s"
1639 "musl/src/math/x86_64/__invtrigl.s"
1640 "musl/src/math/x86_64/acosl.s"
1641 "musl/src/math/x86_64/asinl.s"
1642 "musl/src/math/x86_64/atan2l.s"
1643 "musl/src/math/x86_64/atanl.s"
1644 "musl/src/math/x86_64/ceill.s"
1645 "musl/src/math/x86_64/exp2l.s"
1646 "musl/src/math/x86_64/expl.s"
1647 "musl/src/math/x86_64/expm1l.s"
1648 "musl/src/math/x86_64/fabs.s"
1649 "musl/src/math/x86_64/fabsf.s"
1650 "musl/src/math/x86_64/fabsl.s"
1651 "musl/src/math/x86_64/floorl.s"
1652 "musl/src/math/x86_64/fma.c"
1653 "musl/src/math/x86_64/fmaf.c"
1654 "musl/src/math/x86_64/fmodl.s"
1655 "musl/src/math/x86_64/llrint.s"
1656 "musl/src/math/x86_64/llrintf.s"
1657 "musl/src/math/x86_64/llrintl.s"
1658 "musl/src/math/x86_64/log10l.s"
1659 "musl/src/math/x86_64/log1pl.s"
1660 "musl/src/math/x86_64/log2l.s"
1661 "musl/src/math/x86_64/logl.s"
1662 "musl/src/math/x86_64/lrint.s"
1663 "musl/src/math/x86_64/lrintf.s"
1664 "musl/src/math/x86_64/lrintl.s"
1665 "musl/src/math/x86_64/remainderl.s"
1666 "musl/src/math/x86_64/rintl.s"
1667 "musl/src/math/x86_64/sqrt.s"
1668 "musl/src/math/x86_64/sqrtf.s"
1669 "musl/src/math/x86_64/sqrtl.s"
1670 "musl/src/math/x86_64/truncl.s"
1671 "musl/src/misc/a64l.c"
1672 "musl/src/misc/basename.c"
1673 "musl/src/misc/dirname.c"
1674 "musl/src/misc/ffs.c"
1675 "musl/src/misc/ffsl.c"
1676 "musl/src/misc/ffsll.c"
1677 "musl/src/misc/fmtmsg.c"
1678 "musl/src/misc/forkpty.c"
1679 "musl/src/misc/get_current_dir_name.c"
1680 "musl/src/misc/getauxval.c"
1681 "musl/src/misc/getdomainname.c"
1682 "musl/src/misc/getentropy.c"
1683 "musl/src/misc/gethostid.c"
1684 "musl/src/misc/getopt.c"
1685 "musl/src/misc/getopt_long.c"
1686 "musl/src/misc/getpriority.c"
1687 "musl/src/misc/getresgid.c"
1688 "musl/src/misc/getresuid.c"
1689 "musl/src/misc/getrlimit.c"
1690 "musl/src/misc/getrusage.c"
1691 "musl/src/misc/getsubopt.c"
1692 "musl/src/misc/initgroups.c"
1693 "musl/src/misc/ioctl.c"
1694 "musl/src/misc/issetugid.c"
1695 "musl/src/misc/lockf.c"
1696 "musl/src/misc/login_tty.c"
1697 "musl/src/misc/mntent.c"
1698 "musl/src/misc/nftw.c"
1699 "musl/src/misc/openpty.c"
1700 "musl/src/misc/ptsname.c"
1701 "musl/src/misc/pty.c"
1702 "musl/src/misc/realpath.c"
1703 "musl/src/misc/setdomainname.c"
1704 "musl/src/misc/setpriority.c"
1705 "musl/src/misc/setrlimit.c"
1706 "musl/src/misc/syscall.c"
1707 "musl/src/misc/syslog.c"
1708 "musl/src/misc/uname.c"
1709 "musl/src/misc/wordexp.c"
1710 "musl/src/mman/madvise.c"
1711 "musl/src/mman/mincore.c"
1712 "musl/src/mman/mlock.c"
1713 "musl/src/mman/mlockall.c"
1714 "musl/src/mman/mmap.c"
1715 "musl/src/mman/mprotect.c"
1716 "musl/src/mman/mremap.c"
1717 "musl/src/mman/msync.c"
1718 "musl/src/mman/munlock.c"
1719 "musl/src/mman/munlockall.c"
1720 "musl/src/mman/munmap.c"
1721 "musl/src/mman/posix_madvise.c"
1722 "musl/src/mman/shm_open.c"
1723 "musl/src/mq/mq_close.c"
1724 "musl/src/mq/mq_getattr.c"
1725 "musl/src/mq/mq_notify.c"
1726 "musl/src/mq/mq_open.c"
1727 "musl/src/mq/mq_receive.c"
1728 "musl/src/mq/mq_send.c"
1729 "musl/src/mq/mq_setattr.c"
1730 "musl/src/mq/mq_timedreceive.c"
1731 "musl/src/mq/mq_timedsend.c"
1732 "musl/src/mq/mq_unlink.c"
1733 "musl/src/multibyte/btowc.c"
1734 "musl/src/multibyte/c16rtomb.c"
1735 "musl/src/multibyte/c32rtomb.c"
1736 "musl/src/multibyte/internal.c"
1737 "musl/src/multibyte/internal.h"
1738 "musl/src/multibyte/mblen.c"
1739 "musl/src/multibyte/mbrlen.c"
1740 "musl/src/multibyte/mbrtoc16.c"
1741 "musl/src/multibyte/mbrtoc32.c"
1742 "musl/src/multibyte/mbrtowc.c"
1743 "musl/src/multibyte/mbsinit.c"
1744 "musl/src/multibyte/mbsnrtowcs.c"
1745 "musl/src/multibyte/mbsrtowcs.c"
1746 "musl/src/multibyte/mbstowcs.c"
1747 "musl/src/multibyte/mbtowc.c"
1748 "musl/src/multibyte/wcrtomb.c"
1749 "musl/src/multibyte/wcsnrtombs.c"
1750 "musl/src/multibyte/wcsrtombs.c"
1751 "musl/src/multibyte/wcstombs.c"
1752 "musl/src/multibyte/wctob.c"
1753 "musl/src/multibyte/wctomb.c"
1754 "musl/src/network/accept.c"
1755 "musl/src/network/accept4.c"
1756 "musl/src/network/bind.c"
1757 "musl/src/network/connect.c"
1758 "musl/src/network/dn_comp.c"
1759 "musl/src/network/dn_expand.c"
1760 "musl/src/network/dn_skipname.c"
1761 "musl/src/network/dns_parse.c"
1762 "musl/src/network/ent.c"
1763 "musl/src/network/ether.c"
1764 "musl/src/network/freeaddrinfo.c"
1765 "musl/src/network/gai_strerror.c"
1766 "musl/src/network/getaddrinfo.c"
1767 "musl/src/network/gethostbyaddr.c"
1768 "musl/src/network/gethostbyaddr_r.c"
1769 "musl/src/network/gethostbyname.c"
1770 "musl/src/network/gethostbyname2.c"
1771 "musl/src/network/gethostbyname2_r.c"
1772 "musl/src/network/gethostbyname_r.c"
1773 "musl/src/network/getifaddrs.c"
1774 "musl/src/network/getnameinfo.c"
1775 "musl/src/network/getpeername.c"
1776 "musl/src/network/getservbyname.c"
1777 "musl/src/network/getservbyname_r.c"
1778 "musl/src/network/getservbyport.c"
1779 "musl/src/network/getservbyport_r.c"
1780 "musl/src/network/getsockname.c"
1781 "musl/src/network/getsockopt.c"
1782 "musl/src/network/h_errno.c"
1783 "musl/src/network/herror.c"
1784 "musl/src/network/hstrerror.c"
1785 "musl/src/network/htonl.c"
1786 "musl/src/network/htons.c"
1787 "musl/src/network/if_freenameindex.c"
1788 "musl/src/network/if_indextoname.c"
1789 "musl/src/network/if_nameindex.c"
1790 "musl/src/network/if_nametoindex.c"
1791 "musl/src/network/in6addr_any.c"
1792 "musl/src/network/in6addr_loopback.c"
1793 "musl/src/network/inet_addr.c"
1794 "musl/src/network/inet_aton.c"
1795 "musl/src/network/inet_legacy.c"
1796 "musl/src/network/inet_ntoa.c"
1797 "musl/src/network/inet_ntop.c"
1798 "musl/src/network/inet_pton.c"
1799 "musl/src/network/listen.c"
1800 "musl/src/network/lookup.h"
1801 "musl/src/network/lookup_ipliteral.c"
1802 "musl/src/network/lookup_name.c"
1803 "musl/src/network/lookup_serv.c"
1804 "musl/src/network/netlink.c"
1805 "musl/src/network/netlink.h"
1806 "musl/src/network/netname.c"
1807 "musl/src/network/ns_parse.c"
1808 "musl/src/network/ntohl.c"
1809 "musl/src/network/ntohs.c"
1810 "musl/src/network/proto.c"
1811 "musl/src/network/recv.c"
1812 "musl/src/network/recvfrom.c"
1813 "musl/src/network/recvmmsg.c"
1814 "musl/src/network/recvmsg.c"
1815 "musl/src/network/res_init.c"
1816 "musl/src/network/res_mkquery.c"
1817 "musl/src/network/res_msend.c"
1818 "musl/src/network/res_query.c"
1819 "musl/src/network/res_querydomain.c"
1820 "musl/src/network/res_send.c"
1821 "musl/src/network/res_state.c"
1822 "musl/src/network/resolvconf.c"
1823 "musl/src/network/send.c"
1824 "musl/src/network/sendmmsg.c"
1825 "musl/src/network/sendmsg.c"
1826 "musl/src/network/sendto.c"
1827 "musl/src/network/serv.c"
1828 "musl/src/network/setsockopt.c"
1829 "musl/src/network/shutdown.c"
1830 "musl/src/network/sockatmark.c"
1831 "musl/src/network/socket.c"
1832 "musl/src/network/socketpair.c"
1833 "musl/src/passwd/fgetgrent.c"
1834 "musl/src/passwd/fgetpwent.c"
1835 "musl/src/passwd/fgetspent.c"
1836 "musl/src/passwd/getgr_a.c"
1837 "musl/src/passwd/getgr_r.c"
1838 "musl/src/passwd/getgrent.c"
1839 "musl/src/passwd/getgrent_a.c"
1840 "musl/src/passwd/getgrouplist.c"
1841 "musl/src/passwd/getpw_a.c"
1842 "musl/src/passwd/getpw_r.c"
1843 "musl/src/passwd/getpwent.c"
1844 "musl/src/passwd/getpwent_a.c"
1845 "musl/src/passwd/getspent.c"
1846 "musl/src/passwd/getspnam.c"
1847 "musl/src/passwd/getspnam_r.c"
1848 "musl/src/passwd/lckpwdf.c"
1849 "musl/src/passwd/nscd.h"
1850 "musl/src/passwd/nscd_query.c"
1851 "musl/src/passwd/putgrent.c"
1852 "musl/src/passwd/putpwent.c"
1853 "musl/src/passwd/putspent.c"
1854 "musl/src/passwd/pwf.h"
1855 "musl/src/prng/__rand48_step.c"
1856 "musl/src/prng/__seed48.c"
1857 "musl/src/prng/drand48.c"
1858 "musl/src/prng/lcong48.c"
1859 "musl/src/prng/lrand48.c"
1860 "musl/src/prng/mrand48.c"
1861 "musl/src/prng/rand.c"
1862 "musl/src/prng/rand48.h"
1863 "musl/src/prng/rand_r.c"
1864 "musl/src/prng/random.c"
1865 "musl/src/prng/seed48.c"
1866 "musl/src/prng/srand48.c"
1867 "musl/src/process/arm/vfork.s"
1868 "musl/src/process/execl.c"
1869 "musl/src/process/execle.c"
1870 "musl/src/process/execlp.c"
1871 "musl/src/process/execv.c"
1872 "musl/src/process/execve.c"
1873 "musl/src/process/execvp.c"
1874 "musl/src/process/fdop.h"
1875 "musl/src/process/fexecve.c"
1876 "musl/src/process/fork.c"
1877 "musl/src/process/i386/vfork.s"
1878 "musl/src/process/posix_spawn.c"
1879 "musl/src/process/posix_spawn_file_actions_addclose.c"
1880 "musl/src/process/posix_spawn_file_actions_adddup2.c"
1881 "musl/src/process/posix_spawn_file_actions_addopen.c"
1882 "musl/src/process/posix_spawn_file_actions_destroy.c"
1883 "musl/src/process/posix_spawn_file_actions_init.c"
1884 "musl/src/process/posix_spawnattr_destroy.c"
1885 "musl/src/process/posix_spawnattr_getflags.c"
1886 "musl/src/process/posix_spawnattr_getpgroup.c"
1887 "musl/src/process/posix_spawnattr_getsigdefault.c"
1888 "musl/src/process/posix_spawnattr_getsigmask.c"
1889 "musl/src/process/posix_spawnattr_init.c"
1890 "musl/src/process/posix_spawnattr_sched.c"
1891 "musl/src/process/posix_spawnattr_setflags.c"
1892 "musl/src/process/posix_spawnattr_setpgroup.c"
1893 "musl/src/process/posix_spawnattr_setsigdefault.c"
1894 "musl/src/process/posix_spawnattr_setsigmask.c"
1895 "musl/src/process/posix_spawnp.c"
1896 "musl/src/process/s390x/vfork.s"
1897 "musl/src/process/sh/vfork.s"
1898 "musl/src/process/system.c"
1899 "musl/src/process/vfork.c"
1900 "musl/src/process/wait.c"
1901 "musl/src/process/waitid.c"
1902 "musl/src/process/waitpid.c"
1903 "musl/src/process/x32/vfork.s"
1904 "musl/src/process/x86_64/vfork.s"
1905 "musl/src/regex/fnmatch.c"
1906 "musl/src/regex/glob.c"
1907 "musl/src/regex/regcomp.c"
1908 "musl/src/regex/regerror.c"
1909 "musl/src/regex/regexec.c"
1910 "musl/src/regex/tre-mem.c"
1911 "musl/src/regex/tre.h"
1912 "musl/src/sched/affinity.c"
1913 "musl/src/sched/sched_cpucount.c"
1914 "musl/src/sched/sched_get_priority_max.c"
1915 "musl/src/sched/sched_getcpu.c"
1916 "musl/src/sched/sched_getparam.c"
1917 "musl/src/sched/sched_getscheduler.c"
1918 "musl/src/sched/sched_rr_get_interval.c"
1919 "musl/src/sched/sched_setparam.c"
1920 "musl/src/sched/sched_setscheduler.c"
1921 "musl/src/sched/sched_yield.c"
1922 "musl/src/search/hsearch.c"
1923 "musl/src/search/insque.c"
1924 "musl/src/search/lsearch.c"
1925 "musl/src/search/tdelete.c"
1926 "musl/src/search/tdestroy.c"
1927 "musl/src/search/tfind.c"
1928 "musl/src/search/tsearch.c"
1929 "musl/src/search/tsearch.h"
1930 "musl/src/search/twalk.c"
1931 "musl/src/select/poll.c"
1932 "musl/src/select/pselect.c"
1933 "musl/src/select/select.c"
1934 "musl/src/setjmp/aarch64/longjmp.s"
1935 "musl/src/setjmp/aarch64/setjmp.s"
1936 "musl/src/setjmp/arm/longjmp.s"
1937 "musl/src/setjmp/arm/setjmp.s"
1938 "musl/src/setjmp/i386/longjmp.s"
1939 "musl/src/setjmp/i386/setjmp.s"
1940 "musl/src/setjmp/longjmp.c"
1941 "musl/src/setjmp/m68k/longjmp.s"
1942 "musl/src/setjmp/m68k/setjmp.s"
1943 "musl/src/setjmp/microblaze/longjmp.s"
1944 "musl/src/setjmp/microblaze/setjmp.s"
1945 "musl/src/setjmp/mips/longjmp.S"
1946 "musl/src/setjmp/mips/setjmp.S"
1947 "musl/src/setjmp/mips64/longjmp.S"
1948 "musl/src/setjmp/mips64/setjmp.S"
1949 "musl/src/setjmp/mipsn32/longjmp.S"
1950 "musl/src/setjmp/mipsn32/setjmp.S"
1951 "musl/src/setjmp/or1k/longjmp.s"
1952 "musl/src/setjmp/or1k/setjmp.s"
1953 "musl/src/setjmp/powerpc/longjmp.S"
1954 "musl/src/setjmp/powerpc/setjmp.S"
1955 "musl/src/setjmp/powerpc64/longjmp.s"
1956 "musl/src/setjmp/powerpc64/setjmp.s"
1957 "musl/src/setjmp/s390x/longjmp.s"
1958 "musl/src/setjmp/s390x/setjmp.s"
1959 "musl/src/setjmp/setjmp.c"
1960 "musl/src/setjmp/sh/longjmp.S"
1961 "musl/src/setjmp/sh/setjmp.S"
1962 "musl/src/setjmp/x32/longjmp.s"
1963 "musl/src/setjmp/x32/setjmp.s"
1964 "musl/src/setjmp/x86_64/longjmp.s"
1965 "musl/src/setjmp/x86_64/setjmp.s"
1966 "musl/src/signal/aarch64/restore.s"
1967 "musl/src/signal/aarch64/sigsetjmp.s"
1968 "musl/src/signal/arm/restore.s"
1969 "musl/src/signal/arm/sigsetjmp.s"
1970 "musl/src/signal/block.c"
1971 "musl/src/signal/getitimer.c"
1972 "musl/src/signal/i386/restore.s"
1973 "musl/src/signal/i386/sigsetjmp.s"
1974 "musl/src/signal/kill.c"
1975 "musl/src/signal/killpg.c"
1976 "musl/src/signal/m68k/sigsetjmp.s"
1977 "musl/src/signal/microblaze/restore.s"
1978 "musl/src/signal/microblaze/sigsetjmp.s"
1979 "musl/src/signal/mips/restore.s"
1980 "musl/src/signal/mips/sigsetjmp.s"
1981 "musl/src/signal/mips64/restore.s"
1982 "musl/src/signal/mips64/sigsetjmp.s"
1983 "musl/src/signal/mipsn32/restore.s"
1984 "musl/src/signal/mipsn32/sigsetjmp.s"
1985 "musl/src/signal/or1k/sigsetjmp.s"
1986 "musl/src/signal/powerpc/restore.s"
1987 "musl/src/signal/powerpc/sigsetjmp.s"
1988 "musl/src/signal/powerpc64/restore.s"
1989 "musl/src/signal/powerpc64/sigsetjmp.s"
1990 "musl/src/signal/psiginfo.c"
1991 "musl/src/signal/psignal.c"
1992 "musl/src/signal/raise.c"
1993 "musl/src/signal/restore.c"
1994 "musl/src/signal/s390x/restore.s"
1995 "musl/src/signal/s390x/sigsetjmp.s"
1996 "musl/src/signal/setitimer.c"
1997 "musl/src/signal/sh/restore.s"
1998 "musl/src/signal/sh/sigsetjmp.s"
1999 "musl/src/signal/sigaction.c"
2000 "musl/src/signal/sigaddset.c"
2001 "musl/src/signal/sigaltstack.c"
2002 "musl/src/signal/sigandset.c"
2003 "musl/src/signal/sigdelset.c"
2004 "musl/src/signal/sigemptyset.c"
2005 "musl/src/signal/sigfillset.c"
2006 "musl/src/signal/sighold.c"
2007 "musl/src/signal/sigignore.c"
2008 "musl/src/signal/siginterrupt.c"
2009 "musl/src/signal/sigisemptyset.c"
2010 "musl/src/signal/sigismember.c"
2011 "musl/src/signal/siglongjmp.c"
2012 "musl/src/signal/signal.c"
2013 "musl/src/signal/sigorset.c"
2014 "musl/src/signal/sigpause.c"
2015 "musl/src/signal/sigpending.c"
2016 "musl/src/signal/sigprocmask.c"
2017 "musl/src/signal/sigqueue.c"
2018 "musl/src/signal/sigrelse.c"
2019 "musl/src/signal/sigrtmax.c"
2020 "musl/src/signal/sigrtmin.c"
2021 "musl/src/signal/sigset.c"
2022 "musl/src/signal/sigsetjmp.c"
2023 "musl/src/signal/sigsetjmp_tail.c"
2024 "musl/src/signal/sigsuspend.c"
2025 "musl/src/signal/sigtimedwait.c"
2026 "musl/src/signal/sigwait.c"
2027 "musl/src/signal/sigwaitinfo.c"
2028 "musl/src/signal/x32/restore.s"
2029 "musl/src/signal/x32/sigsetjmp.s"
2030 "musl/src/signal/x86_64/restore.s"
2031 "musl/src/signal/x86_64/sigsetjmp.s"
2032 "musl/src/stat/__xstat.c"
2033 "musl/src/stat/chmod.c"
2034 "musl/src/stat/fchmod.c"
2035 "musl/src/stat/fchmodat.c"
2036 "musl/src/stat/fstat.c"
2037 "musl/src/stat/fstatat.c"
2038 "musl/src/stat/futimens.c"
2039 "musl/src/stat/futimesat.c"
2040 "musl/src/stat/lchmod.c"
2041 "musl/src/stat/lstat.c"
2042 "musl/src/stat/mkdir.c"
2043 "musl/src/stat/mkdirat.c"
2044 "musl/src/stat/mkfifo.c"
2045 "musl/src/stat/mkfifoat.c"
2046 "musl/src/stat/mknod.c"
2047 "musl/src/stat/mknodat.c"
2048 "musl/src/stat/stat.c"
2049 "musl/src/stat/statvfs.c"
2050 "musl/src/stat/umask.c"
2051 "musl/src/stat/utimensat.c"
2052 "musl/src/stdio/.fwrite.c.swp"
2053 "musl/src/stdio/__fclose_ca.c"
2054 "musl/src/stdio/__fdopen.c"
2055 "musl/src/stdio/__fmodeflags.c"
2056 "musl/src/stdio/__fopen_rb_ca.c"
2057 "musl/src/stdio/__lockfile.c"
2058 "musl/src/stdio/__overflow.c"
2059 "musl/src/stdio/__stdio_close.c"
2060 "musl/src/stdio/__stdio_exit.c"
2061 "musl/src/stdio/__stdio_read.c"
2062 "musl/src/stdio/__stdio_seek.c"
2063 "musl/src/stdio/__stdio_write.c"
2064 "musl/src/stdio/__stdout_write.c"
2065 "musl/src/stdio/__string_read.c"
2066 "musl/src/stdio/__toread.c"
2067 "musl/src/stdio/__towrite.c"
2068 "musl/src/stdio/__uflow.c"
2069 "musl/src/stdio/asprintf.c"
2070 "musl/src/stdio/clearerr.c"
2071 "musl/src/stdio/dprintf.c"
2072 "musl/src/stdio/ext.c"
2073 "musl/src/stdio/ext2.c"
2074 "musl/src/stdio/fclose.c"
2075 "musl/src/stdio/feof.c"
2076 "musl/src/stdio/ferror.c"
2077 "musl/src/stdio/fflush.c"
2078 "musl/src/stdio/fgetc.c"
2079 "musl/src/stdio/fgetln.c"
2080 "musl/src/stdio/fgetpos.c"
2081 "musl/src/stdio/fgets.c"
2082 "musl/src/stdio/fgetwc.c"
2083 "musl/src/stdio/fgetws.c"
2084 "musl/src/stdio/fileno.c"
2085 "musl/src/stdio/flockfile.c"
2086 "musl/src/stdio/fmemopen.c"
2087 "musl/src/stdio/fopen.c"
2088 "musl/src/stdio/fopencookie.c"
2089 "musl/src/stdio/fprintf.c"
2090 "musl/src/stdio/fputc.c"
2091 "musl/src/stdio/fputs.c"
2092 "musl/src/stdio/fputwc.c"
2093 "musl/src/stdio/fputws.c"
2094 "musl/src/stdio/fread.c"
2095 "musl/src/stdio/freopen.c"
2096 "musl/src/stdio/fscanf.c"
2097 "musl/src/stdio/fseek.c"
2098 "musl/src/stdio/fsetpos.c"
2099 "musl/src/stdio/ftell.c"
2100 "musl/src/stdio/ftrylockfile.c"
2101 "musl/src/stdio/funlockfile.c"
2102 "musl/src/stdio/fwide.c"
2103 "musl/src/stdio/fwprintf.c"
2104 "musl/src/stdio/fwrite.c"
2105 "musl/src/stdio/fwscanf.c"
2106 "musl/src/stdio/getc.c"
2107 "musl/src/stdio/getc.h"
2108 "musl/src/stdio/getc_unlocked.c"
2109 "musl/src/stdio/getchar.c"
2110 "musl/src/stdio/getchar_unlocked.c"
2111 "musl/src/stdio/getdelim.c"
2112 "musl/src/stdio/getline.c"
2113 "musl/src/stdio/gets.c"
2114 "musl/src/stdio/getw.c"
2115 "musl/src/stdio/getwc.c"
2116 "musl/src/stdio/getwchar.c"
2117 "musl/src/stdio/ofl.c"
2118 "musl/src/stdio/ofl_add.c"
2119 "musl/src/stdio/open_memstream.c"
2120 "musl/src/stdio/open_wmemstream.c"
2121 "musl/src/stdio/pclose.c"
2122 "musl/src/stdio/perror.c"
2123 "musl/src/stdio/popen.c"
2124 "musl/src/stdio/printf.c"
2125 "musl/src/stdio/putc.c"
2126 "musl/src/stdio/putc.h"
2127 "musl/src/stdio/putc_unlocked.c"
2128 "musl/src/stdio/putchar.c"
2129 "musl/src/stdio/putchar_unlocked.c"
2130 "musl/src/stdio/puts.c"
2131 "musl/src/stdio/putw.c"
2132 "musl/src/stdio/putwc.c"
2133 "musl/src/stdio/putwchar.c"
2134 "musl/src/stdio/remove.c"
2135 "musl/src/stdio/rename.c"
2136 "musl/src/stdio/rewind.c"
2137 "musl/src/stdio/scanf.c"
2138 "musl/src/stdio/setbuf.c"
2139 "musl/src/stdio/setbuffer.c"
2140 "musl/src/stdio/setlinebuf.c"
2141 "musl/src/stdio/setvbuf.c"
2142 "musl/src/stdio/snprintf.c"
2143 "musl/src/stdio/sprintf.c"
2144 "musl/src/stdio/sscanf.c"
2145 "musl/src/stdio/stderr.c"
2146 "musl/src/stdio/stdin.c"
2147 "musl/src/stdio/stdout.c"
2148 "musl/src/stdio/swprintf.c"
2149 "musl/src/stdio/swscanf.c"
2150 "musl/src/stdio/tempnam.c"
2151 "musl/src/stdio/tmpfile.c"
2152 "musl/src/stdio/tmpnam.c"
2153 "musl/src/stdio/ungetc.c"
2154 "musl/src/stdio/ungetwc.c"
2155 "musl/src/stdio/vasprintf.c"
2156 "musl/src/stdio/vdprintf.c"
2157 "musl/src/stdio/vfprintf.c"
2158 "musl/src/stdio/vfscanf.c"
2159 "musl/src/stdio/vfwprintf.c"
2160 "musl/src/stdio/vfwscanf.c"
2161 "musl/src/stdio/vprintf.c"
2162 "musl/src/stdio/vscanf.c"
2163 "musl/src/stdio/vsnprintf.c"
2164 "musl/src/stdio/vsprintf.c"
2165 "musl/src/stdio/vsscanf.c"
2166 "musl/src/stdio/vswprintf.c"
2167 "musl/src/stdio/vswscanf.c"
2168 "musl/src/stdio/vwprintf.c"
2169 "musl/src/stdio/vwscanf.c"
2170 "musl/src/stdio/wprintf.c"
2171 "musl/src/stdio/wscanf.c"
2172 "musl/src/stdlib/abs.c"
2173 "musl/src/stdlib/atof.c"
2174 "musl/src/stdlib/atoi.c"
2175 "musl/src/stdlib/atol.c"
2176 "musl/src/stdlib/atoll.c"
2177 "musl/src/stdlib/bsearch.c"
2178 "musl/src/stdlib/div.c"
2179 "musl/src/stdlib/ecvt.c"
2180 "musl/src/stdlib/fcvt.c"
2181 "musl/src/stdlib/gcvt.c"
2182 "musl/src/stdlib/imaxabs.c"
2183 "musl/src/stdlib/imaxdiv.c"
2184 "musl/src/stdlib/labs.c"
2185 "musl/src/stdlib/ldiv.c"
2186 "musl/src/stdlib/llabs.c"
2187 "musl/src/stdlib/lldiv.c"
2188 "musl/src/stdlib/qsort.c"
2189 "musl/src/stdlib/strtod.c"
2190 "musl/src/stdlib/strtol.c"
2191 "musl/src/stdlib/wcstod.c"
2192 "musl/src/stdlib/wcstol.c"
2193 "musl/src/string/arm/__aeabi_memcpy.s"
2194 "musl/src/string/arm/__aeabi_memset.s"
2195 "musl/src/string/arm/memcpy.c"
2196 "musl/src/string/arm/memcpy_le.S"
2197 "musl/src/string/bcmp.c"
2198 "musl/src/string/bcopy.c"
2199 "musl/src/string/bzero.c"
2200 "musl/src/string/explicit_bzero.c"
2201 "musl/src/string/i386/memcpy.s"
2202 "musl/src/string/i386/memmove.s"
2203 "musl/src/string/i386/memset.s"
2204 "musl/src/string/index.c"
2205 "musl/src/string/memccpy.c"
2206 "musl/src/string/memchr.c"
2207 "musl/src/string/memcmp.c"
2208 "musl/src/string/memcpy.c"
2209 "musl/src/string/memmem.c"
2210 "musl/src/string/memmove.c"
2211 "musl/src/string/mempcpy.c"
2212 "musl/src/string/memrchr.c"
2213 "musl/src/string/memset.c"
2214 "musl/src/string/rindex.c"
2215 "musl/src/string/stpcpy.c"
2216 "musl/src/string/stpncpy.c"
2217 "musl/src/string/strcasecmp.c"
2218 "musl/src/string/strcasestr.c"
2219 "musl/src/string/strcat.c"
2220 "musl/src/string/strchr.c"
2221 "musl/src/string/strchrnul.c"
2222 "musl/src/string/strcmp.c"
2223 "musl/src/string/strcpy.c"
2224 "musl/src/string/strcspn.c"
2225 "musl/src/string/strdup.c"
2226 "musl/src/string/strerror_r.c"
2227 "musl/src/string/strlcat.c"
2228 "musl/src/string/strlcpy.c"
2229 "musl/src/string/strlen.c"
2230 "musl/src/string/strncasecmp.c"
2231 "musl/src/string/strncat.c"
2232 "musl/src/string/strncmp.c"
2233 "musl/src/string/strncpy.c"
2234 "musl/src/string/strndup.c"
2235 "musl/src/string/strnlen.c"
2236 "musl/src/string/strpbrk.c"
2237 "musl/src/string/strrchr.c"
2238 "musl/src/string/strsep.c"
2239 "musl/src/string/strsignal.c"
2240 "musl/src/string/strspn.c"
2241 "musl/src/string/strstr.c"
2242 "musl/src/string/strtok.c"
2243 "musl/src/string/strtok_r.c"
2244 "musl/src/string/strverscmp.c"
2245 "musl/src/string/swab.c"
2246 "musl/src/string/wcpcpy.c"
2247 "musl/src/string/wcpncpy.c"
2248 "musl/src/string/wcscasecmp.c"
2249 "musl/src/string/wcscasecmp_l.c"
2250 "musl/src/string/wcscat.c"
2251 "musl/src/string/wcschr.c"
2252 "musl/src/string/wcscmp.c"
2253 "musl/src/string/wcscpy.c"
2254 "musl/src/string/wcscspn.c"
2255 "musl/src/string/wcsdup.c"
2256 "musl/src/string/wcslen.c"
2257 "musl/src/string/wcsncasecmp.c"
2258 "musl/src/string/wcsncasecmp_l.c"
2259 "musl/src/string/wcsncat.c"
2260 "musl/src/string/wcsncmp.c"
2261 "musl/src/string/wcsncpy.c"
2262 "musl/src/string/wcsnlen.c"
2263 "musl/src/string/wcspbrk.c"
2264 "musl/src/string/wcsrchr.c"
2265 "musl/src/string/wcsspn.c"
2266 "musl/src/string/wcsstr.c"
2267 "musl/src/string/wcstok.c"
2268 "musl/src/string/wcswcs.c"
2269 "musl/src/string/wmemchr.c"
2270 "musl/src/string/wmemcmp.c"
2271 "musl/src/string/wmemcpy.c"
2272 "musl/src/string/wmemmove.c"
2273 "musl/src/string/wmemset.c"
2274 "musl/src/string/x86_64/memcpy.s"
2275 "musl/src/string/x86_64/memmove.s"
2276 "musl/src/string/x86_64/memset.s"
2277 "musl/src/temp/__randname.c"
2278 "musl/src/temp/mkdtemp.c"
2279 "musl/src/temp/mkostemp.c"
2280 "musl/src/temp/mkostemps.c"
2281 "musl/src/temp/mkstemp.c"
2282 "musl/src/temp/mkstemps.c"
2283 "musl/src/temp/mktemp.c"
2284 "musl/src/termios/cfgetospeed.c"
2285 "musl/src/termios/cfmakeraw.c"
2286 "musl/src/termios/cfsetospeed.c"
2287 "musl/src/termios/tcdrain.c"
2288 "musl/src/termios/tcflow.c"
2289 "musl/src/termios/tcflush.c"
2290 "musl/src/termios/tcgetattr.c"
2291 "musl/src/termios/tcgetsid.c"
2292 "musl/src/termios/tcsendbreak.c"
2293 "musl/src/termios/tcsetattr.c"
2294 "musl/src/thread/__lock.c"
2295 "musl/src/thread/__set_thread_area.c"
2296 "musl/src/thread/__syscall_cp.c"
2297 "musl/src/thread/__timedwait.c"
2298 "musl/src/thread/__tls_get_addr.c"
2299 "musl/src/thread/__unmapself.c"
2300 "musl/src/thread/__wait.c"
2301 "musl/src/thread/aarch64/__set_thread_area.s"
2302 "musl/src/thread/aarch64/__unmapself.s"
2303 "musl/src/thread/aarch64/clone.s"
2304 "musl/src/thread/aarch64/syscall_cp.s"
2305 "musl/src/thread/arm/__aeabi_read_tp.s"
2306 "musl/src/thread/arm/__set_thread_area.c"
2307 "musl/src/thread/arm/__unmapself.s"
2308 "musl/src/thread/arm/atomics.s"
2309 "musl/src/thread/arm/clone.s"
2310 "musl/src/thread/arm/syscall_cp.s"
2311 "musl/src/thread/call_once.c"
2312 "musl/src/thread/clone.c"
2313 "musl/src/thread/cnd_broadcast.c"
2314 "musl/src/thread/cnd_destroy.c"
2315 "musl/src/thread/cnd_init.c"
2316 "musl/src/thread/cnd_signal.c"
2317 "musl/src/thread/cnd_timedwait.c"
2318 "musl/src/thread/cnd_wait.c"
2319 "musl/src/thread/default_attr.c"
2320 "musl/src/thread/i386/__set_thread_area.s"
2321 "musl/src/thread/i386/__unmapself.s"
2322 "musl/src/thread/i386/clone.s"
2323 "musl/src/thread/i386/syscall_cp.s"
2324 "musl/src/thread/i386/tls.s"
2325 "musl/src/thread/lock_ptc.c"
2326 "musl/src/thread/m68k/__m68k_read_tp.s"
2327 "musl/src/thread/m68k/clone.s"
2328 "musl/src/thread/m68k/syscall_cp.s"
2329 "musl/src/thread/microblaze/__set_thread_area.s"
2330 "musl/src/thread/microblaze/__unmapself.s"
2331 "musl/src/thread/microblaze/clone.s"
2332 "musl/src/thread/microblaze/syscall_cp.s"
2333 "musl/src/thread/mips/__unmapself.s"
2334 "musl/src/thread/mips/clone.s"
2335 "musl/src/thread/mips/syscall_cp.s"
2336 "musl/src/thread/mips64/__unmapself.s"
2337 "musl/src/thread/mips64/clone.s"
2338 "musl/src/thread/mips64/syscall_cp.s"
2339 "musl/src/thread/mipsn32/__unmapself.s"
2340 "musl/src/thread/mipsn32/clone.s"
2341 "musl/src/thread/mipsn32/syscall_cp.s"
2342 "musl/src/thread/mtx_destroy.c"
2343 "musl/src/thread/mtx_init.c"
2344 "musl/src/thread/mtx_lock.c"
2345 "musl/src/thread/mtx_timedlock.c"
2346 "musl/src/thread/mtx_trylock.c"
2347 "musl/src/thread/mtx_unlock.c"
2348 "musl/src/thread/or1k/__set_thread_area.s"
2349 "musl/src/thread/or1k/__unmapself.s"
2350 "musl/src/thread/or1k/clone.s"
2351 "musl/src/thread/or1k/syscall_cp.s"
2352 "musl/src/thread/powerpc/__set_thread_area.s"
2353 "musl/src/thread/powerpc/__unmapself.s"
2354 "musl/src/thread/powerpc/clone.s"
2355 "musl/src/thread/powerpc/syscall_cp.s"
2356 "musl/src/thread/powerpc64/__set_thread_area.s"
2357 "musl/src/thread/powerpc64/__unmapself.s"
2358 "musl/src/thread/powerpc64/clone.s"
2359 "musl/src/thread/powerpc64/syscall_cp.s"
2360 "musl/src/thread/pthread_atfork.c"
2361 "musl/src/thread/pthread_attr_destroy.c"
2362 "musl/src/thread/pthread_attr_get.c"
2363 "musl/src/thread/pthread_attr_init.c"
2364 "musl/src/thread/pthread_attr_setdetachstate.c"
2365 "musl/src/thread/pthread_attr_setguardsize.c"
2366 "musl/src/thread/pthread_attr_setinheritsched.c"
2367 "musl/src/thread/pthread_attr_setschedparam.c"
2368 "musl/src/thread/pthread_attr_setschedpolicy.c"
2369 "musl/src/thread/pthread_attr_setscope.c"
2370 "musl/src/thread/pthread_attr_setstack.c"
2371 "musl/src/thread/pthread_attr_setstacksize.c"
2372 "musl/src/thread/pthread_barrier_destroy.c"
2373 "musl/src/thread/pthread_barrier_init.c"
2374 "musl/src/thread/pthread_barrier_wait.c"
2375 "musl/src/thread/pthread_barrierattr_destroy.c"
2376 "musl/src/thread/pthread_barrierattr_init.c"
2377 "musl/src/thread/pthread_barrierattr_setpshared.c"
2378 "musl/src/thread/pthread_cancel.c"
2379 "musl/src/thread/pthread_cleanup_push.c"
2380 "musl/src/thread/pthread_cond_broadcast.c"
2381 "musl/src/thread/pthread_cond_destroy.c"
2382 "musl/src/thread/pthread_cond_init.c"
2383 "musl/src/thread/pthread_cond_signal.c"
2384 "musl/src/thread/pthread_cond_timedwait.c"
2385 "musl/src/thread/pthread_cond_wait.c"
2386 "musl/src/thread/pthread_condattr_destroy.c"
2387 "musl/src/thread/pthread_condattr_init.c"
2388 "musl/src/thread/pthread_condattr_setclock.c"
2389 "musl/src/thread/pthread_condattr_setpshared.c"
2390 "musl/src/thread/pthread_create.c"
2391 "musl/src/thread/pthread_detach.c"
2392 "musl/src/thread/pthread_equal.c"
2393 "musl/src/thread/pthread_getattr_np.c"
2394 "musl/src/thread/pthread_getconcurrency.c"
2395 "musl/src/thread/pthread_getcpuclockid.c"
2396 "musl/src/thread/pthread_getschedparam.c"
2397 "musl/src/thread/pthread_getspecific.c"
2398 "musl/src/thread/pthread_join.c"
2399 "musl/src/thread/pthread_key_create.c"
2400 "musl/src/thread/pthread_key_delete.c"
2401 "musl/src/thread/pthread_kill.c"
2402 "musl/src/thread/pthread_mutex_consistent.c"
2403 "musl/src/thread/pthread_mutex_destroy.c"
2404 "musl/src/thread/pthread_mutex_getprioceiling.c"
2405 "musl/src/thread/pthread_mutex_init.c"
2406 "musl/src/thread/pthread_mutex_lock.c"
2407 "musl/src/thread/pthread_mutex_setprioceiling.c"
2408 "musl/src/thread/pthread_mutex_timedlock.c"
2409 "musl/src/thread/pthread_mutex_trylock.c"
2410 "musl/src/thread/pthread_mutex_unlock.c"
2411 "musl/src/thread/pthread_mutexattr_destroy.c"
2412 "musl/src/thread/pthread_mutexattr_init.c"
2413 "musl/src/thread/pthread_mutexattr_setprotocol.c"
2414 "musl/src/thread/pthread_mutexattr_setpshared.c"
2415 "musl/src/thread/pthread_mutexattr_setrobust.c"
2416 "musl/src/thread/pthread_mutexattr_settype.c"
2417 "musl/src/thread/pthread_once.c"
2418 "musl/src/thread/pthread_rwlock_destroy.c"
2419 "musl/src/thread/pthread_rwlock_init.c"
2420 "musl/src/thread/pthread_rwlock_rdlock.c"
2421 "musl/src/thread/pthread_rwlock_timedrdlock.c"
2422 "musl/src/thread/pthread_rwlock_timedwrlock.c"
2423 "musl/src/thread/pthread_rwlock_tryrdlock.c"
2424 "musl/src/thread/pthread_rwlock_trywrlock.c"
2425 "musl/src/thread/pthread_rwlock_unlock.c"
2426 "musl/src/thread/pthread_rwlock_wrlock.c"
2427 "musl/src/thread/pthread_rwlockattr_destroy.c"
2428 "musl/src/thread/pthread_rwlockattr_init.c"
2429 "musl/src/thread/pthread_rwlockattr_setpshared.c"
2430 "musl/src/thread/pthread_self.c"
2431 "musl/src/thread/pthread_setattr_default_np.c"
2432 "musl/src/thread/pthread_setcancelstate.c"
2433 "musl/src/thread/pthread_setcanceltype.c"
2434 "musl/src/thread/pthread_setconcurrency.c"
2435 "musl/src/thread/pthread_setname_np.c"
2436 "musl/src/thread/pthread_setschedparam.c"
2437 "musl/src/thread/pthread_setschedprio.c"
2438 "musl/src/thread/pthread_setspecific.c"
2439 "musl/src/thread/pthread_sigmask.c"
2440 "musl/src/thread/pthread_spin_destroy.c"
2441 "musl/src/thread/pthread_spin_init.c"
2442 "musl/src/thread/pthread_spin_lock.c"
2443 "musl/src/thread/pthread_spin_trylock.c"
2444 "musl/src/thread/pthread_spin_unlock.c"
2445 "musl/src/thread/pthread_testcancel.c"
2446 "musl/src/thread/s390x/__set_thread_area.s"
2447 "musl/src/thread/s390x/__tls_get_offset.s"
2448 "musl/src/thread/s390x/__unmapself.s"
2449 "musl/src/thread/s390x/clone.s"
2450 "musl/src/thread/s390x/syscall_cp.s"
2451 "musl/src/thread/sem_destroy.c"
2452 "musl/src/thread/sem_getvalue.c"
2453 "musl/src/thread/sem_init.c"
2454 "musl/src/thread/sem_open.c"
2455 "musl/src/thread/sem_post.c"
2456 "musl/src/thread/sem_timedwait.c"
2457 "musl/src/thread/sem_trywait.c"
2458 "musl/src/thread/sem_unlink.c"
2459 "musl/src/thread/sem_wait.c"
2460 "musl/src/thread/sh/__set_thread_area.c"
2461 "musl/src/thread/sh/__unmapself.c"
2462 "musl/src/thread/sh/__unmapself_mmu.s"
2463 "musl/src/thread/sh/atomics.s"
2464 "musl/src/thread/sh/clone.s"
2465 "musl/src/thread/sh/syscall_cp.s"
2466 "musl/src/thread/synccall.c"
2467 "musl/src/thread/syscall_cp.c"
2468 "musl/src/thread/thrd_create.c"
2469 "musl/src/thread/thrd_exit.c"
2470 "musl/src/thread/thrd_join.c"
2471 "musl/src/thread/thrd_sleep.c"
2472 "musl/src/thread/thrd_yield.c"
2473 "musl/src/thread/tls.c"
2474 "musl/src/thread/tss_create.c"
2475 "musl/src/thread/tss_delete.c"
2476 "musl/src/thread/tss_set.c"
2477 "musl/src/thread/vmlock.c"
2478 "musl/src/thread/x32/__set_thread_area.s"
2479 "musl/src/thread/x32/__unmapself.s"
2480 "musl/src/thread/x32/clone.s"
2481 "musl/src/thread/x32/syscall_cp.s"
2482 "musl/src/thread/x32/syscall_cp_fixup.c"
2483 "musl/src/thread/x86_64/__set_thread_area.s"
2484 "musl/src/thread/x86_64/__unmapself.s"
2485 "musl/src/thread/x86_64/clone.s"
2486 "musl/src/thread/x86_64/syscall_cp.s"
2487 "musl/src/time/__map_file.c"
2488 "musl/src/time/__month_to_secs.c"
2489 "musl/src/time/__secs_to_tm.c"
2490 "musl/src/time/__tm_to_secs.c"
2491 "musl/src/time/__tz.c"
2492 "musl/src/time/__year_to_secs.c"
2493 "musl/src/time/asctime.c"
2494 "musl/src/time/asctime_r.c"
2495 "musl/src/time/clock.c"
2496 "musl/src/time/clock_getcpuclockid.c"
2497 "musl/src/time/clock_getres.c"
2498 "musl/src/time/clock_gettime.c"
2499 "musl/src/time/clock_nanosleep.c"
2500 "musl/src/time/clock_settime.c"
2501 "musl/src/time/ctime.c"
2502 "musl/src/time/ctime_r.c"
2503 "musl/src/time/difftime.c"
2504 "musl/src/time/ftime.c"
2505 "musl/src/time/getdate.c"
2506 "musl/src/time/gettimeofday.c"
2507 "musl/src/time/gmtime.c"
2508 "musl/src/time/gmtime_r.c"
2509 "musl/src/time/localtime.c"
2510 "musl/src/time/localtime_r.c"
2511 "musl/src/time/mktime.c"
2512 "musl/src/time/nanosleep.c"
2513 "musl/src/time/strftime.c"
2514 "musl/src/time/strptime.c"
2515 "musl/src/time/time.c"
2516 "musl/src/time/time_impl.h"
2517 "musl/src/time/timegm.c"
2518 "musl/src/time/timer_create.c"
2519 "musl/src/time/timer_delete.c"
2520 "musl/src/time/timer_getoverrun.c"
2521 "musl/src/time/timer_gettime.c"
2522 "musl/src/time/timer_settime.c"
2523 "musl/src/time/times.c"
2524 "musl/src/time/timespec_get.c"
2525 "musl/src/time/utime.c"
2526 "musl/src/time/wcsftime.c"
2527 "musl/src/unistd/_exit.c"
2528 "musl/src/unistd/access.c"
2529 "musl/src/unistd/acct.c"
2530 "musl/src/unistd/alarm.c"
2531 "musl/src/unistd/chdir.c"
2532 "musl/src/unistd/chown.c"
2533 "musl/src/unistd/close.c"
2534 "musl/src/unistd/ctermid.c"
2535 "musl/src/unistd/dup.c"
2536 "musl/src/unistd/dup2.c"
2537 "musl/src/unistd/dup3.c"
2538 "musl/src/unistd/faccessat.c"
2539 "musl/src/unistd/fchdir.c"
2540 "musl/src/unistd/fchown.c"
2541 "musl/src/unistd/fchownat.c"
2542 "musl/src/unistd/fdatasync.c"
2543 "musl/src/unistd/fsync.c"
2544 "musl/src/unistd/ftruncate.c"
2545 "musl/src/unistd/getcwd.c"
2546 "musl/src/unistd/getegid.c"
2547 "musl/src/unistd/geteuid.c"
2548 "musl/src/unistd/getgid.c"
2549 "musl/src/unistd/getgroups.c"
2550 "musl/src/unistd/gethostname.c"
2551 "musl/src/unistd/getlogin.c"
2552 "musl/src/unistd/getlogin_r.c"
2553 "musl/src/unistd/getpgid.c"
2554 "musl/src/unistd/getpgrp.c"
2555 "musl/src/unistd/getpid.c"
2556 "musl/src/unistd/getppid.c"
2557 "musl/src/unistd/getsid.c"
2558 "musl/src/unistd/getuid.c"
2559 "musl/src/unistd/isatty.c"
2560 "musl/src/unistd/lchown.c"
2561 "musl/src/unistd/link.c"
2562 "musl/src/unistd/linkat.c"
2563 "musl/src/unistd/lseek.c"
2564 "musl/src/unistd/mips/pipe.s"
2565 "musl/src/unistd/mips64/pipe.s"
2566 "musl/src/unistd/mipsn32/pipe.s"
2567 "musl/src/unistd/nice.c"
2568 "musl/src/unistd/pause.c"
2569 "musl/src/unistd/pipe.c"
2570 "musl/src/unistd/pipe2.c"
2571 "musl/src/unistd/posix_close.c"
2572 "musl/src/unistd/pread.c"
2573 "musl/src/unistd/preadv.c"
2574 "musl/src/unistd/pwrite.c"
2575 "musl/src/unistd/pwritev.c"
2576 "musl/src/unistd/read.c"
2577 "musl/src/unistd/readlink.c"
2578 "musl/src/unistd/readlinkat.c"
2579 "musl/src/unistd/readv.c"
2580 "musl/src/unistd/renameat.c"
2581 "musl/src/unistd/rmdir.c"
2582 "musl/src/unistd/setegid.c"
2583 "musl/src/unistd/seteuid.c"
2584 "musl/src/unistd/setgid.c"
2585 "musl/src/unistd/setpgid.c"
2586 "musl/src/unistd/setpgrp.c"
2587 "musl/src/unistd/setregid.c"
2588 "musl/src/unistd/setresgid.c"
2589 "musl/src/unistd/setresuid.c"
2590 "musl/src/unistd/setreuid.c"
2591 "musl/src/unistd/setsid.c"
2592 "musl/src/unistd/setuid.c"
2593 "musl/src/unistd/setxid.c"
2594 "musl/src/unistd/sh/pipe.s"
2595 "musl/src/unistd/sleep.c"
2596 "musl/src/unistd/symlink.c"
2597 "musl/src/unistd/symlinkat.c"
2598 "musl/src/unistd/sync.c"
2599 "musl/src/unistd/tcgetpgrp.c"
2600 "musl/src/unistd/tcsetpgrp.c"
2601 "musl/src/unistd/truncate.c"
2602 "musl/src/unistd/ttyname.c"
2603 "musl/src/unistd/ttyname_r.c"
2604 "musl/src/unistd/ualarm.c"
2605 "musl/src/unistd/unlink.c"
2606 "musl/src/unistd/unlinkat.c"
2607 "musl/src/unistd/usleep.c"
2608 "musl/src/unistd/write.c"
2609 "musl/src/unistd/writev.c"
2610)
2611
8112612set(ZIG_LIBC_FILES
8122613 "dummy/c.zig"
8132614 "dummy/c/i386.zig"
......@@ -4299,314 +6100,313 @@ set(ZIG_LIBC_FILES
42996100 "include/x86_64-linux-musl/bits/stat.h"
43006101 "include/x86_64-linux-musl/bits/syscall.h"
43016102 "include/x86_64-linux-musl/bits/user.h"
4302 "musl/crt/mips64/crtn.s"
4303 "musl/crt/mips64/crti.s"
4304 "musl/crt/crt1.c"
4305 "musl/crt/x32/crtn.s"
4306 "musl/crt/x32/crti.s"
4307 "musl/crt/crtn.c"
4308 "musl/crt/powerpc64/crtn.s"
4309 "musl/crt/powerpc64/crti.s"
4310 "musl/crt/crti.c"
4311 "musl/crt/microblaze/crtn.s"
4312 "musl/crt/microblaze/crti.s"
4313 "musl/crt/arm/crtn.s"
4314 "musl/crt/arm/crti.s"
4315 "musl/crt/rcrt1.c"
4316 "musl/crt/s390x/crtn.s"
4317 "musl/crt/s390x/crti.s"
4318 "musl/crt/mips/crtn.s"
4319 "musl/crt/mips/crti.s"
4320 "musl/crt/x86_64/crtn.s"
4321 "musl/crt/x86_64/crti.s"
4322 "musl/crt/i386/crtn.s"
4323 "musl/crt/i386/crti.s"
4324 "musl/crt/aarch64/crtn.s"
4325 "musl/crt/aarch64/crti.s"
4326 "musl/crt/mipsn32/crtn.s"
4327 "musl/crt/mipsn32/crti.s"
4328 "musl/crt/or1k/crtn.s"
4329 "musl/crt/or1k/crti.s"
4330 "musl/crt/powerpc/crtn.s"
4331 "musl/crt/powerpc/crti.s"
4332 "musl/crt/Scrt1.c"
4333 "musl/crt/sh/crtn.s"
4334 "musl/crt/sh/crti.s"
4335 "musl/src/internal/libc.h"
4336 "musl/src/include/features.h"
4337 "musl/arch/mips64/pthread_arch.h"
4338 "musl/arch/mips64/crt_arch.h"
4339 "musl/arch/mips64/ksigaction.h"
4340 "musl/arch/mips64/reloc.h"
4341 "musl/arch/mips64/syscall_arch.h"
6103 "musl/arch/aarch64/atomic_arch.h"
6104 "musl/arch/aarch64/bits/alltypes.h.in"
6105 "musl/arch/aarch64/bits/endian.h"
6106 "musl/arch/aarch64/bits/fcntl.h"
6107 "musl/arch/aarch64/bits/fenv.h"
6108 "musl/arch/aarch64/bits/float.h"
6109 "musl/arch/aarch64/bits/hwcap.h"
6110 "musl/arch/aarch64/bits/ipc.h"
6111 "musl/arch/aarch64/bits/limits.h"
6112 "musl/arch/aarch64/bits/msg.h"
6113 "musl/arch/aarch64/bits/posix.h"
6114 "musl/arch/aarch64/bits/reg.h"
6115 "musl/arch/aarch64/bits/sem.h"
6116 "musl/arch/aarch64/bits/setjmp.h"
6117 "musl/arch/aarch64/bits/shm.h"
6118 "musl/arch/aarch64/bits/signal.h"
6119 "musl/arch/aarch64/bits/socket.h"
6120 "musl/arch/aarch64/bits/stat.h"
6121 "musl/arch/aarch64/bits/stdint.h"
6122 "musl/arch/aarch64/bits/syscall.h.in"
6123 "musl/arch/aarch64/bits/user.h"
6124 "musl/arch/aarch64/crt_arch.h"
6125 "musl/arch/aarch64/pthread_arch.h"
6126 "musl/arch/aarch64/reloc.h"
6127 "musl/arch/aarch64/syscall_arch.h"
6128 "musl/arch/arm/atomic_arch.h"
6129 "musl/arch/arm/bits/alltypes.h.in"
6130 "musl/arch/arm/bits/endian.h"
6131 "musl/arch/arm/bits/fcntl.h"
6132 "musl/arch/arm/bits/fenv.h"
6133 "musl/arch/arm/bits/float.h"
6134 "musl/arch/arm/bits/hwcap.h"
6135 "musl/arch/arm/bits/ioctl_fix.h"
6136 "musl/arch/arm/bits/limits.h"
6137 "musl/arch/arm/bits/posix.h"
6138 "musl/arch/arm/bits/ptrace.h"
6139 "musl/arch/arm/bits/reg.h"
6140 "musl/arch/arm/bits/setjmp.h"
6141 "musl/arch/arm/bits/signal.h"
6142 "musl/arch/arm/bits/stat.h"
6143 "musl/arch/arm/bits/stdint.h"
6144 "musl/arch/arm/bits/syscall.h.in"
6145 "musl/arch/arm/bits/user.h"
6146 "musl/arch/arm/crt_arch.h"
6147 "musl/arch/arm/pthread_arch.h"
6148 "musl/arch/arm/reloc.h"
6149 "musl/arch/arm/syscall_arch.h"
6150 "musl/arch/generic/bits/errno.h"
6151 "musl/arch/generic/bits/fcntl.h"
6152 "musl/arch/generic/bits/fenv.h"
6153 "musl/arch/generic/bits/hwcap.h"
6154 "musl/arch/generic/bits/io.h"
6155 "musl/arch/generic/bits/ioctl.h"
6156 "musl/arch/generic/bits/ioctl_fix.h"
6157 "musl/arch/generic/bits/ipc.h"
6158 "musl/arch/generic/bits/kd.h"
6159 "musl/arch/generic/bits/link.h"
6160 "musl/arch/generic/bits/mman.h"
6161 "musl/arch/generic/bits/msg.h"
6162 "musl/arch/generic/bits/poll.h"
6163 "musl/arch/generic/bits/ptrace.h"
6164 "musl/arch/generic/bits/resource.h"
6165 "musl/arch/generic/bits/sem.h"
6166 "musl/arch/generic/bits/shm.h"
6167 "musl/arch/generic/bits/socket.h"
6168 "musl/arch/generic/bits/soundcard.h"
6169 "musl/arch/generic/bits/statfs.h"
6170 "musl/arch/generic/bits/termios.h"
6171 "musl/arch/generic/bits/vt.h"
6172 "musl/arch/i386/atomic_arch.h"
6173 "musl/arch/i386/bits/alltypes.h.in"
6174 "musl/arch/i386/bits/endian.h"
6175 "musl/arch/i386/bits/fenv.h"
6176 "musl/arch/i386/bits/float.h"
6177 "musl/arch/i386/bits/io.h"
6178 "musl/arch/i386/bits/limits.h"
6179 "musl/arch/i386/bits/mman.h"
6180 "musl/arch/i386/bits/posix.h"
6181 "musl/arch/i386/bits/ptrace.h"
6182 "musl/arch/i386/bits/reg.h"
6183 "musl/arch/i386/bits/setjmp.h"
6184 "musl/arch/i386/bits/signal.h"
6185 "musl/arch/i386/bits/stat.h"
6186 "musl/arch/i386/bits/stdint.h"
6187 "musl/arch/i386/bits/syscall.h.in"
6188 "musl/arch/i386/bits/user.h"
6189 "musl/arch/i386/crt_arch.h"
6190 "musl/arch/i386/pthread_arch.h"
6191 "musl/arch/i386/reloc.h"
6192 "musl/arch/i386/syscall_arch.h"
6193 "musl/arch/mips/atomic_arch.h"
6194 "musl/arch/mips/bits/alltypes.h.in"
6195 "musl/arch/mips/bits/endian.h"
6196 "musl/arch/mips/bits/errno.h"
6197 "musl/arch/mips/bits/fcntl.h"
6198 "musl/arch/mips/bits/fenv.h"
6199 "musl/arch/mips/bits/float.h"
6200 "musl/arch/mips/bits/hwcap.h"
6201 "musl/arch/mips/bits/ioctl.h"
6202 "musl/arch/mips/bits/limits.h"
6203 "musl/arch/mips/bits/mman.h"
6204 "musl/arch/mips/bits/msg.h"
6205 "musl/arch/mips/bits/poll.h"
6206 "musl/arch/mips/bits/posix.h"
6207 "musl/arch/mips/bits/ptrace.h"
6208 "musl/arch/mips/bits/reg.h"
6209 "musl/arch/mips/bits/resource.h"
6210 "musl/arch/mips/bits/sem.h"
6211 "musl/arch/mips/bits/setjmp.h"
6212 "musl/arch/mips/bits/shm.h"
6213 "musl/arch/mips/bits/signal.h"
6214 "musl/arch/mips/bits/socket.h"
6215 "musl/arch/mips/bits/stat.h"
6216 "musl/arch/mips/bits/statfs.h"
6217 "musl/arch/mips/bits/stdint.h"
6218 "musl/arch/mips/bits/syscall.h.in"
6219 "musl/arch/mips/bits/termios.h"
6220 "musl/arch/mips/bits/user.h"
6221 "musl/arch/mips/crt_arch.h"
6222 "musl/arch/mips/ksigaction.h"
6223 "musl/arch/mips/pthread_arch.h"
6224 "musl/arch/mips/reloc.h"
6225 "musl/arch/mips/syscall_arch.h"
43426226 "musl/arch/mips64/atomic_arch.h"
4343 "musl/arch/mips64/bits/float.h"
6227 "musl/arch/mips64/bits/alltypes.h.in"
6228 "musl/arch/mips64/bits/endian.h"
43446229 "musl/arch/mips64/bits/errno.h"
4345 "musl/arch/mips64/bits/mman.h"
4346 "musl/arch/mips64/bits/stdint.h"
4347 "musl/arch/mips64/bits/termios.h"
4348 "musl/arch/mips64/bits/reg.h"
4349 "musl/arch/mips64/bits/ipc.h"
6230 "musl/arch/mips64/bits/fcntl.h"
43506231 "musl/arch/mips64/bits/fenv.h"
6232 "musl/arch/mips64/bits/float.h"
6233 "musl/arch/mips64/bits/hwcap.h"
6234 "musl/arch/mips64/bits/ioctl.h"
6235 "musl/arch/mips64/bits/ipc.h"
6236 "musl/arch/mips64/bits/limits.h"
6237 "musl/arch/mips64/bits/mman.h"
43516238 "musl/arch/mips64/bits/msg.h"
6239 "musl/arch/mips64/bits/poll.h"
6240 "musl/arch/mips64/bits/posix.h"
43526241 "musl/arch/mips64/bits/ptrace.h"
6242 "musl/arch/mips64/bits/reg.h"
43536243 "musl/arch/mips64/bits/resource.h"
4354 "musl/arch/mips64/bits/posix.h"
6244 "musl/arch/mips64/bits/sem.h"
43556245 "musl/arch/mips64/bits/setjmp.h"
4356 "musl/arch/mips64/bits/alltypes.h.in"
4357 "musl/arch/mips64/bits/syscall.h.in"
43586246 "musl/arch/mips64/bits/shm.h"
4359 "musl/arch/mips64/bits/hwcap.h"
4360 "musl/arch/mips64/bits/endian.h"
4361 "musl/arch/mips64/bits/limits.h"
4362 "musl/arch/mips64/bits/poll.h"
4363 "musl/arch/mips64/bits/ioctl.h"
4364 "musl/arch/mips64/bits/fcntl.h"
43656247 "musl/arch/mips64/bits/signal.h"
4366 "musl/arch/mips64/bits/stat.h"
4367 "musl/arch/mips64/bits/user.h"
4368 "musl/arch/mips64/bits/sem.h"
43696248 "musl/arch/mips64/bits/socket.h"
6249 "musl/arch/mips64/bits/stat.h"
43706250 "musl/arch/mips64/bits/statfs.h"
4371 "musl/arch/generic/bits/errno.h"
4372 "musl/arch/generic/bits/mman.h"
4373 "musl/arch/generic/bits/termios.h"
4374 "musl/arch/generic/bits/kd.h"
4375 "musl/arch/generic/bits/ipc.h"
4376 "musl/arch/generic/bits/fenv.h"
4377 "musl/arch/generic/bits/msg.h"
4378 "musl/arch/generic/bits/vt.h"
4379 "musl/arch/generic/bits/ptrace.h"
4380 "musl/arch/generic/bits/io.h"
4381 "musl/arch/generic/bits/resource.h"
4382 "musl/arch/generic/bits/link.h"
4383 "musl/arch/generic/bits/shm.h"
4384 "musl/arch/generic/bits/hwcap.h"
4385 "musl/arch/generic/bits/poll.h"
4386 "musl/arch/generic/bits/ioctl.h"
4387 "musl/arch/generic/bits/fcntl.h"
4388 "musl/arch/generic/bits/ioctl_fix.h"
4389 "musl/arch/generic/bits/sem.h"
4390 "musl/arch/generic/bits/socket.h"
4391 "musl/arch/generic/bits/statfs.h"
4392 "musl/arch/generic/bits/soundcard.h"
4393 "musl/arch/powerpc64/pthread_arch.h"
4394 "musl/arch/powerpc64/crt_arch.h"
4395 "musl/arch/powerpc64/reloc.h"
4396 "musl/arch/powerpc64/syscall_arch.h"
4397 "musl/arch/powerpc64/atomic_arch.h"
4398 "musl/arch/powerpc64/bits/float.h"
4399 "musl/arch/powerpc64/bits/errno.h"
4400 "musl/arch/powerpc64/bits/mman.h"
4401 "musl/arch/powerpc64/bits/stdint.h"
4402 "musl/arch/powerpc64/bits/termios.h"
4403 "musl/arch/powerpc64/bits/reg.h"
4404 "musl/arch/powerpc64/bits/ipc.h"
4405 "musl/arch/powerpc64/bits/fenv.h"
4406 "musl/arch/powerpc64/bits/msg.h"
4407 "musl/arch/powerpc64/bits/ptrace.h"
4408 "musl/arch/powerpc64/bits/posix.h"
4409 "musl/arch/powerpc64/bits/setjmp.h"
4410 "musl/arch/powerpc64/bits/alltypes.h.in"
4411 "musl/arch/powerpc64/bits/syscall.h.in"
4412 "musl/arch/powerpc64/bits/shm.h"
4413 "musl/arch/powerpc64/bits/hwcap.h"
4414 "musl/arch/powerpc64/bits/endian.h"
4415 "musl/arch/powerpc64/bits/limits.h"
4416 "musl/arch/powerpc64/bits/ioctl.h"
4417 "musl/arch/powerpc64/bits/fcntl.h"
4418 "musl/arch/powerpc64/bits/signal.h"
4419 "musl/arch/powerpc64/bits/stat.h"
4420 "musl/arch/powerpc64/bits/user.h"
4421 "musl/arch/powerpc64/bits/sem.h"
4422 "musl/arch/powerpc64/bits/socket.h"
4423 "musl/arch/arm/pthread_arch.h"
4424 "musl/arch/arm/crt_arch.h"
4425 "musl/arch/arm/reloc.h"
4426 "musl/arch/arm/syscall_arch.h"
4427 "musl/arch/arm/atomic_arch.h"
4428 "musl/arch/arm/bits/float.h"
4429 "musl/arch/arm/bits/stdint.h"
4430 "musl/arch/arm/bits/reg.h"
4431 "musl/arch/arm/bits/fenv.h"
4432 "musl/arch/arm/bits/ptrace.h"
4433 "musl/arch/arm/bits/posix.h"
4434 "musl/arch/arm/bits/setjmp.h"
4435 "musl/arch/arm/bits/alltypes.h.in"
4436 "musl/arch/arm/bits/syscall.h.in"
4437 "musl/arch/arm/bits/hwcap.h"
4438 "musl/arch/arm/bits/endian.h"
4439 "musl/arch/arm/bits/limits.h"
4440 "musl/arch/arm/bits/fcntl.h"
4441 "musl/arch/arm/bits/signal.h"
4442 "musl/arch/arm/bits/stat.h"
4443 "musl/arch/arm/bits/user.h"
4444 "musl/arch/arm/bits/ioctl_fix.h"
4445 "musl/arch/s390x/pthread_arch.h"
4446 "musl/arch/s390x/crt_arch.h"
4447 "musl/arch/s390x/reloc.h"
4448 "musl/arch/s390x/syscall_arch.h"
6251 "musl/arch/mips64/bits/stdint.h"
6252 "musl/arch/mips64/bits/syscall.h.in"
6253 "musl/arch/mips64/bits/termios.h"
6254 "musl/arch/mips64/bits/user.h"
6255 "musl/arch/mips64/crt_arch.h"
6256 "musl/arch/mips64/ksigaction.h"
6257 "musl/arch/mips64/pthread_arch.h"
6258 "musl/arch/mips64/reloc.h"
6259 "musl/arch/mips64/syscall_arch.h"
6260 "musl/arch/powerpc/atomic_arch.h"
6261 "musl/arch/powerpc/bits/alltypes.h.in"
6262 "musl/arch/powerpc/bits/endian.h"
6263 "musl/arch/powerpc/bits/errno.h"
6264 "musl/arch/powerpc/bits/fcntl.h"
6265 "musl/arch/powerpc/bits/fenv.h"
6266 "musl/arch/powerpc/bits/float.h"
6267 "musl/arch/powerpc/bits/hwcap.h"
6268 "musl/arch/powerpc/bits/ioctl.h"
6269 "musl/arch/powerpc/bits/ipc.h"
6270 "musl/arch/powerpc/bits/limits.h"
6271 "musl/arch/powerpc/bits/mman.h"
6272 "musl/arch/powerpc/bits/msg.h"
6273 "musl/arch/powerpc/bits/posix.h"
6274 "musl/arch/powerpc/bits/ptrace.h"
6275 "musl/arch/powerpc/bits/reg.h"
6276 "musl/arch/powerpc/bits/sem.h"
6277 "musl/arch/powerpc/bits/setjmp.h"
6278 "musl/arch/powerpc/bits/shm.h"
6279 "musl/arch/powerpc/bits/signal.h"
6280 "musl/arch/powerpc/bits/socket.h"
6281 "musl/arch/powerpc/bits/stat.h"
6282 "musl/arch/powerpc/bits/stdint.h"
6283 "musl/arch/powerpc/bits/syscall.h.in"
6284 "musl/arch/powerpc/bits/termios.h"
6285 "musl/arch/powerpc/bits/user.h"
6286 "musl/arch/powerpc/crt_arch.h"
6287 "musl/arch/powerpc/pthread_arch.h"
6288 "musl/arch/powerpc/reloc.h"
6289 "musl/arch/powerpc/syscall_arch.h"
6290 "musl/arch/powerpc64/atomic_arch.h"
6291 "musl/arch/powerpc64/bits/alltypes.h.in"
6292 "musl/arch/powerpc64/bits/endian.h"
6293 "musl/arch/powerpc64/bits/errno.h"
6294 "musl/arch/powerpc64/bits/fcntl.h"
6295 "musl/arch/powerpc64/bits/fenv.h"
6296 "musl/arch/powerpc64/bits/float.h"
6297 "musl/arch/powerpc64/bits/hwcap.h"
6298 "musl/arch/powerpc64/bits/ioctl.h"
6299 "musl/arch/powerpc64/bits/ipc.h"
6300 "musl/arch/powerpc64/bits/limits.h"
6301 "musl/arch/powerpc64/bits/mman.h"
6302 "musl/arch/powerpc64/bits/msg.h"
6303 "musl/arch/powerpc64/bits/posix.h"
6304 "musl/arch/powerpc64/bits/ptrace.h"
6305 "musl/arch/powerpc64/bits/reg.h"
6306 "musl/arch/powerpc64/bits/sem.h"
6307 "musl/arch/powerpc64/bits/setjmp.h"
6308 "musl/arch/powerpc64/bits/shm.h"
6309 "musl/arch/powerpc64/bits/signal.h"
6310 "musl/arch/powerpc64/bits/socket.h"
6311 "musl/arch/powerpc64/bits/stat.h"
6312 "musl/arch/powerpc64/bits/stdint.h"
6313 "musl/arch/powerpc64/bits/syscall.h.in"
6314 "musl/arch/powerpc64/bits/termios.h"
6315 "musl/arch/powerpc64/bits/user.h"
6316 "musl/arch/powerpc64/crt_arch.h"
6317 "musl/arch/powerpc64/pthread_arch.h"
6318 "musl/arch/powerpc64/reloc.h"
6319 "musl/arch/powerpc64/syscall_arch.h"
44496320 "musl/arch/s390x/atomic_arch.h"
6321 "musl/arch/s390x/bits/alltypes.h.in"
6322 "musl/arch/s390x/bits/endian.h"
6323 "musl/arch/s390x/bits/fcntl.h"
6324 "musl/arch/s390x/bits/fenv.h"
44506325 "musl/arch/s390x/bits/float.h"
4451 "musl/arch/s390x/bits/stdint.h"
4452 "musl/arch/s390x/bits/reg.h"
6326 "musl/arch/s390x/bits/hwcap.h"
6327 "musl/arch/s390x/bits/ioctl_fix.h"
44536328 "musl/arch/s390x/bits/ipc.h"
4454 "musl/arch/s390x/bits/fenv.h"
4455 "musl/arch/s390x/bits/msg.h"
4456 "musl/arch/s390x/bits/ptrace.h"
6329 "musl/arch/s390x/bits/limits.h"
44576330 "musl/arch/s390x/bits/link.h"
6331 "musl/arch/s390x/bits/msg.h"
44586332 "musl/arch/s390x/bits/posix.h"
6333 "musl/arch/s390x/bits/ptrace.h"
6334 "musl/arch/s390x/bits/reg.h"
6335 "musl/arch/s390x/bits/sem.h"
44596336 "musl/arch/s390x/bits/setjmp.h"
4460 "musl/arch/s390x/bits/alltypes.h.in"
4461 "musl/arch/s390x/bits/syscall.h.in"
44626337 "musl/arch/s390x/bits/shm.h"
4463 "musl/arch/s390x/bits/hwcap.h"
4464 "musl/arch/s390x/bits/endian.h"
4465 "musl/arch/s390x/bits/limits.h"
4466 "musl/arch/s390x/bits/fcntl.h"
44676338 "musl/arch/s390x/bits/signal.h"
4468 "musl/arch/s390x/bits/stat.h"
4469 "musl/arch/s390x/bits/user.h"
4470 "musl/arch/s390x/bits/ioctl_fix.h"
4471 "musl/arch/s390x/bits/sem.h"
44726339 "musl/arch/s390x/bits/socket.h"
6340 "musl/arch/s390x/bits/stat.h"
44736341 "musl/arch/s390x/bits/statfs.h"
4474 "musl/arch/mips/pthread_arch.h"
4475 "musl/arch/mips/crt_arch.h"
4476 "musl/arch/mips/ksigaction.h"
4477 "musl/arch/mips/reloc.h"
4478 "musl/arch/mips/syscall_arch.h"
4479 "musl/arch/mips/atomic_arch.h"
4480 "musl/arch/mips/bits/float.h"
4481 "musl/arch/mips/bits/errno.h"
4482 "musl/arch/mips/bits/mman.h"
4483 "musl/arch/mips/bits/stdint.h"
4484 "musl/arch/mips/bits/termios.h"
4485 "musl/arch/mips/bits/reg.h"
4486 "musl/arch/mips/bits/fenv.h"
4487 "musl/arch/mips/bits/msg.h"
4488 "musl/arch/mips/bits/ptrace.h"
4489 "musl/arch/mips/bits/resource.h"
4490 "musl/arch/mips/bits/posix.h"
4491 "musl/arch/mips/bits/setjmp.h"
4492 "musl/arch/mips/bits/alltypes.h.in"
4493 "musl/arch/mips/bits/syscall.h.in"
4494 "musl/arch/mips/bits/shm.h"
4495 "musl/arch/mips/bits/hwcap.h"
4496 "musl/arch/mips/bits/endian.h"
4497 "musl/arch/mips/bits/limits.h"
4498 "musl/arch/mips/bits/poll.h"
4499 "musl/arch/mips/bits/ioctl.h"
4500 "musl/arch/mips/bits/fcntl.h"
4501 "musl/arch/mips/bits/signal.h"
4502 "musl/arch/mips/bits/stat.h"
4503 "musl/arch/mips/bits/user.h"
4504 "musl/arch/mips/bits/sem.h"
4505 "musl/arch/mips/bits/socket.h"
4506 "musl/arch/mips/bits/statfs.h"
4507 "musl/arch/x86_64/pthread_arch.h"
4508 "musl/arch/x86_64/crt_arch.h"
4509 "musl/arch/x86_64/ksigaction.h"
4510 "musl/arch/x86_64/reloc.h"
4511 "musl/arch/x86_64/syscall_arch.h"
6342 "musl/arch/s390x/bits/stdint.h"
6343 "musl/arch/s390x/bits/syscall.h.in"
6344 "musl/arch/s390x/bits/user.h"
6345 "musl/arch/s390x/crt_arch.h"
6346 "musl/arch/s390x/pthread_arch.h"
6347 "musl/arch/s390x/reloc.h"
6348 "musl/arch/s390x/syscall_arch.h"
45126349 "musl/arch/x86_64/atomic_arch.h"
6350 "musl/arch/x86_64/bits/alltypes.h.in"
6351 "musl/arch/x86_64/bits/endian.h"
6352 "musl/arch/x86_64/bits/fcntl.h"
6353 "musl/arch/x86_64/bits/fenv.h"
45136354 "musl/arch/x86_64/bits/float.h"
4514 "musl/arch/x86_64/bits/mman.h"
4515 "musl/arch/x86_64/bits/stdint.h"
4516 "musl/arch/x86_64/bits/reg.h"
6355 "musl/arch/x86_64/bits/io.h"
45176356 "musl/arch/x86_64/bits/ipc.h"
4518 "musl/arch/x86_64/bits/fenv.h"
6357 "musl/arch/x86_64/bits/limits.h"
6358 "musl/arch/x86_64/bits/mman.h"
45196359 "musl/arch/x86_64/bits/msg.h"
4520 "musl/arch/x86_64/bits/ptrace.h"
4521 "musl/arch/x86_64/bits/io.h"
45226360 "musl/arch/x86_64/bits/posix.h"
6361 "musl/arch/x86_64/bits/ptrace.h"
6362 "musl/arch/x86_64/bits/reg.h"
45236363 "musl/arch/x86_64/bits/setjmp.h"
4524 "musl/arch/x86_64/bits/alltypes.h.in"
4525 "musl/arch/x86_64/bits/syscall.h.in"
45266364 "musl/arch/x86_64/bits/shm.h"
4527 "musl/arch/x86_64/bits/endian.h"
4528 "musl/arch/x86_64/bits/limits.h"
4529 "musl/arch/x86_64/bits/fcntl.h"
45306365 "musl/arch/x86_64/bits/signal.h"
6366 "musl/arch/x86_64/bits/socket.h"
45316367 "musl/arch/x86_64/bits/stat.h"
6368 "musl/arch/x86_64/bits/stdint.h"
6369 "musl/arch/x86_64/bits/syscall.h.in"
45326370 "musl/arch/x86_64/bits/user.h"
4533 "musl/arch/x86_64/bits/socket.h"
4534 "musl/arch/i386/pthread_arch.h"
4535 "musl/arch/i386/crt_arch.h"
4536 "musl/arch/i386/reloc.h"
4537 "musl/arch/i386/syscall_arch.h"
4538 "musl/arch/i386/atomic_arch.h"
4539 "musl/arch/i386/bits/float.h"
4540 "musl/arch/i386/bits/mman.h"
4541 "musl/arch/i386/bits/stdint.h"
4542 "musl/arch/i386/bits/reg.h"
4543 "musl/arch/i386/bits/fenv.h"
4544 "musl/arch/i386/bits/ptrace.h"
4545 "musl/arch/i386/bits/io.h"
4546 "musl/arch/i386/bits/posix.h"
4547 "musl/arch/i386/bits/setjmp.h"
4548 "musl/arch/i386/bits/alltypes.h.in"
4549 "musl/arch/i386/bits/syscall.h.in"
4550 "musl/arch/i386/bits/endian.h"
4551 "musl/arch/i386/bits/limits.h"
4552 "musl/arch/i386/bits/signal.h"
4553 "musl/arch/i386/bits/stat.h"
4554 "musl/arch/i386/bits/user.h"
4555 "musl/arch/aarch64/pthread_arch.h"
4556 "musl/arch/aarch64/crt_arch.h"
4557 "musl/arch/aarch64/reloc.h"
4558 "musl/arch/aarch64/syscall_arch.h"
4559 "musl/arch/aarch64/atomic_arch.h"
4560 "musl/arch/aarch64/bits/float.h"
4561 "musl/arch/aarch64/bits/stdint.h"
4562 "musl/arch/aarch64/bits/reg.h"
4563 "musl/arch/aarch64/bits/ipc.h"
4564 "musl/arch/aarch64/bits/fenv.h"
4565 "musl/arch/aarch64/bits/msg.h"
4566 "musl/arch/aarch64/bits/posix.h"
4567 "musl/arch/aarch64/bits/setjmp.h"
4568 "musl/arch/aarch64/bits/alltypes.h.in"
4569 "musl/arch/aarch64/bits/syscall.h.in"
4570 "musl/arch/aarch64/bits/shm.h"
4571 "musl/arch/aarch64/bits/hwcap.h"
4572 "musl/arch/aarch64/bits/endian.h"
4573 "musl/arch/aarch64/bits/limits.h"
4574 "musl/arch/aarch64/bits/fcntl.h"
4575 "musl/arch/aarch64/bits/signal.h"
4576 "musl/arch/aarch64/bits/stat.h"
4577 "musl/arch/aarch64/bits/user.h"
4578 "musl/arch/aarch64/bits/sem.h"
4579 "musl/arch/aarch64/bits/socket.h"
4580 "musl/arch/powerpc/pthread_arch.h"
4581 "musl/arch/powerpc/crt_arch.h"
4582 "musl/arch/powerpc/reloc.h"
4583 "musl/arch/powerpc/syscall_arch.h"
4584 "musl/arch/powerpc/atomic_arch.h"
4585 "musl/arch/powerpc/bits/float.h"
4586 "musl/arch/powerpc/bits/errno.h"
4587 "musl/arch/powerpc/bits/mman.h"
4588 "musl/arch/powerpc/bits/stdint.h"
4589 "musl/arch/powerpc/bits/termios.h"
4590 "musl/arch/powerpc/bits/reg.h"
4591 "musl/arch/powerpc/bits/ipc.h"
4592 "musl/arch/powerpc/bits/fenv.h"
4593 "musl/arch/powerpc/bits/msg.h"
4594 "musl/arch/powerpc/bits/ptrace.h"
4595 "musl/arch/powerpc/bits/posix.h"
4596 "musl/arch/powerpc/bits/setjmp.h"
4597 "musl/arch/powerpc/bits/alltypes.h.in"
4598 "musl/arch/powerpc/bits/syscall.h.in"
4599 "musl/arch/powerpc/bits/shm.h"
4600 "musl/arch/powerpc/bits/hwcap.h"
4601 "musl/arch/powerpc/bits/endian.h"
4602 "musl/arch/powerpc/bits/limits.h"
4603 "musl/arch/powerpc/bits/ioctl.h"
4604 "musl/arch/powerpc/bits/fcntl.h"
4605 "musl/arch/powerpc/bits/signal.h"
4606 "musl/arch/powerpc/bits/stat.h"
4607 "musl/arch/powerpc/bits/user.h"
4608 "musl/arch/powerpc/bits/sem.h"
4609 "musl/arch/powerpc/bits/socket.h"
6371 "musl/arch/x86_64/crt_arch.h"
6372 "musl/arch/x86_64/ksigaction.h"
6373 "musl/arch/x86_64/pthread_arch.h"
6374 "musl/arch/x86_64/reloc.h"
6375 "musl/arch/x86_64/syscall_arch.h"
6376 "musl/crt/Scrt1.c"
6377 "musl/crt/aarch64/crti.s"
6378 "musl/crt/aarch64/crtn.s"
6379 "musl/crt/arm/crti.s"
6380 "musl/crt/arm/crtn.s"
6381 "musl/crt/crt1.c"
6382 "musl/crt/crti.c"
6383 "musl/crt/crtn.c"
6384 "musl/crt/i386/crti.s"
6385 "musl/crt/i386/crtn.s"
6386 "musl/crt/microblaze/crti.s"
6387 "musl/crt/microblaze/crtn.s"
6388 "musl/crt/mips/crti.s"
6389 "musl/crt/mips/crtn.s"
6390 "musl/crt/mips64/crti.s"
6391 "musl/crt/mips64/crtn.s"
6392 "musl/crt/mipsn32/crti.s"
6393 "musl/crt/mipsn32/crtn.s"
6394 "musl/crt/or1k/crti.s"
6395 "musl/crt/or1k/crtn.s"
6396 "musl/crt/powerpc/crti.s"
6397 "musl/crt/powerpc/crtn.s"
6398 "musl/crt/powerpc64/crti.s"
6399 "musl/crt/powerpc64/crtn.s"
6400 "musl/crt/rcrt1.c"
6401 "musl/crt/s390x/crti.s"
6402 "musl/crt/s390x/crtn.s"
6403 "musl/crt/sh/crti.s"
6404 "musl/crt/sh/crtn.s"
6405 "musl/crt/x32/crti.s"
6406 "musl/crt/x32/crtn.s"
6407 "musl/crt/x86_64/crti.s"
6408 "musl/crt/x86_64/crtn.s"
6409 ${ZIG_MUSL_SRC_FILES}
46106410)
46116411
46126412set(ZIG_LIBUNWIND_FILES
......@@ -4836,10 +6636,13 @@ set(LIBC_FILES_DEST "${ZIG_LIB_DIR}/libc")
48366636set(LIBUNWIND_FILES_DEST "${ZIG_LIB_DIR}/libunwind")
48376637set(LIBCXX_FILES_DEST "${ZIG_LIB_DIR}/libcxx")
48386638set(ZIG_STD_DEST "${ZIG_LIB_DIR}/std")
4839set(CONFIGURE_OUT_FILE "${CMAKE_BINARY_DIR}/config.h")
48406639configure_file (
48416640 "${CMAKE_SOURCE_DIR}/src/config.h.in"
4842 ${CONFIGURE_OUT_FILE}
6641 "${CMAKE_BINARY_DIR}/config.h"
6642)
6643configure_file (
6644 "${CMAKE_SOURCE_DIR}/src/install_files.h.in"
6645 "${CMAKE_BINARY_DIR}/install_files.h"
48436646)
48446647
48456648include_directories(
libc/musl/src/aio/aio.c created+400
......@@ -0,0 +1,400 @@
1#include <aio.h>
2#include <pthread.h>
3#include <semaphore.h>
4#include <limits.h>
5#include <errno.h>
6#include <unistd.h>
7#include <stdlib.h>
8#include <sys/auxv.h>
9#include "syscall.h"
10#include "atomic.h"
11#include "pthread_impl.h"
12
13/* The following is a threads-based implementation of AIO with minimal
14 * dependence on implementation details. Most synchronization is
15 * performed with pthread primitives, but atomics and futex operations
16 * are used for notification in a couple places where the pthread
17 * primitives would be inefficient or impractical.
18 *
19 * For each fd with outstanding aio operations, an aio_queue structure
20 * is maintained. These are reference-counted and destroyed by the last
21 * aio worker thread to exit. Accessing any member of the aio_queue
22 * structure requires a lock on the aio_queue. Adding and removing aio
23 * queues themselves requires a write lock on the global map object,
24 * a 4-level table mapping file descriptor numbers to aio queues. A
25 * read lock on the map is used to obtain locks on existing queues by
26 * excluding destruction of the queue by a different thread while it is
27 * being locked.
28 *
29 * Each aio queue has a list of active threads/operations. Presently there
30 * is a one to one relationship between threads and operations. The only
31 * members of the aio_thread structure which are accessed by other threads
32 * are the linked list pointers, op (which is immutable), running (which
33 * is updated atomically), and err (which is synchronized via running),
34 * so no locking is necessary. Most of the other other members are used
35 * for sharing data between the main flow of execution and cancellation
36 * cleanup handler.
37 *
38 * Taking any aio locks requires having all signals blocked. This is
39 * necessary because aio_cancel is needed by close, and close is required
40 * to be async-signal safe. All aio worker threads run with all signals
41 * blocked permanently.
42 */
43
44struct aio_thread {
45 pthread_t td;
46 struct aiocb *cb;
47 struct aio_thread *next, *prev;
48 struct aio_queue *q;
49 volatile int running;
50 int err, op;
51 ssize_t ret;
52};
53
54struct aio_queue {
55 int fd, seekable, append, ref, init;
56 pthread_mutex_t lock;
57 pthread_cond_t cond;
58 struct aio_thread *head;
59};
60
61struct aio_args {
62 struct aiocb *cb;
63 struct aio_queue *q;
64 int op;
65 sem_t sem;
66};
67
68static pthread_rwlock_t maplock = PTHREAD_RWLOCK_INITIALIZER;
69static struct aio_queue *****map;
70static volatile int aio_fd_cnt;
71volatile int __aio_fut;
72
73static struct aio_queue *__aio_get_queue(int fd, int need)
74{
75 if (fd < 0) {
76 errno = EBADF;
77 return 0;
78 }
79 int a=fd>>24;
80 unsigned char b=fd>>16, c=fd>>8, d=fd;
81 struct aio_queue *q = 0;
82 pthread_rwlock_rdlock(&maplock);
83 if ((!map || !map[a] || !map[a][b] || !map[a][b][c] || !(q=map[a][b][c][d])) && need) {
84 pthread_rwlock_unlock(&maplock);
85 if (fcntl(fd, F_GETFD) < 0) return 0;
86 pthread_rwlock_wrlock(&maplock);
87 if (!map) map = calloc(sizeof *map, (-1U/2+1)>>24);
88 if (!map) goto out;
89 if (!map[a]) map[a] = calloc(sizeof **map, 256);
90 if (!map[a]) goto out;
91 if (!map[a][b]) map[a][b] = calloc(sizeof ***map, 256);
92 if (!map[a][b]) goto out;
93 if (!map[a][b][c]) map[a][b][c] = calloc(sizeof ****map, 256);
94 if (!map[a][b][c]) goto out;
95 if (!(q = map[a][b][c][d])) {
96 map[a][b][c][d] = q = calloc(sizeof *****map, 1);
97 if (q) {
98 q->fd = fd;
99 pthread_mutex_init(&q->lock, 0);
100 pthread_cond_init(&q->cond, 0);
101 a_inc(&aio_fd_cnt);
102 }
103 }
104 }
105 if (q) pthread_mutex_lock(&q->lock);
106out:
107 pthread_rwlock_unlock(&maplock);
108 return q;
109}
110
111static void __aio_unref_queue(struct aio_queue *q)
112{
113 if (q->ref > 1) {
114 q->ref--;
115 pthread_mutex_unlock(&q->lock);
116 return;
117 }
118
119 /* This is potentially the last reference, but a new reference
120 * may arrive since we cannot free the queue object without first
121 * taking the maplock, which requires releasing the queue lock. */
122 pthread_mutex_unlock(&q->lock);
123 pthread_rwlock_wrlock(&maplock);
124 pthread_mutex_lock(&q->lock);
125 if (q->ref == 1) {
126 int fd=q->fd;
127 int a=fd>>24;
128 unsigned char b=fd>>16, c=fd>>8, d=fd;
129 map[a][b][c][d] = 0;
130 a_dec(&aio_fd_cnt);
131 pthread_rwlock_unlock(&maplock);
132 pthread_mutex_unlock(&q->lock);
133 free(q);
134 } else {
135 q->ref--;
136 pthread_rwlock_unlock(&maplock);
137 pthread_mutex_unlock(&q->lock);
138 }
139}
140
141static void cleanup(void *ctx)
142{
143 struct aio_thread *at = ctx;
144 struct aio_queue *q = at->q;
145 struct aiocb *cb = at->cb;
146 struct sigevent sev = cb->aio_sigevent;
147
148 /* There are four potential types of waiters we could need to wake:
149 * 1. Callers of aio_cancel/close.
150 * 2. Callers of aio_suspend with a single aiocb.
151 * 3. Callers of aio_suspend with a list.
152 * 4. AIO worker threads waiting for sequenced operations.
153 * Types 1-3 are notified via atomics/futexes, mainly for AS-safety
154 * considerations. Type 4 is notified later via a cond var. */
155
156 cb->__ret = at->ret;
157 if (a_swap(&at->running, 0) < 0)
158 __wake(&at->running, -1, 1);
159 if (a_swap(&cb->__err, at->err) != EINPROGRESS)
160 __wake(&cb->__err, -1, 1);
161 if (a_swap(&__aio_fut, 0))
162 __wake(&__aio_fut, -1, 1);
163
164 pthread_mutex_lock(&q->lock);
165
166 if (at->next) at->next->prev = at->prev;
167 if (at->prev) at->prev->next = at->next;
168 else q->head = at->next;
169
170 /* Signal aio worker threads waiting for sequenced operations. */
171 pthread_cond_broadcast(&q->cond);
172
173 __aio_unref_queue(q);
174
175 if (sev.sigev_notify == SIGEV_SIGNAL) {
176 siginfo_t si = {
177 .si_signo = sev.sigev_signo,
178 .si_value = sev.sigev_value,
179 .si_code = SI_ASYNCIO,
180 .si_pid = getpid(),
181 .si_uid = getuid()
182 };
183 __syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si);
184 }
185 if (sev.sigev_notify == SIGEV_THREAD) {
186 a_store(&__pthread_self()->cancel, 0);
187 sev.sigev_notify_function(sev.sigev_value);
188 }
189}
190
191static void *io_thread_func(void *ctx)
192{
193 struct aio_thread at, *p;
194
195 struct aio_args *args = ctx;
196 struct aiocb *cb = args->cb;
197 int fd = cb->aio_fildes;
198 int op = args->op;
199 void *buf = (void *)cb->aio_buf;
200 size_t len = cb->aio_nbytes;
201 off_t off = cb->aio_offset;
202
203 struct aio_queue *q = args->q;
204 ssize_t ret;
205
206 pthread_mutex_lock(&q->lock);
207 sem_post(&args->sem);
208
209 at.op = op;
210 at.running = 1;
211 at.ret = -1;
212 at.err = ECANCELED;
213 at.q = q;
214 at.td = __pthread_self();
215 at.cb = cb;
216 at.prev = 0;
217 if ((at.next = q->head)) at.next->prev = &at;
218 q->head = &at;
219
220 if (!q->init) {
221 int seekable = lseek(fd, 0, SEEK_CUR) >= 0;
222 q->seekable = seekable;
223 q->append = !seekable || (fcntl(fd, F_GETFL) & O_APPEND);
224 q->init = 1;
225 }
226
227 pthread_cleanup_push(cleanup, &at);
228
229 /* Wait for sequenced operations. */
230 if (op!=LIO_READ && (op!=LIO_WRITE || q->append)) {
231 for (;;) {
232 for (p=at.next; p && p->op!=LIO_WRITE; p=p->next);
233 if (!p) break;
234 pthread_cond_wait(&q->cond, &q->lock);
235 }
236 }
237
238 pthread_mutex_unlock(&q->lock);
239
240 switch (op) {
241 case LIO_WRITE:
242 ret = q->append ? write(fd, buf, len) : pwrite(fd, buf, len, off);
243 break;
244 case LIO_READ:
245 ret = !q->seekable ? read(fd, buf, len) : pread(fd, buf, len, off);
246 break;
247 case O_SYNC:
248 ret = fsync(fd);
249 break;
250 case O_DSYNC:
251 ret = fdatasync(fd);
252 break;
253 }
254 at.ret = ret;
255 at.err = ret<0 ? errno : 0;
256
257 pthread_cleanup_pop(1);
258
259 return 0;
260}
261
262static size_t io_thread_stack_size = MINSIGSTKSZ+2048;
263static pthread_once_t init_stack_size_once;
264
265static void init_stack_size()
266{
267 unsigned long val = __getauxval(AT_MINSIGSTKSZ);
268 if (val > MINSIGSTKSZ) io_thread_stack_size = val + 512;
269}
270
271static int submit(struct aiocb *cb, int op)
272{
273 int ret = 0;
274 pthread_attr_t a;
275 sigset_t allmask, origmask;
276 pthread_t td;
277 struct aio_queue *q = __aio_get_queue(cb->aio_fildes, 1);
278 struct aio_args args = { .cb = cb, .op = op, .q = q };
279 sem_init(&args.sem, 0, 0);
280
281 if (!q) {
282 if (errno != EBADF) errno = EAGAIN;
283 cb->__ret = -1;
284 cb->__err = errno;
285 return -1;
286 }
287 q->ref++;
288 pthread_mutex_unlock(&q->lock);
289
290 if (cb->aio_sigevent.sigev_notify == SIGEV_THREAD) {
291 if (cb->aio_sigevent.sigev_notify_attributes)
292 a = *cb->aio_sigevent.sigev_notify_attributes;
293 else
294 pthread_attr_init(&a);
295 } else {
296 pthread_once(&init_stack_size_once, init_stack_size);
297 pthread_attr_init(&a);
298 pthread_attr_setstacksize(&a, io_thread_stack_size);
299 pthread_attr_setguardsize(&a, 0);
300 }
301 pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
302 sigfillset(&allmask);
303 pthread_sigmask(SIG_BLOCK, &allmask, &origmask);
304 cb->__err = EINPROGRESS;
305 if (pthread_create(&td, &a, io_thread_func, &args)) {
306 pthread_mutex_lock(&q->lock);
307 __aio_unref_queue(q);
308 cb->__err = errno = EAGAIN;
309 cb->__ret = ret = -1;
310 }
311 pthread_sigmask(SIG_SETMASK, &origmask, 0);
312
313 if (!ret) {
314 while (sem_wait(&args.sem));
315 }
316
317 return ret;
318}
319
320int aio_read(struct aiocb *cb)
321{
322 return submit(cb, LIO_READ);
323}
324
325int aio_write(struct aiocb *cb)
326{
327 return submit(cb, LIO_WRITE);
328}
329
330int aio_fsync(int op, struct aiocb *cb)
331{
332 if (op != O_SYNC && op != O_DSYNC) {
333 errno = EINVAL;
334 return -1;
335 }
336 return submit(cb, op);
337}
338
339ssize_t aio_return(struct aiocb *cb)
340{
341 return cb->__ret;
342}
343
344int aio_error(const struct aiocb *cb)
345{
346 a_barrier();
347 return cb->__err & 0x7fffffff;
348}
349
350int aio_cancel(int fd, struct aiocb *cb)
351{
352 sigset_t allmask, origmask;
353 int ret = AIO_ALLDONE;
354 struct aio_thread *p;
355 struct aio_queue *q;
356
357 /* Unspecified behavior case. Report an error. */
358 if (cb && fd != cb->aio_fildes) {
359 errno = EINVAL;
360 return -1;
361 }
362
363 sigfillset(&allmask);
364 pthread_sigmask(SIG_BLOCK, &allmask, &origmask);
365
366 errno = ENOENT;
367 if (!(q = __aio_get_queue(fd, 0))) {
368 if (errno == EBADF) ret = -1;
369 goto done;
370 }
371
372 for (p = q->head; p; p = p->next) {
373 if (cb && cb != p->cb) continue;
374 /* Transition target from running to running-with-waiters */
375 if (a_cas(&p->running, 1, -1)) {
376 pthread_cancel(p->td);
377 __wait(&p->running, 0, -1, 1);
378 if (p->err == ECANCELED) ret = AIO_CANCELED;
379 }
380 }
381
382 pthread_mutex_unlock(&q->lock);
383done:
384 pthread_sigmask(SIG_SETMASK, &origmask, 0);
385 return ret;
386}
387
388int __aio_close(int fd)
389{
390 a_barrier();
391 if (aio_fd_cnt) aio_cancel(fd, 0);
392 return fd;
393}
394
395weak_alias(aio_cancel, aio_cancel64);
396weak_alias(aio_error, aio_error64);
397weak_alias(aio_fsync, aio_fsync64);
398weak_alias(aio_read, aio_read64);
399weak_alias(aio_write, aio_write64);
400weak_alias(aio_return, aio_return64);
libc/musl/src/aio/aio_suspend.c created+76
......@@ -0,0 +1,76 @@
1#include <aio.h>
2#include <errno.h>
3#include <time.h>
4#include "atomic.h"
5#include "pthread_impl.h"
6
7int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec *ts)
8{
9 int i, tid = 0, ret, expect = 0;
10 struct timespec at;
11 volatile int dummy_fut, *pfut;
12 int nzcnt = 0;
13 const struct aiocb *cb = 0;
14
15 pthread_testcancel();
16
17 if (cnt<0) {
18 errno = EINVAL;
19 return -1;
20 }
21
22 for (i=0; i<cnt; i++) if (cbs[i]) {
23 if (aio_error(cbs[i]) != EINPROGRESS) return 0;
24 nzcnt++;
25 cb = cbs[i];
26 }
27
28 if (ts) {
29 clock_gettime(CLOCK_MONOTONIC, &at);
30 at.tv_sec += ts->tv_sec;
31 if ((at.tv_nsec += ts->tv_nsec) >= 1000000000) {
32 at.tv_nsec -= 1000000000;
33 at.tv_sec++;
34 }
35 }
36
37 for (;;) {
38 for (i=0; i<cnt; i++)
39 if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS)
40 return 0;
41
42 switch (nzcnt) {
43 case 0:
44 pfut = &dummy_fut;
45 break;
46 case 1:
47 pfut = (void *)&cb->__err;
48 expect = EINPROGRESS | 0x80000000;
49 a_cas(pfut, EINPROGRESS, expect);
50 break;
51 default:
52 pfut = &__aio_fut;
53 if (!tid) tid = __pthread_self()->tid;
54 expect = a_cas(pfut, 0, tid);
55 if (!expect) expect = tid;
56 /* Need to recheck the predicate before waiting. */
57 for (i=0; i<cnt; i++)
58 if (cbs[i] && aio_error(cbs[i]) != EINPROGRESS)
59 return 0;
60 break;
61 }
62
63 ret = __timedwait_cp(pfut, expect, CLOCK_MONOTONIC, ts?&at:0, 1);
64
65 switch (ret) {
66 case ETIMEDOUT:
67 ret = EAGAIN;
68 case ECANCELED:
69 case EINTR:
70 errno = ret;
71 return -1;
72 }
73 }
74}
75
76weak_alias(aio_suspend, aio_suspend64);
libc/musl/src/aio/lio_listio.c created+143
......@@ -0,0 +1,143 @@
1#include <aio.h>
2#include <errno.h>
3#include <unistd.h>
4#include <string.h>
5#include "pthread_impl.h"
6
7struct lio_state {
8 struct sigevent *sev;
9 int cnt;
10 struct aiocb *cbs[];
11};
12
13static int lio_wait(struct lio_state *st)
14{
15 int i, err, got_err = 0;
16 int cnt = st->cnt;
17 struct aiocb **cbs = st->cbs;
18
19 for (;;) {
20 for (i=0; i<cnt; i++) {
21 if (!cbs[i]) continue;
22 err = aio_error(cbs[i]);
23 if (err==EINPROGRESS)
24 break;
25 if (err) got_err=1;
26 cbs[i] = 0;
27 }
28 if (i==cnt) {
29 if (got_err) {
30 errno = EIO;
31 return -1;
32 }
33 return 0;
34 }
35 if (aio_suspend((void *)cbs, cnt, 0))
36 return -1;
37 }
38}
39
40static void notify_signal(struct sigevent *sev)
41{
42 siginfo_t si = {
43 .si_signo = sev->sigev_signo,
44 .si_value = sev->sigev_value,
45 .si_code = SI_ASYNCIO,
46 .si_pid = getpid(),
47 .si_uid = getuid()
48 };
49 __syscall(SYS_rt_sigqueueinfo, si.si_pid, si.si_signo, &si);
50}
51
52static void *wait_thread(void *p)
53{
54 struct lio_state *st = p;
55 struct sigevent *sev = st->sev;
56 lio_wait(st);
57 free(st);
58 switch (sev->sigev_notify) {
59 case SIGEV_SIGNAL:
60 notify_signal(sev);
61 break;
62 case SIGEV_THREAD:
63 sev->sigev_notify_function(sev->sigev_value);
64 break;
65 }
66 return 0;
67}
68
69int lio_listio(int mode, struct aiocb *restrict const *restrict cbs, int cnt, struct sigevent *restrict sev)
70{
71 int i, ret;
72 struct lio_state *st=0;
73
74 if (cnt < 0) {
75 errno = EINVAL;
76 return -1;
77 }
78
79 if (mode == LIO_WAIT || (sev && sev->sigev_notify != SIGEV_NONE)) {
80 if (!(st = malloc(sizeof *st + cnt*sizeof *cbs))) {
81 errno = EAGAIN;
82 return -1;
83 }
84 st->cnt = cnt;
85 st->sev = sev;
86 memcpy(st->cbs, (void*) cbs, cnt*sizeof *cbs);
87 }
88
89 for (i=0; i<cnt; i++) {
90 if (!cbs[i]) continue;
91 switch (cbs[i]->aio_lio_opcode) {
92 case LIO_READ:
93 ret = aio_read(cbs[i]);
94 break;
95 case LIO_WRITE:
96 ret = aio_write(cbs[i]);
97 break;
98 default:
99 continue;
100 }
101 if (ret) {
102 free(st);
103 errno = EAGAIN;
104 return -1;
105 }
106 }
107
108 if (mode == LIO_WAIT) {
109 ret = lio_wait(st);
110 free(st);
111 return ret;
112 }
113
114 if (st) {
115 pthread_attr_t a;
116 sigset_t set;
117 pthread_t td;
118
119 if (sev->sigev_notify == SIGEV_THREAD) {
120 if (sev->sigev_notify_attributes)
121 a = *sev->sigev_notify_attributes;
122 else
123 pthread_attr_init(&a);
124 } else {
125 pthread_attr_init(&a);
126 pthread_attr_setstacksize(&a, PAGE_SIZE);
127 pthread_attr_setguardsize(&a, 0);
128 }
129 pthread_attr_setdetachstate(&a, PTHREAD_CREATE_DETACHED);
130 sigfillset(&set);
131 pthread_sigmask(SIG_BLOCK, &set, &set);
132 if (pthread_create(&td, &a, wait_thread, st)) {
133 free(st);
134 errno = EAGAIN;
135 return -1;
136 }
137 pthread_sigmask(SIG_SETMASK, &set, 0);
138 }
139
140 return 0;
141}
142
143weak_alias(lio_listio, lio_listio64);
libc/musl/src/complex/__cexp.c created+87
......@@ -0,0 +1,87 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/k_exp.c */
2/*-
3 * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "libm.h"
29
30static const uint32_t k = 1799; /* constant for reduction */
31static const double kln2 = 1246.97177782734161156; /* k * ln2 */
32
33/*
34 * Compute exp(x), scaled to avoid spurious overflow. An exponent is
35 * returned separately in 'expt'.
36 *
37 * Input: ln(DBL_MAX) <= x < ln(2 * DBL_MAX / DBL_MIN_DENORM) ~= 1454.91
38 * Output: 2**1023 <= y < 2**1024
39 */
40static double __frexp_exp(double x, int *expt)
41{
42 double exp_x;
43 uint32_t hx;
44
45 /*
46 * We use exp(x) = exp(x - kln2) * 2**k, carefully chosen to
47 * minimize |exp(kln2) - 2**k|. We also scale the exponent of
48 * exp_x to MAX_EXP so that the result can be multiplied by
49 * a tiny number without losing accuracy due to denormalization.
50 */
51 exp_x = exp(x - kln2);
52 GET_HIGH_WORD(hx, exp_x);
53 *expt = (hx >> 20) - (0x3ff + 1023) + k;
54 SET_HIGH_WORD(exp_x, (hx & 0xfffff) | ((0x3ff + 1023) << 20));
55 return exp_x;
56}
57
58/*
59 * __ldexp_cexp(x, expt) compute exp(x) * 2**expt.
60 * It is intended for large arguments (real part >= ln(DBL_MAX))
61 * where care is needed to avoid overflow.
62 *
63 * The present implementation is narrowly tailored for our hyperbolic and
64 * exponential functions. We assume expt is small (0 or -1), and the caller
65 * has filtered out very large x, for which overflow would be inevitable.
66 */
67double complex __ldexp_cexp(double complex z, int expt)
68{
69 double x, y, exp_x, scale1, scale2;
70 int ex_expt, half_expt;
71
72 x = creal(z);
73 y = cimag(z);
74 exp_x = __frexp_exp(x, &ex_expt);
75 expt += ex_expt;
76
77 /*
78 * Arrange so that scale1 * scale2 == 2**expt. We use this to
79 * compensate for scalbn being horrendously slow.
80 */
81 half_expt = expt / 2;
82 INSERT_WORDS(scale1, (0x3ff + half_expt) << 20, 0);
83 half_expt = expt - half_expt;
84 INSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0);
85
86 return CMPLX(cos(y) * exp_x * scale1 * scale2, sin(y) * exp_x * scale1 * scale2);
87}
libc/musl/src/complex/__cexpf.c created+68
......@@ -0,0 +1,68 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/k_expf.c */
2/*-
3 * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "libm.h"
29
30static const uint32_t k = 235; /* constant for reduction */
31static const float kln2 = 162.88958740F; /* k * ln2 */
32
33/*
34 * See __cexp.c for details.
35 *
36 * Input: ln(FLT_MAX) <= x < ln(2 * FLT_MAX / FLT_MIN_DENORM) ~= 192.7
37 * Output: 2**127 <= y < 2**128
38 */
39static float __frexp_expf(float x, int *expt)
40{
41 float exp_x;
42 uint32_t hx;
43
44 exp_x = expf(x - kln2);
45 GET_FLOAT_WORD(hx, exp_x);
46 *expt = (hx >> 23) - (0x7f + 127) + k;
47 SET_FLOAT_WORD(exp_x, (hx & 0x7fffff) | ((0x7f + 127) << 23));
48 return exp_x;
49}
50
51float complex __ldexp_cexpf(float complex z, int expt)
52{
53 float x, y, exp_x, scale1, scale2;
54 int ex_expt, half_expt;
55
56 x = crealf(z);
57 y = cimagf(z);
58 exp_x = __frexp_expf(x, &ex_expt);
59 expt += ex_expt;
60
61 half_expt = expt / 2;
62 SET_FLOAT_WORD(scale1, (0x7f + half_expt) << 23);
63 half_expt = expt - half_expt;
64 SET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23);
65
66 return CMPLXF(cosf(y) * exp_x * scale1 * scale2,
67 sinf(y) * exp_x * scale1 * scale2);
68}
libc/musl/src/complex/cabs.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3double cabs(double complex z)
4{
5 return hypot(creal(z), cimag(z));
6}
libc/musl/src/complex/cabsf.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3float cabsf(float complex z)
4{
5 return hypotf(crealf(z), cimagf(z));
6}
libc/musl/src/complex/cabsl.c created+13
......@@ -0,0 +1,13 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double cabsl(long double complex z)
5{
6 return cabs(z);
7}
8#else
9long double cabsl(long double complex z)
10{
11 return hypotl(creall(z), cimagl(z));
12}
13#endif
libc/musl/src/complex/cacos.c created+11
......@@ -0,0 +1,11 @@
1#include "libm.h"
2
3// FIXME: Hull et al. "Implementing the complex arcsine and arccosine functions using exception handling" 1997
4
5/* acos(z) = pi/2 - asin(z) */
6
7double complex cacos(double complex z)
8{
9 z = casin(z);
10 return CMPLX(M_PI_2 - creal(z), -cimag(z));
11}
libc/musl/src/complex/cacosf.c created+9
......@@ -0,0 +1,9 @@
1#include "libm.h"
2
3// FIXME
4
5float complex cacosf(float complex z)
6{
7 z = casinf(z);
8 return CMPLXF((float)M_PI_2 - crealf(z), -cimagf(z));
9}
libc/musl/src/complex/cacosh.c created+9
......@@ -0,0 +1,9 @@
1#include "libm.h"
2
3/* acosh(z) = i acos(z) */
4
5double complex cacosh(double complex z)
6{
7 z = cacos(z);
8 return CMPLX(-cimag(z), creal(z));
9}
libc/musl/src/complex/cacoshf.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3float complex cacoshf(float complex z)
4{
5 z = cacosf(z);
6 return CMPLXF(-cimagf(z), crealf(z));
7}
libc/musl/src/complex/cacoshl.c created+14
......@@ -0,0 +1,14 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex cacoshl(long double complex z)
5{
6 return cacosh(z);
7}
8#else
9long double complex cacoshl(long double complex z)
10{
11 z = cacosl(z);
12 return CMPLXL(-cimagl(z), creall(z));
13}
14#endif
libc/musl/src/complex/cacosl.c created+16
......@@ -0,0 +1,16 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex cacosl(long double complex z)
5{
6 return cacos(z);
7}
8#else
9// FIXME
10#define PI_2 1.57079632679489661923132169163975144L
11long double complex cacosl(long double complex z)
12{
13 z = casinl(z);
14 return CMPLXL(PI_2 - creall(z), -cimagl(z));
15}
16#endif
libc/musl/src/complex/carg.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3double carg(double complex z)
4{
5 return atan2(cimag(z), creal(z));
6}
libc/musl/src/complex/cargf.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3float cargf(float complex z)
4{
5 return atan2f(cimagf(z), crealf(z));
6}
libc/musl/src/complex/cargl.c created+13
......@@ -0,0 +1,13 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double cargl(long double complex z)
5{
6 return carg(z);
7}
8#else
9long double cargl(long double complex z)
10{
11 return atan2l(cimagl(z), creall(z));
12}
13#endif
libc/musl/src/complex/casin.c created+17
......@@ -0,0 +1,17 @@
1#include "libm.h"
2
3// FIXME
4
5/* asin(z) = -i log(i z + sqrt(1 - z*z)) */
6
7double complex casin(double complex z)
8{
9 double complex w;
10 double x, y;
11
12 x = creal(z);
13 y = cimag(z);
14 w = CMPLX(1.0 - (x - y)*(x + y), -2.0*x*y);
15 double complex r = clog(CMPLX(-y, x) + csqrt(w));
16 return CMPLX(cimag(r), -creal(r));
17}
libc/musl/src/complex/casinf.c created+15
......@@ -0,0 +1,15 @@
1#include "libm.h"
2
3// FIXME
4
5float complex casinf(float complex z)
6{
7 float complex w;
8 float x, y;
9
10 x = crealf(z);
11 y = cimagf(z);
12 w = CMPLXF(1.0 - (x - y)*(x + y), -2.0*x*y);
13 float complex r = clogf(CMPLXF(-y, x) + csqrtf(w));
14 return CMPLXF(cimagf(r), -crealf(r));
15}
libc/musl/src/complex/casinh.c created+9
......@@ -0,0 +1,9 @@
1#include "libm.h"
2
3/* asinh(z) = -i asin(i z) */
4
5double complex casinh(double complex z)
6{
7 z = casin(CMPLX(-cimag(z), creal(z)));
8 return CMPLX(cimag(z), -creal(z));
9}
libc/musl/src/complex/casinhf.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3float complex casinhf(float complex z)
4{
5 z = casinf(CMPLXF(-cimagf(z), crealf(z)));
6 return CMPLXF(cimagf(z), -crealf(z));
7}
libc/musl/src/complex/casinhl.c created+14
......@@ -0,0 +1,14 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex casinhl(long double complex z)
5{
6 return casinh(z);
7}
8#else
9long double complex casinhl(long double complex z)
10{
11 z = casinl(CMPLXL(-cimagl(z), creall(z)));
12 return CMPLXL(cimagl(z), -creall(z));
13}
14#endif
libc/musl/src/complex/casinl.c created+21
......@@ -0,0 +1,21 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex casinl(long double complex z)
5{
6 return casin(z);
7}
8#else
9// FIXME
10long double complex casinl(long double complex z)
11{
12 long double complex w;
13 long double x, y;
14
15 x = creall(z);
16 y = cimagl(z);
17 w = CMPLXL(1.0 - (x - y)*(x + y), -2.0*x*y);
18 long double complex r = clogl(CMPLXL(-y, x) + csqrtl(w));
19 return CMPLXL(cimagl(r), -creall(r));
20}
21#endif
libc/musl/src/complex/catan.c created+107
......@@ -0,0 +1,107 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/s_catan.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Complex circular arc tangent
19 *
20 *
21 * SYNOPSIS:
22 *
23 * double complex catan();
24 * double complex z, w;
25 *
26 * w = catan (z);
27 *
28 *
29 * DESCRIPTION:
30 *
31 * If
32 * z = x + iy,
33 *
34 * then
35 * 1 ( 2x )
36 * Re w = - arctan(-----------) + k PI
37 * 2 ( 2 2)
38 * (1 - x - y )
39 *
40 * ( 2 2)
41 * 1 (x + (y+1) )
42 * Im w = - log(------------)
43 * 4 ( 2 2)
44 * (x + (y-1) )
45 *
46 * Where k is an arbitrary integer.
47 *
48 * catan(z) = -i catanh(iz).
49 *
50 * ACCURACY:
51 *
52 * Relative error:
53 * arithmetic domain # trials peak rms
54 * DEC -10,+10 5900 1.3e-16 7.8e-18
55 * IEEE -10,+10 30000 2.3e-15 8.5e-17
56 * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2,
57 * had peak relative error 1.5e-16, rms relative error
58 * 2.9e-17. See also clog().
59 */
60
61#include "libm.h"
62
63#define MAXNUM 1.0e308
64
65static const double DP1 = 3.14159265160560607910E0;
66static const double DP2 = 1.98418714791870343106E-9;
67static const double DP3 = 1.14423774522196636802E-17;
68
69static double _redupi(double x)
70{
71 double t;
72 long i;
73
74 t = x/M_PI;
75 if (t >= 0.0)
76 t += 0.5;
77 else
78 t -= 0.5;
79
80 i = t; /* the multiple */
81 t = i;
82 t = ((x - t * DP1) - t * DP2) - t * DP3;
83 return t;
84}
85
86double complex catan(double complex z)
87{
88 double complex w;
89 double a, t, x, x2, y;
90
91 x = creal(z);
92 y = cimag(z);
93
94 x2 = x * x;
95 a = 1.0 - x2 - (y * y);
96
97 t = 0.5 * atan2(2.0 * x, a);
98 w = _redupi(t);
99
100 t = y - 1.0;
101 a = x2 + (t * t);
102
103 t = y + 1.0;
104 a = (x2 + t * t)/a;
105 w = CMPLX(w, 0.25 * log(a));
106 return w;
107}
libc/musl/src/complex/catanf.c created+115
......@@ -0,0 +1,115 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/s_catanf.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Complex circular arc tangent
19 *
20 *
21 * SYNOPSIS:
22 *
23 * float complex catanf();
24 * float complex z, w;
25 *
26 * w = catanf( z );
27 *
28 *
29 * DESCRIPTION:
30 *
31 * If
32 * z = x + iy,
33 *
34 * then
35 * 1 ( 2x )
36 * Re w = - arctan(-----------) + k PI
37 * 2 ( 2 2)
38 * (1 - x - y )
39 *
40 * ( 2 2)
41 * 1 (x + (y+1) )
42 * Im w = - log(------------)
43 * 4 ( 2 2)
44 * (x + (y-1) )
45 *
46 * Where k is an arbitrary integer.
47 *
48 *
49 * ACCURACY:
50 *
51 * Relative error:
52 * arithmetic domain # trials peak rms
53 * IEEE -10,+10 30000 2.3e-6 5.2e-8
54 */
55
56#include "libm.h"
57
58#define MAXNUMF 1.0e38F
59
60static const double DP1 = 3.140625;
61static const double DP2 = 9.67502593994140625E-4;
62static const double DP3 = 1.509957990978376432E-7;
63
64static float _redupif(float xx)
65{
66 float x, t;
67 long i;
68
69 x = xx;
70 t = x/(float)M_PI;
71 if (t >= 0.0f)
72 t += 0.5f;
73 else
74 t -= 0.5f;
75
76 i = t; /* the multiple */
77 t = i;
78 t = ((x - t * DP1) - t * DP2) - t * DP3;
79 return t;
80}
81
82float complex catanf(float complex z)
83{
84 float complex w;
85 float a, t, x, x2, y;
86
87 x = crealf(z);
88 y = cimagf(z);
89
90 if ((x == 0.0f) && (y > 1.0f))
91 goto ovrf;
92
93 x2 = x * x;
94 a = 1.0f - x2 - (y * y);
95 if (a == 0.0f)
96 goto ovrf;
97
98 t = 0.5f * atan2f(2.0f * x, a);
99 w = _redupif(t);
100
101 t = y - 1.0f;
102 a = x2 + (t * t);
103 if (a == 0.0f)
104 goto ovrf;
105
106 t = y + 1.0f;
107 a = (x2 + (t * t))/a;
108 w = w + (0.25f * logf (a)) * I;
109 return w;
110
111ovrf:
112 // FIXME
113 w = MAXNUMF + MAXNUMF * I;
114 return w;
115}
libc/musl/src/complex/catanh.c created+9
......@@ -0,0 +1,9 @@
1#include "libm.h"
2
3/* atanh = -i atan(i z) */
4
5double complex catanh(double complex z)
6{
7 z = catan(CMPLX(-cimag(z), creal(z)));
8 return CMPLX(cimag(z), -creal(z));
9}
libc/musl/src/complex/catanhf.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3float complex catanhf(float complex z)
4{
5 z = catanf(CMPLXF(-cimagf(z), crealf(z)));
6 return CMPLXF(cimagf(z), -crealf(z));
7}
libc/musl/src/complex/catanhl.c created+14
......@@ -0,0 +1,14 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex catanhl(long double complex z)
5{
6 return catanh(z);
7}
8#else
9long double complex catanhl(long double complex z)
10{
11 z = catanl(CMPLXL(-cimagl(z), creall(z)));
12 return CMPLXL(cimagl(z), -creall(z));
13}
14#endif
libc/musl/src/complex/catanl.c created+126
......@@ -0,0 +1,126 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/s_catanl.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Complex circular arc tangent
19 *
20 *
21 * SYNOPSIS:
22 *
23 * long double complex catanl();
24 * long double complex z, w;
25 *
26 * w = catanl( z );
27 *
28 *
29 * DESCRIPTION:
30 *
31 * If
32 * z = x + iy,
33 *
34 * then
35 * 1 ( 2x )
36 * Re w = - arctan(-----------) + k PI
37 * 2 ( 2 2)
38 * (1 - x - y )
39 *
40 * ( 2 2)
41 * 1 (x + (y+1) )
42 * Im w = - log(------------)
43 * 4 ( 2 2)
44 * (x + (y-1) )
45 *
46 * Where k is an arbitrary integer.
47 *
48 *
49 * ACCURACY:
50 *
51 * Relative error:
52 * arithmetic domain # trials peak rms
53 * DEC -10,+10 5900 1.3e-16 7.8e-18
54 * IEEE -10,+10 30000 2.3e-15 8.5e-17
55 * The check catan( ctan(z) ) = z, with |x| and |y| < PI/2,
56 * had peak relative error 1.5e-16, rms relative error
57 * 2.9e-17. See also clog().
58 */
59
60#include <complex.h>
61#include <float.h>
62#include "libm.h"
63
64#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
65long double complex catanl(long double complex z)
66{
67 return catan(z);
68}
69#else
70static const long double PIL = 3.141592653589793238462643383279502884197169L;
71static const long double DP1 = 3.14159265358979323829596852490908531763125L;
72static const long double DP2 = 1.6667485837041756656403424829301998703007e-19L;
73static const long double DP3 = 1.8830410776607851167459095484560349402753e-39L;
74
75static long double redupil(long double x)
76{
77 long double t;
78 long i;
79
80 t = x / PIL;
81 if (t >= 0.0L)
82 t += 0.5L;
83 else
84 t -= 0.5L;
85
86 i = t; /* the multiple */
87 t = i;
88 t = ((x - t * DP1) - t * DP2) - t * DP3;
89 return t;
90}
91
92long double complex catanl(long double complex z)
93{
94 long double complex w;
95 long double a, t, x, x2, y;
96
97 x = creall(z);
98 y = cimagl(z);
99
100 if ((x == 0.0L) && (y > 1.0L))
101 goto ovrf;
102
103 x2 = x * x;
104 a = 1.0L - x2 - (y * y);
105 if (a == 0.0L)
106 goto ovrf;
107
108 t = atan2l(2.0L * x, a) * 0.5L;
109 w = redupil(t);
110
111 t = y - 1.0L;
112 a = x2 + (t * t);
113 if (a == 0.0L)
114 goto ovrf;
115
116 t = y + 1.0L;
117 a = (x2 + (t * t)) / a;
118 w = w + (0.25L * logl(a)) * I;
119 return w;
120
121ovrf:
122 // FIXME
123 w = LDBL_MAX + LDBL_MAX * I;
124 return w;
125}
126#endif
libc/musl/src/complex/ccos.c created+8
......@@ -0,0 +1,8 @@
1#include "libm.h"
2
3/* cos(z) = cosh(i z) */
4
5double complex ccos(double complex z)
6{
7 return ccosh(CMPLX(-cimag(z), creal(z)));
8}
libc/musl/src/complex/ccosf.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3float complex ccosf(float complex z)
4{
5 return ccoshf(CMPLXF(-cimagf(z), crealf(z)));
6}
libc/musl/src/complex/ccosh.c created+140
......@@ -0,0 +1,140 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_ccosh.c */
2/*-
3 * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/*
28 * Hyperbolic cosine of a complex argument z = x + i y.
29 *
30 * cosh(z) = cosh(x+iy)
31 * = cosh(x) cos(y) + i sinh(x) sin(y).
32 *
33 * Exceptional values are noted in the comments within the source code.
34 * These values and the return value were taken from n1124.pdf.
35 */
36
37#include "libm.h"
38
39static const double huge = 0x1p1023;
40
41double complex ccosh(double complex z)
42{
43 double x, y, h;
44 int32_t hx, hy, ix, iy, lx, ly;
45
46 x = creal(z);
47 y = cimag(z);
48
49 EXTRACT_WORDS(hx, lx, x);
50 EXTRACT_WORDS(hy, ly, y);
51
52 ix = 0x7fffffff & hx;
53 iy = 0x7fffffff & hy;
54
55 /* Handle the nearly-non-exceptional cases where x and y are finite. */
56 if (ix < 0x7ff00000 && iy < 0x7ff00000) {
57 if ((iy | ly) == 0)
58 return CMPLX(cosh(x), x * y);
59 if (ix < 0x40360000) /* small x: normal case */
60 return CMPLX(cosh(x) * cos(y), sinh(x) * sin(y));
61
62 /* |x| >= 22, so cosh(x) ~= exp(|x|) */
63 if (ix < 0x40862e42) {
64 /* x < 710: exp(|x|) won't overflow */
65 h = exp(fabs(x)) * 0.5;
66 return CMPLX(h * cos(y), copysign(h, x) * sin(y));
67 } else if (ix < 0x4096bbaa) {
68 /* x < 1455: scale to avoid overflow */
69 z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
70 return CMPLX(creal(z), cimag(z) * copysign(1, x));
71 } else {
72 /* x >= 1455: the result always overflows */
73 h = huge * x;
74 return CMPLX(h * h * cos(y), h * sin(y));
75 }
76 }
77
78 /*
79 * cosh(+-0 +- I Inf) = dNaN + I sign(d(+-0, dNaN))0.
80 * The sign of 0 in the result is unspecified. Choice = normally
81 * the same as dNaN. Raise the invalid floating-point exception.
82 *
83 * cosh(+-0 +- I NaN) = d(NaN) + I sign(d(+-0, NaN))0.
84 * The sign of 0 in the result is unspecified. Choice = normally
85 * the same as d(NaN).
86 */
87 if ((ix | lx) == 0 && iy >= 0x7ff00000)
88 return CMPLX(y - y, copysign(0, x * (y - y)));
89
90 /*
91 * cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0.
92 *
93 * cosh(NaN +- I 0) = d(NaN) + I sign(d(NaN, +-0))0.
94 * The sign of 0 in the result is unspecified.
95 */
96 if ((iy | ly) == 0 && ix >= 0x7ff00000) {
97 if (((hx & 0xfffff) | lx) == 0)
98 return CMPLX(x * x, copysign(0, x) * y);
99 return CMPLX(x * x, copysign(0, (x + x) * y));
100 }
101
102 /*
103 * cosh(x +- I Inf) = dNaN + I dNaN.
104 * Raise the invalid floating-point exception for finite nonzero x.
105 *
106 * cosh(x + I NaN) = d(NaN) + I d(NaN).
107 * Optionally raises the invalid floating-point exception for finite
108 * nonzero x. Choice = don't raise (except for signaling NaNs).
109 */
110 if (ix < 0x7ff00000 && iy >= 0x7ff00000)
111 return CMPLX(y - y, x * (y - y));
112
113 /*
114 * cosh(+-Inf + I NaN) = +Inf + I d(NaN).
115 *
116 * cosh(+-Inf +- I Inf) = +Inf + I dNaN.
117 * The sign of Inf in the result is unspecified. Choice = always +.
118 * Raise the invalid floating-point exception.
119 *
120 * cosh(+-Inf + I y) = +Inf cos(y) +- I Inf sin(y)
121 */
122 if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
123 if (iy >= 0x7ff00000)
124 return CMPLX(x * x, x * (y - y));
125 return CMPLX((x * x) * cos(y), x * sin(y));
126 }
127
128 /*
129 * cosh(NaN + I NaN) = d(NaN) + I d(NaN).
130 *
131 * cosh(NaN +- I Inf) = d(NaN) + I d(NaN).
132 * Optionally raises the invalid floating-point exception.
133 * Choice = raise.
134 *
135 * cosh(NaN + I y) = d(NaN) + I d(NaN).
136 * Optionally raises the invalid floating-point exception for finite
137 * nonzero y. Choice = don't raise (except for signaling NaNs).
138 */
139 return CMPLX((x * x) * (y - y), (x + x) * (y - y));
140}
libc/musl/src/complex/ccoshf.c created+90
......@@ -0,0 +1,90 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_ccoshf.c */
2/*-
3 * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/*
28 * Hyperbolic cosine of a complex argument. See s_ccosh.c for details.
29 */
30
31#include "libm.h"
32
33static const float huge = 0x1p127;
34
35float complex ccoshf(float complex z)
36{
37 float x, y, h;
38 int32_t hx, hy, ix, iy;
39
40 x = crealf(z);
41 y = cimagf(z);
42
43 GET_FLOAT_WORD(hx, x);
44 GET_FLOAT_WORD(hy, y);
45
46 ix = 0x7fffffff & hx;
47 iy = 0x7fffffff & hy;
48
49 if (ix < 0x7f800000 && iy < 0x7f800000) {
50 if (iy == 0)
51 return CMPLXF(coshf(x), x * y);
52 if (ix < 0x41100000) /* small x: normal case */
53 return CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y));
54
55 /* |x| >= 9, so cosh(x) ~= exp(|x|) */
56 if (ix < 0x42b17218) {
57 /* x < 88.7: expf(|x|) won't overflow */
58 h = expf(fabsf(x)) * 0.5f;
59 return CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y));
60 } else if (ix < 0x4340b1e7) {
61 /* x < 192.7: scale to avoid overflow */
62 z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
63 return CMPLXF(crealf(z), cimagf(z) * copysignf(1, x));
64 } else {
65 /* x >= 192.7: the result always overflows */
66 h = huge * x;
67 return CMPLXF(h * h * cosf(y), h * sinf(y));
68 }
69 }
70
71 if (ix == 0 && iy >= 0x7f800000)
72 return CMPLXF(y - y, copysignf(0, x * (y - y)));
73
74 if (iy == 0 && ix >= 0x7f800000) {
75 if ((hx & 0x7fffff) == 0)
76 return CMPLXF(x * x, copysignf(0, x) * y);
77 return CMPLXF(x * x, copysignf(0, (x + x) * y));
78 }
79
80 if (ix < 0x7f800000 && iy >= 0x7f800000)
81 return CMPLXF(y - y, x * (y - y));
82
83 if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
84 if (iy >= 0x7f800000)
85 return CMPLXF(x * x, x * (y - y));
86 return CMPLXF((x * x) * cosf(y), x * sinf(y));
87 }
88
89 return CMPLXF((x * x) * (y - y), (x + x) * (y - y));
90}
libc/musl/src/complex/ccoshl.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3//FIXME
4long double complex ccoshl(long double complex z)
5{
6 return ccosh(z);
7}
libc/musl/src/complex/ccosl.c created+13
......@@ -0,0 +1,13 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex ccosl(long double complex z)
5{
6 return ccos(z);
7}
8#else
9long double complex ccosl(long double complex z)
10{
11 return ccoshl(CMPLXL(-cimagl(z), creall(z)));
12}
13#endif
libc/musl/src/complex/cexp.c created+83
......@@ -0,0 +1,83 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_cexp.c */
2/*-
3 * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "libm.h"
29
30static const uint32_t
31exp_ovfl = 0x40862e42, /* high bits of MAX_EXP * ln2 ~= 710 */
32cexp_ovfl = 0x4096b8e4; /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */
33
34double complex cexp(double complex z)
35{
36 double x, y, exp_x;
37 uint32_t hx, hy, lx, ly;
38
39 x = creal(z);
40 y = cimag(z);
41
42 EXTRACT_WORDS(hy, ly, y);
43 hy &= 0x7fffffff;
44
45 /* cexp(x + I 0) = exp(x) + I 0 */
46 if ((hy | ly) == 0)
47 return CMPLX(exp(x), y);
48 EXTRACT_WORDS(hx, lx, x);
49 /* cexp(0 + I y) = cos(y) + I sin(y) */
50 if (((hx & 0x7fffffff) | lx) == 0)
51 return CMPLX(cos(y), sin(y));
52
53 if (hy >= 0x7ff00000) {
54 if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) {
55 /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
56 return CMPLX(y - y, y - y);
57 } else if (hx & 0x80000000) {
58 /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
59 return CMPLX(0.0, 0.0);
60 } else {
61 /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
62 return CMPLX(x, y - y);
63 }
64 }
65
66 if (hx >= exp_ovfl && hx <= cexp_ovfl) {
67 /*
68 * x is between 709.7 and 1454.3, so we must scale to avoid
69 * overflow in exp(x).
70 */
71 return __ldexp_cexp(z, 0);
72 } else {
73 /*
74 * Cases covered here:
75 * - x < exp_ovfl and exp(x) won't overflow (common case)
76 * - x > cexp_ovfl, so exp(x) * s overflows for all s > 0
77 * - x = +-Inf (generated by exp())
78 * - x = NaN (spurious inexact exception from y)
79 */
80 exp_x = exp(x);
81 return CMPLX(exp_x * cos(y), exp_x * sin(y));
82 }
83}
libc/musl/src/complex/cexpf.c created+83
......@@ -0,0 +1,83 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_cexpf.c */
2/*-
3 * Copyright (c) 2011 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "libm.h"
29
30static const uint32_t
31exp_ovfl = 0x42b17218, /* MAX_EXP * ln2 ~= 88.722839355 */
32cexp_ovfl = 0x43400074; /* (MAX_EXP - MIN_DENORM_EXP) * ln2 */
33
34float complex cexpf(float complex z)
35{
36 float x, y, exp_x;
37 uint32_t hx, hy;
38
39 x = crealf(z);
40 y = cimagf(z);
41
42 GET_FLOAT_WORD(hy, y);
43 hy &= 0x7fffffff;
44
45 /* cexp(x + I 0) = exp(x) + I 0 */
46 if (hy == 0)
47 return CMPLXF(expf(x), y);
48 GET_FLOAT_WORD(hx, x);
49 /* cexp(0 + I y) = cos(y) + I sin(y) */
50 if ((hx & 0x7fffffff) == 0)
51 return CMPLXF(cosf(y), sinf(y));
52
53 if (hy >= 0x7f800000) {
54 if ((hx & 0x7fffffff) != 0x7f800000) {
55 /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
56 return CMPLXF(y - y, y - y);
57 } else if (hx & 0x80000000) {
58 /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
59 return CMPLXF(0.0, 0.0);
60 } else {
61 /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
62 return CMPLXF(x, y - y);
63 }
64 }
65
66 if (hx >= exp_ovfl && hx <= cexp_ovfl) {
67 /*
68 * x is between 88.7 and 192, so we must scale to avoid
69 * overflow in expf(x).
70 */
71 return __ldexp_cexpf(z, 0);
72 } else {
73 /*
74 * Cases covered here:
75 * - x < exp_ovfl and exp(x) won't overflow (common case)
76 * - x > cexp_ovfl, so exp(x) * s overflows for all s > 0
77 * - x = +-Inf (generated by exp())
78 * - x = NaN (spurious inexact exception from y)
79 */
80 exp_x = expf(x);
81 return CMPLXF(exp_x * cosf(y), exp_x * sinf(y));
82 }
83}
libc/musl/src/complex/cexpl.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3//FIXME
4long double complex cexpl(long double complex z)
5{
6 return cexp(z);
7}
libc/musl/src/complex/cimag.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3double (cimag)(double complex z)
4{
5 return cimag(z);
6}
libc/musl/src/complex/cimagf.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3float (cimagf)(float complex z)
4{
5 return cimagf(z);
6}
libc/musl/src/complex/cimagl.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3long double (cimagl)(long double complex z)
4{
5 return cimagl(z);
6}
libc/musl/src/complex/clog.c created+14
......@@ -0,0 +1,14 @@
1#include "libm.h"
2
3// FIXME
4
5/* log(z) = log(|z|) + i arg(z) */
6
7double complex clog(double complex z)
8{
9 double r, phi;
10
11 r = cabs(z);
12 phi = carg(z);
13 return CMPLX(log(r), phi);
14}
libc/musl/src/complex/clogf.c created+12
......@@ -0,0 +1,12 @@
1#include "libm.h"
2
3// FIXME
4
5float complex clogf(float complex z)
6{
7 float r, phi;
8
9 r = cabsf(z);
10 phi = cargf(z);
11 return CMPLXF(logf(r), phi);
12}
libc/musl/src/complex/clogl.c created+18
......@@ -0,0 +1,18 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex clogl(long double complex z)
5{
6 return clog(z);
7}
8#else
9// FIXME
10long double complex clogl(long double complex z)
11{
12 long double r, phi;
13
14 r = cabsl(z);
15 phi = cargl(z);
16 return CMPLXL(logl(r), phi);
17}
18#endif
libc/musl/src/complex/conj.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3double complex conj(double complex z)
4{
5 return CMPLX(creal(z), -cimag(z));
6}
libc/musl/src/complex/conjf.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3float complex conjf(float complex z)
4{
5 return CMPLXF(crealf(z), -cimagf(z));
6}
libc/musl/src/complex/conjl.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3long double complex conjl(long double complex z)
4{
5 return CMPLXL(creall(z), -cimagl(z));
6}
libc/musl/src/complex/cpow.c created+8
......@@ -0,0 +1,8 @@
1#include "libm.h"
2
3/* pow(z, c) = exp(c log(z)), See C99 G.6.4.1 */
4
5double complex cpow(double complex z, double complex c)
6{
7 return cexp(c * clog(z));
8}
libc/musl/src/complex/cpowf.c created+6
......@@ -0,0 +1,6 @@
1#include "libm.h"
2
3float complex cpowf(float complex z, float complex c)
4{
5 return cexpf(c * clogf(z));
6}
libc/musl/src/complex/cpowl.c created+13
......@@ -0,0 +1,13 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex cpowl(long double complex z, long double complex c)
5{
6 return cpow(z, c);
7}
8#else
9long double complex cpowl(long double complex z, long double complex c)
10{
11 return cexpl(c * clogl(z));
12}
13#endif
libc/musl/src/complex/cproj.c created+8
......@@ -0,0 +1,8 @@
1#include "libm.h"
2
3double complex cproj(double complex z)
4{
5 if (isinf(creal(z)) || isinf(cimag(z)))
6 return CMPLX(INFINITY, copysign(0.0, creal(z)));
7 return z;
8}
libc/musl/src/complex/cprojf.c created+8
......@@ -0,0 +1,8 @@
1#include "libm.h"
2
3float complex cprojf(float complex z)
4{
5 if (isinf(crealf(z)) || isinf(cimagf(z)))
6 return CMPLXF(INFINITY, copysignf(0.0, crealf(z)));
7 return z;
8}
libc/musl/src/complex/cprojl.c created+15
......@@ -0,0 +1,15 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex cprojl(long double complex z)
5{
6 return cproj(z);
7}
8#else
9long double complex cprojl(long double complex z)
10{
11 if (isinf(creall(z)) || isinf(cimagl(z)))
12 return CMPLXL(INFINITY, copysignl(0.0, creall(z)));
13 return z;
14}
15#endif
libc/musl/src/complex/creal.c created+6
......@@ -0,0 +1,6 @@
1#include <complex.h>
2
3double (creal)(double complex z)
4{
5 return creal(z);
6}
libc/musl/src/complex/crealf.c created+6
......@@ -0,0 +1,6 @@
1#include <complex.h>
2
3float (crealf)(float complex z)
4{
5 return crealf(z);
6}
libc/musl/src/complex/creall.c created+6
......@@ -0,0 +1,6 @@
1#include <complex.h>
2
3long double (creall)(long double complex z)
4{
5 return creall(z);
6}
libc/musl/src/complex/csin.c created+9
......@@ -0,0 +1,9 @@
1#include "libm.h"
2
3/* sin(z) = -i sinh(i z) */
4
5double complex csin(double complex z)
6{
7 z = csinh(CMPLX(-cimag(z), creal(z)));
8 return CMPLX(cimag(z), -creal(z));
9}
libc/musl/src/complex/csinf.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3float complex csinf(float complex z)
4{
5 z = csinhf(CMPLXF(-cimagf(z), crealf(z)));
6 return CMPLXF(cimagf(z), -crealf(z));
7}
libc/musl/src/complex/csinh.c created+141
......@@ -0,0 +1,141 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_csinh.c */
2/*-
3 * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/*
28 * Hyperbolic sine of a complex argument z = x + i y.
29 *
30 * sinh(z) = sinh(x+iy)
31 * = sinh(x) cos(y) + i cosh(x) sin(y).
32 *
33 * Exceptional values are noted in the comments within the source code.
34 * These values and the return value were taken from n1124.pdf.
35 */
36
37#include "libm.h"
38
39static const double huge = 0x1p1023;
40
41double complex csinh(double complex z)
42{
43 double x, y, h;
44 int32_t hx, hy, ix, iy, lx, ly;
45
46 x = creal(z);
47 y = cimag(z);
48
49 EXTRACT_WORDS(hx, lx, x);
50 EXTRACT_WORDS(hy, ly, y);
51
52 ix = 0x7fffffff & hx;
53 iy = 0x7fffffff & hy;
54
55 /* Handle the nearly-non-exceptional cases where x and y are finite. */
56 if (ix < 0x7ff00000 && iy < 0x7ff00000) {
57 if ((iy | ly) == 0)
58 return CMPLX(sinh(x), y);
59 if (ix < 0x40360000) /* small x: normal case */
60 return CMPLX(sinh(x) * cos(y), cosh(x) * sin(y));
61
62 /* |x| >= 22, so cosh(x) ~= exp(|x|) */
63 if (ix < 0x40862e42) {
64 /* x < 710: exp(|x|) won't overflow */
65 h = exp(fabs(x)) * 0.5;
66 return CMPLX(copysign(h, x) * cos(y), h * sin(y));
67 } else if (ix < 0x4096bbaa) {
68 /* x < 1455: scale to avoid overflow */
69 z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
70 return CMPLX(creal(z) * copysign(1, x), cimag(z));
71 } else {
72 /* x >= 1455: the result always overflows */
73 h = huge * x;
74 return CMPLX(h * cos(y), h * h * sin(y));
75 }
76 }
77
78 /*
79 * sinh(+-0 +- I Inf) = sign(d(+-0, dNaN))0 + I dNaN.
80 * The sign of 0 in the result is unspecified. Choice = normally
81 * the same as dNaN. Raise the invalid floating-point exception.
82 *
83 * sinh(+-0 +- I NaN) = sign(d(+-0, NaN))0 + I d(NaN).
84 * The sign of 0 in the result is unspecified. Choice = normally
85 * the same as d(NaN).
86 */
87 if ((ix | lx) == 0 && iy >= 0x7ff00000)
88 return CMPLX(copysign(0, x * (y - y)), y - y);
89
90 /*
91 * sinh(+-Inf +- I 0) = +-Inf + I +-0.
92 *
93 * sinh(NaN +- I 0) = d(NaN) + I +-0.
94 */
95 if ((iy | ly) == 0 && ix >= 0x7ff00000) {
96 if (((hx & 0xfffff) | lx) == 0)
97 return CMPLX(x, y);
98 return CMPLX(x, copysign(0, y));
99 }
100
101 /*
102 * sinh(x +- I Inf) = dNaN + I dNaN.
103 * Raise the invalid floating-point exception for finite nonzero x.
104 *
105 * sinh(x + I NaN) = d(NaN) + I d(NaN).
106 * Optionally raises the invalid floating-point exception for finite
107 * nonzero x. Choice = don't raise (except for signaling NaNs).
108 */
109 if (ix < 0x7ff00000 && iy >= 0x7ff00000)
110 return CMPLX(y - y, x * (y - y));
111
112 /*
113 * sinh(+-Inf + I NaN) = +-Inf + I d(NaN).
114 * The sign of Inf in the result is unspecified. Choice = normally
115 * the same as d(NaN).
116 *
117 * sinh(+-Inf +- I Inf) = +Inf + I dNaN.
118 * The sign of Inf in the result is unspecified. Choice = always +.
119 * Raise the invalid floating-point exception.
120 *
121 * sinh(+-Inf + I y) = +-Inf cos(y) + I Inf sin(y)
122 */
123 if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
124 if (iy >= 0x7ff00000)
125 return CMPLX(x * x, x * (y - y));
126 return CMPLX(x * cos(y), INFINITY * sin(y));
127 }
128
129 /*
130 * sinh(NaN + I NaN) = d(NaN) + I d(NaN).
131 *
132 * sinh(NaN +- I Inf) = d(NaN) + I d(NaN).
133 * Optionally raises the invalid floating-point exception.
134 * Choice = raise.
135 *
136 * sinh(NaN + I y) = d(NaN) + I d(NaN).
137 * Optionally raises the invalid floating-point exception for finite
138 * nonzero y. Choice = don't raise (except for signaling NaNs).
139 */
140 return CMPLX((x * x) * (y - y), (x + x) * (y - y));
141}
libc/musl/src/complex/csinhf.c created+90
......@@ -0,0 +1,90 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_csinhf.c */
2/*-
3 * Copyright (c) 2005 Bruce D. Evans and Steven G. Kargl
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/*
28 * Hyperbolic sine of a complex argument z. See s_csinh.c for details.
29 */
30
31#include "libm.h"
32
33static const float huge = 0x1p127;
34
35float complex csinhf(float complex z)
36{
37 float x, y, h;
38 int32_t hx, hy, ix, iy;
39
40 x = crealf(z);
41 y = cimagf(z);
42
43 GET_FLOAT_WORD(hx, x);
44 GET_FLOAT_WORD(hy, y);
45
46 ix = 0x7fffffff & hx;
47 iy = 0x7fffffff & hy;
48
49 if (ix < 0x7f800000 && iy < 0x7f800000) {
50 if (iy == 0)
51 return CMPLXF(sinhf(x), y);
52 if (ix < 0x41100000) /* small x: normal case */
53 return CMPLXF(sinhf(x) * cosf(y), coshf(x) * sinf(y));
54
55 /* |x| >= 9, so cosh(x) ~= exp(|x|) */
56 if (ix < 0x42b17218) {
57 /* x < 88.7: expf(|x|) won't overflow */
58 h = expf(fabsf(x)) * 0.5f;
59 return CMPLXF(copysignf(h, x) * cosf(y), h * sinf(y));
60 } else if (ix < 0x4340b1e7) {
61 /* x < 192.7: scale to avoid overflow */
62 z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
63 return CMPLXF(crealf(z) * copysignf(1, x), cimagf(z));
64 } else {
65 /* x >= 192.7: the result always overflows */
66 h = huge * x;
67 return CMPLXF(h * cosf(y), h * h * sinf(y));
68 }
69 }
70
71 if (ix == 0 && iy >= 0x7f800000)
72 return CMPLXF(copysignf(0, x * (y - y)), y - y);
73
74 if (iy == 0 && ix >= 0x7f800000) {
75 if ((hx & 0x7fffff) == 0)
76 return CMPLXF(x, y);
77 return CMPLXF(x, copysignf(0, y));
78 }
79
80 if (ix < 0x7f800000 && iy >= 0x7f800000)
81 return CMPLXF(y - y, x * (y - y));
82
83 if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
84 if (iy >= 0x7f800000)
85 return CMPLXF(x * x, x * (y - y));
86 return CMPLXF(x * cosf(y), INFINITY * sinf(y));
87 }
88
89 return CMPLXF((x * x) * (y - y), (x + x) * (y - y));
90}
libc/musl/src/complex/csinhl.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3//FIXME
4long double complex csinhl(long double complex z)
5{
6 return csinh(z);
7}
libc/musl/src/complex/csinl.c created+14
......@@ -0,0 +1,14 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex csinl(long double complex z)
5{
6 return csin(z);
7}
8#else
9long double complex csinl(long double complex z)
10{
11 z = csinhl(CMPLXL(-cimagl(z), creall(z)));
12 return CMPLXL(cimagl(z), -creall(z));
13}
14#endif
libc/musl/src/complex/csqrt.c created+100
......@@ -0,0 +1,100 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_csqrt.c */
2/*-
3 * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "libm.h"
29
30/*
31 * gcc doesn't implement complex multiplication or division correctly,
32 * so we need to handle infinities specially. We turn on this pragma to
33 * notify conforming c99 compilers that the fast-but-incorrect code that
34 * gcc generates is acceptable, since the special cases have already been
35 * handled.
36 */
37#pragma STDC CX_LIMITED_RANGE ON
38
39/* We risk spurious overflow for components >= DBL_MAX / (1 + sqrt(2)). */
40#define THRESH 0x1.a827999fcef32p+1022
41
42double complex csqrt(double complex z)
43{
44 double complex result;
45 double a, b;
46 double t;
47 int scale;
48
49 a = creal(z);
50 b = cimag(z);
51
52 /* Handle special cases. */
53 if (z == 0)
54 return CMPLX(0, b);
55 if (isinf(b))
56 return CMPLX(INFINITY, b);
57 if (isnan(a)) {
58 t = (b - b) / (b - b); /* raise invalid if b is not a NaN */
59 return CMPLX(a, t); /* return NaN + NaN i */
60 }
61 if (isinf(a)) {
62 /*
63 * csqrt(inf + NaN i) = inf + NaN i
64 * csqrt(inf + y i) = inf + 0 i
65 * csqrt(-inf + NaN i) = NaN +- inf i
66 * csqrt(-inf + y i) = 0 + inf i
67 */
68 if (signbit(a))
69 return CMPLX(fabs(b - b), copysign(a, b));
70 else
71 return CMPLX(a, copysign(b - b, b));
72 }
73 /*
74 * The remaining special case (b is NaN) is handled just fine by
75 * the normal code path below.
76 */
77
78 /* Scale to avoid overflow. */
79 if (fabs(a) >= THRESH || fabs(b) >= THRESH) {
80 a *= 0.25;
81 b *= 0.25;
82 scale = 1;
83 } else {
84 scale = 0;
85 }
86
87 /* Algorithm 312, CACM vol 10, Oct 1967. */
88 if (a >= 0) {
89 t = sqrt((a + hypot(a, b)) * 0.5);
90 result = CMPLX(t, b / (2 * t));
91 } else {
92 t = sqrt((-a + hypot(a, b)) * 0.5);
93 result = CMPLX(fabs(b) / (2 * t), copysign(t, b));
94 }
95
96 /* Rescale. */
97 if (scale)
98 result *= 2;
99 return result;
100}
libc/musl/src/complex/csqrtf.c created+82
......@@ -0,0 +1,82 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_csqrtf.c */
2/*-
3 * Copyright (c) 2007 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "libm.h"
29
30/*
31 * gcc doesn't implement complex multiplication or division correctly,
32 * so we need to handle infinities specially. We turn on this pragma to
33 * notify conforming c99 compilers that the fast-but-incorrect code that
34 * gcc generates is acceptable, since the special cases have already been
35 * handled.
36 */
37#pragma STDC CX_LIMITED_RANGE ON
38
39float complex csqrtf(float complex z)
40{
41 float a = crealf(z), b = cimagf(z);
42 double t;
43
44 /* Handle special cases. */
45 if (z == 0)
46 return CMPLXF(0, b);
47 if (isinf(b))
48 return CMPLXF(INFINITY, b);
49 if (isnan(a)) {
50 t = (b - b) / (b - b); /* raise invalid if b is not a NaN */
51 return CMPLXF(a, t); /* return NaN + NaN i */
52 }
53 if (isinf(a)) {
54 /*
55 * csqrtf(inf + NaN i) = inf + NaN i
56 * csqrtf(inf + y i) = inf + 0 i
57 * csqrtf(-inf + NaN i) = NaN +- inf i
58 * csqrtf(-inf + y i) = 0 + inf i
59 */
60 if (signbit(a))
61 return CMPLXF(fabsf(b - b), copysignf(a, b));
62 else
63 return CMPLXF(a, copysignf(b - b, b));
64 }
65 /*
66 * The remaining special case (b is NaN) is handled just fine by
67 * the normal code path below.
68 */
69
70 /*
71 * We compute t in double precision to avoid overflow and to
72 * provide correct rounding in nearly all cases.
73 * This is Algorithm 312, CACM vol 10, Oct 1967.
74 */
75 if (a >= 0) {
76 t = sqrt((a + hypot(a, b)) * 0.5);
77 return CMPLXF(t, b / (2.0 * t));
78 } else {
79 t = sqrt((-a + hypot(a, b)) * 0.5);
80 return CMPLXF(fabsf(b) / (2.0 * t), copysignf(t, b));
81 }
82}
libc/musl/src/complex/csqrtl.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3//FIXME
4long double complex csqrtl(long double complex z)
5{
6 return csqrt(z);
7}
libc/musl/src/complex/ctan.c created+9
......@@ -0,0 +1,9 @@
1#include "libm.h"
2
3/* tan(z) = -i tanh(i z) */
4
5double complex ctan(double complex z)
6{
7 z = ctanh(CMPLX(-cimag(z), creal(z)));
8 return CMPLX(cimag(z), -creal(z));
9}
libc/musl/src/complex/ctanf.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3float complex ctanf(float complex z)
4{
5 z = ctanhf(CMPLXF(-cimagf(z), crealf(z)));
6 return CMPLXF(cimagf(z), -crealf(z));
7}
libc/musl/src/complex/ctanh.c created+129
......@@ -0,0 +1,129 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_ctanh.c */
2/*-
3 * Copyright (c) 2011 David Schultz
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/*
28 * Hyperbolic tangent of a complex argument z = x + i y.
29 *
30 * The algorithm is from:
31 *
32 * W. Kahan. Branch Cuts for Complex Elementary Functions or Much
33 * Ado About Nothing's Sign Bit. In The State of the Art in
34 * Numerical Analysis, pp. 165 ff. Iserles and Powell, eds., 1987.
35 *
36 * Method:
37 *
38 * Let t = tan(x)
39 * beta = 1/cos^2(y)
40 * s = sinh(x)
41 * rho = cosh(x)
42 *
43 * We have:
44 *
45 * tanh(z) = sinh(z) / cosh(z)
46 *
47 * sinh(x) cos(y) + i cosh(x) sin(y)
48 * = ---------------------------------
49 * cosh(x) cos(y) + i sinh(x) sin(y)
50 *
51 * cosh(x) sinh(x) / cos^2(y) + i tan(y)
52 * = -------------------------------------
53 * 1 + sinh^2(x) / cos^2(y)
54 *
55 * beta rho s + i t
56 * = ----------------
57 * 1 + beta s^2
58 *
59 * Modifications:
60 *
61 * I omitted the original algorithm's handling of overflow in tan(x) after
62 * verifying with nearpi.c that this can't happen in IEEE single or double
63 * precision. I also handle large x differently.
64 */
65
66#include "libm.h"
67
68double complex ctanh(double complex z)
69{
70 double x, y;
71 double t, beta, s, rho, denom;
72 uint32_t hx, ix, lx;
73
74 x = creal(z);
75 y = cimag(z);
76
77 EXTRACT_WORDS(hx, lx, x);
78 ix = hx & 0x7fffffff;
79
80 /*
81 * ctanh(NaN + i 0) = NaN + i 0
82 *
83 * ctanh(NaN + i y) = NaN + i NaN for y != 0
84 *
85 * The imaginary part has the sign of x*sin(2*y), but there's no
86 * special effort to get this right.
87 *
88 * ctanh(+-Inf +- i Inf) = +-1 +- 0
89 *
90 * ctanh(+-Inf + i y) = +-1 + 0 sin(2y) for y finite
91 *
92 * The imaginary part of the sign is unspecified. This special
93 * case is only needed to avoid a spurious invalid exception when
94 * y is infinite.
95 */
96 if (ix >= 0x7ff00000) {
97 if ((ix & 0xfffff) | lx) /* x is NaN */
98 return CMPLX(x, (y == 0 ? y : x * y));
99 SET_HIGH_WORD(x, hx - 0x40000000); /* x = copysign(1, x) */
100 return CMPLX(x, copysign(0, isinf(y) ? y : sin(y) * cos(y)));
101 }
102
103 /*
104 * ctanh(+-0 + i NAN) = +-0 + i NaN
105 * ctanh(+-0 +- i Inf) = +-0 + i NaN
106 * ctanh(x + i NAN) = NaN + i NaN
107 * ctanh(x +- i Inf) = NaN + i NaN
108 */
109 if (!isfinite(y))
110 return CMPLX(x ? y - y : x, y - y);
111
112 /*
113 * ctanh(+-huge + i +-y) ~= +-1 +- i 2sin(2y)/exp(2x), using the
114 * approximation sinh^2(huge) ~= exp(2*huge) / 4.
115 * We use a modified formula to avoid spurious overflow.
116 */
117 if (ix >= 0x40360000) { /* x >= 22 */
118 double exp_mx = exp(-fabs(x));
119 return CMPLX(copysign(1, x), 4 * sin(y) * cos(y) * exp_mx * exp_mx);
120 }
121
122 /* Kahan's algorithm */
123 t = tan(y);
124 beta = 1.0 + t * t; /* = 1 / cos^2(y) */
125 s = sinh(x);
126 rho = sqrt(1 + s * s); /* = cosh(x) */
127 denom = 1 + beta * s * s;
128 return CMPLX((beta * rho * s) / denom, t / denom);
129}
libc/musl/src/complex/ctanhf.c created+66
......@@ -0,0 +1,66 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_ctanhf.c */
2/*-
3 * Copyright (c) 2011 David Schultz
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice unmodified, this list of conditions, and the following
11 * disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27/*
28 * Hyperbolic tangent of a complex argument z. See s_ctanh.c for details.
29 */
30
31#include "libm.h"
32
33float complex ctanhf(float complex z)
34{
35 float x, y;
36 float t, beta, s, rho, denom;
37 uint32_t hx, ix;
38
39 x = crealf(z);
40 y = cimagf(z);
41
42 GET_FLOAT_WORD(hx, x);
43 ix = hx & 0x7fffffff;
44
45 if (ix >= 0x7f800000) {
46 if (ix & 0x7fffff)
47 return CMPLXF(x, (y == 0 ? y : x * y));
48 SET_FLOAT_WORD(x, hx - 0x40000000);
49 return CMPLXF(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)));
50 }
51
52 if (!isfinite(y))
53 return CMPLXF(ix ? y - y : x, y - y);
54
55 if (ix >= 0x41300000) { /* x >= 11 */
56 float exp_mx = expf(-fabsf(x));
57 return CMPLXF(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx);
58 }
59
60 t = tanf(y);
61 beta = 1.0 + t * t;
62 s = sinhf(x);
63 rho = sqrtf(1 + s * s);
64 denom = 1 + beta * s * s;
65 return CMPLXF((beta * rho * s) / denom, t / denom);
66}
libc/musl/src/complex/ctanhl.c created+7
......@@ -0,0 +1,7 @@
1#include "libm.h"
2
3//FIXME
4long double complex ctanhl(long double complex z)
5{
6 return ctanh(z);
7}
libc/musl/src/complex/ctanl.c created+14
......@@ -0,0 +1,14 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double complex ctanl(long double complex z)
5{
6 return ctan(z);
7}
8#else
9long double complex ctanl(long double complex z)
10{
11 z = ctanhl(CMPLXL(-cimagl(z), creall(z)));
12 return CMPLXL(cimagl(z), -creall(z));
13}
14#endif
libc/musl/src/conf/confstr.c created+17
......@@ -0,0 +1,17 @@
1#include <unistd.h>
2#include <stdio.h>
3#include <errno.h>
4
5size_t confstr(int name, char *buf, size_t len)
6{
7 const char *s = "";
8 if (!name) {
9 s = "/bin:/usr/bin";
10 } else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>33U) {
11 errno = EINVAL;
12 return 0;
13 }
14 // snprintf is overkill but avoid wasting code size to implement
15 // this completely useless function and its truncation semantics
16 return snprintf(buf, len, "%s", s) + 1;
17}
libc/musl/src/conf/fpathconf.c created+35
......@@ -0,0 +1,35 @@
1#include <unistd.h>
2#include <limits.h>
3#include <errno.h>
4
5long fpathconf(int fd, int name)
6{
7 static const short values[] = {
8 [_PC_LINK_MAX] = _POSIX_LINK_MAX,
9 [_PC_MAX_CANON] = _POSIX_MAX_CANON,
10 [_PC_MAX_INPUT] = _POSIX_MAX_INPUT,
11 [_PC_NAME_MAX] = NAME_MAX,
12 [_PC_PATH_MAX] = PATH_MAX,
13 [_PC_PIPE_BUF] = PIPE_BUF,
14 [_PC_CHOWN_RESTRICTED] = 1,
15 [_PC_NO_TRUNC] = 1,
16 [_PC_VDISABLE] = 0,
17 [_PC_SYNC_IO] = 1,
18 [_PC_ASYNC_IO] = -1,
19 [_PC_PRIO_IO] = -1,
20 [_PC_SOCK_MAXBUF] = -1,
21 [_PC_FILESIZEBITS] = FILESIZEBITS,
22 [_PC_REC_INCR_XFER_SIZE] = 4096,
23 [_PC_REC_MAX_XFER_SIZE] = 4096,
24 [_PC_REC_MIN_XFER_SIZE] = 4096,
25 [_PC_REC_XFER_ALIGN] = 4096,
26 [_PC_ALLOC_SIZE_MIN] = 4096,
27 [_PC_SYMLINK_MAX] = -1,
28 [_PC_2_SYMLINKS] = 1
29 };
30 if (name >= sizeof(values)/sizeof(values[0])) {
31 errno = EINVAL;
32 return -1;
33 }
34 return values[name];
35}
libc/musl/src/conf/legacy.c created+22
......@@ -0,0 +1,22 @@
1#include <sys/sysinfo.h>
2#include <unistd.h>
3
4int get_nprocs_conf()
5{
6 return sysconf(_SC_NPROCESSORS_CONF);
7}
8
9int get_nprocs()
10{
11 return sysconf(_SC_NPROCESSORS_ONLN);
12}
13
14long get_phys_pages()
15{
16 return sysconf(_SC_PHYS_PAGES);
17}
18
19long get_avphys_pages()
20{
21 return sysconf(_SC_AVPHYS_PAGES);
22}
libc/musl/src/conf/pathconf.c created+6
......@@ -0,0 +1,6 @@
1#include <unistd.h>
2
3long pathconf(const char *path, int name)
4{
5 return fpathconf(-1, name);
6}
libc/musl/src/conf/sysconf.c created+219
......@@ -0,0 +1,219 @@
1#include <unistd.h>
2#include <limits.h>
3#include <errno.h>
4#include <sys/resource.h>
5#include <signal.h>
6#include <sys/sysinfo.h>
7#include "syscall.h"
8#include "libc.h"
9
10#define JT(x) (-256|(x))
11#define VER JT(1)
12#define JT_ARG_MAX JT(2)
13#define JT_MQ_PRIO_MAX JT(3)
14#define JT_PAGE_SIZE JT(4)
15#define JT_SEM_VALUE_MAX JT(5)
16#define JT_NPROCESSORS_CONF JT(6)
17#define JT_NPROCESSORS_ONLN JT(7)
18#define JT_PHYS_PAGES JT(8)
19#define JT_AVPHYS_PAGES JT(9)
20#define JT_ZERO JT(10)
21#define JT_DELAYTIMER_MAX JT(11)
22
23#define RLIM(x) (-32768|(RLIMIT_ ## x))
24
25long sysconf(int name)
26{
27 static const short values[] = {
28 [_SC_ARG_MAX] = JT_ARG_MAX,
29 [_SC_CHILD_MAX] = RLIM(NPROC),
30 [_SC_CLK_TCK] = 100,
31 [_SC_NGROUPS_MAX] = 32,
32 [_SC_OPEN_MAX] = RLIM(NOFILE),
33 [_SC_STREAM_MAX] = -1,
34 [_SC_TZNAME_MAX] = TZNAME_MAX,
35 [_SC_JOB_CONTROL] = 1,
36 [_SC_SAVED_IDS] = 1,
37 [_SC_REALTIME_SIGNALS] = VER,
38 [_SC_PRIORITY_SCHEDULING] = -1,
39 [_SC_TIMERS] = VER,
40 [_SC_ASYNCHRONOUS_IO] = VER,
41 [_SC_PRIORITIZED_IO] = -1,
42 [_SC_SYNCHRONIZED_IO] = -1,
43 [_SC_FSYNC] = VER,
44 [_SC_MAPPED_FILES] = VER,
45 [_SC_MEMLOCK] = VER,
46 [_SC_MEMLOCK_RANGE] = VER,
47 [_SC_MEMORY_PROTECTION] = VER,
48 [_SC_MESSAGE_PASSING] = VER,
49 [_SC_SEMAPHORES] = VER,
50 [_SC_SHARED_MEMORY_OBJECTS] = VER,
51 [_SC_AIO_LISTIO_MAX] = -1,
52 [_SC_AIO_MAX] = -1,
53 [_SC_AIO_PRIO_DELTA_MAX] = JT_ZERO, /* ?? */
54 [_SC_DELAYTIMER_MAX] = JT_DELAYTIMER_MAX,
55 [_SC_MQ_OPEN_MAX] = -1,
56 [_SC_MQ_PRIO_MAX] = JT_MQ_PRIO_MAX,
57 [_SC_VERSION] = VER,
58 [_SC_PAGE_SIZE] = JT_PAGE_SIZE,
59 [_SC_RTSIG_MAX] = _NSIG - 1 - 31 - 3,
60 [_SC_SEM_NSEMS_MAX] = SEM_NSEMS_MAX,
61 [_SC_SEM_VALUE_MAX] = JT_SEM_VALUE_MAX,
62 [_SC_SIGQUEUE_MAX] = -1,
63 [_SC_TIMER_MAX] = -1,
64 [_SC_BC_BASE_MAX] = _POSIX2_BC_BASE_MAX,
65 [_SC_BC_DIM_MAX] = _POSIX2_BC_DIM_MAX,
66 [_SC_BC_SCALE_MAX] = _POSIX2_BC_SCALE_MAX,
67 [_SC_BC_STRING_MAX] = _POSIX2_BC_STRING_MAX,
68 [_SC_COLL_WEIGHTS_MAX] = COLL_WEIGHTS_MAX,
69 [_SC_EXPR_NEST_MAX] = -1,
70 [_SC_LINE_MAX] = -1,
71 [_SC_RE_DUP_MAX] = RE_DUP_MAX,
72 [_SC_2_VERSION] = VER,
73 [_SC_2_C_BIND] = VER,
74 [_SC_2_C_DEV] = -1,
75 [_SC_2_FORT_DEV] = -1,
76 [_SC_2_FORT_RUN] = -1,
77 [_SC_2_SW_DEV] = -1,
78 [_SC_2_LOCALEDEF] = -1,
79 [_SC_IOV_MAX] = IOV_MAX,
80 [_SC_THREADS] = VER,
81 [_SC_THREAD_SAFE_FUNCTIONS] = VER,
82 [_SC_GETGR_R_SIZE_MAX] = -1,
83 [_SC_GETPW_R_SIZE_MAX] = -1,
84 [_SC_LOGIN_NAME_MAX] = 256,
85 [_SC_TTY_NAME_MAX] = TTY_NAME_MAX,
86 [_SC_THREAD_DESTRUCTOR_ITERATIONS] = PTHREAD_DESTRUCTOR_ITERATIONS,
87 [_SC_THREAD_KEYS_MAX] = PTHREAD_KEYS_MAX,
88 [_SC_THREAD_STACK_MIN] = PTHREAD_STACK_MIN,
89 [_SC_THREAD_THREADS_MAX] = -1,
90 [_SC_THREAD_ATTR_STACKADDR] = VER,
91 [_SC_THREAD_ATTR_STACKSIZE] = VER,
92 [_SC_THREAD_PRIORITY_SCHEDULING] = VER,
93 [_SC_THREAD_PRIO_INHERIT] = -1,
94 [_SC_THREAD_PRIO_PROTECT] = -1,
95 [_SC_THREAD_PROCESS_SHARED] = VER,
96 [_SC_NPROCESSORS_CONF] = JT_NPROCESSORS_CONF,
97 [_SC_NPROCESSORS_ONLN] = JT_NPROCESSORS_ONLN,
98 [_SC_PHYS_PAGES] = JT_PHYS_PAGES,
99 [_SC_AVPHYS_PAGES] = JT_AVPHYS_PAGES,
100 [_SC_ATEXIT_MAX] = -1,
101 [_SC_PASS_MAX] = -1,
102 [_SC_XOPEN_VERSION] = _XOPEN_VERSION,
103 [_SC_XOPEN_XCU_VERSION] = _XOPEN_VERSION,
104 [_SC_XOPEN_UNIX] = 1,
105 [_SC_XOPEN_CRYPT] = -1,
106 [_SC_XOPEN_ENH_I18N] = 1,
107 [_SC_XOPEN_SHM] = 1,
108 [_SC_2_CHAR_TERM] = -1,
109 [_SC_2_UPE] = -1,
110 [_SC_XOPEN_XPG2] = -1,
111 [_SC_XOPEN_XPG3] = -1,
112 [_SC_XOPEN_XPG4] = -1,
113 [_SC_NZERO] = NZERO,
114 [_SC_XBS5_ILP32_OFF32] = -1,
115 [_SC_XBS5_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1,
116 [_SC_XBS5_LP64_OFF64] = sizeof(long)==8 ? 1 : -1,
117 [_SC_XBS5_LPBIG_OFFBIG] = -1,
118 [_SC_XOPEN_LEGACY] = -1,
119 [_SC_XOPEN_REALTIME] = -1,
120 [_SC_XOPEN_REALTIME_THREADS] = -1,
121 [_SC_ADVISORY_INFO] = VER,
122 [_SC_BARRIERS] = VER,
123 [_SC_CLOCK_SELECTION] = VER,
124 [_SC_CPUTIME] = VER,
125 [_SC_THREAD_CPUTIME] = VER,
126 [_SC_MONOTONIC_CLOCK] = VER,
127 [_SC_READER_WRITER_LOCKS] = VER,
128 [_SC_SPIN_LOCKS] = VER,
129 [_SC_REGEXP] = 1,
130 [_SC_SHELL] = 1,
131 [_SC_SPAWN] = VER,
132 [_SC_SPORADIC_SERVER] = -1,
133 [_SC_THREAD_SPORADIC_SERVER] = -1,
134 [_SC_TIMEOUTS] = VER,
135 [_SC_TYPED_MEMORY_OBJECTS] = -1,
136 [_SC_2_PBS] = -1,
137 [_SC_2_PBS_ACCOUNTING] = -1,
138 [_SC_2_PBS_LOCATE] = -1,
139 [_SC_2_PBS_MESSAGE] = -1,
140 [_SC_2_PBS_TRACK] = -1,
141 [_SC_SYMLOOP_MAX] = SYMLOOP_MAX,
142 [_SC_STREAMS] = JT_ZERO,
143 [_SC_2_PBS_CHECKPOINT] = -1,
144 [_SC_V6_ILP32_OFF32] = -1,
145 [_SC_V6_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1,
146 [_SC_V6_LP64_OFF64] = sizeof(long)==8 ? 1 : -1,
147 [_SC_V6_LPBIG_OFFBIG] = -1,
148 [_SC_HOST_NAME_MAX] = HOST_NAME_MAX,
149 [_SC_TRACE] = -1,
150 [_SC_TRACE_EVENT_FILTER] = -1,
151 [_SC_TRACE_INHERIT] = -1,
152 [_SC_TRACE_LOG] = -1,
153
154 [_SC_IPV6] = VER,
155 [_SC_RAW_SOCKETS] = VER,
156 [_SC_V7_ILP32_OFF32] = -1,
157 [_SC_V7_ILP32_OFFBIG] = sizeof(long)==4 ? 1 : -1,
158 [_SC_V7_LP64_OFF64] = sizeof(long)==8 ? 1 : -1,
159 [_SC_V7_LPBIG_OFFBIG] = -1,
160 [_SC_SS_REPL_MAX] = -1,
161 [_SC_TRACE_EVENT_NAME_MAX] = -1,
162 [_SC_TRACE_NAME_MAX] = -1,
163 [_SC_TRACE_SYS_MAX] = -1,
164 [_SC_TRACE_USER_EVENT_MAX] = -1,
165 [_SC_XOPEN_STREAMS] = JT_ZERO,
166 [_SC_THREAD_ROBUST_PRIO_INHERIT] = -1,
167 [_SC_THREAD_ROBUST_PRIO_PROTECT] = -1,
168 };
169
170 if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {
171 errno = EINVAL;
172 return -1;
173 } else if (values[name] >= -1) {
174 return values[name];
175 } else if (values[name] < -256) {
176 struct rlimit lim;
177 getrlimit(values[name]&16383, &lim);
178 if (lim.rlim_cur == RLIM_INFINITY)
179 return -1;
180 return lim.rlim_cur > LONG_MAX ? LONG_MAX : lim.rlim_cur;
181 }
182
183 switch ((unsigned char)values[name]) {
184 case VER & 255:
185 return _POSIX_VERSION;
186 case JT_ARG_MAX & 255:
187 return ARG_MAX;
188 case JT_MQ_PRIO_MAX & 255:
189 return MQ_PRIO_MAX;
190 case JT_PAGE_SIZE & 255:
191 return PAGE_SIZE;
192 case JT_SEM_VALUE_MAX & 255:
193 return SEM_VALUE_MAX;
194 case JT_DELAYTIMER_MAX & 255:
195 return DELAYTIMER_MAX;
196 case JT_NPROCESSORS_CONF & 255:
197 case JT_NPROCESSORS_ONLN & 255: ;
198 unsigned char set[128] = {1};
199 int i, cnt;
200 __syscall(SYS_sched_getaffinity, 0, sizeof set, set);
201 for (i=cnt=0; i<sizeof set; i++)
202 for (; set[i]; set[i]&=set[i]-1, cnt++);
203 return cnt;
204 case JT_PHYS_PAGES & 255:
205 case JT_AVPHYS_PAGES & 255: ;
206 unsigned long long mem;
207 struct sysinfo si;
208 __lsysinfo(&si);
209 if (!si.mem_unit) si.mem_unit = 1;
210 if (name==_SC_PHYS_PAGES) mem = si.totalram;
211 else mem = si.freeram + si.bufferram;
212 mem *= si.mem_unit;
213 mem /= PAGE_SIZE;
214 return (mem > LONG_MAX) ? LONG_MAX : mem;
215 case JT_ZERO & 255:
216 return 0;
217 }
218 return values[name];
219}
libc/musl/src/crypt/crypt.c created+14
......@@ -0,0 +1,14 @@
1#include <unistd.h>
2#include <crypt.h>
3
4char *crypt(const char *key, const char *salt)
5{
6 /* This buffer is sufficiently large for all
7 * currently-supported hash types. It needs to be updated if
8 * longer hashes are added. The cast to struct crypt_data * is
9 * purely to meet the public API requirements of the crypt_r
10 * function; the implementation of crypt_r uses the object
11 * purely as a char buffer. */
12 static char buf[128];
13 return __crypt_r(key, salt, (struct crypt_data *)buf);
14}
libc/musl/src/crypt/crypt_blowfish.c created+798
......@@ -0,0 +1,798 @@
1/* Modified by Rich Felker in for inclusion in musl libc, based on
2 * Solar Designer's second size-optimized version sent to the musl
3 * mailing list. */
4
5/*
6 * The crypt_blowfish homepage is:
7 *
8 * http://www.openwall.com/crypt/
9 *
10 * This code comes from John the Ripper password cracker, with reentrant
11 * and crypt(3) interfaces added, but optimizations specific to password
12 * cracking removed.
13 *
14 * Written by Solar Designer <solar at openwall.com> in 1998-2012.
15 * No copyright is claimed, and the software is hereby placed in the public
16 * domain. In case this attempt to disclaim copyright and place the software
17 * in the public domain is deemed null and void, then the software is
18 * Copyright (c) 1998-2012 Solar Designer and it is hereby released to the
19 * general public under the following terms:
20 *
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted.
23 *
24 * There's ABSOLUTELY NO WARRANTY, express or implied.
25 *
26 * It is my intent that you should be able to use this on your system,
27 * as part of a software package, or anywhere else to improve security,
28 * ensure compatibility, or for any other purpose. I would appreciate
29 * it if you give credit where it is due and keep your modifications in
30 * the public domain as well, but I don't require that in order to let
31 * you place this code and any modifications you make under a license
32 * of your choice.
33 *
34 * This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
35 * "$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
36 * ideas. The password hashing algorithm was designed by David Mazieres
37 * <dm at lcs.mit.edu>. For more information on the level of compatibility,
38 * please refer to the comments in BF_set_key() below and to the included
39 * crypt(3) man page.
40 *
41 * There's a paper on the algorithm that explains its design decisions:
42 *
43 * http://www.usenix.org/events/usenix99/provos.html
44 *
45 * Some of the tricks in BF_ROUND might be inspired by Eric Young's
46 * Blowfish library (I can't be sure if I would think of something if I
47 * hadn't seen his code).
48 */
49
50#include <string.h>
51#include <stdint.h>
52
53typedef uint32_t BF_word;
54typedef int32_t BF_word_signed;
55
56/* Number of Blowfish rounds, this is also hardcoded into a few places */
57#define BF_N 16
58
59typedef BF_word BF_key[BF_N + 2];
60
61typedef union {
62 struct {
63 BF_key P;
64 BF_word S[4][0x100];
65 } s;
66 BF_word PS[BF_N + 2 + 4 * 0x100];
67} BF_ctx;
68
69/*
70 * Magic IV for 64 Blowfish encryptions that we do at the end.
71 * The string is "OrpheanBeholderScryDoubt" on big-endian.
72 */
73static const BF_word BF_magic_w[6] = {
74 0x4F727068, 0x65616E42, 0x65686F6C,
75 0x64657253, 0x63727944, 0x6F756274
76};
77
78/*
79 * P-box and S-box tables initialized with digits of Pi.
80 */
81static const BF_ctx BF_init_state = {{
82 {
83 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
84 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
85 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
86 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
87 0x9216d5d9, 0x8979fb1b
88 }, {
89 {
90 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
91 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
92 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
93 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
94 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
95 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
96 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
97 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
98 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
99 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
100 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
101 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
102 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
103 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
104 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
105 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
106 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
107 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
108 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
109 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
110 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
111 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
112 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
113 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
114 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
115 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
116 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
117 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
118 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
119 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
120 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
121 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
122 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
123 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
124 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
125 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
126 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
127 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
128 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
129 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
130 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
131 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
132 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
133 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
134 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
135 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
136 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
137 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
138 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
139 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
140 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
141 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
142 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
143 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
144 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
145 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
146 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
147 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
148 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
149 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
150 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
151 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
152 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
153 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
154 }, {
155 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
156 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
157 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
158 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
159 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
160 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
161 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
162 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
163 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
164 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
165 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
166 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
167 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
168 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
169 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
170 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
171 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
172 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
173 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
174 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
175 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
176 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
177 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
178 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
179 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
180 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
181 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
182 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
183 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
184 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
185 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
186 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
187 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
188 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
189 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
190 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
191 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
192 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
193 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
194 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
195 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
196 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
197 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
198 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
199 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
200 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
201 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
202 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
203 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
204 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
205 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
206 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
207 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
208 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
209 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
210 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
211 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
212 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
213 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
214 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
215 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
216 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
217 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
218 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
219 }, {
220 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
221 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
222 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
223 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
224 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
225 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
226 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
227 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
228 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
229 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
230 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
231 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
232 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
233 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
234 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
235 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
236 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
237 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
238 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
239 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
240 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
241 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
242 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
243 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
244 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
245 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
246 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
247 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
248 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
249 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
250 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
251 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
252 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
253 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
254 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
255 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
256 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
257 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
258 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
259 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
260 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
261 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
262 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
263 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
264 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
265 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
266 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
267 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
268 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
269 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
270 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
271 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
272 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
273 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
274 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
275 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
276 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
277 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
278 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
279 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
280 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
281 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
282 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
283 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
284 }, {
285 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
286 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
287 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
288 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
289 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
290 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
291 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
292 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
293 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
294 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
295 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
296 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
297 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
298 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
299 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
300 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
301 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
302 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
303 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
304 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
305 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
306 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
307 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
308 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
309 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
310 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
311 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
312 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
313 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
314 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
315 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
316 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
317 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
318 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
319 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
320 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
321 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
322 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
323 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
324 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
325 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
326 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
327 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
328 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
329 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
330 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
331 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
332 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
333 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
334 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
335 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
336 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
337 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
338 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
339 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
340 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
341 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
342 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
343 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
344 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
345 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
346 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
347 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
348 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
349 }
350 }
351}};
352
353static const unsigned char BF_itoa64[64 + 1] =
354 "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
355
356static const unsigned char BF_atoi64[0x60] = {
357 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 0, 1,
358 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 64, 64, 64, 64, 64,
359 64, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
360 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 64, 64, 64, 64, 64,
361 64, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
362 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 64, 64, 64, 64, 64
363};
364
365#define BF_safe_atoi64(dst, src) \
366{ \
367 tmp = (unsigned char)(src); \
368 if ((unsigned int)(tmp -= 0x20) >= 0x60) return -1; \
369 tmp = BF_atoi64[tmp]; \
370 if (tmp > 63) return -1; \
371 (dst) = tmp; \
372}
373
374static int BF_decode(BF_word *dst, const char *src, int size)
375{
376 unsigned char *dptr = (unsigned char *)dst;
377 unsigned char *end = dptr + size;
378 const unsigned char *sptr = (const unsigned char *)src;
379 unsigned int tmp, c1, c2, c3, c4;
380
381 do {
382 BF_safe_atoi64(c1, *sptr++);
383 BF_safe_atoi64(c2, *sptr++);
384 *dptr++ = (c1 << 2) | ((c2 & 0x30) >> 4);
385 if (dptr >= end) break;
386
387 BF_safe_atoi64(c3, *sptr++);
388 *dptr++ = ((c2 & 0x0F) << 4) | ((c3 & 0x3C) >> 2);
389 if (dptr >= end) break;
390
391 BF_safe_atoi64(c4, *sptr++);
392 *dptr++ = ((c3 & 0x03) << 6) | c4;
393 } while (dptr < end);
394
395 return 0;
396}
397
398static void BF_encode(char *dst, const BF_word *src, int size)
399{
400 const unsigned char *sptr = (const unsigned char *)src;
401 const unsigned char *end = sptr + size;
402 unsigned char *dptr = (unsigned char *)dst;
403 unsigned int c1, c2;
404
405 do {
406 c1 = *sptr++;
407 *dptr++ = BF_itoa64[c1 >> 2];
408 c1 = (c1 & 0x03) << 4;
409 if (sptr >= end) {
410 *dptr++ = BF_itoa64[c1];
411 break;
412 }
413
414 c2 = *sptr++;
415 c1 |= c2 >> 4;
416 *dptr++ = BF_itoa64[c1];
417 c1 = (c2 & 0x0f) << 2;
418 if (sptr >= end) {
419 *dptr++ = BF_itoa64[c1];
420 break;
421 }
422
423 c2 = *sptr++;
424 c1 |= c2 >> 6;
425 *dptr++ = BF_itoa64[c1];
426 *dptr++ = BF_itoa64[c2 & 0x3f];
427 } while (sptr < end);
428}
429
430static void BF_swap(BF_word *x, int count)
431{
432 if ((union { int i; char c; }){1}.c)
433 do {
434 BF_word tmp = *x;
435 tmp = (tmp << 16) | (tmp >> 16);
436 *x++ = ((tmp & 0x00FF00FF) << 8) | ((tmp >> 8) & 0x00FF00FF);
437 } while (--count);
438}
439
440#define BF_ROUND(L, R, N) \
441 tmp1 = L & 0xFF; \
442 tmp2 = L >> 8; \
443 tmp2 &= 0xFF; \
444 tmp3 = L >> 16; \
445 tmp3 &= 0xFF; \
446 tmp4 = L >> 24; \
447 tmp1 = ctx->s.S[3][tmp1]; \
448 tmp2 = ctx->s.S[2][tmp2]; \
449 tmp3 = ctx->s.S[1][tmp3]; \
450 tmp3 += ctx->s.S[0][tmp4]; \
451 tmp3 ^= tmp2; \
452 R ^= ctx->s.P[N + 1]; \
453 tmp3 += tmp1; \
454 R ^= tmp3;
455
456static BF_word BF_encrypt(BF_ctx *ctx,
457 BF_word L, BF_word R,
458 BF_word *start, BF_word *end)
459{
460 BF_word tmp1, tmp2, tmp3, tmp4;
461 BF_word *ptr = start;
462
463 do {
464 L ^= ctx->s.P[0];
465#if 0
466 BF_ROUND(L, R, 0);
467 BF_ROUND(R, L, 1);
468 BF_ROUND(L, R, 2);
469 BF_ROUND(R, L, 3);
470 BF_ROUND(L, R, 4);
471 BF_ROUND(R, L, 5);
472 BF_ROUND(L, R, 6);
473 BF_ROUND(R, L, 7);
474 BF_ROUND(L, R, 8);
475 BF_ROUND(R, L, 9);
476 BF_ROUND(L, R, 10);
477 BF_ROUND(R, L, 11);
478 BF_ROUND(L, R, 12);
479 BF_ROUND(R, L, 13);
480 BF_ROUND(L, R, 14);
481 BF_ROUND(R, L, 15);
482#else
483 for (int i=0; i<16; i+=2) {
484 BF_ROUND(L, R, i);
485 BF_ROUND(R, L, i+1);
486 }
487#endif
488 tmp4 = R;
489 R = L;
490 L = tmp4 ^ ctx->s.P[BF_N + 1];
491 *ptr++ = L;
492 *ptr++ = R;
493 } while (ptr < end);
494
495 return L;
496}
497
498static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
499 unsigned char flags)
500{
501 const char *ptr = key;
502 unsigned int bug, i, j;
503 BF_word safety, sign, diff, tmp[2];
504
505/*
506 * There was a sign extension bug in older revisions of this function. While
507 * we would have liked to simply fix the bug and move on, we have to provide
508 * a backwards compatibility feature (essentially the bug) for some systems and
509 * a safety measure for some others. The latter is needed because for certain
510 * multiple inputs to the buggy algorithm there exist easily found inputs to
511 * the correct algorithm that produce the same hash. Thus, we optionally
512 * deviate from the correct algorithm just enough to avoid such collisions.
513 * While the bug itself affected the majority of passwords containing
514 * characters with the 8th bit set (although only a percentage of those in a
515 * collision-producing way), the anti-collision safety measure affects
516 * only a subset of passwords containing the '\xff' character (not even all of
517 * those passwords, just some of them). This character is not found in valid
518 * UTF-8 sequences and is rarely used in popular 8-bit character encodings.
519 * Thus, the safety measure is unlikely to cause much annoyance, and is a
520 * reasonable tradeoff to use when authenticating against existing hashes that
521 * are not reliably known to have been computed with the correct algorithm.
522 *
523 * We use an approach that tries to minimize side-channel leaks of password
524 * information - that is, we mostly use fixed-cost bitwise operations instead
525 * of branches or table lookups. (One conditional branch based on password
526 * length remains. It is not part of the bug aftermath, though, and is
527 * difficult and possibly unreasonable to avoid given the use of C strings by
528 * the caller, which results in similar timing leaks anyway.)
529 *
530 * For actual implementation, we set an array index in the variable "bug"
531 * (0 means no bug, 1 means sign extension bug emulation) and a flag in the
532 * variable "safety" (bit 16 is set when the safety measure is requested).
533 * Valid combinations of settings are:
534 *
535 * Prefix "$2a$": bug = 0, safety = 0x10000
536 * Prefix "$2x$": bug = 1, safety = 0
537 * Prefix "$2y$": bug = 0, safety = 0
538 */
539 bug = flags & 1;
540 safety = ((BF_word)flags & 2) << 15;
541
542 sign = diff = 0;
543
544 for (i = 0; i < BF_N + 2; i++) {
545 tmp[0] = tmp[1] = 0;
546 for (j = 0; j < 4; j++) {
547 tmp[0] <<= 8;
548 tmp[0] |= (unsigned char)*ptr; /* correct */
549 tmp[1] <<= 8;
550 tmp[1] |= (signed char)*ptr; /* bug */
551/*
552 * Sign extension in the first char has no effect - nothing to overwrite yet,
553 * and those extra 24 bits will be fully shifted out of the 32-bit word. For
554 * chars 2, 3, 4 in each four-char block, we set bit 7 of "sign" if sign
555 * extension in tmp[1] occurs. Once this flag is set, it remains set.
556 */
557 if (j)
558 sign |= tmp[1] & 0x80;
559 if (!*ptr)
560 ptr = key;
561 else
562 ptr++;
563 }
564 diff |= tmp[0] ^ tmp[1]; /* Non-zero on any differences */
565
566 expanded[i] = tmp[bug];
567 initial[i] = BF_init_state.s.P[i] ^ tmp[bug];
568 }
569
570/*
571 * At this point, "diff" is zero iff the correct and buggy algorithms produced
572 * exactly the same result. If so and if "sign" is non-zero, which indicates
573 * that there was a non-benign sign extension, this means that we have a
574 * collision between the correctly computed hash for this password and a set of
575 * passwords that could be supplied to the buggy algorithm. Our safety measure
576 * is meant to protect from such many-buggy to one-correct collisions, by
577 * deviating from the correct algorithm in such cases. Let's check for this.
578 */
579 diff |= diff >> 16; /* still zero iff exact match */
580 diff &= 0xffff; /* ditto */
581 diff += 0xffff; /* bit 16 set iff "diff" was non-zero (on non-match) */
582 sign <<= 9; /* move the non-benign sign extension flag to bit 16 */
583 sign &= ~diff & safety; /* action needed? */
584
585/*
586 * If we have determined that we need to deviate from the correct algorithm,
587 * flip bit 16 in initial expanded key. (The choice of 16 is arbitrary, but
588 * let's stick to it now. It came out of the approach we used above, and it's
589 * not any worse than any other choice we could make.)
590 *
591 * It is crucial that we don't do the same to the expanded key used in the main
592 * Eksblowfish loop. By doing it to only one of these two, we deviate from a
593 * state that could be directly specified by a password to the buggy algorithm
594 * (and to the fully correct one as well, but that's a side-effect).
595 */
596 initial[0] ^= sign;
597}
598
599static char *BF_crypt(const char *key, const char *setting,
600 char *output, BF_word min)
601{
602 static const unsigned char flags_by_subtype[26] =
603 {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
604 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0};
605 struct {
606 BF_ctx ctx;
607 BF_key expanded_key;
608 union {
609 BF_word salt[4];
610 BF_word output[6];
611 } binary;
612 } data;
613 BF_word count;
614 int i;
615
616 if (setting[0] != '$' ||
617 setting[1] != '2' ||
618 setting[2] - 'a' > 25U ||
619 !flags_by_subtype[setting[2] - 'a'] ||
620 setting[3] != '$' ||
621 setting[4] - '0' > 1U ||
622 setting[5] - '0' > 9U ||
623 setting[6] != '$') {
624 return NULL;
625 }
626
627 count = (BF_word)1 << ((setting[4] - '0') * 10 + (setting[5] - '0'));
628 if (count < min || BF_decode(data.binary.salt, &setting[7], 16)) {
629 return NULL;
630 }
631 BF_swap(data.binary.salt, 4);
632
633 BF_set_key(key, data.expanded_key, data.ctx.s.P,
634 flags_by_subtype[setting[2] - 'a']);
635
636 memcpy(data.ctx.s.S, BF_init_state.s.S, sizeof(data.ctx.s.S));
637
638 {
639 BF_word L = 0, R = 0;
640 BF_word *ptr = &data.ctx.PS[0];
641 do {
642 L = BF_encrypt(&data.ctx,
643 L ^ data.binary.salt[0], R ^ data.binary.salt[1],
644 ptr, ptr);
645 R = *(ptr + 1);
646 ptr += 2;
647
648 if (ptr >= &data.ctx.PS[BF_N + 2 + 4 * 0x100])
649 break;
650
651 L = BF_encrypt(&data.ctx,
652 L ^ data.binary.salt[2], R ^ data.binary.salt[3],
653 ptr, ptr);
654 R = *(ptr + 1);
655 ptr += 2;
656 } while (1);
657 }
658
659 do {
660 int done;
661
662 for (i = 0; i < BF_N + 2; i += 2) {
663 data.ctx.s.P[i] ^= data.expanded_key[i];
664 data.ctx.s.P[i + 1] ^= data.expanded_key[i + 1];
665 }
666
667 done = 0;
668 do {
669 BF_encrypt(&data.ctx, 0, 0,
670 &data.ctx.PS[0],
671 &data.ctx.PS[BF_N + 2 + 4 * 0x100]);
672
673 if (done)
674 break;
675 done = 1;
676
677 {
678 BF_word tmp1, tmp2, tmp3, tmp4;
679
680 tmp1 = data.binary.salt[0];
681 tmp2 = data.binary.salt[1];
682 tmp3 = data.binary.salt[2];
683 tmp4 = data.binary.salt[3];
684 for (i = 0; i < BF_N; i += 4) {
685 data.ctx.s.P[i] ^= tmp1;
686 data.ctx.s.P[i + 1] ^= tmp2;
687 data.ctx.s.P[i + 2] ^= tmp3;
688 data.ctx.s.P[i + 3] ^= tmp4;
689 }
690 data.ctx.s.P[16] ^= tmp1;
691 data.ctx.s.P[17] ^= tmp2;
692 }
693 } while (1);
694 } while (--count);
695
696 for (i = 0; i < 6; i += 2) {
697 BF_word L, LR[2];
698
699 L = BF_magic_w[i];
700 LR[1] = BF_magic_w[i + 1];
701
702 count = 64;
703 do {
704 L = BF_encrypt(&data.ctx, L, LR[1],
705 &LR[0], &LR[0]);
706 } while (--count);
707
708 data.binary.output[i] = L;
709 data.binary.output[i + 1] = LR[1];
710 }
711
712 memcpy(output, setting, 7 + 22 - 1);
713 output[7 + 22 - 1] = BF_itoa64[
714 BF_atoi64[setting[7 + 22 - 1] - 0x20] & 0x30];
715
716/* This has to be bug-compatible with the original implementation, so
717 * only encode 23 of the 24 bytes. :-) */
718 BF_swap(data.binary.output, 6);
719 BF_encode(&output[7 + 22], data.binary.output, 23);
720 output[7 + 22 + 31] = '\0';
721
722 return output;
723}
724
725/*
726 * Please preserve the runtime self-test. It serves two purposes at once:
727 *
728 * 1. We really can't afford the risk of producing incompatible hashes e.g.
729 * when there's something like gcc bug 26587 again, whereas an application or
730 * library integrating this code might not also integrate our external tests or
731 * it might not run them after every build. Even if it does, the miscompile
732 * might only occur on the production build, but not on a testing build (such
733 * as because of different optimization settings). It is painful to recover
734 * from incorrectly-computed hashes - merely fixing whatever broke is not
735 * enough. Thus, a proactive measure like this self-test is needed.
736 *
737 * 2. We don't want to leave sensitive data from our actual password hash
738 * computation on the stack or in registers. Previous revisions of the code
739 * would do explicit cleanups, but simply running the self-test after hash
740 * computation is more reliable.
741 *
742 * The performance cost of this quick self-test is around 0.6% at the "$2a$08"
743 * setting.
744 */
745char *__crypt_blowfish(const char *key, const char *setting, char *output)
746{
747 const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
748 const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu";
749 static const char test_hash[2][34] =
750 {"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* $2x$ */
751 "i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55"}; /* $2a$, $2y$ */
752 char *retval;
753 const char *p;
754 int ok;
755 struct {
756 char s[7 + 22 + 1];
757 char o[7 + 22 + 31 + 1 + 1 + 1];
758 } buf;
759
760/* Hash the supplied password */
761 retval = BF_crypt(key, setting, output, 16);
762
763/*
764 * Do a quick self-test. It is important that we make both calls to BF_crypt()
765 * from the same scope such that they likely use the same stack locations,
766 * which makes the second call overwrite the first call's sensitive data on the
767 * stack and makes it more likely that any alignment related issues would be
768 * detected by the self-test.
769 */
770 memcpy(buf.s, test_setting, sizeof(buf.s));
771 if (retval)
772 buf.s[2] = setting[2];
773 memset(buf.o, 0x55, sizeof(buf.o));
774 buf.o[sizeof(buf.o) - 1] = 0;
775 p = BF_crypt(test_key, buf.s, buf.o, 1);
776
777 ok = (p == buf.o &&
778 !memcmp(p, buf.s, 7 + 22) &&
779 !memcmp(p + (7 + 22),
780 test_hash[buf.s[2] & 1],
781 31 + 1 + 1 + 1));
782
783 {
784 const char *k = "\xff\xa3" "34" "\xff\xff\xff\xa3" "345";
785 BF_key ae, ai, ye, yi;
786 BF_set_key(k, ae, ai, 2); /* $2a$ */
787 BF_set_key(k, ye, yi, 4); /* $2y$ */
788 ai[0] ^= 0x10000; /* undo the safety (for comparison) */
789 ok = ok && ai[0] == 0xdb9c59bc && ye[17] == 0x33343500 &&
790 !memcmp(ae, ye, sizeof(ae)) &&
791 !memcmp(ai, yi, sizeof(ai));
792 }
793
794 if (ok && retval)
795 return retval;
796
797 return "*";
798}
libc/musl/src/crypt/crypt_des.c created+1016
......@@ -0,0 +1,1016 @@
1/*
2 * This version has been further modified by Rich Felker, primary author
3 * and maintainer of musl libc, to remove table generation code and
4 * replaced all runtime-generated constant tables with static-initialized
5 * tables in the binary, in the interest of minimizing non-shareable
6 * memory usage and stack size requirements.
7 */
8/*
9 * This version is derived from the original implementation of FreeSec
10 * (release 1.1) by David Burren. I've made it reentrant, reduced its memory
11 * usage from about 70 KB to about 7 KB (with only minimal performance impact
12 * and keeping code size about the same), made the handling of invalid salts
13 * mostly UFC-crypt compatible, added a quick runtime self-test (which also
14 * serves to zeroize the stack from sensitive data), and added optional tests.
15 * - Solar Designer <solar at openwall.com>
16 */
17
18/*
19 * FreeSec: libcrypt for NetBSD
20 *
21 * Copyright (c) 1994 David Burren
22 * Copyright (c) 2000,2002,2010,2012 Solar Designer
23 * All rights reserved.
24 *
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 * 1. Redistributions of source code must retain the above copyright
29 * notice, this list of conditions and the following disclaimer.
30 * 2. Redistributions in binary form must reproduce the above copyright
31 * notice, this list of conditions and the following disclaimer in the
32 * documentation and/or other materials provided with the distribution.
33 * 3. Neither the name of the author nor the names of other contributors
34 * may be used to endorse or promote products derived from this software
35 * without specific prior written permission.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
38 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
40 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
41 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
42 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
43 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
45 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
46 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 *
49 * $Owl: Owl/packages/glibc/crypt_freesec.c,v 1.6 2010/02/20 14:45:06 solar Exp $
50 * $Id: crypt.c,v 1.15 1994/09/13 04:58:49 davidb Exp $
51 *
52 * This is an original implementation of the DES and the crypt(3) interfaces
53 * by David Burren. It has been heavily re-worked by Solar Designer.
54 */
55
56#include <stdint.h>
57#include <string.h>
58
59#include "crypt_des.h"
60
61#define _PASSWORD_EFMT1 '_'
62
63static const unsigned char key_shifts[16] = {
64 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
65};
66
67static const uint32_t psbox[8][64] = {
68 {
69 0x00808200,0x00000000,0x00008000,0x00808202,
70 0x00808002,0x00008202,0x00000002,0x00008000,
71 0x00000200,0x00808200,0x00808202,0x00000200,
72 0x00800202,0x00808002,0x00800000,0x00000002,
73 0x00000202,0x00800200,0x00800200,0x00008200,
74 0x00008200,0x00808000,0x00808000,0x00800202,
75 0x00008002,0x00800002,0x00800002,0x00008002,
76 0x00000000,0x00000202,0x00008202,0x00800000,
77 0x00008000,0x00808202,0x00000002,0x00808000,
78 0x00808200,0x00800000,0x00800000,0x00000200,
79 0x00808002,0x00008000,0x00008200,0x00800002,
80 0x00000200,0x00000002,0x00800202,0x00008202,
81 0x00808202,0x00008002,0x00808000,0x00800202,
82 0x00800002,0x00000202,0x00008202,0x00808200,
83 0x00000202,0x00800200,0x00800200,0x00000000,
84 0x00008002,0x00008200,0x00000000,0x00808002,
85 },{
86 0x40084010,0x40004000,0x00004000,0x00084010,
87 0x00080000,0x00000010,0x40080010,0x40004010,
88 0x40000010,0x40084010,0x40084000,0x40000000,
89 0x40004000,0x00080000,0x00000010,0x40080010,
90 0x00084000,0x00080010,0x40004010,0x00000000,
91 0x40000000,0x00004000,0x00084010,0x40080000,
92 0x00080010,0x40000010,0x00000000,0x00084000,
93 0x00004010,0x40084000,0x40080000,0x00004010,
94 0x00000000,0x00084010,0x40080010,0x00080000,
95 0x40004010,0x40080000,0x40084000,0x00004000,
96 0x40080000,0x40004000,0x00000010,0x40084010,
97 0x00084010,0x00000010,0x00004000,0x40000000,
98 0x00004010,0x40084000,0x00080000,0x40000010,
99 0x00080010,0x40004010,0x40000010,0x00080010,
100 0x00084000,0x00000000,0x40004000,0x00004010,
101 0x40000000,0x40080010,0x40084010,0x00084000,
102 },{
103 0x00000104,0x04010100,0x00000000,0x04010004,
104 0x04000100,0x00000000,0x00010104,0x04000100,
105 0x00010004,0x04000004,0x04000004,0x00010000,
106 0x04010104,0x00010004,0x04010000,0x00000104,
107 0x04000000,0x00000004,0x04010100,0x00000100,
108 0x00010100,0x04010000,0x04010004,0x00010104,
109 0x04000104,0x00010100,0x00010000,0x04000104,
110 0x00000004,0x04010104,0x00000100,0x04000000,
111 0x04010100,0x04000000,0x00010004,0x00000104,
112 0x00010000,0x04010100,0x04000100,0x00000000,
113 0x00000100,0x00010004,0x04010104,0x04000100,
114 0x04000004,0x00000100,0x00000000,0x04010004,
115 0x04000104,0x00010000,0x04000000,0x04010104,
116 0x00000004,0x00010104,0x00010100,0x04000004,
117 0x04010000,0x04000104,0x00000104,0x04010000,
118 0x00010104,0x00000004,0x04010004,0x00010100,
119 },{
120 0x80401000,0x80001040,0x80001040,0x00000040,
121 0x00401040,0x80400040,0x80400000,0x80001000,
122 0x00000000,0x00401000,0x00401000,0x80401040,
123 0x80000040,0x00000000,0x00400040,0x80400000,
124 0x80000000,0x00001000,0x00400000,0x80401000,
125 0x00000040,0x00400000,0x80001000,0x00001040,
126 0x80400040,0x80000000,0x00001040,0x00400040,
127 0x00001000,0x00401040,0x80401040,0x80000040,
128 0x00400040,0x80400000,0x00401000,0x80401040,
129 0x80000040,0x00000000,0x00000000,0x00401000,
130 0x00001040,0x00400040,0x80400040,0x80000000,
131 0x80401000,0x80001040,0x80001040,0x00000040,
132 0x80401040,0x80000040,0x80000000,0x00001000,
133 0x80400000,0x80001000,0x00401040,0x80400040,
134 0x80001000,0x00001040,0x00400000,0x80401000,
135 0x00000040,0x00400000,0x00001000,0x00401040,
136 },{
137 0x00000080,0x01040080,0x01040000,0x21000080,
138 0x00040000,0x00000080,0x20000000,0x01040000,
139 0x20040080,0x00040000,0x01000080,0x20040080,
140 0x21000080,0x21040000,0x00040080,0x20000000,
141 0x01000000,0x20040000,0x20040000,0x00000000,
142 0x20000080,0x21040080,0x21040080,0x01000080,
143 0x21040000,0x20000080,0x00000000,0x21000000,
144 0x01040080,0x01000000,0x21000000,0x00040080,
145 0x00040000,0x21000080,0x00000080,0x01000000,
146 0x20000000,0x01040000,0x21000080,0x20040080,
147 0x01000080,0x20000000,0x21040000,0x01040080,
148 0x20040080,0x00000080,0x01000000,0x21040000,
149 0x21040080,0x00040080,0x21000000,0x21040080,
150 0x01040000,0x00000000,0x20040000,0x21000000,
151 0x00040080,0x01000080,0x20000080,0x00040000,
152 0x00000000,0x20040000,0x01040080,0x20000080,
153 },{
154 0x10000008,0x10200000,0x00002000,0x10202008,
155 0x10200000,0x00000008,0x10202008,0x00200000,
156 0x10002000,0x00202008,0x00200000,0x10000008,
157 0x00200008,0x10002000,0x10000000,0x00002008,
158 0x00000000,0x00200008,0x10002008,0x00002000,
159 0x00202000,0x10002008,0x00000008,0x10200008,
160 0x10200008,0x00000000,0x00202008,0x10202000,
161 0x00002008,0x00202000,0x10202000,0x10000000,
162 0x10002000,0x00000008,0x10200008,0x00202000,
163 0x10202008,0x00200000,0x00002008,0x10000008,
164 0x00200000,0x10002000,0x10000000,0x00002008,
165 0x10000008,0x10202008,0x00202000,0x10200000,
166 0x00202008,0x10202000,0x00000000,0x10200008,
167 0x00000008,0x00002000,0x10200000,0x00202008,
168 0x00002000,0x00200008,0x10002008,0x00000000,
169 0x10202000,0x10000000,0x00200008,0x10002008,
170 },{
171 0x00100000,0x02100001,0x02000401,0x00000000,
172 0x00000400,0x02000401,0x00100401,0x02100400,
173 0x02100401,0x00100000,0x00000000,0x02000001,
174 0x00000001,0x02000000,0x02100001,0x00000401,
175 0x02000400,0x00100401,0x00100001,0x02000400,
176 0x02000001,0x02100000,0x02100400,0x00100001,
177 0x02100000,0x00000400,0x00000401,0x02100401,
178 0x00100400,0x00000001,0x02000000,0x00100400,
179 0x02000000,0x00100400,0x00100000,0x02000401,
180 0x02000401,0x02100001,0x02100001,0x00000001,
181 0x00100001,0x02000000,0x02000400,0x00100000,
182 0x02100400,0x00000401,0x00100401,0x02100400,
183 0x00000401,0x02000001,0x02100401,0x02100000,
184 0x00100400,0x00000000,0x00000001,0x02100401,
185 0x00000000,0x00100401,0x02100000,0x00000400,
186 0x02000001,0x02000400,0x00000400,0x00100001,
187 },{
188 0x08000820,0x00000800,0x00020000,0x08020820,
189 0x08000000,0x08000820,0x00000020,0x08000000,
190 0x00020020,0x08020000,0x08020820,0x00020800,
191 0x08020800,0x00020820,0x00000800,0x00000020,
192 0x08020000,0x08000020,0x08000800,0x00000820,
193 0x00020800,0x00020020,0x08020020,0x08020800,
194 0x00000820,0x00000000,0x00000000,0x08020020,
195 0x08000020,0x08000800,0x00020820,0x00020000,
196 0x00020820,0x00020000,0x08020800,0x00000800,
197 0x00000020,0x08020020,0x00000800,0x00020820,
198 0x08000800,0x00000020,0x08000020,0x08020000,
199 0x08020020,0x08000000,0x00020000,0x08000820,
200 0x00000000,0x08020820,0x00020020,0x08000020,
201 0x08020000,0x08000800,0x08000820,0x00000000,
202 0x08020820,0x00020800,0x00020800,0x00000820,
203 0x00000820,0x00020020,0x08000000,0x08020800,
204 },
205};
206static const uint32_t ip_maskl[16][16] = {
207 {
208 0x00000000,0x00010000,0x00000000,0x00010000,
209 0x01000000,0x01010000,0x01000000,0x01010000,
210 0x00000000,0x00010000,0x00000000,0x00010000,
211 0x01000000,0x01010000,0x01000000,0x01010000,
212 },{
213 0x00000000,0x00000001,0x00000000,0x00000001,
214 0x00000100,0x00000101,0x00000100,0x00000101,
215 0x00000000,0x00000001,0x00000000,0x00000001,
216 0x00000100,0x00000101,0x00000100,0x00000101,
217 },{
218 0x00000000,0x00020000,0x00000000,0x00020000,
219 0x02000000,0x02020000,0x02000000,0x02020000,
220 0x00000000,0x00020000,0x00000000,0x00020000,
221 0x02000000,0x02020000,0x02000000,0x02020000,
222 },{
223 0x00000000,0x00000002,0x00000000,0x00000002,
224 0x00000200,0x00000202,0x00000200,0x00000202,
225 0x00000000,0x00000002,0x00000000,0x00000002,
226 0x00000200,0x00000202,0x00000200,0x00000202,
227 },{
228 0x00000000,0x00040000,0x00000000,0x00040000,
229 0x04000000,0x04040000,0x04000000,0x04040000,
230 0x00000000,0x00040000,0x00000000,0x00040000,
231 0x04000000,0x04040000,0x04000000,0x04040000,
232 },{
233 0x00000000,0x00000004,0x00000000,0x00000004,
234 0x00000400,0x00000404,0x00000400,0x00000404,
235 0x00000000,0x00000004,0x00000000,0x00000004,
236 0x00000400,0x00000404,0x00000400,0x00000404,
237 },{
238 0x00000000,0x00080000,0x00000000,0x00080000,
239 0x08000000,0x08080000,0x08000000,0x08080000,
240 0x00000000,0x00080000,0x00000000,0x00080000,
241 0x08000000,0x08080000,0x08000000,0x08080000,
242 },{
243 0x00000000,0x00000008,0x00000000,0x00000008,
244 0x00000800,0x00000808,0x00000800,0x00000808,
245 0x00000000,0x00000008,0x00000000,0x00000008,
246 0x00000800,0x00000808,0x00000800,0x00000808,
247 },{
248 0x00000000,0x00100000,0x00000000,0x00100000,
249 0x10000000,0x10100000,0x10000000,0x10100000,
250 0x00000000,0x00100000,0x00000000,0x00100000,
251 0x10000000,0x10100000,0x10000000,0x10100000,
252 },{
253 0x00000000,0x00000010,0x00000000,0x00000010,
254 0x00001000,0x00001010,0x00001000,0x00001010,
255 0x00000000,0x00000010,0x00000000,0x00000010,
256 0x00001000,0x00001010,0x00001000,0x00001010,
257 },{
258 0x00000000,0x00200000,0x00000000,0x00200000,
259 0x20000000,0x20200000,0x20000000,0x20200000,
260 0x00000000,0x00200000,0x00000000,0x00200000,
261 0x20000000,0x20200000,0x20000000,0x20200000,
262 },{
263 0x00000000,0x00000020,0x00000000,0x00000020,
264 0x00002000,0x00002020,0x00002000,0x00002020,
265 0x00000000,0x00000020,0x00000000,0x00000020,
266 0x00002000,0x00002020,0x00002000,0x00002020,
267 },{
268 0x00000000,0x00400000,0x00000000,0x00400000,
269 0x40000000,0x40400000,0x40000000,0x40400000,
270 0x00000000,0x00400000,0x00000000,0x00400000,
271 0x40000000,0x40400000,0x40000000,0x40400000,
272 },{
273 0x00000000,0x00000040,0x00000000,0x00000040,
274 0x00004000,0x00004040,0x00004000,0x00004040,
275 0x00000000,0x00000040,0x00000000,0x00000040,
276 0x00004000,0x00004040,0x00004000,0x00004040,
277 },{
278 0x00000000,0x00800000,0x00000000,0x00800000,
279 0x80000000,0x80800000,0x80000000,0x80800000,
280 0x00000000,0x00800000,0x00000000,0x00800000,
281 0x80000000,0x80800000,0x80000000,0x80800000,
282 },{
283 0x00000000,0x00000080,0x00000000,0x00000080,
284 0x00008000,0x00008080,0x00008000,0x00008080,
285 0x00000000,0x00000080,0x00000000,0x00000080,
286 0x00008000,0x00008080,0x00008000,0x00008080,
287 },
288};
289static const uint32_t ip_maskr[16][16] = {
290 {
291 0x00000000,0x00000000,0x00010000,0x00010000,
292 0x00000000,0x00000000,0x00010000,0x00010000,
293 0x01000000,0x01000000,0x01010000,0x01010000,
294 0x01000000,0x01000000,0x01010000,0x01010000,
295 },{
296 0x00000000,0x00000000,0x00000001,0x00000001,
297 0x00000000,0x00000000,0x00000001,0x00000001,
298 0x00000100,0x00000100,0x00000101,0x00000101,
299 0x00000100,0x00000100,0x00000101,0x00000101,
300 },{
301 0x00000000,0x00000000,0x00020000,0x00020000,
302 0x00000000,0x00000000,0x00020000,0x00020000,
303 0x02000000,0x02000000,0x02020000,0x02020000,
304 0x02000000,0x02000000,0x02020000,0x02020000,
305 },{
306 0x00000000,0x00000000,0x00000002,0x00000002,
307 0x00000000,0x00000000,0x00000002,0x00000002,
308 0x00000200,0x00000200,0x00000202,0x00000202,
309 0x00000200,0x00000200,0x00000202,0x00000202,
310 },{
311 0x00000000,0x00000000,0x00040000,0x00040000,
312 0x00000000,0x00000000,0x00040000,0x00040000,
313 0x04000000,0x04000000,0x04040000,0x04040000,
314 0x04000000,0x04000000,0x04040000,0x04040000,
315 },{
316 0x00000000,0x00000000,0x00000004,0x00000004,
317 0x00000000,0x00000000,0x00000004,0x00000004,
318 0x00000400,0x00000400,0x00000404,0x00000404,
319 0x00000400,0x00000400,0x00000404,0x00000404,
320 },{
321 0x00000000,0x00000000,0x00080000,0x00080000,
322 0x00000000,0x00000000,0x00080000,0x00080000,
323 0x08000000,0x08000000,0x08080000,0x08080000,
324 0x08000000,0x08000000,0x08080000,0x08080000,
325 },{
326 0x00000000,0x00000000,0x00000008,0x00000008,
327 0x00000000,0x00000000,0x00000008,0x00000008,
328 0x00000800,0x00000800,0x00000808,0x00000808,
329 0x00000800,0x00000800,0x00000808,0x00000808,
330 },{
331 0x00000000,0x00000000,0x00100000,0x00100000,
332 0x00000000,0x00000000,0x00100000,0x00100000,
333 0x10000000,0x10000000,0x10100000,0x10100000,
334 0x10000000,0x10000000,0x10100000,0x10100000,
335 },{
336 0x00000000,0x00000000,0x00000010,0x00000010,
337 0x00000000,0x00000000,0x00000010,0x00000010,
338 0x00001000,0x00001000,0x00001010,0x00001010,
339 0x00001000,0x00001000,0x00001010,0x00001010,
340 },{
341 0x00000000,0x00000000,0x00200000,0x00200000,
342 0x00000000,0x00000000,0x00200000,0x00200000,
343 0x20000000,0x20000000,0x20200000,0x20200000,
344 0x20000000,0x20000000,0x20200000,0x20200000,
345 },{
346 0x00000000,0x00000000,0x00000020,0x00000020,
347 0x00000000,0x00000000,0x00000020,0x00000020,
348 0x00002000,0x00002000,0x00002020,0x00002020,
349 0x00002000,0x00002000,0x00002020,0x00002020,
350 },{
351 0x00000000,0x00000000,0x00400000,0x00400000,
352 0x00000000,0x00000000,0x00400000,0x00400000,
353 0x40000000,0x40000000,0x40400000,0x40400000,
354 0x40000000,0x40000000,0x40400000,0x40400000,
355 },{
356 0x00000000,0x00000000,0x00000040,0x00000040,
357 0x00000000,0x00000000,0x00000040,0x00000040,
358 0x00004000,0x00004000,0x00004040,0x00004040,
359 0x00004000,0x00004000,0x00004040,0x00004040,
360 },{
361 0x00000000,0x00000000,0x00800000,0x00800000,
362 0x00000000,0x00000000,0x00800000,0x00800000,
363 0x80000000,0x80000000,0x80800000,0x80800000,
364 0x80000000,0x80000000,0x80800000,0x80800000,
365 },{
366 0x00000000,0x00000000,0x00000080,0x00000080,
367 0x00000000,0x00000000,0x00000080,0x00000080,
368 0x00008000,0x00008000,0x00008080,0x00008080,
369 0x00008000,0x00008000,0x00008080,0x00008080,
370 },
371};
372static const uint32_t fp_maskl[8][16] = {
373 {
374 0x00000000,0x40000000,0x00400000,0x40400000,
375 0x00004000,0x40004000,0x00404000,0x40404000,
376 0x00000040,0x40000040,0x00400040,0x40400040,
377 0x00004040,0x40004040,0x00404040,0x40404040,
378 },{
379 0x00000000,0x10000000,0x00100000,0x10100000,
380 0x00001000,0x10001000,0x00101000,0x10101000,
381 0x00000010,0x10000010,0x00100010,0x10100010,
382 0x00001010,0x10001010,0x00101010,0x10101010,
383 },{
384 0x00000000,0x04000000,0x00040000,0x04040000,
385 0x00000400,0x04000400,0x00040400,0x04040400,
386 0x00000004,0x04000004,0x00040004,0x04040004,
387 0x00000404,0x04000404,0x00040404,0x04040404,
388 },{
389 0x00000000,0x01000000,0x00010000,0x01010000,
390 0x00000100,0x01000100,0x00010100,0x01010100,
391 0x00000001,0x01000001,0x00010001,0x01010001,
392 0x00000101,0x01000101,0x00010101,0x01010101,
393 },{
394 0x00000000,0x80000000,0x00800000,0x80800000,
395 0x00008000,0x80008000,0x00808000,0x80808000,
396 0x00000080,0x80000080,0x00800080,0x80800080,
397 0x00008080,0x80008080,0x00808080,0x80808080,
398 },{
399 0x00000000,0x20000000,0x00200000,0x20200000,
400 0x00002000,0x20002000,0x00202000,0x20202000,
401 0x00000020,0x20000020,0x00200020,0x20200020,
402 0x00002020,0x20002020,0x00202020,0x20202020,
403 },{
404 0x00000000,0x08000000,0x00080000,0x08080000,
405 0x00000800,0x08000800,0x00080800,0x08080800,
406 0x00000008,0x08000008,0x00080008,0x08080008,
407 0x00000808,0x08000808,0x00080808,0x08080808,
408 },{
409 0x00000000,0x02000000,0x00020000,0x02020000,
410 0x00000200,0x02000200,0x00020200,0x02020200,
411 0x00000002,0x02000002,0x00020002,0x02020002,
412 0x00000202,0x02000202,0x00020202,0x02020202,
413 },
414};
415static const uint32_t fp_maskr[8][16] = {
416 {
417 0x00000000,0x40000000,0x00400000,0x40400000,
418 0x00004000,0x40004000,0x00404000,0x40404000,
419 0x00000040,0x40000040,0x00400040,0x40400040,
420 0x00004040,0x40004040,0x00404040,0x40404040,
421 },{
422 0x00000000,0x10000000,0x00100000,0x10100000,
423 0x00001000,0x10001000,0x00101000,0x10101000,
424 0x00000010,0x10000010,0x00100010,0x10100010,
425 0x00001010,0x10001010,0x00101010,0x10101010,
426 },{
427 0x00000000,0x04000000,0x00040000,0x04040000,
428 0x00000400,0x04000400,0x00040400,0x04040400,
429 0x00000004,0x04000004,0x00040004,0x04040004,
430 0x00000404,0x04000404,0x00040404,0x04040404,
431 },{
432 0x00000000,0x01000000,0x00010000,0x01010000,
433 0x00000100,0x01000100,0x00010100,0x01010100,
434 0x00000001,0x01000001,0x00010001,0x01010001,
435 0x00000101,0x01000101,0x00010101,0x01010101,
436 },{
437 0x00000000,0x80000000,0x00800000,0x80800000,
438 0x00008000,0x80008000,0x00808000,0x80808000,
439 0x00000080,0x80000080,0x00800080,0x80800080,
440 0x00008080,0x80008080,0x00808080,0x80808080,
441 },{
442 0x00000000,0x20000000,0x00200000,0x20200000,
443 0x00002000,0x20002000,0x00202000,0x20202000,
444 0x00000020,0x20000020,0x00200020,0x20200020,
445 0x00002020,0x20002020,0x00202020,0x20202020,
446 },{
447 0x00000000,0x08000000,0x00080000,0x08080000,
448 0x00000800,0x08000800,0x00080800,0x08080800,
449 0x00000008,0x08000008,0x00080008,0x08080008,
450 0x00000808,0x08000808,0x00080808,0x08080808,
451 },{
452 0x00000000,0x02000000,0x00020000,0x02020000,
453 0x00000200,0x02000200,0x00020200,0x02020200,
454 0x00000002,0x02000002,0x00020002,0x02020002,
455 0x00000202,0x02000202,0x00020202,0x02020202,
456 },
457};
458static const uint32_t key_perm_maskl[8][16] = {
459 {
460 0x00000000,0x00000000,0x00000010,0x00000010,
461 0x00001000,0x00001000,0x00001010,0x00001010,
462 0x00100000,0x00100000,0x00100010,0x00100010,
463 0x00101000,0x00101000,0x00101010,0x00101010,
464 },{
465 0x00000000,0x00000000,0x00000020,0x00000020,
466 0x00002000,0x00002000,0x00002020,0x00002020,
467 0x00200000,0x00200000,0x00200020,0x00200020,
468 0x00202000,0x00202000,0x00202020,0x00202020,
469 },{
470 0x00000000,0x00000000,0x00000040,0x00000040,
471 0x00004000,0x00004000,0x00004040,0x00004040,
472 0x00400000,0x00400000,0x00400040,0x00400040,
473 0x00404000,0x00404000,0x00404040,0x00404040,
474 },{
475 0x00000000,0x00000000,0x00000080,0x00000080,
476 0x00008000,0x00008000,0x00008080,0x00008080,
477 0x00800000,0x00800000,0x00800080,0x00800080,
478 0x00808000,0x00808000,0x00808080,0x00808080,
479 },{
480 0x00000000,0x00000001,0x00000100,0x00000101,
481 0x00010000,0x00010001,0x00010100,0x00010101,
482 0x01000000,0x01000001,0x01000100,0x01000101,
483 0x01010000,0x01010001,0x01010100,0x01010101,
484 },{
485 0x00000000,0x00000002,0x00000200,0x00000202,
486 0x00020000,0x00020002,0x00020200,0x00020202,
487 0x02000000,0x02000002,0x02000200,0x02000202,
488 0x02020000,0x02020002,0x02020200,0x02020202,
489 },{
490 0x00000000,0x00000004,0x00000400,0x00000404,
491 0x00040000,0x00040004,0x00040400,0x00040404,
492 0x04000000,0x04000004,0x04000400,0x04000404,
493 0x04040000,0x04040004,0x04040400,0x04040404,
494 },{
495 0x00000000,0x00000008,0x00000800,0x00000808,
496 0x00080000,0x00080008,0x00080800,0x00080808,
497 0x08000000,0x08000008,0x08000800,0x08000808,
498 0x08080000,0x08080008,0x08080800,0x08080808,
499 },
500};
501static const uint32_t key_perm_maskr[12][16] = {
502 {
503 0x00000000,0x00000001,0x00000000,0x00000001,
504 0x00000000,0x00000001,0x00000000,0x00000001,
505 0x00000000,0x00000001,0x00000000,0x00000001,
506 0x00000000,0x00000001,0x00000000,0x00000001,
507 },{
508 0x00000000,0x00000000,0x00100000,0x00100000,
509 0x00001000,0x00001000,0x00101000,0x00101000,
510 0x00000010,0x00000010,0x00100010,0x00100010,
511 0x00001010,0x00001010,0x00101010,0x00101010,
512 },{
513 0x00000000,0x00000002,0x00000000,0x00000002,
514 0x00000000,0x00000002,0x00000000,0x00000002,
515 0x00000000,0x00000002,0x00000000,0x00000002,
516 0x00000000,0x00000002,0x00000000,0x00000002,
517 },{
518 0x00000000,0x00000000,0x00200000,0x00200000,
519 0x00002000,0x00002000,0x00202000,0x00202000,
520 0x00000020,0x00000020,0x00200020,0x00200020,
521 0x00002020,0x00002020,0x00202020,0x00202020,
522 },{
523 0x00000000,0x00000004,0x00000000,0x00000004,
524 0x00000000,0x00000004,0x00000000,0x00000004,
525 0x00000000,0x00000004,0x00000000,0x00000004,
526 0x00000000,0x00000004,0x00000000,0x00000004,
527 },{
528 0x00000000,0x00000000,0x00400000,0x00400000,
529 0x00004000,0x00004000,0x00404000,0x00404000,
530 0x00000040,0x00000040,0x00400040,0x00400040,
531 0x00004040,0x00004040,0x00404040,0x00404040,
532 },{
533 0x00000000,0x00000008,0x00000000,0x00000008,
534 0x00000000,0x00000008,0x00000000,0x00000008,
535 0x00000000,0x00000008,0x00000000,0x00000008,
536 0x00000000,0x00000008,0x00000000,0x00000008,
537 },{
538 0x00000000,0x00000000,0x00800000,0x00800000,
539 0x00008000,0x00008000,0x00808000,0x00808000,
540 0x00000080,0x00000080,0x00800080,0x00800080,
541 0x00008080,0x00008080,0x00808080,0x00808080,
542 },{
543 0x00000000,0x00000000,0x01000000,0x01000000,
544 0x00010000,0x00010000,0x01010000,0x01010000,
545 0x00000100,0x00000100,0x01000100,0x01000100,
546 0x00010100,0x00010100,0x01010100,0x01010100,
547 },{
548 0x00000000,0x00000000,0x02000000,0x02000000,
549 0x00020000,0x00020000,0x02020000,0x02020000,
550 0x00000200,0x00000200,0x02000200,0x02000200,
551 0x00020200,0x00020200,0x02020200,0x02020200,
552 },{
553 0x00000000,0x00000000,0x04000000,0x04000000,
554 0x00040000,0x00040000,0x04040000,0x04040000,
555 0x00000400,0x00000400,0x04000400,0x04000400,
556 0x00040400,0x00040400,0x04040400,0x04040400,
557 },{
558 0x00000000,0x00000000,0x08000000,0x08000000,
559 0x00080000,0x00080000,0x08080000,0x08080000,
560 0x00000800,0x00000800,0x08000800,0x08000800,
561 0x00080800,0x00080800,0x08080800,0x08080800,
562 },
563};
564static const uint32_t comp_maskl0[4][8] = {
565 {
566 0x00000000,0x00020000,0x00000001,0x00020001,
567 0x00080000,0x000a0000,0x00080001,0x000a0001,
568 },{
569 0x00000000,0x00001000,0x00000000,0x00001000,
570 0x00000040,0x00001040,0x00000040,0x00001040,
571 },{
572 0x00000000,0x00400000,0x00000020,0x00400020,
573 0x00008000,0x00408000,0x00008020,0x00408020,
574 },{
575 0x00000000,0x00100000,0x00000800,0x00100800,
576 0x00000000,0x00100000,0x00000800,0x00100800,
577 },
578};
579static const uint32_t comp_maskr0[4][8] = {
580 {
581 0x00000000,0x00200000,0x00020000,0x00220000,
582 0x00000002,0x00200002,0x00020002,0x00220002,
583 },{
584 0x00000000,0x00000000,0x00100000,0x00100000,
585 0x00000004,0x00000004,0x00100004,0x00100004,
586 },{
587 0x00000000,0x00004000,0x00000800,0x00004800,
588 0x00000000,0x00004000,0x00000800,0x00004800,
589 },{
590 0x00000000,0x00400000,0x00008000,0x00408000,
591 0x00000008,0x00400008,0x00008008,0x00408008,
592 },
593};
594static const uint32_t comp_maskl1[4][16] = {
595 {
596 0x00000000,0x00000010,0x00004000,0x00004010,
597 0x00040000,0x00040010,0x00044000,0x00044010,
598 0x00000100,0x00000110,0x00004100,0x00004110,
599 0x00040100,0x00040110,0x00044100,0x00044110,
600 },{
601 0x00000000,0x00800000,0x00000002,0x00800002,
602 0x00000200,0x00800200,0x00000202,0x00800202,
603 0x00200000,0x00a00000,0x00200002,0x00a00002,
604 0x00200200,0x00a00200,0x00200202,0x00a00202,
605 },{
606 0x00000000,0x00002000,0x00000004,0x00002004,
607 0x00000400,0x00002400,0x00000404,0x00002404,
608 0x00000000,0x00002000,0x00000004,0x00002004,
609 0x00000400,0x00002400,0x00000404,0x00002404,
610 },{
611 0x00000000,0x00010000,0x00000008,0x00010008,
612 0x00000080,0x00010080,0x00000088,0x00010088,
613 0x00000000,0x00010000,0x00000008,0x00010008,
614 0x00000080,0x00010080,0x00000088,0x00010088,
615 },
616};
617static const uint32_t comp_maskr1[4][16] = {
618 {
619 0x00000000,0x00000000,0x00000080,0x00000080,
620 0x00002000,0x00002000,0x00002080,0x00002080,
621 0x00000001,0x00000001,0x00000081,0x00000081,
622 0x00002001,0x00002001,0x00002081,0x00002081,
623 },{
624 0x00000000,0x00000010,0x00800000,0x00800010,
625 0x00010000,0x00010010,0x00810000,0x00810010,
626 0x00000200,0x00000210,0x00800200,0x00800210,
627 0x00010200,0x00010210,0x00810200,0x00810210,
628 },{
629 0x00000000,0x00000400,0x00001000,0x00001400,
630 0x00080000,0x00080400,0x00081000,0x00081400,
631 0x00000020,0x00000420,0x00001020,0x00001420,
632 0x00080020,0x00080420,0x00081020,0x00081420,
633 },{
634 0x00000000,0x00000100,0x00040000,0x00040100,
635 0x00000000,0x00000100,0x00040000,0x00040100,
636 0x00000040,0x00000140,0x00040040,0x00040140,
637 0x00000040,0x00000140,0x00040040,0x00040140,
638 },
639};
640
641static const unsigned char ascii64[] =
642 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
643/* 0000000000111111111122222222223333333333444444444455555555556666 */
644/* 0123456789012345678901234567890123456789012345678901234567890123 */
645
646/*
647 * We match the behavior of UFC-crypt on systems where "char" is signed by
648 * default (the majority), regardless of char's signedness on our system.
649 */
650static uint32_t ascii_to_bin(int ch)
651{
652 int sch = (ch < 0x80) ? ch : -(0x100 - ch);
653 int retval;
654
655 retval = sch - '.';
656 if (sch >= 'A') {
657 retval = sch - ('A' - 12);
658 if (sch >= 'a')
659 retval = sch - ('a' - 38);
660 }
661 retval &= 0x3f;
662
663 return retval;
664}
665
666/*
667 * When we choose to "support" invalid salts, nevertheless disallow those
668 * containing characters that would violate the passwd file format.
669 */
670static inline int ascii_is_unsafe(unsigned char ch)
671{
672 return !ch || ch == '\n' || ch == ':';
673}
674
675static uint32_t setup_salt(uint32_t salt)
676{
677 uint32_t obit, saltbit, saltbits;
678 unsigned int i;
679
680 saltbits = 0;
681 saltbit = 1;
682 obit = 0x800000;
683 for (i = 0; i < 24; i++) {
684 if (salt & saltbit)
685 saltbits |= obit;
686 saltbit <<= 1;
687 obit >>= 1;
688 }
689
690 return saltbits;
691}
692
693void __des_setkey(const unsigned char *key, struct expanded_key *ekey)
694{
695 uint32_t k0, k1, rawkey0, rawkey1;
696 unsigned int shifts, round, i, ibit;
697
698 rawkey0 =
699 (uint32_t)key[3] |
700 ((uint32_t)key[2] << 8) |
701 ((uint32_t)key[1] << 16) |
702 ((uint32_t)key[0] << 24);
703 rawkey1 =
704 (uint32_t)key[7] |
705 ((uint32_t)key[6] << 8) |
706 ((uint32_t)key[5] << 16) |
707 ((uint32_t)key[4] << 24);
708
709 /*
710 * Do key permutation and split into two 28-bit subkeys.
711 */
712 k0 = k1 = 0;
713 for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {
714 unsigned int j = i << 1;
715 k0 |= key_perm_maskl[i][(rawkey0 >> ibit) & 0xf] |
716 key_perm_maskl[i + 4][(rawkey1 >> ibit) & 0xf];
717 k1 |= key_perm_maskr[j][(rawkey0 >> ibit) & 0xf];
718 ibit -= 4;
719 k1 |= key_perm_maskr[j + 1][(rawkey0 >> ibit) & 0xf] |
720 key_perm_maskr[i + 8][(rawkey1 >> ibit) & 0xf];
721 }
722
723 /*
724 * Rotate subkeys and do compression permutation.
725 */
726 shifts = 0;
727 for (round = 0; round < 16; round++) {
728 uint32_t t0, t1;
729 uint32_t kl, kr;
730
731 shifts += key_shifts[round];
732
733 t0 = (k0 << shifts) | (k0 >> (28 - shifts));
734 t1 = (k1 << shifts) | (k1 >> (28 - shifts));
735
736 kl = kr = 0;
737 ibit = 25;
738 for (i = 0; i < 4; i++) {
739 kl |= comp_maskl0[i][(t0 >> ibit) & 7];
740 kr |= comp_maskr0[i][(t1 >> ibit) & 7];
741 ibit -= 4;
742 kl |= comp_maskl1[i][(t0 >> ibit) & 0xf];
743 kr |= comp_maskr1[i][(t1 >> ibit) & 0xf];
744 ibit -= 3;
745 }
746 ekey->l[round] = kl;
747 ekey->r[round] = kr;
748 }
749}
750
751/*
752 * l_in, r_in, l_out, and r_out are in pseudo-"big-endian" format.
753 */
754void __do_des(uint32_t l_in, uint32_t r_in,
755 uint32_t *l_out, uint32_t *r_out,
756 uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)
757{
758 uint32_t l, r;
759
760 /*
761 * Do initial permutation (IP).
762 */
763 l = r = 0;
764 if (l_in | r_in) {
765 unsigned int i, ibit;
766 for (i = 0, ibit = 28; i < 8; i++, ibit -= 4) {
767 l |= ip_maskl[i][(l_in >> ibit) & 0xf] |
768 ip_maskl[i + 8][(r_in >> ibit) & 0xf];
769 r |= ip_maskr[i][(l_in >> ibit) & 0xf] |
770 ip_maskr[i + 8][(r_in >> ibit) & 0xf];
771 }
772 }
773
774 while (count--) {
775 /*
776 * Do each round.
777 */
778 unsigned int round = 16;
779 const uint32_t *kl = ekey->l;
780 const uint32_t *kr = ekey->r;
781 uint32_t f;
782 while (round--) {
783 uint32_t r48l, r48r;
784 /*
785 * Expand R to 48 bits (simulate the E-box).
786 */
787 r48l = ((r & 0x00000001) << 23)
788 | ((r & 0xf8000000) >> 9)
789 | ((r & 0x1f800000) >> 11)
790 | ((r & 0x01f80000) >> 13)
791 | ((r & 0x001f8000) >> 15);
792
793 r48r = ((r & 0x0001f800) << 7)
794 | ((r & 0x00001f80) << 5)
795 | ((r & 0x000001f8) << 3)
796 | ((r & 0x0000001f) << 1)
797 | ((r & 0x80000000) >> 31);
798 /*
799 * Do salting for crypt() and friends, and
800 * XOR with the permuted key.
801 */
802 f = (r48l ^ r48r) & saltbits;
803 r48l ^= f ^ *kl++;
804 r48r ^= f ^ *kr++;
805 /*
806 * Do S-box lookups (which shrink it back to 32 bits)
807 * and do the P-box permutation at the same time.
808 */
809 f = psbox[0][r48l >> 18]
810 | psbox[1][(r48l >> 12) & 0x3f]
811 | psbox[2][(r48l >> 6) & 0x3f]
812 | psbox[3][r48l & 0x3f]
813 | psbox[4][r48r >> 18]
814 | psbox[5][(r48r >> 12) & 0x3f]
815 | psbox[6][(r48r >> 6) & 0x3f]
816 | psbox[7][r48r & 0x3f];
817 /*
818 * Now that we've permuted things, complete f().
819 */
820 f ^= l;
821 l = r;
822 r = f;
823 }
824 r = l;
825 l = f;
826 }
827
828 /*
829 * Do final permutation (inverse of IP).
830 */
831 {
832 unsigned int i, ibit;
833 uint32_t lo, ro;
834 lo = ro = 0;
835 for (i = 0, ibit = 28; i < 4; i++, ibit -= 4) {
836 ro |= fp_maskr[i][(l >> ibit) & 0xf] |
837 fp_maskr[i + 4][(r >> ibit) & 0xf];
838 ibit -= 4;
839 lo |= fp_maskl[i][(l >> ibit) & 0xf] |
840 fp_maskl[i + 4][(r >> ibit) & 0xf];
841 }
842 *l_out = lo;
843 *r_out = ro;
844 }
845}
846
847static void des_cipher(const unsigned char *in, unsigned char *out,
848 uint32_t count, uint32_t saltbits, const struct expanded_key *ekey)
849{
850 uint32_t l_out, r_out, rawl, rawr;
851
852 rawl =
853 (uint32_t)in[3] |
854 ((uint32_t)in[2] << 8) |
855 ((uint32_t)in[1] << 16) |
856 ((uint32_t)in[0] << 24);
857 rawr =
858 (uint32_t)in[7] |
859 ((uint32_t)in[6] << 8) |
860 ((uint32_t)in[5] << 16) |
861 ((uint32_t)in[4] << 24);
862
863 __do_des(rawl, rawr, &l_out, &r_out, count, saltbits, ekey);
864
865 out[0] = l_out >> 24;
866 out[1] = l_out >> 16;
867 out[2] = l_out >> 8;
868 out[3] = l_out;
869 out[4] = r_out >> 24;
870 out[5] = r_out >> 16;
871 out[6] = r_out >> 8;
872 out[7] = r_out;
873}
874
875static char *_crypt_extended_r_uut(const char *_key, const char *_setting, char *output)
876{
877 const unsigned char *key = (const unsigned char *)_key;
878 const unsigned char *setting = (const unsigned char *)_setting;
879 struct expanded_key ekey;
880 unsigned char keybuf[8];
881 unsigned char *p, *q;
882 uint32_t count, salt, l, r0, r1;
883 unsigned int i;
884
885 /*
886 * Copy the key, shifting each character left by one bit and padding
887 * with zeroes.
888 */
889 q = keybuf;
890 while (q <= &keybuf[sizeof(keybuf) - 1]) {
891 *q++ = *key << 1;
892 if (*key)
893 key++;
894 }
895 __des_setkey(keybuf, &ekey);
896
897 if (*setting == _PASSWORD_EFMT1) {
898 /*
899 * "new"-style:
900 * setting - underscore, 4 chars of count, 4 chars of salt
901 * key - unlimited characters
902 */
903 for (i = 1, count = 0; i < 5; i++) {
904 uint32_t value = ascii_to_bin(setting[i]);
905 if (ascii64[value] != setting[i])
906 return NULL;
907 count |= value << (i - 1) * 6;
908 }
909 if (!count)
910 return NULL;
911
912 for (i = 5, salt = 0; i < 9; i++) {
913 uint32_t value = ascii_to_bin(setting[i]);
914 if (ascii64[value] != setting[i])
915 return NULL;
916 salt |= value << (i - 5) * 6;
917 }
918
919 while (*key) {
920 /*
921 * Encrypt the key with itself.
922 */
923 des_cipher(keybuf, keybuf, 1, 0, &ekey);
924 /*
925 * And XOR with the next 8 characters of the key.
926 */
927 q = keybuf;
928 while (q <= &keybuf[sizeof(keybuf) - 1] && *key)
929 *q++ ^= *key++ << 1;
930 __des_setkey(keybuf, &ekey);
931 }
932
933 memcpy(output, setting, 9);
934 output[9] = '\0';
935 p = (unsigned char *)output + 9;
936 } else {
937 /*
938 * "old"-style:
939 * setting - 2 chars of salt
940 * key - up to 8 characters
941 */
942 count = 25;
943
944 if (ascii_is_unsafe(setting[0]) || ascii_is_unsafe(setting[1]))
945 return NULL;
946
947 salt = (ascii_to_bin(setting[1]) << 6)
948 | ascii_to_bin(setting[0]);
949
950 output[0] = setting[0];
951 output[1] = setting[1];
952 p = (unsigned char *)output + 2;
953 }
954
955 /*
956 * Do it.
957 */
958 __do_des(0, 0, &r0, &r1, count, setup_salt(salt), &ekey);
959
960 /*
961 * Now encode the result...
962 */
963 l = (r0 >> 8);
964 *p++ = ascii64[(l >> 18) & 0x3f];
965 *p++ = ascii64[(l >> 12) & 0x3f];
966 *p++ = ascii64[(l >> 6) & 0x3f];
967 *p++ = ascii64[l & 0x3f];
968
969 l = (r0 << 16) | ((r1 >> 16) & 0xffff);
970 *p++ = ascii64[(l >> 18) & 0x3f];
971 *p++ = ascii64[(l >> 12) & 0x3f];
972 *p++ = ascii64[(l >> 6) & 0x3f];
973 *p++ = ascii64[l & 0x3f];
974
975 l = r1 << 2;
976 *p++ = ascii64[(l >> 12) & 0x3f];
977 *p++ = ascii64[(l >> 6) & 0x3f];
978 *p++ = ascii64[l & 0x3f];
979 *p = 0;
980
981 return output;
982}
983
984char *__crypt_des(const char *key, const char *setting, char *output)
985{
986 const char *test_key = "\x80\xff\x80\x01 "
987 "\x7f\x81\x80\x80\x0d\x0a\xff\x7f \x81 test";
988 const char *test_setting = "_0.../9Zz";
989 const char *test_hash = "_0.../9ZzX7iSJNd21sU";
990 char test_buf[21];
991 char *retval;
992 const char *p;
993
994 if (*setting != _PASSWORD_EFMT1) {
995 test_setting = "\x80x";
996 test_hash = "\x80x22/wK52ZKGA";
997 }
998
999 /*
1000 * Hash the supplied password.
1001 */
1002 retval = _crypt_extended_r_uut(key, setting, output);
1003
1004 /*
1005 * Perform a quick self-test. It is important that we make both calls
1006 * to _crypt_extended_r_uut() from the same scope such that they likely
1007 * use the same stack locations, which makes the second call overwrite
1008 * the first call's sensitive data on the stack and makes it more
1009 * likely that any alignment related issues would be detected.
1010 */
1011 p = _crypt_extended_r_uut(test_key, test_setting, test_buf);
1012 if (p && !strcmp(p, test_hash) && retval)
1013 return retval;
1014
1015 return (setting[0]=='*') ? "x" : "*";
1016}
libc/musl/src/crypt/crypt_des.h created+14
......@@ -0,0 +1,14 @@
1#ifndef CRYPT_DES_H
2#define CRYPT_DES_H
3
4#include <stdint.h>
5
6struct expanded_key {
7 uint32_t l[16], r[16];
8};
9
10hidden void __des_setkey(const unsigned char *, struct expanded_key *);
11hidden void __do_des(uint32_t, uint32_t, uint32_t *, uint32_t *,
12 uint32_t, uint32_t, const struct expanded_key *);
13
14#endif
libc/musl/src/crypt/crypt_md5.c created+285
......@@ -0,0 +1,285 @@
1/*
2 * md5 crypt implementation
3 *
4 * original md5 crypt design is from Poul-Henning Kamp
5 * this implementation was created based on the code in freebsd
6 * at least 32bit int is assumed, key is limited and $1$ prefix is mandatory,
7 * on error "*" is returned
8 */
9#include <string.h>
10#include <stdint.h>
11
12/* public domain md5 implementation based on rfc1321 and libtomcrypt */
13
14struct md5 {
15 uint64_t len; /* processed message length */
16 uint32_t h[4]; /* hash state */
17 uint8_t buf[64]; /* message block buffer */
18};
19
20static uint32_t rol(uint32_t n, int k) { return (n << k) | (n >> (32-k)); }
21#define F(x,y,z) (z ^ (x & (y ^ z)))
22#define G(x,y,z) (y ^ (z & (y ^ x)))
23#define H(x,y,z) (x ^ y ^ z)
24#define I(x,y,z) (y ^ (x | ~z))
25#define FF(a,b,c,d,w,s,t) a += F(b,c,d) + w + t; a = rol(a,s) + b
26#define GG(a,b,c,d,w,s,t) a += G(b,c,d) + w + t; a = rol(a,s) + b
27#define HH(a,b,c,d,w,s,t) a += H(b,c,d) + w + t; a = rol(a,s) + b
28#define II(a,b,c,d,w,s,t) a += I(b,c,d) + w + t; a = rol(a,s) + b
29
30static const uint32_t tab[64] = {
310xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
320x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
330xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
340x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
350xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
360x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
370xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
380x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
39};
40
41static void processblock(struct md5 *s, const uint8_t *buf)
42{
43 uint32_t i, W[16], a, b, c, d;
44
45 for (i = 0; i < 16; i++) {
46 W[i] = buf[4*i];
47 W[i] |= (uint32_t)buf[4*i+1]<<8;
48 W[i] |= (uint32_t)buf[4*i+2]<<16;
49 W[i] |= (uint32_t)buf[4*i+3]<<24;
50 }
51
52 a = s->h[0];
53 b = s->h[1];
54 c = s->h[2];
55 d = s->h[3];
56
57 i = 0;
58 while (i < 16) {
59 FF(a,b,c,d, W[i], 7, tab[i]); i++;
60 FF(d,a,b,c, W[i], 12, tab[i]); i++;
61 FF(c,d,a,b, W[i], 17, tab[i]); i++;
62 FF(b,c,d,a, W[i], 22, tab[i]); i++;
63 }
64 while (i < 32) {
65 GG(a,b,c,d, W[(5*i+1)%16], 5, tab[i]); i++;
66 GG(d,a,b,c, W[(5*i+1)%16], 9, tab[i]); i++;
67 GG(c,d,a,b, W[(5*i+1)%16], 14, tab[i]); i++;
68 GG(b,c,d,a, W[(5*i+1)%16], 20, tab[i]); i++;
69 }
70 while (i < 48) {
71 HH(a,b,c,d, W[(3*i+5)%16], 4, tab[i]); i++;
72 HH(d,a,b,c, W[(3*i+5)%16], 11, tab[i]); i++;
73 HH(c,d,a,b, W[(3*i+5)%16], 16, tab[i]); i++;
74 HH(b,c,d,a, W[(3*i+5)%16], 23, tab[i]); i++;
75 }
76 while (i < 64) {
77 II(a,b,c,d, W[7*i%16], 6, tab[i]); i++;
78 II(d,a,b,c, W[7*i%16], 10, tab[i]); i++;
79 II(c,d,a,b, W[7*i%16], 15, tab[i]); i++;
80 II(b,c,d,a, W[7*i%16], 21, tab[i]); i++;
81 }
82
83 s->h[0] += a;
84 s->h[1] += b;
85 s->h[2] += c;
86 s->h[3] += d;
87}
88
89static void pad(struct md5 *s)
90{
91 unsigned r = s->len % 64;
92
93 s->buf[r++] = 0x80;
94 if (r > 56) {
95 memset(s->buf + r, 0, 64 - r);
96 r = 0;
97 processblock(s, s->buf);
98 }
99 memset(s->buf + r, 0, 56 - r);
100 s->len *= 8;
101 s->buf[56] = s->len;
102 s->buf[57] = s->len >> 8;
103 s->buf[58] = s->len >> 16;
104 s->buf[59] = s->len >> 24;
105 s->buf[60] = s->len >> 32;
106 s->buf[61] = s->len >> 40;
107 s->buf[62] = s->len >> 48;
108 s->buf[63] = s->len >> 56;
109 processblock(s, s->buf);
110}
111
112static void md5_init(struct md5 *s)
113{
114 s->len = 0;
115 s->h[0] = 0x67452301;
116 s->h[1] = 0xefcdab89;
117 s->h[2] = 0x98badcfe;
118 s->h[3] = 0x10325476;
119}
120
121static void md5_sum(struct md5 *s, uint8_t *md)
122{
123 int i;
124
125 pad(s);
126 for (i = 0; i < 4; i++) {
127 md[4*i] = s->h[i];
128 md[4*i+1] = s->h[i] >> 8;
129 md[4*i+2] = s->h[i] >> 16;
130 md[4*i+3] = s->h[i] >> 24;
131 }
132}
133
134static void md5_update(struct md5 *s, const void *m, unsigned long len)
135{
136 const uint8_t *p = m;
137 unsigned r = s->len % 64;
138
139 s->len += len;
140 if (r) {
141 if (len < 64 - r) {
142 memcpy(s->buf + r, p, len);
143 return;
144 }
145 memcpy(s->buf + r, p, 64 - r);
146 len -= 64 - r;
147 p += 64 - r;
148 processblock(s, s->buf);
149 }
150 for (; len >= 64; len -= 64, p += 64)
151 processblock(s, p);
152 memcpy(s->buf, p, len);
153}
154
155/*-
156 * Copyright (c) 2003 Poul-Henning Kamp
157 * All rights reserved.
158 *
159 * Redistribution and use in source and binary forms, with or without
160 * modification, are permitted provided that the following conditions
161 * are met:
162 * 1. Redistributions of source code must retain the above copyright
163 * notice, this list of conditions and the following disclaimer.
164 * 2. Redistributions in binary form must reproduce the above copyright
165 * notice, this list of conditions and the following disclaimer in the
166 * documentation and/or other materials provided with the distribution.
167 *
168 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
169 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
170 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
171 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
172 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
173 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
174 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
175 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
176 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
177 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
178 * SUCH DAMAGE.
179 */
180
181/* key limit is not part of the original design, added for DoS protection */
182#define KEY_MAX 30000
183#define SALT_MAX 8
184
185static const unsigned char b64[] =
186"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
187
188static char *to64(char *s, unsigned int u, int n)
189{
190 while (--n >= 0) {
191 *s++ = b64[u % 64];
192 u /= 64;
193 }
194 return s;
195}
196
197static char *md5crypt(const char *key, const char *setting, char *output)
198{
199 struct md5 ctx;
200 unsigned char md[16];
201 unsigned int i, klen, slen;
202 const char *salt;
203 char *p;
204
205 /* reject large keys */
206 klen = strnlen(key, KEY_MAX+1);
207 if (klen > KEY_MAX)
208 return 0;
209
210 /* setting: $1$salt$ (closing $ is optional) */
211 if (strncmp(setting, "$1$", 3) != 0)
212 return 0;
213 salt = setting + 3;
214 for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++);
215 slen = i;
216
217 /* md5(key salt key) */
218 md5_init(&ctx);
219 md5_update(&ctx, key, klen);
220 md5_update(&ctx, salt, slen);
221 md5_update(&ctx, key, klen);
222 md5_sum(&ctx, md);
223
224 /* md5(key $1$ salt repeated-md weird-key[0]-0) */
225 md5_init(&ctx);
226 md5_update(&ctx, key, klen);
227 md5_update(&ctx, setting, 3 + slen);
228 for (i = klen; i > sizeof md; i -= sizeof md)
229 md5_update(&ctx, md, sizeof md);
230 md5_update(&ctx, md, i);
231 md[0] = 0;
232 for (i = klen; i; i >>= 1)
233 if (i & 1)
234 md5_update(&ctx, md, 1);
235 else
236 md5_update(&ctx, key, 1);
237 md5_sum(&ctx, md);
238
239 /* md = f(md, key, salt) iteration */
240 for (i = 0; i < 1000; i++) {
241 md5_init(&ctx);
242 if (i % 2)
243 md5_update(&ctx, key, klen);
244 else
245 md5_update(&ctx, md, sizeof md);
246 if (i % 3)
247 md5_update(&ctx, salt, slen);
248 if (i % 7)
249 md5_update(&ctx, key, klen);
250 if (i % 2)
251 md5_update(&ctx, md, sizeof md);
252 else
253 md5_update(&ctx, key, klen);
254 md5_sum(&ctx, md);
255 }
256
257 /* output is $1$salt$hash */
258 memcpy(output, setting, 3 + slen);
259 p = output + 3 + slen;
260 *p++ = '$';
261 static const unsigned char perm[][3] = {
262 0,6,12,1,7,13,2,8,14,3,9,15,4,10,5 };
263 for (i=0; i<5; i++) p = to64(p,
264 (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
265 p = to64(p, md[11], 2);
266 *p = 0;
267
268 return output;
269}
270
271char *__crypt_md5(const char *key, const char *setting, char *output)
272{
273 static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
274 static const char testsetting[] = "$1$abcd0123$";
275 static const char testhash[] = "$1$abcd0123$9Qcg8DyviekV3tDGMZynJ1";
276 char testbuf[64];
277 char *p, *q;
278
279 p = md5crypt(key, setting, output);
280 /* self test and stack cleanup */
281 q = md5crypt(testkey, testsetting, testbuf);
282 if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
283 return "*";
284 return p;
285}
libc/musl/src/crypt/crypt_r.c created+23
......@@ -0,0 +1,23 @@
1#include <crypt.h>
2
3char *__crypt_r(const char *key, const char *salt, struct crypt_data *data)
4{
5 /* Per the crypt_r API, the caller has provided a pointer to
6 * struct crypt_data; however, this implementation does not
7 * use the structure to store any internal state, and treats
8 * it purely as a char buffer for storing the result. */
9 char *output = (char *)data;
10 if (salt[0] == '$' && salt[1] && salt[2]) {
11 if (salt[1] == '1' && salt[2] == '$')
12 return __crypt_md5(key, salt, output);
13 if (salt[1] == '2' && salt[3] == '$')
14 return __crypt_blowfish(key, salt, output);
15 if (salt[1] == '5' && salt[2] == '$')
16 return __crypt_sha256(key, salt, output);
17 if (salt[1] == '6' && salt[2] == '$')
18 return __crypt_sha512(key, salt, output);
19 }
20 return __crypt_des(key, salt, output);
21}
22
23weak_alias(__crypt_r, crypt_r);
libc/musl/src/crypt/crypt_sha256.c created+322
......@@ -0,0 +1,322 @@
1/*
2 * public domain sha256 crypt implementation
3 *
4 * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt
5 * in this implementation at least 32bit int is assumed,
6 * key length is limited, the $5$ prefix is mandatory, '\n' and ':' is rejected
7 * in the salt and rounds= setting must contain a valid iteration count,
8 * on error "*" is returned.
9 */
10#include <ctype.h>
11#include <stdlib.h>
12#include <stdio.h>
13#include <string.h>
14#include <stdint.h>
15
16/* public domain sha256 implementation based on fips180-3 */
17
18struct sha256 {
19 uint64_t len; /* processed message length */
20 uint32_t h[8]; /* hash state */
21 uint8_t buf[64]; /* message block buffer */
22};
23
24static uint32_t ror(uint32_t n, int k) { return (n >> k) | (n << (32-k)); }
25#define Ch(x,y,z) (z ^ (x & (y ^ z)))
26#define Maj(x,y,z) ((x & y) | (z & (x | y)))
27#define S0(x) (ror(x,2) ^ ror(x,13) ^ ror(x,22))
28#define S1(x) (ror(x,6) ^ ror(x,11) ^ ror(x,25))
29#define R0(x) (ror(x,7) ^ ror(x,18) ^ (x>>3))
30#define R1(x) (ror(x,17) ^ ror(x,19) ^ (x>>10))
31
32static const uint32_t K[64] = {
330x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
340xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
350xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
360x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
370x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
380xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
390x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
400x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
41};
42
43static void processblock(struct sha256 *s, const uint8_t *buf)
44{
45 uint32_t W[64], t1, t2, a, b, c, d, e, f, g, h;
46 int i;
47
48 for (i = 0; i < 16; i++) {
49 W[i] = (uint32_t)buf[4*i]<<24;
50 W[i] |= (uint32_t)buf[4*i+1]<<16;
51 W[i] |= (uint32_t)buf[4*i+2]<<8;
52 W[i] |= buf[4*i+3];
53 }
54 for (; i < 64; i++)
55 W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
56 a = s->h[0];
57 b = s->h[1];
58 c = s->h[2];
59 d = s->h[3];
60 e = s->h[4];
61 f = s->h[5];
62 g = s->h[6];
63 h = s->h[7];
64 for (i = 0; i < 64; i++) {
65 t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
66 t2 = S0(a) + Maj(a,b,c);
67 h = g;
68 g = f;
69 f = e;
70 e = d + t1;
71 d = c;
72 c = b;
73 b = a;
74 a = t1 + t2;
75 }
76 s->h[0] += a;
77 s->h[1] += b;
78 s->h[2] += c;
79 s->h[3] += d;
80 s->h[4] += e;
81 s->h[5] += f;
82 s->h[6] += g;
83 s->h[7] += h;
84}
85
86static void pad(struct sha256 *s)
87{
88 unsigned r = s->len % 64;
89
90 s->buf[r++] = 0x80;
91 if (r > 56) {
92 memset(s->buf + r, 0, 64 - r);
93 r = 0;
94 processblock(s, s->buf);
95 }
96 memset(s->buf + r, 0, 56 - r);
97 s->len *= 8;
98 s->buf[56] = s->len >> 56;
99 s->buf[57] = s->len >> 48;
100 s->buf[58] = s->len >> 40;
101 s->buf[59] = s->len >> 32;
102 s->buf[60] = s->len >> 24;
103 s->buf[61] = s->len >> 16;
104 s->buf[62] = s->len >> 8;
105 s->buf[63] = s->len;
106 processblock(s, s->buf);
107}
108
109static void sha256_init(struct sha256 *s)
110{
111 s->len = 0;
112 s->h[0] = 0x6a09e667;
113 s->h[1] = 0xbb67ae85;
114 s->h[2] = 0x3c6ef372;
115 s->h[3] = 0xa54ff53a;
116 s->h[4] = 0x510e527f;
117 s->h[5] = 0x9b05688c;
118 s->h[6] = 0x1f83d9ab;
119 s->h[7] = 0x5be0cd19;
120}
121
122static void sha256_sum(struct sha256 *s, uint8_t *md)
123{
124 int i;
125
126 pad(s);
127 for (i = 0; i < 8; i++) {
128 md[4*i] = s->h[i] >> 24;
129 md[4*i+1] = s->h[i] >> 16;
130 md[4*i+2] = s->h[i] >> 8;
131 md[4*i+3] = s->h[i];
132 }
133}
134
135static void sha256_update(struct sha256 *s, const void *m, unsigned long len)
136{
137 const uint8_t *p = m;
138 unsigned r = s->len % 64;
139
140 s->len += len;
141 if (r) {
142 if (len < 64 - r) {
143 memcpy(s->buf + r, p, len);
144 return;
145 }
146 memcpy(s->buf + r, p, 64 - r);
147 len -= 64 - r;
148 p += 64 - r;
149 processblock(s, s->buf);
150 }
151 for (; len >= 64; len -= 64, p += 64)
152 processblock(s, p);
153 memcpy(s->buf, p, len);
154}
155
156static const unsigned char b64[] =
157"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
158
159static char *to64(char *s, unsigned int u, int n)
160{
161 while (--n >= 0) {
162 *s++ = b64[u % 64];
163 u /= 64;
164 }
165 return s;
166}
167
168/* key limit is not part of the original design, added for DoS protection.
169 * rounds limit has been lowered (versus the reference/spec), also for DoS
170 * protection. runtime is O(klen^2 + klen*rounds) */
171#define KEY_MAX 256
172#define SALT_MAX 16
173#define ROUNDS_DEFAULT 5000
174#define ROUNDS_MIN 1000
175#define ROUNDS_MAX 9999999
176
177/* hash n bytes of the repeated md message digest */
178static void hashmd(struct sha256 *s, unsigned int n, const void *md)
179{
180 unsigned int i;
181
182 for (i = n; i > 32; i -= 32)
183 sha256_update(s, md, 32);
184 sha256_update(s, md, i);
185}
186
187static char *sha256crypt(const char *key, const char *setting, char *output)
188{
189 struct sha256 ctx;
190 unsigned char md[32], kmd[32], smd[32];
191 unsigned int i, r, klen, slen;
192 char rounds[20] = "";
193 const char *salt;
194 char *p;
195
196 /* reject large keys */
197 klen = strnlen(key, KEY_MAX+1);
198 if (klen > KEY_MAX)
199 return 0;
200
201 /* setting: $5$rounds=n$salt$ (rounds=n$ and closing $ are optional) */
202 if (strncmp(setting, "$5$", 3) != 0)
203 return 0;
204 salt = setting + 3;
205
206 r = ROUNDS_DEFAULT;
207 if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) {
208 unsigned long u;
209 char *end;
210
211 /*
212 * this is a deviation from the reference:
213 * bad rounds setting is rejected if it is
214 * - empty
215 * - unterminated (missing '$')
216 * - begins with anything but a decimal digit
217 * the reference implementation treats these bad
218 * rounds as part of the salt or parse them with
219 * strtoul semantics which may cause problems
220 * including non-portable hashes that depend on
221 * the host's value of ULONG_MAX.
222 */
223 salt += sizeof "rounds=" - 1;
224 if (!isdigit(*salt))
225 return 0;
226 u = strtoul(salt, &end, 10);
227 if (*end != '$')
228 return 0;
229 salt = end+1;
230 if (u < ROUNDS_MIN)
231 r = ROUNDS_MIN;
232 else if (u > ROUNDS_MAX)
233 return 0;
234 else
235 r = u;
236 /* needed when rounds is zero prefixed or out of bounds */
237 sprintf(rounds, "rounds=%u$", r);
238 }
239
240 for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)
241 /* reject characters that interfere with /etc/shadow parsing */
242 if (salt[i] == '\n' || salt[i] == ':')
243 return 0;
244 slen = i;
245
246 /* B = sha(key salt key) */
247 sha256_init(&ctx);
248 sha256_update(&ctx, key, klen);
249 sha256_update(&ctx, salt, slen);
250 sha256_update(&ctx, key, klen);
251 sha256_sum(&ctx, md);
252
253 /* A = sha(key salt repeat-B alternate-B-key) */
254 sha256_init(&ctx);
255 sha256_update(&ctx, key, klen);
256 sha256_update(&ctx, salt, slen);
257 hashmd(&ctx, klen, md);
258 for (i = klen; i > 0; i >>= 1)
259 if (i & 1)
260 sha256_update(&ctx, md, sizeof md);
261 else
262 sha256_update(&ctx, key, klen);
263 sha256_sum(&ctx, md);
264
265 /* DP = sha(repeat-key), this step takes O(klen^2) time */
266 sha256_init(&ctx);
267 for (i = 0; i < klen; i++)
268 sha256_update(&ctx, key, klen);
269 sha256_sum(&ctx, kmd);
270
271 /* DS = sha(repeat-salt) */
272 sha256_init(&ctx);
273 for (i = 0; i < 16 + md[0]; i++)
274 sha256_update(&ctx, salt, slen);
275 sha256_sum(&ctx, smd);
276
277 /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */
278 for (i = 0; i < r; i++) {
279 sha256_init(&ctx);
280 if (i % 2)
281 hashmd(&ctx, klen, kmd);
282 else
283 sha256_update(&ctx, md, sizeof md);
284 if (i % 3)
285 sha256_update(&ctx, smd, slen);
286 if (i % 7)
287 hashmd(&ctx, klen, kmd);
288 if (i % 2)
289 sha256_update(&ctx, md, sizeof md);
290 else
291 hashmd(&ctx, klen, kmd);
292 sha256_sum(&ctx, md);
293 }
294
295 /* output is $5$rounds=n$salt$hash */
296 p = output;
297 p += sprintf(p, "$5$%s%.*s$", rounds, slen, salt);
298 static const unsigned char perm[][3] = {
299 0,10,20,21,1,11,12,22,2,3,13,23,24,4,14,
300 15,25,5,6,16,26,27,7,17,18,28,8,9,19,29 };
301 for (i=0; i<10; i++) p = to64(p,
302 (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
303 p = to64(p, (md[31]<<8)|md[30], 3);
304 *p = 0;
305 return output;
306}
307
308char *__crypt_sha256(const char *key, const char *setting, char *output)
309{
310 static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
311 static const char testsetting[] = "$5$rounds=1234$abc0123456789$";
312 static const char testhash[] = "$5$rounds=1234$abc0123456789$3VfDjPt05VHFn47C/ojFZ6KRPYrOjj1lLbH.dkF3bZ6";
313 char testbuf[128];
314 char *p, *q;
315
316 p = sha256crypt(key, setting, output);
317 /* self test and stack cleanup */
318 q = sha256crypt(testkey, testsetting, testbuf);
319 if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
320 return "*";
321 return p;
322}
libc/musl/src/crypt/crypt_sha512.c created+371
......@@ -0,0 +1,371 @@
1/*
2 * public domain sha512 crypt implementation
3 *
4 * original sha crypt design: http://people.redhat.com/drepper/SHA-crypt.txt
5 * in this implementation at least 32bit int is assumed,
6 * key length is limited, the $6$ prefix is mandatory, '\n' and ':' is rejected
7 * in the salt and rounds= setting must contain a valid iteration count,
8 * on error "*" is returned.
9 */
10#include <ctype.h>
11#include <stdlib.h>
12#include <stdio.h>
13#include <string.h>
14#include <stdint.h>
15
16/* public domain sha512 implementation based on fips180-3 */
17/* >=2^64 bits messages are not supported (about 2000 peta bytes) */
18
19struct sha512 {
20 uint64_t len; /* processed message length */
21 uint64_t h[8]; /* hash state */
22 uint8_t buf[128]; /* message block buffer */
23};
24
25static uint64_t ror(uint64_t n, int k) { return (n >> k) | (n << (64-k)); }
26#define Ch(x,y,z) (z ^ (x & (y ^ z)))
27#define Maj(x,y,z) ((x & y) | (z & (x | y)))
28#define S0(x) (ror(x,28) ^ ror(x,34) ^ ror(x,39))
29#define S1(x) (ror(x,14) ^ ror(x,18) ^ ror(x,41))
30#define R0(x) (ror(x,1) ^ ror(x,8) ^ (x>>7))
31#define R1(x) (ror(x,19) ^ ror(x,61) ^ (x>>6))
32
33static const uint64_t K[80] = {
340x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
350x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
360xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
370x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
380xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
390x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
400x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
410xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
420x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
430x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
440xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
450xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
460x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
470x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
480x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
490x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
500xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
510x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
520x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
530x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
54};
55
56static void processblock(struct sha512 *s, const uint8_t *buf)
57{
58 uint64_t W[80], t1, t2, a, b, c, d, e, f, g, h;
59 int i;
60
61 for (i = 0; i < 16; i++) {
62 W[i] = (uint64_t)buf[8*i]<<56;
63 W[i] |= (uint64_t)buf[8*i+1]<<48;
64 W[i] |= (uint64_t)buf[8*i+2]<<40;
65 W[i] |= (uint64_t)buf[8*i+3]<<32;
66 W[i] |= (uint64_t)buf[8*i+4]<<24;
67 W[i] |= (uint64_t)buf[8*i+5]<<16;
68 W[i] |= (uint64_t)buf[8*i+6]<<8;
69 W[i] |= buf[8*i+7];
70 }
71 for (; i < 80; i++)
72 W[i] = R1(W[i-2]) + W[i-7] + R0(W[i-15]) + W[i-16];
73 a = s->h[0];
74 b = s->h[1];
75 c = s->h[2];
76 d = s->h[3];
77 e = s->h[4];
78 f = s->h[5];
79 g = s->h[6];
80 h = s->h[7];
81 for (i = 0; i < 80; i++) {
82 t1 = h + S1(e) + Ch(e,f,g) + K[i] + W[i];
83 t2 = S0(a) + Maj(a,b,c);
84 h = g;
85 g = f;
86 f = e;
87 e = d + t1;
88 d = c;
89 c = b;
90 b = a;
91 a = t1 + t2;
92 }
93 s->h[0] += a;
94 s->h[1] += b;
95 s->h[2] += c;
96 s->h[3] += d;
97 s->h[4] += e;
98 s->h[5] += f;
99 s->h[6] += g;
100 s->h[7] += h;
101}
102
103static void pad(struct sha512 *s)
104{
105 unsigned r = s->len % 128;
106
107 s->buf[r++] = 0x80;
108 if (r > 112) {
109 memset(s->buf + r, 0, 128 - r);
110 r = 0;
111 processblock(s, s->buf);
112 }
113 memset(s->buf + r, 0, 120 - r);
114 s->len *= 8;
115 s->buf[120] = s->len >> 56;
116 s->buf[121] = s->len >> 48;
117 s->buf[122] = s->len >> 40;
118 s->buf[123] = s->len >> 32;
119 s->buf[124] = s->len >> 24;
120 s->buf[125] = s->len >> 16;
121 s->buf[126] = s->len >> 8;
122 s->buf[127] = s->len;
123 processblock(s, s->buf);
124}
125
126static void sha512_init(struct sha512 *s)
127{
128 s->len = 0;
129 s->h[0] = 0x6a09e667f3bcc908ULL;
130 s->h[1] = 0xbb67ae8584caa73bULL;
131 s->h[2] = 0x3c6ef372fe94f82bULL;
132 s->h[3] = 0xa54ff53a5f1d36f1ULL;
133 s->h[4] = 0x510e527fade682d1ULL;
134 s->h[5] = 0x9b05688c2b3e6c1fULL;
135 s->h[6] = 0x1f83d9abfb41bd6bULL;
136 s->h[7] = 0x5be0cd19137e2179ULL;
137}
138
139static void sha512_sum(struct sha512 *s, uint8_t *md)
140{
141 int i;
142
143 pad(s);
144 for (i = 0; i < 8; i++) {
145 md[8*i] = s->h[i] >> 56;
146 md[8*i+1] = s->h[i] >> 48;
147 md[8*i+2] = s->h[i] >> 40;
148 md[8*i+3] = s->h[i] >> 32;
149 md[8*i+4] = s->h[i] >> 24;
150 md[8*i+5] = s->h[i] >> 16;
151 md[8*i+6] = s->h[i] >> 8;
152 md[8*i+7] = s->h[i];
153 }
154}
155
156static void sha512_update(struct sha512 *s, const void *m, unsigned long len)
157{
158 const uint8_t *p = m;
159 unsigned r = s->len % 128;
160
161 s->len += len;
162 if (r) {
163 if (len < 128 - r) {
164 memcpy(s->buf + r, p, len);
165 return;
166 }
167 memcpy(s->buf + r, p, 128 - r);
168 len -= 128 - r;
169 p += 128 - r;
170 processblock(s, s->buf);
171 }
172 for (; len >= 128; len -= 128, p += 128)
173 processblock(s, p);
174 memcpy(s->buf, p, len);
175}
176
177static const unsigned char b64[] =
178"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
179
180static char *to64(char *s, unsigned int u, int n)
181{
182 while (--n >= 0) {
183 *s++ = b64[u % 64];
184 u /= 64;
185 }
186 return s;
187}
188
189/* key limit is not part of the original design, added for DoS protection.
190 * rounds limit has been lowered (versus the reference/spec), also for DoS
191 * protection. runtime is O(klen^2 + klen*rounds) */
192#define KEY_MAX 256
193#define SALT_MAX 16
194#define ROUNDS_DEFAULT 5000
195#define ROUNDS_MIN 1000
196#define ROUNDS_MAX 9999999
197
198/* hash n bytes of the repeated md message digest */
199static void hashmd(struct sha512 *s, unsigned int n, const void *md)
200{
201 unsigned int i;
202
203 for (i = n; i > 64; i -= 64)
204 sha512_update(s, md, 64);
205 sha512_update(s, md, i);
206}
207
208static char *sha512crypt(const char *key, const char *setting, char *output)
209{
210 struct sha512 ctx;
211 unsigned char md[64], kmd[64], smd[64];
212 unsigned int i, r, klen, slen;
213 char rounds[20] = "";
214 const char *salt;
215 char *p;
216
217 /* reject large keys */
218 for (i = 0; i <= KEY_MAX && key[i]; i++);
219 if (i > KEY_MAX)
220 return 0;
221 klen = i;
222
223 /* setting: $6$rounds=n$salt$ (rounds=n$ and closing $ are optional) */
224 if (strncmp(setting, "$6$", 3) != 0)
225 return 0;
226 salt = setting + 3;
227
228 r = ROUNDS_DEFAULT;
229 if (strncmp(salt, "rounds=", sizeof "rounds=" - 1) == 0) {
230 unsigned long u;
231 char *end;
232
233 /*
234 * this is a deviation from the reference:
235 * bad rounds setting is rejected if it is
236 * - empty
237 * - unterminated (missing '$')
238 * - begins with anything but a decimal digit
239 * the reference implementation treats these bad
240 * rounds as part of the salt or parse them with
241 * strtoul semantics which may cause problems
242 * including non-portable hashes that depend on
243 * the host's value of ULONG_MAX.
244 */
245 salt += sizeof "rounds=" - 1;
246 if (!isdigit(*salt))
247 return 0;
248 u = strtoul(salt, &end, 10);
249 if (*end != '$')
250 return 0;
251 salt = end+1;
252 if (u < ROUNDS_MIN)
253 r = ROUNDS_MIN;
254 else if (u > ROUNDS_MAX)
255 return 0;
256 else
257 r = u;
258 /* needed when rounds is zero prefixed or out of bounds */
259 sprintf(rounds, "rounds=%u$", r);
260 }
261
262 for (i = 0; i < SALT_MAX && salt[i] && salt[i] != '$'; i++)
263 /* reject characters that interfere with /etc/shadow parsing */
264 if (salt[i] == '\n' || salt[i] == ':')
265 return 0;
266 slen = i;
267
268 /* B = sha(key salt key) */
269 sha512_init(&ctx);
270 sha512_update(&ctx, key, klen);
271 sha512_update(&ctx, salt, slen);
272 sha512_update(&ctx, key, klen);
273 sha512_sum(&ctx, md);
274
275 /* A = sha(key salt repeat-B alternate-B-key) */
276 sha512_init(&ctx);
277 sha512_update(&ctx, key, klen);
278 sha512_update(&ctx, salt, slen);
279 hashmd(&ctx, klen, md);
280 for (i = klen; i > 0; i >>= 1)
281 if (i & 1)
282 sha512_update(&ctx, md, sizeof md);
283 else
284 sha512_update(&ctx, key, klen);
285 sha512_sum(&ctx, md);
286
287 /* DP = sha(repeat-key), this step takes O(klen^2) time */
288 sha512_init(&ctx);
289 for (i = 0; i < klen; i++)
290 sha512_update(&ctx, key, klen);
291 sha512_sum(&ctx, kmd);
292
293 /* DS = sha(repeat-salt) */
294 sha512_init(&ctx);
295 for (i = 0; i < 16 + md[0]; i++)
296 sha512_update(&ctx, salt, slen);
297 sha512_sum(&ctx, smd);
298
299 /* iterate A = f(A,DP,DS), this step takes O(rounds*klen) time */
300 for (i = 0; i < r; i++) {
301 sha512_init(&ctx);
302 if (i % 2)
303 hashmd(&ctx, klen, kmd);
304 else
305 sha512_update(&ctx, md, sizeof md);
306 if (i % 3)
307 sha512_update(&ctx, smd, slen);
308 if (i % 7)
309 hashmd(&ctx, klen, kmd);
310 if (i % 2)
311 sha512_update(&ctx, md, sizeof md);
312 else
313 hashmd(&ctx, klen, kmd);
314 sha512_sum(&ctx, md);
315 }
316
317 /* output is $6$rounds=n$salt$hash */
318 p = output;
319 p += sprintf(p, "$6$%s%.*s$", rounds, slen, salt);
320#if 1
321 static const unsigned char perm[][3] = {
322 0,21,42,22,43,1,44,2,23,3,24,45,25,46,4,
323 47,5,26,6,27,48,28,49,7,50,8,29,9,30,51,
324 31,52,10,53,11,32,12,33,54,34,55,13,56,14,35,
325 15,36,57,37,58,16,59,17,38,18,39,60,40,61,19,
326 62,20,41 };
327 for (i=0; i<21; i++) p = to64(p,
328 (md[perm[i][0]]<<16)|(md[perm[i][1]]<<8)|md[perm[i][2]], 4);
329#else
330 p = to64(p, (md[0]<<16)|(md[21]<<8)|md[42], 4);
331 p = to64(p, (md[22]<<16)|(md[43]<<8)|md[1], 4);
332 p = to64(p, (md[44]<<16)|(md[2]<<8)|md[23], 4);
333 p = to64(p, (md[3]<<16)|(md[24]<<8)|md[45], 4);
334 p = to64(p, (md[25]<<16)|(md[46]<<8)|md[4], 4);
335 p = to64(p, (md[47]<<16)|(md[5]<<8)|md[26], 4);
336 p = to64(p, (md[6]<<16)|(md[27]<<8)|md[48], 4);
337 p = to64(p, (md[28]<<16)|(md[49]<<8)|md[7], 4);
338 p = to64(p, (md[50]<<16)|(md[8]<<8)|md[29], 4);
339 p = to64(p, (md[9]<<16)|(md[30]<<8)|md[51], 4);
340 p = to64(p, (md[31]<<16)|(md[52]<<8)|md[10], 4);
341 p = to64(p, (md[53]<<16)|(md[11]<<8)|md[32], 4);
342 p = to64(p, (md[12]<<16)|(md[33]<<8)|md[54], 4);
343 p = to64(p, (md[34]<<16)|(md[55]<<8)|md[13], 4);
344 p = to64(p, (md[56]<<16)|(md[14]<<8)|md[35], 4);
345 p = to64(p, (md[15]<<16)|(md[36]<<8)|md[57], 4);
346 p = to64(p, (md[37]<<16)|(md[58]<<8)|md[16], 4);
347 p = to64(p, (md[59]<<16)|(md[17]<<8)|md[38], 4);
348 p = to64(p, (md[18]<<16)|(md[39]<<8)|md[60], 4);
349 p = to64(p, (md[40]<<16)|(md[61]<<8)|md[19], 4);
350 p = to64(p, (md[62]<<16)|(md[20]<<8)|md[41], 4);
351#endif
352 p = to64(p, md[63], 2);
353 *p = 0;
354 return output;
355}
356
357char *__crypt_sha512(const char *key, const char *setting, char *output)
358{
359 static const char testkey[] = "Xy01@#\x01\x02\x80\x7f\xff\r\n\x81\t !";
360 static const char testsetting[] = "$6$rounds=1234$abc0123456789$";
361 static const char testhash[] = "$6$rounds=1234$abc0123456789$BCpt8zLrc/RcyuXmCDOE1ALqMXB2MH6n1g891HhFj8.w7LxGv.FTkqq6Vxc/km3Y0jE0j24jY5PIv/oOu6reg1";
362 char testbuf[128];
363 char *p, *q;
364
365 p = sha512crypt(key, setting, output);
366 /* self test and stack cleanup */
367 q = sha512crypt(testkey, testsetting, testbuf);
368 if (!p || q != testbuf || memcmp(testbuf, testhash, sizeof testhash))
369 return "*";
370 return p;
371}
libc/musl/src/crypt/encrypt.c created+52
......@@ -0,0 +1,52 @@
1#include <stdint.h>
2#include <stdlib.h>
3#include <unistd.h>
4
5#include "crypt_des.h"
6
7static struct expanded_key __encrypt_key;
8
9void setkey(const char *key)
10{
11 unsigned char bkey[8];
12 int i, j;
13
14 for (i = 0; i < 8; i++) {
15 bkey[i] = 0;
16 for (j = 7; j >= 0; j--, key++)
17 bkey[i] |= (uint32_t)(*key & 1) << j;
18 }
19
20 __des_setkey(bkey, &__encrypt_key);
21}
22
23void encrypt(char *block, int edflag)
24{
25 struct expanded_key decrypt_key, *key;
26 uint32_t b[2];
27 int i, j;
28 char *p;
29
30 p = block;
31 for (i = 0; i < 2; i++) {
32 b[i] = 0;
33 for (j = 31; j >= 0; j--, p++)
34 b[i] |= (uint32_t)(*p & 1) << j;
35 }
36
37 key = &__encrypt_key;
38 if (edflag) {
39 key = &decrypt_key;
40 for (i = 0; i < 16; i++) {
41 decrypt_key.l[i] = __encrypt_key.l[15-i];
42 decrypt_key.r[i] = __encrypt_key.r[15-i];
43 }
44 }
45
46 __do_des(b[0], b[1], b, b + 1, 1, 0, key);
47
48 p = block;
49 for (i = 0; i < 2; i++)
50 for (j = 31; j >= 0; j--)
51 *p++ = b[i]>>j & 1;
52}
libc/musl/src/ctype/__ctype_b_loc.c created+41
......@@ -0,0 +1,41 @@
1#include <endian.h>
2
3#if __BYTE_ORDER == __BIG_ENDIAN
4#define X(x) x
5#else
6#define X(x) (((x)/256 | (x)*256) % 65536)
7#endif
8
9static const unsigned short table[] = {
100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
14X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),
15X(0x200),X(0x320),X(0x220),X(0x220),X(0x220),X(0x220),X(0x200),X(0x200),
16X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),
17X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),X(0x200),
18X(0x160),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
19X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
20X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),X(0x8d8),
21X(0x8d8),X(0x8d8),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
22X(0x4c0),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8d5),X(0x8c5),
23X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),
24X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),X(0x8c5),
25X(0x8c5),X(0x8c5),X(0x8c5),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),
26X(0x4c0),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8d6),X(0x8c6),
27X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),
28X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),X(0x8c6),
29X(0x8c6),X(0x8c6),X(0x8c6),X(0x4c0),X(0x4c0),X(0x4c0),X(0x4c0),X(0x200),
300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
310,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
320,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
330,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
34};
35
36static const unsigned short *const ptable = table+128;
37
38const unsigned short **__ctype_b_loc(void)
39{
40 return (void *)&ptable;
41}
libc/musl/src/ctype/__ctype_get_mb_cur_max.c created+7
......@@ -0,0 +1,7 @@
1#include <stdlib.h>
2#include "locale_impl.h"
3
4size_t __ctype_get_mb_cur_max()
5{
6 return MB_CUR_MAX;
7}
libc/musl/src/ctype/__ctype_tolower_loc.c created+30
......@@ -0,0 +1,30 @@
1#include <stdint.h>
2
3static const int32_t table[] = {
40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
80,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
916,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
1032,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
1148,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
1264,
13'a','b','c','d','e','f','g','h','i','j','k','l','m',
14'n','o','p','q','r','s','t','u','v','w','x','y','z',
1591,92,93,94,95,96,
16'a','b','c','d','e','f','g','h','i','j','k','l','m',
17'n','o','p','q','r','s','t','u','v','w','x','y','z',
18123,124,125,126,127,
190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
210,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
23};
24
25static const int32_t *const ptable = table+128;
26
27const int32_t **__ctype_tolower_loc(void)
28{
29 return (void *)&ptable;
30}
libc/musl/src/ctype/__ctype_toupper_loc.c created+30
......@@ -0,0 +1,30 @@
1#include <stdint.h>
2
3static const int32_t table[] = {
40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
80,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
916,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
1032,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
1148,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
1264,
13'A','B','C','D','E','F','G','H','I','J','K','L','M',
14'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
1591,92,93,94,95,96,
16'A','B','C','D','E','F','G','H','I','J','K','L','M',
17'N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
18123,124,125,126,127,
190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
200,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
210,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
23};
24
25static const int32_t *const ptable = table+128;
26
27const int32_t **__ctype_toupper_loc(void)
28{
29 return (void *)&ptable;
30}
libc/musl/src/ctype/alpha.h created+163
......@@ -0,0 +1,163 @@
118,17,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,17,34,35,36,17,37,38,39,40,
241,42,43,44,17,45,46,47,16,16,48,16,16,16,16,16,16,16,49,50,51,16,52,53,16,16,
317,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,54,
417,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
517,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
617,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
717,17,17,55,17,17,17,17,56,17,57,58,59,60,61,62,17,17,17,17,17,17,17,17,17,17,
817,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
917,17,17,17,17,17,17,63,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1016,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,64,65,17,66,67,
1168,69,70,71,72,73,74,17,75,76,77,78,79,80,16,16,16,81,82,83,84,85,86,87,88,89,
1216,90,16,91,92,16,16,17,17,17,93,94,95,16,16,16,16,16,16,16,16,16,16,17,17,17,
1317,96,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,97,16,16,16,16,16,16,
1416,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1516,17,17,98,99,16,16,16,100,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
1617,17,17,17,17,17,17,101,17,17,102,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1716,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,103,
18104,16,16,16,16,16,16,16,16,16,105,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1916,16,16,16,16,16,16,16,16,106,107,108,109,16,16,16,16,16,16,16,16,110,16,16,
2016,16,16,16,16,111,112,16,16,16,16,113,16,16,114,16,16,16,16,16,16,16,16,16,
2116,16,16,16,
2216,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
23255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
24255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,254,255,255,7,254,
25255,255,7,0,0,0,0,0,4,32,4,255,255,127,255,255,255,127,255,255,255,255,255,
26255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
27255,195,255,3,0,31,80,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,223,188,64,215,255,255,
28251,255,255,255,255,255,255,255,255,255,191,255,255,255,255,255,255,255,255,
29255,255,255,255,255,255,255,255,255,3,252,255,255,255,255,255,255,255,255,255,
30255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,127,2,254,255,255,
31255,255,0,0,0,0,0,255,191,182,0,255,255,255,7,7,0,0,0,255,7,255,255,255,255,
32255,255,255,254,255,195,255,255,255,255,255,255,255,255,255,255,255,255,239,
3331,254,225,255,
34159,0,0,255,255,255,255,255,255,0,224,255,255,255,255,255,255,255,255,255,255,
35255,255,3,0,255,255,255,255,255,7,48,4,255,255,255,252,255,31,0,0,255,255,255,
361,255,7,0,0,0,0,0,0,255,255,223,63,0,0,240,255,248,3,255,255,255,255,255,255,
37255,255,255,239,255,223,225,255,207,255,254,255,239,159,249,255,255,253,197,
38227,159,89,128,176,207,255,3,16,238,135,249,255,255,253,109,195,135,25,2,94,
39192,255,63,0,238,191,251,255,255,253,237,227,191,27,1,0,207,255,0,30,238,159,
40249,255,255,253,237,227,159,25,192,176,207,255,2,0,236,199,61,214,24,199,255,
41195,199,29,129,0,192,255,0,0,239,223,253,255,255,253,255,227,223,29,96,7,207,
42255,0,0,239,223,253,255,255,253,239,227,223,29,96,64,207,255,6,0,239,223,253,
43255,255,255,255,231,223,93,240,128,207,255,0,252,236,255,127,252,255,255,251,
4447,127,128,95,255,192,255,12,0,254,255,255,255,255,127,255,7,63,32,255,3,0,0,
450,0,150,37,240,254,174,236,255,59,95,32,255,243,0,0,0,
460,1,0,0,0,255,3,0,0,255,254,255,255,255,31,254,255,3,255,255,254,255,255,255,
4731,0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,249,255,3,255,255,231,193,255,
48255,127,64,255,51,255,255,255,255,191,32,255,255,255,255,255,247,255,255,255,
49255,255,255,255,255,255,61,127,61,255,255,255,255,255,61,255,255,255,255,61,
50127,61,255,127,255,255,255,255,255,255,255,61,255,255,255,255,255,255,255,255,
51135,0,0,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,63,63,254,255,
52255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
53255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
54255,255,255,255,255,159,255,255,254,255,255,7,255,255,255,255,255,255,255,255,
55255,199,255,1,255,223,15,0,255,255,15,0,255,255,15,0,255,223,13,0,255,255,255,
56255,255,255,207,255,255,1,128,16,255,3,0,0,0,0,255,3,255,255,255,255,255,255,
57255,255,255,255,255,0,255,255,255,255,255,7,255,255,255,255,255,255,255,255,
5863,
590,255,255,255,127,255,15,255,1,192,255,255,255,255,63,31,0,255,255,255,255,
60255,15,255,255,255,3,255,3,0,0,0,0,255,255,255,15,255,255,255,255,255,255,255,
61127,254,255,31,0,255,3,255,3,128,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,
62255,239,255,239,15,255,3,0,0,0,0,255,255,255,255,255,243,255,255,255,255,255,
63255,191,255,3,0,255,255,255,255,255,255,63,0,255,227,255,255,255,255,255,63,
64255,1,0,0,0,0,0,0,0,0,0,0,0,222,111,0,255,255,255,255,255,255,255,255,255,255,
65255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,128,255,31,0,
66255,255,63,63,255,255,255,255,63,63,255,170,255,255,255,63,255,255,255,255,
67255,255,223,95,220,31,207,15,255,31,220,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,128,
680,0,255,31,0,0,0,0,0,0,0,0,0,0,0,0,132,252,47,62,80,189,255,243,224,67,0,0,
69255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
700,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,255,255,255,255,255,255,3,0,
710,255,255,255,255,255,127,255,255,255,255,255,127,255,255,255,255,255,255,255,
72255,255,255,255,255,255,255,255,255,31,120,12,0,255,255,255,255,191,32,255,
73255,255,255,255,255,255,128,0,0,255,255,127,0,127,127,127,127,127,127,127,127,
74255,255,255,255,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
750,0,224,0,0,0,254,3,62,31,254,255,255,255,255,255,255,255,255,255,127,224,254,
76255,255,255,255,255,255,255,255,255,255,247,224,255,255,255,255,127,254,255,
77255,255,255,255,255,255,255,255,255,127,0,0,255,255,255,7,0,0,0,0,0,0,255,255,
78255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
79255,255,255,63,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,
80255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,
810,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,
820,0,0,0,0,0,255,255,255,255,255,63,255,31,255,255,255,15,0,0,255,255,255,255,
83255,127,240,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,
840,128,255,252,255,255,255,255,255,255,255,255,255,255,255,255,249,255,255,255,
85127,255,0,0,0,0,0,0,0,128,255,187,247,255,255,255,0,0,0,255,255,255,255,255,
86255,15,0,255,255,255,255,255,255,255,255,47,0,255,3,0,0,252,40,255,255,255,
87255,255,7,255,255,255,255,7,0,255,255,255,31,255,255,255,255,255,255,247,255,
880,128,255,3,223,255,255,127,255,255,255,255,255,255,127,0,255,63,255,3,255,
89255,127,196,255,255,255,255,255,255,255,127,5,0,0,56,255,255,60,0,126,126,126,
900,127,127,255,255,255,255,255,247,63,0,255,255,255,255,255,255,255,255,255,
91255,255,255,255,255,255,7,255,3,255,255,255,255,255,255,255,255,255,255,255,
92255,255,255,255,255,255,255,255,255,15,0,255,255,127,248,255,255,255,255,255,
9315,255,255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,255,255,
94255,255,255,255,255,255,255,255,3,0,0,0,0,127,0,248,224,255,253,127,95,219,
95255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,248,255,255,255,
96255,255,255,255,255,255,255,255,255,63,0,0,255,255,255,255,255,255,255,255,
97252,255,255,255,255,255,255,0,0,0,0,0,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,
98255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,255,3,
99254,255,255,7,254,255,255,7,192,255,255,255,255,255,255,255,255,255,255,127,
100252,252,252,28,0,0,0,0,255,239,255,255,127,255,255,183,255,63,255,63,0,0,0,0,
101255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,0,0,0,0,0,0,0,
102255,255,255,255,255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1030,0,0,0,0,0,0,0,255,255,255,31,255,255,255,255,255,255,1,0,0,0,0,
1040,255,255,255,255,0,224,255,255,255,7,255,255,255,255,255,7,255,255,255,63,
105255,255,255,255,15,255,62,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,
106255,255,255,255,255,255,255,255,255,63,255,3,255,255,255,255,15,255,255,255,
107255,15,255,255,255,255,255,0,255,255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,
1080,0,0,0,0,0,0,0,255,255,255,255,255,255,127,0,255,255,63,0,255,0,0,0,0,0,0,0,
1090,0,0,0,0,0,0,0,0,0,0,0,63,253,255,255,255,255,191,145,255,255,63,0,255,255,
110127,0,255,255,255,127,0,0,0,0,0,0,0,0,255,255,55,0,255,255,63,0,255,255,255,3,
1110,0,0,0,0,0,0,0,255,255,255,255,255,255,255,192,0,0,0,0,0,0,0,0,111,240,239,
112254,255,255,15,0,0,0,0,0,255,255,255,31,255,255,255,31,0,0,0,0,255,254,255,
113255,31,0,0,0,255,255,255,255,255,255,63,0,255,255,63,0,255,255,7,0,255,255,3,
1140,0,0,0,0,0,0,0,0,0,0,0,
1150,255,255,255,255,255,255,255,255,255,1,0,0,0,0,0,0,255,255,255,255,255,255,7,
1160,255,255,255,255,255,255,7,0,255,255,255,255,255,255,255,255,63,0,0,0,192,
117255,0,0,252,255,255,255,255,255,255,1,0,0,255,255,255,1,255,3,255,255,255,255,
118255,255,199,255,0,0,255,255,255,255,71,0,255,255,255,255,255,255,255,255,30,0,
119255,23,0,0,0,0,255,255,251,255,255,255,159,64,0,0,0,0,0,0,0,0,127,189,255,191,
120255,1,255,255,255,255,255,255,255,1,255,3,239,159,249,255,255,253,237,227,159,
12125,129,224,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,
122255,255,187,7,255,3,0,0,0,0,255,255,255,255,255,255,255,255,179,0,255,3,0,0,0,
1230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,63,127,0,0,0,63,0,0,
1240,0,255,255,255,255,255,255,255,127,17,0,255,3,0,0,0,0,255,255,255,255,255,
125255,63,0,255,3,0,0,0,0,0,
1260,255,255,255,227,255,7,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1270,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,3,
1280,128,255,255,255,255,255,255,231,127,0,0,255,255,255,255,255,255,207,255,255,
1290,0,0,0,0,255,255,255,255,255,255,255,1,255,253,255,255,255,255,127,127,1,0,
130255,3,0,0,252,255,255,255,252,255,255,254,127,0,0,0,0,0,0,0,0,0,127,251,255,
131255,255,255,127,180,203,0,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,
132255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,
1330,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,127,0,
1340,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
135255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1360,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
137255,255,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1380,0,255,255,255,255,255,255,255,1,255,255,255,127,255,3,0,0,0,0,0,0,0,0,0,0,0,
1390,255,255,255,63,0,0,255,255,255,255,255,255,127,0,15,0,255,3,248,255,255,224,
140255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,31,0,255,
141255,255,255,255,127,0,0,248,255,0,0,0,0,0,0,0,0,3,0,0,0,255,255,255,255,255,
142255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
143255,255,255,255,255,31,0,0,255,255,255,255,255,255,255,255,255,255,255,255,
144255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,
145255,255,255,127,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,
146255,255,255,255,255,255,255,
147255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
148255,255,255,255,255,255,255,255,255,255,255,255,255,15,255,255,255,255,255,
149255,255,255,255,255,255,255,255,7,255,31,255,1,255,67,0,0,0,0,0,0,0,0,0,0,0,0,
150255,255,255,255,255,255,255,255,255,255,223,255,255,255,255,255,255,255,255,
151223,100,222,255,235,239,255,255,255,255,255,255,255,191,231,223,223,255,255,
152255,123,95,252,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
153255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
154255,255,255,255,255,255,255,255,63,255,255,255,253,255,255,247,255,255,255,
155247,255,255,223,255,255,255,223,255,255,127,255,255,255,127,255,255,255,253,
156255,255,255,253,255,255,247,207,255,255,255,255,255,255,127,255,255,249,219,7,
1570,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,
158255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,
1590,0,0,0,0,
1600,255,255,255,255,255,255,255,255,143,0,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1610,0,0,0,239,255,255,255,150,254,247,10,132,234,150,170,150,247,247,94,255,251,
162255,15,238,251,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,3,255,255,255,3,
163255,255,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
libc/musl/src/ctype/isalnum.c created+13
......@@ -0,0 +1,13 @@
1#include <ctype.h>
2
3int isalnum(int c)
4{
5 return isalpha(c) || isdigit(c);
6}
7
8int __isalnum_l(int c, locale_t l)
9{
10 return isalnum(c);
11}
12
13weak_alias(__isalnum_l, isalnum_l);
libc/musl/src/ctype/isalpha.c created+14
......@@ -0,0 +1,14 @@
1#include <ctype.h>
2#undef isalpha
3
4int isalpha(int c)
5{
6 return ((unsigned)c|32)-'a' < 26;
7}
8
9int __isalpha_l(int c, locale_t l)
10{
11 return isalpha(c);
12}
13
14weak_alias(__isalpha_l, isalpha_l);
libc/musl/src/ctype/isascii.c created+7
......@@ -0,0 +1,7 @@
1#include <ctype.h>
2#undef isascii
3
4int isascii(int c)
5{
6 return !(c&~0x7f);
7}
libc/musl/src/ctype/isblank.c created+13
......@@ -0,0 +1,13 @@
1#include <ctype.h>
2
3int isblank(int c)
4{
5 return (c == ' ' || c == '\t');
6}
7
8int __isblank_l(int c, locale_t l)
9{
10 return isblank(c);
11}
12
13weak_alias(__isblank_l, isblank_l);
libc/musl/src/ctype/iscntrl.c created+13
......@@ -0,0 +1,13 @@
1#include <ctype.h>
2
3int iscntrl(int c)
4{
5 return (unsigned)c < 0x20 || c == 0x7f;
6}
7
8int __iscntrl_l(int c, locale_t l)
9{
10 return iscntrl(c);
11}
12
13weak_alias(__iscntrl_l, iscntrl_l);
libc/musl/src/ctype/isdigit.c created+14
......@@ -0,0 +1,14 @@
1#include <ctype.h>
2#undef isdigit
3
4int isdigit(int c)
5{
6 return (unsigned)c-'0' < 10;
7}
8
9int __isdigit_l(int c, locale_t l)
10{
11 return isdigit(c);
12}
13
14weak_alias(__isdigit_l, isdigit_l);
libc/musl/src/ctype/isgraph.c created+14
......@@ -0,0 +1,14 @@
1#include <ctype.h>
2#undef isgraph
3
4int isgraph(int c)
5{
6 return (unsigned)c-0x21 < 0x5e;
7}
8
9int __isgraph_l(int c, locale_t l)
10{
11 return isgraph(c);
12}
13
14weak_alias(__isgraph_l, isgraph_l);
libc/musl/src/ctype/islower.c created+14
......@@ -0,0 +1,14 @@
1#include <ctype.h>
2#undef islower
3
4int islower(int c)
5{
6 return (unsigned)c-'a' < 26;
7}
8
9int __islower_l(int c, locale_t l)
10{
11 return islower(c);
12}
13
14weak_alias(__islower_l, islower_l);
libc/musl/src/ctype/isprint.c created+14
......@@ -0,0 +1,14 @@
1#include <ctype.h>
2#undef isprint
3
4int isprint(int c)
5{
6 return (unsigned)c-0x20 < 0x5f;
7}
8
9int __isprint_l(int c, locale_t l)
10{
11 return isprint(c);
12}
13
14weak_alias(__isprint_l, isprint_l);
libc/musl/src/ctype/ispunct.c created+13
......@@ -0,0 +1,13 @@
1#include <ctype.h>
2
3int ispunct(int c)
4{
5 return isgraph(c) && !isalnum(c);
6}
7
8int __ispunct_l(int c, locale_t l)
9{
10 return ispunct(c);
11}
12
13weak_alias(__ispunct_l, ispunct_l);
libc/musl/src/ctype/isspace.c created+14
......@@ -0,0 +1,14 @@
1#include <ctype.h>
2#undef isspace
3
4int isspace(int c)
5{
6 return c == ' ' || (unsigned)c-'\t' < 5;
7}
8
9int __isspace_l(int c, locale_t l)
10{
11 return isspace(c);
12}
13
14weak_alias(__isspace_l, isspace_l);
libc/musl/src/ctype/isupper.c created+14
......@@ -0,0 +1,14 @@
1#include <ctype.h>
2#undef isupper
3
4int isupper(int c)
5{
6 return (unsigned)c-'A' < 26;
7}
8
9int __isupper_l(int c, locale_t l)
10{
11 return isupper(c);
12}
13
14weak_alias(__isupper_l, isupper_l);
libc/musl/src/ctype/iswalnum.c created+13
......@@ -0,0 +1,13 @@
1#include <wctype.h>
2
3int iswalnum(wint_t wc)
4{
5 return iswdigit(wc) || iswalpha(wc);
6}
7
8int __iswalnum_l(wint_t c, locale_t l)
9{
10 return iswalnum(c);
11}
12
13weak_alias(__iswalnum_l, iswalnum_l);
libc/musl/src/ctype/iswalpha.c created+21
......@@ -0,0 +1,21 @@
1#include <wctype.h>
2
3static const unsigned char table[] = {
4#include "alpha.h"
5};
6
7int iswalpha(wint_t wc)
8{
9 if (wc<0x20000U)
10 return (table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1;
11 if (wc<0x2fffeU)
12 return 1;
13 return 0;
14}
15
16int __iswalpha_l(wint_t c, locale_t l)
17{
18 return iswalpha(c);
19}
20
21weak_alias(__iswalpha_l, iswalpha_l);
libc/musl/src/ctype/iswblank.c created+14
......@@ -0,0 +1,14 @@
1#include <wctype.h>
2#include <ctype.h>
3
4int iswblank(wint_t wc)
5{
6 return isblank(wc);
7}
8
9int __iswblank_l(wint_t c, locale_t l)
10{
11 return iswblank(c);
12}
13
14weak_alias(__iswblank_l, iswblank_l);
libc/musl/src/ctype/iswcntrl.c created+16
......@@ -0,0 +1,16 @@
1#include <wctype.h>
2
3int iswcntrl(wint_t wc)
4{
5 return (unsigned)wc < 32
6 || (unsigned)(wc-0x7f) < 33
7 || (unsigned)(wc-0x2028) < 2
8 || (unsigned)(wc-0xfff9) < 3;
9}
10
11int __iswcntrl_l(wint_t c, locale_t l)
12{
13 return iswcntrl(c);
14}
15
16weak_alias(__iswcntrl_l, iswcntrl_l);
libc/musl/src/ctype/iswctype.c created+75
......@@ -0,0 +1,75 @@
1#include <wctype.h>
2#include <string.h>
3
4#define WCTYPE_ALNUM 1
5#define WCTYPE_ALPHA 2
6#define WCTYPE_BLANK 3
7#define WCTYPE_CNTRL 4
8#define WCTYPE_DIGIT 5
9#define WCTYPE_GRAPH 6
10#define WCTYPE_LOWER 7
11#define WCTYPE_PRINT 8
12#define WCTYPE_PUNCT 9
13#define WCTYPE_SPACE 10
14#define WCTYPE_UPPER 11
15#define WCTYPE_XDIGIT 12
16
17int iswctype(wint_t wc, wctype_t type)
18{
19 switch (type) {
20 case WCTYPE_ALNUM:
21 return iswalnum(wc);
22 case WCTYPE_ALPHA:
23 return iswalpha(wc);
24 case WCTYPE_BLANK:
25 return iswblank(wc);
26 case WCTYPE_CNTRL:
27 return iswcntrl(wc);
28 case WCTYPE_DIGIT:
29 return iswdigit(wc);
30 case WCTYPE_GRAPH:
31 return iswgraph(wc);
32 case WCTYPE_LOWER:
33 return iswlower(wc);
34 case WCTYPE_PRINT:
35 return iswprint(wc);
36 case WCTYPE_PUNCT:
37 return iswpunct(wc);
38 case WCTYPE_SPACE:
39 return iswspace(wc);
40 case WCTYPE_UPPER:
41 return iswupper(wc);
42 case WCTYPE_XDIGIT:
43 return iswxdigit(wc);
44 }
45 return 0;
46}
47
48wctype_t wctype(const char *s)
49{
50 int i;
51 const char *p;
52 /* order must match! */
53 static const char names[] =
54 "alnum\0" "alpha\0" "blank\0"
55 "cntrl\0" "digit\0" "graph\0"
56 "lower\0" "print\0" "punct\0"
57 "space\0" "upper\0" "xdigit";
58 for (i=1, p=names; *p; i++, p+=6)
59 if (*s == *p && !strcmp(s, p))
60 return i;
61 return 0;
62}
63
64int __iswctype_l(wint_t c, wctype_t t, locale_t l)
65{
66 return iswctype(c, t);
67}
68
69wctype_t __wctype_l(const char *s, locale_t l)
70{
71 return wctype(s);
72}
73
74weak_alias(__iswctype_l, iswctype_l);
75weak_alias(__wctype_l, wctype_l);
libc/musl/src/ctype/iswdigit.c created+15
......@@ -0,0 +1,15 @@
1#include <wctype.h>
2
3#undef iswdigit
4
5int iswdigit(wint_t wc)
6{
7 return (unsigned)wc-'0' < 10;
8}
9
10int __iswdigit_l(wint_t c, locale_t l)
11{
12 return iswdigit(c);
13}
14
15weak_alias(__iswdigit_l, iswdigit_l);
libc/musl/src/ctype/iswgraph.c created+14
......@@ -0,0 +1,14 @@
1#include <wctype.h>
2
3int iswgraph(wint_t wc)
4{
5 /* ISO C defines this function as: */
6 return !iswspace(wc) && iswprint(wc);
7}
8
9int __iswgraph_l(wint_t c, locale_t l)
10{
11 return iswgraph(c);
12}
13
14weak_alias(__iswgraph_l, iswgraph_l);
libc/musl/src/ctype/iswlower.c created+13
......@@ -0,0 +1,13 @@
1#include <wctype.h>
2
3int iswlower(wint_t wc)
4{
5 return towupper(wc) != wc;
6}
7
8int __iswlower_l(wint_t c, locale_t l)
9{
10 return iswlower(c);
11}
12
13weak_alias(__iswlower_l, iswlower_l);
libc/musl/src/ctype/iswprint.c created+26
......@@ -0,0 +1,26 @@
1#include <wctype.h>
2
3/* Consider all legal codepoints as printable except for:
4 * - C0 and C1 control characters
5 * - U+2028 and U+2029 (line/para break)
6 * - U+FFF9 through U+FFFB (interlinear annotation controls)
7 * The following code is optimized heavily to make hot paths for the
8 * expected printable characters. */
9
10int iswprint(wint_t wc)
11{
12 if (wc < 0xffU)
13 return (wc+1 & 0x7f) >= 0x21;
14 if (wc < 0x2028U || wc-0x202aU < 0xd800-0x202a || wc-0xe000U < 0xfff9-0xe000)
15 return 1;
16 if (wc-0xfffcU > 0x10ffff-0xfffc || (wc&0xfffe)==0xfffe)
17 return 0;
18 return 1;
19}
20
21int __iswprint_l(wint_t c, locale_t l)
22{
23 return iswprint(c);
24}
25
26weak_alias(__iswprint_l, iswprint_l);
libc/musl/src/ctype/iswpunct.c created+19
......@@ -0,0 +1,19 @@
1#include <wctype.h>
2
3static const unsigned char table[] = {
4#include "punct.h"
5};
6
7int iswpunct(wint_t wc)
8{
9 if (wc<0x20000U)
10 return (table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1;
11 return 0;
12}
13
14int __iswpunct_l(wint_t c, locale_t l)
15{
16 return iswpunct(c);
17}
18
19weak_alias(__iswpunct_l, iswpunct_l);
libc/musl/src/ctype/iswspace.c created+24
......@@ -0,0 +1,24 @@
1#include <wchar.h>
2#include <wctype.h>
3
4/* Our definition of whitespace is the Unicode White_Space property,
5 * minus non-breaking spaces (U+00A0, U+2007, and U+202F) and script-
6 * specific characters with non-blank glyphs (U+1680 and U+180E). */
7
8int iswspace(wint_t wc)
9{
10 static const wchar_t spaces[] = {
11 ' ', '\t', '\n', '\r', 11, 12, 0x0085,
12 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
13 0x2006, 0x2008, 0x2009, 0x200a,
14 0x2028, 0x2029, 0x205f, 0x3000, 0
15 };
16 return wc && wcschr(spaces, wc);
17}
18
19int __iswspace_l(wint_t c, locale_t l)
20{
21 return iswspace(c);
22}
23
24weak_alias(__iswspace_l, iswspace_l);
libc/musl/src/ctype/iswupper.c created+13
......@@ -0,0 +1,13 @@
1#include <wctype.h>
2
3int iswupper(wint_t wc)
4{
5 return towlower(wc) != wc;
6}
7
8int __iswupper_l(wint_t c, locale_t l)
9{
10 return iswupper(c);
11}
12
13weak_alias(__iswupper_l, iswupper_l);
libc/musl/src/ctype/iswxdigit.c created+13
......@@ -0,0 +1,13 @@
1#include <wctype.h>
2
3int iswxdigit(wint_t wc)
4{
5 return (unsigned)(wc-'0') < 10 || (unsigned)((wc|32)-'a') < 6;
6}
7
8int __iswxdigit_l(wint_t c, locale_t l)
9{
10 return iswxdigit(c);
11}
12
13weak_alias(__iswxdigit_l, iswxdigit_l);
libc/musl/src/ctype/isxdigit.c created+13
......@@ -0,0 +1,13 @@
1#include <ctype.h>
2
3int isxdigit(int c)
4{
5 return isdigit(c) || ((unsigned)c|32)-'a' < 6;
6}
7
8int __isxdigit_l(int c, locale_t l)
9{
10 return isxdigit(c);
11}
12
13weak_alias(__isxdigit_l, isxdigit_l);
libc/musl/src/ctype/nonspacing.h created+81
......@@ -0,0 +1,81 @@
116,16,16,18,19,20,21,22,23,24,25,26,27,28,29,30,31,16,16,32,16,16,16,33,34,35,
236,37,38,39,16,16,40,16,16,16,16,16,16,16,16,16,16,16,41,42,16,16,43,16,16,16,
316,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
416,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
516,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
616,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
716,16,16,16,16,16,16,16,16,16,44,16,45,46,47,48,16,16,16,16,16,16,16,16,16,16,
816,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
916,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1016,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,49,16,16,50,
1151,16,52,53,54,16,16,16,16,16,16,55,16,16,16,16,16,56,57,58,59,60,61,62,63,16,
1216,64,16,65,66,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1316,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1416,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1516,16,16,67,68,16,16,16,69,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1616,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1716,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1816,16,16,16,16,16,16,70,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1916,16,71,72,16,16,16,16,16,16,16,73,16,16,16,16,16,74,16,16,16,16,16,16,16,75,
2076,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
2116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
22255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
23255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
24255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
250,0,0,0,0,0,0,248,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
260,0,0,254,255,255,255,255,191,182,0,0,0,0,0,0,0,63,0,255,23,0,0,0,0,0,248,255,
27255,0,0,1,0,0,0,0,0,0,0,0,0,0,0,192,191,159,61,0,0,0,128,2,0,0,0,255,255,255,
287,0,0,0,0,0,0,0,0,0,0,192,255,1,0,0,0,0,0,0,248,15,0,0,0,192,251,239,62,0,0,0,
290,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,240,255,255,255,255,
30255,7,0,0,0,0,0,0,20,254,33,254,0,12,0,0,0,2,0,0,0,0,0,0,16,30,32,0,0,12,0,0,
310,6,0,0,0,0,0,0,16,134,57,2,0,0,0,35,0,6,0,0,0,0,0,0,16,190,33,0,0,12,0,0,252,
322,0,0,0,0,0,0,144,30,32,64,0,12,0,0,0,4,0,0,0,0,0,0,0,1,32,0,0,0,0,0,0,1,0,0,
330,0,0,0,192,193,61,96,0,12,0,0,0,2,0,0,0,0,0,0,144,64,48,0,0,12,0,0,0,3,0,0,0,
340,0,0,24,30,32,0,0,12,0,0,0,0,0,0,0,0,0,0,0,0,4,92,0,0,0,0,0,0,0,0,0,0,0,242,
357,128,127,0,0,0,0,0,0,0,0,0,0,0,0,242,27,0,63,0,0,0,0,0,0,0,0,0,3,0,0,160,2,0,
360,0,0,0,0,254,127,223,224,255,254,255,255,255,31,64,0,0,0,0,0,0,0,0,0,0,0,0,
37224,253,102,0,0,0,195,1,0,30,0,100,32,0,32,0,0,0,0,0,0,0,0,0,0,0,
380,0,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,
390,0,28,0,0,0,12,0,0,0,12,0,0,0,0,0,0,0,176,63,64,254,15,32,0,0,0,0,0,120,0,0,
400,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,135,1,4,14,0,
410,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,9,0,0,0,0,0,0,64,127,
42229,31,248,159,0,0,0,0,0,0,255,127,0,0,0,0,0,0,0,0,15,0,0,0,0,0,208,23,4,0,0,
430,0,248,15,0,3,0,0,0,60,59,0,0,0,0,0,0,64,163,3,0,0,0,0,0,0,240,207,0,0,0,0,0,
440,0,0,0,0,0,0,0,0,0,0,0,0,0,247,255,253,33,16,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
450,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,
46251,0,248,0,0,0,124,0,0,0,0,0,0,223,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,
47255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,0,0,0,
480,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,
490,60,0,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
500,0,0,128,247,63,0,0,0,192,0,0,0,0,0,0,0,0,0,0,3,0,68,8,0,0,96,0,0,0,0,0,0,0,
510,0,0,0,0,0,0,0,0,0,0,0,48,0,0,0,255,255,3,0,0,0,0,0,192,63,0,0,128,255,3,0,0,
520,0,0,7,0,0,0,0,0,200,19,0,0,0,0,32,0,0,0,0,0,0,0,0,126,102,0,8,16,0,0,0,0,0,
5316,0,0,0,0,0,0,157,193,2,0,0,0,0,48,64,
540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,33,0,0,0,0,0,64,
550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,255,255,0,
560,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,
570,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
580,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
590,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
600,110,240,0,0,0,0,0,135,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,
610,2,0,0,0,0,0,0,255,127,0,0,0,0,0,0,128,3,0,0,0,0,0,120,38,0,0,0,0,0,0,0,0,7,
620,0,0,128,239,31,0,0,0,0,0,0,0,8,0,3,0,0,0,0,0,192,127,0,28,0,0,0,0,0,0,0,0,0,
630,0,128,211,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,248,7,0,0,3,0,0,0,0,
640,0,16,1,0,0,0,192,31,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,
6592,0,0,0,0,0,0,0,0,0,0,0,0,0,248,133,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
660,0,0,0,0,0,0,0,0,0,60,176,1,0,0,48,0,0,0,0,0,0,0,0,0,0,248,167,1,0,0,0,0,0,0,
670,0,0,0,0,0,40,191,0,0,0,0,0,0,0,0,0,0,0,0,224,188,15,0,0,0,0,0,0,0,0,0,0,0,0,
680,0,0,0,0,0,0,0,0,0,0,0,0,
690,126,6,0,0,0,0,248,121,128,0,126,14,0,0,0,0,0,252,127,3,0,0,0,0,0,0,0,0,0,0,
700,0,0,0,0,0,0,0,127,191,0,0,0,0,0,0,0,0,0,0,252,255,255,252,109,0,0,0,0,0,0,0,
710,0,0,0,0,0,0,0,126,180,191,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
720,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,0,0,127,
730,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
740,0,0,128,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7596,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,248,255,231,15,0,0,
760,60,0,0,0,0,0,0,0,0,0,
770,0,0,0,0,0,0,0,0,28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
78255,255,255,255,127,248,255,255,255,255,255,31,32,0,16,0,0,248,254,255,0,0,0,
790,0,0,0,0,0,0,127,255,255,249,219,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
800,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,
810,0,0,0,0,0,0,240,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
libc/musl/src/ctype/punct.h created+129
......@@ -0,0 +1,129 @@
118,16,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,16,16,34,35,16,36,37,38,39,
240,41,42,43,16,44,45,46,17,17,47,17,17,17,17,17,17,48,49,50,51,52,53,54,55,17,
316,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,56,
416,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
516,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
616,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
716,16,16,16,16,16,16,16,57,16,58,59,60,61,62,63,16,16,16,16,16,16,16,16,16,16,
816,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
916,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,64,16,16,16,16,16,16,16,16,16,
1016,16,16,16,16,16,16,16,16,16,16,16,16,16,65,16,16,66,16,67,68,
1169,16,70,71,72,16,73,16,16,74,75,76,77,78,16,79,16,80,81,82,83,84,85,86,87,88,
1216,89,16,90,91,16,16,16,16,16,16,92,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1316,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1416,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1516,16,16,93,94,16,16,16,95,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1616,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1716,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1816,16,16,16,16,16,16,96,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1916,97,98,99,100,16,16,101,102,17,17,103,16,16,16,16,16,16,16,16,16,16,16,16,
2016,104,105,16,16,16,16,106,16,107,108,109,17,17,17,110,111,112,113,16,16,16,
2116,16,
2216,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
23255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
24255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,254,255,0,252,1,0,0,248,1,
250,0,120,0,0,0,0,255,251,223,251,0,0,128,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
260,0,0,0,0,0,0,0,0,0,0,60,0,252,255,224,175,255,255,255,255,255,255,255,255,
27255,255,223,255,255,255,255,255,32,64,176,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,
280,0,0,0,0,0,0,0,0,0,0,0,0,0,252,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
290,0,0,252,0,0,0,0,0,230,254,255,255,255,0,64,73,0,0,0,0,0,24,0,255,255,0,216,
300,0,0,0,0,0,0,1,0,60,0,0,0,0,0,0,0,0,0,0,0,0,16,224,1,30,0,
3196,255,191,0,0,0,0,0,0,255,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,207,3,
320,0,0,3,0,32,255,127,0,0,0,78,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,252,0,0,0,0,0,
330,0,0,0,16,0,32,30,0,48,0,1,0,0,0,0,0,0,0,0,16,0,32,0,0,0,0,252,47,0,0,0,0,0,
340,0,16,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,32,0,0,0,0,3,224,0,0,0,0,0,0,0,16,
350,32,0,0,0,0,253,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,255,7,0,0,0,0,0,0,0,0,0,32,0,
360,0,0,0,255,0,0,0,0,0,0,0,16,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,160,0,127,0,
370,255,3,0,0,0,0,0,0,0,0,0,4,0,0,0,0,16,0,0,0,0,0,0,128,0,128,192,223,0,12,0,0,
380,0,0,0,0,0,0,0,0,0,0,31,0,0,0,0,0,
390,254,255,255,255,0,252,255,255,0,0,0,0,0,0,0,0,252,0,0,0,0,0,0,192,255,223,
40255,7,0,0,0,0,0,0,0,0,0,0,128,6,0,252,0,0,24,62,0,0,128,191,0,204,0,0,0,0,0,0,
410,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,96,255,255,255,31,0,0,255,3,0,0,0,0,0,0,0,0,
420,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
430,0,0,0,0,0,0,0,0,0,96,0,0,1,0,0,24,0,0,0,0,0,0,0,0,0,56,0,0,0,0,16,0,0,0,112,
440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,0,0,254,127,47,0,0,255,3,255,127,0,0,0,0,0,0,
450,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,49,0,0,0,0,0,
460,0,0,0,0,0,0,0,0,0,0,0,0,196,255,255,255,
47255,0,0,0,192,0,0,0,0,0,0,0,0,1,0,224,159,0,0,0,0,127,63,255,127,0,0,0,0,0,0,
480,0,0,0,0,0,0,0,16,0,16,0,0,252,255,255,255,31,0,0,0,0,0,12,0,0,0,0,0,0,64,0,
4912,240,0,0,0,0,0,0,192,248,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,255,0,255,255,
50255,33,144,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,
51127,0,224,251,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,3,224,0,224,0,
52224,0,96,128,248,255,255,255,252,255,255,255,255,255,127,223,255,241,127,255,
53127,0,0,255,255,255,255,0,0,255,255,255,255,1,0,123,3,208,193,175,66,0,12,31,
54188,255,255,0,0,0,0,0,14,255,255,255,255,255,255,255,255,255,255,255,255,255,
55255,255,255,255,255,127,0,0,0,255,7,0,0,255,255,255,255,255,255,255,255,255,
56255,63,0,0,0,0,0,0,252,255,
57255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,207,255,255,255,
5863,255,255,255,255,227,255,253,7,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
590,0,0,0,0,0,0,0,0,0,0,0,224,135,3,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,128,0,0,0,
600,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,127,255,255,255,3,0,0,0,0,0,0,
61255,255,255,251,255,255,255,255,255,255,255,255,255,255,15,0,255,255,255,255,
62255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
63255,255,255,63,0,0,0,255,15,30,255,255,255,1,252,193,224,0,0,0,0,0,0,0,0,0,0,
640,30,1,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,0,0,
650,0,255,255,255,255,15,0,0,0,255,255,255,127,255,255,255,255,255,255,255,255,
66255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
67127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,
68255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,0,0,0,
690,0,0,192,0,224,0,0,0,0,0,0,0,0,0,0,0,128,15,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
70255,0,255,255,127,0,3,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
7168,8,0,0,0,15,255,3,0,0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,16,192,0,0,255,255,3,23,
720,0,0,0,0,248,0,0,0,0,8,128,0,0,0,0,0,0,0,0,0,0,8,0,255,63,0,192,32,0,0,0,0,0,
730,0,0,0,0,0,0,0,0,240,0,0,128,59,0,0,0,0,0,0,0,128,2,0,0,192,0,0,67,0,0,0,0,0,
740,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,0,
750,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
760,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,2,0,0,0,0,0,0,
770,0,0,0,0,0,0,0,0,0,252,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,
780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,255,255,255,3,255,255,255,255,255,255,247,
79255,127,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,254,255,0,252,1,0,0,248,1,0,
800,248,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,127,0,48,135,255,255,255,255,255,
81143,255,0,0,0,0,0,0,224,255,255,127,255,15,1,0,0,0,0,0,255,255,255,255,255,63,
820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,
8315,0,0,0,0,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,
840,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
85128,255,0,0,128,255,0,0,0,0,128,255,0,0,0,0,0,0,0,0,0,248,0,0,192,143,0,0,0,
86128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,255,255,252,255,255,255,255,255,0,0,0,0,
870,0,0,135,255,0,255,1,0,0,0,224,0,0,0,224,0,0,0,0,0,1,0,0,96,248,127,0,0,0,0,
880,0,0,0,254,0,0,0,255,0,0,0,255,0,0,0,30,0,254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
890,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,0,0,0,0,0,0,0,0,0,0,0,
900,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
910,0,0,0,0,0,0,0,0,192,63,252,255,63,0,0,128,3,0,0,0,0,0,0,254,3,0,0,0,0,0,0,0,
920,0,0,0,0,0,24,0,15,0,0,0,0,0,56,0,0,0,0,0,0,0,0,0,225,63,0,232,254,255,31,0,
930,0,0,0,0,0,96,63,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,
940,16,0,32,0,0,192,31,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,
95248,0,40,0,0,0,0,0,0,0,0,0,0,0,0,76,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
960,0,0,0,0,0,0,0,0,128,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,128,14,0,0,0,255,31,
970,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,252,0,0,0,0,0,0,0,0,0,0,0,
980,0,0,0,0,0,0,0,0,0,0,0,
990,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,7,0,0,0,0,0,0,
1000,24,128,255,0,0,0,0,0,0,0,0,0,0,223,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
101128,62,0,0,252,255,31,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,52,
1020,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,
1030,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,
1040,0,0,0,0,0,0,0,0,63,0,0,0,0,0,0,0,128,255,48,0,0,248,3,0,0,0,0,0,0,0,0,0,0,0,
1050,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,7,0,0,0,0,0,0,0,0,0,0,0,
1060,
1070,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,176,15,0,0,0,0,0,0,0,0,0,0,0,255,255,
108255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
109255,255,255,255,255,255,255,255,255,63,0,255,255,255,255,127,254,255,255,255,
110255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
111255,1,0,0,255,255,255,255,255,255,255,255,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1120,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,127,0,255,255,3,0,0,0,0,
1130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,
1140,8,0,0,0,8,0,0,32,0,0,0,32,0,0,128,0,0,0,128,0,0,0,2,0,0,0,2,0,0,8,0,0,0,0,0,
1150,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,15,0,
116248,254,255,0,0,0,0,0,0,0,0,0,
1170,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,255,127,0,0,0,0,0,0,0,0,
1180,0,0,0,0,112,7,0,192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
1190,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,255,255,255,255,255,15,255,
120255,255,255,255,255,255,255,255,255,255,255,15,0,255,127,254,255,254,255,254,
121255,255,255,63,0,255,31,255,255,255,127,0,0,0,252,0,0,0,12,0,0,0,252,255,255,
122255,31,0,0,0,0,0,0,192,255,255,255,7,0,255,255,255,255,255,15,255,1,3,0,63,0,
1230,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,
124255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,255,31,
125255,1,255,255,255,255,255,255,255,255,255,255,255,255,255,255,15,0,255,255,
126255,255,255,255,255,255,255,255,31,0,0,0,0,
1270,255,15,255,255,255,255,255,255,255,0,255,3,255,255,255,255,255,0,255,255,
128255,63,0,0,0,0,0,0,0,0,0,0,255,15,255,255,255,255,255,127,255,31,255,255,255,
12915,0,0,255,255,255,0,0,0,0,0,1,0,255,255,127,0,0,0,
libc/musl/src/ctype/toascii.c created+7
......@@ -0,0 +1,7 @@
1#include <ctype.h>
2
3/* nonsense function that should NEVER be used! */
4int toascii(int c)
5{
6 return c & 0x7f;
7}
libc/musl/src/ctype/tolower.c created+14
......@@ -0,0 +1,14 @@
1#include <ctype.h>
2
3int tolower(int c)
4{
5 if (isupper(c)) return c | 32;
6 return c;
7}
8
9int __tolower_l(int c, locale_t l)
10{
11 return tolower(c);
12}
13
14weak_alias(__tolower_l, tolower_l);
libc/musl/src/ctype/toupper.c created+14
......@@ -0,0 +1,14 @@
1#include <ctype.h>
2
3int toupper(int c)
4{
5 if (islower(c)) return c & 0x5f;
6 return c;
7}
8
9int __toupper_l(int c, locale_t l)
10{
11 return toupper(c);
12}
13
14weak_alias(__toupper_l, toupper_l);
libc/musl/src/ctype/towctrans.c created+318
......@@ -0,0 +1,318 @@
1#include <ctype.h>
2#include <stddef.h>
3#include <wctype.h>
4
5#define CASEMAP(u1,u2,l) { (u1), (l)-(u1), (u2)-(u1)+1 }
6#define CASELACE(u1,u2) CASEMAP((u1),(u2),(u1)+1)
7
8static const struct {
9 unsigned short upper;
10 signed char lower;
11 unsigned char len;
12} casemaps[] = {
13 CASEMAP(0xc0,0xde,0xe0),
14
15 CASELACE(0x0100,0x012e),
16 CASELACE(0x0132,0x0136),
17 CASELACE(0x0139,0x0147),
18 CASELACE(0x014a,0x0176),
19 CASELACE(0x0179,0x017d),
20
21 CASELACE(0x370,0x372),
22 CASEMAP(0x391,0x3a1,0x3b1),
23 CASEMAP(0x3a3,0x3ab,0x3c3),
24 CASEMAP(0x400,0x40f,0x450),
25 CASEMAP(0x410,0x42f,0x430),
26
27 CASELACE(0x460,0x480),
28 CASELACE(0x48a,0x4be),
29 CASELACE(0x4c1,0x4cd),
30 CASELACE(0x4d0,0x50e),
31
32 CASELACE(0x514,0x52e),
33 CASEMAP(0x531,0x556,0x561),
34
35 CASELACE(0x01a0,0x01a4),
36 CASELACE(0x01b3,0x01b5),
37 CASELACE(0x01cd,0x01db),
38 CASELACE(0x01de,0x01ee),
39 CASELACE(0x01f8,0x021e),
40 CASELACE(0x0222,0x0232),
41 CASELACE(0x03d8,0x03ee),
42
43 CASELACE(0x1e00,0x1e94),
44 CASELACE(0x1ea0,0x1efe),
45
46 CASEMAP(0x1f08,0x1f0f,0x1f00),
47 CASEMAP(0x1f18,0x1f1d,0x1f10),
48 CASEMAP(0x1f28,0x1f2f,0x1f20),
49 CASEMAP(0x1f38,0x1f3f,0x1f30),
50 CASEMAP(0x1f48,0x1f4d,0x1f40),
51
52 CASEMAP(0x1f68,0x1f6f,0x1f60),
53 CASEMAP(0x1f88,0x1f8f,0x1f80),
54 CASEMAP(0x1f98,0x1f9f,0x1f90),
55 CASEMAP(0x1fa8,0x1faf,0x1fa0),
56 CASEMAP(0x1fb8,0x1fb9,0x1fb0),
57 CASEMAP(0x1fba,0x1fbb,0x1f70),
58 CASEMAP(0x1fc8,0x1fcb,0x1f72),
59 CASEMAP(0x1fd8,0x1fd9,0x1fd0),
60 CASEMAP(0x1fda,0x1fdb,0x1f76),
61 CASEMAP(0x1fe8,0x1fe9,0x1fe0),
62 CASEMAP(0x1fea,0x1feb,0x1f7a),
63 CASEMAP(0x1ff8,0x1ff9,0x1f78),
64 CASEMAP(0x1ffa,0x1ffb,0x1f7c),
65
66 CASEMAP(0x13f0,0x13f5,0x13f8),
67 CASELACE(0xa698,0xa69a),
68 CASELACE(0xa796,0xa79e),
69
70 CASELACE(0x246,0x24e),
71 CASELACE(0x510,0x512),
72 CASEMAP(0x2160,0x216f,0x2170),
73 CASEMAP(0x2c00,0x2c2e,0x2c30),
74 CASELACE(0x2c67,0x2c6b),
75 CASELACE(0x2c80,0x2ce2),
76 CASELACE(0x2ceb,0x2ced),
77
78 CASELACE(0xa640,0xa66c),
79 CASELACE(0xa680,0xa696),
80
81 CASELACE(0xa722,0xa72e),
82 CASELACE(0xa732,0xa76e),
83 CASELACE(0xa779,0xa77b),
84 CASELACE(0xa77e,0xa786),
85
86 CASELACE(0xa790,0xa792),
87 CASELACE(0xa7a0,0xa7a8),
88
89 CASELACE(0xa7b4,0xa7b6),
90
91 CASEMAP(0xff21,0xff3a,0xff41),
92 { 0,0,0 }
93};
94
95static const unsigned short pairs[][2] = {
96 { 'I', 0x0131 },
97 { 'S', 0x017f },
98 { 0x0130, 'i' },
99 { 0x0178, 0x00ff },
100 { 0x0181, 0x0253 },
101 { 0x0182, 0x0183 },
102 { 0x0184, 0x0185 },
103 { 0x0186, 0x0254 },
104 { 0x0187, 0x0188 },
105 { 0x0189, 0x0256 },
106 { 0x018a, 0x0257 },
107 { 0x018b, 0x018c },
108 { 0x018e, 0x01dd },
109 { 0x018f, 0x0259 },
110 { 0x0190, 0x025b },
111 { 0x0191, 0x0192 },
112 { 0x0193, 0x0260 },
113 { 0x0194, 0x0263 },
114 { 0x0196, 0x0269 },
115 { 0x0197, 0x0268 },
116 { 0x0198, 0x0199 },
117 { 0x019c, 0x026f },
118 { 0x019d, 0x0272 },
119 { 0x019f, 0x0275 },
120 { 0x01a6, 0x0280 },
121 { 0x01a7, 0x01a8 },
122 { 0x01a9, 0x0283 },
123 { 0x01ac, 0x01ad },
124 { 0x01ae, 0x0288 },
125 { 0x01af, 0x01b0 },
126 { 0x01b1, 0x028a },
127 { 0x01b2, 0x028b },
128 { 0x01b7, 0x0292 },
129 { 0x01b8, 0x01b9 },
130 { 0x01bc, 0x01bd },
131 { 0x01c4, 0x01c6 },
132 { 0x01c4, 0x01c5 },
133 { 0x01c5, 0x01c6 },
134 { 0x01c7, 0x01c9 },
135 { 0x01c7, 0x01c8 },
136 { 0x01c8, 0x01c9 },
137 { 0x01ca, 0x01cc },
138 { 0x01ca, 0x01cb },
139 { 0x01cb, 0x01cc },
140 { 0x01f1, 0x01f3 },
141 { 0x01f1, 0x01f2 },
142 { 0x01f2, 0x01f3 },
143 { 0x01f4, 0x01f5 },
144 { 0x01f6, 0x0195 },
145 { 0x01f7, 0x01bf },
146 { 0x0220, 0x019e },
147 { 0x0386, 0x03ac },
148 { 0x0388, 0x03ad },
149 { 0x0389, 0x03ae },
150 { 0x038a, 0x03af },
151 { 0x038c, 0x03cc },
152 { 0x038e, 0x03cd },
153 { 0x038f, 0x03ce },
154 { 0x0399, 0x0345 },
155 { 0x0399, 0x1fbe },
156 { 0x03a3, 0x03c2 },
157 { 0x03f7, 0x03f8 },
158 { 0x03fa, 0x03fb },
159 { 0x1e60, 0x1e9b },
160 { 0x1e9e, 0xdf },
161
162 { 0x1f59, 0x1f51 },
163 { 0x1f5b, 0x1f53 },
164 { 0x1f5d, 0x1f55 },
165 { 0x1f5f, 0x1f57 },
166 { 0x1fbc, 0x1fb3 },
167 { 0x1fcc, 0x1fc3 },
168 { 0x1fec, 0x1fe5 },
169 { 0x1ffc, 0x1ff3 },
170
171 { 0x23a, 0x2c65 },
172 { 0x23b, 0x23c },
173 { 0x23d, 0x19a },
174 { 0x23e, 0x2c66 },
175 { 0x241, 0x242 },
176 { 0x243, 0x180 },
177 { 0x244, 0x289 },
178 { 0x245, 0x28c },
179 { 0x3f4, 0x3b8 },
180 { 0x3f9, 0x3f2 },
181 { 0x3fd, 0x37b },
182 { 0x3fe, 0x37c },
183 { 0x3ff, 0x37d },
184 { 0x4c0, 0x4cf },
185
186 { 0x2126, 0x3c9 },
187 { 0x212a, 'k' },
188 { 0x212b, 0xe5 },
189 { 0x2132, 0x214e },
190 { 0x2183, 0x2184 },
191 { 0x2c60, 0x2c61 },
192 { 0x2c62, 0x26b },
193 { 0x2c63, 0x1d7d },
194 { 0x2c64, 0x27d },
195 { 0x2c6d, 0x251 },
196 { 0x2c6e, 0x271 },
197 { 0x2c6f, 0x250 },
198 { 0x2c70, 0x252 },
199 { 0x2c72, 0x2c73 },
200 { 0x2c75, 0x2c76 },
201 { 0x2c7e, 0x23f },
202 { 0x2c7f, 0x240 },
203 { 0x2cf2, 0x2cf3 },
204
205 { 0xa77d, 0x1d79 },
206 { 0xa78b, 0xa78c },
207 { 0xa78d, 0x265 },
208 { 0xa7aa, 0x266 },
209
210 { 0x10c7, 0x2d27 },
211 { 0x10cd, 0x2d2d },
212
213 /* bogus greek 'symbol' letters */
214 { 0x376, 0x377 },
215 { 0x39c, 0xb5 },
216 { 0x392, 0x3d0 },
217 { 0x398, 0x3d1 },
218 { 0x3a6, 0x3d5 },
219 { 0x3a0, 0x3d6 },
220 { 0x39a, 0x3f0 },
221 { 0x3a1, 0x3f1 },
222 { 0x395, 0x3f5 },
223 { 0x3cf, 0x3d7 },
224
225 { 0xa7ab, 0x25c },
226 { 0xa7ac, 0x261 },
227 { 0xa7ad, 0x26c },
228 { 0xa7ae, 0x26a },
229 { 0xa7b0, 0x29e },
230 { 0xa7b1, 0x287 },
231 { 0xa7b2, 0x29d },
232 { 0xa7b3, 0xab53 },
233
234 /* special cyrillic lowercase forms */
235 { 0x412, 0x1c80 },
236 { 0x414, 0x1c81 },
237 { 0x41e, 0x1c82 },
238 { 0x421, 0x1c83 },
239 { 0x422, 0x1c84 },
240 { 0x422, 0x1c85 },
241 { 0x42a, 0x1c86 },
242 { 0x462, 0x1c87 },
243 { 0xa64a, 0x1c88 },
244
245 { 0,0 }
246};
247
248
249static wchar_t __towcase(wchar_t wc, int lower)
250{
251 int i;
252 int lmul = 2*lower-1;
253 int lmask = lower-1;
254 /* no letters with case in these large ranges */
255 if (!iswalpha(wc)
256 || (unsigned)wc - 0x0600 <= 0x0fff-0x0600
257 || (unsigned)wc - 0x2e00 <= 0xa63f-0x2e00
258 || (unsigned)wc - 0xa800 <= 0xab52-0xa800
259 || (unsigned)wc - 0xabc0 <= 0xfeff-0xabc0)
260 return wc;
261 /* special case because the diff between upper/lower is too big */
262 if (lower && (unsigned)wc - 0x10a0 < 0x2e)
263 if (wc>0x10c5 && wc != 0x10c7 && wc != 0x10cd) return wc;
264 else return wc + 0x2d00 - 0x10a0;
265 if (!lower && (unsigned)wc - 0x2d00 < 0x26)
266 if (wc>0x2d25 && wc != 0x2d27 && wc != 0x2d2d) return wc;
267 else return wc + 0x10a0 - 0x2d00;
268 if (lower && (unsigned)wc - 0x13a0 < 0x50)
269 return wc + 0xab70 - 0x13a0;
270 if (!lower && (unsigned)wc - 0xab70 < 0x50)
271 return wc + 0x13a0 - 0xab70;
272 for (i=0; casemaps[i].len; i++) {
273 int base = casemaps[i].upper + (lmask & casemaps[i].lower);
274 if ((unsigned)wc-base < casemaps[i].len) {
275 if (casemaps[i].lower == 1)
276 return wc + lower - ((wc-casemaps[i].upper)&1);
277 return wc + lmul*casemaps[i].lower;
278 }
279 }
280 for (i=0; pairs[i][1-lower]; i++) {
281 if (pairs[i][1-lower] == wc)
282 return pairs[i][lower];
283 }
284 if ((unsigned)wc - (0x10428 - 0x28*lower) < 0x28)
285 return wc - 0x28 + 0x50*lower;
286 if ((unsigned)wc - (0x104d8 - 0x28*lower) < 0x24)
287 return wc - 0x28 + 0x50*lower;
288 if ((unsigned)wc - (0x10cc0 - 0x40*lower) < 0x33)
289 return wc - 0x40 + 0x80*lower;
290 if ((unsigned)wc - (0x118c0 - 0x20*lower) < 0x20)
291 return wc - 0x20 + 0x40*lower;
292 if ((unsigned)wc - (0x1e922 - 0x22*lower) < 0x22)
293 return wc - 0x22 + 0x44*lower;
294 return wc;
295}
296
297wint_t towupper(wint_t wc)
298{
299 return (unsigned)wc < 128 ? toupper(wc) : __towcase(wc, 0);
300}
301
302wint_t towlower(wint_t wc)
303{
304 return (unsigned)wc < 128 ? tolower(wc) : __towcase(wc, 1);
305}
306
307wint_t __towupper_l(wint_t c, locale_t l)
308{
309 return towupper(c);
310}
311
312wint_t __towlower_l(wint_t c, locale_t l)
313{
314 return towlower(c);
315}
316
317weak_alias(__towupper_l, towupper_l);
318weak_alias(__towlower_l, towlower_l);
libc/musl/src/ctype/wcswidth.c created+8
......@@ -0,0 +1,8 @@
1#include <wchar.h>
2
3int wcswidth(const wchar_t *wcs, size_t n)
4{
5 int l=0, k=0;
6 for (; n-- && *wcs && (k = wcwidth(*wcs)) >= 0; l+=k, wcs++);
7 return (k < 0) ? k : l;
8}
libc/musl/src/ctype/wctrans.c created+29
......@@ -0,0 +1,29 @@
1#include <wctype.h>
2#include <string.h>
3
4wctrans_t wctrans(const char *class)
5{
6 if (!strcmp(class, "toupper")) return (wctrans_t)1;
7 if (!strcmp(class, "tolower")) return (wctrans_t)2;
8 return 0;
9}
10
11wint_t towctrans(wint_t wc, wctrans_t trans)
12{
13 if (trans == (wctrans_t)1) return towupper(wc);
14 if (trans == (wctrans_t)2) return towlower(wc);
15 return wc;
16}
17
18wctrans_t __wctrans_l(const char *s, locale_t l)
19{
20 return wctrans(s);
21}
22
23wint_t __towctrans_l(wint_t c, wctrans_t t, locale_t l)
24{
25 return towctrans(c, t);
26}
27
28weak_alias(__wctrans_l, wctrans_l);
29weak_alias(__towctrans_l, towctrans_l);
libc/musl/src/ctype/wcwidth.c created+29
......@@ -0,0 +1,29 @@
1#include <wchar.h>
2
3static const unsigned char table[] = {
4#include "nonspacing.h"
5};
6
7static const unsigned char wtable[] = {
8#include "wide.h"
9};
10
11int wcwidth(wchar_t wc)
12{
13 if (wc < 0xffU)
14 return (wc+1 & 0x7f) >= 0x21 ? 1 : wc ? -1 : 0;
15 if ((wc & 0xfffeffffU) < 0xfffe) {
16 if ((table[table[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1)
17 return 0;
18 if ((wtable[wtable[wc>>8]*32+((wc&255)>>3)]>>(wc&7))&1)
19 return 2;
20 return 1;
21 }
22 if ((wc & 0xfffe) == 0xfffe)
23 return -1;
24 if (wc-0x20000U < 0x20000)
25 return 2;
26 if (wc == 0xe0001 || wc-0xe0020U < 0x5f || wc-0xe0100 < 0xef)
27 return 0;
28 return 1;
29}
libc/musl/src/ctype/wide.h created+63
......@@ -0,0 +1,63 @@
116,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,16,16,16,16,16,16,16,16,
216,16,16,16,16,16,16,16,16,19,16,20,21,22,16,16,16,23,16,16,24,25,26,27,28,17,
317,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,29,
417,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
517,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
617,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
717,17,17,17,17,17,17,17,30,16,16,16,16,31,16,16,17,17,17,17,17,17,17,17,17,17,
817,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
917,17,17,17,17,17,17,32,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1016,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,16,16,16,33,
1134,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1216,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1316,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1416,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1516,16,16,16,16,16,16,16,35,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,
1617,17,17,17,17,17,36,17,17,37,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1716,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,38,39,16,16,
1816,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
1916,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
2016,16,16,16,16,16,16,40,41,42,43,44,45,46,16,16,47,16,16,16,16,16,
2116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,
22255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
23255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
24255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,0,6,0,0,0,0,
250,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,30,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
260,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,48,0,0,0,0,0,0,255,15,0,0,0,0,128,0,0,8,
270,2,12,0,96,48,64,16,0,0,4,44,36,32,12,0,0,0,1,0,0,0,80,184,0,0,0,0,0,0,0,224,
280,0,0,1,128,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,
290,0,0,0,0,0,0,
300,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,251,255,255,255,255,255,255,255,
31255,255,255,15,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
32255,255,255,255,255,255,255,255,255,255,255,63,0,0,0,255,15,255,255,255,255,
33255,255,255,127,254,255,255,255,255,255,255,255,255,255,127,254,255,255,255,
34255,255,255,255,255,255,255,255,255,224,255,255,255,255,127,254,255,255,255,
35255,255,255,255,255,255,255,127,255,255,255,255,255,7,255,255,255,255,15,0,
36255,255,255,255,255,127,255,255,255,255,255,0,255,255,255,255,255,255,255,255,
37255,255,255,255,255,255,255,255,255,255,255,255,255,127,255,255,255,255,255,
38255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,
390,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
40255,31,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,
41255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
420,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
43255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,255,3,0,0,255,255,255,255,247,255,127,15,0,0,
440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,255,255,255,255,255,255,255,255,255,255,
45255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
460,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,255,255,255,255,255,255,255,255,255,255,255,
47255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,
480,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
49255,255,255,255,255,255,255,255,255,255,255,7,0,255,255,255,127,0,0,0,0,0,0,0,
500,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
51255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
52255,255,255,255,255,255,255,255,255,255,255,255,
5315,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,
540,0,0,0,0,0,0,0,0,0,0,0,0,64,254,7,0,0,0,0,0,0,0,0,0,0,0,0,7,0,255,255,255,
55255,255,15,255,1,3,0,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,
561,224,191,255,255,255,255,255,255,255,255,223,255,255,15,0,255,255,255,255,
57255,135,15,0,255,255,17,255,255,255,255,255,255,255,255,127,253,255,255,255,
58255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
59159,255,255,255,255,255,255,255,63,0,120,255,255,255,0,0,4,0,0,96,0,16,0,0,0,
600,0,0,0,0,0,0,248,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,255,255,
61255,255,255,255,255,255,63,16,7,0,0,24,240,1,0,0,255,255,255,255,255,127,255,
6231,255,255,255,15,0,0,255,255,255,0,0,0,0,0,1,0,255,255,127,0,0,
630,
libc/musl/src/dirent/__dirent.h created+11
......@@ -0,0 +1,11 @@
1struct __dirstream
2{
3 off_t tell;
4 int fd;
5 int buf_pos;
6 int buf_end;
7 volatile int lock[1];
8 /* Any changes to this struct must preserve the property:
9 * offsetof(struct __dirent, buf) % sizeof(off_t) == 0 */
10 char buf[2048];
11};
libc/musl/src/dirent/alphasort.c created+9
......@@ -0,0 +1,9 @@
1#include <string.h>
2#include <dirent.h>
3
4int alphasort(const struct dirent **a, const struct dirent **b)
5{
6 return strcoll((*a)->d_name, (*b)->d_name);
7}
8
9weak_alias(alphasort, alphasort64);
libc/musl/src/dirent/closedir.c created+11
......@@ -0,0 +1,11 @@
1#include <dirent.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include "__dirent.h"
5
6int closedir(DIR *dir)
7{
8 int ret = close(dir->fd);
9 free(dir);
10 return ret;
11}
libc/musl/src/dirent/dirfd.c created+7
......@@ -0,0 +1,7 @@
1#include <dirent.h>
2#include "__dirent.h"
3
4int dirfd(DIR *d)
5{
6 return d->fd;
7}
libc/musl/src/dirent/fdopendir.c created+27
......@@ -0,0 +1,27 @@
1#include <dirent.h>
2#include <fcntl.h>
3#include <sys/stat.h>
4#include <errno.h>
5#include <stdlib.h>
6#include "__dirent.h"
7
8DIR *fdopendir(int fd)
9{
10 DIR *dir;
11 struct stat st;
12
13 if (fstat(fd, &st) < 0) {
14 return 0;
15 }
16 if (!S_ISDIR(st.st_mode)) {
17 errno = ENOTDIR;
18 return 0;
19 }
20 if (!(dir = calloc(1, sizeof *dir))) {
21 return 0;
22 }
23
24 fcntl(fd, F_SETFD, FD_CLOEXEC);
25 dir->fd = fd;
26 return dir;
27}
libc/musl/src/dirent/opendir.c created+21
......@@ -0,0 +1,21 @@
1#define _GNU_SOURCE
2#include <dirent.h>
3#include <fcntl.h>
4#include <stdlib.h>
5#include "__dirent.h"
6#include "syscall.h"
7
8DIR *opendir(const char *name)
9{
10 int fd;
11 DIR *dir;
12
13 if ((fd = open(name, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) < 0)
14 return 0;
15 if (!(dir = calloc(1, sizeof *dir))) {
16 __syscall(SYS_close, fd);
17 return 0;
18 }
19 dir->fd = fd;
20 return dir;
21}
libc/musl/src/dirent/readdir.c created+29
......@@ -0,0 +1,29 @@
1#include <dirent.h>
2#include <errno.h>
3#include <stddef.h>
4#include "__dirent.h"
5#include "syscall.h"
6
7typedef char dirstream_buf_alignment_check[1-2*(int)(
8 offsetof(struct __dirstream, buf) % sizeof(off_t))];
9
10struct dirent *readdir(DIR *dir)
11{
12 struct dirent *de;
13
14 if (dir->buf_pos >= dir->buf_end) {
15 int len = __syscall(SYS_getdents, dir->fd, dir->buf, sizeof dir->buf);
16 if (len <= 0) {
17 if (len < 0 && len != -ENOENT) errno = -len;
18 return 0;
19 }
20 dir->buf_end = len;
21 dir->buf_pos = 0;
22 }
23 de = (void *)(dir->buf + dir->buf_pos);
24 dir->buf_pos += de->d_reclen;
25 dir->tell = de->d_off;
26 return de;
27}
28
29weak_alias(readdir, readdir64);
libc/musl/src/dirent/readdir_r.c created+29
......@@ -0,0 +1,29 @@
1#include <dirent.h>
2#include <errno.h>
3#include <string.h>
4#include "__dirent.h"
5#include "lock.h"
6
7int readdir_r(DIR *restrict dir, struct dirent *restrict buf, struct dirent **restrict result)
8{
9 struct dirent *de;
10 int errno_save = errno;
11 int ret;
12
13 LOCK(dir->lock);
14 errno = 0;
15 de = readdir(dir);
16 if ((ret = errno)) {
17 UNLOCK(dir->lock);
18 return ret;
19 }
20 errno = errno_save;
21 if (de) memcpy(buf, de, de->d_reclen);
22 else buf = NULL;
23
24 UNLOCK(dir->lock);
25 *result = buf;
26 return 0;
27}
28
29weak_alias(readdir_r, readdir64_r);
libc/musl/src/dirent/rewinddir.c created+13
......@@ -0,0 +1,13 @@
1#include <dirent.h>
2#include <unistd.h>
3#include "__dirent.h"
4#include "lock.h"
5
6void rewinddir(DIR *dir)
7{
8 LOCK(dir->lock);
9 lseek(dir->fd, 0, SEEK_SET);
10 dir->buf_pos = dir->buf_end = 0;
11 dir->tell = 0;
12 UNLOCK(dir->lock);
13}
libc/musl/src/dirent/scandir.c created+47
......@@ -0,0 +1,47 @@
1#include <dirent.h>
2#include <string.h>
3#include <stdlib.h>
4#include <stdint.h>
5#include <errno.h>
6#include <stddef.h>
7
8int scandir(const char *path, struct dirent ***res,
9 int (*sel)(const struct dirent *),
10 int (*cmp)(const struct dirent **, const struct dirent **))
11{
12 DIR *d = opendir(path);
13 struct dirent *de, **names=0, **tmp;
14 size_t cnt=0, len=0;
15 int old_errno = errno;
16
17 if (!d) return -1;
18
19 while ((errno=0), (de = readdir(d))) {
20 if (sel && !sel(de)) continue;
21 if (cnt >= len) {
22 len = 2*len+1;
23 if (len > SIZE_MAX/sizeof *names) break;
24 tmp = realloc(names, len * sizeof *names);
25 if (!tmp) break;
26 names = tmp;
27 }
28 names[cnt] = malloc(de->d_reclen);
29 if (!names[cnt]) break;
30 memcpy(names[cnt++], de, de->d_reclen);
31 }
32
33 closedir(d);
34
35 if (errno) {
36 if (names) while (cnt-->0) free(names[cnt]);
37 free(names);
38 return -1;
39 }
40 errno = old_errno;
41
42 if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);
43 *res = names;
44 return cnt;
45}
46
47weak_alias(scandir, scandir64);
libc/musl/src/dirent/seekdir.c created+12
......@@ -0,0 +1,12 @@
1#include <dirent.h>
2#include <unistd.h>
3#include "__dirent.h"
4#include "lock.h"
5
6void seekdir(DIR *dir, long off)
7{
8 LOCK(dir->lock);
9 dir->tell = lseek(dir->fd, off, SEEK_SET);
10 dir->buf_pos = dir->buf_end = 0;
11 UNLOCK(dir->lock);
12}
libc/musl/src/dirent/telldir.c created+7
......@@ -0,0 +1,7 @@
1#include <dirent.h>
2#include "__dirent.h"
3
4long telldir(DIR *dir)
5{
6 return dir->tell;
7}
libc/musl/src/dirent/versionsort.c created+11
......@@ -0,0 +1,11 @@
1#define _GNU_SOURCE
2#include <string.h>
3#include <dirent.h>
4
5int versionsort(const struct dirent **a, const struct dirent **b)
6{
7 return strverscmp((*a)->d_name, (*b)->d_name);
8}
9
10#undef versionsort64
11weak_alias(versionsort, versionsort64);
libc/musl/src/env/__environ.c created+6
......@@ -0,0 +1,6 @@
1#include <unistd.h>
2
3char **__environ = 0;
4weak_alias(__environ, ___environ);
5weak_alias(__environ, _environ);
6weak_alias(__environ, environ);
libc/musl/src/env/__init_tls.c created+147
......@@ -0,0 +1,147 @@
1#include <elf.h>
2#include <limits.h>
3#include <sys/mman.h>
4#include <string.h>
5#include <stddef.h>
6#include "pthread_impl.h"
7#include "libc.h"
8#include "atomic.h"
9#include "syscall.h"
10
11int __init_tp(void *p)
12{
13 pthread_t td = p;
14 td->self = td;
15 int r = __set_thread_area(TP_ADJ(p));
16 if (r < 0) return -1;
17 if (!r) libc.can_do_threads = 1;
18 td->detach_state = DT_JOINABLE;
19 td->tid = __syscall(SYS_set_tid_address, &td->detach_state);
20 td->locale = &libc.global_locale;
21 td->robust_list.head = &td->robust_list.head;
22 return 0;
23}
24
25static struct builtin_tls {
26 char c;
27 struct pthread pt;
28 void *space[16];
29} builtin_tls[1];
30#define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
31
32static struct tls_module main_tls;
33
34void *__copy_tls(unsigned char *mem)
35{
36 pthread_t td;
37 struct tls_module *p;
38 size_t i;
39 uintptr_t *dtv;
40
41#ifdef TLS_ABOVE_TP
42 dtv = (uintptr_t*)(mem + libc.tls_size) - (libc.tls_cnt + 1);
43
44 mem += -((uintptr_t)mem + sizeof(struct pthread)) & (libc.tls_align-1);
45 td = (pthread_t)mem;
46 mem += sizeof(struct pthread);
47
48 for (i=1, p=libc.tls_head; p; i++, p=p->next) {
49 dtv[i] = (uintptr_t)(mem + p->offset) + DTP_OFFSET;
50 memcpy(mem + p->offset, p->image, p->len);
51 }
52#else
53 dtv = (uintptr_t *)mem;
54
55 mem += libc.tls_size - sizeof(struct pthread);
56 mem -= (uintptr_t)mem & (libc.tls_align-1);
57 td = (pthread_t)mem;
58
59 for (i=1, p=libc.tls_head; p; i++, p=p->next) {
60 dtv[i] = (uintptr_t)(mem - p->offset) + DTP_OFFSET;
61 memcpy(mem - p->offset, p->image, p->len);
62 }
63#endif
64 dtv[0] = libc.tls_cnt;
65 td->dtv = td->dtv_copy = dtv;
66 return td;
67}
68
69#if ULONG_MAX == 0xffffffff
70typedef Elf32_Phdr Phdr;
71#else
72typedef Elf64_Phdr Phdr;
73#endif
74
75extern weak hidden const size_t _DYNAMIC[];
76
77static void static_init_tls(size_t *aux)
78{
79 unsigned char *p;
80 size_t n;
81 Phdr *phdr, *tls_phdr=0;
82 size_t base = 0;
83 void *mem;
84
85 for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
86 phdr = (void *)p;
87 if (phdr->p_type == PT_PHDR)
88 base = aux[AT_PHDR] - phdr->p_vaddr;
89 if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
90 base = (size_t)_DYNAMIC - phdr->p_vaddr;
91 if (phdr->p_type == PT_TLS)
92 tls_phdr = phdr;
93 if (phdr->p_type == PT_GNU_STACK &&
94 phdr->p_memsz > __default_stacksize)
95 __default_stacksize =
96 phdr->p_memsz < DEFAULT_STACK_MAX ?
97 phdr->p_memsz : DEFAULT_STACK_MAX;
98 }
99
100 if (tls_phdr) {
101 main_tls.image = (void *)(base + tls_phdr->p_vaddr);
102 main_tls.len = tls_phdr->p_filesz;
103 main_tls.size = tls_phdr->p_memsz;
104 main_tls.align = tls_phdr->p_align;
105 libc.tls_cnt = 1;
106 libc.tls_head = &main_tls;
107 }
108
109 main_tls.size += (-main_tls.size - (uintptr_t)main_tls.image)
110 & (main_tls.align-1);
111#ifdef TLS_ABOVE_TP
112 main_tls.offset = GAP_ABOVE_TP;
113 main_tls.offset += -GAP_ABOVE_TP & (main_tls.align-1);
114#else
115 main_tls.offset = main_tls.size;
116#endif
117 if (main_tls.align < MIN_TLS_ALIGN) main_tls.align = MIN_TLS_ALIGN;
118
119 libc.tls_align = main_tls.align;
120 libc.tls_size = 2*sizeof(void *) + sizeof(struct pthread)
121#ifdef TLS_ABOVE_TP
122 + main_tls.offset
123#endif
124 + main_tls.size + main_tls.align
125 + MIN_TLS_ALIGN-1 & -MIN_TLS_ALIGN;
126
127 if (libc.tls_size > sizeof builtin_tls) {
128#ifndef SYS_mmap2
129#define SYS_mmap2 SYS_mmap
130#endif
131 mem = (void *)__syscall(
132 SYS_mmap2,
133 0, libc.tls_size, PROT_READ|PROT_WRITE,
134 MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
135 /* -4095...-1 cast to void * will crash on dereference anyway,
136 * so don't bloat the init code checking for error codes and
137 * explicitly calling a_crash(). */
138 } else {
139 mem = builtin_tls;
140 }
141
142 /* Failure to initialize thread pointer is always fatal. */
143 if (__init_tp(__copy_tls(mem)) < 0)
144 a_crash();
145}
146
147weak_alias(static_init_tls, __init_tls);
libc/musl/src/env/__libc_start_main.c created+96
......@@ -0,0 +1,96 @@
1#include <elf.h>
2#include <poll.h>
3#include <fcntl.h>
4#include <signal.h>
5#include <unistd.h>
6#include "syscall.h"
7#include "atomic.h"
8#include "libc.h"
9
10static void dummy(void) {}
11weak_alias(dummy, _init);
12
13extern weak hidden void (*const __init_array_start)(void), (*const __init_array_end)(void);
14
15static void dummy1(void *p) {}
16weak_alias(dummy1, __init_ssp);
17
18#define AUX_CNT 38
19
20#ifdef __GNUC__
21__attribute__((__noinline__))
22#endif
23void __init_libc(char **envp, char *pn)
24{
25 size_t i, *auxv, aux[AUX_CNT] = { 0 };
26 __environ = envp;
27 for (i=0; envp[i]; i++);
28 libc.auxv = auxv = (void *)(envp+i+1);
29 for (i=0; auxv[i]; i+=2) if (auxv[i]<AUX_CNT) aux[auxv[i]] = auxv[i+1];
30 __hwcap = aux[AT_HWCAP];
31 __sysinfo = aux[AT_SYSINFO];
32 libc.page_size = aux[AT_PAGESZ];
33
34 if (!pn) pn = (void*)aux[AT_EXECFN];
35 if (!pn) pn = "";
36 __progname = __progname_full = pn;
37 for (i=0; pn[i]; i++) if (pn[i]=='/') __progname = pn+i+1;
38
39 __init_tls(aux);
40 __init_ssp((void *)aux[AT_RANDOM]);
41
42 if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID]
43 && !aux[AT_SECURE]) return;
44
45 struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} };
46 int r =
47#ifdef SYS_poll
48 __syscall(SYS_poll, pfd, 3, 0);
49#else
50 __syscall(SYS_ppoll, pfd, 3, &(struct timespec){0}, 0, _NSIG/8);
51#endif
52 if (r<0) a_crash();
53 for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL)
54 if (__sys_open("/dev/null", O_RDWR)<0)
55 a_crash();
56 libc.secure = 1;
57}
58
59static void libc_start_init(void)
60{
61 _init();
62 uintptr_t a = (uintptr_t)&__init_array_start;
63 for (; a<(uintptr_t)&__init_array_end; a+=sizeof(void(*)()))
64 (*(void (**)(void))a)();
65}
66
67weak_alias(libc_start_init, __libc_start_init);
68
69typedef int lsm2_fn(int (*)(int,char **,char **), int, char **);
70static lsm2_fn libc_start_main_stage2;
71
72int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv)
73{
74 char **envp = argv+argc+1;
75
76 /* External linkage, and explicit noinline attribute if available,
77 * are used to prevent the stack frame used during init from
78 * persisting for the entire process lifetime. */
79 __init_libc(envp, argv[0]);
80
81 /* Barrier against hoisting application code or anything using ssp
82 * or thread pointer prior to its initialization above. */
83 lsm2_fn *stage2 = libc_start_main_stage2;
84 __asm__ ( "" : "+r"(stage2) : : "memory" );
85 return stage2(main, argc, argv);
86}
87
88static int libc_start_main_stage2(int (*main)(int,char **,char **), int argc, char **argv)
89{
90 char **envp = argv+argc+1;
91 __libc_start_init();
92
93 /* Pass control to the application */
94 exit(main(argc, argv, envp));
95 return 0;
96}
libc/musl/src/env/__reset_tls.c created+15
......@@ -0,0 +1,15 @@
1#include <string.h>
2#include "pthread_impl.h"
3#include "libc.h"
4
5void __reset_tls()
6{
7 pthread_t self = __pthread_self();
8 struct tls_module *p;
9 size_t i, n = self->dtv[0];
10 if (n) for (p=libc.tls_head, i=1; i<=n; i++, p=p->next) {
11 char *mem = (char *)(self->dtv[i] - DTP_OFFSET);
12 memcpy(mem, p->image, p->len);
13 memset(mem+p->len, 0, p->size - p->len);
14 }
15}
libc/musl/src/env/__stack_chk_fail.c created+22
......@@ -0,0 +1,22 @@
1#include <string.h>
2#include <stdint.h>
3#include "pthread_impl.h"
4
5uintptr_t __stack_chk_guard;
6
7void __init_ssp(void *entropy)
8{
9 if (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t));
10 else __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245;
11
12 __pthread_self()->CANARY = __stack_chk_guard;
13}
14
15void __stack_chk_fail(void)
16{
17 a_crash();
18}
19
20hidden void __stack_chk_fail_local(void);
21
22weak_alias(__stack_chk_fail, __stack_chk_fail_local);
libc/musl/src/env/clearenv.c created+14
......@@ -0,0 +1,14 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <unistd.h>
4
5static void dummy(char *old, char *new) {}
6weak_alias(dummy, __env_rm_add);
7
8int clearenv()
9{
10 char **e = __environ;
11 __environ = 0;
12 if (e) while (*e) __env_rm_add(*e++, 0);
13 return 0;
14}
libc/musl/src/env/getenv.c created+13
......@@ -0,0 +1,13 @@
1#include <stdlib.h>
2#include <string.h>
3#include <unistd.h>
4
5char *getenv(const char *name)
6{
7 size_t l = __strchrnul(name, '=') - name;
8 if (l && !name[l] && __environ)
9 for (char **e = __environ; *e; e++)
10 if (!strncmp(name, *e, l) && l[*e] == '=')
11 return *e + l+1;
12 return 0;
13}
libc/musl/src/env/putenv.c created+46
......@@ -0,0 +1,46 @@
1#include <stdlib.h>
2#include <string.h>
3#include <unistd.h>
4
5static void dummy(char *old, char *new) {}
6weak_alias(dummy, __env_rm_add);
7
8int __putenv(char *s, size_t l, char *r)
9{
10 size_t i=0;
11 if (__environ) {
12 for (char **e = __environ; *e; e++, i++)
13 if (!strncmp(s, *e, l+1)) {
14 char *tmp = *e;
15 *e = s;
16 __env_rm_add(tmp, r);
17 return 0;
18 }
19 }
20 static char **oldenv;
21 char **newenv;
22 if (__environ == oldenv) {
23 newenv = realloc(oldenv, sizeof *newenv * (i+2));
24 if (!newenv) goto oom;
25 } else {
26 newenv = malloc(sizeof *newenv * (i+2));
27 if (!newenv) goto oom;
28 if (i) memcpy(newenv, __environ, sizeof *newenv * i);
29 free(oldenv);
30 }
31 newenv[i] = s;
32 newenv[i+1] = 0;
33 __environ = oldenv = newenv;
34 if (r) __env_rm_add(0, r);
35 return 0;
36oom:
37 free(r);
38 return -1;
39}
40
41int putenv(char *s)
42{
43 size_t l = __strchrnul(s, '=') - s;
44 if (!l || !s[l]) return unsetenv(s);
45 return __putenv(s, l, 0);
46}
libc/musl/src/env/setenv.c created+42
......@@ -0,0 +1,42 @@
1#include <stdlib.h>
2#include <string.h>
3#include <errno.h>
4
5void __env_rm_add(char *old, char *new)
6{
7 static char **env_alloced;
8 static size_t env_alloced_n;
9 for (size_t i=0; i < env_alloced_n; i++)
10 if (env_alloced[i] == old) {
11 env_alloced[i] = new;
12 free(old);
13 return;
14 } else if (!env_alloced[i] && new) {
15 env_alloced[i] = new;
16 new = 0;
17 }
18 if (!new) return;
19 char **t = realloc(env_alloced, sizeof *t * (env_alloced_n+1));
20 if (!t) return;
21 (env_alloced = t)[env_alloced_n++] = new;
22}
23
24int setenv(const char *var, const char *value, int overwrite)
25{
26 char *s;
27 size_t l1, l2;
28
29 if (!var || !(l1 = __strchrnul(var, '=') - var) || var[l1]) {
30 errno = EINVAL;
31 return -1;
32 }
33 if (!overwrite && getenv(var)) return 0;
34
35 l2 = strlen(value);
36 s = malloc(l1+l2+2);
37 if (!s) return -1;
38 memcpy(s, var, l1);
39 s[l1] = '=';
40 memcpy(s+l1+1, value, l2+1);
41 return __putenv(s, l1, s);
42}
libc/musl/src/env/unsetenv.c created+28
......@@ -0,0 +1,28 @@
1#include <stdlib.h>
2#include <string.h>
3#include <errno.h>
4#include <unistd.h>
5
6static void dummy(char *old, char *new) {}
7weak_alias(dummy, __env_rm_add);
8
9int unsetenv(const char *name)
10{
11 size_t l = __strchrnul(name, '=') - name;
12 if (!l || name[l]) {
13 errno = EINVAL;
14 return -1;
15 }
16 if (__environ) {
17 char **e = __environ, **eo = e;
18 for (; *e; e++)
19 if (!strncmp(name, *e, l) && l[*e] == '=')
20 __env_rm_add(*e, 0);
21 else if (eo != e)
22 *eo++ = *e;
23 else
24 eo++;
25 if (eo != e) *eo = 0;
26 }
27 return 0;
28}
libc/musl/src/errno/__errno_location.c created+9
......@@ -0,0 +1,9 @@
1#include <errno.h>
2#include "pthread_impl.h"
3
4int *__errno_location(void)
5{
6 return &__pthread_self()->errno_val;
7}
8
9weak_alias(__errno_location, ___errno_location);
libc/musl/src/errno/__strerror.h created+105
......@@ -0,0 +1,105 @@
1/* This file is sorted such that 'errors' which represent exceptional
2 * conditions under which a correct program may fail come first, followed
3 * by messages that indicate an incorrect program or system failure. The
4 * macro E() along with double-inclusion is used to ensure that ordering
5 * of the strings remains synchronized. */
6
7E(EILSEQ, "Illegal byte sequence")
8E(EDOM, "Domain error")
9E(ERANGE, "Result not representable")
10
11E(ENOTTY, "Not a tty")
12E(EACCES, "Permission denied")
13E(EPERM, "Operation not permitted")
14E(ENOENT, "No such file or directory")
15E(ESRCH, "No such process")
16E(EEXIST, "File exists")
17
18E(EOVERFLOW, "Value too large for data type")
19E(ENOSPC, "No space left on device")
20E(ENOMEM, "Out of memory")
21
22E(EBUSY, "Resource busy")
23E(EINTR, "Interrupted system call")
24E(EAGAIN, "Resource temporarily unavailable")
25E(ESPIPE, "Invalid seek")
26
27E(EXDEV, "Cross-device link")
28E(EROFS, "Read-only file system")
29E(ENOTEMPTY, "Directory not empty")
30
31E(ECONNRESET, "Connection reset by peer")
32E(ETIMEDOUT, "Operation timed out")
33E(ECONNREFUSED, "Connection refused")
34E(EHOSTDOWN, "Host is down")
35E(EHOSTUNREACH, "Host is unreachable")
36E(EADDRINUSE, "Address in use")
37
38E(EPIPE, "Broken pipe")
39E(EIO, "I/O error")
40E(ENXIO, "No such device or address")
41E(ENOTBLK, "Block device required")
42E(ENODEV, "No such device")
43E(ENOTDIR, "Not a directory")
44E(EISDIR, "Is a directory")
45E(ETXTBSY, "Text file busy")
46E(ENOEXEC, "Exec format error")
47
48E(EINVAL, "Invalid argument")
49
50E(E2BIG, "Argument list too long")
51E(ELOOP, "Symbolic link loop")
52E(ENAMETOOLONG, "Filename too long")
53E(ENFILE, "Too many open files in system")
54E(EMFILE, "No file descriptors available")
55E(EBADF, "Bad file descriptor")
56E(ECHILD, "No child process")
57E(EFAULT, "Bad address")
58E(EFBIG, "File too large")
59E(EMLINK, "Too many links")
60E(ENOLCK, "No locks available")
61
62E(EDEADLK, "Resource deadlock would occur")
63E(ENOTRECOVERABLE, "State not recoverable")
64E(EOWNERDEAD, "Previous owner died")
65E(ECANCELED, "Operation canceled")
66E(ENOSYS, "Function not implemented")
67E(ENOMSG, "No message of desired type")
68E(EIDRM, "Identifier removed")
69E(ENOSTR, "Device not a stream")
70E(ENODATA, "No data available")
71E(ETIME, "Device timeout")
72E(ENOSR, "Out of streams resources")
73E(ENOLINK, "Link has been severed")
74E(EPROTO, "Protocol error")
75E(EBADMSG, "Bad message")
76E(EBADFD, "File descriptor in bad state")
77E(ENOTSOCK, "Not a socket")
78E(EDESTADDRREQ, "Destination address required")
79E(EMSGSIZE, "Message too large")
80E(EPROTOTYPE, "Protocol wrong type for socket")
81E(ENOPROTOOPT, "Protocol not available")
82E(EPROTONOSUPPORT,"Protocol not supported")
83E(ESOCKTNOSUPPORT,"Socket type not supported")
84E(ENOTSUP, "Not supported")
85E(EPFNOSUPPORT, "Protocol family not supported")
86E(EAFNOSUPPORT, "Address family not supported by protocol")
87E(EADDRNOTAVAIL,"Address not available")
88E(ENETDOWN, "Network is down")
89E(ENETUNREACH, "Network unreachable")
90E(ENETRESET, "Connection reset by network")
91E(ECONNABORTED, "Connection aborted")
92E(ENOBUFS, "No buffer space available")
93E(EISCONN, "Socket is connected")
94E(ENOTCONN, "Socket not connected")
95E(ESHUTDOWN, "Cannot send after socket shutdown")
96E(EALREADY, "Operation already in progress")
97E(EINPROGRESS, "Operation in progress")
98E(ESTALE, "Stale file handle")
99E(EREMOTEIO, "Remote I/O error")
100E(EDQUOT, "Quota exceeded")
101E(ENOMEDIUM, "No medium found")
102E(EMEDIUMTYPE, "Wrong medium type")
103E(EMULTIHOP, "Multihop attempted")
104
105E(0, "No error information")
libc/musl/src/errno/strerror.c created+36
......@@ -0,0 +1,36 @@
1#include <errno.h>
2#include <string.h>
3#include "locale_impl.h"
4
5#define E(a,b) ((unsigned char)a),
6static const unsigned char errid[] = {
7#include "__strerror.h"
8};
9
10#undef E
11#define E(a,b) b "\0"
12static const char errmsg[] =
13#include "__strerror.h"
14;
15
16char *__strerror_l(int e, locale_t loc)
17{
18 const char *s;
19 int i;
20 /* mips has one error code outside of the 8-bit range due to a
21 * historical typo, so we just remap it. */
22 if (EDQUOT==1133) {
23 if (e==109) e=-1;
24 else if (e==EDQUOT) e=109;
25 }
26 for (i=0; errid[i] && errid[i] != e; i++);
27 for (s=errmsg; i; s++, i--) for (; *s; s++);
28 return (char *)LCTRANS(s, LC_MESSAGES, loc);
29}
30
31char *strerror(int e)
32{
33 return __strerror_l(e, CURRENT_LOCALE);
34}
35
36weak_alias(__strerror_l, strerror_l);
libc/musl/src/exit/_Exit.c created+8
......@@ -0,0 +1,8 @@
1#include <stdlib.h>
2#include "syscall.h"
3
4_Noreturn void _Exit(int ec)
5{
6 __syscall(SYS_exit_group, ec);
7 for (;;) __syscall(SYS_exit, ec);
8}
libc/musl/src/exit/abort.c created+32
......@@ -0,0 +1,32 @@
1#include <stdlib.h>
2#include <signal.h>
3#include "syscall.h"
4#include "pthread_impl.h"
5#include "atomic.h"
6#include "lock.h"
7#include "ksigaction.h"
8
9hidden volatile int __abort_lock[1];
10
11_Noreturn void abort(void)
12{
13 raise(SIGABRT);
14
15 /* If there was a SIGABRT handler installed and it returned, or if
16 * SIGABRT was blocked or ignored, take an AS-safe lock to prevent
17 * sigaction from installing a new SIGABRT handler, uninstall any
18 * handler that may be present, and re-raise the signal to generate
19 * the default action of abnormal termination. */
20 __block_all_sigs(0);
21 LOCK(__abort_lock);
22 __syscall(SYS_rt_sigaction, SIGABRT,
23 &(struct k_sigaction){.handler = SIG_DFL}, 0, _NSIG/8);
24 __syscall(SYS_tkill, __pthread_self()->tid, SIGABRT);
25 __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
26 &(long[_NSIG/(8*sizeof(long))]){1UL<<(SIGABRT-1)}, 0, _NSIG/8);
27
28 /* Beyond this point should be unreachable. */
29 a_crash();
30 raise(SIGKILL);
31 _Exit(127);
32}
libc/musl/src/exit/arm/__aeabi_atexit.c created+6
......@@ -0,0 +1,6 @@
1int __cxa_atexit(void (*func)(void *), void *arg, void *dso);
2
3int __aeabi_atexit (void *obj, void (*func) (void *), void *d)
4{
5 return __cxa_atexit (func, obj, d);
6}
libc/musl/src/exit/assert.c created+9
......@@ -0,0 +1,9 @@
1#include <stdio.h>
2#include <stdlib.h>
3
4_Noreturn void __assert_fail(const char *expr, const char *file, int line, const char *func)
5{
6 fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line);
7 fflush(NULL);
8 abort();
9}
libc/musl/src/exit/at_quick_exit.c created+31
......@@ -0,0 +1,31 @@
1#include <stdlib.h>
2#include "libc.h"
3#include "lock.h"
4
5#define COUNT 32
6
7static void (*funcs[COUNT])(void);
8static int count;
9static volatile int lock[1];
10
11void __funcs_on_quick_exit()
12{
13 void (*func)(void);
14 LOCK(lock);
15 while (count > 0) {
16 func = funcs[--count];
17 UNLOCK(lock);
18 func();
19 LOCK(lock);
20 }
21}
22
23int at_quick_exit(void (*func)(void))
24{
25 int r = 0;
26 LOCK(lock);
27 if (count == 32) r = -1;
28 else funcs[count++] = func;
29 UNLOCK(lock);
30 return r;
31}
libc/musl/src/exit/atexit.c created+72
......@@ -0,0 +1,72 @@
1#include <stdlib.h>
2#include <stdint.h>
3#include "libc.h"
4#include "lock.h"
5
6/* Ensure that at least 32 atexit handlers can be registered without malloc */
7#define COUNT 32
8
9static struct fl
10{
11 struct fl *next;
12 void (*f[COUNT])(void *);
13 void *a[COUNT];
14} builtin, *head;
15
16static int slot;
17static volatile int lock[1];
18
19void __funcs_on_exit()
20{
21 void (*func)(void *), *arg;
22 LOCK(lock);
23 for (; head; head=head->next, slot=COUNT) while(slot-->0) {
24 func = head->f[slot];
25 arg = head->a[slot];
26 UNLOCK(lock);
27 func(arg);
28 LOCK(lock);
29 }
30}
31
32void __cxa_finalize(void *dso)
33{
34}
35
36int __cxa_atexit(void (*func)(void *), void *arg, void *dso)
37{
38 LOCK(lock);
39
40 /* Defer initialization of head so it can be in BSS */
41 if (!head) head = &builtin;
42
43 /* If the current function list is full, add a new one */
44 if (slot==COUNT) {
45 struct fl *new_fl = calloc(sizeof(struct fl), 1);
46 if (!new_fl) {
47 UNLOCK(lock);
48 return -1;
49 }
50 new_fl->next = head;
51 head = new_fl;
52 slot = 0;
53 }
54
55 /* Append function to the list. */
56 head->f[slot] = func;
57 head->a[slot] = arg;
58 slot++;
59
60 UNLOCK(lock);
61 return 0;
62}
63
64static void call(void *p)
65{
66 ((void (*)(void))(uintptr_t)p)();
67}
68
69int atexit(void (*func)(void))
70{
71 return __cxa_atexit(call, (void *)(uintptr_t)func, 0);
72}
libc/musl/src/exit/exit.c created+33
......@@ -0,0 +1,33 @@
1#include <stdlib.h>
2#include <stdint.h>
3#include "libc.h"
4
5static void dummy()
6{
7}
8
9/* atexit.c and __stdio_exit.c override these. the latter is linked
10 * as a consequence of linking either __toread.c or __towrite.c. */
11weak_alias(dummy, __funcs_on_exit);
12weak_alias(dummy, __stdio_exit);
13weak_alias(dummy, _fini);
14
15extern weak hidden void (*const __fini_array_start)(void), (*const __fini_array_end)(void);
16
17static void libc_exit_fini(void)
18{
19 uintptr_t a = (uintptr_t)&__fini_array_end;
20 for (; a>(uintptr_t)&__fini_array_start; a-=sizeof(void(*)()))
21 (*(void (**)())(a-sizeof(void(*)())))();
22 _fini();
23}
24
25weak_alias(libc_exit_fini, __libc_exit_fini);
26
27_Noreturn void exit(int code)
28{
29 __funcs_on_exit();
30 __libc_exit_fini();
31 __stdio_exit();
32 _Exit(code);
33}
libc/musl/src/exit/quick_exit.c created+11
......@@ -0,0 +1,11 @@
1#include <stdlib.h>
2#include "libc.h"
3
4static void dummy() { }
5weak_alias(dummy, __funcs_on_quick_exit);
6
7_Noreturn void quick_exit(int code)
8{
9 __funcs_on_quick_exit();
10 _Exit(code);
11}
libc/musl/src/fcntl/creat.c created+8
......@@ -0,0 +1,8 @@
1#include <fcntl.h>
2
3int creat(const char *filename, mode_t mode)
4{
5 return open(filename, O_CREAT|O_WRONLY|O_TRUNC, mode);
6}
7
8weak_alias(creat, creat64);
libc/musl/src/fcntl/fcntl.c created+48
......@@ -0,0 +1,48 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include <stdarg.h>
4#include <errno.h>
5#include "syscall.h"
6
7int fcntl(int fd, int cmd, ...)
8{
9 unsigned long arg;
10 va_list ap;
11 va_start(ap, cmd);
12 arg = va_arg(ap, unsigned long);
13 va_end(ap);
14 if (cmd == F_SETFL) arg |= O_LARGEFILE;
15 if (cmd == F_SETLKW) return syscall_cp(SYS_fcntl, fd, cmd, (void *)arg);
16 if (cmd == F_GETOWN) {
17 struct f_owner_ex ex;
18 int ret = __syscall(SYS_fcntl, fd, F_GETOWN_EX, &ex);
19 if (ret == -EINVAL) return __syscall(SYS_fcntl, fd, cmd, (void *)arg);
20 if (ret) return __syscall_ret(ret);
21 return ex.type == F_OWNER_PGRP ? -ex.pid : ex.pid;
22 }
23 if (cmd == F_DUPFD_CLOEXEC) {
24 int ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, arg);
25 if (ret != -EINVAL) {
26 if (ret >= 0)
27 __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
28 return __syscall_ret(ret);
29 }
30 ret = __syscall(SYS_fcntl, fd, F_DUPFD_CLOEXEC, 0);
31 if (ret != -EINVAL) {
32 if (ret >= 0) __syscall(SYS_close, ret);
33 return __syscall_ret(-EINVAL);
34 }
35 ret = __syscall(SYS_fcntl, fd, F_DUPFD, arg);
36 if (ret >= 0) __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
37 return __syscall_ret(ret);
38 }
39 switch (cmd) {
40 case F_SETLK:
41 case F_GETLK:
42 case F_GETOWN_EX:
43 case F_SETOWN_EX:
44 return syscall(SYS_fcntl, fd, cmd, (void *)arg);
45 default:
46 return syscall(SYS_fcntl, fd, cmd, arg);
47 }
48}
libc/musl/src/fcntl/open.c created+23
......@@ -0,0 +1,23 @@
1#include <fcntl.h>
2#include <stdarg.h>
3#include "syscall.h"
4
5int open(const char *filename, int flags, ...)
6{
7 mode_t mode = 0;
8
9 if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
10 va_list ap;
11 va_start(ap, flags);
12 mode = va_arg(ap, mode_t);
13 va_end(ap);
14 }
15
16 int fd = __sys_open_cp(filename, flags, mode);
17 if (fd>=0 && (flags & O_CLOEXEC))
18 __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
19
20 return __syscall_ret(fd);
21}
22
23weak_alias(open, open64);
libc/musl/src/fcntl/openat.c created+19
......@@ -0,0 +1,19 @@
1#include <fcntl.h>
2#include <stdarg.h>
3#include "syscall.h"
4
5int openat(int fd, const char *filename, int flags, ...)
6{
7 mode_t mode = 0;
8
9 if ((flags & O_CREAT) || (flags & O_TMPFILE) == O_TMPFILE) {
10 va_list ap;
11 va_start(ap, flags);
12 mode = va_arg(ap, mode_t);
13 va_end(ap);
14 }
15
16 return syscall_cp(SYS_openat, fd, filename, flags|O_LARGEFILE, mode);
17}
18
19weak_alias(openat, openat64);
libc/musl/src/fcntl/posix_fadvise.c created+18
......@@ -0,0 +1,18 @@
1#include <fcntl.h>
2#include "syscall.h"
3
4int posix_fadvise(int fd, off_t base, off_t len, int advice)
5{
6#if defined(SYSCALL_FADVISE_6_ARG)
7 /* Some archs, at least arm and powerpc, have the syscall
8 * arguments reordered to avoid needing 7 argument registers
9 * due to 64-bit argument alignment. */
10 return -__syscall(SYS_fadvise, fd, advice,
11 __SYSCALL_LL_E(base), __SYSCALL_LL_E(len));
12#else
13 return -__syscall(SYS_fadvise, fd, __SYSCALL_LL_O(base),
14 __SYSCALL_LL_E(len), advice);
15#endif
16}
17
18weak_alias(posix_fadvise, posix_fadvise64);
libc/musl/src/fcntl/posix_fallocate.c created+10
......@@ -0,0 +1,10 @@
1#include <fcntl.h>
2#include "syscall.h"
3
4int posix_fallocate(int fd, off_t base, off_t len)
5{
6 return -__syscall(SYS_fallocate, fd, 0, __SYSCALL_LL_E(base),
7 __SYSCALL_LL_E(len));
8}
9
10weak_alias(posix_fallocate, posix_fallocate64);
libc/musl/src/fenv/__flt_rounds.c created+19
......@@ -0,0 +1,19 @@
1#include <float.h>
2#include <fenv.h>
3
4int __flt_rounds()
5{
6 switch (fegetround()) {
7#ifdef FE_TOWARDZERO
8 case FE_TOWARDZERO: return 0;
9#endif
10 case FE_TONEAREST: return 1;
11#ifdef FE_UPWARD
12 case FE_UPWARD: return 2;
13#endif
14#ifdef FE_DOWNWARD
15 case FE_DOWNWARD: return 3;
16#endif
17 }
18 return -1;
19}
libc/musl/src/fenv/aarch64/fenv.s created+68
......@@ -0,0 +1,68 @@
1.global fegetround
2.type fegetround,%function
3fegetround:
4 mrs x0, fpcr
5 and w0, w0, #0xc00000
6 ret
7
8.global __fesetround
9.hidden __fesetround
10.type __fesetround,%function
11__fesetround:
12 mrs x1, fpcr
13 bic w1, w1, #0xc00000
14 orr w1, w1, w0
15 msr fpcr, x1
16 mov w0, #0
17 ret
18
19.global fetestexcept
20.type fetestexcept,%function
21fetestexcept:
22 and w0, w0, #0x1f
23 mrs x1, fpsr
24 and w0, w0, w1
25 ret
26
27.global feclearexcept
28.type feclearexcept,%function
29feclearexcept:
30 and w0, w0, #0x1f
31 mrs x1, fpsr
32 bic w1, w1, w0
33 msr fpsr, x1
34 mov w0, #0
35 ret
36
37.global feraiseexcept
38.type feraiseexcept,%function
39feraiseexcept:
40 and w0, w0, #0x1f
41 mrs x1, fpsr
42 orr w1, w1, w0
43 msr fpsr, x1
44 mov w0, #0
45 ret
46
47.global fegetenv
48.type fegetenv,%function
49fegetenv:
50 mrs x1, fpcr
51 mrs x2, fpsr
52 stp w1, w2, [x0]
53 mov w0, #0
54 ret
55
56// TODO preserve some bits
57.global fesetenv
58.type fesetenv,%function
59fesetenv:
60 mov x1, #0
61 mov x2, #0
62 cmn x0, #1
63 b.eq 1f
64 ldp w1, w2, [x0]
651: msr fpcr, x1
66 msr fpsr, x2
67 mov w0, #0
68 ret
libc/musl/src/fenv/arm/fenv-hf.S created+70
......@@ -0,0 +1,70 @@
1#if __ARM_PCS_VFP
2
3.syntax unified
4.fpu vfp
5
6.global fegetround
7.type fegetround,%function
8fegetround:
9 fmrx r0, fpscr
10 and r0, r0, #0xc00000
11 bx lr
12
13.global __fesetround
14.hidden __fesetround
15.type __fesetround,%function
16__fesetround:
17 fmrx r3, fpscr
18 bic r3, r3, #0xc00000
19 orr r3, r3, r0
20 fmxr fpscr, r3
21 mov r0, #0
22 bx lr
23
24.global fetestexcept
25.type fetestexcept,%function
26fetestexcept:
27 and r0, r0, #0x1f
28 fmrx r3, fpscr
29 and r0, r0, r3
30 bx lr
31
32.global feclearexcept
33.type feclearexcept,%function
34feclearexcept:
35 and r0, r0, #0x1f
36 fmrx r3, fpscr
37 bic r3, r3, r0
38 fmxr fpscr, r3
39 mov r0, #0
40 bx lr
41
42.global feraiseexcept
43.type feraiseexcept,%function
44feraiseexcept:
45 and r0, r0, #0x1f
46 fmrx r3, fpscr
47 orr r3, r3, r0
48 fmxr fpscr, r3
49 mov r0, #0
50 bx lr
51
52.global fegetenv
53.type fegetenv,%function
54fegetenv:
55 fmrx r3, fpscr
56 str r3, [r0]
57 mov r0, #0
58 bx lr
59
60.global fesetenv
61.type fesetenv,%function
62fesetenv:
63 cmn r0, #1
64 moveq r3, #0
65 ldrne r3, [r0]
66 fmxr fpscr, r3
67 mov r0, #0
68 bx lr
69
70#endif
libc/musl/src/fenv/arm/fenv.c created+3
......@@ -0,0 +1,3 @@
1#if !__ARM_PCS_VFP
2#include "../fenv.c"
3#endif
libc/musl/src/fenv/fegetexceptflag.c created+7
......@@ -0,0 +1,7 @@
1#include <fenv.h>
2
3int fegetexceptflag(fexcept_t *fp, int mask)
4{
5 *fp = fetestexcept(mask);
6 return 0;
7}
libc/musl/src/fenv/feholdexcept.c created+8
......@@ -0,0 +1,8 @@
1#include <fenv.h>
2
3int feholdexcept(fenv_t *envp)
4{
5 fegetenv(envp);
6 feclearexcept(FE_ALL_EXCEPT);
7 return 0;
8}
libc/musl/src/fenv/fenv.c created+38
......@@ -0,0 +1,38 @@
1#include <fenv.h>
2
3/* Dummy functions for archs lacking fenv implementation */
4
5int feclearexcept(int mask)
6{
7 return 0;
8}
9
10int feraiseexcept(int mask)
11{
12 return 0;
13}
14
15int fetestexcept(int mask)
16{
17 return 0;
18}
19
20int fegetround(void)
21{
22 return FE_TONEAREST;
23}
24
25int __fesetround(int r)
26{
27 return 0;
28}
29
30int fegetenv(fenv_t *envp)
31{
32 return 0;
33}
34
35int fesetenv(const fenv_t *envp)
36{
37 return 0;
38}
libc/musl/src/fenv/fesetexceptflag.c created+8
......@@ -0,0 +1,8 @@
1#include <fenv.h>
2
3int fesetexceptflag(const fexcept_t *fp, int mask)
4{
5 feclearexcept(~*fp & mask);
6 feraiseexcept(*fp & mask);
7 return 0;
8}
libc/musl/src/fenv/fesetround.c created+23
......@@ -0,0 +1,23 @@
1#include <fenv.h>
2#include <features.h>
3
4/* __fesetround wrapper for arch independent argument check */
5
6hidden int __fesetround(int);
7
8int fesetround(int r)
9{
10 if (r != FE_TONEAREST
11#ifdef FE_DOWNWARD
12 && r != FE_DOWNWARD
13#endif
14#ifdef FE_UPWARD
15 && r != FE_UPWARD
16#endif
17#ifdef FE_TOWARDZERO
18 && r != FE_TOWARDZERO
19#endif
20 )
21 return -1;
22 return __fesetround(r);
23}
libc/musl/src/fenv/feupdateenv.c created+9
......@@ -0,0 +1,9 @@
1#include <fenv.h>
2
3int feupdateenv(const fenv_t *envp)
4{
5 int ex = fetestexcept(FE_ALL_EXCEPT);
6 fesetenv(envp);
7 feraiseexcept(ex);
8 return 0;
9}
libc/musl/src/fenv/i386/fenv.s created+164
......@@ -0,0 +1,164 @@
1.hidden __hwcap
2
3.global feclearexcept
4.type feclearexcept,@function
5feclearexcept:
6 mov 4(%esp),%ecx
7 and $0x3f,%ecx
8 fnstsw %ax
9 # consider sse fenv as well if the cpu has XMM capability
10 call 1f
111: addl $__hwcap-1b,(%esp)
12 pop %edx
13 testl $0x02000000,(%edx)
14 jz 2f
15 # maintain exceptions in the sse mxcsr, clear x87 exceptions
16 test %eax,%ecx
17 jz 1f
18 fnclex
191: push %edx
20 stmxcsr (%esp)
21 pop %edx
22 and $0x3f,%eax
23 or %eax,%edx
24 test %edx,%ecx
25 jz 1f
26 not %ecx
27 and %ecx,%edx
28 push %edx
29 ldmxcsr (%esp)
30 pop %edx
311: xor %eax,%eax
32 ret
33 # only do the expensive x87 fenv load/store when needed
342: test %eax,%ecx
35 jz 1b
36 not %ecx
37 and %ecx,%eax
38 test $0x3f,%eax
39 jz 1f
40 fnclex
41 jmp 1b
421: sub $32,%esp
43 fnstenv (%esp)
44 mov %al,4(%esp)
45 fldenv (%esp)
46 add $32,%esp
47 xor %eax,%eax
48 ret
49
50.global feraiseexcept
51.type feraiseexcept,@function
52feraiseexcept:
53 mov 4(%esp),%eax
54 and $0x3f,%eax
55 sub $32,%esp
56 fnstenv (%esp)
57 or %al,4(%esp)
58 fldenv (%esp)
59 add $32,%esp
60 xor %eax,%eax
61 ret
62
63.global __fesetround
64.hidden __fesetround
65.type __fesetround,@function
66__fesetround:
67 mov 4(%esp),%ecx
68 push %eax
69 xor %eax,%eax
70 fnstcw (%esp)
71 andb $0xf3,1(%esp)
72 or %ch,1(%esp)
73 fldcw (%esp)
74 # consider sse fenv as well if the cpu has XMM capability
75 call 1f
761: addl $__hwcap-1b,(%esp)
77 pop %edx
78 testl $0x02000000,(%edx)
79 jz 1f
80 stmxcsr (%esp)
81 shl $3,%ch
82 andb $0x9f,1(%esp)
83 or %ch,1(%esp)
84 ldmxcsr (%esp)
851: pop %ecx
86 ret
87
88.global fegetround
89.type fegetround,@function
90fegetround:
91 push %eax
92 fnstcw (%esp)
93 pop %eax
94 and $0xc00,%eax
95 ret
96
97.global fegetenv
98.type fegetenv,@function
99fegetenv:
100 mov 4(%esp),%ecx
101 xor %eax,%eax
102 fnstenv (%ecx)
103 # consider sse fenv as well if the cpu has XMM capability
104 call 1f
1051: addl $__hwcap-1b,(%esp)
106 pop %edx
107 testl $0x02000000,(%edx)
108 jz 1f
109 push %eax
110 stmxcsr (%esp)
111 pop %edx
112 and $0x3f,%edx
113 or %edx,4(%ecx)
1141: ret
115
116.global fesetenv
117.type fesetenv,@function
118fesetenv:
119 mov 4(%esp),%ecx
120 xor %eax,%eax
121 inc %ecx
122 jz 1f
123 fldenv -1(%ecx)
124 movl -1(%ecx),%ecx
125 jmp 2f
1261: push %eax
127 push %eax
128 push %eax
129 push %eax
130 pushl $0xffff
131 push %eax
132 pushl $0x37f
133 fldenv (%esp)
134 add $28,%esp
135 # consider sse fenv as well if the cpu has XMM capability
1362: call 1f
1371: addl $__hwcap-1b,(%esp)
138 pop %edx
139 testl $0x02000000,(%edx)
140 jz 1f
141 # mxcsr := same rounding mode, cleared exceptions, default mask
142 and $0xc00,%ecx
143 shl $3,%ecx
144 or $0x1f80,%ecx
145 mov %ecx,4(%esp)
146 ldmxcsr 4(%esp)
1471: ret
148
149.global fetestexcept
150.type fetestexcept,@function
151fetestexcept:
152 mov 4(%esp),%ecx
153 and $0x3f,%ecx
154 fnstsw %ax
155 # consider sse fenv as well if the cpu has XMM capability
156 call 1f
1571: addl $__hwcap-1b,(%esp)
158 pop %edx
159 testl $0x02000000,(%edx)
160 jz 1f
161 stmxcsr 4(%esp)
162 or 4(%esp),%eax
1631: and %ecx,%eax
164 ret
libc/musl/src/fenv/m68k/fenv.c created+85
......@@ -0,0 +1,85 @@
1#include <fenv.h>
2#include <features.h>
3
4#if __HAVE_68881__ || __mcffpu__
5
6static unsigned getsr()
7{
8 unsigned v;
9 __asm__ __volatile__ ("fmove.l %%fpsr,%0" : "=dm"(v));
10 return v;
11}
12
13static void setsr(unsigned v)
14{
15 __asm__ __volatile__ ("fmove.l %0,%%fpsr" : : "dm"(v));
16}
17
18static unsigned getcr()
19{
20 unsigned v;
21 __asm__ __volatile__ ("fmove.l %%fpcr,%0" : "=dm"(v));
22 return v;
23}
24
25static void setcr(unsigned v)
26{
27 __asm__ __volatile__ ("fmove.l %0,%%fpcr" : : "dm"(v));
28}
29
30int feclearexcept(int mask)
31{
32 if (mask & ~FE_ALL_EXCEPT) return -1;
33 setsr(getsr() & ~mask);
34 return 0;
35}
36
37int feraiseexcept(int mask)
38{
39 if (mask & ~FE_ALL_EXCEPT) return -1;
40 setsr(getsr() | mask);
41 return 0;
42}
43
44int fetestexcept(int mask)
45{
46 return getsr() & mask;
47}
48
49int fegetround(void)
50{
51 return getcr() & FE_UPWARD;
52}
53
54hidden int __fesetround(int r)
55{
56 setcr((getcr() & ~FE_UPWARD) | r);
57 return 0;
58}
59
60int fegetenv(fenv_t *envp)
61{
62 envp->__control_register = getcr();
63 envp->__status_register = getsr();
64 __asm__ __volatile__ ("fmove.l %%fpiar,%0"
65 : "=dm"(envp->__instruction_address));
66 return 0;
67}
68
69int fesetenv(const fenv_t *envp)
70{
71 static const fenv_t default_env = { 0 };
72 if (envp == FE_DFL_ENV)
73 envp = &default_env;
74 setcr(envp->__control_register);
75 setsr(envp->__status_register);
76 __asm__ __volatile__ ("fmove.l %0,%%fpiar"
77 : : "dm"(envp->__instruction_address));
78 return 0;
79}
80
81#else
82
83#include "../fenv.c"
84
85#endif
libc/musl/src/fenv/mips/fenv-sf.c created+3
......@@ -0,0 +1,3 @@
1#ifdef __mips_soft_float
2#include "../fenv.c"
3#endif
libc/musl/src/fenv/mips/fenv.S created+72
......@@ -0,0 +1,72 @@
1#ifndef __mips_soft_float
2
3.set noreorder
4
5.global feclearexcept
6.type feclearexcept,@function
7feclearexcept:
8 and $4, $4, 0x7c
9 cfc1 $5, $31
10 or $5, $5, $4
11 xor $5, $5, $4
12 ctc1 $5, $31
13 jr $ra
14 li $2, 0
15
16.global feraiseexcept
17.type feraiseexcept,@function
18feraiseexcept:
19 and $4, $4, 0x7c
20 cfc1 $5, $31
21 or $5, $5, $4
22 ctc1 $5, $31
23 jr $ra
24 li $2, 0
25
26.global fetestexcept
27.type fetestexcept,@function
28fetestexcept:
29 and $4, $4, 0x7c
30 cfc1 $2, $31
31 jr $ra
32 and $2, $2, $4
33
34.global fegetround
35.type fegetround,@function
36fegetround:
37 cfc1 $2, $31
38 jr $ra
39 andi $2, $2, 3
40
41.global __fesetround
42.hidden __fesetround
43.type __fesetround,@function
44__fesetround:
45 cfc1 $5, $31
46 li $6, -4
47 and $5, $5, $6
48 or $5, $5, $4
49 ctc1 $5, $31
50 jr $ra
51 li $2, 0
52
53.global fegetenv
54.type fegetenv,@function
55fegetenv:
56 cfc1 $5, $31
57 sw $5, 0($4)
58 jr $ra
59 li $2, 0
60
61.global fesetenv
62.type fesetenv,@function
63fesetenv:
64 addiu $5, $4, 1
65 beq $5, $0, 1f
66 nop
67 lw $5, 0($4)
681: ctc1 $5, $31
69 jr $ra
70 li $2, 0
71
72#endif
libc/musl/src/fenv/mips64/fenv-sf.c created+3
......@@ -0,0 +1,3 @@
1#ifdef __mips_soft_float
2#include "../fenv.c"
3#endif
libc/musl/src/fenv/mips64/fenv.S created+72
......@@ -0,0 +1,72 @@
1#ifndef __mips_soft_float
2
3.set noreorder
4
5.global feclearexcept
6.type feclearexcept,@function
7feclearexcept:
8 and $4, $4, 0x7c
9 cfc1 $5, $31
10 or $5, $5, $4
11 xor $5, $5, $4
12 ctc1 $5, $31
13 jr $ra
14 li $2, 0
15
16.global feraiseexcept
17.type feraiseexcept,@function
18feraiseexcept:
19 and $4, $4, 0x7c
20 cfc1 $5, $31
21 or $5, $5, $4
22 ctc1 $5, $31
23 jr $ra
24 li $2, 0
25
26.global fetestexcept
27.type fetestexcept,@function
28fetestexcept:
29 and $4, $4, 0x7c
30 cfc1 $2, $31
31 jr $ra
32 and $2, $2, $4
33
34.global fegetround
35.type fegetround,@function
36fegetround:
37 cfc1 $2, $31
38 jr $ra
39 andi $2, $2, 3
40
41.global __fesetround
42.hidden __fesetround
43.type __fesetround,@function
44__fesetround:
45 cfc1 $5, $31
46 li $6, -4
47 and $5, $5, $6
48 or $5, $5, $4
49 ctc1 $5, $31
50 jr $ra
51 li $2, 0
52
53.global fegetenv
54.type fegetenv,@function
55fegetenv:
56 cfc1 $5, $31
57 sw $5, 0($4)
58 jr $ra
59 li $2, 0
60
61.global fesetenv
62.type fesetenv,@function
63fesetenv:
64 daddiu $5, $4, 1
65 beq $5, $0, 1f
66 nop
67 lw $5, 0($4)
681: ctc1 $5, $31
69 jr $ra
70 li $2, 0
71
72#endif
libc/musl/src/fenv/mipsn32/fenv-sf.c created+3
......@@ -0,0 +1,3 @@
1#ifdef __mips_soft_float
2#include "../fenv.c"
3#endif
libc/musl/src/fenv/mipsn32/fenv.S created+71
......@@ -0,0 +1,71 @@
1#ifndef __mips_soft_float
2
3.set noreorder
4.global feclearexcept
5.type feclearexcept,@function
6feclearexcept:
7 and $4, $4, 0x7c
8 cfc1 $5, $31
9 or $5, $5, $4
10 xor $5, $5, $4
11 ctc1 $5, $31
12 jr $ra
13 li $2, 0
14
15.global feraiseexcept
16.type feraiseexcept,@function
17feraiseexcept:
18 and $4, $4, 0x7c
19 cfc1 $5, $31
20 or $5, $5, $4
21 ctc1 $5, $31
22 jr $ra
23 li $2, 0
24
25.global fetestexcept
26.type fetestexcept,@function
27fetestexcept:
28 and $4, $4, 0x7c
29 cfc1 $2, $31
30 jr $ra
31 and $2, $2, $4
32
33.global fegetround
34.type fegetround,@function
35fegetround:
36 cfc1 $2, $31
37 jr $ra
38 andi $2, $2, 3
39
40.global __fesetround
41.hidden __fesetround
42.type __fesetround,@function
43__fesetround:
44 cfc1 $5, $31
45 li $6, -4
46 and $5, $5, $6
47 or $5, $5, $4
48 ctc1 $5, $31
49 jr $ra
50 li $2, 0
51
52.global fegetenv
53.type fegetenv,@function
54fegetenv:
55 cfc1 $5, $31
56 sw $5, 0($4)
57 jr $ra
58 li $2, 0
59
60.global fesetenv
61.type fesetenv,@function
62fesetenv:
63 addiu $5, $4, 1
64 beq $5, $0, 1f
65 nop
66 lw $5, 0($4)
671: ctc1 $5, $31
68 jr $ra
69 li $2, 0
70
71#endif
libc/musl/src/fenv/powerpc/fenv-sf.c created+3
......@@ -0,0 +1,3 @@
1#ifdef _SOFT_FLOAT
2#include "../fenv.c"
3#endif
libc/musl/src/fenv/powerpc/fenv.S created+130
......@@ -0,0 +1,130 @@
1#ifndef _SOFT_FLOAT
2.global feclearexcept
3.type feclearexcept,@function
4feclearexcept:
5 andis. 3,3,0x3e00
6 /* if (r3 & FE_INVALID) r3 |= all_invalid_flags */
7 andis. 0,3,0x2000
8 stwu 1,-16(1)
9 beq- 0,1f
10 oris 3,3,0x01f8
11 ori 3,3,0x0700
121:
13 /*
14 * note: fpscr contains various fpu status and control
15 * flags and we dont check if r3 may alter other flags
16 * than the exception related ones
17 * ufpscr &= ~r3
18 */
19 mffs 0
20 stfd 0,8(1)
21 lwz 9,12(1)
22 andc 9,9,3
23 stw 9,12(1)
24 lfd 0,8(1)
25 mtfsf 255,0
26
27 /* return 0 */
28 li 3,0
29 addi 1,1,16
30 blr
31
32.global feraiseexcept
33.type feraiseexcept,@function
34feraiseexcept:
35 andis. 3,3,0x3e00
36 /* if (r3 & FE_INVALID) r3 |= software_invalid_flag */
37 andis. 0,3,0x2000
38 stwu 1,-16(1)
39 beq- 0,1f
40 ori 3,3,0x0400
411:
42 /* fpscr |= r3 */
43 mffs 0
44 stfd 0,8(1)
45 lwz 9,12(1)
46 or 9,9,3
47 stw 9,12(1)
48 lfd 0,8(1)
49 mtfsf 255,0
50
51 /* return 0 */
52 li 3,0
53 addi 1,1,16
54 blr
55
56.global fetestexcept
57.type fetestexcept,@function
58fetestexcept:
59 andis. 3,3,0x3e00
60 /* return r3 & fpscr */
61 stwu 1,-16(1)
62 mffs 0
63 stfd 0,8(1)
64 lwz 9,12(1)
65 addi 1,1,16
66 and 3,3,9
67 blr
68
69.global fegetround
70.type fegetround,@function
71fegetround:
72 /* return fpscr & 3 */
73 stwu 1,-16(1)
74 mffs 0
75 stfd 0,8(1)
76 lwz 3,12(1)
77 addi 1,1,16
78 clrlwi 3,3,30
79 blr
80
81.global __fesetround
82.hidden __fesetround
83.type __fesetround,@function
84__fesetround:
85 /*
86 * note: invalid input is not checked, r3 < 4 must hold
87 * fpscr = (fpscr & -4U) | r3
88 */
89 stwu 1,-16(1)
90 mffs 0
91 stfd 0,8(1)
92 lwz 9,12(1)
93 clrrwi 9,9,2
94 or 9,9,3
95 stw 9,12(1)
96 lfd 0,8(1)
97 mtfsf 255,0
98
99 /* return 0 */
100 li 3,0
101 addi 1,1,16
102 blr
103
104.global fegetenv
105.type fegetenv,@function
106fegetenv:
107 /* *r3 = fpscr */
108 mffs 0
109 stfd 0,0(3)
110 /* return 0 */
111 li 3,0
112 blr
113
114.global fesetenv
115.type fesetenv,@function
116fesetenv:
117 cmpwi 3, -1
118 bne 1f
119 mflr 4
120 bl 2f
121 .zero 8
1222: mflr 3
123 mtlr 4
1241: /* fpscr = *r3 */
125 lfd 0,0(3)
126 mtfsf 255,0
127 /* return 0 */
128 li 3,0
129 blr
130#endif
libc/musl/src/fenv/powerpc64/fenv.c created+69
......@@ -0,0 +1,69 @@
1#define _GNU_SOURCE
2#include <fenv.h>
3#include <features.h>
4
5static inline double get_fpscr_f(void)
6{
7 double d;
8 __asm__ __volatile__("mffs %0" : "=d"(d));
9 return d;
10}
11
12static inline long get_fpscr(void)
13{
14 return (union {double f; long i;}) {get_fpscr_f()}.i;
15}
16
17static inline void set_fpscr_f(double fpscr)
18{
19 __asm__ __volatile__("mtfsf 255, %0" : : "d"(fpscr));
20}
21
22static void set_fpscr(long fpscr)
23{
24 set_fpscr_f((union {long i; double f;}) {fpscr}.f);
25}
26
27int feclearexcept(int mask)
28{
29 mask &= FE_ALL_EXCEPT;
30 if (mask & FE_INVALID) mask |= FE_ALL_INVALID;
31 set_fpscr(get_fpscr() & ~mask);
32 return 0;
33}
34
35int feraiseexcept(int mask)
36{
37 mask &= FE_ALL_EXCEPT;
38 if (mask & FE_INVALID) mask |= FE_INVALID_SOFTWARE;
39 set_fpscr(get_fpscr() | mask);
40 return 0;
41}
42
43int fetestexcept(int mask)
44{
45 return get_fpscr() & mask & FE_ALL_EXCEPT;
46}
47
48int fegetround(void)
49{
50 return get_fpscr() & 3;
51}
52
53hidden int __fesetround(int r)
54{
55 set_fpscr(get_fpscr() & ~3L | r);
56 return 0;
57}
58
59int fegetenv(fenv_t *envp)
60{
61 *envp = get_fpscr_f();
62 return 0;
63}
64
65int fesetenv(const fenv_t *envp)
66{
67 set_fpscr_f(envp != FE_DFL_ENV ? *envp : 0);
68 return 0;
69}
libc/musl/src/fenv/s390x/fenv.c created+56
......@@ -0,0 +1,56 @@
1#include <fenv.h>
2#include <features.h>
3
4static inline unsigned get_fpc(void)
5{
6 unsigned fpc;
7 __asm__ __volatile__("efpc %0" : "=r"(fpc));
8 return fpc;
9}
10
11static inline void set_fpc(unsigned fpc)
12{
13 __asm__ __volatile__("sfpc %0" :: "r"(fpc));
14}
15
16int feclearexcept(int mask)
17{
18 mask &= FE_ALL_EXCEPT;
19 set_fpc(get_fpc() & ~mask);
20 return 0;
21}
22
23int feraiseexcept(int mask)
24{
25 mask &= FE_ALL_EXCEPT;
26 set_fpc(get_fpc() | mask);
27 return 0;
28}
29
30int fetestexcept(int mask)
31{
32 return get_fpc() & mask & FE_ALL_EXCEPT;
33}
34
35int fegetround(void)
36{
37 return get_fpc() & 3;
38}
39
40hidden int __fesetround(int r)
41{
42 set_fpc(get_fpc() & ~3L | r);
43 return 0;
44}
45
46int fegetenv(fenv_t *envp)
47{
48 *envp = get_fpc();
49 return 0;
50}
51
52int fesetenv(const fenv_t *envp)
53{
54 set_fpc(envp != FE_DFL_ENV ? *envp : 0);
55 return 0;
56}
libc/musl/src/fenv/sh/fenv-nofpu.c created+3
......@@ -0,0 +1,3 @@
1#if !__SH_FPU_ANY__ && !__SH4__
2#include "../fenv.c"
3#endif
libc/musl/src/fenv/sh/fenv.S created+79
......@@ -0,0 +1,79 @@
1#if __SH_FPU_ANY__ || __SH4__
2
3.global fegetround
4.type fegetround, @function
5fegetround:
6 sts fpscr, r0
7 rts
8 and #3, r0
9
10.global __fesetround
11.hidden __fesetround
12.type __fesetround, @function
13__fesetround:
14 sts fpscr, r0
15 or r4, r0
16 lds r0, fpscr
17 rts
18 mov #0, r0
19
20.global fetestexcept
21.type fetestexcept, @function
22fetestexcept:
23 sts fpscr, r0
24 and r4, r0
25 rts
26 and #0x7c, r0
27
28.global feclearexcept
29.type feclearexcept, @function
30feclearexcept:
31 mov r4, r0
32 and #0x7c, r0
33 not r0, r4
34 sts fpscr, r0
35 and r4, r0
36 lds r0, fpscr
37 rts
38 mov #0, r0
39
40.global feraiseexcept
41.type feraiseexcept, @function
42feraiseexcept:
43 mov r4, r0
44 and #0x7c, r0
45 sts fpscr, r4
46 or r4, r0
47 lds r0, fpscr
48 rts
49 mov #0, r0
50
51.global fegetenv
52.type fegetenv, @function
53fegetenv:
54 sts fpscr, r0
55 mov.l r0, @r4
56 rts
57 mov #0, r0
58
59.global fesetenv
60.type fesetenv, @function
61fesetenv:
62 mov r4, r0
63 cmp/eq #-1, r0
64 bf 1f
65
66 ! the default environment is complicated by the fact that we need to
67 ! preserve the current precision bit, which we do not know a priori
68 sts fpscr, r0
69 mov #8, r1
70 swap.w r1, r1
71 bra 2f
72 and r1, r0
73
741: mov.l @r4, r0 ! non-default environment
752: lds r0, fpscr
76 rts
77 mov #0, r0
78
79#endif
libc/musl/src/fenv/x32/fenv.s created+98
......@@ -0,0 +1,98 @@
1.global feclearexcept
2.type feclearexcept,@function
3feclearexcept:
4 # maintain exceptions in the sse mxcsr, clear x87 exceptions
5 mov %edi,%ecx
6 and $0x3f,%ecx
7 fnstsw %ax
8 test %eax,%ecx
9 jz 1f
10 fnclex
111: stmxcsr -8(%esp)
12 and $0x3f,%eax
13 or %eax,-8(%esp)
14 test %ecx,-8(%esp)
15 jz 1f
16 not %ecx
17 and %ecx,-8(%esp)
18 ldmxcsr -8(%esp)
191: xor %eax,%eax
20 ret
21
22.global feraiseexcept
23.type feraiseexcept,@function
24feraiseexcept:
25 and $0x3f,%edi
26 stmxcsr -8(%esp)
27 or %edi,-8(%esp)
28 ldmxcsr -8(%esp)
29 xor %eax,%eax
30 ret
31
32.global __fesetround
33.hidden __fesetround
34.type __fesetround,@function
35__fesetround:
36 push %rax
37 xor %eax,%eax
38 mov %edi,%ecx
39 fnstcw (%esp)
40 andb $0xf3,1(%esp)
41 or %ch,1(%esp)
42 fldcw (%esp)
43 stmxcsr (%esp)
44 shl $3,%ch
45 andb $0x9f,1(%esp)
46 or %ch,1(%esp)
47 ldmxcsr (%esp)
48 pop %rcx
49 ret
50
51.global fegetround
52.type fegetround,@function
53fegetround:
54 push %rax
55 stmxcsr (%esp)
56 pop %rax
57 shr $3,%eax
58 and $0xc00,%eax
59 ret
60
61.global fegetenv
62.type fegetenv,@function
63fegetenv:
64 xor %eax,%eax
65 fnstenv (%edi)
66 stmxcsr 28(%edi)
67 ret
68
69.global fesetenv
70.type fesetenv,@function
71fesetenv:
72 xor %eax,%eax
73 inc %edi
74 jz 1f
75 fldenv -1(%edi)
76 ldmxcsr 27(%edi)
77 ret
781: push %rax
79 push %rax
80 pushq $0xffff
81 pushq $0x37f
82 fldenv (%esp)
83 pushq $0x1f80
84 ldmxcsr (%esp)
85 add $40,%esp
86 ret
87
88.global fetestexcept
89.type fetestexcept,@function
90fetestexcept:
91 and $0x3f,%edi
92 push %rax
93 stmxcsr (%esp)
94 pop %rsi
95 fnstsw %ax
96 or %esi,%eax
97 and %edi,%eax
98 ret
libc/musl/src/fenv/x86_64/fenv.s created+98
......@@ -0,0 +1,98 @@
1.global feclearexcept
2.type feclearexcept,@function
3feclearexcept:
4 # maintain exceptions in the sse mxcsr, clear x87 exceptions
5 mov %edi,%ecx
6 and $0x3f,%ecx
7 fnstsw %ax
8 test %eax,%ecx
9 jz 1f
10 fnclex
111: stmxcsr -8(%rsp)
12 and $0x3f,%eax
13 or %eax,-8(%rsp)
14 test %ecx,-8(%rsp)
15 jz 1f
16 not %ecx
17 and %ecx,-8(%rsp)
18 ldmxcsr -8(%rsp)
191: xor %eax,%eax
20 ret
21
22.global feraiseexcept
23.type feraiseexcept,@function
24feraiseexcept:
25 and $0x3f,%edi
26 stmxcsr -8(%rsp)
27 or %edi,-8(%rsp)
28 ldmxcsr -8(%rsp)
29 xor %eax,%eax
30 ret
31
32.global __fesetround
33.hidden __fesetround
34.type __fesetround,@function
35__fesetround:
36 push %rax
37 xor %eax,%eax
38 mov %edi,%ecx
39 fnstcw (%rsp)
40 andb $0xf3,1(%rsp)
41 or %ch,1(%rsp)
42 fldcw (%rsp)
43 stmxcsr (%rsp)
44 shl $3,%ch
45 andb $0x9f,1(%rsp)
46 or %ch,1(%rsp)
47 ldmxcsr (%rsp)
48 pop %rcx
49 ret
50
51.global fegetround
52.type fegetround,@function
53fegetround:
54 push %rax
55 stmxcsr (%rsp)
56 pop %rax
57 shr $3,%eax
58 and $0xc00,%eax
59 ret
60
61.global fegetenv
62.type fegetenv,@function
63fegetenv:
64 xor %eax,%eax
65 fnstenv (%rdi)
66 stmxcsr 28(%rdi)
67 ret
68
69.global fesetenv
70.type fesetenv,@function
71fesetenv:
72 xor %eax,%eax
73 inc %rdi
74 jz 1f
75 fldenv -1(%rdi)
76 ldmxcsr 27(%rdi)
77 ret
781: push %rax
79 push %rax
80 pushq $0xffff
81 pushq $0x37f
82 fldenv (%rsp)
83 pushq $0x1f80
84 ldmxcsr (%rsp)
85 add $40,%rsp
86 ret
87
88.global fetestexcept
89.type fetestexcept,@function
90fetestexcept:
91 and $0x3f,%edi
92 push %rax
93 stmxcsr (%rsp)
94 pop %rsi
95 fnstsw %ax
96 or %esi,%eax
97 and %edi,%eax
98 ret
libc/musl/src/include/arpa/inet.h created+8
......@@ -0,0 +1,8 @@
1#ifndef ARPA_INET_H
2#define ARPA_INET_H
3
4#include_next "arpa/inet.h"
5
6hidden int __inet_aton(const char *, struct in_addr *);
7
8#endif
libc/musl/src/include/crypt.h created+16
......@@ -0,0 +1,16 @@
1#ifndef CRYPT_H
2#define CRYPT_H
3
4#include_next "crypt.h"
5
6#include <features.h>
7
8hidden char *__crypt_r(const char *, const char *, struct crypt_data *);
9
10hidden char *__crypt_des(const char *, const char *, char *);
11hidden char *__crypt_md5(const char *, const char *, char *);
12hidden char *__crypt_blowfish(const char *, const char *, char *);
13hidden char *__crypt_sha256(const char *, const char *, char *);
14hidden char *__crypt_sha512(const char *, const char *, char *);
15
16#endif
libc/musl/src/include/errno.h created+11
......@@ -0,0 +1,11 @@
1#ifndef ERRNO_H
2#define ERRNO_H
3
4#include_next "errno.h"
5
6hidden int *___errno_location(void);
7
8#undef errno
9#define errno (*___errno_location())
10
11#endif
libc/musl/src/include/langinfo.h created+8
......@@ -0,0 +1,8 @@
1#ifndef LANGINFO_H
2#define LANGINFO_H
3
4#include_next "langinfo.h"
5
6char *__nl_langinfo_l(nl_item, locale_t);
7
8#endif
libc/musl/src/include/pthread.h created+22
......@@ -0,0 +1,22 @@
1#ifndef PTHREAD_H
2#define PTHREAD_H
3
4#include_next "pthread.h"
5
6hidden int __pthread_once(pthread_once_t *, void (*)(void));
7hidden void __pthread_testcancel(void);
8hidden int __pthread_setcancelstate(int, int *);
9hidden int __pthread_create(pthread_t *restrict, const pthread_attr_t *restrict, void *(*)(void *), void *restrict);
10hidden _Noreturn void __pthread_exit(void *);
11hidden int __pthread_join(pthread_t, void **);
12hidden int __pthread_mutex_lock(pthread_mutex_t *);
13hidden int __pthread_mutex_trylock(pthread_mutex_t *);
14hidden int __pthread_mutex_trylock_owner(pthread_mutex_t *);
15hidden int __pthread_mutex_timedlock(pthread_mutex_t *restrict, const struct timespec *restrict);
16hidden int __pthread_mutex_unlock(pthread_mutex_t *);
17hidden int __private_cond_signal(pthread_cond_t *, int);
18hidden int __pthread_cond_timedwait(pthread_cond_t *restrict, pthread_mutex_t *restrict, const struct timespec *restrict);
19hidden int __pthread_key_create(pthread_key_t *, void (*)(void *));
20hidden int __pthread_key_delete(pthread_key_t);
21
22#endif
libc/musl/src/include/resolv.h created+12
......@@ -0,0 +1,12 @@
1#ifndef RESOLV_H
2#define RESOLV_H
3
4#include_next "resolv.h"
5
6hidden int __dn_expand(const unsigned char *, const unsigned char *, const unsigned char *, char *, int);
7
8hidden int __res_mkquery(int, const char *, int, int, const unsigned char *, int, const unsigned char*, unsigned char *, int);
9hidden int __res_send(const unsigned char *, int, unsigned char *, int);
10hidden int __res_msend(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int);
11
12#endif
libc/musl/src/include/signal.h created+14
......@@ -0,0 +1,14 @@
1#ifndef SIGNAL_H
2#define SIGNAL_H
3
4#include_next "signal.h"
5
6hidden int __sigaction(int, const struct sigaction *, struct sigaction *);
7
8hidden void __block_all_sigs(void *);
9hidden void __block_app_sigs(void *);
10hidden void __restore_sigs(void *);
11
12hidden void __get_handler_set(sigset_t *);
13
14#endif
libc/musl/src/include/stdio.h created+18
......@@ -0,0 +1,18 @@
1#ifndef STDIO_H
2#define STDIO_H
3
4#include_next "stdio.h"
5
6#undef stdin
7#undef stdout
8#undef stderr
9
10extern hidden FILE __stdin_FILE;
11extern hidden FILE __stdout_FILE;
12extern hidden FILE __stderr_FILE;
13
14#define stdin (&__stdin_FILE)
15#define stdout (&__stdout_FILE)
16#define stderr (&__stderr_FILE)
17
18#endif
libc/musl/src/include/stdlib.h created+12
......@@ -0,0 +1,12 @@
1#ifndef STDLIB_H
2#define STDLIB_H
3
4#include_next "stdlib.h"
5
6hidden int __putenv(char *, size_t, char *);
7hidden void __env_rm_add(char *, char *);
8hidden int __mkostemps(char *, int, int);
9hidden int __ptsname_r(int, char *, size_t);
10hidden char *__randname(char *);
11
12#endif
libc/musl/src/include/string.h created+11
......@@ -0,0 +1,11 @@
1#ifndef STRING_H
2#define STRING_H
3
4#include_next "string.h"
5
6hidden void *__memrchr(const void *, int, size_t);
7hidden char *__stpcpy(char *, const char *);
8hidden char *__stpncpy(char *, const char *, size_t);
9hidden char *__strchrnul(const char *, int);
10
11#endif
libc/musl/src/include/sys/auxv.h created+10
......@@ -0,0 +1,10 @@
1#ifndef SYS_AUXV_H
2#define SYS_AUXV_H
3
4#include_next "sys/auxv.h"
5
6#include <features.h>
7
8hidden unsigned long __getauxval(unsigned long);
9
10#endif
libc/musl/src/include/sys/mman.h created+20
......@@ -0,0 +1,20 @@
1#ifndef SYS_MMAN_H
2#define SYS_MMAN_H
3
4#include_next "sys/mman.h"
5
6hidden void __vm_wait(void);
7hidden void __vm_lock(void);
8hidden void __vm_unlock(void);
9
10hidden void *__mmap(void *, size_t, int, int, int, off_t);
11hidden int __munmap(void *, size_t);
12hidden void *__mremap(void *, size_t, size_t, int, ...);
13hidden int __madvise(void *, size_t, int);
14hidden int __mprotect(void *, size_t, int);
15
16hidden const unsigned char *__map_file(const char *, size_t *);
17
18hidden char *__shm_mapname(const char *, char *);
19
20#endif
libc/musl/src/include/sys/sysinfo.h created+9
......@@ -0,0 +1,9 @@
1#ifndef SYS_SYSINFO_H
2#define SYS_SYSINFO_H
3
4#include_next "sys/sysinfo.h"
5#include <features.h>
6
7hidden int __lsysinfo(struct sysinfo *);
8
9#endif
libc/musl/src/include/sys/time.h created+8
......@@ -0,0 +1,8 @@
1#ifndef SYS_TIME_H
2#define SYS_TIME_H
3
4#include_next "sys/time.h"
5
6hidden int __futimesat(int, const char *, const struct timeval [2]);
7
8#endif
libc/musl/src/include/time.h created+14
......@@ -0,0 +1,14 @@
1#ifndef TIME_H
2#define TIME_H
3
4#include_next "time.h"
5
6hidden int __clock_gettime(clockid_t, struct timespec *);
7
8hidden char *__asctime_r(const struct tm *, char *);
9hidden struct tm *__gmtime_r(const time_t *restrict, struct tm *restrict);
10hidden struct tm *__localtime_r(const time_t *restrict, struct tm *restrict);
11
12hidden size_t __strftime_l(char *restrict, size_t, const char *restrict, const struct tm *restrict, locale_t);
13
14#endif
libc/musl/src/include/unistd.h created+13
......@@ -0,0 +1,13 @@
1#ifndef UNISTD_H
2#define UNISTD_H
3
4#include_next "unistd.h"
5
6extern char **__environ;
7
8hidden int __dup3(int, int, int);
9hidden int __mkostemps(char *, int, int);
10hidden int __execvpe(const char *, char *const *, char *const *);
11hidden int __aio_close(int);
12
13#endif
libc/musl/src/internal/aarch64/syscall.s created+14
......@@ -0,0 +1,14 @@
1.global __syscall
2.hidden __syscall
3.type __syscall,%function
4__syscall:
5 uxtw x8,w0
6 mov x0,x1
7 mov x1,x2
8 mov x2,x3
9 mov x3,x4
10 mov x4,x5
11 mov x5,x6
12 mov x6,x7
13 svc 0
14 ret
libc/musl/src/internal/arm/syscall.s created+15
......@@ -0,0 +1,15 @@
1.syntax unified
2.global __syscall
3.hidden __syscall
4.type __syscall,%function
5__syscall:
6 mov ip,sp
7 stmfd sp!,{r4,r5,r6,r7}
8 mov r7,r0
9 mov r0,r1
10 mov r1,r2
11 mov r2,r3
12 ldmfd ip,{r3,r4,r5,r6}
13 svc 0
14 ldmfd sp!,{r4,r5,r6,r7}
15 bx lr
libc/musl/src/internal/atomic.h created+318
......@@ -0,0 +1,318 @@
1#ifndef _ATOMIC_H
2#define _ATOMIC_H
3
4#include <stdint.h>
5
6#include "atomic_arch.h"
7
8#ifdef a_ll
9
10#ifndef a_pre_llsc
11#define a_pre_llsc()
12#endif
13
14#ifndef a_post_llsc
15#define a_post_llsc()
16#endif
17
18#ifndef a_cas
19#define a_cas a_cas
20static inline int a_cas(volatile int *p, int t, int s)
21{
22 int old;
23 a_pre_llsc();
24 do old = a_ll(p);
25 while (old==t && !a_sc(p, s));
26 a_post_llsc();
27 return old;
28}
29#endif
30
31#ifndef a_swap
32#define a_swap a_swap
33static inline int a_swap(volatile int *p, int v)
34{
35 int old;
36 a_pre_llsc();
37 do old = a_ll(p);
38 while (!a_sc(p, v));
39 a_post_llsc();
40 return old;
41}
42#endif
43
44#ifndef a_fetch_add
45#define a_fetch_add a_fetch_add
46static inline int a_fetch_add(volatile int *p, int v)
47{
48 int old;
49 a_pre_llsc();
50 do old = a_ll(p);
51 while (!a_sc(p, (unsigned)old + v));
52 a_post_llsc();
53 return old;
54}
55#endif
56
57#ifndef a_fetch_and
58#define a_fetch_and a_fetch_and
59static inline int a_fetch_and(volatile int *p, int v)
60{
61 int old;
62 a_pre_llsc();
63 do old = a_ll(p);
64 while (!a_sc(p, old & v));
65 a_post_llsc();
66 return old;
67}
68#endif
69
70#ifndef a_fetch_or
71#define a_fetch_or a_fetch_or
72static inline int a_fetch_or(volatile int *p, int v)
73{
74 int old;
75 a_pre_llsc();
76 do old = a_ll(p);
77 while (!a_sc(p, old | v));
78 a_post_llsc();
79 return old;
80}
81#endif
82
83#endif
84
85#ifdef a_ll_p
86
87#ifndef a_cas_p
88#define a_cas_p a_cas_p
89static inline void *a_cas_p(volatile void *p, void *t, void *s)
90{
91 void *old;
92 a_pre_llsc();
93 do old = a_ll_p(p);
94 while (old==t && !a_sc_p(p, s));
95 a_post_llsc();
96 return old;
97}
98#endif
99
100#endif
101
102#ifndef a_cas
103#error missing definition of a_cas
104#endif
105
106#ifndef a_swap
107#define a_swap a_swap
108static inline int a_swap(volatile int *p, int v)
109{
110 int old;
111 do old = *p;
112 while (a_cas(p, old, v) != old);
113 return old;
114}
115#endif
116
117#ifndef a_fetch_add
118#define a_fetch_add a_fetch_add
119static inline int a_fetch_add(volatile int *p, int v)
120{
121 int old;
122 do old = *p;
123 while (a_cas(p, old, (unsigned)old+v) != old);
124 return old;
125}
126#endif
127
128#ifndef a_fetch_and
129#define a_fetch_and a_fetch_and
130static inline int a_fetch_and(volatile int *p, int v)
131{
132 int old;
133 do old = *p;
134 while (a_cas(p, old, old&v) != old);
135 return old;
136}
137#endif
138#ifndef a_fetch_or
139#define a_fetch_or a_fetch_or
140static inline int a_fetch_or(volatile int *p, int v)
141{
142 int old;
143 do old = *p;
144 while (a_cas(p, old, old|v) != old);
145 return old;
146}
147#endif
148
149#ifndef a_and
150#define a_and a_and
151static inline void a_and(volatile int *p, int v)
152{
153 a_fetch_and(p, v);
154}
155#endif
156
157#ifndef a_or
158#define a_or a_or
159static inline void a_or(volatile int *p, int v)
160{
161 a_fetch_or(p, v);
162}
163#endif
164
165#ifndef a_inc
166#define a_inc a_inc
167static inline void a_inc(volatile int *p)
168{
169 a_fetch_add(p, 1);
170}
171#endif
172
173#ifndef a_dec
174#define a_dec a_dec
175static inline void a_dec(volatile int *p)
176{
177 a_fetch_add(p, -1);
178}
179#endif
180
181#ifndef a_store
182#define a_store a_store
183static inline void a_store(volatile int *p, int v)
184{
185#ifdef a_barrier
186 a_barrier();
187 *p = v;
188 a_barrier();
189#else
190 a_swap(p, v);
191#endif
192}
193#endif
194
195#ifndef a_barrier
196#define a_barrier a_barrier
197static void a_barrier()
198{
199 volatile int tmp = 0;
200 a_cas(&tmp, 0, 0);
201}
202#endif
203
204#ifndef a_spin
205#define a_spin a_barrier
206#endif
207
208#ifndef a_and_64
209#define a_and_64 a_and_64
210static inline void a_and_64(volatile uint64_t *p, uint64_t v)
211{
212 union { uint64_t v; uint32_t r[2]; } u = { v };
213 if (u.r[0]+1) a_and((int *)p, u.r[0]);
214 if (u.r[1]+1) a_and((int *)p+1, u.r[1]);
215}
216#endif
217
218#ifndef a_or_64
219#define a_or_64 a_or_64
220static inline void a_or_64(volatile uint64_t *p, uint64_t v)
221{
222 union { uint64_t v; uint32_t r[2]; } u = { v };
223 if (u.r[0]) a_or((int *)p, u.r[0]);
224 if (u.r[1]) a_or((int *)p+1, u.r[1]);
225}
226#endif
227
228#ifndef a_cas_p
229typedef char a_cas_p_undefined_but_pointer_not_32bit[-sizeof(char) == 0xffffffff ? 1 : -1];
230#define a_cas_p a_cas_p
231static inline void *a_cas_p(volatile void *p, void *t, void *s)
232{
233 return (void *)a_cas((volatile int *)p, (int)t, (int)s);
234}
235#endif
236
237#ifndef a_or_l
238#define a_or_l a_or_l
239static inline void a_or_l(volatile void *p, long v)
240{
241 if (sizeof(long) == sizeof(int)) a_or(p, v);
242 else a_or_64(p, v);
243}
244#endif
245
246#ifndef a_crash
247#define a_crash a_crash
248static inline void a_crash()
249{
250 *(volatile char *)0=0;
251}
252#endif
253
254#ifndef a_ctz_32
255#define a_ctz_32 a_ctz_32
256static inline int a_ctz_32(uint32_t x)
257{
258#ifdef a_clz_32
259 return 31-a_clz_32(x&-x);
260#else
261 static const char debruijn32[32] = {
262 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
263 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
264 };
265 return debruijn32[(x&-x)*0x076be629 >> 27];
266#endif
267}
268#endif
269
270#ifndef a_ctz_64
271#define a_ctz_64 a_ctz_64
272static inline int a_ctz_64(uint64_t x)
273{
274 static const char debruijn64[64] = {
275 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
276 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
277 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
278 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
279 };
280 if (sizeof(long) < 8) {
281 uint32_t y = x;
282 if (!y) {
283 y = x>>32;
284 return 32 + a_ctz_32(y);
285 }
286 return a_ctz_32(y);
287 }
288 return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
289}
290#endif
291
292static inline int a_ctz_l(unsigned long x)
293{
294 return (sizeof(long) < 8) ? a_ctz_32(x) : a_ctz_64(x);
295}
296
297#ifndef a_clz_64
298#define a_clz_64 a_clz_64
299static inline int a_clz_64(uint64_t x)
300{
301#ifdef a_clz_32
302 if (x>>32)
303 return a_clz_32(x>>32);
304 return a_clz_32(x) + 32;
305#else
306 uint32_t y;
307 int r;
308 if (x>>32) y=x>>32, r=0; else y=x, r=32;
309 if (y>>16) y>>=16; else r |= 16;
310 if (y>>8) y>>=8; else r |= 8;
311 if (y>>4) y>>=4; else r |= 4;
312 if (y>>2) y>>=2; else r |= 2;
313 return r | !(y>>1);
314#endif
315}
316#endif
317
318#endif
libc/musl/src/internal/dynlink.h created+108
......@@ -0,0 +1,108 @@
1#ifndef _INTERNAL_RELOC_H
2#define _INTERNAL_RELOC_H
3
4#include <features.h>
5#include <elf.h>
6#include <stdint.h>
7#include <stddef.h>
8#include <stdarg.h>
9
10#if UINTPTR_MAX == 0xffffffff
11typedef Elf32_Ehdr Ehdr;
12typedef Elf32_Phdr Phdr;
13typedef Elf32_Sym Sym;
14#define R_TYPE(x) ((x)&255)
15#define R_SYM(x) ((x)>>8)
16#define R_INFO ELF32_R_INFO
17#else
18typedef Elf64_Ehdr Ehdr;
19typedef Elf64_Phdr Phdr;
20typedef Elf64_Sym Sym;
21#define R_TYPE(x) ((x)&0x7fffffff)
22#define R_SYM(x) ((x)>>32)
23#define R_INFO ELF64_R_INFO
24#endif
25
26/* These enum constants provide unmatchable default values for
27 * any relocation type the arch does not use. */
28enum {
29 REL_NONE = 0,
30 REL_SYMBOLIC = -100,
31 REL_GOT,
32 REL_PLT,
33 REL_RELATIVE,
34 REL_OFFSET,
35 REL_OFFSET32,
36 REL_COPY,
37 REL_SYM_OR_REL,
38 REL_DTPMOD,
39 REL_DTPOFF,
40 REL_TPOFF,
41 REL_TPOFF_NEG,
42 REL_TLSDESC,
43 REL_FUNCDESC,
44 REL_FUNCDESC_VAL,
45};
46
47struct fdpic_loadseg {
48 uintptr_t addr, p_vaddr, p_memsz;
49};
50
51struct fdpic_loadmap {
52 unsigned short version, nsegs;
53 struct fdpic_loadseg segs[];
54};
55
56struct fdpic_dummy_loadmap {
57 unsigned short version, nsegs;
58 struct fdpic_loadseg segs[1];
59};
60
61#include "reloc.h"
62
63#ifndef FDPIC_CONSTDISP_FLAG
64#define FDPIC_CONSTDISP_FLAG 0
65#endif
66
67#ifndef DL_FDPIC
68#define DL_FDPIC 0
69#endif
70
71#ifndef DL_NOMMU_SUPPORT
72#define DL_NOMMU_SUPPORT 0
73#endif
74
75#if !DL_FDPIC
76#define IS_RELATIVE(x,s) ( \
77 (R_TYPE(x) == REL_RELATIVE) || \
78 (R_TYPE(x) == REL_SYM_OR_REL && !R_SYM(x)) )
79#else
80#define IS_RELATIVE(x,s) ( ( \
81 (R_TYPE(x) == REL_FUNCDESC_VAL) || \
82 (R_TYPE(x) == REL_SYMBOLIC) ) \
83 && (((s)[R_SYM(x)].st_info & 0xf) == STT_SECTION) )
84#endif
85
86#ifndef NEED_MIPS_GOT_RELOCS
87#define NEED_MIPS_GOT_RELOCS 0
88#endif
89
90#ifndef DT_DEBUG_INDIRECT
91#define DT_DEBUG_INDIRECT 0
92#endif
93
94#define AUX_CNT 32
95#define DYN_CNT 32
96
97typedef void (*stage2_func)(unsigned char *, size_t *);
98typedef _Noreturn void (*stage3_func)(size_t *);
99
100hidden void *__dlsym(void *restrict, const char *restrict, void *restrict);
101
102hidden void __dl_seterr(const char *, ...);
103hidden int __dl_invalid_handle(void *);
104hidden void __dl_vseterr(const char *, va_list);
105
106hidden ptrdiff_t __tlsdesc_static(), __tlsdesc_dynamic();
107
108#endif
libc/musl/src/internal/fdpic_crt.h created+28
......@@ -0,0 +1,28 @@
1#include <stdint.h>
2#include <features.h>
3
4hidden void *__fdpic_fixup(void *map, uintptr_t *a, uintptr_t *z)
5{
6 /* If map is a null pointer, the program was loaded by a
7 * non-FDPIC-aware ELF loader, and fixups are not needed,
8 * but the value for the GOT pointer is. */
9 if (!map) return (void *)z[-1];
10
11 struct {
12 unsigned short version, nsegs;
13 struct fdpic_loadseg {
14 uintptr_t addr, p_vaddr, p_memsz;
15 } segs[];
16 } *lm = map;
17 int nsegs = lm->nsegs, rseg = 0, vseg = 0;
18 for (;;) {
19 while (*a-lm->segs[rseg].p_vaddr >= lm->segs[rseg].p_memsz)
20 if (++rseg == nsegs) rseg = 0;
21 uintptr_t *r = (uintptr_t *)
22 (*a + lm->segs[rseg].addr - lm->segs[rseg].p_vaddr);
23 if (++a == z) return r;
24 while (*r-lm->segs[vseg].p_vaddr >= lm->segs[vseg].p_memsz)
25 if (++vseg == nsegs) vseg = 0;
26 *r += lm->segs[vseg].addr - lm->segs[vseg].p_vaddr;
27 }
28}
libc/musl/src/internal/floatscan.c created+510
......@@ -0,0 +1,510 @@
1#include <stdint.h>
2#include <stdio.h>
3#include <math.h>
4#include <float.h>
5#include <limits.h>
6#include <errno.h>
7#include <ctype.h>
8
9#include "shgetc.h"
10#include "floatscan.h"
11
12#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
13
14#define LD_B1B_DIG 2
15#define LD_B1B_MAX 9007199, 254740991
16#define KMAX 128
17
18#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
19
20#define LD_B1B_DIG 3
21#define LD_B1B_MAX 18, 446744073, 709551615
22#define KMAX 2048
23
24#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
25
26#define LD_B1B_DIG 4
27#define LD_B1B_MAX 10384593, 717069655, 257060992, 658440191
28#define KMAX 2048
29
30#else
31#error Unsupported long double representation
32#endif
33
34#define MASK (KMAX-1)
35
36#define CONCAT2(x,y) x ## y
37#define CONCAT(x,y) CONCAT2(x,y)
38
39static long long scanexp(FILE *f, int pok)
40{
41 int c;
42 int x;
43 long long y;
44 int neg = 0;
45
46 c = shgetc(f);
47 if (c=='+' || c=='-') {
48 neg = (c=='-');
49 c = shgetc(f);
50 if (c-'0'>=10U && pok) shunget(f);
51 }
52 if (c-'0'>=10U) {
53 shunget(f);
54 return LLONG_MIN;
55 }
56 for (x=0; c-'0'<10U && x<INT_MAX/10; c = shgetc(f))
57 x = 10*x + c-'0';
58 for (y=x; c-'0'<10U && y<LLONG_MAX/100; c = shgetc(f))
59 y = 10*y + c-'0';
60 for (; c-'0'<10U; c = shgetc(f));
61 shunget(f);
62 return neg ? -y : y;
63}
64
65
66static long double decfloat(FILE *f, int c, int bits, int emin, int sign, int pok)
67{
68 uint32_t x[KMAX];
69 static const uint32_t th[] = { LD_B1B_MAX };
70 int i, j, k, a, z;
71 long long lrp=0, dc=0;
72 long long e10=0;
73 int lnz = 0;
74 int gotdig = 0, gotrad = 0;
75 int rp;
76 int e2;
77 int emax = -emin-bits+3;
78 int denormal = 0;
79 long double y;
80 long double frac=0;
81 long double bias=0;
82 static const int p10s[] = { 10, 100, 1000, 10000,
83 100000, 1000000, 10000000, 100000000 };
84
85 j=0;
86 k=0;
87
88 /* Don't let leading zeros consume buffer space */
89 for (; c=='0'; c = shgetc(f)) gotdig=1;
90 if (c=='.') {
91 gotrad = 1;
92 for (c = shgetc(f); c=='0'; c = shgetc(f)) gotdig=1, lrp--;
93 }
94
95 x[0] = 0;
96 for (; c-'0'<10U || c=='.'; c = shgetc(f)) {
97 if (c == '.') {
98 if (gotrad) break;
99 gotrad = 1;
100 lrp = dc;
101 } else if (k < KMAX-3) {
102 dc++;
103 if (c!='0') lnz = dc;
104 if (j) x[k] = x[k]*10 + c-'0';
105 else x[k] = c-'0';
106 if (++j==9) {
107 k++;
108 j=0;
109 }
110 gotdig=1;
111 } else {
112 dc++;
113 if (c!='0') {
114 lnz = (KMAX-4)*9;
115 x[KMAX-4] |= 1;
116 }
117 }
118 }
119 if (!gotrad) lrp=dc;
120
121 if (gotdig && (c|32)=='e') {
122 e10 = scanexp(f, pok);
123 if (e10 == LLONG_MIN) {
124 if (pok) {
125 shunget(f);
126 } else {
127 shlim(f, 0);
128 return 0;
129 }
130 e10 = 0;
131 }
132 lrp += e10;
133 } else if (c>=0) {
134 shunget(f);
135 }
136 if (!gotdig) {
137 errno = EINVAL;
138 shlim(f, 0);
139 return 0;
140 }
141
142 /* Handle zero specially to avoid nasty special cases later */
143 if (!x[0]) return sign * 0.0;
144
145 /* Optimize small integers (w/no exponent) and over/under-flow */
146 if (lrp==dc && dc<10 && (bits>30 || x[0]>>bits==0))
147 return sign * (long double)x[0];
148 if (lrp > -emin/2) {
149 errno = ERANGE;
150 return sign * LDBL_MAX * LDBL_MAX;
151 }
152 if (lrp < emin-2*LDBL_MANT_DIG) {
153 errno = ERANGE;
154 return sign * LDBL_MIN * LDBL_MIN;
155 }
156
157 /* Align incomplete final B1B digit */
158 if (j) {
159 for (; j<9; j++) x[k]*=10;
160 k++;
161 j=0;
162 }
163
164 a = 0;
165 z = k;
166 e2 = 0;
167 rp = lrp;
168
169 /* Optimize small to mid-size integers (even in exp. notation) */
170 if (lnz<9 && lnz<=rp && rp < 18) {
171 if (rp == 9) return sign * (long double)x[0];
172 if (rp < 9) return sign * (long double)x[0] / p10s[8-rp];
173 int bitlim = bits-3*(int)(rp-9);
174 if (bitlim>30 || x[0]>>bitlim==0)
175 return sign * (long double)x[0] * p10s[rp-10];
176 }
177
178 /* Drop trailing zeros */
179 for (; !x[z-1]; z--);
180
181 /* Align radix point to B1B digit boundary */
182 if (rp % 9) {
183 int rpm9 = rp>=0 ? rp%9 : rp%9+9;
184 int p10 = p10s[8-rpm9];
185 uint32_t carry = 0;
186 for (k=a; k!=z; k++) {
187 uint32_t tmp = x[k] % p10;
188 x[k] = x[k]/p10 + carry;
189 carry = 1000000000/p10 * tmp;
190 if (k==a && !x[k]) {
191 a = (a+1 & MASK);
192 rp -= 9;
193 }
194 }
195 if (carry) x[z++] = carry;
196 rp += 9-rpm9;
197 }
198
199 /* Upscale until desired number of bits are left of radix point */
200 while (rp < 9*LD_B1B_DIG || (rp == 9*LD_B1B_DIG && x[a]<th[0])) {
201 uint32_t carry = 0;
202 e2 -= 29;
203 for (k=(z-1 & MASK); ; k=(k-1 & MASK)) {
204 uint64_t tmp = ((uint64_t)x[k] << 29) + carry;
205 if (tmp > 1000000000) {
206 carry = tmp / 1000000000;
207 x[k] = tmp % 1000000000;
208 } else {
209 carry = 0;
210 x[k] = tmp;
211 }
212 if (k==(z-1 & MASK) && k!=a && !x[k]) z = k;
213 if (k==a) break;
214 }
215 if (carry) {
216 rp += 9;
217 a = (a-1 & MASK);
218 if (a == z) {
219 z = (z-1 & MASK);
220 x[z-1 & MASK] |= x[z];
221 }
222 x[a] = carry;
223 }
224 }
225
226 /* Downscale until exactly number of bits are left of radix point */
227 for (;;) {
228 uint32_t carry = 0;
229 int sh = 1;
230 for (i=0; i<LD_B1B_DIG; i++) {
231 k = (a+i & MASK);
232 if (k == z || x[k] < th[i]) {
233 i=LD_B1B_DIG;
234 break;
235 }
236 if (x[a+i & MASK] > th[i]) break;
237 }
238 if (i==LD_B1B_DIG && rp==9*LD_B1B_DIG) break;
239 /* FIXME: find a way to compute optimal sh */
240 if (rp > 9+9*LD_B1B_DIG) sh = 9;
241 e2 += sh;
242 for (k=a; k!=z; k=(k+1 & MASK)) {
243 uint32_t tmp = x[k] & (1<<sh)-1;
244 x[k] = (x[k]>>sh) + carry;
245 carry = (1000000000>>sh) * tmp;
246 if (k==a && !x[k]) {
247 a = (a+1 & MASK);
248 i--;
249 rp -= 9;
250 }
251 }
252 if (carry) {
253 if ((z+1 & MASK) != a) {
254 x[z] = carry;
255 z = (z+1 & MASK);
256 } else x[z-1 & MASK] |= 1;
257 }
258 }
259
260 /* Assemble desired bits into floating point variable */
261 for (y=i=0; i<LD_B1B_DIG; i++) {
262 if ((a+i & MASK)==z) x[(z=(z+1 & MASK))-1] = 0;
263 y = 1000000000.0L * y + x[a+i & MASK];
264 }
265
266 y *= sign;
267
268 /* Limit precision for denormal results */
269 if (bits > LDBL_MANT_DIG+e2-emin) {
270 bits = LDBL_MANT_DIG+e2-emin;
271 if (bits<0) bits=0;
272 denormal = 1;
273 }
274
275 /* Calculate bias term to force rounding, move out lower bits */
276 if (bits < LDBL_MANT_DIG) {
277 bias = copysignl(scalbn(1, 2*LDBL_MANT_DIG-bits-1), y);
278 frac = fmodl(y, scalbn(1, LDBL_MANT_DIG-bits));
279 y -= frac;
280 y += bias;
281 }
282
283 /* Process tail of decimal input so it can affect rounding */
284 if ((a+i & MASK) != z) {
285 uint32_t t = x[a+i & MASK];
286 if (t < 500000000 && (t || (a+i+1 & MASK) != z))
287 frac += 0.25*sign;
288 else if (t > 500000000)
289 frac += 0.75*sign;
290 else if (t == 500000000) {
291 if ((a+i+1 & MASK) == z)
292 frac += 0.5*sign;
293 else
294 frac += 0.75*sign;
295 }
296 if (LDBL_MANT_DIG-bits >= 2 && !fmodl(frac, 1))
297 frac++;
298 }
299
300 y += frac;
301 y -= bias;
302
303 if ((e2+LDBL_MANT_DIG & INT_MAX) > emax-5) {
304 if (fabs(y) >= CONCAT(0x1p, LDBL_MANT_DIG)) {
305 if (denormal && bits==LDBL_MANT_DIG+e2-emin)
306 denormal = 0;
307 y *= 0.5;
308 e2++;
309 }
310 if (e2+LDBL_MANT_DIG>emax || (denormal && frac))
311 errno = ERANGE;
312 }
313
314 return scalbnl(y, e2);
315}
316
317static long double hexfloat(FILE *f, int bits, int emin, int sign, int pok)
318{
319 uint32_t x = 0;
320 long double y = 0;
321 long double scale = 1;
322 long double bias = 0;
323 int gottail = 0, gotrad = 0, gotdig = 0;
324 long long rp = 0;
325 long long dc = 0;
326 long long e2 = 0;
327 int d;
328 int c;
329
330 c = shgetc(f);
331
332 /* Skip leading zeros */
333 for (; c=='0'; c = shgetc(f)) gotdig = 1;
334
335 if (c=='.') {
336 gotrad = 1;
337 c = shgetc(f);
338 /* Count zeros after the radix point before significand */
339 for (rp=0; c=='0'; c = shgetc(f), rp--) gotdig = 1;
340 }
341
342 for (; c-'0'<10U || (c|32)-'a'<6U || c=='.'; c = shgetc(f)) {
343 if (c=='.') {
344 if (gotrad) break;
345 rp = dc;
346 gotrad = 1;
347 } else {
348 gotdig = 1;
349 if (c > '9') d = (c|32)+10-'a';
350 else d = c-'0';
351 if (dc<8) {
352 x = x*16 + d;
353 } else if (dc < LDBL_MANT_DIG/4+1) {
354 y += d*(scale/=16);
355 } else if (d && !gottail) {
356 y += 0.5*scale;
357 gottail = 1;
358 }
359 dc++;
360 }
361 }
362 if (!gotdig) {
363 shunget(f);
364 if (pok) {
365 shunget(f);
366 if (gotrad) shunget(f);
367 } else {
368 shlim(f, 0);
369 }
370 return sign * 0.0;
371 }
372 if (!gotrad) rp = dc;
373 while (dc<8) x *= 16, dc++;
374 if ((c|32)=='p') {
375 e2 = scanexp(f, pok);
376 if (e2 == LLONG_MIN) {
377 if (pok) {
378 shunget(f);
379 } else {
380 shlim(f, 0);
381 return 0;
382 }
383 e2 = 0;
384 }
385 } else {
386 shunget(f);
387 }
388 e2 += 4*rp - 32;
389
390 if (!x) return sign * 0.0;
391 if (e2 > -emin) {
392 errno = ERANGE;
393 return sign * LDBL_MAX * LDBL_MAX;
394 }
395 if (e2 < emin-2*LDBL_MANT_DIG) {
396 errno = ERANGE;
397 return sign * LDBL_MIN * LDBL_MIN;
398 }
399
400 while (x < 0x80000000) {
401 if (y>=0.5) {
402 x += x + 1;
403 y += y - 1;
404 } else {
405 x += x;
406 y += y;
407 }
408 e2--;
409 }
410
411 if (bits > 32+e2-emin) {
412 bits = 32+e2-emin;
413 if (bits<0) bits=0;
414 }
415
416 if (bits < LDBL_MANT_DIG)
417 bias = copysignl(scalbn(1, 32+LDBL_MANT_DIG-bits-1), sign);
418
419 if (bits<32 && y && !(x&1)) x++, y=0;
420
421 y = bias + sign*(long double)x + sign*y;
422 y -= bias;
423
424 if (!y) errno = ERANGE;
425
426 return scalbnl(y, e2);
427}
428
429long double __floatscan(FILE *f, int prec, int pok)
430{
431 int sign = 1;
432 size_t i;
433 int bits;
434 int emin;
435 int c;
436
437 switch (prec) {
438 case 0:
439 bits = FLT_MANT_DIG;
440 emin = FLT_MIN_EXP-bits;
441 break;
442 case 1:
443 bits = DBL_MANT_DIG;
444 emin = DBL_MIN_EXP-bits;
445 break;
446 case 2:
447 bits = LDBL_MANT_DIG;
448 emin = LDBL_MIN_EXP-bits;
449 break;
450 default:
451 return 0;
452 }
453
454 while (isspace((c=shgetc(f))));
455
456 if (c=='+' || c=='-') {
457 sign -= 2*(c=='-');
458 c = shgetc(f);
459 }
460
461 for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
462 if (i<7) c = shgetc(f);
463 if (i==3 || i==8 || (i>3 && pok)) {
464 if (i!=8) {
465 shunget(f);
466 if (pok) for (; i>3; i--) shunget(f);
467 }
468 return sign * INFINITY;
469 }
470 if (!i) for (i=0; i<3 && (c|32)=="nan"[i]; i++)
471 if (i<2) c = shgetc(f);
472 if (i==3) {
473 if (shgetc(f) != '(') {
474 shunget(f);
475 return NAN;
476 }
477 for (i=1; ; i++) {
478 c = shgetc(f);
479 if (c-'0'<10U || c-'A'<26U || c-'a'<26U || c=='_')
480 continue;
481 if (c==')') return NAN;
482 shunget(f);
483 if (!pok) {
484 errno = EINVAL;
485 shlim(f, 0);
486 return 0;
487 }
488 while (i--) shunget(f);
489 return NAN;
490 }
491 return NAN;
492 }
493
494 if (i) {
495 shunget(f);
496 errno = EINVAL;
497 shlim(f, 0);
498 return 0;
499 }
500
501 if (c=='0') {
502 c = shgetc(f);
503 if ((c|32) == 'x')
504 return hexfloat(f, bits, emin, sign, pok);
505 shunget(f);
506 c = '0';
507 }
508
509 return decfloat(f, c, bits, emin, sign, pok);
510}
libc/musl/src/internal/floatscan.h created+8
......@@ -0,0 +1,8 @@
1#ifndef FLOATSCAN_H
2#define FLOATSCAN_H
3
4#include <stdio.h>
5
6hidden long double __floatscan(FILE *, int, int);
7
8#endif
libc/musl/src/internal/futex.h created+19
......@@ -0,0 +1,19 @@
1#ifndef _INTERNAL_FUTEX_H
2#define _INTERNAL_FUTEX_H
3
4#define FUTEX_WAIT 0
5#define FUTEX_WAKE 1
6#define FUTEX_FD 2
7#define FUTEX_REQUEUE 3
8#define FUTEX_CMP_REQUEUE 4
9#define FUTEX_WAKE_OP 5
10#define FUTEX_LOCK_PI 6
11#define FUTEX_UNLOCK_PI 7
12#define FUTEX_TRYLOCK_PI 8
13#define FUTEX_WAIT_BITSET 9
14
15#define FUTEX_PRIVATE 128
16
17#define FUTEX_CLOCK_REALTIME 256
18
19#endif
libc/musl/src/internal/i386/syscall.s created+78
......@@ -0,0 +1,78 @@
1.hidden __sysinfo
2
3# The calling convention for __vsyscall has the syscall number
4# and 5 args arriving as: eax, edx, ecx, edi, esi, 4(%esp).
5# This ensures that the inline asm in the C code never has to touch
6# ebx or ebp (which are unavailable in PIC and frame-pointer-using
7# code, respectively), and optimizes for size/simplicity in the caller.
8
9.global __vsyscall
10.hidden __vsyscall
11.type __vsyscall,@function
12__vsyscall:
13 push %edi
14 push %ebx
15 mov %edx,%ebx
16 mov %edi,%edx
17 mov 12(%esp),%edi
18 push %eax
19 call 1f
202: mov %ebx,%edx
21 pop %ebx
22 pop %ebx
23 pop %edi
24 ret
25
261: mov (%esp),%eax
27 add $[__sysinfo-2b],%eax
28 mov (%eax),%eax
29 test %eax,%eax
30 jz 1f
31 push %eax
32 mov 8(%esp),%eax
33 ret # tail call to kernel vsyscall entry
341: mov 4(%esp),%eax
35 int $128
36 ret
37
38# The __vsyscall6 entry point is used only for 6-argument syscalls.
39# Instead of passing the 5th argument on the stack, a pointer to the
40# 5th and 6th arguments is passed. This is ugly, but there are no
41# register constraints the inline asm could use that would make it
42# possible to pass two arguments on the stack.
43
44.global __vsyscall6
45.hidden __vsyscall6
46.type __vsyscall6,@function
47__vsyscall6:
48 push %ebp
49 push %eax
50 mov 12(%esp), %ebp
51 mov (%ebp), %eax
52 mov 4(%ebp), %ebp
53 push %eax
54 mov 4(%esp),%eax
55 call __vsyscall
56 pop %ebp
57 pop %ebp
58 pop %ebp
59 ret
60
61.global __syscall
62.hidden __syscall
63.type __syscall,@function
64__syscall:
65 lea 24(%esp),%eax
66 push %esi
67 push %edi
68 push %eax
69 mov 16(%esp),%eax
70 mov 20(%esp),%edx
71 mov 24(%esp),%ecx
72 mov 28(%esp),%edi
73 mov 32(%esp),%esi
74 call __vsyscall6
75 pop %edi
76 pop %edi
77 pop %esi
78 ret
libc/musl/src/internal/intscan.c created+100
......@@ -0,0 +1,100 @@
1#include <limits.h>
2#include <errno.h>
3#include <ctype.h>
4#include "shgetc.h"
5
6/* Lookup table for digit values. -1==255>=36 -> invalid */
7static const unsigned char table[] = { -1,
8-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
9-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
10-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
11 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
12-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
1325,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
14-1,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
1525,26,27,28,29,30,31,32,33,34,35,-1,-1,-1,-1,-1,
16-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
17-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
18-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
19-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
20-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
21-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
22-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
23-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
24};
25
26unsigned long long __intscan(FILE *f, unsigned base, int pok, unsigned long long lim)
27{
28 const unsigned char *val = table+1;
29 int c, neg=0;
30 unsigned x;
31 unsigned long long y;
32 if (base > 36 || base == 1) {
33 errno = EINVAL;
34 return 0;
35 }
36 while (isspace((c=shgetc(f))));
37 if (c=='+' || c=='-') {
38 neg = -(c=='-');
39 c = shgetc(f);
40 }
41 if ((base == 0 || base == 16) && c=='0') {
42 c = shgetc(f);
43 if ((c|32)=='x') {
44 c = shgetc(f);
45 if (val[c]>=16) {
46 shunget(f);
47 if (pok) shunget(f);
48 else shlim(f, 0);
49 return 0;
50 }
51 base = 16;
52 } else if (base == 0) {
53 base = 8;
54 }
55 } else {
56 if (base == 0) base = 10;
57 if (val[c] >= base) {
58 shunget(f);
59 shlim(f, 0);
60 errno = EINVAL;
61 return 0;
62 }
63 }
64 if (base == 10) {
65 for (x=0; c-'0'<10U && x<=UINT_MAX/10-1; c=shgetc(f))
66 x = x*10 + (c-'0');
67 for (y=x; c-'0'<10U && y<=ULLONG_MAX/10 && 10*y<=ULLONG_MAX-(c-'0'); c=shgetc(f))
68 y = y*10 + (c-'0');
69 if (c-'0'>=10U) goto done;
70 } else if (!(base & base-1)) {
71 int bs = "\0\1\2\4\7\3\6\5"[(0x17*base)>>5&7];
72 for (x=0; val[c]<base && x<=UINT_MAX/32; c=shgetc(f))
73 x = x<<bs | val[c];
74 for (y=x; val[c]<base && y<=ULLONG_MAX>>bs; c=shgetc(f))
75 y = y<<bs | val[c];
76 } else {
77 for (x=0; val[c]<base && x<=UINT_MAX/36-1; c=shgetc(f))
78 x = x*base + val[c];
79 for (y=x; val[c]<base && y<=ULLONG_MAX/base && base*y<=ULLONG_MAX-val[c]; c=shgetc(f))
80 y = y*base + val[c];
81 }
82 if (val[c]<base) {
83 for (; val[c]<base; c=shgetc(f));
84 errno = ERANGE;
85 y = lim;
86 if (lim&1) neg = 0;
87 }
88done:
89 shunget(f);
90 if (y>=lim) {
91 if (!(lim&1) && !neg) {
92 errno = ERANGE;
93 return lim-1;
94 } else if (y>lim) {
95 errno = ERANGE;
96 return lim;
97 }
98 }
99 return (y^neg)-neg;
100}
libc/musl/src/internal/intscan.h created+8
......@@ -0,0 +1,8 @@
1#ifndef INTSCAN_H
2#define INTSCAN_H
3
4#include <stdio.h>
5
6hidden unsigned long long __intscan(FILE *, unsigned, int, unsigned long long);
7
8#endif
libc/musl/src/internal/ksigaction.h created+13
......@@ -0,0 +1,13 @@
1#include <features.h>
2
3/* This is the structure used for the rt_sigaction syscall on most archs,
4 * but it can be overridden by a file with the same name in the top-level
5 * arch dir for a given arch, if necessary. */
6struct k_sigaction {
7 void (*handler)(int);
8 unsigned long flags;
9 void (*restorer)(void);
10 unsigned mask[2];
11};
12
13hidden void __restore(), __restore_rt();
libc/musl/src/internal/libc.c created+10
......@@ -0,0 +1,10 @@
1#include "libc.h"
2
3struct __libc __libc;
4
5size_t __hwcap;
6size_t __sysinfo;
7char *__progname=0, *__progname_full=0;
8
9weak_alias(__progname, program_invocation_short_name);
10weak_alias(__progname_full, program_invocation_name);
libc/musl/src/internal/libm.h created+199
......@@ -0,0 +1,199 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12
13#ifndef _LIBM_H
14#define _LIBM_H
15
16#include <stdint.h>
17#include <float.h>
18#include <math.h>
19#include <complex.h>
20#include <endian.h>
21
22#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
23#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
24union ldshape {
25 long double f;
26 struct {
27 uint64_t m;
28 uint16_t se;
29 } i;
30};
31#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
32/* This is the m68k variant of 80-bit long double, and this definition only works
33 * on archs where the alignment requirement of uint64_t is <= 4. */
34union ldshape {
35 long double f;
36 struct {
37 uint16_t se;
38 uint16_t pad;
39 uint64_t m;
40 } i;
41};
42#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __LITTLE_ENDIAN
43union ldshape {
44 long double f;
45 struct {
46 uint64_t lo;
47 uint32_t mid;
48 uint16_t top;
49 uint16_t se;
50 } i;
51 struct {
52 uint64_t lo;
53 uint64_t hi;
54 } i2;
55};
56#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384 && __BYTE_ORDER == __BIG_ENDIAN
57union ldshape {
58 long double f;
59 struct {
60 uint16_t se;
61 uint16_t top;
62 uint32_t mid;
63 uint64_t lo;
64 } i;
65 struct {
66 uint64_t hi;
67 uint64_t lo;
68 } i2;
69};
70#else
71#error Unsupported long double representation
72#endif
73
74#define FORCE_EVAL(x) do { \
75 if (sizeof(x) == sizeof(float)) { \
76 volatile float __x; \
77 __x = (x); \
78 } else if (sizeof(x) == sizeof(double)) { \
79 volatile double __x; \
80 __x = (x); \
81 } else { \
82 volatile long double __x; \
83 __x = (x); \
84 } \
85} while(0)
86
87/* Get two 32 bit ints from a double. */
88#define EXTRACT_WORDS(hi,lo,d) \
89do { \
90 union {double f; uint64_t i;} __u; \
91 __u.f = (d); \
92 (hi) = __u.i >> 32; \
93 (lo) = (uint32_t)__u.i; \
94} while (0)
95
96/* Get the more significant 32 bit int from a double. */
97#define GET_HIGH_WORD(hi,d) \
98do { \
99 union {double f; uint64_t i;} __u; \
100 __u.f = (d); \
101 (hi) = __u.i >> 32; \
102} while (0)
103
104/* Get the less significant 32 bit int from a double. */
105#define GET_LOW_WORD(lo,d) \
106do { \
107 union {double f; uint64_t i;} __u; \
108 __u.f = (d); \
109 (lo) = (uint32_t)__u.i; \
110} while (0)
111
112/* Set a double from two 32 bit ints. */
113#define INSERT_WORDS(d,hi,lo) \
114do { \
115 union {double f; uint64_t i;} __u; \
116 __u.i = ((uint64_t)(hi)<<32) | (uint32_t)(lo); \
117 (d) = __u.f; \
118} while (0)
119
120/* Set the more significant 32 bits of a double from an int. */
121#define SET_HIGH_WORD(d,hi) \
122do { \
123 union {double f; uint64_t i;} __u; \
124 __u.f = (d); \
125 __u.i &= 0xffffffff; \
126 __u.i |= (uint64_t)(hi) << 32; \
127 (d) = __u.f; \
128} while (0)
129
130/* Set the less significant 32 bits of a double from an int. */
131#define SET_LOW_WORD(d,lo) \
132do { \
133 union {double f; uint64_t i;} __u; \
134 __u.f = (d); \
135 __u.i &= 0xffffffff00000000ull; \
136 __u.i |= (uint32_t)(lo); \
137 (d) = __u.f; \
138} while (0)
139
140/* Get a 32 bit int from a float. */
141#define GET_FLOAT_WORD(w,d) \
142do { \
143 union {float f; uint32_t i;} __u; \
144 __u.f = (d); \
145 (w) = __u.i; \
146} while (0)
147
148/* Set a float from a 32 bit int. */
149#define SET_FLOAT_WORD(d,w) \
150do { \
151 union {float f; uint32_t i;} __u; \
152 __u.i = (w); \
153 (d) = __u.f; \
154} while (0)
155
156#undef __CMPLX
157#undef CMPLX
158#undef CMPLXF
159#undef CMPLXL
160
161#define __CMPLX(x, y, t) \
162 ((union { _Complex t __z; t __xy[2]; }){.__xy = {(x),(y)}}.__z)
163
164#define CMPLX(x, y) __CMPLX(x, y, double)
165#define CMPLXF(x, y) __CMPLX(x, y, float)
166#define CMPLXL(x, y) __CMPLX(x, y, long double)
167
168/* fdlibm kernel functions */
169
170hidden int __rem_pio2_large(double*,double*,int,int,int);
171
172hidden int __rem_pio2(double,double*);
173hidden double __sin(double,double,int);
174hidden double __cos(double,double);
175hidden double __tan(double,double,int);
176hidden double __expo2(double);
177hidden double complex __ldexp_cexp(double complex,int);
178
179hidden int __rem_pio2f(float,double*);
180hidden float __sindf(double);
181hidden float __cosdf(double);
182hidden float __tandf(double,int);
183hidden float __expo2f(float);
184hidden float complex __ldexp_cexpf(float complex,int);
185
186hidden int __rem_pio2l(long double, long double *);
187hidden long double __sinl(long double, long double, int);
188hidden long double __cosl(long double, long double);
189hidden long double __tanl(long double, long double, int);
190
191/* polynomial evaluation */
192hidden long double __polevll(long double, const long double *, int);
193hidden long double __p1evll(long double, const long double *, int);
194
195extern int __signgam;
196hidden double __lgamma_r(double, int *);
197hidden float __lgammaf_r(float, int *);
198
199#endif
libc/musl/src/internal/locale_impl.h created+45
......@@ -0,0 +1,45 @@
1#ifndef _LOCALE_IMPL_H
2#define _LOCALE_IMPL_H
3
4#include <locale.h>
5#include <stdlib.h>
6#include "libc.h"
7#include "pthread_impl.h"
8
9#define LOCALE_NAME_MAX 23
10
11struct __locale_map {
12 const void *map;
13 size_t map_size;
14 char name[LOCALE_NAME_MAX+1];
15 const struct __locale_map *next;
16};
17
18extern hidden const struct __locale_map __c_dot_utf8;
19extern hidden const struct __locale_struct __c_locale;
20extern hidden const struct __locale_struct __c_dot_utf8_locale;
21
22hidden const struct __locale_map *__get_locale(int, const char *);
23hidden const char *__mo_lookup(const void *, size_t, const char *);
24hidden const char *__lctrans(const char *, const struct __locale_map *);
25hidden const char *__lctrans_cur(const char *);
26hidden const char *__lctrans_impl(const char *, const struct __locale_map *);
27hidden int __loc_is_allocated(locale_t);
28hidden char *__gettextdomain(void);
29
30#define LOC_MAP_FAILED ((const struct __locale_map *)-1)
31
32#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])
33#define LCTRANS_CUR(msg) __lctrans_cur(msg)
34
35#define C_LOCALE ((locale_t)&__c_locale)
36#define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale)
37
38#define CURRENT_LOCALE (__pthread_self()->locale)
39
40#define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
41
42#undef MB_CUR_MAX
43#define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
44
45#endif
libc/musl/src/internal/lock.h created+9
......@@ -0,0 +1,9 @@
1#ifndef LOCK_H
2#define LOCK_H
3
4hidden void __lock(volatile int *);
5hidden void __unlock(volatile int *);
6#define LOCK(x) __lock(x)
7#define UNLOCK(x) __unlock(x)
8
9#endif
libc/musl/src/internal/m68k/syscall.s created+9
......@@ -0,0 +1,9 @@
1.global __syscall
2.hidden __syscall
3.type __syscall,%function
4__syscall:
5 movem.l %d2-%d5,-(%sp)
6 movem.l 20(%sp),%d0-%d5/%a0
7 trap #0
8 movem.l (%sp)+,%d2-%d5
9 rts
libc/musl/src/internal/malloc_impl.h created+46
......@@ -0,0 +1,46 @@
1#ifndef MALLOC_IMPL_H
2#define MALLOC_IMPL_H
3
4#include <sys/mman.h>
5
6hidden void *__expand_heap(size_t *);
7
8hidden void __malloc_donate(char *, char *);
9
10hidden void *__memalign(size_t, size_t);
11
12struct chunk {
13 size_t psize, csize;
14 struct chunk *next, *prev;
15};
16
17struct bin {
18 volatile int lock[2];
19 struct chunk *head;
20 struct chunk *tail;
21};
22
23#define SIZE_ALIGN (4*sizeof(size_t))
24#define SIZE_MASK (-SIZE_ALIGN)
25#define OVERHEAD (2*sizeof(size_t))
26#define MMAP_THRESHOLD (0x1c00*SIZE_ALIGN)
27#define DONTCARE 16
28#define RECLAIM 163840
29
30#define CHUNK_SIZE(c) ((c)->csize & -2)
31#define CHUNK_PSIZE(c) ((c)->psize & -2)
32#define PREV_CHUNK(c) ((struct chunk *)((char *)(c) - CHUNK_PSIZE(c)))
33#define NEXT_CHUNK(c) ((struct chunk *)((char *)(c) + CHUNK_SIZE(c)))
34#define MEM_TO_CHUNK(p) (struct chunk *)((char *)(p) - OVERHEAD)
35#define CHUNK_TO_MEM(c) (void *)((char *)(c) + OVERHEAD)
36#define BIN_TO_CHUNK(i) (MEM_TO_CHUNK(&mal.bins[i].head))
37
38#define C_INUSE ((size_t)1)
39
40#define IS_MMAPPED(c) !((c)->csize & (C_INUSE))
41
42hidden void __bin_chunk(struct chunk *);
43
44hidden extern int __malloc_replaced;
45
46#endif
libc/musl/src/internal/microblaze/syscall.s created+14
......@@ -0,0 +1,14 @@
1.global __syscall
2.hidden __syscall
3.type __syscall,@function
4__syscall:
5 addi r12, r5, 0 # Save the system call number
6 add r5, r6, r0 # Shift the arguments, arg1
7 add r6, r7, r0 # arg2
8 add r7, r8, r0 # arg3
9 add r8, r9, r0 # arg4
10 add r9, r10, r0 # arg5
11 lwi r10, r1, 28 # Get arg6.
12 brki r14, 0x8 # syscall
13 rtsd r15, 8
14 nop
libc/musl/src/internal/mips/syscall.s created+26
......@@ -0,0 +1,26 @@
1.set noreorder
2
3.global __syscall
4.hidden __syscall
5.type __syscall,@function
6__syscall:
7 move $2, $4
8 move $4, $5
9 move $5, $6
10 move $6, $7
11 lw $7, 16($sp)
12 lw $8, 20($sp)
13 lw $9, 24($sp)
14 lw $10,28($sp)
15 subu $sp, $sp, 32
16 sw $8, 16($sp)
17 sw $9, 20($sp)
18 sw $10,24($sp)
19 sw $2 ,28($sp)
20 lw $2, 28($sp)
21 syscall
22 beq $7, $0, 1f
23 addu $sp, $sp, 32
24 subu $2, $0, $2
251: jr $ra
26 nop
libc/musl/src/internal/mips64/syscall.s created+19
......@@ -0,0 +1,19 @@
1.set noreorder
2.global __syscall
3.hidden __syscall
4.type __syscall,@function
5__syscall:
6 move $2, $4
7 move $4, $5
8 move $5, $6
9 move $6, $7
10 move $7, $8
11 move $8, $9
12 move $9, $10
13 move $10, $11
14 syscall
15 beq $7, $0, 1f
16 nop
17 dsubu $2, $0, $2
181: jr $ra
19 nop
libc/musl/src/internal/mipsn32/syscall.s created+19
......@@ -0,0 +1,19 @@
1.set noreorder
2.global __syscall
3.hidden __syscall
4.type __syscall,@function
5__syscall:
6 move $2, $4
7 move $4, $5
8 move $5, $6
9 move $6, $7
10 move $7, $8
11 move $8, $9
12 move $9, $10
13 move $10, $11
14 syscall
15 beq $7, $0, 1f
16 nop
17 subu $2, $0, $2
181: jr $ra
19 nop
libc/musl/src/internal/or1k/syscall.s created+14
......@@ -0,0 +1,14 @@
1.global __syscall
2.hidden __syscall
3.type __syscall,@function
4__syscall:
5 l.ori r11, r3, 0
6 l.lwz r3, 0(r1)
7 l.lwz r4, 4(r1)
8 l.lwz r5, 8(r1)
9 l.lwz r6, 12(r1)
10 l.lwz r7, 16(r1)
11 l.lwz r8, 20(r1)
12 l.sys 1
13 l.jr r9
14 l.nop
libc/musl/src/internal/powerpc/syscall.s created+19
......@@ -0,0 +1,19 @@
1 .global __syscall
2 .hidden __syscall
3 .type __syscall,@function
4__syscall:
5 mr 0, 3 # Save the system call number
6 mr 3, 4 # Shift the arguments: arg1
7 mr 4, 5 # arg2
8 mr 5, 6 # arg3
9 mr 6, 7 # arg4
10 mr 7, 8 # arg5
11 mr 8, 9 # arg6
12 sc
13 bnslr+ # return if not summary overflow
14 #else error:
15 # return negated value.
16 neg 3, 3
17 blr
18 .end __syscall
19 .size __syscall, .-__syscall
libc/musl/src/internal/powerpc64/syscall.s created+17
......@@ -0,0 +1,17 @@
1 .global __syscall
2 .hidden __syscall
3 .type __syscall,@function
4__syscall:
5 mr 0, 3 # Save the system call number
6 mr 3, 4 # Shift the arguments: arg1
7 mr 4, 5 # arg2
8 mr 5, 6 # arg3
9 mr 6, 7 # arg4
10 mr 7, 8 # arg5
11 mr 8, 9 # arg6
12 sc
13 bnslr+ # return if not summary overflow
14 neg 3, 3 # otherwise error: return negated value.
15 blr
16 .end __syscall
17 .size __syscall, .-__syscall
libc/musl/src/internal/procfdname.c created+15
......@@ -0,0 +1,15 @@
1#include "syscall.h"
2
3void __procfdname(char *buf, unsigned fd)
4{
5 unsigned i, j;
6 for (i=0; (buf[i] = "/proc/self/fd/"[i]); i++);
7 if (!fd) {
8 buf[i] = '0';
9 buf[i+1] = 0;
10 return;
11 }
12 for (j=fd; j; j/=10, i++);
13 buf[i] = 0;
14 for (; fd; fd/=10) buf[--i] = '0' + fd%10;
15}
libc/musl/src/internal/pthread_impl.h created+198
......@@ -0,0 +1,198 @@
1#ifndef _PTHREAD_IMPL_H
2#define _PTHREAD_IMPL_H
3
4#include <pthread.h>
5#include <signal.h>
6#include <errno.h>
7#include <limits.h>
8#include <sys/mman.h>
9#include "libc.h"
10#include "syscall.h"
11#include "atomic.h"
12#include "futex.h"
13
14#define pthread __pthread
15
16struct pthread {
17 /* Part 1 -- these fields may be external or
18 * internal (accessed via asm) ABI. Do not change. */
19 struct pthread *self;
20 uintptr_t *dtv;
21 void *unused1, *unused2;
22 uintptr_t sysinfo;
23 uintptr_t canary, canary2;
24
25 /* Part 2 -- implementation details, non-ABI. */
26 int tid;
27 int errno_val;
28 volatile int detach_state;
29 volatile int cancel;
30 volatile unsigned char canceldisable, cancelasync;
31 unsigned char tsd_used:1;
32 unsigned char unblock_cancel:1;
33 unsigned char dlerror_flag:1;
34 unsigned char *map_base;
35 size_t map_size;
36 void *stack;
37 size_t stack_size;
38 size_t guard_size;
39 void *start_arg;
40 void *(*start)(void *);
41 void *result;
42 struct __ptcb *cancelbuf;
43 void **tsd;
44 struct {
45 volatile void *volatile head;
46 long off;
47 volatile void *volatile pending;
48 } robust_list;
49 volatile int timer_id;
50 locale_t locale;
51 volatile int killlock[1];
52 char *dlerror_buf;
53 void *stdio_locks;
54
55 /* Part 3 -- the positions of these fields relative to
56 * the end of the structure is external and internal ABI. */
57 uintptr_t canary_at_end;
58 uintptr_t *dtv_copy;
59};
60
61struct start_sched_args {
62 void *start_arg;
63 void *(*start_fn)(void *);
64 sigset_t mask;
65 pthread_attr_t *attr;
66 volatile int futex;
67};
68
69enum {
70 DT_EXITED = 0,
71 DT_EXITING,
72 DT_JOINABLE,
73 DT_DETACHED,
74 DT_DYNAMIC,
75};
76
77struct __timer {
78 int timerid;
79 pthread_t thread;
80};
81
82#define __SU (sizeof(size_t)/sizeof(int))
83
84#define _a_stacksize __u.__s[0]
85#define _a_guardsize __u.__s[1]
86#define _a_stackaddr __u.__s[2]
87#define _a_detach __u.__i[3*__SU+0]
88#define _a_sched __u.__i[3*__SU+1]
89#define _a_policy __u.__i[3*__SU+2]
90#define _a_prio __u.__i[3*__SU+3]
91#define _m_type __u.__i[0]
92#define _m_lock __u.__vi[1]
93#define _m_waiters __u.__vi[2]
94#define _m_prev __u.__p[3]
95#define _m_next __u.__p[4]
96#define _m_count __u.__i[5]
97#define _c_shared __u.__p[0]
98#define _c_seq __u.__vi[2]
99#define _c_waiters __u.__vi[3]
100#define _c_clock __u.__i[4]
101#define _c_lock __u.__vi[8]
102#define _c_head __u.__p[1]
103#define _c_tail __u.__p[5]
104#define _rw_lock __u.__vi[0]
105#define _rw_waiters __u.__vi[1]
106#define _rw_shared __u.__i[2]
107#define _b_lock __u.__vi[0]
108#define _b_waiters __u.__vi[1]
109#define _b_limit __u.__i[2]
110#define _b_count __u.__vi[3]
111#define _b_waiters2 __u.__vi[4]
112#define _b_inst __u.__p[3]
113
114#include "pthread_arch.h"
115
116#ifndef CANARY
117#define CANARY canary
118#endif
119
120#ifndef DTP_OFFSET
121#define DTP_OFFSET 0
122#endif
123
124#ifndef tls_mod_off_t
125#define tls_mod_off_t size_t
126#endif
127
128#define SIGTIMER 32
129#define SIGCANCEL 33
130#define SIGSYNCCALL 34
131
132#define SIGALL_SET ((sigset_t *)(const unsigned long long [2]){ -1,-1 })
133#define SIGPT_SET \
134 ((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \
135 [sizeof(long)==4] = 3UL<<(32*(sizeof(long)>4)) })
136#define SIGTIMER_SET \
137 ((sigset_t *)(const unsigned long [_NSIG/8/sizeof(long)]){ \
138 0x80000000 })
139
140void *__tls_get_addr(tls_mod_off_t *);
141hidden void *__tls_get_new(tls_mod_off_t *);
142hidden int __init_tp(void *);
143hidden void *__copy_tls(unsigned char *);
144hidden void __reset_tls();
145
146hidden void __dl_thread_cleanup(void);
147hidden void __testcancel();
148hidden void __do_cleanup_push(struct __ptcb *);
149hidden void __do_cleanup_pop(struct __ptcb *);
150hidden void __pthread_tsd_run_dtors();
151
152hidden void __pthread_key_delete_synccall(void (*)(void *), void *);
153hidden int __pthread_key_delete_impl(pthread_key_t);
154
155extern hidden volatile int __block_new_threads;
156extern hidden volatile size_t __pthread_tsd_size;
157extern hidden void *__pthread_tsd_main[];
158extern hidden volatile int __aio_fut;
159extern hidden volatile int __eintr_valid_flag;
160
161hidden int __clone(int (*)(void *), void *, int, void *, ...);
162hidden int __set_thread_area(void *);
163hidden int __libc_sigaction(int, const struct sigaction *, struct sigaction *);
164hidden void __unmapself(void *, size_t);
165
166hidden int __timedwait(volatile int *, int, clockid_t, const struct timespec *, int);
167hidden int __timedwait_cp(volatile int *, int, clockid_t, const struct timespec *, int);
168hidden void __wait(volatile int *, volatile int *, int, int);
169static inline void __wake(volatile void *addr, int cnt, int priv)
170{
171 if (priv) priv = FUTEX_PRIVATE;
172 if (cnt<0) cnt = INT_MAX;
173 __syscall(SYS_futex, addr, FUTEX_WAKE|priv, cnt) != -ENOSYS ||
174 __syscall(SYS_futex, addr, FUTEX_WAKE, cnt);
175}
176static inline void __futexwait(volatile void *addr, int val, int priv)
177{
178 if (priv) priv = FUTEX_PRIVATE;
179 __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS ||
180 __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);
181}
182
183hidden void __acquire_ptc(void);
184hidden void __release_ptc(void);
185hidden void __inhibit_ptc(void);
186
187extern hidden unsigned __default_stacksize;
188extern hidden unsigned __default_guardsize;
189
190#define DEFAULT_STACK_SIZE 131072
191#define DEFAULT_GUARD_SIZE 8192
192
193#define DEFAULT_STACK_MAX (8<<20)
194#define DEFAULT_GUARD_MAX (1<<20)
195
196#define __ATTRP_C11_THREAD ((void*)(uintptr_t)-1)
197
198#endif
libc/musl/src/internal/s390x/syscall.s created+15
......@@ -0,0 +1,15 @@
1.global __syscall
2.hidden __syscall
3.type __syscall, %function
4__syscall:
5 stg %r7, 56(%r15)
6 lgr %r1, %r2
7 lgr %r2, %r3
8 lgr %r3, %r4
9 lgr %r4, %r5
10 lgr %r5, %r6
11 lg %r6, 160(%r15)
12 lg %r7, 168(%r15)
13 svc 0
14 lg %r7, 56(%r15)
15 br %r14
libc/musl/src/internal/sh/__shcall.c created+6
......@@ -0,0 +1,6 @@
1#include <features.h>
2
3hidden int __shcall(void *arg, int (*func)(void *))
4{
5 return func(arg);
6}
libc/musl/src/internal/sh/syscall.s created+23
......@@ -0,0 +1,23 @@
1.global __syscall
2.hidden __syscall
3.type __syscall, @function
4__syscall:
5 ! The kernel syscall entry point documents that the trap number indicates
6 ! the number of arguments being passed, but it then ignores that information.
7 ! Since we do not actually know how many arguments are being passed, we will
8 ! say there are six, since that is the maximum we support here.
9 mov r4, r3
10 mov r5, r4
11 mov r6, r5
12 mov r7, r6
13 mov.l @r15, r7
14 mov.l @(4,r15), r0
15 mov.l @(8,r15), r1
16 trapa #31
17 or r0, r0
18 or r0, r0
19 or r0, r0
20 or r0, r0
21 or r0, r0
22 rts
23 nop
libc/musl/src/internal/shgetc.c created+36
......@@ -0,0 +1,36 @@
1#include "shgetc.h"
2
3/* The shcnt field stores the number of bytes read so far, offset by
4 * the value of buf-rpos at the last function call (__shlim or __shgetc),
5 * so that between calls the inline shcnt macro can add rpos-buf to get
6 * the actual count. */
7
8void __shlim(FILE *f, off_t lim)
9{
10 f->shlim = lim;
11 f->shcnt = f->buf - f->rpos;
12 /* If lim is nonzero, rend must be a valid pointer. */
13 if (lim && f->rend - f->rpos > lim)
14 f->shend = f->rpos + lim;
15 else
16 f->shend = f->rend;
17}
18
19int __shgetc(FILE *f)
20{
21 int c;
22 off_t cnt = shcnt(f);
23 if (f->shlim && cnt >= f->shlim || (c=__uflow(f)) < 0) {
24 f->shcnt = f->buf - f->rpos + cnt;
25 f->shend = 0;
26 return EOF;
27 }
28 cnt++;
29 if (f->shlim && f->rend - f->rpos > f->shlim - cnt)
30 f->shend = f->rpos + (f->shlim - cnt);
31 else
32 f->shend = f->rend;
33 f->shcnt = f->buf - f->rpos + cnt;
34 if (f->rpos[-1] != c) f->rpos[-1] = c;
35 return c;
36}
libc/musl/src/internal/shgetc.h created+32
......@@ -0,0 +1,32 @@
1#include "stdio_impl.h"
2
3/* Scan helper "stdio" functions for use by scanf-family and strto*-family
4 * functions. These accept either a valid stdio FILE, or a minimal pseudo
5 * FILE whose buffer pointers point into a null-terminated string. In the
6 * latter case, the sh_fromstring macro should be used to setup the FILE;
7 * the rest of the structure can be left uninitialized.
8 *
9 * To begin using these functions, shlim must first be called on the FILE
10 * to set a field width limit, or 0 for no limit. For string pseudo-FILEs,
11 * a nonzero limit is not valid and produces undefined behavior. After that,
12 * shgetc, shunget, and shcnt are valid as long as no other stdio functions
13 * are called on the stream.
14 *
15 * When used with a real FILE object, shunget has only one byte of pushback
16 * available. Further shunget (up to a limit of the stdio UNGET buffer size)
17 * will adjust the position but will not restore the data to be read again.
18 * This functionality is needed for the wcsto*-family functions, where it's
19 * okay because the FILE will be discarded immediately anyway. When used
20 * with string pseudo-FILEs, shunget has unlimited pushback, back to the
21 * beginning of the string. */
22
23hidden void __shlim(FILE *, off_t);
24hidden int __shgetc(FILE *);
25
26#define shcnt(f) ((f)->shcnt + ((f)->rpos - (f)->buf))
27#define shlim(f, lim) __shlim((f), (lim))
28#define shgetc(f) (((f)->rpos != (f)->shend) ? *(f)->rpos++ : __shgetc(f))
29#define shunget(f) ((f)->shend ? (void)(f)->rpos-- : (void)0)
30
31#define sh_fromstring(f, s) \
32 ((f)->buf = (f)->rpos = (void *)(s), (f)->rend = (void*)-1)
libc/musl/src/internal/stdio_impl.h created+114
......@@ -0,0 +1,114 @@
1#ifndef _STDIO_IMPL_H
2#define _STDIO_IMPL_H
3
4#include <stdio.h>
5#include "syscall.h"
6
7#define UNGET 8
8
9#define FFINALLOCK(f) ((f)->lock>=0 ? __lockfile((f)) : 0)
10#define FLOCK(f) int __need_unlock = ((f)->lock>=0 ? __lockfile((f)) : 0)
11#define FUNLOCK(f) do { if (__need_unlock) __unlockfile((f)); } while (0)
12
13#define F_PERM 1
14#define F_NORD 4
15#define F_NOWR 8
16#define F_EOF 16
17#define F_ERR 32
18#define F_SVB 64
19#define F_APP 128
20
21struct _IO_FILE {
22 unsigned flags;
23 unsigned char *rpos, *rend;
24 int (*close)(FILE *);
25 unsigned char *wend, *wpos;
26 unsigned char *mustbezero_1;
27 unsigned char *wbase;
28 size_t (*read)(FILE *, unsigned char *, size_t);
29 size_t (*write)(FILE *, const unsigned char *, size_t);
30 off_t (*seek)(FILE *, off_t, int);
31 unsigned char *buf;
32 size_t buf_size;
33 FILE *prev, *next;
34 int fd;
35 int pipe_pid;
36 long lockcount;
37 int mode;
38 volatile int lock;
39 int lbf;
40 void *cookie;
41 off_t off;
42 char *getln_buf;
43 void *mustbezero_2;
44 unsigned char *shend;
45 off_t shlim, shcnt;
46 FILE *prev_locked, *next_locked;
47 struct __locale_struct *locale;
48};
49
50extern hidden FILE *volatile __stdin_used;
51extern hidden FILE *volatile __stdout_used;
52extern hidden FILE *volatile __stderr_used;
53
54hidden int __lockfile(FILE *);
55hidden void __unlockfile(FILE *);
56
57hidden size_t __stdio_read(FILE *, unsigned char *, size_t);
58hidden size_t __stdio_write(FILE *, const unsigned char *, size_t);
59hidden size_t __stdout_write(FILE *, const unsigned char *, size_t);
60hidden off_t __stdio_seek(FILE *, off_t, int);
61hidden int __stdio_close(FILE *);
62
63hidden size_t __string_read(FILE *, unsigned char *, size_t);
64
65hidden int __toread(FILE *);
66hidden int __towrite(FILE *);
67
68hidden void __stdio_exit(void);
69hidden void __stdio_exit_needed(void);
70
71#if defined(__PIC__) && (100*__GNUC__+__GNUC_MINOR__ >= 303)
72__attribute__((visibility("protected")))
73#endif
74int __overflow(FILE *, int), __uflow(FILE *);
75
76hidden int __fseeko(FILE *, off_t, int);
77hidden int __fseeko_unlocked(FILE *, off_t, int);
78hidden off_t __ftello(FILE *);
79hidden off_t __ftello_unlocked(FILE *);
80hidden size_t __fwritex(const unsigned char *, size_t, FILE *);
81hidden int __putc_unlocked(int, FILE *);
82
83hidden FILE *__fdopen(int, const char *);
84hidden int __fmodeflags(const char *);
85
86hidden FILE *__ofl_add(FILE *f);
87hidden FILE **__ofl_lock(void);
88hidden void __ofl_unlock(void);
89
90struct __pthread;
91hidden void __register_locked_file(FILE *, struct __pthread *);
92hidden void __unlist_locked_file(FILE *);
93hidden void __do_orphaned_stdio_locks(void);
94
95#define MAYBE_WAITERS 0x40000000
96
97hidden void __getopt_msg(const char *, const char *, const char *, size_t);
98
99#define feof(f) ((f)->flags & F_EOF)
100#define ferror(f) ((f)->flags & F_ERR)
101
102#define getc_unlocked(f) \
103 ( ((f)->rpos != (f)->rend) ? *(f)->rpos++ : __uflow((f)) )
104
105#define putc_unlocked(c, f) \
106 ( (((unsigned char)(c)!=(f)->lbf && (f)->wpos!=(f)->wend)) \
107 ? *(f)->wpos++ = (unsigned char)(c) \
108 : __overflow((f),(unsigned char)(c)) )
109
110/* Caller-allocated FILE * operations */
111hidden FILE *__fopen_rb_ca(const char *, FILE *, unsigned char *, size_t);
112hidden int __fclose_ca(FILE *);
113
114#endif
libc/musl/src/internal/syscall.c created
libc/musl/src/internal/syscall.h created+251
......@@ -0,0 +1,251 @@
1#ifndef _INTERNAL_SYSCALL_H
2#define _INTERNAL_SYSCALL_H
3
4#include <features.h>
5#include <sys/syscall.h>
6#include "syscall_arch.h"
7
8#ifndef SYSCALL_RLIM_INFINITY
9#define SYSCALL_RLIM_INFINITY (~0ULL)
10#endif
11
12#ifndef SYSCALL_MMAP2_UNIT
13#define SYSCALL_MMAP2_UNIT 4096ULL
14#endif
15
16#ifndef __SYSCALL_LL_PRW
17#define __SYSCALL_LL_PRW(x) __SYSCALL_LL_O(x)
18#endif
19
20#ifndef __scc
21#define __scc(X) ((long) (X))
22typedef long syscall_arg_t;
23#endif
24
25hidden long __syscall_ret(unsigned long), __syscall(syscall_arg_t, ...),
26 __syscall_cp(syscall_arg_t, syscall_arg_t, syscall_arg_t, syscall_arg_t,
27 syscall_arg_t, syscall_arg_t, syscall_arg_t);
28
29#ifdef SYSCALL_NO_INLINE
30#define __syscall0(n) (__syscall)(n)
31#define __syscall1(n,a) (__syscall)(n,__scc(a))
32#define __syscall2(n,a,b) (__syscall)(n,__scc(a),__scc(b))
33#define __syscall3(n,a,b,c) (__syscall)(n,__scc(a),__scc(b),__scc(c))
34#define __syscall4(n,a,b,c,d) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d))
35#define __syscall5(n,a,b,c,d,e) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
36#define __syscall6(n,a,b,c,d,e,f) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
37#else
38#define __syscall1(n,a) __syscall1(n,__scc(a))
39#define __syscall2(n,a,b) __syscall2(n,__scc(a),__scc(b))
40#define __syscall3(n,a,b,c) __syscall3(n,__scc(a),__scc(b),__scc(c))
41#define __syscall4(n,a,b,c,d) __syscall4(n,__scc(a),__scc(b),__scc(c),__scc(d))
42#define __syscall5(n,a,b,c,d,e) __syscall5(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e))
43#define __syscall6(n,a,b,c,d,e,f) __syscall6(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
44#endif
45#define __syscall7(n,a,b,c,d,e,f,g) (__syscall)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f),__scc(g))
46
47#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
48#define __SYSCALL_NARGS(...) __SYSCALL_NARGS_X(__VA_ARGS__,7,6,5,4,3,2,1,0,)
49#define __SYSCALL_CONCAT_X(a,b) a##b
50#define __SYSCALL_CONCAT(a,b) __SYSCALL_CONCAT_X(a,b)
51#define __SYSCALL_DISP(b,...) __SYSCALL_CONCAT(b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)
52
53#define __syscall(...) __SYSCALL_DISP(__syscall,__VA_ARGS__)
54#define syscall(...) __syscall_ret(__syscall(__VA_ARGS__))
55
56#define socketcall __socketcall
57#define socketcall_cp __socketcall_cp
58
59#define __syscall_cp0(n) (__syscall_cp)(n,0,0,0,0,0,0)
60#define __syscall_cp1(n,a) (__syscall_cp)(n,__scc(a),0,0,0,0,0)
61#define __syscall_cp2(n,a,b) (__syscall_cp)(n,__scc(a),__scc(b),0,0,0,0)
62#define __syscall_cp3(n,a,b,c) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),0,0,0)
63#define __syscall_cp4(n,a,b,c,d) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),0,0)
64#define __syscall_cp5(n,a,b,c,d,e) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),0)
65#define __syscall_cp6(n,a,b,c,d,e,f) (__syscall_cp)(n,__scc(a),__scc(b),__scc(c),__scc(d),__scc(e),__scc(f))
66
67#define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
68#define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
69
70#ifndef SYSCALL_USE_SOCKETCALL
71#define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_##nm, a, b, c, d, e, f)
72#define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_##nm, a, b, c, d, e, f)
73#else
74#define __socketcall(nm,a,b,c,d,e,f) syscall(SYS_socketcall, __SC_##nm, \
75 ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
76#define __socketcall_cp(nm,a,b,c,d,e,f) syscall_cp(SYS_socketcall, __SC_##nm, \
77 ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
78#endif
79
80/* fixup legacy 16-bit junk */
81
82#ifdef SYS_getuid32
83#undef SYS_lchown
84#undef SYS_getuid
85#undef SYS_getgid
86#undef SYS_geteuid
87#undef SYS_getegid
88#undef SYS_setreuid
89#undef SYS_setregid
90#undef SYS_getgroups
91#undef SYS_setgroups
92#undef SYS_fchown
93#undef SYS_setresuid
94#undef SYS_getresuid
95#undef SYS_setresgid
96#undef SYS_getresgid
97#undef SYS_chown
98#undef SYS_setuid
99#undef SYS_setgid
100#undef SYS_setfsuid
101#undef SYS_setfsgid
102#define SYS_lchown SYS_lchown32
103#define SYS_getuid SYS_getuid32
104#define SYS_getgid SYS_getgid32
105#define SYS_geteuid SYS_geteuid32
106#define SYS_getegid SYS_getegid32
107#define SYS_setreuid SYS_setreuid32
108#define SYS_setregid SYS_setregid32
109#define SYS_getgroups SYS_getgroups32
110#define SYS_setgroups SYS_setgroups32
111#define SYS_fchown SYS_fchown32
112#define SYS_setresuid SYS_setresuid32
113#define SYS_getresuid SYS_getresuid32
114#define SYS_setresgid SYS_setresgid32
115#define SYS_getresgid SYS_getresgid32
116#define SYS_chown SYS_chown32
117#define SYS_setuid SYS_setuid32
118#define SYS_setgid SYS_setgid32
119#define SYS_setfsuid SYS_setfsuid32
120#define SYS_setfsgid SYS_setfsgid32
121#endif
122
123
124/* fixup legacy 32-bit-vs-lfs64 junk */
125
126#ifdef SYS_fcntl64
127#undef SYS_fcntl
128#define SYS_fcntl SYS_fcntl64
129#endif
130
131#ifdef SYS_getdents64
132#undef SYS_getdents
133#define SYS_getdents SYS_getdents64
134#endif
135
136#ifdef SYS_ftruncate64
137#undef SYS_ftruncate
138#undef SYS_truncate
139#define SYS_ftruncate SYS_ftruncate64
140#define SYS_truncate SYS_truncate64
141#endif
142
143#ifdef SYS_stat64
144#undef SYS_stat
145#define SYS_stat SYS_stat64
146#endif
147
148#ifdef SYS_fstat64
149#undef SYS_fstat
150#define SYS_fstat SYS_fstat64
151#endif
152
153#ifdef SYS_lstat64
154#undef SYS_lstat
155#define SYS_lstat SYS_lstat64
156#endif
157
158#ifdef SYS_statfs64
159#undef SYS_statfs
160#define SYS_statfs SYS_statfs64
161#endif
162
163#ifdef SYS_fstatfs64
164#undef SYS_fstatfs
165#define SYS_fstatfs SYS_fstatfs64
166#endif
167
168#if defined(SYS_newfstatat)
169#undef SYS_fstatat
170#define SYS_fstatat SYS_newfstatat
171#elif defined(SYS_fstatat64)
172#undef SYS_fstatat
173#define SYS_fstatat SYS_fstatat64
174#endif
175
176#ifdef SYS_ugetrlimit
177#undef SYS_getrlimit
178#define SYS_getrlimit SYS_ugetrlimit
179#endif
180
181#ifdef SYS__newselect
182#undef SYS_select
183#define SYS_select SYS__newselect
184#endif
185
186#ifdef SYS_pread64
187#undef SYS_pread
188#undef SYS_pwrite
189#define SYS_pread SYS_pread64
190#define SYS_pwrite SYS_pwrite64
191#endif
192
193#ifdef SYS_fadvise64_64
194#undef SYS_fadvise
195#define SYS_fadvise SYS_fadvise64_64
196#elif defined(SYS_fadvise64)
197#undef SYS_fadvise
198#define SYS_fadvise SYS_fadvise64
199#endif
200
201#ifdef SYS_sendfile64
202#undef SYS_sendfile
203#define SYS_sendfile SYS_sendfile64
204#endif
205
206/* socketcall calls */
207
208#define __SC_socket 1
209#define __SC_bind 2
210#define __SC_connect 3
211#define __SC_listen 4
212#define __SC_accept 5
213#define __SC_getsockname 6
214#define __SC_getpeername 7
215#define __SC_socketpair 8
216#define __SC_send 9
217#define __SC_recv 10
218#define __SC_sendto 11
219#define __SC_recvfrom 12
220#define __SC_shutdown 13
221#define __SC_setsockopt 14
222#define __SC_getsockopt 15
223#define __SC_sendmsg 16
224#define __SC_recvmsg 17
225#define __SC_accept4 18
226#define __SC_recvmmsg 19
227#define __SC_sendmmsg 20
228
229#ifdef SYS_open
230#define __sys_open2(x,pn,fl) __syscall2(SYS_open, pn, (fl)|O_LARGEFILE)
231#define __sys_open3(x,pn,fl,mo) __syscall3(SYS_open, pn, (fl)|O_LARGEFILE, mo)
232#define __sys_open_cp2(x,pn,fl) __syscall_cp2(SYS_open, pn, (fl)|O_LARGEFILE)
233#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp3(SYS_open, pn, (fl)|O_LARGEFILE, mo)
234#else
235#define __sys_open2(x,pn,fl) __syscall3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE)
236#define __sys_open3(x,pn,fl,mo) __syscall4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo)
237#define __sys_open_cp2(x,pn,fl) __syscall_cp3(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE)
238#define __sys_open_cp3(x,pn,fl,mo) __syscall_cp4(SYS_openat, AT_FDCWD, pn, (fl)|O_LARGEFILE, mo)
239#endif
240
241#define __sys_open(...) __SYSCALL_DISP(__sys_open,,__VA_ARGS__)
242#define sys_open(...) __syscall_ret(__sys_open(__VA_ARGS__))
243
244#define __sys_open_cp(...) __SYSCALL_DISP(__sys_open_cp,,__VA_ARGS__)
245#define sys_open_cp(...) __syscall_ret(__sys_open_cp(__VA_ARGS__))
246
247hidden void __procfdname(char __buf[static 15+3*sizeof(int)], unsigned);
248
249hidden void *__vdsosym(const char *, const char *);
250
251#endif
libc/musl/src/internal/syscall_ret.c created+11
......@@ -0,0 +1,11 @@
1#include <errno.h>
2#include "syscall.h"
3
4long __syscall_ret(unsigned long r)
5{
6 if (r > -4096UL) {
7 errno = -r;
8 return -1;
9 }
10 return r;
11}
libc/musl/src/internal/vdso.c created+93
......@@ -0,0 +1,93 @@
1#include <elf.h>
2#include <link.h>
3#include <limits.h>
4#include <stdint.h>
5#include <string.h>
6#include "libc.h"
7#include "syscall.h"
8
9#ifdef VDSO_USEFUL
10
11#if ULONG_MAX == 0xffffffff
12typedef Elf32_Ehdr Ehdr;
13typedef Elf32_Phdr Phdr;
14typedef Elf32_Sym Sym;
15typedef Elf32_Verdef Verdef;
16typedef Elf32_Verdaux Verdaux;
17#else
18typedef Elf64_Ehdr Ehdr;
19typedef Elf64_Phdr Phdr;
20typedef Elf64_Sym Sym;
21typedef Elf64_Verdef Verdef;
22typedef Elf64_Verdaux Verdaux;
23#endif
24
25static int checkver(Verdef *def, int vsym, const char *vername, char *strings)
26{
27 vsym &= 0x7fff;
28 for (;;) {
29 if (!(def->vd_flags & VER_FLG_BASE)
30 && (def->vd_ndx & 0x7fff) == vsym)
31 break;
32 if (def->vd_next == 0)
33 return 0;
34 def = (Verdef *)((char *)def + def->vd_next);
35 }
36 Verdaux *aux = (Verdaux *)((char *)def + def->vd_aux);
37 return !strcmp(vername, strings + aux->vda_name);
38}
39
40#define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON)
41#define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
42
43void *__vdsosym(const char *vername, const char *name)
44{
45 size_t i;
46 for (i=0; libc.auxv[i] != AT_SYSINFO_EHDR; i+=2)
47 if (!libc.auxv[i]) return 0;
48 if (!libc.auxv[i+1]) return 0;
49 Ehdr *eh = (void *)libc.auxv[i+1];
50 Phdr *ph = (void *)((char *)eh + eh->e_phoff);
51 size_t *dynv=0, base=-1;
52 for (i=0; i<eh->e_phnum; i++, ph=(void *)((char *)ph+eh->e_phentsize)) {
53 if (ph->p_type == PT_LOAD)
54 base = (size_t)eh + ph->p_offset - ph->p_vaddr;
55 else if (ph->p_type == PT_DYNAMIC)
56 dynv = (void *)((char *)eh + ph->p_offset);
57 }
58 if (!dynv || base==(size_t)-1) return 0;
59
60 char *strings = 0;
61 Sym *syms = 0;
62 Elf_Symndx *hashtab = 0;
63 uint16_t *versym = 0;
64 Verdef *verdef = 0;
65
66 for (i=0; dynv[i]; i+=2) {
67 void *p = (void *)(base + dynv[i+1]);
68 switch(dynv[i]) {
69 case DT_STRTAB: strings = p; break;
70 case DT_SYMTAB: syms = p; break;
71 case DT_HASH: hashtab = p; break;
72 case DT_VERSYM: versym = p; break;
73 case DT_VERDEF: verdef = p; break;
74 }
75 }
76
77 if (!strings || !syms || !hashtab) return 0;
78 if (!verdef) versym = 0;
79
80 for (i=0; i<hashtab[1]; i++) {
81 if (!(1<<(syms[i].st_info&0xf) & OK_TYPES)) continue;
82 if (!(1<<(syms[i].st_info>>4) & OK_BINDS)) continue;
83 if (!syms[i].st_shndx) continue;
84 if (strcmp(name, strings+syms[i].st_name)) continue;
85 if (versym && !checkver(verdef, versym[i], vername, strings))
86 continue;
87 return (void *)(base + syms[i].st_value);
88 }
89
90 return 0;
91}
92
93#endif
libc/musl/src/internal/version.c created+4
......@@ -0,0 +1,4 @@
1#include "version.h"
2#include "libc.h"
3
4const char __libc_version[] = VERSION;
libc/musl/src/internal/version.h created+1
......@@ -0,0 +1 @@
1#define VERSION "1.1.21"
libc/musl/src/internal/x32/syscall.s created+13
......@@ -0,0 +1,13 @@
1.global __syscall
2.hidden __syscall
3.type __syscall,@function
4__syscall:
5 movq %rdi,%rax
6 movq %rsi,%rdi
7 movq %rdx,%rsi
8 movq %rcx,%rdx
9 movq %r8,%r10
10 movq %r9,%r8
11 movq 8(%rsp),%r9
12 syscall
13 ret
libc/musl/src/internal/x86_64/syscall.s created+13
......@@ -0,0 +1,13 @@
1.global __syscall
2.hidden __syscall
3.type __syscall,@function
4__syscall:
5 movq %rdi,%rax
6 movq %rsi,%rdi
7 movq %rdx,%rsi
8 movq %rcx,%rdx
9 movq %r8,%r10
10 movq %r9,%r8
11 movq 8(%rsp),%r9
12 syscall
13 ret
libc/musl/src/ipc/ftok.c created+10
......@@ -0,0 +1,10 @@
1#include <sys/ipc.h>
2#include <sys/stat.h>
3
4key_t ftok(const char *path, int id)
5{
6 struct stat st;
7 if (stat(path, &st) < 0) return -1;
8
9 return ((st.st_ino & 0xffff) | ((st.st_dev & 0xff) << 16) | ((id & 0xffu) << 24));
10}
libc/musl/src/ipc/ipc.h created+12
......@@ -0,0 +1,12 @@
1#define IPCOP_semop 1
2#define IPCOP_semget 2
3#define IPCOP_semctl 3
4#define IPCOP_semtimedop 4
5#define IPCOP_msgsnd 11
6#define IPCOP_msgrcv 12
7#define IPCOP_msgget 13
8#define IPCOP_msgctl 14
9#define IPCOP_shmat 21
10#define IPCOP_shmdt 22
11#define IPCOP_shmget 23
12#define IPCOP_shmctl 24
libc/musl/src/ipc/msgctl.c created+34
......@@ -0,0 +1,34 @@
1#include <sys/msg.h>
2#include <endian.h>
3#include "syscall.h"
4#include "ipc.h"
5
6#if __BYTE_ORDER != __BIG_ENDIAN
7#undef SYSCALL_IPC_BROKEN_MODE
8#endif
9
10int msgctl(int q, int cmd, struct msqid_ds *buf)
11{
12#ifdef SYSCALL_IPC_BROKEN_MODE
13 struct msqid_ds tmp;
14 if (cmd == IPC_SET) {
15 tmp = *buf;
16 tmp.msg_perm.mode *= 0x10000U;
17 buf = &tmp;
18 }
19#endif
20#ifdef SYS_msgctl
21 int r = __syscall(SYS_msgctl, q, cmd | IPC_64, buf);
22#else
23 int r = __syscall(SYS_ipc, IPCOP_msgctl, q, cmd | IPC_64, 0, buf, 0);
24#endif
25#ifdef SYSCALL_IPC_BROKEN_MODE
26 if (r >= 0) switch (cmd) {
27 case IPC_STAT:
28 case MSG_STAT:
29 case MSG_STAT_ANY:
30 buf->msg_perm.mode >>= 16;
31 }
32#endif
33 return __syscall_ret(r);
34}
libc/musl/src/ipc/msgget.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/msg.h>
2#include "syscall.h"
3#include "ipc.h"
4
5int msgget(key_t k, int flag)
6{
7#ifdef SYS_msgget
8 return syscall(SYS_msgget, k, flag);
9#else
10 return syscall(SYS_ipc, IPCOP_msgget, k, flag);
11#endif
12}
libc/musl/src/ipc/msgrcv.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/msg.h>
2#include "syscall.h"
3#include "ipc.h"
4
5ssize_t msgrcv(int q, void *m, size_t len, long type, int flag)
6{
7#ifdef SYS_msgrcv
8 return syscall_cp(SYS_msgrcv, q, m, len, type, flag);
9#else
10 return syscall_cp(SYS_ipc, IPCOP_msgrcv, q, len, flag, ((long[]){ (long)m, type }));
11#endif
12}
libc/musl/src/ipc/msgsnd.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/msg.h>
2#include "syscall.h"
3#include "ipc.h"
4
5int msgsnd(int q, const void *m, size_t len, int flag)
6{
7#ifdef SYS_msgsnd
8 return syscall_cp(SYS_msgsnd, q, m, len, flag);
9#else
10 return syscall_cp(SYS_ipc, IPCOP_msgsnd, q, len, flag, m);
11#endif
12}
libc/musl/src/ipc/semctl.c created+50
......@@ -0,0 +1,50 @@
1#include <sys/sem.h>
2#include <stdarg.h>
3#include <endian.h>
4#include "syscall.h"
5#include "ipc.h"
6
7#if __BYTE_ORDER != __BIG_ENDIAN
8#undef SYSCALL_IPC_BROKEN_MODE
9#endif
10
11union semun {
12 int val;
13 struct semid_ds *buf;
14 unsigned short *array;
15};
16
17int semctl(int id, int num, int cmd, ...)
18{
19 union semun arg = {0};
20 va_list ap;
21 switch (cmd) {
22 case SETVAL: case GETALL: case SETALL: case IPC_STAT: case IPC_SET:
23 case IPC_INFO: case SEM_INFO: case SEM_STAT:
24 va_start(ap, cmd);
25 arg = va_arg(ap, union semun);
26 va_end(ap);
27 }
28#ifdef SYSCALL_IPC_BROKEN_MODE
29 struct semid_ds tmp;
30 if (cmd == IPC_SET) {
31 tmp = *arg.buf;
32 tmp.sem_perm.mode *= 0x10000U;
33 arg.buf = &tmp;
34 }
35#endif
36#ifdef SYS_semctl
37 int r = __syscall(SYS_semctl, id, num, cmd | IPC_64, arg.buf);
38#else
39 int r = __syscall(SYS_ipc, IPCOP_semctl, id, num, cmd | IPC_64, &arg.buf);
40#endif
41#ifdef SYSCALL_IPC_BROKEN_MODE
42 if (r >= 0) switch (cmd) {
43 case IPC_STAT:
44 case SEM_STAT:
45 case SEM_STAT_ANY:
46 arg.buf->sem_perm.mode >>= 16;
47 }
48#endif
49 return __syscall_ret(r);
50}
libc/musl/src/ipc/semget.c created+19
......@@ -0,0 +1,19 @@
1#include <sys/sem.h>
2#include <limits.h>
3#include <errno.h>
4#include "syscall.h"
5#include "ipc.h"
6
7int semget(key_t key, int n, int fl)
8{
9 /* The kernel uses the wrong type for the sem_nsems member
10 * of struct semid_ds, and thus might not check that the
11 * n fits in the correct (per POSIX) userspace type, so
12 * we have to check here. */
13 if (n > USHRT_MAX) return __syscall_ret(-EINVAL);
14#ifdef SYS_semget
15 return syscall(SYS_semget, key, n, fl);
16#else
17 return syscall(SYS_ipc, IPCOP_semget, key, n, fl);
18#endif
19}
libc/musl/src/ipc/semop.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/sem.h>
2#include "syscall.h"
3#include "ipc.h"
4
5int semop(int id, struct sembuf *buf, size_t n)
6{
7#ifdef SYS_semop
8 return syscall(SYS_semop, id, buf, n);
9#else
10 return syscall(SYS_ipc, IPCOP_semop, id, n, 0, buf);
11#endif
12}
libc/musl/src/ipc/semtimedop.c created+13
......@@ -0,0 +1,13 @@
1#define _GNU_SOURCE
2#include <sys/sem.h>
3#include "syscall.h"
4#include "ipc.h"
5
6int semtimedop(int id, struct sembuf *buf, size_t n, const struct timespec *ts)
7{
8#ifdef SYS_semtimedop
9 return syscall(SYS_semtimedop, id, buf, n, ts);
10#else
11 return syscall(SYS_ipc, IPCOP_semtimedop, id, n, 0, buf, ts);
12#endif
13}
libc/musl/src/ipc/shmat.c created+17
......@@ -0,0 +1,17 @@
1#include <sys/shm.h>
2#include "syscall.h"
3#include "ipc.h"
4
5#ifdef SYS_shmat
6void *shmat(int id, const void *addr, int flag)
7{
8 return (void *)syscall(SYS_shmat, id, addr, flag);
9}
10#else
11void *shmat(int id, const void *addr, int flag)
12{
13 unsigned long ret;
14 ret = syscall(SYS_ipc, IPCOP_shmat, id, flag, &addr, addr);
15 return (ret > -(unsigned long)SHMLBA) ? (void *)ret : (void *)addr;
16}
17#endif
libc/musl/src/ipc/shmctl.c created+34
......@@ -0,0 +1,34 @@
1#include <sys/shm.h>
2#include <endian.h>
3#include "syscall.h"
4#include "ipc.h"
5
6#if __BYTE_ORDER != __BIG_ENDIAN
7#undef SYSCALL_IPC_BROKEN_MODE
8#endif
9
10int shmctl(int id, int cmd, struct shmid_ds *buf)
11{
12#ifdef SYSCALL_IPC_BROKEN_MODE
13 struct shmid_ds tmp;
14 if (cmd == IPC_SET) {
15 tmp = *buf;
16 tmp.shm_perm.mode *= 0x10000U;
17 buf = &tmp;
18 }
19#endif
20#ifdef SYS_shmctl
21 int r = __syscall(SYS_shmctl, id, cmd | IPC_64, buf);
22#else
23 int r = __syscall(SYS_ipc, IPCOP_shmctl, id, cmd | IPC_64, 0, buf, 0);
24#endif
25#ifdef SYSCALL_IPC_BROKEN_MODE
26 if (r >= 0) switch (cmd) {
27 case IPC_STAT:
28 case SHM_STAT:
29 case SHM_STAT_ANY:
30 buf->shm_perm.mode >>= 16;
31 }
32#endif
33 return __syscall_ret(r);
34}
libc/musl/src/ipc/shmdt.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/shm.h>
2#include "syscall.h"
3#include "ipc.h"
4
5int shmdt(const void *addr)
6{
7#ifdef SYS_shmdt
8 return syscall(SYS_shmdt, addr);
9#else
10 return syscall(SYS_ipc, IPCOP_shmdt, 0, 0, 0, addr);
11#endif
12}
libc/musl/src/ipc/shmget.c created+14
......@@ -0,0 +1,14 @@
1#include <sys/shm.h>
2#include <stdint.h>
3#include "syscall.h"
4#include "ipc.h"
5
6int shmget(key_t key, size_t size, int flag)
7{
8 if (size > PTRDIFF_MAX) size = SIZE_MAX;
9#ifdef SYS_shmget
10 return syscall(SYS_shmget, key, size, flag);
11#else
12 return syscall(SYS_ipc, IPCOP_shmget, key, size, flag);
13#endif
14}
libc/musl/src/ldso/__dlsym.c created+10
......@@ -0,0 +1,10 @@
1#include <dlfcn.h>
2#include "dynlink.h"
3
4static void *stub_dlsym(void *restrict p, const char *restrict s, void *restrict ra)
5{
6 __dl_seterr("Symbol not found: %s", s);
7 return 0;
8}
9
10weak_alias(stub_dlsym, __dlsym);
libc/musl/src/ldso/aarch64/dlsym.s created+6
......@@ -0,0 +1,6 @@
1.global dlsym
2.hidden __dlsym
3.type dlsym,%function
4dlsym:
5 mov x2,x30
6 b __dlsym
libc/musl/src/ldso/aarch64/tlsdesc.s created+95
......@@ -0,0 +1,95 @@
1// size_t __tlsdesc_static(size_t *a)
2// {
3// return a[1];
4// }
5.global __tlsdesc_static
6.hidden __tlsdesc_static
7.type __tlsdesc_static,@function
8__tlsdesc_static:
9 ldr x0,[x0,#8]
10 ret
11
12.hidden __tls_get_new
13
14// size_t __tlsdesc_dynamic(size_t *a)
15// {
16// struct {size_t modidx,off;} *p = (void*)a[1];
17// size_t *dtv = *(size_t**)(tp - 8);
18// if (p->modidx <= dtv[0])
19// return dtv[p->modidx] + p->off - tp;
20// return __tls_get_new(p) - tp;
21// }
22.global __tlsdesc_dynamic
23.hidden __tlsdesc_dynamic
24.type __tlsdesc_dynamic,@function
25__tlsdesc_dynamic:
26 stp x1,x2,[sp,#-32]!
27 stp x3,x4,[sp,#16]
28 mrs x1,tpidr_el0 // tp
29 ldr x0,[x0,#8] // p
30 ldr x2,[x0] // p->modidx
31 ldr x3,[x1,#-8] // dtv
32 ldr x4,[x3] // dtv[0]
33 cmp x2,x4
34 b.hi 1f
35 ldr x2,[x3,x2,lsl #3] // dtv[p->modidx]
36 ldr x0,[x0,#8] // p->off
37 add x0,x0,x2
382: sub x0,x0,x1
39 ldp x3,x4,[sp,#16]
40 ldp x1,x2,[sp],#32
41 ret
42
43 // save all registers __tls_get_new may clobber
44 // update sp in two steps because offset must be in [-512,509]
451: stp x29,x30,[sp,#-160]!
46 stp x5,x6,[sp,#16]
47 stp x7,x8,[sp,#32]
48 stp x9,x10,[sp,#48]
49 stp x11,x12,[sp,#64]
50 stp x13,x14,[sp,#80]
51 stp x15,x16,[sp,#96]
52 stp x17,x18,[sp,#112]
53 stp q0,q1,[sp,#128]
54 stp q2,q3,[sp,#-480]!
55 stp q4,q5,[sp,#32]
56 stp q6,q7,[sp,#64]
57 stp q8,q9,[sp,#96]
58 stp q10,q11,[sp,#128]
59 stp q12,q13,[sp,#160]
60 stp q14,q15,[sp,#192]
61 stp q16,q17,[sp,#224]
62 stp q18,q19,[sp,#256]
63 stp q20,q21,[sp,#288]
64 stp q22,q23,[sp,#320]
65 stp q24,q25,[sp,#352]
66 stp q26,q27,[sp,#384]
67 stp q28,q29,[sp,#416]
68 stp q30,q31,[sp,#448]
69 bl __tls_get_new
70 mrs x1,tpidr_el0
71 ldp q4,q5,[sp,#32]
72 ldp q6,q7,[sp,#64]
73 ldp q8,q9,[sp,#96]
74 ldp q10,q11,[sp,#128]
75 ldp q12,q13,[sp,#160]
76 ldp q14,q15,[sp,#192]
77 ldp q16,q17,[sp,#224]
78 ldp q18,q19,[sp,#256]
79 ldp q20,q21,[sp,#288]
80 ldp q22,q23,[sp,#320]
81 ldp q24,q25,[sp,#352]
82 ldp q26,q27,[sp,#384]
83 ldp q28,q29,[sp,#416]
84 ldp q30,q31,[sp,#448]
85 ldp q2,q3,[sp],#480
86 ldp x5,x6,[sp,#16]
87 ldp x7,x8,[sp,#32]
88 ldp x9,x10,[sp,#48]
89 ldp x11,x12,[sp,#64]
90 ldp x13,x14,[sp,#80]
91 ldp x15,x16,[sp,#96]
92 ldp x17,x18,[sp,#112]
93 ldp q0,q1,[sp,#128]
94 ldp x29,x30,[sp],#160
95 b 2b
libc/musl/src/ldso/arm/dlsym.s created+8
......@@ -0,0 +1,8 @@
1.syntax unified
2.text
3.global dlsym
4.hidden __dlsym
5.type dlsym,%function
6dlsym:
7 mov r2,lr
8 b __dlsym
libc/musl/src/ldso/arm/find_exidx.c created+42
......@@ -0,0 +1,42 @@
1#define _GNU_SOURCE
2#include <link.h>
3#include <stdint.h>
4
5struct find_exidx_data {
6 uintptr_t pc, exidx_start;
7 int exidx_len;
8};
9
10static int find_exidx(struct dl_phdr_info *info, size_t size, void *ptr)
11{
12 struct find_exidx_data *data = ptr;
13 const ElfW(Phdr) *phdr = info->dlpi_phdr;
14 uintptr_t addr, exidx_start = 0;
15 int i, match = 0, exidx_len = 0;
16
17 for (i = info->dlpi_phnum; i > 0; i--, phdr++) {
18 addr = info->dlpi_addr + phdr->p_vaddr;
19 switch (phdr->p_type) {
20 case PT_LOAD:
21 match |= data->pc >= addr && data->pc < addr + phdr->p_memsz;
22 break;
23 case PT_ARM_EXIDX:
24 exidx_start = addr;
25 exidx_len = phdr->p_memsz;
26 break;
27 }
28 }
29 data->exidx_start = exidx_start;
30 data->exidx_len = exidx_len;
31 return match;
32}
33
34uintptr_t __gnu_Unwind_Find_exidx(uintptr_t pc, int *pcount)
35{
36 struct find_exidx_data data;
37 data.pc = pc;
38 if (dl_iterate_phdr(find_exidx, &data) <= 0)
39 return 0;
40 *pcount = data.exidx_len / 8;
41 return data.exidx_start;
42}
libc/musl/src/ldso/arm/tlsdesc.S created+72
......@@ -0,0 +1,72 @@
1.syntax unified
2
3.text
4.global __tlsdesc_static
5.hidden __tlsdesc_static
6.type __tlsdesc_static,%function
7__tlsdesc_static:
8 ldr r0,[r0]
9 bx lr
10
11.hidden __tls_get_new
12
13.global __tlsdesc_dynamic
14.hidden __tlsdesc_dynamic
15.type __tlsdesc_dynamic,%function
16__tlsdesc_dynamic:
17 push {r2,r3,ip,lr}
18 ldr r1,[r0]
19 ldr r2,[r1,#4] // r2 = offset
20 ldr r1,[r1] // r1 = modid
21
22#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
23 || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
24 mrc p15,0,r0,c13,c0,3
25#else
26 ldr r0,1f
27 add r0,r0,pc
28 ldr r0,[r0]
292:
30#if __ARM_ARCH >= 5
31 blx r0 // r0 = tp
32#else
33 mov lr,pc
34 bx r0
35#endif
36#endif
37 ldr r3,[r0,#-4] // r3 = dtv
38 ldr ip,[r3] // ip = dtv slot count
39 cmp r1,ip
40 bhi 3f
41 ldr ip,[r3,r1,LSL #2]
42 sub r0,ip,r0
43 add r0,r0,r2 // r0 = r3[r1]-r0+r2
444:
45#if __ARM_ARCH >= 5
46 pop {r2,r3,ip,pc}
47#else
48 pop {r2,r3,ip,lr}
49 bx lr
50#endif
51
523:
53#if __ARM_PCS_VFP || !__SOFTFP__
54 .fpu vfp
55 vpush {d0-d7}
56#endif
57 push {r0-r3}
58 add r0,sp,#4
59 bl __tls_get_new
60 pop {r1-r3,ip}
61#if __ARM_PCS_VFP || !__SOFTFP__
62 vpop {d0-d7}
63#endif
64 sub r0,r0,r1 // r0 = retval-tp
65 b 4b
66
67#if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
68 || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
69#else
70 .align 2
711: .word __a_gettp_ptr - 2b
72#endif
libc/musl/src/ldso/dl_iterate_phdr.c created+46
......@@ -0,0 +1,46 @@
1#include <elf.h>
2#include <link.h>
3#include "libc.h"
4
5#define AUX_CNT 38
6
7extern weak hidden const size_t _DYNAMIC[];
8
9static int static_dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void *data), void *data)
10{
11 unsigned char *p;
12 ElfW(Phdr) *phdr, *tls_phdr=0;
13 size_t base = 0;
14 size_t n;
15 struct dl_phdr_info info;
16 size_t i, aux[AUX_CNT] = {0};
17
18 for (i=0; libc.auxv[i]; i+=2)
19 if (libc.auxv[i]<AUX_CNT) aux[libc.auxv[i]] = libc.auxv[i+1];
20
21 for (p=(void *)aux[AT_PHDR],n=aux[AT_PHNUM]; n; n--,p+=aux[AT_PHENT]) {
22 phdr = (void *)p;
23 if (phdr->p_type == PT_PHDR)
24 base = aux[AT_PHDR] - phdr->p_vaddr;
25 if (phdr->p_type == PT_DYNAMIC && _DYNAMIC)
26 base = (size_t)_DYNAMIC - phdr->p_vaddr;
27 if (phdr->p_type == PT_TLS)
28 tls_phdr = phdr;
29 }
30 info.dlpi_addr = base;
31 info.dlpi_name = "/proc/self/exe";
32 info.dlpi_phdr = (void *)aux[AT_PHDR];
33 info.dlpi_phnum = aux[AT_PHNUM];
34 info.dlpi_adds = 0;
35 info.dlpi_subs = 0;
36 if (tls_phdr) {
37 info.dlpi_tls_modid = 1;
38 info.dlpi_tls_data = (void *)(base + tls_phdr->p_vaddr);
39 } else {
40 info.dlpi_tls_modid = 0;
41 info.dlpi_tls_data = 0;
42 }
43 return (callback)(&info, sizeof (info), data);
44}
45
46weak_alias(static_dl_iterate_phdr, dl_iterate_phdr);
libc/musl/src/ldso/dladdr.c created+9
......@@ -0,0 +1,9 @@
1#define _GNU_SOURCE
2#include <dlfcn.h>
3
4static int stub_dladdr(const void *addr, Dl_info *info)
5{
6 return 0;
7}
8
9weak_alias(stub_dladdr, dladdr);
libc/musl/src/ldso/dlclose.c created+7
......@@ -0,0 +1,7 @@
1#include <dlfcn.h>
2#include "dynlink.h"
3
4int dlclose(void *p)
5{
6 return __dl_invalid_handle(p);
7}
libc/musl/src/ldso/dlerror.c created+59
......@@ -0,0 +1,59 @@
1#include <dlfcn.h>
2#include <stdlib.h>
3#include <stdarg.h>
4#include "pthread_impl.h"
5#include "dynlink.h"
6
7char *dlerror()
8{
9 pthread_t self = __pthread_self();
10 if (!self->dlerror_flag) return 0;
11 self->dlerror_flag = 0;
12 char *s = self->dlerror_buf;
13 if (s == (void *)-1)
14 return "Dynamic linker failed to allocate memory for error message";
15 else
16 return s;
17}
18
19void __dl_thread_cleanup(void)
20{
21 pthread_t self = __pthread_self();
22 if (self->dlerror_buf != (void *)-1)
23 free(self->dlerror_buf);
24}
25
26hidden void __dl_vseterr(const char *fmt, va_list ap)
27{
28 va_list ap2;
29 va_copy(ap2, ap);
30 pthread_t self = __pthread_self();
31 if (self->dlerror_buf != (void *)-1)
32 free(self->dlerror_buf);
33 size_t len = vsnprintf(0, 0, fmt, ap2);
34 va_end(ap2);
35 char *buf = malloc(len+1);
36 if (buf) {
37 vsnprintf(buf, len+1, fmt, ap);
38 } else {
39 buf = (void *)-1;
40 }
41 self->dlerror_buf = buf;
42 self->dlerror_flag = 1;
43}
44
45hidden void __dl_seterr(const char *fmt, ...)
46{
47 va_list ap;
48 va_start(ap, fmt);
49 __dl_vseterr(fmt, ap);
50 va_end(ap);
51}
52
53static int stub_invalid_handle(void *h)
54{
55 __dl_seterr("Invalid library handle %p", (void *)h);
56 return 1;
57}
58
59weak_alias(stub_invalid_handle, __dl_invalid_handle);
libc/musl/src/ldso/dlinfo.c created+14
......@@ -0,0 +1,14 @@
1#define _GNU_SOURCE
2#include <dlfcn.h>
3#include "dynlink.h"
4
5int dlinfo(void *dso, int req, void *res)
6{
7 if (__dl_invalid_handle(dso)) return -1;
8 if (req != RTLD_DI_LINKMAP) {
9 __dl_seterr("Unsupported request %d", req);
10 return -1;
11 }
12 *(struct link_map **)res = dso;
13 return 0;
14}
libc/musl/src/ldso/dlopen.c created+10
......@@ -0,0 +1,10 @@
1#include <dlfcn.h>
2#include "dynlink.h"
3
4static void *stub_dlopen(const char *file, int mode)
5{
6 __dl_seterr("Dynamic loading not supported");
7 return 0;
8}
9
10weak_alias(stub_dlopen, dlopen);
libc/musl/src/ldso/dlsym.c created+7
......@@ -0,0 +1,7 @@
1#include <dlfcn.h>
2#include "dynlink.h"
3
4void *dlsym(void *restrict p, const char *restrict s)
5{
6 return __dlsym(p, s, 0);
7}
libc/musl/src/ldso/i386/dlsym.s created+11
......@@ -0,0 +1,11 @@
1.text
2.global dlsym
3.hidden __dlsym
4.type dlsym,@function
5dlsym:
6 push (%esp)
7 push 12(%esp)
8 push 12(%esp)
9 call __dlsym
10 add $12,%esp
11 ret
libc/musl/src/ldso/i386/tlsdesc.s created+31
......@@ -0,0 +1,31 @@
1.text
2.global __tlsdesc_static
3.hidden __tlsdesc_static
4.type __tlsdesc_static,@function
5__tlsdesc_static:
6 mov 4(%eax),%eax
7 ret
8
9.hidden __tls_get_new
10
11.global __tlsdesc_dynamic
12.hidden __tlsdesc_dynamic
13.type __tlsdesc_dynamic,@function
14__tlsdesc_dynamic:
15 mov 4(%eax),%eax
16 push %edx
17 mov %gs:4,%edx
18 push %ecx
19 mov (%eax),%ecx
20 cmp %ecx,(%edx)
21 jc 1f
22 mov 4(%eax),%eax
23 add (%edx,%ecx,4),%eax
242: pop %ecx
25 sub %gs:0,%eax
26 pop %edx
27 ret
281: push %eax
29 call __tls_get_new
30 pop %ecx
31 jmp 2b
libc/musl/src/ldso/m68k/dlsym.s created+12
......@@ -0,0 +1,12 @@
1.text
2.global dlsym
3.hidden __dlsym
4.type dlsym,@function
5dlsym:
6 move.l (%sp),-(%sp)
7 move.l 12(%sp),-(%sp)
8 move.l 12(%sp),-(%sp)
9 lea __dlsym-.-8,%a1
10 jsr (%pc,%a1)
11 add.l #12,%sp
12 rts
libc/musl/src/ldso/microblaze/dlsym.s created+6
......@@ -0,0 +1,6 @@
1.global dlsym
2.hidden __dlsym
3.type dlsym,@function
4dlsym:
5 brid __dlsym
6 add r7, r15, r0
libc/musl/src/ldso/mips/dlsym.s created+17
......@@ -0,0 +1,17 @@
1.set noreorder
2.global dlsym
3.hidden __dlsym
4.type dlsym,@function
5dlsym:
6 lui $gp, %hi(_gp_disp)
7 addiu $gp, %lo(_gp_disp)
8 addu $gp, $gp, $25
9 move $6, $ra
10 lw $25, %call16(__dlsym)($gp)
11 addiu $sp, $sp, -16
12 sw $ra, 12($sp)
13 jalr $25
14 nop
15 lw $ra, 12($sp)
16 jr $ra
17 addiu $sp, $sp, 16
libc/musl/src/ldso/mips64/dlsym.s created+17
......@@ -0,0 +1,17 @@
1.set noreorder
2.global dlsym
3.hidden __dlsym
4.type dlsym,@function
5dlsym:
6 lui $3, %hi(%neg(%gp_rel(dlsym)))
7 daddiu $3, $3, %lo(%neg(%gp_rel(dlsym)))
8 daddu $3, $3, $25
9 move $6, $ra
10 ld $25, %got_disp(__dlsym)($3)
11 daddiu $sp, $sp, -32
12 sd $ra, 24($sp)
13 jalr $25
14 nop
15 ld $ra, 24($sp)
16 jr $ra
17 daddiu $sp, $sp, 32
libc/musl/src/ldso/mipsn32/dlsym.s created+17
......@@ -0,0 +1,17 @@
1.set noreorder
2.global dlsym
3.hidden __dlsym
4.type dlsym,@function
5dlsym:
6 lui $3, %hi(%neg(%gp_rel(dlsym)))
7 addiu $3, $3, %lo(%neg(%gp_rel(dlsym)))
8 addu $3, $3, $25
9 move $6, $ra
10 lw $25, %got_disp(__dlsym)($3)
11 addiu $sp, $sp, -32
12 sd $ra, 16($sp)
13 jalr $25
14 nop
15 ld $ra, 16($sp)
16 jr $ra
17 addiu $sp, $sp, 32
libc/musl/src/ldso/or1k/dlsym.s created+6
......@@ -0,0 +1,6 @@
1.global dlsym
2.hidden __dlsym
3.type dlsym,@function
4dlsym:
5 l.j __dlsym
6 l.ori r5, r9, 0
libc/musl/src/ldso/powerpc/dlsym.s created+9
......@@ -0,0 +1,9 @@
1 .text
2 .global dlsym
3 .hidden __dlsym
4 .type dlsym,@function
5dlsym:
6 mflr 5 # The return address is arg3.
7 b __dlsym
8 .end dlsym
9 .size dlsym, .-dlsym
libc/musl/src/ldso/powerpc64/dlsym.s created+12
......@@ -0,0 +1,12 @@
1 .text
2 .global dlsym
3 .hidden __dlsym
4 .type dlsym,@function
5dlsym:
6 addis 2, 12, .TOC.-dlsym@ha
7 addi 2, 2, .TOC.-dlsym@l
8 .localentry dlsym,.-dlsym
9 mflr 5 # The return address is arg3.
10 b __dlsym
11 .end dlsym
12 .size dlsym, .-dlsym
libc/musl/src/ldso/s390x/dlsym.s created+6
......@@ -0,0 +1,6 @@
1 .global dlsym
2 .hidden __dlsym
3 .type dlsym,@function
4dlsym:
5 lgr %r4, %r14
6 jg __dlsym
libc/musl/src/ldso/sh/dlsym.s created+11
......@@ -0,0 +1,11 @@
1.text
2.global dlsym
3.hidden __dlsym
4.type dlsym, @function
5dlsym:
6 mov.l L1, r0
71: braf r0
8 mov.l @r15, r6
9
10.align 2
11L1: .long __dlsym@PLT-(1b+4-.)
libc/musl/src/ldso/tlsdesc.c created+9
......@@ -0,0 +1,9 @@
1#include <stddef.h>
2#include <dynlink.h>
3
4ptrdiff_t __tlsdesc_static()
5{
6 return 0;
7}
8
9weak_alias(__tlsdesc_static, __tlsdesc_dynamic);
libc/musl/src/ldso/x32/dlsym.s created+7
......@@ -0,0 +1,7 @@
1.text
2.global dlsym
3.hidden __dlsym
4.type dlsym,@function
5dlsym:
6 mov (%rsp),%rdx
7 jmp __dlsym
libc/musl/src/ldso/x86_64/dlsym.s created+7
......@@ -0,0 +1,7 @@
1.text
2.global dlsym
3.hidden __dlsym
4.type dlsym,@function
5dlsym:
6 mov (%rsp),%rdx
7 jmp __dlsym
libc/musl/src/ldso/x86_64/tlsdesc.s created+44
......@@ -0,0 +1,44 @@
1.text
2.global __tlsdesc_static
3.hidden __tlsdesc_static
4.type __tlsdesc_static,@function
5__tlsdesc_static:
6 mov 8(%rax),%rax
7 ret
8
9.hidden __tls_get_new
10
11.global __tlsdesc_dynamic
12.hidden __tlsdesc_dynamic
13.type __tlsdesc_dynamic,@function
14__tlsdesc_dynamic:
15 mov 8(%rax),%rax
16 push %rdx
17 mov %fs:8,%rdx
18 push %rcx
19 mov (%rax),%rcx
20 cmp %rcx,(%rdx)
21 jc 1f
22 mov 8(%rax),%rax
23 add (%rdx,%rcx,8),%rax
242: pop %rcx
25 sub %fs:0,%rax
26 pop %rdx
27 ret
281: push %rdi
29 push %rdi
30 push %rsi
31 push %r8
32 push %r9
33 push %r10
34 push %r11
35 mov %rax,%rdi
36 call __tls_get_new
37 pop %r11
38 pop %r10
39 pop %r9
40 pop %r8
41 pop %rsi
42 pop %rdi
43 pop %rdi
44 jmp 2b
libc/musl/src/legacy/cuserid.c created+14
......@@ -0,0 +1,14 @@
1#define _GNU_SOURCE
2#include <pwd.h>
3#include <stdio.h>
4#include <unistd.h>
5
6char *cuserid(char *buf)
7{
8 struct passwd pw, *ppw;
9 long pwb[256];
10 if (getpwuid_r(geteuid(), &pw, (void *)pwb, sizeof pwb, &ppw))
11 return 0;
12 snprintf(buf, L_cuserid, "%s", pw.pw_name);
13 return buf;
14}
libc/musl/src/legacy/daemon.c created+33
......@@ -0,0 +1,33 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include <unistd.h>
4
5int daemon(int nochdir, int noclose)
6{
7 if (!nochdir && chdir("/"))
8 return -1;
9 if (!noclose) {
10 int fd, failed = 0;
11 if ((fd = open("/dev/null", O_RDWR)) < 0) return -1;
12 if (dup2(fd, 0) < 0 || dup2(fd, 1) < 0 || dup2(fd, 2) < 0)
13 failed++;
14 if (fd > 2) close(fd);
15 if (failed) return -1;
16 }
17
18 switch(fork()) {
19 case 0: break;
20 case -1: return -1;
21 default: _exit(0);
22 }
23
24 if (setsid() < 0) return -1;
25
26 switch(fork()) {
27 case 0: break;
28 case -1: return -1;
29 default: _exit(0);
30 }
31
32 return 0;
33}
libc/musl/src/legacy/err.c created+67
......@@ -0,0 +1,67 @@
1#include <err.h>
2#include <stdio.h>
3#include <stdarg.h>
4#include <stdlib.h>
5
6extern char *__progname;
7
8void vwarn(const char *fmt, va_list ap)
9{
10 fprintf (stderr, "%s: ", __progname);
11 if (fmt) {
12 vfprintf(stderr, fmt, ap);
13 fputs (": ", stderr);
14 }
15 perror(0);
16}
17
18void vwarnx(const char *fmt, va_list ap)
19{
20 fprintf (stderr, "%s: ", __progname);
21 if (fmt) vfprintf(stderr, fmt, ap);
22 putc('\n', stderr);
23}
24
25_Noreturn void verr(int status, const char *fmt, va_list ap)
26{
27 vwarn(fmt, ap);
28 exit(status);
29}
30
31_Noreturn void verrx(int status, const char *fmt, va_list ap)
32{
33 vwarnx(fmt, ap);
34 exit(status);
35}
36
37void warn(const char *fmt, ...)
38{
39 va_list ap;
40 va_start(ap, fmt);
41 vwarn(fmt, ap);
42 va_end(ap);
43}
44
45void warnx(const char *fmt, ...)
46{
47 va_list ap;
48 va_start(ap, fmt);
49 vwarnx(fmt, ap);
50 va_end(ap);
51}
52
53_Noreturn void err(int status, const char *fmt, ...)
54{
55 va_list ap;
56 va_start(ap, fmt);
57 verr(status, fmt, ap);
58 va_end(ap);
59}
60
61_Noreturn void errx(int status, const char *fmt, ...)
62{
63 va_list ap;
64 va_start(ap, fmt);
65 verrx(status, fmt, ap);
66 va_end(ap);
67}
libc/musl/src/legacy/euidaccess.c created+10
......@@ -0,0 +1,10 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include <fcntl.h>
4
5int euidaccess(const char *filename, int amode)
6{
7 return faccessat(AT_FDCWD, filename, amode, AT_EACCESS);
8}
9
10weak_alias(euidaccess, eaccess);
libc/musl/src/legacy/ftw.c created+11
......@@ -0,0 +1,11 @@
1#include <ftw.h>
2
3int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int fd_limit)
4{
5 /* The following cast assumes that calling a function with one
6 * argument more than it needs behaves as expected. This is
7 * actually undefined, but works on all real-world machines. */
8 return nftw(path, (int (*)())fn, fd_limit, FTW_PHYS);
9}
10
11weak_alias(ftw, ftw64);
libc/musl/src/legacy/futimes.c created+14
......@@ -0,0 +1,14 @@
1#define _GNU_SOURCE
2#include <sys/stat.h>
3#include <sys/time.h>
4
5int futimes(int fd, const struct timeval tv[2])
6{
7 struct timespec times[2];
8 if (!tv) return futimens(fd, 0);
9 times[0].tv_sec = tv[0].tv_sec;
10 times[0].tv_nsec = tv[0].tv_usec * 1000;
11 times[1].tv_sec = tv[1].tv_sec;
12 times[1].tv_nsec = tv[1].tv_usec * 1000;
13 return futimens(fd, times);
14}
libc/musl/src/legacy/getdtablesize.c created+11
......@@ -0,0 +1,11 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include <limits.h>
4#include <sys/resource.h>
5
6int getdtablesize(void)
7{
8 struct rlimit rl;
9 getrlimit(RLIMIT_NOFILE, &rl);
10 return rl.rlim_cur < INT_MAX ? rl.rlim_cur : INT_MAX;
11}
libc/musl/src/legacy/getloadavg.c created+14
......@@ -0,0 +1,14 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <sys/sysinfo.h>
4
5int getloadavg(double *a, int n)
6{
7 struct sysinfo si;
8 if (n <= 0) return n ? -1 : 0;
9 sysinfo(&si);
10 if (n > 3) n = 3;
11 for (int i=0; i<n; i++)
12 a[i] = 1.0/(1<<SI_LOAD_SHIFT) * si.loads[i];
13 return n;
14}
libc/musl/src/legacy/getpagesize.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "libc.h"
4
5int getpagesize(void)
6{
7 return PAGE_SIZE;
8}
libc/musl/src/legacy/getpass.c created+40
......@@ -0,0 +1,40 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3#include <termios.h>
4#include <unistd.h>
5#include <fcntl.h>
6#include <string.h>
7
8char *getpass(const char *prompt)
9{
10 int fd;
11 struct termios s, t;
12 ssize_t l;
13 static char password[128];
14
15 if ((fd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC)) < 0) return 0;
16
17 tcgetattr(fd, &t);
18 s = t;
19 t.c_lflag &= ~(ECHO|ISIG);
20 t.c_lflag |= ICANON;
21 t.c_iflag &= ~(INLCR|IGNCR);
22 t.c_iflag |= ICRNL;
23 tcsetattr(fd, TCSAFLUSH, &t);
24 tcdrain(fd);
25
26 dprintf(fd, "%s", prompt);
27
28 l = read(fd, password, sizeof password);
29 if (l >= 0) {
30 if (l > 0 && password[l-1] == '\n' || l==sizeof password) l--;
31 password[l] = 0;
32 }
33
34 tcsetattr(fd, TCSAFLUSH, &s);
35
36 dprintf(fd, "\n");
37 close(fd);
38
39 return l<0 ? 0 : password;
40}
libc/musl/src/legacy/getusershell.c created+32
......@@ -0,0 +1,32 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3#include <unistd.h>
4
5static const char defshells[] = "/bin/sh\n/bin/csh\n";
6
7static char *line;
8static size_t linesize;
9static FILE *f;
10
11void endusershell(void)
12{
13 if (f) fclose(f);
14 f = 0;
15}
16
17void setusershell(void)
18{
19 if (!f) f = fopen("/etc/shells", "rbe");
20 if (!f) f = fmemopen((void *)defshells, sizeof defshells - 1, "rb");
21}
22
23char *getusershell(void)
24{
25 ssize_t l;
26 if (!f) setusershell();
27 if (!f) return 0;
28 l = getline(&line, &linesize, f);
29 if (l <= 0) return 0;
30 if (line[l-1]=='\n') line[l-1]=0;
31 return line;
32}
libc/musl/src/legacy/isastream.c created+7
......@@ -0,0 +1,7 @@
1#include <stropts.h>
2#include <fcntl.h>
3
4int isastream(int fd)
5{
6 return fcntl(fd, F_GETFD) < 0 ? -1 : 0;
7}
libc/musl/src/legacy/lutimes.c created+14
......@@ -0,0 +1,14 @@
1#define _GNU_SOURCE
2#include <sys/stat.h>
3#include <sys/time.h>
4#include <fcntl.h>
5
6int lutimes(const char *filename, const struct timeval tv[2])
7{
8 struct timespec times[2];
9 times[0].tv_sec = tv[0].tv_sec;
10 times[0].tv_nsec = tv[0].tv_usec * 1000;
11 times[1].tv_sec = tv[1].tv_sec;
12 times[1].tv_nsec = tv[1].tv_usec * 1000;
13 return utimensat(AT_FDCWD, filename, times, AT_SYMLINK_NOFOLLOW);
14}
libc/musl/src/legacy/ulimit.c created+19
......@@ -0,0 +1,19 @@
1#include <sys/resource.h>
2#include <ulimit.h>
3#include <stdarg.h>
4
5long ulimit(int cmd, ...)
6{
7 struct rlimit rl;
8 getrlimit(RLIMIT_FSIZE, &rl);
9 if (cmd == UL_SETFSIZE) {
10 long val;
11 va_list ap;
12 va_start(ap, cmd);
13 val = va_arg(ap, long);
14 va_end(ap);
15 rl.rlim_cur = 512ULL * val;
16 if (setrlimit(RLIMIT_FSIZE, &rl)) return -1;
17 }
18 return rl.rlim_cur / 512;
19}
libc/musl/src/legacy/utmpx.c created+52
......@@ -0,0 +1,52 @@
1#define _GNU_SOURCE
2#include <utmpx.h>
3#include <stddef.h>
4#include <errno.h>
5
6void endutxent(void)
7{
8}
9
10void setutxent(void)
11{
12}
13
14struct utmpx *getutxent(void)
15{
16 return NULL;
17}
18
19struct utmpx *getutxid(const struct utmpx *ut)
20{
21 return NULL;
22}
23
24struct utmpx *getutxline(const struct utmpx *ut)
25{
26 return NULL;
27}
28
29struct utmpx *pututxline(const struct utmpx *ut)
30{
31 return NULL;
32}
33
34void updwtmpx(const char *f, const struct utmpx *u)
35{
36}
37
38static int __utmpxname(const char *f)
39{
40 errno = ENOTSUP;
41 return -1;
42}
43
44weak_alias(endutxent, endutent);
45weak_alias(setutxent, setutent);
46weak_alias(getutxent, getutent);
47weak_alias(getutxid, getutid);
48weak_alias(getutxline, getutline);
49weak_alias(pututxline, pututline);
50weak_alias(updwtmpx, updwtmp);
51weak_alias(__utmpxname, utmpname);
52weak_alias(__utmpxname, utmpxname);
libc/musl/src/legacy/valloc.c created+8
......@@ -0,0 +1,8 @@
1#define _BSD_SOURCE
2#include <stdlib.h>
3#include "libc.h"
4
5void *valloc(size_t size)
6{
7 return memalign(PAGE_SIZE, size);
8}
libc/musl/src/linux/adjtime.c created+27
......@@ -0,0 +1,27 @@
1#define _GNU_SOURCE
2#include <sys/time.h>
3#include <sys/timex.h>
4#include <errno.h>
5#include "syscall.h"
6
7int adjtime(const struct timeval *in, struct timeval *out)
8{
9 struct timex tx = { 0 };
10 if (in) {
11 if (in->tv_sec > 1000 || in->tv_usec > 1000000000) {
12 errno = EINVAL;
13 return -1;
14 }
15 tx.offset = in->tv_sec*1000000 + in->tv_usec;
16 tx.modes = ADJ_OFFSET_SINGLESHOT;
17 }
18 if (syscall(SYS_adjtimex, &tx) < 0) return -1;
19 if (out) {
20 out->tv_sec = tx.offset / 1000000;
21 if ((out->tv_usec = tx.offset % 1000000) < 0) {
22 out->tv_sec--;
23 out->tv_usec += 1000000;
24 }
25 }
26 return 0;
27}
libc/musl/src/linux/adjtimex.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/timex.h>
2#include "syscall.h"
3
4int adjtimex(struct timex *tx)
5{
6 return syscall(SYS_adjtimex, tx);
7}
libc/musl/src/linux/arch_prctl.c created+7
......@@ -0,0 +1,7 @@
1#include "syscall.h"
2#ifdef SYS_arch_prctl
3int arch_prctl(int code, unsigned long addr)
4{
5 return syscall(SYS_arch_prctl, code, addr);
6}
7#endif
libc/musl/src/linux/brk.c created+9
......@@ -0,0 +1,9 @@
1#define _BSD_SOURCE
2#include <unistd.h>
3#include <errno.h>
4#include "syscall.h"
5
6int brk(void *end)
7{
8 return __syscall_ret(-ENOMEM);
9}
libc/musl/src/linux/cache.c created+17
......@@ -0,0 +1,17 @@
1#include "syscall.h"
2
3#ifdef SYS_cacheflush
4int _flush_cache(void *addr, int len, int op)
5{
6 return syscall(SYS_cacheflush, addr, len, op);
7}
8weak_alias(_flush_cache, cacheflush);
9#endif
10
11#ifdef SYS_cachectl
12int __cachectl(void *addr, int len, int op)
13{
14 return syscall(SYS_cachectl, addr, len, op);
15}
16weak_alias(__cachectl, cachectl);
17#endif
libc/musl/src/linux/cap.c created+11
......@@ -0,0 +1,11 @@
1#include "syscall.h"
2
3int capset(void *a, void *b)
4{
5 return syscall(SYS_capset, a, b);
6}
7
8int capget(void *a, void *b)
9{
10 return syscall(SYS_capget, a, b);
11}
libc/musl/src/linux/chroot.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4
5int chroot(const char *path)
6{
7 return syscall(SYS_chroot, path);
8}
libc/musl/src/linux/clock_adjtime.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/timex.h>
2#include "syscall.h"
3
4int clock_adjtime (clockid_t clock_id, struct timex *utx)
5{
6 return syscall(SYS_clock_adjtime, clock_id, utx);
7}
libc/musl/src/linux/clone.c created+21
......@@ -0,0 +1,21 @@
1#define _GNU_SOURCE
2#include <stdarg.h>
3#include <unistd.h>
4#include <sched.h>
5#include "pthread_impl.h"
6#include "syscall.h"
7
8int clone(int (*func)(void *), void *stack, int flags, void *arg, ...)
9{
10 va_list ap;
11 pid_t *ptid, *ctid;
12 void *tls;
13
14 va_start(ap, arg);
15 ptid = va_arg(ap, pid_t *);
16 tls = va_arg(ap, void *);
17 ctid = va_arg(ap, pid_t *);
18 va_end(ap);
19
20 return __syscall_ret(__clone(func, stack, flags, arg, ptid, tls, ctid));
21}
libc/musl/src/linux/epoll.c created+37
......@@ -0,0 +1,37 @@
1#include <sys/epoll.h>
2#include <signal.h>
3#include <errno.h>
4#include "syscall.h"
5
6int epoll_create(int size)
7{
8 return epoll_create1(0);
9}
10
11int epoll_create1(int flags)
12{
13 int r = __syscall(SYS_epoll_create1, flags);
14#ifdef SYS_epoll_create
15 if (r==-ENOSYS && !flags) r = __syscall(SYS_epoll_create, 1);
16#endif
17 return __syscall_ret(r);
18}
19
20int epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev)
21{
22 return syscall(SYS_epoll_ctl, fd, op, fd2, ev);
23}
24
25int epoll_pwait(int fd, struct epoll_event *ev, int cnt, int to, const sigset_t *sigs)
26{
27 int r = __syscall(SYS_epoll_pwait, fd, ev, cnt, to, sigs, _NSIG/8);
28#ifdef SYS_epoll_wait
29 if (r==-ENOSYS && !sigs) r = __syscall(SYS_epoll_wait, fd, ev, cnt, to);
30#endif
31 return __syscall_ret(r);
32}
33
34int epoll_wait(int fd, struct epoll_event *ev, int cnt, int to)
35{
36 return epoll_pwait(fd, ev, cnt, to, 0);
37}
libc/musl/src/linux/eventfd.c created+23
......@@ -0,0 +1,23 @@
1#include <sys/eventfd.h>
2#include <unistd.h>
3#include <errno.h>
4#include "syscall.h"
5
6int eventfd(unsigned int count, int flags)
7{
8 int r = __syscall(SYS_eventfd2, count, flags);
9#ifdef SYS_eventfd
10 if (r==-ENOSYS && !flags) r = __syscall(SYS_eventfd, count);
11#endif
12 return __syscall_ret(r);
13}
14
15int eventfd_read(int fd, eventfd_t *value)
16{
17 return (sizeof(*value) == read(fd, value, sizeof(*value))) ? 0 : -1;
18}
19
20int eventfd_write(int fd, eventfd_t value)
21{
22 return (sizeof(value) == write(fd, &value, sizeof(value))) ? 0 : -1;
23}
libc/musl/src/linux/fallocate.c created+12
......@@ -0,0 +1,12 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include "syscall.h"
4
5int fallocate(int fd, int mode, off_t base, off_t len)
6{
7 return syscall(SYS_fallocate, fd, mode, __SYSCALL_LL_E(base),
8 __SYSCALL_LL_E(len));
9}
10
11#undef fallocate64
12weak_alias(fallocate, fallocate64);
libc/musl/src/linux/fanotify.c created+14
......@@ -0,0 +1,14 @@
1#include "syscall.h"
2#include <sys/fanotify.h>
3
4int fanotify_init(unsigned flags, unsigned event_f_flags)
5{
6 return syscall(SYS_fanotify_init, flags, event_f_flags);
7}
8
9int fanotify_mark(int fanotify_fd, unsigned flags, unsigned long long mask,
10 int dfd, const char *pathname)
11{
12 return syscall(SYS_fanotify_mark, fanotify_fd, flags, __SYSCALL_LL_E(mask), dfd, pathname);
13}
14
libc/musl/src/linux/flock.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/file.h>
2#include "syscall.h"
3
4int flock(int fd, int op)
5{
6 return syscall(SYS_flock, fd, op);
7}
libc/musl/src/linux/getdents.c created+10
......@@ -0,0 +1,10 @@
1#define _BSD_SOURCE
2#include <dirent.h>
3#include "syscall.h"
4
5int getdents(int fd, struct dirent *buf, size_t len)
6{
7 return syscall(SYS_getdents, fd, buf, len);
8}
9
10weak_alias(getdents, getdents64);
libc/musl/src/linux/getrandom.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/random.h>
2#include "syscall.h"
3
4ssize_t getrandom(void *buf, size_t buflen, unsigned flags)
5{
6 return syscall_cp(SYS_getrandom, buf, buflen, flags);
7}
libc/musl/src/linux/inotify.c created+26
......@@ -0,0 +1,26 @@
1#include <sys/inotify.h>
2#include <errno.h>
3#include "syscall.h"
4
5int inotify_init()
6{
7 return inotify_init1(0);
8}
9int inotify_init1(int flags)
10{
11 int r = __syscall(SYS_inotify_init1, flags);
12#ifdef SYS_inotify_init
13 if (r==-ENOSYS && !flags) r = __syscall(SYS_inotify_init);
14#endif
15 return __syscall_ret(r);
16}
17
18int inotify_add_watch(int fd, const char *pathname, uint32_t mask)
19{
20 return syscall(SYS_inotify_add_watch, fd, pathname, mask);
21}
22
23int inotify_rm_watch(int fd, int wd)
24{
25 return syscall(SYS_inotify_rm_watch, fd, wd);
26}
libc/musl/src/linux/ioperm.c created+10
......@@ -0,0 +1,10 @@
1#include "syscall.h"
2
3#ifdef SYS_ioperm
4#include <sys/io.h>
5
6int ioperm(unsigned long from, unsigned long num, int turn_on)
7{
8 return syscall(SYS_ioperm, from, num, turn_on);
9}
10#endif
libc/musl/src/linux/iopl.c created+10
......@@ -0,0 +1,10 @@
1#include "syscall.h"
2
3#ifdef SYS_iopl
4#include <sys/io.h>
5
6int iopl(int level)
7{
8 return syscall(SYS_iopl, level);
9}
10#endif
libc/musl/src/linux/klogctl.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/klog.h>
2#include "syscall.h"
3
4int klogctl (int type, char *buf, int len)
5{
6 return syscall(SYS_syslog, type, buf, len);
7}
libc/musl/src/linux/memfd_create.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE 1
2#include <sys/mman.h>
3#include "syscall.h"
4
5int memfd_create(const char *name, unsigned flags)
6{
7 return syscall(SYS_memfd_create, name, flags);
8}
libc/musl/src/linux/mlock2.c created+10
......@@ -0,0 +1,10 @@
1#define _GNU_SOURCE 1
2#include <sys/mman.h>
3#include "syscall.h"
4
5int mlock2(const void *addr, size_t len, unsigned flags)
6{
7 if (flags == 0)
8 return mlock(addr, len);
9 return syscall(SYS_mlock2, addr, len, flags);
10}
libc/musl/src/linux/module.c created+11
......@@ -0,0 +1,11 @@
1#include "syscall.h"
2
3int init_module(void *a, unsigned long b, const char *c)
4{
5 return syscall(SYS_init_module, a, b, c);
6}
7
8int delete_module(const char *a, unsigned b)
9{
10 return syscall(SYS_delete_module, a, b);
11}
libc/musl/src/linux/mount.c created+17
......@@ -0,0 +1,17 @@
1#include <sys/mount.h>
2#include "syscall.h"
3
4int mount(const char *special, const char *dir, const char *fstype, unsigned long flags, const void *data)
5{
6 return syscall(SYS_mount, special, dir, fstype, flags, data);
7}
8
9int umount(const char *special)
10{
11 return syscall(SYS_umount2, special, 0);
12}
13
14int umount2(const char *special, int flags)
15{
16 return syscall(SYS_umount2, special, flags);
17}
libc/musl/src/linux/name_to_handle_at.c created+10
......@@ -0,0 +1,10 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include "syscall.h"
4
5int name_to_handle_at(int dirfd, const char *pathname,
6 struct file_handle *handle, int *mount_id, int flags)
7{
8 return syscall(SYS_name_to_handle_at, dirfd,
9 pathname, handle, mount_id, flags);
10}
libc/musl/src/linux/open_by_handle_at.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include "syscall.h"
4
5int open_by_handle_at(int mount_fd, struct file_handle *handle, int flags)
6{
7 return syscall(SYS_open_by_handle_at, mount_fd, handle, flags);
8}
libc/musl/src/linux/personality.c created+8
......@@ -0,0 +1,8 @@
1#include <sys/personality.h>
2#include "syscall.h"
3#ifdef SYS_personality
4int personality(unsigned long persona)
5{
6 return syscall(SYS_personality, persona);
7}
8#endif
libc/musl/src/linux/pivot_root.c created+6
......@@ -0,0 +1,6 @@
1#include "syscall.h"
2
3int pivot_root(const char *new, const char *old)
4{
5 return syscall(SYS_pivot_root, new, old);
6}
libc/musl/src/linux/ppoll.c created+10
......@@ -0,0 +1,10 @@
1#define _GNU_SOURCE
2#include <poll.h>
3#include <signal.h>
4#include "syscall.h"
5
6int ppoll(struct pollfd *fds, nfds_t n, const struct timespec *to, const sigset_t *mask)
7{
8 return syscall_cp(SYS_ppoll, fds, n,
9 to ? (struct timespec []){*to} : 0, mask, _NSIG/8);
10}
libc/musl/src/linux/prctl.c created+14
......@@ -0,0 +1,14 @@
1#include <sys/prctl.h>
2#include <stdarg.h>
3#include "syscall.h"
4
5int prctl(int op, ...)
6{
7 unsigned long x[4];
8 int i;
9 va_list ap;
10 va_start(ap, op);
11 for (i=0; i<4; i++) x[i] = va_arg(ap, unsigned long);
12 va_end(ap);
13 return syscall(SYS_prctl, op, x[0], x[1], x[2], x[3]);
14}
libc/musl/src/linux/prlimit.c created+26
......@@ -0,0 +1,26 @@
1#define _GNU_SOURCE
2#include <sys/resource.h>
3#include "syscall.h"
4
5#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
6
7int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlimit *old_limit)
8{
9 struct rlimit tmp;
10 int r;
11 if (new_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
12 tmp = *new_limit;
13 FIX(tmp.rlim_cur);
14 FIX(tmp.rlim_max);
15 new_limit = &tmp;
16 }
17 r = syscall(SYS_prlimit64, pid, resource, new_limit, old_limit);
18 if (!r && old_limit && SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
19 FIX(old_limit->rlim_cur);
20 FIX(old_limit->rlim_max);
21 }
22 return r;
23}
24
25#undef prlimit64
26weak_alias(prlimit, prlimit64);
libc/musl/src/linux/process_vm.c created+13
......@@ -0,0 +1,13 @@
1#define _GNU_SOURCE
2#include <sys/uio.h>
3#include "syscall.h"
4
5ssize_t process_vm_writev(pid_t pid, const struct iovec *lvec, unsigned long liovcnt, const struct iovec *rvec, unsigned long riovcnt, unsigned long flags)
6{
7 return syscall(SYS_process_vm_writev, pid, lvec, liovcnt, rvec, riovcnt, flags);
8}
9
10ssize_t process_vm_readv(pid_t pid, const struct iovec *lvec, unsigned long liovcnt, const struct iovec *rvec, unsigned long riovcnt, unsigned long flags)
11{
12 return syscall(SYS_process_vm_readv, pid, lvec, liovcnt, rvec, riovcnt, flags);
13}
libc/musl/src/linux/ptrace.c created+29
......@@ -0,0 +1,29 @@
1#include <sys/ptrace.h>
2#include <stdarg.h>
3#include <unistd.h>
4#include "syscall.h"
5
6long ptrace(int req, ...)
7{
8 va_list ap;
9 pid_t pid;
10 void *addr, *data, *addr2 = 0;
11 long ret, result;
12
13 va_start(ap, req);
14 pid = va_arg(ap, pid_t);
15 addr = va_arg(ap, void *);
16 data = va_arg(ap, void *);
17 /* PTRACE_{READ,WRITE}{DATA,TEXT} (16...19) are specific to SPARC. */
18#ifdef PTRACE_READDATA
19 if ((unsigned)req - PTRACE_READDATA < 4)
20 addr2 = va_arg(ap, void *);
21#endif
22 va_end(ap);
23
24 if (req-1U < 3) data = &result;
25 ret = syscall(SYS_ptrace, req, pid, addr, data, addr2);
26
27 if (ret < 0 || req-1U >= 3) return ret;
28 return result;
29}
libc/musl/src/linux/quotactl.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/quota.h>
2#include "syscall.h"
3
4int quotactl(int cmd, const char *special, int id, char *addr)
5{
6 return syscall(SYS_quotactl, cmd, special, id, addr);
7}
libc/musl/src/linux/readahead.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include "syscall.h"
4
5ssize_t readahead(int fd, off_t pos, size_t len)
6{
7 return syscall(SYS_readahead, fd, __SYSCALL_LL_O(pos), len);
8}
libc/musl/src/linux/reboot.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/reboot.h>
2#include "syscall.h"
3
4int reboot(int type)
5{
6 return syscall(SYS_reboot, 0xfee1dead, 672274793, type);
7}
libc/musl/src/linux/remap_file_pages.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <sys/mman.h>
3#include "syscall.h"
4
5int remap_file_pages(void *addr, size_t size, int prot, size_t pgoff, int flags)
6{
7 return syscall(SYS_remap_file_pages, addr, size, prot, pgoff, flags);
8}
libc/musl/src/linux/sbrk.c created+11
......@@ -0,0 +1,11 @@
1#define _BSD_SOURCE
2#include <unistd.h>
3#include <stdint.h>
4#include <errno.h>
5#include "syscall.h"
6
7void *sbrk(intptr_t inc)
8{
9 if (inc) return (void *)__syscall_ret(-ENOMEM);
10 return (void *)__syscall(SYS_brk, 0);
11}
libc/musl/src/linux/sendfile.c created+9
......@@ -0,0 +1,9 @@
1#include <sys/sendfile.h>
2#include "syscall.h"
3
4ssize_t sendfile(int out_fd, int in_fd, off_t *ofs, size_t count)
5{
6 return syscall(SYS_sendfile, out_fd, in_fd, ofs, count);
7}
8
9weak_alias(sendfile, sendfile64);
libc/musl/src/linux/setfsgid.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/fsuid.h>
2#include "syscall.h"
3
4int setfsgid(gid_t gid)
5{
6 return syscall(SYS_setfsgid, gid);
7}
libc/musl/src/linux/setfsuid.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/fsuid.h>
2#include "syscall.h"
3
4int setfsuid(uid_t uid)
5{
6 return syscall(SYS_setfsuid, uid);
7}
libc/musl/src/linux/setgroups.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4
5int setgroups(size_t count, const gid_t list[])
6{
7 return syscall(SYS_setgroups, count, list);
8}
libc/musl/src/linux/sethostname.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4
5int sethostname(const char *name, size_t len)
6{
7 return syscall(SYS_sethostname, name, len);
8}
libc/musl/src/linux/setns.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <sched.h>
3#include "syscall.h"
4
5int setns(int fd, int nstype)
6{
7 return syscall(SYS_setns, fd, nstype);
8}
libc/musl/src/linux/settimeofday.c created+8
......@@ -0,0 +1,8 @@
1#define _BSD_SOURCE
2#include <sys/time.h>
3#include "syscall.h"
4
5int settimeofday(const struct timeval *tv, const struct timezone *tz)
6{
7 return syscall(SYS_settimeofday, tv, 0);
8}
libc/musl/src/linux/signalfd.c created+21
......@@ -0,0 +1,21 @@
1#include <sys/signalfd.h>
2#include <signal.h>
3#include <errno.h>
4#include <fcntl.h>
5#include "syscall.h"
6
7int signalfd(int fd, const sigset_t *sigs, int flags)
8{
9 int ret = __syscall(SYS_signalfd4, fd, sigs, _NSIG/8, flags);
10#ifdef SYS_signalfd
11 if (ret != -ENOSYS) return __syscall_ret(ret);
12 ret = __syscall(SYS_signalfd, fd, sigs, _NSIG/8);
13 if (ret >= 0) {
14 if (flags & SFD_CLOEXEC)
15 __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
16 if (flags & SFD_NONBLOCK)
17 __syscall(SYS_fcntl, ret, F_SETFL, O_NONBLOCK);
18 }
19#endif
20 return __syscall_ret(ret);
21}
libc/musl/src/linux/splice.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include "syscall.h"
4
5ssize_t splice(int fd_in, off_t *off_in, int fd_out, off_t *off_out, size_t len, unsigned flags)
6{
7 return syscall(SYS_splice, fd_in, off_in, fd_out, off_out, len, flags);
8}
libc/musl/src/linux/stime.c created+9
......@@ -0,0 +1,9 @@
1#define _GNU_SOURCE
2#include <time.h>
3#include <sys/time.h>
4
5int stime(const time_t *t)
6{
7 struct timeval tv = { .tv_sec = *t, .tv_usec = 0 };
8 return settimeofday(&tv, (void *)0);
9}
libc/musl/src/linux/swap.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/swap.h>
2#include "syscall.h"
3
4int swapon(const char *path, int flags)
5{
6 return syscall(SYS_swapon, path, flags);
7}
8
9int swapoff(const char *path)
10{
11 return syscall(SYS_swapoff, path);
12}
libc/musl/src/linux/sync_file_range.c created+17
......@@ -0,0 +1,17 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include <errno.h>
4#include "syscall.h"
5
6int sync_file_range(int fd, off_t pos, off_t len, unsigned flags)
7{
8#if defined(SYS_sync_file_range2)
9 return syscall(SYS_sync_file_range2, fd, flags,
10 __SYSCALL_LL_E(pos), __SYSCALL_LL_E(len));
11#elif defined(SYS_sync_file_range)
12 return syscall(SYS_sync_file_range, fd,
13 __SYSCALL_LL_O(pos), __SYSCALL_LL_E(len), flags);
14#else
15 return __syscall_ret(-ENOSYS);
16#endif
17}
libc/musl/src/linux/syncfs.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4
5int syncfs(int fd)
6{
7 return syscall(SYS_syncfs, fd);
8}
libc/musl/src/linux/sysinfo.c created+9
......@@ -0,0 +1,9 @@
1#include <sys/sysinfo.h>
2#include "syscall.h"
3
4int __lsysinfo(struct sysinfo *info)
5{
6 return syscall(SYS_sysinfo, info);
7}
8
9weak_alias(__lsysinfo, sysinfo);
libc/musl/src/linux/tee.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include "syscall.h"
4
5ssize_t tee(int src, int dest, size_t len, unsigned flags)
6{
7 return syscall(SYS_tee, src, dest, len, flags);
8}
libc/musl/src/linux/timerfd.c created+17
......@@ -0,0 +1,17 @@
1#include <sys/timerfd.h>
2#include "syscall.h"
3
4int timerfd_create(int clockid, int flags)
5{
6 return syscall(SYS_timerfd_create, clockid, flags);
7}
8
9int timerfd_settime(int fd, int flags, const struct itimerspec *new, struct itimerspec *old)
10{
11 return syscall(SYS_timerfd_settime, fd, flags, new, old);
12}
13
14int timerfd_gettime(int fd, struct itimerspec *cur)
15{
16 return syscall(SYS_timerfd_gettime, fd, cur);
17}
libc/musl/src/linux/unshare.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <sched.h>
3#include "syscall.h"
4
5int unshare(int flags)
6{
7 return syscall(SYS_unshare, flags);
8}
libc/musl/src/linux/utimes.c created+8
......@@ -0,0 +1,8 @@
1#include <sys/time.h>
2#include "fcntl.h"
3#include "syscall.h"
4
5int utimes(const char *path, const struct timeval times[2])
6{
7 return __futimesat(AT_FDCWD, path, times);
8}
libc/musl/src/linux/vhangup.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4
5int vhangup(void)
6{
7 return syscall(SYS_vhangup);
8}
libc/musl/src/linux/vmsplice.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include "syscall.h"
4
5ssize_t vmsplice(int fd, const struct iovec *iov, size_t cnt, unsigned flags)
6{
7 return syscall(SYS_vmsplice, fd, iov, cnt, flags);
8}
libc/musl/src/linux/wait3.c created+9
......@@ -0,0 +1,9 @@
1#define _GNU_SOURCE
2#include <sys/wait.h>
3#include <sys/resource.h>
4#include "syscall.h"
5
6pid_t wait3(int *status, int options, struct rusage *usage)
7{
8 return wait4(-1, status, options, usage);
9}
libc/musl/src/linux/wait4.c created+9
......@@ -0,0 +1,9 @@
1#define _GNU_SOURCE
2#include <sys/wait.h>
3#include <sys/resource.h>
4#include "syscall.h"
5
6pid_t wait4(pid_t pid, int *status, int options, struct rusage *usage)
7{
8 return syscall(SYS_wait4, pid, status, options, usage);
9}
libc/musl/src/linux/x32/sysinfo.c created+49
......@@ -0,0 +1,49 @@
1#include <sys/sysinfo.h>
2#include "syscall.h"
3
4#define klong long long
5#define kulong unsigned long long
6
7struct kernel_sysinfo {
8 klong uptime;
9 kulong loads[3];
10 kulong totalram;
11 kulong freeram;
12 kulong sharedram;
13 kulong bufferram;
14 kulong totalswap;
15 kulong freeswap;
16 short procs;
17 short pad;
18 kulong totalhigh;
19 kulong freehigh;
20 unsigned mem_unit;
21};
22
23int __lsysinfo(struct sysinfo *info)
24{
25 struct kernel_sysinfo tmp;
26 int ret = syscall(SYS_sysinfo, &tmp);
27 if(ret == -1) return ret;
28 info->uptime = tmp.uptime;
29 info->loads[0] = tmp.loads[0];
30 info->loads[1] = tmp.loads[1];
31 info->loads[2] = tmp.loads[2];
32 kulong shifts;
33 kulong max = tmp.totalram | tmp.totalswap;
34 __asm__("bsr %1,%0" : "=r"(shifts) : "r"(max));
35 shifts = shifts >= 32 ? shifts - 31 : 0;
36 info->totalram = tmp.totalram >> shifts;
37 info->freeram = tmp.freeram >> shifts;
38 info->sharedram = tmp.sharedram >> shifts;
39 info->bufferram = tmp.bufferram >> shifts;
40 info->totalswap = tmp.totalswap >> shifts;
41 info->freeswap = tmp.freeswap >> shifts;
42 info->procs = tmp.procs ;
43 info->totalhigh = tmp.totalhigh >> shifts;
44 info->freehigh = tmp.freehigh >> shifts;
45 info->mem_unit = (tmp.mem_unit ? tmp.mem_unit : 1) << shifts;
46 return ret;
47}
48
49weak_alias(__lsysinfo, sysinfo);
libc/musl/src/linux/xattr.c created+62
......@@ -0,0 +1,62 @@
1#include <sys/xattr.h>
2#include "syscall.h"
3
4ssize_t getxattr(const char *path, const char *name, void *value, size_t size)
5{
6 return syscall(SYS_getxattr, path, name, value, size);
7}
8
9ssize_t lgetxattr(const char *path, const char *name, void *value, size_t size)
10{
11 return syscall(SYS_lgetxattr, path, name, value, size);
12}
13
14ssize_t fgetxattr(int filedes, const char *name, void *value, size_t size)
15{
16 return syscall(SYS_fgetxattr, filedes, name, value, size);
17}
18
19ssize_t listxattr(const char *path, char *list, size_t size)
20{
21 return syscall(SYS_listxattr, path, list, size);
22}
23
24ssize_t llistxattr(const char *path, char *list, size_t size)
25{
26 return syscall(SYS_llistxattr, path, list, size);
27}
28
29ssize_t flistxattr(int filedes, char *list, size_t size)
30{
31 return syscall(SYS_flistxattr, filedes, list, size);
32}
33
34int setxattr(const char *path, const char *name, const void *value, size_t size, int flags)
35{
36 return syscall(SYS_setxattr, path, name, value, size, flags);
37}
38
39int lsetxattr(const char *path, const char *name, const void *value, size_t size, int flags)
40{
41 return syscall(SYS_lsetxattr, path, name, value, size, flags);
42}
43
44int fsetxattr(int filedes, const char *name, const void *value, size_t size, int flags)
45{
46 return syscall(SYS_fsetxattr, filedes, name, value, size, flags);
47}
48
49int removexattr(const char *path, const char *name)
50{
51 return syscall(SYS_removexattr, path, name);
52}
53
54int lremovexattr(const char *path, const char *name)
55{
56 return syscall(SYS_lremovexattr, path, name);
57}
58
59int fremovexattr(int fd, const char *name)
60{
61 return syscall(SYS_fremovexattr, fd, name);
62}
libc/musl/src/locale/__lctrans.c created+19
......@@ -0,0 +1,19 @@
1#include <locale.h>
2#include "locale_impl.h"
3
4static const char *dummy(const char *msg, const struct __locale_map *lm)
5{
6 return msg;
7}
8
9weak_alias(dummy, __lctrans_impl);
10
11const char *__lctrans(const char *msg, const struct __locale_map *lm)
12{
13 return __lctrans_impl(msg, lm);
14}
15
16const char *__lctrans_cur(const char *msg)
17{
18 return __lctrans_impl(msg, CURRENT_LOCALE->cat[LC_MESSAGES]);
19}
libc/musl/src/locale/__mo_lookup.c created+42
......@@ -0,0 +1,42 @@
1#include <stdint.h>
2#include <string.h>
3
4static inline uint32_t swapc(uint32_t x, int c)
5{
6 return c ? x>>24 | x>>8&0xff00 | x<<8&0xff0000 | x<<24 : x;
7}
8
9const char *__mo_lookup(const void *p, size_t size, const char *s)
10{
11 const uint32_t *mo = p;
12 int sw = *mo - 0x950412de;
13 uint32_t b = 0, n = swapc(mo[2], sw);
14 uint32_t o = swapc(mo[3], sw);
15 uint32_t t = swapc(mo[4], sw);
16 if (n>=size/4 || o>=size-4*n || t>=size-4*n || ((o|t)%4))
17 return 0;
18 o/=4;
19 t/=4;
20 for (;;) {
21 uint32_t ol = swapc(mo[o+2*(b+n/2)], sw);
22 uint32_t os = swapc(mo[o+2*(b+n/2)+1], sw);
23 if (os >= size || ol >= size-os || ((char *)p)[os+ol])
24 return 0;
25 int sign = strcmp(s, (char *)p + os);
26 if (!sign) {
27 uint32_t tl = swapc(mo[t+2*(b+n/2)], sw);
28 uint32_t ts = swapc(mo[t+2*(b+n/2)+1], sw);
29 if (ts >= size || tl >= size-ts || ((char *)p)[ts+tl])
30 return 0;
31 return (char *)p + ts;
32 }
33 else if (n == 1) return 0;
34 else if (sign < 0)
35 n /= 2;
36 else {
37 b += n/2;
38 n -= n/2;
39 }
40 }
41 return 0;
42}
libc/musl/src/locale/big5.h created+1085
......@@ -0,0 +1,1085 @@
112288,65292,12289,12290,65294,8231,65307,65306,65311,65281,65072,8230,8229,
265104,65105,65106,183,65108,65109,65110,65111,65372,8211,65073,8212,65075,
39588,65076,65103,65288,65289,65077,65078,65371,65373,65079,65080,12308,12309,
465081,65082,12304,12305,65083,65084,12298,12299,65085,65086,12296,12297,65087,
565088,12300,12301,65089,65090,12302,12303,65091,65092,65113,65114,65115,65116,
665117,65118,8216,8217,8220,8221,12317,12318,8245,8242,65283,65286,65290,8251,
7167,12291,9675,9679,9651,9650,9678,9734,9733,9671,9670,9633,9632,9661,9660,
812963,8453,175,65507,65343,717,65097,65098,65101,65102,65099,65100,65119,
965120,65121,65291,65293,215,247,177,8730,65308,65310,65309,8806,8807,8800,
108734,8786,8801,65122,65123,65124,65125,65126,65374,8745,8746,8869,8736,8735,
118895,13266,13265,8747,8750,8757,8756,9792,9794,8853,8857,8593,8595,8592,8594,
128598,8599,8601,8600,8741,8739,65295,65340,8725,65128,65284,65509,12306,65504,
1365505,65285,65312,8451,8457,65129,65130,65131,13269,13212,13213,13214,13262,
1413217,13198,13199,13252,176,20825,20827,20830,20829,20833,20835,21991,29929,
1531950,9601,9602,9603,9604,9605,9606,9607,9608,9615,9614,9613,9612,9611,9610,
169609,9532,9524,9516,9508,9500,9620,9472,9474,9621,9484,9488,9492,9496,9581,
179582,9584,9583,9552,9566,9578,9569,9698,9699,9701,9700,9585,9586,9587,65296,
1865297,65298,65299,65300,65301,65302,65303,65304,65305,8544,8545,8546,8547,
198548,8549,8550,8551,8552,8553,12321,
2012322,12323,12324,12325,12326,12327,12328,12329,21313,21316,21317,65313,65314,
2165315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,
2265328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,65345,65346,
2365347,65348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,
2465360,65361,65362,65363,65364,65365,65366,65367,65368,65369,65370,913,914,915,
25916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,
26936,937,945,946,947,948,949,950,951,952,953,954,955,956,957,958,959,960,961,
27963,964,965,966,967,968,969,12549,12550,12551,12552,12553,12554,12555,12556,
2812557,12558,12559,12560,12561,12562,12563,12564,12565,12566,12567,12568,12569,
2912570,12571,12572,12573,12574,12575,12576,12577,12578,12579,12580,12581,12582,
3012583,12584,12585,729,713,714,711,715,9216,9217,9218,9219,9220,9221,9222,9223,
319224,9225,9226,9227,9228,9229,9230,9231,9232,9233,9234,9235,9236,9237,9238,
329239,9240,9241,9242,9243,9244,9245,9246,9247,9249,8364,0,0,0,0,0,0,0,0,0,0,0,
330,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,19968,20057,19969,19971,20035,20061,20102,
3420108,20154,20799,20837,20843,20960,20992,20993,21147,21269,21313,21340,21448,
3519977,19979,19976,19978,20011,20024,20961,20037,20040,20063,20062,20110,20129,
3620800,20995,21242,21315,21449,21475,22303,
3722763,22805,22823,22899,23376,23377,23379,23544,23567,23586,23608,23665,24029,
3824037,24049,24050,24051,24062,24178,24318,24331,24339,25165,19985,19984,19981,
3920013,20016,20025,20043,23609,20104,20113,20117,20114,20116,20130,20161,20160,
4020163,20166,20167,20173,20170,20171,20164,20803,20801,20839,20845,20846,20844,
4120887,20982,20998,20999,21000,21243,21246,21247,21270,21305,21320,21319,21317,
4221342,21380,21451,21450,21453,22764,22825,22827,22826,22829,23380,23569,23588,
4323610,23663,24052,24187,24319,24340,24341,24515,25096,25142,25163,25166,25903,
4425991,26007,26020,26041,26085,26352,26376,26408,27424,27490,27513,27595,27604,
4527611,27663,27700,28779,29226,29238,29243,29255,29273,29275,29356,29579,19993,
4619990,19989,19988,19992,20027,20045,20047,20046,20197,20184,20180,20181,20182,
4720183,20195,20196,20185,20190,20805,20804,20873,20874,20908,20985,20986,20984,
4821002,21152,21151,21253,21254,21271,21277,20191,21322,21321,21345,21344,21359,
4921358,21435,21487,21476,21491,21484,21486,21481,21480,21500,21496,21493,21483,
5021478,21482,21490,21489,21488,21477,21485,21499,22235,22234,22806,22830,22833,
5122900,22902,23381,23427,23612,24040,24039,24038,24066,24067,24179,24188,24321,
5224344,24343,24517,25098,25171,25172,25170,25169,26021,26086,26414,26412,26410,
5326411,26413,27491,27597,27665,27664,27704,27713,27712,27710,29359,29572,29577,
5429916,29926,29976,29983,29992,29993,30000,30001,30002,30003,30091,30333,30382,
5530399,30446,30683,30690,30707,31034,31166,31348,31435,19998,19999,20050,20051,
5620073,20121,20132,20134,20133,20223,20233,20249,20234,
5720245,20237,20240,20241,20239,20210,20214,20219,20208,20211,20221,20225,20235,
5820809,20807,20806,20808,20840,20849,20877,20912,21015,21009,21010,21006,21014,
5921155,21256,21281,21280,21360,21361,21513,21519,21516,21514,21520,21505,21515,
6021508,21521,21517,21512,21507,21518,21510,21522,22240,22238,22237,22323,22320,
6122312,22317,22316,22319,22313,22809,22810,22839,22840,22916,22904,22915,22909,
6222905,22914,22913,23383,23384,23431,23432,23429,23433,23546,23574,23673,24030,
6324070,24182,24180,24335,24347,24537,24534,25102,25100,25101,25104,25187,25179,
6425176,25910,26089,26088,26092,26093,26354,26355,26377,26429,26420,26417,26421,
6527425,27492,27515,27670,27741,27735,27737,27743,27744,27728,27733,27745,27739,
6627725,27726,28784,29279,29277,30334,31481,31859,31992,32566,32650,32701,32769,
6732771,32780,32786,32819,32895,32905,32907,32908,33251,33258,33267,33276,33292,
6833307,33311,33390,33394,33406,34411,34880,34892,34915,35199,38433,20018,20136,
6920301,20303,20295,20311,20318,20276,20315,20309,20272,20304,20305,20285,20282,
7020280,20291,20308,20284,20294,20323,20316,20320,20271,20302,20278,20313,20317,
7120296,20314,20812,20811,20813,20853,20918,20919,21029,21028,21033,21034,21032,
7221163,21161,21162,21164,21283,21363,21365,21533,21549,21534,21566,21542,21582,
7321543,21574,21571,21555,21576,21570,21531,21545,21578,21561,21563,21560,21550,
7421557,21558,21536,21564,21568,21553,21547,21535,21548,22250,22256,22244,22251,
7522346,22353,22336,22349,22343,22350,22334,22352,22351,22331,22767,22846,22941,
7622930,22952,22942,22947,22937,22934,22925,22948,22931,
7722922,22949,23389,23388,23386,23387,23436,23435,23439,23596,23616,23617,23615,
7823614,23696,23697,23700,23692,24043,24076,24207,24199,24202,24311,24324,24351,
7924420,24418,24439,24441,24536,24524,24535,24525,24561,24555,24568,24554,25106,
8025105,25220,25239,25238,25216,25206,25225,25197,25226,25212,25214,25209,25203,
8125234,25199,25240,25198,25237,25235,25233,25222,25913,25915,25912,26097,26356,
8226463,26446,26447,26448,26449,26460,26454,26462,26441,26438,26464,26451,26455,
8327493,27599,27714,27742,27801,27777,27784,27785,27781,27803,27754,27770,27792,
8427760,27788,27752,27798,27794,27773,27779,27762,27774,27764,27782,27766,27789,
8527796,27800,27778,28790,28796,28797,28792,29282,29281,29280,29380,29378,29590,
8629996,29995,30007,30008,30338,30447,30691,31169,31168,31167,31350,31995,32597,
8732918,32915,32925,32920,32923,32922,32946,33391,33426,33419,33421,35211,35282,
8835328,35895,35910,35925,35997,36196,36208,36275,36523,36554,36763,36784,36802,
8936806,36805,36804,24033,37009,37026,37034,37030,37027,37193,37318,37324,38450,
9038446,38449,38442,38444,20006,20054,20083,20107,20123,20126,20139,20140,20335,
9120381,20365,20339,20351,20332,20379,20363,20358,20355,20336,20341,20360,20329,
9220347,20374,20350,20367,20369,20346,20820,20818,20821,20841,20855,20854,20856,
9320925,20989,21051,21048,21047,21050,21040,21038,21046,21057,21182,21179,21330,
9421332,21331,21329,21350,21367,21368,21369,21462,21460,21463,21619,21621,21654,
9521624,21653,21632,21627,21623,21636,21650,21638,21628,21648,21617,21622,21644,
9621658,21602,21608,21643,21629,21646,22266,22403,22391,
9722378,22377,22369,22374,22372,22396,22812,22857,22855,22856,22852,22868,22974,
9822971,22996,22969,22958,22993,22982,22992,22989,22987,22995,22986,22959,22963,
9922994,22981,23391,23396,23395,23447,23450,23448,23452,23449,23451,23578,23624,
10023621,23622,23735,23713,23736,23721,23723,23729,23731,24088,24090,24086,24085,
10124091,24081,24184,24218,24215,24220,24213,24214,24310,24358,24359,24361,24448,
10224449,24447,24444,24541,24544,24573,24565,24575,24591,24596,24623,24629,24598,
10324618,24597,24609,24615,24617,24619,24603,25110,25109,25151,25150,25152,25215,
10425289,25292,25284,25279,25282,25273,25298,25307,25259,25299,25300,25291,25288,
10525256,25277,25276,25296,25305,25287,25293,25269,25306,25265,25304,25302,25303,
10625286,25260,25294,25918,26023,26044,26106,26132,26131,26124,26118,26114,26126,
10726112,26127,26133,26122,26119,26381,26379,26477,26507,26517,26481,26524,26483,
10826487,26503,26525,26519,26479,26480,26495,26505,26494,26512,26485,26522,26515,
10926492,26474,26482,27427,27494,27495,27519,27667,27675,27875,27880,27891,27825,
11027852,27877,27827,27837,27838,27836,27874,27819,27861,27859,27832,27844,27833,
11127841,27822,27863,27845,27889,27839,27835,27873,27867,27850,27820,27887,27868,
11227862,27872,28821,28814,28818,28810,28825,29228,29229,29240,29256,29287,29289,
11329376,29390,29401,29399,29392,29609,29608,29599,29611,29605,30013,30109,30105,
11430106,30340,30402,30450,30452,30693,30717,31038,31040,31041,31177,31176,31354,
11531353,31482,31998,32596,32652,32651,32773,32954,32933,32930,32945,32929,32939,
11632937,32948,32938,32943,33253,33278,33293,33459,33437,
11733433,33453,33469,33439,33465,33457,33452,33445,33455,33464,33443,33456,33470,
11833463,34382,34417,21021,34920,36555,36814,36820,36817,37045,37048,37041,37046,
11937319,37329,38263,38272,38428,38464,38463,38459,38468,38466,38585,38632,38738,
12038750,20127,20141,20142,20449,20405,20399,20415,20448,20433,20431,20445,20419,
12120406,20440,20447,20426,20439,20398,20432,20420,20418,20442,20430,20446,20407,
12220823,20882,20881,20896,21070,21059,21066,21069,21068,21067,21063,21191,21193,
12321187,21185,21261,21335,21371,21402,21467,21676,21696,21672,21710,21705,21688,
12421670,21683,21703,21698,21693,21674,21697,21700,21704,21679,21675,21681,21691,
12521673,21671,21695,22271,22402,22411,22432,22435,22434,22478,22446,22419,22869,
12622865,22863,22862,22864,23004,23000,23039,23011,23016,23043,23013,23018,23002,
12723014,23041,23035,23401,23459,23462,23460,23458,23461,23553,23630,23631,23629,
12823627,23769,23762,24055,24093,24101,24095,24189,24224,24230,24314,24328,24365,
12924421,24456,24453,24458,24459,24455,24460,24457,24594,24605,24608,24613,24590,
13024616,24653,24688,24680,24674,24646,24643,24684,24683,24682,24676,25153,25308,
13125366,25353,25340,25325,25345,25326,25341,25351,25329,25335,25327,25324,25342,
13225332,25361,25346,25919,25925,26027,26045,26082,26149,26157,26144,26151,26159,
13326143,26152,26161,26148,26359,26623,26579,26609,26580,26576,26604,26550,26543,
13426613,26601,26607,26564,26577,26548,26586,26597,26552,26575,26590,26611,26544,
13526585,26594,26589,26578,27498,27523,27526,27573,27602,27607,27679,27849,27915,
13627954,27946,27969,27941,27916,27953,27934,27927,27963,
13727965,27966,27958,27931,27893,27961,27943,27960,27945,27950,27957,27918,27947,
13828843,28858,28851,28844,28847,28845,28856,28846,28836,29232,29298,29295,29300,
13929417,29408,29409,29623,29642,29627,29618,29645,29632,29619,29978,29997,30031,
14030028,30030,30027,30123,30116,30117,30114,30115,30328,30342,30343,30344,30408,
14130406,30403,30405,30465,30457,30456,30473,30475,30462,30460,30471,30684,30722,
14230740,30732,30733,31046,31049,31048,31047,31161,31162,31185,31186,31179,31359,
14331361,31487,31485,31869,32002,32005,32000,32009,32007,32004,32006,32568,32654,
14432703,32772,32784,32781,32785,32822,32982,32997,32986,32963,32964,32972,32993,
14532987,32974,32990,32996,32989,33268,33314,33511,33539,33541,33507,33499,33510,
14633540,33509,33538,33545,33490,33495,33521,33537,33500,33492,33489,33502,33491,
14733503,33519,33542,34384,34425,34427,34426,34893,34923,35201,35284,35336,35330,
14835331,35998,36000,36212,36211,36276,36557,36556,36848,36838,36834,36842,36837,
14936845,36843,36836,36840,37066,37070,37057,37059,37195,37194,37325,38274,38480,
15038475,38476,38477,38754,38761,38859,38893,38899,38913,39080,39131,39135,39318,
15139321,20056,20147,20492,20493,20515,20463,20518,20517,20472,20521,20502,20486,
15220540,20511,20506,20498,20497,20474,20480,20500,20520,20465,20513,20491,20505,
15320504,20467,20462,20525,20522,20478,20523,20489,20860,20900,20901,20898,20941,
15420940,20934,20939,21078,21084,21076,21083,21085,21290,21375,21407,21405,21471,
15521736,21776,21761,21815,21756,21733,21746,21766,21754,21780,21737,21741,21729,
15621769,21742,21738,21734,21799,21767,21757,21775,22275,
15722276,22466,22484,22475,22467,22537,22799,22871,22872,22874,23057,23064,23068,
15823071,23067,23059,23020,23072,23075,23081,23077,23052,23049,23403,23640,23472,
15923475,23478,23476,23470,23477,23481,23480,23556,23633,23637,23632,23789,23805,
16023803,23786,23784,23792,23798,23809,23796,24046,24109,24107,24235,24237,24231,
16124369,24466,24465,24464,24665,24675,24677,24656,24661,24685,24681,24687,24708,
16224735,24730,24717,24724,24716,24709,24726,25159,25331,25352,25343,25422,25406,
16325391,25429,25410,25414,25423,25417,25402,25424,25405,25386,25387,25384,25421,
16425420,25928,25929,26009,26049,26053,26178,26185,26191,26179,26194,26188,26181,
16526177,26360,26388,26389,26391,26657,26680,26696,26694,26707,26681,26690,26708,
16626665,26803,26647,26700,26705,26685,26612,26704,26688,26684,26691,26666,26693,
16726643,26648,26689,27530,27529,27575,27683,27687,27688,27686,27684,27888,28010,
16828053,28040,28039,28006,28024,28023,27993,28051,28012,28041,28014,27994,28020,
16928009,28044,28042,28025,28037,28005,28052,28874,28888,28900,28889,28872,28879,
17029241,29305,29436,29433,29437,29432,29431,29574,29677,29705,29678,29664,29674,
17129662,30036,30045,30044,30042,30041,30142,30149,30151,30130,30131,30141,30140,
17230137,30146,30136,30347,30384,30410,30413,30414,30505,30495,30496,30504,30697,
17330768,30759,30776,30749,30772,30775,30757,30765,30752,30751,30770,31061,31056,
17431072,31071,31062,31070,31069,31063,31066,31204,31203,31207,31199,31206,31209,
17531192,31364,31368,31449,31494,31505,31881,32033,32023,32011,32010,32032,32034,
17632020,32016,32021,32026,32028,32013,32025,32027,32570,
17732607,32660,32709,32705,32774,32792,32789,32793,32791,32829,32831,33009,33026,
17833008,33029,33005,33012,33030,33016,33011,33032,33021,33034,33020,33007,33261,
17933260,33280,33296,33322,33323,33320,33324,33467,33579,33618,33620,33610,33592,
18033616,33609,33589,33588,33615,33586,33593,33590,33559,33600,33585,33576,33603,
18134388,34442,34474,34451,34468,34473,34444,34467,34460,34928,34935,34945,34946,
18234941,34937,35352,35344,35342,35340,35349,35338,35351,35347,35350,35343,35345,
18335912,35962,35961,36001,36002,36215,36524,36562,36564,36559,36785,36865,36870,
18436855,36864,36858,36852,36867,36861,36869,36856,37013,37089,37085,37090,37202,
18537197,37196,37336,37341,37335,37340,37337,38275,38498,38499,38497,38491,38493,
18638500,38488,38494,38587,39138,39340,39592,39640,39717,39730,39740,20094,20602,
18720605,20572,20551,20547,20556,20570,20553,20581,20598,20558,20565,20597,20596,
18820599,20559,20495,20591,20589,20828,20885,20976,21098,21103,21202,21209,21208,
18921205,21264,21263,21273,21311,21312,21310,21443,26364,21830,21866,21862,21828,
19021854,21857,21827,21834,21809,21846,21839,21845,21807,21860,21816,21806,21852,
19121804,21859,21811,21825,21847,22280,22283,22281,22495,22533,22538,22534,22496,
19222500,22522,22530,22581,22519,22521,22816,22882,23094,23105,23113,23142,23146,
19323104,23100,23138,23130,23110,23114,23408,23495,23493,23492,23490,23487,23494,
19423561,23560,23559,23648,23644,23645,23815,23814,23822,23835,23830,23842,23825,
19523849,23828,23833,23844,23847,23831,24034,24120,24118,24115,24119,24247,24248,
19624246,24245,24254,24373,24375,24407,24428,24425,24427,
19724471,24473,24478,24472,24481,24480,24476,24703,24739,24713,24736,24744,24779,
19824756,24806,24765,24773,24763,24757,24796,24764,24792,24789,24774,24799,24760,
19924794,24775,25114,25115,25160,25504,25511,25458,25494,25506,25509,25463,25447,
20025496,25514,25457,25513,25481,25475,25499,25451,25512,25476,25480,25497,25505,
20125516,25490,25487,25472,25467,25449,25448,25466,25949,25942,25937,25945,25943,
20221855,25935,25944,25941,25940,26012,26011,26028,26063,26059,26060,26062,26205,
20326202,26212,26216,26214,26206,26361,21207,26395,26753,26799,26786,26771,26805,
20426751,26742,26801,26791,26775,26800,26755,26820,26797,26758,26757,26772,26781,
20526792,26783,26785,26754,27442,27578,27627,27628,27691,28046,28092,28147,28121,
20628082,28129,28108,28132,28155,28154,28165,28103,28107,28079,28113,28078,28126,
20728153,28088,28151,28149,28101,28114,28186,28085,28122,28139,28120,28138,28145,
20828142,28136,28102,28100,28074,28140,28095,28134,28921,28937,28938,28925,28911,
20929245,29309,29313,29468,29467,29462,29459,29465,29575,29701,29706,29699,29702,
21029694,29709,29920,29942,29943,29980,29986,30053,30054,30050,30064,30095,30164,
21130165,30133,30154,30157,30350,30420,30418,30427,30519,30526,30524,30518,30520,
21230522,30827,30787,30798,31077,31080,31085,31227,31378,31381,31520,31528,31515,
21331532,31526,31513,31518,31534,31890,31895,31893,32070,32067,32113,32046,32057,
21432060,32064,32048,32051,32068,32047,32066,32050,32049,32573,32670,32666,32716,
21532718,32722,32796,32842,32838,33071,33046,33059,33067,33065,33072,33060,33282,
21633333,33335,33334,33337,33678,33694,33688,33656,33698,
21733686,33725,33707,33682,33674,33683,33673,33696,33655,33659,33660,33670,33703,
21834389,24426,34503,34496,34486,34500,34485,34502,34507,34481,34479,34505,34899,
21934974,34952,34987,34962,34966,34957,34955,35219,35215,35370,35357,35363,35365,
22035377,35373,35359,35355,35362,35913,35930,36009,36012,36011,36008,36010,36007,
22136199,36198,36286,36282,36571,36575,36889,36877,36890,36887,36899,36895,36893,
22236880,36885,36894,36896,36879,36898,36886,36891,36884,37096,37101,37117,37207,
22337326,37365,37350,37347,37351,37357,37353,38281,38506,38517,38515,38520,38512,
22438516,38518,38519,38508,38592,38634,38633,31456,31455,38914,38915,39770,40165,
22540565,40575,40613,40635,20642,20621,20613,20633,20625,20608,20630,20632,20634,
22626368,20977,21106,21108,21109,21097,21214,21213,21211,21338,21413,21883,21888,
22721927,21884,21898,21917,21912,21890,21916,21930,21908,21895,21899,21891,21939,
22821934,21919,21822,21938,21914,21947,21932,21937,21886,21897,21931,21913,22285,
22922575,22570,22580,22564,22576,22577,22561,22557,22560,22777,22778,22880,23159,
23023194,23167,23186,23195,23207,23411,23409,23506,23500,23507,23504,23562,23563,
23123601,23884,23888,23860,23879,24061,24133,24125,24128,24131,24190,24266,24257,
23224258,24260,24380,24429,24489,24490,24488,24785,24801,24754,24758,24800,24860,
23324867,24826,24853,24816,24827,24820,24936,24817,24846,24822,24841,24832,24850,
23425119,25161,25507,25484,25551,25536,25577,25545,25542,25549,25554,25571,25552,
23525569,25558,25581,25582,25462,25588,25578,25563,25682,25562,25593,25950,25958,
23625954,25955,26001,26000,26031,26222,26224,26228,26230,
23726223,26257,26234,26238,26231,26366,26367,26399,26397,26874,26837,26848,26840,
23826839,26885,26847,26869,26862,26855,26873,26834,26866,26851,26827,26829,26893,
23926898,26894,26825,26842,26990,26875,27454,27450,27453,27544,27542,27580,27631,
24027694,27695,27692,28207,28216,28244,28193,28210,28263,28234,28192,28197,28195,
24128187,28251,28248,28196,28246,28270,28205,28198,28271,28212,28237,28218,28204,
24228227,28189,28222,28363,28297,28185,28238,28259,28228,28274,28265,28255,28953,
24328954,28966,28976,28961,28982,29038,28956,29260,29316,29312,29494,29477,29492,
24429481,29754,29738,29747,29730,29733,29749,29750,29748,29743,29723,29734,29736,
24529989,29990,30059,30058,30178,30171,30179,30169,30168,30174,30176,30331,30332,
24630358,30355,30388,30428,30543,30701,30813,30828,30831,31245,31240,31243,31237,
24731232,31384,31383,31382,31461,31459,31561,31574,31558,31568,31570,31572,31565,
24831563,31567,31569,31903,31909,32094,32080,32104,32085,32043,32110,32114,32097,
24932102,32098,32112,32115,21892,32724,32725,32779,32850,32901,33109,33108,33099,
25033105,33102,33081,33094,33086,33100,33107,33140,33298,33308,33769,33795,33784,
25133805,33760,33733,33803,33729,33775,33777,33780,33879,33802,33776,33804,33740,
25233789,33778,33738,33848,33806,33796,33756,33799,33748,33759,34395,34527,34521,
25334541,34516,34523,34532,34512,34526,34903,35009,35010,34993,35203,35222,35387,
25435424,35413,35422,35388,35393,35412,35419,35408,35398,35380,35386,35382,35414,
25535937,35970,36015,36028,36019,36029,36033,36027,36032,36020,36023,36022,36031,
25636024,36234,36229,36225,36302,36317,36299,36314,36305,
25736300,36315,36294,36603,36600,36604,36764,36910,36917,36913,36920,36914,36918,
25837122,37109,37129,37118,37219,37221,37327,37396,37397,37411,37385,37406,37389,
25937392,37383,37393,38292,38287,38283,38289,38291,38290,38286,38538,38542,38539,
26038525,38533,38534,38541,38514,38532,38593,38597,38596,38598,38599,38639,38642,
26138860,38917,38918,38920,39143,39146,39151,39145,39154,39149,39342,39341,40643,
26240653,40657,20098,20653,20661,20658,20659,20677,20670,20652,20663,20667,20655,
26320679,21119,21111,21117,21215,21222,21220,21218,21219,21295,21983,21992,21971,
26421990,21966,21980,21959,21969,21987,21988,21999,21978,21985,21957,21958,21989,
26521961,22290,22291,22622,22609,22616,22615,22618,22612,22635,22604,22637,22602,
26622626,22610,22603,22887,23233,23241,23244,23230,23229,23228,23219,23234,23218,
26723913,23919,24140,24185,24265,24264,24338,24409,24492,24494,24858,24847,24904,
26824863,24819,24859,24825,24833,24840,24910,24908,24900,24909,24894,24884,24871,
26924845,24838,24887,25121,25122,25619,25662,25630,25642,25645,25661,25644,25615,
27025628,25620,25613,25654,25622,25623,25606,25964,26015,26032,26263,26249,26247,
27126248,26262,26244,26264,26253,26371,27028,26989,26970,26999,26976,26964,26997,
27226928,27010,26954,26984,26987,26974,26963,27001,27014,26973,26979,26971,27463,
27327506,27584,27583,27603,27645,28322,28335,28371,28342,28354,28304,28317,28359,
27428357,28325,28312,28348,28346,28331,28369,28310,28316,28356,28372,28330,28327,
27528340,29006,29017,29033,29028,29001,29031,29020,29036,29030,29004,29029,29022,
27628998,29032,29014,29242,29266,29495,29509,29503,29502,
27729807,29786,29781,29791,29790,29761,29759,29785,29787,29788,30070,30072,30208,
27830192,30209,30194,30193,30202,30207,30196,30195,30430,30431,30555,30571,30566,
27930558,30563,30585,30570,30572,30556,30565,30568,30562,30702,30862,30896,30871,
28030872,30860,30857,30844,30865,30867,30847,31098,31103,31105,33836,31165,31260,
28131258,31264,31252,31263,31262,31391,31392,31607,31680,31584,31598,31591,31921,
28231923,31925,32147,32121,32145,32129,32143,32091,32622,32617,32618,32626,32681,
28332680,32676,32854,32856,32902,32900,33137,33136,33144,33125,33134,33139,33131,
28433145,33146,33126,33285,33351,33922,33911,33853,33841,33909,33894,33899,33865,
28533900,33883,33852,33845,33889,33891,33897,33901,33862,34398,34396,34399,34553,
28634579,34568,34567,34560,34558,34555,34562,34563,34566,34570,34905,35039,35028,
28735033,35036,35032,35037,35041,35018,35029,35026,35228,35299,35435,35442,35443,
28835430,35433,35440,35463,35452,35427,35488,35441,35461,35437,35426,35438,35436,
28935449,35451,35390,35432,35938,35978,35977,36042,36039,36040,36036,36018,36035,
29036034,36037,36321,36319,36328,36335,36339,36346,36330,36324,36326,36530,36611,
29136617,36606,36618,36767,36786,36939,36938,36947,36930,36948,36924,36949,36944,
29236935,36943,36942,36941,36945,36926,36929,37138,37143,37228,37226,37225,37321,
29337431,37463,37432,37437,37440,37438,37467,37451,37476,37457,37428,37449,37453,
29437445,37433,37439,37466,38296,38552,38548,38549,38605,38603,38601,38602,38647,
29538651,38649,38646,38742,38772,38774,38928,38929,38931,38922,38930,38924,39164,
29639156,39165,39166,39347,39345,39348,39649,40169,40578,
29740718,40723,40736,20711,20718,20709,20694,20717,20698,20693,20687,20689,20721,
29820686,20713,20834,20979,21123,21122,21297,21421,22014,22016,22043,22039,22013,
29922036,22022,22025,22029,22030,22007,22038,22047,22024,22032,22006,22296,22294,
30022645,22654,22659,22675,22666,22649,22661,22653,22781,22821,22818,22820,22890,
30122889,23265,23270,23273,23255,23254,23256,23267,23413,23518,23527,23521,23525,
30223526,23528,23522,23524,23519,23565,23650,23940,23943,24155,24163,24149,24151,
30324148,24275,24278,24330,24390,24432,24505,24903,24895,24907,24951,24930,24931,
30424927,24922,24920,24949,25130,25735,25688,25684,25764,25720,25695,25722,25681,
30525703,25652,25709,25723,25970,26017,26071,26070,26274,26280,26269,27036,27048,
30627029,27073,27054,27091,27083,27035,27063,27067,27051,27060,27088,27085,27053,
30727084,27046,27075,27043,27465,27468,27699,28467,28436,28414,28435,28404,28457,
30828478,28448,28460,28431,28418,28450,28415,28399,28422,28465,28472,28466,28451,
30928437,28459,28463,28552,28458,28396,28417,28402,28364,28407,29076,29081,29053,
31029066,29060,29074,29246,29330,29334,29508,29520,29796,29795,29802,29808,29805,
31129956,30097,30247,30221,30219,30217,30227,30433,30435,30596,30589,30591,30561,
31230913,30879,30887,30899,30889,30883,31118,31119,31117,31278,31281,31402,31401,
31331469,31471,31649,31637,31627,31605,31639,31645,31636,31631,31672,31623,31620,
31431929,31933,31934,32187,32176,32156,32189,32190,32160,32202,32180,32178,32177,
31532186,32162,32191,32181,32184,32173,32210,32199,32172,32624,32736,32737,32735,
31632862,32858,32903,33104,33152,33167,33160,33162,33151,
31733154,33255,33274,33287,33300,33310,33355,33993,33983,33990,33988,33945,33950,
31833970,33948,33995,33976,33984,34003,33936,33980,34001,33994,34623,34588,34619,
31934594,34597,34612,34584,34645,34615,34601,35059,35074,35060,35065,35064,35069,
32035048,35098,35055,35494,35468,35486,35491,35469,35489,35475,35492,35498,35493,
32135496,35480,35473,35482,35495,35946,35981,35980,36051,36049,36050,36203,36249,
32236245,36348,36628,36626,36629,36627,36771,36960,36952,36956,36963,36953,36958,
32336962,36957,36955,37145,37144,37150,37237,37240,37239,37236,37496,37504,37509,
32437528,37526,37499,37523,37532,37544,37500,37521,38305,38312,38313,38307,38309,
32538308,38553,38556,38555,38604,38610,38656,38780,38789,38902,38935,38936,39087,
32639089,39171,39173,39180,39177,39361,39599,39600,39654,39745,39746,40180,40182,
32740179,40636,40763,40778,20740,20736,20731,20725,20729,20738,20744,20745,20741,
32820956,21127,21128,21129,21133,21130,21232,21426,22062,22075,22073,22066,22079,
32922068,22057,22099,22094,22103,22132,22070,22063,22064,22656,22687,22686,22707,
33022684,22702,22697,22694,22893,23305,23291,23307,23285,23308,23304,23534,23532,
33123529,23531,23652,23653,23965,23956,24162,24159,24161,24290,24282,24287,24285,
33224291,24288,24392,24433,24503,24501,24950,24935,24942,24925,24917,24962,24956,
33324944,24939,24958,24999,24976,25003,24974,25004,24986,24996,24980,25006,25134,
33425705,25711,25721,25758,25778,25736,25744,25776,25765,25747,25749,25769,25746,
33525774,25773,25771,25754,25772,25753,25762,25779,25973,25975,25976,26286,26283,
33626292,26289,27171,27167,27112,27137,27166,27161,27133,
33727169,27155,27146,27123,27138,27141,27117,27153,27472,27470,27556,27589,27590,
33828479,28540,28548,28497,28518,28500,28550,28525,28507,28536,28526,28558,28538,
33928528,28516,28567,28504,28373,28527,28512,28511,29087,29100,29105,29096,29270,
34029339,29518,29527,29801,29835,29827,29822,29824,30079,30240,30249,30239,30244,
34130246,30241,30242,30362,30394,30436,30606,30599,30604,30609,30603,30923,30917,
34230906,30922,30910,30933,30908,30928,31295,31292,31296,31293,31287,31291,31407,
34331406,31661,31665,31684,31668,31686,31687,31681,31648,31692,31946,32224,32244,
34432239,32251,32216,32236,32221,32232,32227,32218,32222,32233,32158,32217,32242,
34532249,32629,32631,32687,32745,32806,33179,33180,33181,33184,33178,33176,34071,
34634109,34074,34030,34092,34093,34067,34065,34083,34081,34068,34028,34085,34047,
34734054,34690,34676,34678,34656,34662,34680,34664,34649,34647,34636,34643,34907,
34834909,35088,35079,35090,35091,35093,35082,35516,35538,35527,35524,35477,35531,
34935576,35506,35529,35522,35519,35504,35542,35533,35510,35513,35547,35916,35918,
35035948,36064,36062,36070,36068,36076,36077,36066,36067,36060,36074,36065,36205,
35136255,36259,36395,36368,36381,36386,36367,36393,36383,36385,36382,36538,36637,
35236635,36639,36649,36646,36650,36636,36638,36645,36969,36974,36968,36973,36983,
35337168,37165,37159,37169,37255,37257,37259,37251,37573,37563,37559,37610,37548,
35437604,37569,37555,37564,37586,37575,37616,37554,38317,38321,38660,38662,38663,
35538665,38752,38797,38795,38799,38945,38955,38940,39091,39178,39187,39186,39192,
35639389,39376,39391,39387,39377,39381,39378,39385,39607,
35739662,39663,39719,39749,39748,39799,39791,40198,40201,40195,40617,40638,40654,
35822696,40786,20754,20760,20756,20752,20757,20864,20906,20957,21137,21139,21235,
35922105,22123,22137,22121,22116,22136,22122,22120,22117,22129,22127,22124,22114,
36022134,22721,22718,22727,22725,22894,23325,23348,23416,23536,23566,24394,25010,
36124977,25001,24970,25037,25014,25022,25034,25032,25136,25797,25793,25803,25787,
36225788,25818,25796,25799,25794,25805,25791,25810,25812,25790,25972,26310,26313,
36326297,26308,26311,26296,27197,27192,27194,27225,27243,27224,27193,27204,27234,
36427233,27211,27207,27189,27231,27208,27481,27511,27653,28610,28593,28577,28611,
36528580,28609,28583,28595,28608,28601,28598,28582,28576,28596,29118,29129,29136,
36629138,29128,29141,29113,29134,29145,29148,29123,29124,29544,29852,29859,29848,
36729855,29854,29922,29964,29965,30260,30264,30266,30439,30437,30624,30622,30623,
36830629,30952,30938,30956,30951,31142,31309,31310,31302,31308,31307,31418,31705,
36931761,31689,31716,31707,31713,31721,31718,31957,31958,32266,32273,32264,32283,
37032291,32286,32285,32265,32272,32633,32690,32752,32753,32750,32808,33203,33193,
37133192,33275,33288,33368,33369,34122,34137,34120,34152,34153,34115,34121,34157,
37234154,34142,34691,34719,34718,34722,34701,34913,35114,35122,35109,35115,35105,
37335242,35238,35558,35578,35563,35569,35584,35548,35559,35566,35582,35585,35586,
37435575,35565,35571,35574,35580,35947,35949,35987,36084,36420,36401,36404,36418,
37536409,36405,36667,36655,36664,36659,36776,36774,36981,36980,36984,36978,36988,
37636986,37172,37266,37664,37686,37624,37683,37679,37666,
37737628,37675,37636,37658,37648,37670,37665,37653,37678,37657,38331,38567,38568,
37838570,38613,38670,38673,38678,38669,38675,38671,38747,38748,38758,38808,38960,
37938968,38971,38967,38957,38969,38948,39184,39208,39198,39195,39201,39194,39405,
38039394,39409,39608,39612,39675,39661,39720,39825,40213,40227,40230,40232,40210,
38140219,40664,40660,40845,40860,20778,20767,20769,20786,21237,22158,22144,22160,
38222149,22151,22159,22741,22739,22737,22734,23344,23338,23332,23418,23607,23656,
38323996,23994,23997,23992,24171,24396,24509,25033,25026,25031,25062,25035,25138,
38425140,25806,25802,25816,25824,25840,25830,25836,25841,25826,25837,25986,25987,
38526329,26326,27264,27284,27268,27298,27292,27355,27299,27262,27287,27280,27296,
38627484,27566,27610,27656,28632,28657,28639,28640,28635,28644,28651,28655,28544,
38728652,28641,28649,28629,28654,28656,29159,29151,29166,29158,29157,29165,29164,
38829172,29152,29237,29254,29552,29554,29865,29872,29862,29864,30278,30274,30284,
38930442,30643,30634,30640,30636,30631,30637,30703,30967,30970,30964,30959,30977,
39031143,31146,31319,31423,31751,31757,31742,31735,31756,31712,31968,31964,31966,
39131970,31967,31961,31965,32302,32318,32326,32311,32306,32323,32299,32317,32305,
39232325,32321,32308,32313,32328,32309,32319,32303,32580,32755,32764,32881,32882,
39332880,32879,32883,33222,33219,33210,33218,33216,33215,33213,33225,33214,33256,
39433289,33393,34218,34180,34174,34204,34193,34196,34223,34203,34183,34216,34186,
39534407,34752,34769,34739,34770,34758,34731,34747,34746,34760,34763,35131,35126,
39635140,35128,35133,35244,35598,35607,35609,35611,35594,
39735616,35613,35588,35600,35905,35903,35955,36090,36093,36092,36088,36091,36264,
39836425,36427,36424,36426,36676,36670,36674,36677,36671,36991,36989,36996,36993,
39936994,36992,37177,37283,37278,37276,37709,37762,37672,37749,37706,37733,37707,
40037656,37758,37740,37723,37744,37722,37716,38346,38347,38348,38344,38342,38577,
40138584,38614,38684,38686,38816,38867,38982,39094,39221,39425,39423,39854,39851,
40239850,39853,40251,40255,40587,40655,40670,40668,40669,40667,40766,40779,21474,
40322165,22190,22745,22744,23352,24413,25059,25139,25844,25842,25854,25862,25850,
40425851,25847,26039,26332,26406,27315,27308,27331,27323,27320,27330,27310,27311,
40527487,27512,27567,28681,28683,28670,28678,28666,28689,28687,29179,29180,29182,
40629176,29559,29557,29863,29887,29973,30294,30296,30290,30653,30655,30651,30652,
40730990,31150,31329,31330,31328,31428,31429,31787,31783,31786,31774,31779,31777,
40831975,32340,32341,32350,32346,32353,32338,32345,32584,32761,32763,32887,32886,
40933229,33231,33290,34255,34217,34253,34256,34249,34224,34234,34233,34214,34799,
41034796,34802,34784,35206,35250,35316,35624,35641,35628,35627,35920,36101,36441,
41136451,36454,36452,36447,36437,36544,36681,36685,36999,36995,37000,37291,37292,
41237328,37780,37770,37782,37794,37811,37806,37804,37808,37784,37786,37783,38356,
41338358,38352,38357,38626,38620,38617,38619,38622,38692,38819,38822,38829,38905,
41438989,38991,38988,38990,38995,39098,39230,39231,39229,39214,39333,39438,39617,
41539683,39686,39759,39758,39757,39882,39881,39933,39880,39872,40273,40285,40288,
41640672,40725,40748,20787,22181,22750,22751,22754,23541,
41740848,24300,25074,25079,25078,25077,25856,25871,26336,26333,27365,27357,27354,
41827347,28699,28703,28712,28698,28701,28693,28696,29190,29197,29272,29346,29560,
41929562,29885,29898,29923,30087,30086,30303,30305,30663,31001,31153,31339,31337,
42031806,31807,31800,31805,31799,31808,32363,32365,32377,32361,32362,32645,32371,
42132694,32697,32696,33240,34281,34269,34282,34261,34276,34277,34295,34811,34821,
42234829,34809,34814,35168,35167,35158,35166,35649,35676,35672,35657,35674,35662,
42335663,35654,35673,36104,36106,36476,36466,36487,36470,36460,36474,36468,36692,
42436686,36781,37002,37003,37297,37294,37857,37841,37855,37827,37832,37852,37853,
42537846,37858,37837,37848,37860,37847,37864,38364,38580,38627,38698,38695,38753,
42638876,38907,39006,39000,39003,39100,39237,39241,39446,39449,39693,39912,39911,
42739894,39899,40329,40289,40306,40298,40300,40594,40599,40595,40628,21240,22184,
42822199,22198,22196,22204,22756,23360,23363,23421,23542,24009,25080,25082,25880,
42925876,25881,26342,26407,27372,28734,28720,28722,29200,29563,29903,30306,30309,
43031014,31018,31020,31019,31431,31478,31820,31811,31821,31983,31984,36782,32381,
43132380,32386,32588,32768,33242,33382,34299,34297,34321,34298,34310,34315,34311,
43234314,34836,34837,35172,35258,35320,35696,35692,35686,35695,35679,35691,36111,
43336109,36489,36481,36485,36482,37300,37323,37912,37891,37885,38369,38704,39108,
43439250,39249,39336,39467,39472,39479,39477,39955,39949,40569,40629,40680,40751,
43540799,40803,40801,20791,20792,22209,22208,22210,22804,23660,24013,25084,25086,
43625885,25884,26005,26345,27387,27396,27386,27570,28748,
43729211,29351,29910,29908,30313,30675,31824,32399,32396,32700,34327,34349,34330,
43834851,34850,34849,34847,35178,35180,35261,35700,35703,35709,36115,36490,36493,
43936491,36703,36783,37306,37934,37939,37941,37946,37944,37938,37931,38370,38712,
44038713,38706,38911,39015,39013,39255,39493,39491,39488,39486,39631,39764,39761,
44139981,39973,40367,40372,40386,40376,40605,40687,40729,40796,40806,40807,20796,
44220795,22216,22218,22217,23423,24020,24018,24398,25087,25892,27402,27489,28753,
44328760,29568,29924,30090,30318,30316,31155,31840,31839,32894,32893,33247,35186,
44435183,35324,35712,36118,36119,36497,36499,36705,37192,37956,37969,37970,38717,
44538718,38851,38849,39019,39253,39509,39501,39634,39706,40009,39985,39998,39995,
44640403,40407,40756,40812,40810,40852,22220,24022,25088,25891,25899,25898,26348,
44727408,29914,31434,31844,31843,31845,32403,32406,32404,33250,34360,34367,34865,
44835722,37008,37007,37987,37984,37988,38760,39023,39260,39514,39515,39511,39635,
44939636,39633,40020,40023,40022,40421,40607,40692,22225,22761,25900,28766,30321,
45030322,30679,32592,32648,34870,34873,34914,35731,35730,35734,33399,36123,37312,
45137994,38722,38728,38724,38854,39024,39519,39714,39768,40031,40441,40442,40572,
45240573,40711,40823,40818,24307,27414,28771,31852,31854,34875,35264,36513,37313,
45338002,38000,39025,39262,39638,39715,40652,28772,30682,35738,38007,38857,39522,
45439525,32412,35740,36522,37317,38013,38014,38012,40055,40056,40695,35924,38015,
45540474,29224,39530,39729,40475,40478,31858,9312,9313,9314,9315,9316,9317,9318,
4569319,9320,9321,9332,9333,9334,9335,9336,
4579337,9338,9339,9340,9341,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,
45820022,20031,20101,20128,20866,20886,20907,21241,21304,21353,21430,22794,23424,
45924027,24186,24191,24308,24400,24417,25908,26080,30098,30326,36789,38582,168,
460710,12541,12542,12445,12446,0,0,12293,12294,12295,12540,65339,65341,10045,
46112353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,
46212366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,
46312379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,
46412392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,
46512405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,
46612418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,
46712431,12432,12433,12434,12435,12449,12450,12451,12452,12453,12454,12455,12456,
46812457,12458,12459,12460,12461,12462,12463,12464,12465,12466,12467,12468,12469,
46912470,12471,12472,12473,12474,12475,12476,12477,12478,12479,12480,12481,12482,
47012483,12484,12485,12486,12487,12488,12489,12490,12491,12492,12493,12494,12495,
47112496,12497,12498,12499,12500,12501,12502,12503,12504,12505,12506,12507,12508,
47212509,12510,12511,12512,12513,12514,12515,12516,12517,12518,12519,12520,12521,
47312522,12523,12524,12525,12526,12527,12528,12529,12530,12531,12532,12533,12534,
4741040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,
4751054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,
4761069,1070,
4771071,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,
4781085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,
4791100,1101,1102,1103,8679,8632,8633,12751,204,20058,138,20994,17553,40880,
48020872,40881,30215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
4810,0,0,0,0,0,0,0,0,0,65506,65508,65287,65282,12849,8470,8481,12443,12444,11904,
48211908,11910,11911,11912,11914,11916,11917,11925,11932,11933,11941,11943,11946,
48311948,11950,11958,11964,11966,11974,11978,11980,11981,11983,11990,11991,11998,
48412003,0,0,0,643,592,603,596,629,339,248,331,650,618,20034,20060,20981,21274,
48521378,19975,19980,20039,20109,22231,64012,23662,24435,19983,20871,19982,20014,
48620115,20162,20169,20168,20888,21244,21356,21433,22304,22787,22828,23568,24063,
48726081,27571,27596,27668,29247,20017,20028,20200,20188,20201,20193,20189,20186,
48821004,21276,21324,22306,22307,22807,22831,23425,23428,23570,23611,23668,23667,
48924068,24192,24194,24521,25097,25168,27669,27702,27715,27711,27707,29358,29360,
49029578,31160,32906,38430,20238,20248,20268,20213,20244,20209,20224,20215,20232,
49120253,20226,20229,20258,20243,20228,20212,20242,20913,21011,21001,21008,21158,
49221282,21279,21325,21386,21511,22241,22239,22318,22314,22324,22844,22912,22908,
49322917,22907,22910,22903,22911,23382,23573,23589,23676,23674,23675,
49423678,24031,24181,24196,24322,24346,24436,24533,24532,24527,25180,25182,25188,
49525185,25190,25186,25177,25184,25178,25189,26095,26094,26430,26425,26424,26427,
49626426,26431,26428,26419,27672,27718,27730,27740,27727,27722,27732,27723,27724,
49728785,29278,29364,29365,29582,29994,30335,31349,32593,33400,33404,33408,33405,
49833407,34381,35198,37017,37015,37016,37019,37012,38434,38436,38432,38435,20310,
49920283,20322,20297,20307,20324,20286,20327,20306,20319,20289,20312,20269,20275,
50020287,20321,20879,20921,21020,21022,21025,21165,21166,21257,21347,21362,21390,
50121391,21552,21559,21546,21588,21573,21529,21532,21541,21528,21565,21583,21569,
50221544,21540,21575,22254,22247,22245,22337,22341,22348,22345,22347,22354,22790,
50322848,22950,22936,22944,22935,22926,22946,22928,22927,22951,22945,23438,23442,
50423592,23594,23693,23695,23688,23691,23689,23698,23690,23686,23699,23701,24032,
50524074,24078,24203,24201,24204,24200,24205,24325,24349,24440,24438,24530,24529,
50624528,24557,24552,24558,24563,24545,24548,24547,24570,24559,24567,24571,24576,
50724564,25146,25219,25228,25230,25231,25236,25223,25201,25211,25210,25200,25217,
50825224,25207,25213,25202,25204,25911,26096,26100,26099,26098,26101,26437,26439,
50926457,26453,26444,26440,26461,26445,26458,26443,27600,27673,27674,27768,27751,
51027755,27780,27787,27791,27761,27759,27753,27802,27757,27783,27797,27804,27750,
51127763,27749,27771,27790,28788,28794,29283,29375,29373,29379,29382,29377,29370,
51229381,29589,29591,29587,29588,29586,30010,30009,30100,30101,30337,31037,32820,
51332917,32921,32912,32914,32924,33424,33423,33413,33422,
51433425,33427,33418,33411,33412,35960,36809,36799,37023,37025,37029,37022,37031,
51537024,38448,38440,38447,38445,20019,20376,20348,20357,20349,20352,20359,20342,
51620340,20361,20356,20343,20300,20375,20330,20378,20345,20353,20344,20368,20380,
51720372,20382,20370,20354,20373,20331,20334,20894,20924,20926,21045,21042,21043,
51821062,21041,21180,21258,21259,21308,21394,21396,21639,21631,21633,21649,21634,
51921640,21611,21626,21630,21605,21612,21620,21606,21645,21615,21601,21600,21656,
52021603,21607,21604,22263,22265,22383,22386,22381,22379,22385,22384,22390,22400,
52122389,22395,22387,22388,22370,22376,22397,22796,22853,22965,22970,22991,22990,
52222962,22988,22977,22966,22972,22979,22998,22961,22973,22976,22984,22964,22983,
52323394,23397,23443,23445,23620,23623,23726,23716,23712,23733,23727,23720,23724,
52423711,23715,23725,23714,23722,23719,23709,23717,23734,23728,23718,24087,24084,
52524089,24360,24354,24355,24356,24404,24450,24446,24445,24542,24549,24621,24614,
52624601,24626,24587,24628,24586,24599,24627,24602,24606,24620,24610,24589,24592,
52724622,24595,24593,24588,24585,24604,25108,25149,25261,25268,25297,25278,25258,
52825270,25290,25262,25267,25263,25275,25257,25264,25272,25917,26024,26043,26121,
52926108,26116,26130,26120,26107,26115,26123,26125,26117,26109,26129,26128,26358,
53026378,26501,26476,26510,26514,26486,26491,26520,26502,26500,26484,26509,26508,
53126490,26527,26513,26521,26499,26493,26497,26488,26489,26516,27429,27520,27518,
53227614,27677,27795,27884,27883,27886,27865,27830,27860,27821,27879,27831,27856,
53327842,27834,27843,27846,27885,27890,27858,27869,27828,
53427786,27805,27776,27870,27840,27952,27853,27847,27824,27897,27855,27881,27857,
53528820,28824,28805,28819,28806,28804,28817,28822,28802,28826,28803,29290,29398,
53629387,29400,29385,29404,29394,29396,29402,29388,29393,29604,29601,29613,29606,
53729602,29600,29612,29597,29917,29928,30015,30016,30014,30092,30104,30383,30451,
53830449,30448,30453,30712,30716,30713,30715,30714,30711,31042,31039,31173,31352,
53931355,31483,31861,31997,32821,32911,32942,32931,32952,32949,32941,33312,33440,
54033472,33451,33434,33432,33435,33461,33447,33454,33468,33438,33466,33460,33448,
54133441,33449,33474,33444,33475,33462,33442,34416,34415,34413,34414,35926,36818,
54236811,36819,36813,36822,36821,36823,37042,37044,37039,37043,37040,38457,38461,
54338460,38458,38467,20429,20421,20435,20402,20425,20427,20417,20436,20444,20441,
54420411,20403,20443,20423,20438,20410,20416,20409,20460,21060,21065,21184,21186,
54521309,21372,21399,21398,21401,21400,21690,21665,21677,21669,21711,21699,33549,
54621687,21678,21718,21686,21701,21702,21664,21616,21692,21666,21694,21618,21726,
54721680,22453,22430,22431,22436,22412,22423,22429,22427,22420,22424,22415,22425,
54822437,22426,22421,22772,22797,22867,23009,23006,23022,23040,23025,23005,23034,
54923037,23036,23030,23012,23026,23031,23003,23017,23027,23029,23008,23038,23028,
55023021,23464,23628,23760,23768,23756,23767,23755,23771,23774,23770,23753,23751,
55123754,23766,23763,23764,23759,23752,23750,23758,23775,23800,24057,24097,24098,
55224099,24096,24100,24240,24228,24226,24219,24227,24229,24327,24366,24406,24454,
55324631,24633,24660,24690,24670,24645,24659,24647,24649,
55424667,24652,24640,24642,24671,24612,24644,24664,24678,24686,25154,25155,25295,
55525357,25355,25333,25358,25347,25323,25337,25359,25356,25336,25334,25344,25363,
55625364,25338,25365,25339,25328,25921,25923,26026,26047,26166,26145,26162,26165,
55726140,26150,26146,26163,26155,26170,26141,26164,26169,26158,26383,26384,26561,
55826610,26568,26554,26588,26555,26616,26584,26560,26551,26565,26603,26596,26591,
55926549,26573,26547,26615,26614,26606,26595,26562,26553,26574,26599,26608,26546,
56026620,26566,26605,26572,26542,26598,26587,26618,26569,26570,26563,26602,26571,
56127432,27522,27524,27574,27606,27608,27616,27680,27681,27944,27956,27949,27935,
56227964,27967,27922,27914,27866,27955,27908,27929,27962,27930,27921,27904,27933,
56327970,27905,27928,27959,27907,27919,27968,27911,27936,27948,27912,27938,27913,
56427920,28855,28831,28862,28849,28848,28833,28852,28853,28841,29249,29257,29258,
56529292,29296,29299,29294,29386,29412,29416,29419,29407,29418,29414,29411,29573,
56629644,29634,29640,29637,29625,29622,29621,29620,29675,29631,29639,29630,29635,
56729638,29624,29643,29932,29934,29998,30023,30024,30119,30122,30329,30404,30472,
56830467,30468,30469,30474,30455,30459,30458,30695,30696,30726,30737,30738,30725,
56930736,30735,30734,30729,30723,30739,31050,31052,31051,31045,31044,31189,31181,
57031183,31190,31182,31360,31358,31441,31488,31489,31866,31864,31865,31871,31872,
57131873,32003,32008,32001,32600,32657,32653,32702,32775,32782,32783,32788,32823,
57232984,32967,32992,32977,32968,32962,32976,32965,32995,32985,32988,32970,32981,
57332969,32975,32983,32998,32973,33279,33313,33428,33497,
57433534,33529,33543,33512,33536,33493,33594,33515,33494,33524,33516,33505,33522,
57533525,33548,33531,33526,33520,33514,33508,33504,33530,33523,33517,34423,34420,
57634428,34419,34881,34894,34919,34922,34921,35283,35332,35335,36210,36835,36833,
57736846,36832,37105,37053,37055,37077,37061,37054,37063,37067,37064,37332,37331,
57838484,38479,38481,38483,38474,38478,20510,20485,20487,20499,20514,20528,20507,
57920469,20468,20531,20535,20524,20470,20471,20503,20508,20512,20519,20533,20527,
58020529,20494,20826,20884,20883,20938,20932,20933,20936,20942,21089,21082,21074,
58121086,21087,21077,21090,21197,21262,21406,21798,21730,21783,21778,21735,21747,
58221732,21786,21759,21764,21768,21739,21777,21765,21745,21770,21755,21751,21752,
58321728,21774,21763,21771,22273,22274,22476,22578,22485,22482,22458,22470,22461,
58422460,22456,22454,22463,22471,22480,22457,22465,22798,22858,23065,23062,23085,
58523086,23061,23055,23063,23050,23070,23091,23404,23463,23469,23468,23555,23638,
58623636,23788,23807,23790,23793,23799,23808,23801,24105,24104,24232,24238,24234,
58724236,24371,24368,24423,24669,24666,24679,24641,24738,24712,24704,24722,24705,
58824733,24707,24725,24731,24727,24711,24732,24718,25113,25158,25330,25360,25430,
58925388,25412,25413,25398,25411,25572,25401,25419,25418,25404,25385,25409,25396,
59025432,25428,25433,25389,25415,25395,25434,25425,25400,25431,25408,25416,25930,
59125926,26054,26051,26052,26050,26186,26207,26183,26193,26386,26387,26655,26650,
59226697,26674,26675,26683,26699,26703,26646,26673,26652,26677,26667,26669,26671,
59326702,26692,26676,26653,26642,26644,26662,26664,26670,
59426701,26682,26661,26656,27436,27439,27437,27441,27444,27501,32898,27528,27622,
59527620,27624,27619,27618,27623,27685,28026,28003,28004,28022,27917,28001,28050,
59627992,28002,28013,28015,28049,28045,28143,28031,28038,27998,28007,28000,28055,
59728016,28028,27999,28034,28056,27951,28008,28043,28030,28032,28036,27926,28035,
59828027,28029,28021,28048,28892,28883,28881,28893,28875,32569,28898,28887,28882,
59928894,28896,28884,28877,28869,28870,28871,28890,28878,28897,29250,29304,29303,
60029302,29440,29434,29428,29438,29430,29427,29435,29441,29651,29657,29669,29654,
60129628,29671,29667,29673,29660,29650,29659,29652,29661,29658,29655,29656,29672,
60229918,29919,29940,29941,29985,30043,30047,30128,30145,30139,30148,30144,30143,
60330134,30138,30346,30409,30493,30491,30480,30483,30482,30499,30481,30485,30489,
60430490,30498,30503,30755,30764,30754,30773,30767,30760,30766,30763,30753,30761,
60530771,30762,30769,31060,31067,31055,31068,31059,31058,31057,31211,31212,31200,
60631214,31213,31210,31196,31198,31197,31366,31369,31365,31371,31372,31370,31367,
60731448,31504,31492,31507,31493,31503,31496,31498,31502,31497,31506,31876,31889,
60831882,31884,31880,31885,31877,32030,32029,32017,32014,32024,32022,32019,32031,
60932018,32015,32012,32604,32609,32606,32608,32605,32603,32662,32658,32707,32706,
61032704,32790,32830,32825,33018,33010,33017,33013,33025,33019,33024,33281,33327,
61133317,33587,33581,33604,33561,33617,33573,33622,33599,33601,33574,33564,33570,
61233602,33614,33563,33578,33544,33596,33613,33558,33572,33568,33591,33583,33577,
61333607,33605,33612,33619,33566,33580,33611,33575,33608,
61434387,34386,34466,34472,34454,34445,34449,34462,34439,34455,34438,34443,34458,
61534437,34469,34457,34465,34471,34453,34456,34446,34461,34448,34452,34883,34884,
61634925,34933,34934,34930,34944,34929,34943,34927,34947,34942,34932,34940,35346,
61735911,35927,35963,36004,36003,36214,36216,36277,36279,36278,36561,36563,36862,
61836853,36866,36863,36859,36868,36860,36854,37078,37088,37081,37082,37091,37087,
61937093,37080,37083,37079,37084,37092,37200,37198,37199,37333,37346,37338,38492,
62038495,38588,39139,39647,39727,20095,20592,20586,20577,20574,20576,20563,20555,
62120573,20594,20552,20557,20545,20571,20554,20578,20501,20549,20575,20585,20587,
62220579,20580,20550,20544,20590,20595,20567,20561,20944,21099,21101,21100,21102,
62321206,21203,21293,21404,21877,21878,21820,21837,21840,21812,21802,21841,21858,
62421814,21813,21808,21842,21829,21772,21810,21861,21838,21817,21832,21805,21819,
62521824,21835,22282,22279,22523,22548,22498,22518,22492,22516,22528,22509,22525,
62622536,22520,22539,22515,22479,22535,22510,22499,22514,22501,22508,22497,22542,
62722524,22544,22503,22529,22540,22513,22505,22512,22541,22532,22876,23136,23128,
62823125,23143,23134,23096,23093,23149,23120,23135,23141,23148,23123,23140,23127,
62923107,23133,23122,23108,23131,23112,23182,23102,23117,23097,23116,23152,23145,
63023111,23121,23126,23106,23132,23410,23406,23489,23488,23641,23838,23819,23837,
63123834,23840,23820,23848,23821,23846,23845,23823,23856,23826,23843,23839,23854,
63224126,24116,24241,24244,24249,24242,24243,24374,24376,24475,24470,24479,24714,
63324720,24710,24766,24752,24762,24787,24788,24783,24804,
63424793,24797,24776,24753,24795,24759,24778,24767,24771,24781,24768,25394,25445,
63525482,25474,25469,25533,25502,25517,25501,25495,25515,25486,25455,25479,25488,
63625454,25519,25461,25500,25453,25518,25468,25508,25403,25503,25464,25477,25473,
63725489,25485,25456,25939,26061,26213,26209,26203,26201,26204,26210,26392,26745,
63826759,26768,26780,26733,26734,26798,26795,26966,26735,26787,26796,26793,26741,
63926740,26802,26767,26743,26770,26748,26731,26738,26794,26752,26737,26750,26779,
64026774,26763,26784,26761,26788,26744,26747,26769,26764,26762,26749,27446,27443,
64127447,27448,27537,27535,27533,27534,27532,27690,28096,28075,28084,28083,28276,
64228076,28137,28130,28087,28150,28116,28160,28104,28128,28127,28118,28094,28133,
64328124,28125,28123,28148,28106,28093,28141,28144,28090,28117,28098,28111,28105,
64428112,28146,28115,28157,28119,28109,28131,28091,28922,28941,28919,28951,28916,
64528940,28912,28932,28915,28944,28924,28927,28934,28947,28928,28920,28918,28939,
64628930,28942,29310,29307,29308,29311,29469,29463,29447,29457,29464,29450,29448,
64729439,29455,29470,29576,29686,29688,29685,29700,29697,29693,29703,29696,29690,
64829692,29695,29708,29707,29684,29704,30052,30051,30158,30162,30159,30155,30156,
64930161,30160,30351,30345,30419,30521,30511,30509,30513,30514,30516,30515,30525,
65030501,30523,30517,30792,30802,30793,30797,30794,30796,30758,30789,30800,31076,
65131079,31081,31082,31075,31083,31073,31163,31226,31224,31222,31223,31375,31380,
65231376,31541,31559,31540,31525,31536,31522,31524,31539,31512,31530,31517,31537,
65331531,31533,31535,31538,31544,31514,31523,31892,31896,
65431894,31907,32053,32061,32056,32054,32058,32069,32044,32041,32065,32071,32062,
65532063,32074,32059,32040,32611,32661,32668,32669,32667,32714,32715,32717,32720,
65632721,32711,32719,32713,32799,32798,32795,32839,32835,32840,33048,33061,33049,
65733051,33069,33055,33068,33054,33057,33045,33063,33053,33058,33297,33336,33331,
65833338,33332,33330,33396,33680,33699,33704,33677,33658,33651,33700,33652,33679,
65933665,33685,33689,33653,33684,33705,33661,33667,33676,33693,33691,33706,33675,
66033662,33701,33711,33672,33687,33712,33663,33702,33671,33710,33654,33690,34393,
66134390,34495,34487,34498,34497,34501,34490,34480,34504,34489,34483,34488,34508,
66234484,34491,34492,34499,34493,34494,34898,34953,34965,34984,34978,34986,34970,
66334961,34977,34975,34968,34983,34969,34971,34967,34980,34988,34956,34963,34958,
66435202,35286,35289,35285,35376,35367,35372,35358,35897,35899,35932,35933,35965,
66536005,36221,36219,36217,36284,36290,36281,36287,36289,36568,36574,36573,36572,
66636567,36576,36577,36900,36875,36881,36892,36876,36897,37103,37098,37104,37108,
66737106,37107,37076,37099,37100,37097,37206,37208,37210,37203,37205,37356,37364,
66837361,37363,37368,37348,37369,37354,37355,37367,37352,37358,38266,38278,38280,
66938524,38509,38507,38513,38511,38591,38762,38916,39141,39319,20635,20629,20628,
67020638,20619,20643,20611,20620,20622,20637,20584,20636,20626,20610,20615,20831,
67120948,21266,21265,21412,21415,21905,21928,21925,21933,21879,22085,21922,21907,
67221896,21903,21941,21889,21923,21906,21924,21885,21900,21926,21887,21909,21921,
67321902,22284,22569,22583,22553,22558,22567,22563,22568,
67422517,22600,22565,22556,22555,22579,22591,22582,22574,22585,22584,22573,22572,
67522587,22881,23215,23188,23199,23162,23202,23198,23160,23206,23164,23205,23212,
67623189,23214,23095,23172,23178,23191,23171,23179,23209,23163,23165,23180,23196,
67723183,23187,23197,23530,23501,23499,23508,23505,23498,23502,23564,23600,23863,
67823875,23915,23873,23883,23871,23861,23889,23886,23893,23859,23866,23890,23869,
67923857,23897,23874,23865,23881,23864,23868,23858,23862,23872,23877,24132,24129,
68024408,24486,24485,24491,24777,24761,24780,24802,24782,24772,24852,24818,24842,
68124854,24837,24821,24851,24824,24828,24830,24769,24835,24856,24861,24848,24831,
68224836,24843,25162,25492,25521,25520,25550,25573,25576,25583,25539,25757,25587,
68325546,25568,25590,25557,25586,25589,25697,25567,25534,25565,25564,25540,25560,
68425555,25538,25543,25548,25547,25544,25584,25559,25561,25906,25959,25962,25956,
68525948,25960,25957,25996,26013,26014,26030,26064,26066,26236,26220,26235,26240,
68626225,26233,26218,26226,26369,26892,26835,26884,26844,26922,26860,26858,26865,
68726895,26838,26871,26859,26852,26870,26899,26896,26867,26849,26887,26828,26888,
68826992,26804,26897,26863,26822,26900,26872,26832,26877,26876,26856,26891,26890,
68926903,26830,26824,26845,26846,26854,26868,26833,26886,26836,26857,26901,26917,
69026823,27449,27451,27455,27452,27540,27543,27545,27541,27581,27632,27634,27635,
69127696,28156,28230,28231,28191,28233,28296,28220,28221,28229,28258,28203,28223,
69228225,28253,28275,28188,28211,28235,28224,28241,28219,28163,28206,28254,28264,
69328252,28257,28209,28200,28256,28273,28267,28217,28194,
69428208,28243,28261,28199,28280,28260,28279,28245,28281,28242,28262,28213,28214,
69528250,28960,28958,28975,28923,28974,28977,28963,28965,28962,28978,28959,28968,
69628986,28955,29259,29274,29320,29321,29318,29317,29323,29458,29451,29488,29474,
69729489,29491,29479,29490,29485,29478,29475,29493,29452,29742,29740,29744,29739,
69829718,29722,29729,29741,29745,29732,29731,29725,29737,29728,29746,29947,29999,
69930063,30060,30183,30170,30177,30182,30173,30175,30180,30167,30357,30354,30426,
70030534,30535,30532,30541,30533,30538,30542,30539,30540,30686,30700,30816,30820,
70130821,30812,30829,30833,30826,30830,30832,30825,30824,30814,30818,31092,31091,
70231090,31088,31234,31242,31235,31244,31236,31385,31462,31460,31562,31547,31556,
70331560,31564,31566,31552,31576,31557,31906,31902,31912,31905,32088,32111,32099,
70432083,32086,32103,32106,32079,32109,32092,32107,32082,32084,32105,32081,32095,
70532078,32574,32575,32613,32614,32674,32672,32673,32727,32849,32847,32848,33022,
70632980,33091,33098,33106,33103,33095,33085,33101,33082,33254,33262,33271,33272,
70733273,33284,33340,33341,33343,33397,33595,33743,33785,33827,33728,33768,33810,
70833767,33764,33788,33782,33808,33734,33736,33771,33763,33727,33793,33757,33765,
70933752,33791,33761,33739,33742,33750,33781,33737,33801,33807,33758,33809,33798,
71033730,33779,33749,33786,33735,33745,33770,33811,33731,33772,33774,33732,33787,
71133751,33762,33819,33755,33790,34520,34530,34534,34515,34531,34522,34538,34525,
71234539,34524,34540,34537,34519,34536,34513,34888,34902,34901,35002,35031,35001,
71335000,35008,35006,34998,35004,34999,35005,34994,35073,
71435017,35221,35224,35223,35293,35290,35291,35406,35405,35385,35417,35392,35415,
71535416,35396,35397,35410,35400,35409,35402,35404,35407,35935,35969,35968,36026,
71636030,36016,36025,36021,36228,36224,36233,36312,36307,36301,36295,36310,36316,
71736303,36309,36313,36296,36311,36293,36591,36599,36602,36601,36582,36590,36581,
71836597,36583,36584,36598,36587,36593,36588,36596,36585,36909,36916,36911,37126,
71937164,37124,37119,37116,37128,37113,37115,37121,37120,37127,37125,37123,37217,
72037220,37215,37218,37216,37377,37386,37413,37379,37402,37414,37391,37388,37376,
72137394,37375,37373,37382,37380,37415,37378,37404,37412,37401,37399,37381,37398,
72238267,38285,38284,38288,38535,38526,38536,38537,38531,38528,38594,38600,38595,
72338641,38640,38764,38768,38766,38919,39081,39147,40166,40697,20099,20100,20150,
72420669,20671,20678,20654,20676,20682,20660,20680,20674,20656,20673,20666,20657,
72520683,20681,20662,20664,20951,21114,21112,21115,21116,21955,21979,21964,21968,
72621963,21962,21981,21952,21972,21956,21993,21951,21970,21901,21967,21973,21986,
72721974,21960,22002,21965,21977,21954,22292,22611,22632,22628,22607,22605,22601,
72822639,22613,22606,22621,22617,22629,22619,22589,22627,22641,22780,23239,23236,
72923243,23226,23224,23217,23221,23216,23231,23240,23227,23238,23223,23232,23242,
73023220,23222,23245,23225,23184,23510,23512,23513,23583,23603,23921,23907,23882,
73123909,23922,23916,23902,23912,23911,23906,24048,24143,24142,24138,24141,24139,
73224261,24268,24262,24267,24263,24384,24495,24493,24823,24905,24906,24875,24901,
73324886,24882,24878,24902,24879,24911,24873,24896,25120,
73437224,25123,25125,25124,25541,25585,25579,25616,25618,25609,25632,25636,25651,
73525667,25631,25621,25624,25657,25655,25634,25635,25612,25638,25648,25640,25665,
73625653,25647,25610,25626,25664,25637,25639,25611,25575,25627,25646,25633,25614,
73725967,26002,26067,26246,26252,26261,26256,26251,26250,26265,26260,26232,26400,
73826982,26975,26936,26958,26978,26993,26943,26949,26986,26937,26946,26967,26969,
73927002,26952,26953,26933,26988,26931,26941,26981,26864,27000,26932,26985,26944,
74026991,26948,26998,26968,26945,26996,26956,26939,26955,26935,26972,26959,26961,
74126930,26962,26927,27003,26940,27462,27461,27459,27458,27464,27457,27547,64013,
74227643,27644,27641,27639,27640,28315,28374,28360,28303,28352,28319,28307,28308,
74328320,28337,28345,28358,28370,28349,28353,28318,28361,28343,28336,28365,28326,
74428367,28338,28350,28355,28380,28376,28313,28306,28302,28301,28324,28321,28351,
74528339,28368,28362,28311,28334,28323,28999,29012,29010,29027,29024,28993,29021,
74629026,29042,29048,29034,29025,28994,29016,28995,29003,29040,29023,29008,29011,
74728996,29005,29018,29263,29325,29324,29329,29328,29326,29500,29506,29499,29498,
74829504,29514,29513,29764,29770,29771,29778,29777,29783,29760,29775,29776,29774,
74929762,29766,29773,29780,29921,29951,29950,29949,29981,30073,30071,27011,30191,
75030223,30211,30199,30206,30204,30201,30200,30224,30203,30198,30189,30197,30205,
75130361,30389,30429,30549,30559,30560,30546,30550,30554,30569,30567,30548,30553,
75230573,30688,30855,30874,30868,30863,30852,30869,30853,30854,30881,30851,30841,
75330873,30848,30870,30843,31100,31106,31101,31097,31249,
75431256,31257,31250,31255,31253,31266,31251,31259,31248,31395,31394,31390,31467,
75531590,31588,31597,31604,31593,31602,31589,31603,31601,31600,31585,31608,31606,
75631587,31922,31924,31919,32136,32134,32128,32141,32127,32133,32122,32142,32123,
75732131,32124,32140,32148,32132,32125,32146,32621,32619,32615,32616,32620,32678,
75832677,32679,32731,32732,32801,33124,33120,33143,33116,33129,33115,33122,33138,
75926401,33118,33142,33127,33135,33092,33121,33309,33353,33348,33344,33346,33349,
76034033,33855,33878,33910,33913,33935,33933,33893,33873,33856,33926,33895,33840,
76133869,33917,33882,33881,33908,33907,33885,34055,33886,33847,33850,33844,33914,
76233859,33912,33842,33861,33833,33753,33867,33839,33858,33837,33887,33904,33849,
76333870,33868,33874,33903,33989,33934,33851,33863,33846,33843,33896,33918,33860,
76433835,33888,33876,33902,33872,34571,34564,34551,34572,34554,34518,34549,34637,
76534552,34574,34569,34561,34550,34573,34565,35030,35019,35021,35022,35038,35035,
76635034,35020,35024,35205,35227,35295,35301,35300,35297,35296,35298,35292,35302,
76735446,35462,35455,35425,35391,35447,35458,35460,35445,35459,35457,35444,35450,
76835900,35915,35914,35941,35940,35942,35974,35972,35973,36044,36200,36201,36241,
76936236,36238,36239,36237,36243,36244,36240,36242,36336,36320,36332,36337,36334,
77036304,36329,36323,36322,36327,36338,36331,36340,36614,36607,36609,36608,36613,
77136615,36616,36610,36619,36946,36927,36932,36937,36925,37136,37133,37135,37137,
77237142,37140,37131,37134,37230,37231,37448,37458,37424,37434,37478,37427,37477,
77337470,37507,37422,37450,37446,37485,37484,37455,37472,
77437479,37487,37430,37473,37488,37425,37460,37475,37456,37490,37454,37459,37452,
77537462,37426,38303,38300,38302,38299,38546,38547,38545,38551,38606,38650,38653,
77638648,38645,38771,38775,38776,38770,38927,38925,38926,39084,39158,39161,39343,
77739346,39344,39349,39597,39595,39771,40170,40173,40167,40576,40701,20710,20692,
77820695,20712,20723,20699,20714,20701,20708,20691,20716,20720,20719,20707,20704,
77920952,21120,21121,21225,21227,21296,21420,22055,22037,22028,22034,22012,22031,
78022044,22017,22035,22018,22010,22045,22020,22015,22009,22665,22652,22672,22680,
78122662,22657,22655,22644,22667,22650,22663,22673,22670,22646,22658,22664,22651,
78222676,22671,22782,22891,23260,23278,23269,23253,23274,23258,23277,23275,23283,
78323266,23264,23259,23276,23262,23261,23257,23272,23263,23415,23520,23523,23651,
78423938,23936,23933,23942,23930,23937,23927,23946,23945,23944,23934,23932,23949,
78523929,23935,24152,24153,24147,24280,24273,24279,24270,24284,24277,24281,24274,
78624276,24388,24387,24431,24502,24876,24872,24897,24926,24945,24947,24914,24915,
78724946,24940,24960,24948,24916,24954,24923,24933,24891,24938,24929,24918,25129,
78825127,25131,25643,25677,25691,25693,25716,25718,25714,25715,25725,25717,25702,
78925766,25678,25730,25694,25692,25675,25683,25696,25680,25727,25663,25708,25707,
79025689,25701,25719,25971,26016,26273,26272,26271,26373,26372,26402,27057,27062,
79127081,27040,27086,27030,27056,27052,27068,27025,27033,27022,27047,27021,27049,
79227070,27055,27071,27076,27069,27044,27092,27065,27082,27034,27087,27059,27027,
79327050,27041,27038,27097,27031,27024,27074,27061,27045,
79427078,27466,27469,27467,27550,27551,27552,27587,27588,27646,28366,28405,28401,
79528419,28453,28408,28471,28411,28462,28425,28494,28441,28442,28455,28440,28475,
79628434,28397,28426,28470,28531,28409,28398,28461,28480,28464,28476,28469,28395,
79728423,28430,28483,28421,28413,28406,28473,28444,28412,28474,28447,28429,28446,
79828424,28449,29063,29072,29065,29056,29061,29058,29071,29051,29062,29057,29079,
79929252,29267,29335,29333,29331,29507,29517,29521,29516,29794,29811,29809,29813,
80029810,29799,29806,29952,29954,29955,30077,30096,30230,30216,30220,30229,30225,
80130218,30228,30392,30593,30588,30597,30594,30574,30592,30575,30590,30595,30898,
80230890,30900,30893,30888,30846,30891,30878,30885,30880,30892,30882,30884,31128,
80331114,31115,31126,31125,31124,31123,31127,31112,31122,31120,31275,31306,31280,
80431279,31272,31270,31400,31403,31404,31470,31624,31644,31626,31633,31632,31638,
80531629,31628,31643,31630,31621,31640,21124,31641,31652,31618,31931,31935,31932,
80631930,32167,32183,32194,32163,32170,32193,32192,32197,32157,32206,32196,32198,
80732203,32204,32175,32185,32150,32188,32159,32166,32174,32169,32161,32201,32627,
80832738,32739,32741,32734,32804,32861,32860,33161,33158,33155,33159,33165,33164,
80933163,33301,33943,33956,33953,33951,33978,33998,33986,33964,33966,33963,33977,
81033972,33985,33997,33962,33946,33969,34000,33949,33959,33979,33954,33940,33991,
81133996,33947,33961,33967,33960,34006,33944,33974,33999,33952,34007,34004,34002,
81234011,33968,33937,34401,34611,34595,34600,34667,34624,34606,34590,34593,34585,
81334587,34627,34604,34625,34622,34630,34592,34610,34602,
81434605,34620,34578,34618,34609,34613,34626,34598,34599,34616,34596,34586,34608,
81534577,35063,35047,35057,35058,35066,35070,35054,35068,35062,35067,35056,35052,
81635051,35229,35233,35231,35230,35305,35307,35304,35499,35481,35467,35474,35471,
81735478,35901,35944,35945,36053,36047,36055,36246,36361,36354,36351,36365,36349,
81836362,36355,36359,36358,36357,36350,36352,36356,36624,36625,36622,36621,37155,
81937148,37152,37154,37151,37149,37146,37156,37153,37147,37242,37234,37241,37235,
82037541,37540,37494,37531,37498,37536,37524,37546,37517,37542,37530,37547,37497,
82137527,37503,37539,37614,37518,37506,37525,37538,37501,37512,37537,37514,37510,
82237516,37529,37543,37502,37511,37545,37533,37515,37421,38558,38561,38655,38744,
82338781,38778,38782,38787,38784,38786,38779,38788,38785,38783,38862,38861,38934,
82439085,39086,39170,39168,39175,39325,39324,39363,39353,39355,39354,39362,39357,
82539367,39601,39651,39655,39742,39743,39776,39777,39775,40177,40178,40181,40615,
82620735,20739,20784,20728,20742,20743,20726,20734,20747,20748,20733,20746,21131,
82721132,21233,21231,22088,22082,22092,22069,22081,22090,22089,22086,22104,22106,
82822080,22067,22077,22060,22078,22072,22058,22074,22298,22699,22685,22705,22688,
82922691,22703,22700,22693,22689,22783,23295,23284,23293,23287,23286,23299,23288,
83023298,23289,23297,23303,23301,23311,23655,23961,23959,23967,23954,23970,23955,
83123957,23968,23964,23969,23962,23966,24169,24157,24160,24156,32243,24283,24286,
83224289,24393,24498,24971,24963,24953,25009,25008,24994,24969,24987,24979,25007,
83325005,24991,24978,25002,24993,24973,24934,25011,25133,
83425710,25712,25750,25760,25733,25751,25756,25743,25739,25738,25740,25763,25759,
83525704,25777,25752,25974,25978,25977,25979,26034,26035,26293,26288,26281,26290,
83626295,26282,26287,27136,27142,27159,27109,27128,27157,27121,27108,27168,27135,
83727116,27106,27163,27165,27134,27175,27122,27118,27156,27127,27111,27200,27144,
83827110,27131,27149,27132,27115,27145,27140,27160,27173,27151,27126,27174,27143,
83927124,27158,27473,27557,27555,27554,27558,27649,27648,27647,27650,28481,28454,
84028542,28551,28614,28562,28557,28553,28556,28514,28495,28549,28506,28566,28534,
84128524,28546,28501,28530,28498,28496,28503,28564,28563,28509,28416,28513,28523,
84228541,28519,28560,28499,28555,28521,28543,28565,28515,28535,28522,28539,29106,
84329103,29083,29104,29088,29082,29097,29109,29085,29093,29086,29092,29089,29098,
84429084,29095,29107,29336,29338,29528,29522,29534,29535,29536,29533,29531,29537,
84529530,29529,29538,29831,29833,29834,29830,29825,29821,29829,29832,29820,29817,
84629960,29959,30078,30245,30238,30233,30237,30236,30243,30234,30248,30235,30364,
84730365,30366,30363,30605,30607,30601,30600,30925,30907,30927,30924,30929,30926,
84830932,30920,30915,30916,30921,31130,31137,31136,31132,31138,31131,27510,31289,
84931410,31412,31411,31671,31691,31678,31660,31694,31663,31673,31690,31669,31941,
85031944,31948,31947,32247,32219,32234,32231,32215,32225,32259,32250,32230,32246,
85132241,32240,32238,32223,32630,32684,32688,32685,32749,32747,32746,32748,32742,
85232744,32868,32871,33187,33183,33182,33173,33186,33177,33175,33302,33359,33363,
85333362,33360,33358,33361,34084,34107,34063,34048,34089,
85434062,34057,34061,34079,34058,34087,34076,34043,34091,34042,34056,34060,34036,
85534090,34034,34069,34039,34027,34035,34044,34066,34026,34025,34070,34046,34088,
85634077,34094,34050,34045,34078,34038,34097,34086,34023,34024,34032,34031,34041,
85734072,34080,34096,34059,34073,34095,34402,34646,34659,34660,34679,34785,34675,
85834648,34644,34651,34642,34657,34650,34641,34654,34669,34666,34640,34638,34655,
85934653,34671,34668,34682,34670,34652,34661,34639,34683,34677,34658,34663,34665,
86034906,35077,35084,35092,35083,35095,35096,35097,35078,35094,35089,35086,35081,
86135234,35236,35235,35309,35312,35308,35535,35526,35512,35539,35537,35540,35541,
86235515,35543,35518,35520,35525,35544,35523,35514,35517,35545,35902,35917,35983,
86336069,36063,36057,36072,36058,36061,36071,36256,36252,36257,36251,36384,36387,
86436389,36388,36398,36373,36379,36374,36369,36377,36390,36391,36372,36370,36376,
86536371,36380,36375,36378,36652,36644,36632,36634,36640,36643,36630,36631,36979,
86636976,36975,36967,36971,37167,37163,37161,37162,37170,37158,37166,37253,37254,
86737258,37249,37250,37252,37248,37584,37571,37572,37568,37593,37558,37583,37617,
86837599,37592,37609,37591,37597,37580,37615,37570,37608,37578,37576,37582,37606,
86937581,37589,37577,37600,37598,37607,37585,37587,37557,37601,37574,37556,38268,
87038316,38315,38318,38320,38564,38562,38611,38661,38664,38658,38746,38794,38798,
87138792,38864,38863,38942,38941,38950,38953,38952,38944,38939,38951,39090,39176,
87239162,39185,39188,39190,39191,39189,39388,39373,39375,39379,39380,39374,39369,
87339382,39384,39371,39383,39372,39603,39660,39659,39667,
87439666,39665,39750,39747,39783,39796,39793,39782,39798,39797,39792,39784,39780,
87539788,40188,40186,40189,40191,40183,40199,40192,40185,40187,40200,40197,40196,
87640579,40659,40719,40720,20764,20755,20759,20762,20753,20958,21300,21473,22128,
87722112,22126,22131,22118,22115,22125,22130,22110,22135,22300,22299,22728,22717,
87822729,22719,22714,22722,22716,22726,23319,23321,23323,23329,23316,23315,23312,
87923318,23336,23322,23328,23326,23535,23980,23985,23977,23975,23989,23984,23982,
88023978,23976,23986,23981,23983,23988,24167,24168,24166,24175,24297,24295,24294,
88124296,24293,24395,24508,24989,25000,24982,25029,25012,25030,25025,25036,25018,
88225023,25016,24972,25815,25814,25808,25807,25801,25789,25737,25795,25819,25843,
88325817,25907,25983,25980,26018,26312,26302,26304,26314,26315,26319,26301,26299,
88426298,26316,26403,27188,27238,27209,27239,27186,27240,27198,27229,27245,27254,
88527227,27217,27176,27226,27195,27199,27201,27242,27236,27216,27215,27220,27247,
88627241,27232,27196,27230,27222,27221,27213,27214,27206,27477,27476,27478,27559,
88727562,27563,27592,27591,27652,27651,27654,28589,28619,28579,28615,28604,28622,
88828616,28510,28612,28605,28574,28618,28584,28676,28581,28590,28602,28588,28586,
88928623,28607,28600,28578,28617,28587,28621,28591,28594,28592,29125,29122,29119,
89029112,29142,29120,29121,29131,29140,29130,29127,29135,29117,29144,29116,29126,
89129146,29147,29341,29342,29545,29542,29543,29548,29541,29547,29546,29823,29850,
89229856,29844,29842,29845,29857,29963,30080,30255,30253,30257,30269,30259,30268,
89330261,30258,30256,30395,30438,30618,30621,30625,30620,
89430619,30626,30627,30613,30617,30615,30941,30953,30949,30954,30942,30947,30939,
89530945,30946,30957,30943,30944,31140,31300,31304,31303,31414,31416,31413,31409,
89631415,31710,31715,31719,31709,31701,31717,31706,31720,31737,31700,31722,31714,
89731708,31723,31704,31711,31954,31956,31959,31952,31953,32274,32289,32279,32268,
89832287,32288,32275,32270,32284,32277,32282,32290,32267,32271,32278,32269,32276,
89932293,32292,32579,32635,32636,32634,32689,32751,32810,32809,32876,33201,33190,
90033198,33209,33205,33195,33200,33196,33204,33202,33207,33191,33266,33365,33366,
90133367,34134,34117,34155,34125,34131,34145,34136,34112,34118,34148,34113,34146,
90234116,34129,34119,34147,34110,34139,34161,34126,34158,34165,34133,34151,34144,
90334188,34150,34141,34132,34149,34156,34403,34405,34404,34715,34703,34711,34707,
90434706,34696,34689,34710,34712,34681,34695,34723,34693,34704,34705,34717,34692,
90534708,34716,34714,34697,35102,35110,35120,35117,35118,35111,35121,35106,35113,
90635107,35119,35116,35103,35313,35552,35554,35570,35572,35573,35549,35604,35556,
90735551,35568,35528,35550,35553,35560,35583,35567,35579,35985,35986,35984,36085,
90836078,36081,36080,36083,36204,36206,36261,36263,36403,36414,36408,36416,36421,
90936406,36412,36413,36417,36400,36415,36541,36662,36654,36661,36658,36665,36663,
91036660,36982,36985,36987,36998,37114,37171,37173,37174,37267,37264,37265,37261,
91137263,37671,37662,37640,37663,37638,37647,37754,37688,37692,37659,37667,37650,
91237633,37702,37677,37646,37645,37579,37661,37626,37669,37651,37625,37623,37684,
91337634,37668,37631,37673,37689,37685,37674,37652,37644,
91437643,37630,37641,37632,37627,37654,38332,38349,38334,38329,38330,38326,38335,
91538325,38333,38569,38612,38667,38674,38672,38809,38807,38804,38896,38904,38965,
91638959,38962,39204,39199,39207,39209,39326,39406,39404,39397,39396,39408,39395,
91739402,39401,39399,39609,39615,39604,39611,39670,39674,39673,39671,39731,39808,
91839813,39815,39804,39806,39803,39810,39827,39826,39824,39802,39829,39805,39816,
91940229,40215,40224,40222,40212,40233,40221,40216,40226,40208,40217,40223,40584,
92040582,40583,40622,40621,40661,40662,40698,40722,40765,20774,20773,20770,20772,
92120768,20777,21236,22163,22156,22157,22150,22148,22147,22142,22146,22143,22145,
92222742,22740,22735,22738,23341,23333,23346,23331,23340,23335,23334,23343,23342,
92323419,23537,23538,23991,24172,24170,24510,24507,25027,25013,25020,25063,25056,
92425061,25060,25064,25054,25839,25833,25827,25835,25828,25832,25985,25984,26038,
92526074,26322,27277,27286,27265,27301,27273,27295,27291,27297,27294,27271,27283,
92627278,27285,27267,27304,27300,27281,27263,27302,27290,27269,27276,27282,27483,
92727565,27657,28620,28585,28660,28628,28643,28636,28653,28647,28646,28638,28658,
92828637,28642,28648,29153,29169,29160,29170,29156,29168,29154,29555,29550,29551,
92929847,29874,29867,29840,29866,29869,29873,29861,29871,29968,29969,29970,29967,
93030084,30275,30280,30281,30279,30372,30441,30645,30635,30642,30647,30646,30644,
93130641,30632,30704,30963,30973,30978,30971,30972,30962,30981,30969,30974,30980,
93231147,31144,31324,31323,31318,31320,31316,31322,31422,31424,31425,31749,31759,
93331730,31744,31743,31739,31758,31732,31755,31731,31746,
93431753,31747,31745,31736,31741,31750,31728,31729,31760,31754,31976,32301,32316,
93532322,32307,38984,32312,32298,32329,32320,32327,32297,32332,32304,32315,32310,
93632324,32314,32581,32639,32638,32637,32756,32754,32812,33211,33220,33228,33226,
93733221,33223,33212,33257,33371,33370,33372,34179,34176,34191,34215,34197,34208,
93834187,34211,34171,34212,34202,34206,34167,34172,34185,34209,34170,34168,34135,
93934190,34198,34182,34189,34201,34205,34177,34210,34178,34184,34181,34169,34166,
94034200,34192,34207,34408,34750,34730,34733,34757,34736,34732,34745,34741,34748,
94134734,34761,34755,34754,34764,34743,34735,34756,34762,34740,34742,34751,34744,
94234749,34782,34738,35125,35123,35132,35134,35137,35154,35127,35138,35245,35247,
94335246,35314,35315,35614,35608,35606,35601,35589,35595,35618,35599,35602,35605,
94435591,35597,35592,35590,35612,35603,35610,35919,35952,35954,35953,35951,35989,
94535988,36089,36207,36430,36429,36435,36432,36428,36423,36675,36672,36997,36990,
94637176,37274,37282,37275,37273,37279,37281,37277,37280,37793,37763,37807,37732,
94737718,37703,37756,37720,37724,37750,37705,37712,37713,37728,37741,37775,37708,
94837738,37753,37719,37717,37714,37711,37745,37751,37755,37729,37726,37731,37735,
94937760,37710,37721,38343,38336,38345,38339,38341,38327,38574,38576,38572,38688,
95038687,38680,38685,38681,38810,38817,38812,38814,38813,38869,38868,38897,38977,
95138980,38986,38985,38981,38979,39205,39211,39212,39210,39219,39218,39215,39213,
95239217,39216,39320,39331,39329,39426,39418,39412,39415,39417,39416,39414,39419,
95339421,39422,39420,39427,39614,39678,39677,39681,39676,
95439752,39834,39848,39838,39835,39846,39841,39845,39844,39814,39842,39840,39855,
95540243,40257,40295,40246,40238,40239,40241,40248,40240,40261,40258,40259,40254,
95640247,40256,40253,32757,40237,40586,40585,40589,40624,40648,40666,40699,40703,
95740740,40739,40738,40788,40864,20785,20781,20782,22168,22172,22167,22170,22173,
95822169,22896,23356,23657,23658,24000,24173,24174,25048,25055,25069,25070,25073,
95925066,25072,25067,25046,25065,25855,25860,25853,25848,25857,25859,25852,26004,
96026075,26330,26331,26328,27333,27321,27325,27361,27334,27322,27318,27319,27335,
96127316,27309,27486,27593,27659,28679,28684,28685,28673,28677,28692,28686,28671,
96228672,28667,28710,28668,28663,28682,29185,29183,29177,29187,29181,29558,29880,
96329888,29877,29889,29886,29878,29883,29890,29972,29971,30300,30308,30297,30288,
96430291,30295,30298,30374,30397,30444,30658,30650,30975,30988,30995,30996,30985,
96530992,30994,30993,31149,31148,31327,31772,31785,31769,31776,31775,31789,31773,
96631782,31784,31778,31781,31792,32348,32336,32342,32355,32344,32354,32351,32337,
96732352,32343,32339,32693,32691,32759,32760,32885,33233,33234,33232,33375,33374,
96834228,34246,34240,34243,34242,34227,34229,34237,34247,34244,34239,34251,34254,
96934248,34245,34225,34230,34258,34340,34232,34231,34238,34409,34791,34790,34786,
97034779,34795,34794,34789,34783,34803,34788,34772,34780,34771,34797,34776,34787,
97134724,34775,34777,34817,34804,34792,34781,35155,35147,35151,35148,35142,35152,
97235153,35145,35626,35623,35619,35635,35632,35637,35655,35631,35644,35646,35633,
97335621,35639,35622,35638,35630,35620,35643,35645,35642,
97435906,35957,35993,35992,35991,36094,36100,36098,36096,36444,36450,36448,36439,
97536438,36446,36453,36455,36443,36442,36449,36445,36457,36436,36678,36679,36680,
97636683,37160,37178,37179,37182,37288,37285,37287,37295,37290,37813,37772,37778,
97737815,37787,37789,37769,37799,37774,37802,37790,37798,37781,37768,37785,37791,
97837773,37809,37777,37810,37796,37800,37812,37795,37797,38354,38355,38353,38579,
97938615,38618,24002,38623,38616,38621,38691,38690,38693,38828,38830,38824,38827,
98038820,38826,38818,38821,38871,38873,38870,38872,38906,38992,38993,38994,39096,
98139233,39228,39226,39439,39435,39433,39437,39428,39441,39434,39429,39431,39430,
98239616,39644,39688,39684,39685,39721,39733,39754,39756,39755,39879,39878,39875,
98339871,39873,39861,39864,39891,39862,39876,39865,39869,40284,40275,40271,40266,
98440283,40267,40281,40278,40268,40279,40274,40276,40287,40280,40282,40590,40588,
98540671,40705,40704,40726,40741,40747,40746,40745,40744,40780,40789,20788,20789,
98621142,21239,21428,22187,22189,22182,22183,22186,22188,22746,22749,22747,22802,
98723357,23358,23359,24003,24176,24511,25083,25863,25872,25869,25865,25868,25870,
98825988,26078,26077,26334,27367,27360,27340,27345,27353,27339,27359,27356,27344,
98927371,27343,27341,27358,27488,27568,27660,28697,28711,28704,28694,28715,28705,
99028706,28707,28713,28695,28708,28700,28714,29196,29194,29191,29186,29189,29349,
99129350,29348,29347,29345,29899,29893,29879,29891,29974,30304,30665,30666,30660,
99230705,31005,31003,31009,31004,30999,31006,31152,31335,31336,31795,31804,31801,
99331788,31803,31980,31978,32374,32373,32376,32368,32375,
99432367,32378,32370,32372,32360,32587,32586,32643,32646,32695,32765,32766,32888,
99533239,33237,33380,33377,33379,34283,34289,34285,34265,34273,34280,34266,34263,
99634284,34290,34296,34264,34271,34275,34268,34257,34288,34278,34287,34270,34274,
99734816,34810,34819,34806,34807,34825,34828,34827,34822,34812,34824,34815,34826,
99834818,35170,35162,35163,35159,35169,35164,35160,35165,35161,35208,35255,35254,
99935318,35664,35656,35658,35648,35667,35670,35668,35659,35669,35665,35650,35666,
100035671,35907,35959,35958,35994,36102,36103,36105,36268,36266,36269,36267,36461,
100136472,36467,36458,36463,36475,36546,36690,36689,36687,36688,36691,36788,37184,
100237183,37296,37293,37854,37831,37839,37826,37850,37840,37881,37868,37836,37849,
100337801,37862,37834,37844,37870,37859,37845,37828,37838,37824,37842,37863,38269,
100438362,38363,38625,38697,38699,38700,38696,38694,38835,38839,38838,38877,38878,
100538879,39004,39001,39005,38999,39103,39101,39099,39102,39240,39239,39235,39334,
100639335,39450,39445,39461,39453,39460,39451,39458,39456,39463,39459,39454,39452,
100739444,39618,39691,39690,39694,39692,39735,39914,39915,39904,39902,39908,39910,
100839906,39920,39892,39895,39916,39900,39897,39909,39893,39905,39898,40311,40321,
100940330,40324,40328,40305,40320,40312,40326,40331,40332,40317,40299,40308,40309,
101040304,40297,40325,40307,40315,40322,40303,40313,40319,40327,40296,40596,40593,
101140640,40700,40749,40768,40769,40781,40790,40791,40792,21303,22194,22197,22195,
101222755,23365,24006,24007,24302,24303,24512,24513,25081,25879,25878,25877,25875,
101326079,26344,26339,26340,27379,27376,27370,27368,27385,
101427377,27374,27375,28732,28725,28719,28727,28724,28721,28738,28728,28735,28730,
101528729,28736,28731,28723,28737,29203,29204,29352,29565,29564,29882,30379,30378,
101630398,30445,30668,30670,30671,30669,30706,31013,31011,31015,31016,31012,31017,
101731154,31342,31340,31341,31479,31817,31816,31818,31815,31813,31982,32379,32382,
101832385,32384,32698,32767,32889,33243,33241,33291,33384,33385,34338,34303,34305,
101934302,34331,34304,34294,34308,34313,34309,34316,34301,34841,34832,34833,34839,
102034835,34838,35171,35174,35257,35319,35680,35690,35677,35688,35683,35685,35687,
102135693,36270,36486,36488,36484,36697,36694,36695,36693,36696,36698,37005,37187,
102237185,37303,37301,37298,37299,37899,37907,37883,37920,37903,37908,37886,37909,
102337904,37928,37913,37901,37877,37888,37879,37895,37902,37910,37906,37882,37897,
102437880,37898,37887,37884,37900,37878,37905,37894,38366,38368,38367,38702,38703,
102538841,38843,38909,38910,39008,39010,39011,39007,39105,39106,39248,39246,39257,
102639244,39243,39251,39474,39476,39473,39468,39466,39478,39465,39470,39480,39469,
102739623,39626,39622,39696,39698,39697,39947,39944,39927,39941,39954,39928,40000,
102839943,39950,39942,39959,39956,39945,40351,40345,40356,40349,40338,40344,40336,
102940347,40352,40340,40348,40362,40343,40353,40346,40354,40360,40350,40355,40383,
103040361,40342,40358,40359,40601,40603,40602,40677,40676,40679,40678,40752,40750,
103140795,40800,40798,40797,40793,40849,20794,20793,21144,21143,22211,22205,22206,
103223368,23367,24011,24015,24305,25085,25883,27394,27388,27395,27384,27392,28739,
103328740,28746,28744,28745,28741,28742,29213,29210,29209,
103429566,29975,30314,30672,31021,31025,31023,31828,31827,31986,32394,32391,32392,
103532395,32390,32397,32589,32699,32816,33245,34328,34346,34342,34335,34339,34332,
103634329,34343,34350,34337,34336,34345,34334,34341,34857,34845,34843,34848,34852,
103734844,34859,34890,35181,35177,35182,35179,35322,35705,35704,35653,35706,35707,
103836112,36116,36271,36494,36492,36702,36699,36701,37190,37188,37189,37305,37951,
103937947,37942,37929,37949,37948,37936,37945,37930,37943,37932,37952,37937,38373,
104038372,38371,38709,38714,38847,38881,39012,39113,39110,39104,39256,39254,39481,
104139485,39494,39492,39490,39489,39482,39487,39629,39701,39703,39704,39702,39738,
104239762,39979,39965,39964,39980,39971,39976,39977,39972,39969,40375,40374,40380,
104340385,40391,40394,40399,40382,40389,40387,40379,40373,40398,40377,40378,40364,
104440392,40369,40365,40396,40371,40397,40370,40570,40604,40683,40686,40685,40731,
104540728,40730,40753,40782,40805,40804,40850,20153,22214,22213,22219,22897,23371,
104623372,24021,24017,24306,25889,25888,25894,25890,27403,27400,27401,27661,28757,
104728758,28759,28754,29214,29215,29353,29567,29912,29909,29913,29911,30317,30381,
104831029,31156,31344,31345,31831,31836,31833,31835,31834,31988,31985,32401,32591,
104932647,33246,33387,34356,34357,34355,34348,34354,34358,34860,34856,34854,34858,
105034853,35185,35263,35262,35323,35710,35716,35714,35718,35717,35711,36117,36501,
105136500,36506,36498,36496,36502,36503,36704,36706,37191,37964,37968,37962,37963,
105237967,37959,37957,37960,37961,37958,38719,38883,39018,39017,39115,39252,39259,
105339502,39507,39508,39500,39503,39496,39498,39497,39506,
105439504,39632,39705,39723,39739,39766,39765,40006,40008,39999,40004,39993,39987,
105540001,39996,39991,39988,39986,39997,39990,40411,40402,40414,40410,40395,40400,
105640412,40401,40415,40425,40409,40408,40406,40437,40405,40413,40630,40688,40757,
105740755,40754,40770,40811,40853,40866,20797,21145,22760,22759,22898,23373,24024,
105834863,24399,25089,25091,25092,25897,25893,26006,26347,27409,27410,27407,27594,
105928763,28762,29218,29570,29569,29571,30320,30676,31847,31846,32405,33388,34362,
106034368,34361,34364,34353,34363,34366,34864,34866,34862,34867,35190,35188,35187,
106135326,35724,35726,35723,35720,35909,36121,36504,36708,36707,37308,37986,37973,
106237981,37975,37982,38852,38853,38912,39510,39513,39710,39711,39712,40018,40024,
106340016,40010,40013,40011,40021,40025,40012,40014,40443,40439,40431,40419,40427,
106440440,40420,40438,40417,40430,40422,40434,40432,40418,40428,40436,40435,40424,
106540429,40642,40656,40690,40691,40710,40732,40760,40759,40758,40771,40783,40817,
106640816,40814,40815,22227,22221,23374,23661,25901,26349,26350,27411,28767,28769,
106728765,28768,29219,29915,29925,30677,31032,31159,31158,31850,32407,32649,33389,
106834371,34872,34871,34869,34891,35732,35733,36510,36511,36512,36509,37310,37309,
106937314,37995,37992,37993,38629,38726,38723,38727,38855,38885,39518,39637,39769,
107040035,40039,40038,40034,40030,40032,40450,40446,40455,40451,40454,40453,40448,
107140449,40457,40447,40445,40452,40608,40734,40774,40820,40821,40822,22228,25902,
107226040,27416,27417,27415,27418,28770,29222,29354,30680,30681,31033,31849,31851,
107331990,32410,32408,32411,32409,33248,33249,34374,34375,
107434376,35193,35194,35196,35195,35327,35736,35737,36517,36516,36515,37998,37997,
107537999,38001,38003,38729,39026,39263,40040,40046,40045,40459,40461,40464,40463,
107640466,40465,40609,40693,40713,40775,40824,40827,40826,40825,22302,28774,31855,
107734876,36274,36518,37315,38004,38008,38006,38005,39520,40052,40051,40049,40053,
107840468,40467,40694,40714,40868,28776,28773,31991,34410,34878,34877,34879,35742,
107935996,36521,36553,38731,39027,39028,39116,39265,39339,39524,39526,39527,39716,
108040469,40471,40776,25095,27422,29223,34380,36520,38018,38016,38017,39529,39528,
108139726,40473,29225,34379,35743,38019,40057,40631,30325,39531,40058,40477,28777,
108228778,40612,40830,40777,40856,30849,37561,35023,22715,24658,31911,23290,9556,
10839574,9559,9568,9580,9571,9562,9577,9565,9554,9572,9557,9566,9578,9569,9560,
10849575,9563,9555,9573,9558,9567,9579,9570,9561,9576,9564,9553,9552,9581,9582,
10859584,9583,9619,
libc/musl/src/locale/bind_textdomain_codeset.c created+11
......@@ -0,0 +1,11 @@
1#include <libintl.h>
2#include <string.h>
3#include <strings.h>
4#include <errno.h>
5
6char *bind_textdomain_codeset(const char *domainname, const char *codeset)
7{
8 if (codeset && strcasecmp(codeset, "UTF-8"))
9 errno = EINVAL;
10 return NULL;
11}
libc/musl/src/locale/c_locale.c created+15
......@@ -0,0 +1,15 @@
1#include "locale_impl.h"
2#include <stdint.h>
3
4static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
5
6const struct __locale_map __c_dot_utf8 = {
7 .map = empty_mo,
8 .map_size = sizeof empty_mo,
9 .name = "C.UTF-8"
10};
11
12const struct __locale_struct __c_locale = { 0 };
13const struct __locale_struct __c_dot_utf8_locale = {
14 .cat[LC_CTYPE] = &__c_dot_utf8
15};
libc/musl/src/locale/catclose.c created+6
......@@ -0,0 +1,6 @@
1#include <nl_types.h>
2
3int catclose (nl_catd catd)
4{
5 return 0;
6}
libc/musl/src/locale/catgets.c created+6
......@@ -0,0 +1,6 @@
1#include <nl_types.h>
2
3char *catgets (nl_catd catd, int set_id, int msg_id, const char *s)
4{
5 return (char *)s;
6}
libc/musl/src/locale/catopen.c created+8
......@@ -0,0 +1,8 @@
1#include <nl_types.h>
2#include <errno.h>
3
4nl_catd catopen (const char *name, int oflag)
5{
6 errno = EOPNOTSUPP;
7 return (nl_catd)-1;
8}
libc/musl/src/locale/codepages.h created+320
......@@ -0,0 +1,320 @@
1"iso88591\0"
2"latin1\0"
3"\0\100"
4
5"iso88592\0"
6"\0\50"
7"\240\20\364\127\116\244\334\364\324\51\250\124\65\125\126\156\265\42\27\134"
8"\260\24\24\230\116\264\340\4\225\137\270\130\105\225\126\157\15\66\127\134"
9"\111\5\43\214\100\304\314\144\320\61\14\45\143\321\62\30\65\343\214\103"
10"\20\355\364\323\64\324\24\145\315\65\115\215\245\115\131\334\164\163\325\67"
11"\112\205\43\316\100\344\320\164\320\71\15\245\163\321\72\31\265\343\316\103"
12"\21\361\4\324\74\364\30\145\317\75\116\221\245\217\131\374\364\203\25\140"
13
14"iso88593\0"
15"\0\50"
16"\240\220\364\327\50\244\0\40\322\51\250\260\64\25\107\56\265\2\0\134"
17"\260\224\44\313\54\264\324\62\322\55\270\264\104\125\107\57\365\2\100\134"
18"\300\4\43\14\0\304\50\204\320\61\310\44\243\314\62\314\64\343\314\63"
19"\0\104\43\315\64\324\170\144\315\65\32\145\243\315\66\334\204\25\325\67"
20"\340\204\43\16\0\344\54\224\320\71\350\244\243\316\72\354\264\343\316\73"
21"\0\304\43\317\74\364\174\144\317\75\33\345\243\317\76\374\210\45\25\140"
22
23"iso88594\0"
24"\0\50"
25"\240\20\44\323\122\244\230\124\323\51\250\124\45\21\110\133\265\42\327\53"
26"\260\24\24\30\123\264\234\144\223\137\270\130\65\121\110\134\5\65\227\120"
27"\0\5\43\314\60\304\24\143\214\112\14\45\143\321\62\24\65\343\14\112"
28"\20\365\64\24\114\324\124\143\315\65\330\234\245\315\66\334\164\365\325\67"
29"\1\205\43\316\70\344\224\143\316\112\15\245\163\321\72\25\265\343\116\112"
30"\21\371\104\124\114\364\324\143\317\75\370\240\245\317\76\374\170\5\26\140"
31
32"iso88595\0"
33"\0\50"
34"\240\104\47\335\164\324\125\147\335\165\330\145\247\335\166"
35"\334\265\322\235\167\337\201\27\236\170\343\221\127\236\171"
36"\347\241\227\236\172\353\261\327\236\173\357\301\27\237\174"
37"\363\321\127\237\175\367\341\227\237\176\373\361\327\237\177\377\1\30\240\200"
38"\3\22\130\240\201\7\42\230\240\202\13\62\330\240\203\17\102\30\241\204"
39"\23\122\130\241\205\27\142\230\241\206\33\162\330\241\207\46\177\10\142\210"
40"\42\216\110\142\211\46\236\210\142\212\52\236\262\42\213"
41
42"iso88596\0"
43"\0\50"
44"\240\0\0\0\0\244\0\0\0\0\0\0\0\0\0\142\266\2\0\0\0\0\0\0\0\0\0\0\0\0"
45"\0\0\0\300\230\0\0\0\0\231\0\224\151\346\231\150\246\251\346\232"
46"\154\266\351\346\233\160\306\51\347\234\164\326\151\347\235"
47"\170\346\251\347\236\174\366\351\47\0\0\0\0\0\0\177\2\32\250\240"
48"\203\22\132\250\241\207\42\232\250\242\213\62\332\250\243\217\102\32\51\0"
49"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
50
51"iso88597\0"
52"\0\50"
53"\240\114\114\361\50\44\227\154\312\51\250\244\222\330\52\254\264\2\100\304"
54"\260\304\42\313\54\212\55\306\330\55\215\71\366\330\56\220\365\22\231\144"
55"\223\121\126\231\145\227\141\226\231\146\233\161\326\231\147"
56"\237\201\26\232\150\243\221\6\100\151\246\235\206\132\152\252\255\306\132\153"
57"\256\275\6\133\154\262\315\106\133\155\266\335\206\133\156\272\355\306\133\157"
58"\276\375\6\134\160\302\15\107\134\161\306\35\207\134\162\312\55\307\134\163"
59"\316\75\7\35\0"
60
61"iso88598\0"
62"\0\50"
63"\240\0\40\312\50\244\224\142\312\51\250\244\162\315\52\254\264\342\312\53"
64"\260\304\42\313\54\264\324\142\313\55\270\344\162\317\56\274\364\342\13\0"
65"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
66"\0\0\0\200\304\102\16\111\144\221\106\36\211\144\222\112\56\311\144\223"
67"\116\76\11\145\224\122\116\111\145\225\126\136\211\145\226\132\156\311\45\0"
68"\0\64\354\60\0"
69
70"iso88599\0"
71"\0\64"
72"\34\105\43\315\64\324\124\143\315\65\330\144\243\315\66\334\260\64\325\67"
73"\340\204\43\316\70\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73"
74"\35\305\43\317\74\364\324\143\317\75\370\344\243\317\76\374\264\104\325\77"
75
76"iso885910\0"
77"\0\50"
78"\240\20\44\21\110\50\231\4\323\51\65\101\124\325\126\162\265\362\125\120"
79"\260\24\64\121\110\51\235\24\323\55\66\105\144\25\127\163\105\14\226\120"
80"\0\5\43\314\60\304\24\143\214\112\14\45\143\321\62\24\65\343\314\63"
81"\320\364\64\324\64\324\124\143\115\127\330\234\245\315\66\334\164\343\315\67"
82"\1\205\43\316\70\344\224\143\316\112\15\245\163\321\72\25\265\343\316\73"
83"\360\370\104\324\74\364\324\143\217\127\370\240\245\317\76\374\364\343\217\114"
84
85"iso885911\0"
86"tis620\0"
87"\0\50"
88"\240\170\372\51\250\241\212\72\52\251\245\232\172\52\252\251\252\272\52\253"
89"\255\272\372\52\254\261\312\72\53\255\265\332\172\53\256\271\352\272\53\257"
90"\275\372\372\53\260\301\12\73\54\261\305\32\173\54\262\311\52\273\54\263"
91"\315\72\373\54\264\321\112\73\55\265\325\132\173\55\0\0\0\0\0\266"
92"\331\152\273\55\267\335\172\373\55\270\341\212\73\56\271\345\232\173\56\272"
93"\351\252\273\56\273\355\272\373\56\274\361\312\73\57\275\0\0\0\0\0"
94
95"iso885913\0"
96"\0\50"
97"\240\134\54\312\50\244\140\154\312\51\330\244\262\324\52\254\264\342\212\61"
98"\260\304\42\313\54\26\327\142\313\55\370\344\302\324\56\274\364\342\213\71"
99"\4\251\4\220\101\304\24\143\221\104\14\45\343\26\105\40\301\204\122\115"
100"\125\355\324\323\64\103\125\143\315\65\147\345\364\324\127\334\300\45\327\67"
101"\5\255\24\320\101\344\224\163\321\104\15\245\363\126\105\41\305\224\222\115"
102"\126\361\344\323\74\104\325\143\317\75\150\351\4\25\130\374\304\65\27\305"
103
104"iso885914\0"
105"\0\50"
106"\240\324\153\357\50\12\55\164\357\51\3\247\122\60\276\11\267\342\112\133"
107"\371\352\353\321\107\373\362\153\113\277\4\373\153\360\277\12\37\214\60\300"
108"\300\4\43\314\60\304\24\143\314\61\310\44\243\314\62\314\64\343\314\63"
109"\151\105\43\315\64\324\124\143\115\300\330\144\243\315\66\334\164\263\326\67"
110"\340\204\43\316\70\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73"
111"\152\305\43\317\74\364\324\143\217\300\370\344\243\317\76\374\364\303\326\77"
112
113"iso885915\0"
114"latin9\0"
115"\0\51"
116"\44\227\122\325\51\126\245\242\312\52\254\264\342\312\53\260\304\42\313\54"
117"\162\325\142\313\55\163\345\242\313\56\107\41\325\326\57\300\4\43\314\60"
118"\304\24\143\314\61\310\44\243\314\62\314\64\343\314\63\320\104\43\315\64"
119"\324\124\143\315\65\330\144\243\315\66\334\164\343\315\67\340\204\43\316\70"
120"\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73\360\304\43\317\74"
121"\364\324\143\317\75\370\344\243\317\76\374\364\343\317\77"
122
123"iso885916\0"
124"\0\50"
125"\240\20\124\120\116\44\143\134\325\51\126\245\222\327\52\156\265\362\26\134"
126"\260\304\302\220\116\162\135\154\313\55\163\65\244\327\56\107\41\325\126\134"
127"\300\4\43\214\100\304\30\144\314\61\310\44\243\314\62\314\64\343\314\63"
128"\20\355\44\315\64\324\24\145\315\123\145\145\243\315\66\334\130\264\327\67"
129"\340\204\43\316\100\344\34\144\316\71\350\244\243\316\72\354\264\343\316\73"
130"\21\361\44\317\74\364\30\145\17\124\146\345\243\317\76\374\134\304\327\77"
131
132"cp1250\0"
133"windows1250\0"
134"\0\40"
135"\44\3\120\61\0\30\163\234\261\306\0\164\134\225\307\117\145\45\227\133"
136"\0\114\114\261\305\27\157\374\60\304\0\234\154\325\307\120\151\65\327\133"
137"\240\370\365\127\116\244\20\144\312\51\250\244\62\325\52\254\264\342\12\134"
138"\260\304\22\230\116\264\324\142\313\55\270\24\104\325\56\67\15\206\123\134"
139"\111\5\43\214\100\304\314\144\320\61\14\45\143\321\62\30\65\343\214\103"
140"\20\355\364\323\64\324\24\145\315\65\115\215\245\115\131\334\164\163\325\67"
141"\112\205\43\316\100\344\320\164\320\71\15\245\163\321\72\31\265\343\316\103"
142"\21\361\4\324\74\364\30\145\317\75\116\221\245\217\131\374\364\203\25\140"
143
144"cp1251\0"
145"windows1251\0"
146"\0\40"
147"\322\115\127\161\210\30\163\234\261\306\44\167\234\235\307\332\161\267\235\167"
148"\40\116\114\261\305\27\157\374\60\304\0\234\174\342\307\50\252\230\42\213"
149"\240\164\267\42\166\244\264\150\312\51\321\245\102\335\52\254\264\342\312\165"
150"\260\304\142\35\211\56\326\142\313\55\37\232\54\342\56\46\126\67\142\211"
151"\337\201\27\236\170\343\221\127\236\171\347\241\227\236\172"
152"\353\261\327\236\173\357\301\27\237\174\363\321\127\237\175"
153"\367\341\227\237\176\373\361\327\237\177\377\1\30\240\200\3\22\130\240\201"
154"\7\42\230\240\202\13\62\330\240\203\17\102\30\241\204\23\122\130\241\205"
155"\27\142\230\241\206\33\162\330\241\207"
156
157"cp1252\0"
158"windows1252\0"
159"\0\40"
160"\44\3\120\61\135\30\163\234\261\306\175\165\134\225\307\107\1\40\27\0"
161"\0\114\114\261\305\27\157\374\60\304\202\235\154\325\307\110\1\60\127\133"
162"\240\204\42\312\50\244\224\142\312\51\250\244\242\312\52\254\264\342\312\53"
163"\260\304\42\313\54\264\324\142\313\55\270\344\242\313\56\274\364\342\313\57"
164"\300\4\43\314\60\304\24\143\314\61\310\44\243\314\62\314\64\343\314\63"
165"\320\104\43\315\64\324\124\143\315\65\330\144\243\315\66\334\164\343\315\67"
166"\340\204\43\316\70\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73"
167"\360\304\43\317\74\364\324\143\317\75\370\344\243\317\76\374\364\343\317\77"
168
169"cp1253\0"
170"windows1253\0"
171"\0\40"
172"\44\3\120\61\135\30\163\234\261\306\0\164\14\200\307\0\0\0\0\0"
173"\0\114\114\261\305\27\157\374\60\304\0\234\14\300\307\0\0\0\0\0"
174"\240\54\306\330\50\244\224\142\312\51\250\244\2\300\52\254\264\342\112\304"
175"\260\304\42\313\54\212\325\142\313\55\215\71\366\330\56\220\365\22\231\144"
176"\223\121\126\231\145\227\141\226\231\146\233\161\326\231\147"
177"\237\201\26\232\150\243\221\6\100\151\246\235\206\132\152\252\255\306\132\153"
178"\256\275\6\133\154\262\315\106\133\155\266\335\206\133\156\272\355\306\133\157"
179"\276\375\6\134\160\302\15\107\134\161\306\35\207\134\162\312\55\307\134\163"
180"\316\75\7\35\0"
181
182"cp1254\0"
183"windows1254\0"
184"\0\40"
185"\44\3\120\61\135\30\163\234\261\306\175\165\134\225\307\107\1\0\0\0"
186"\0\114\114\261\305\27\157\374\60\304\202\235\154\325\307\110\1\0\100\133"
187"\240\204\42\312\50\244\224\142\312\51\250\244\242\312\52\254\264\342\312\53"
188"\260\304\42\313\54\264\324\142\313\55\270\344\242\313\56\274\364\342\313\57"
189"\300\4\43\314\60\304\24\143\314\61\310\44\243\314\62\314\64\343\314\63"
190"\34\105\43\315\64\324\124\143\315\65\330\144\243\315\66\334\260\64\325\67"
191"\340\204\43\316\70\344\224\143\316\71\350\244\243\316\72\354\264\343\316\73"
192"\35\305\43\317\74\364\324\143\317\75\370\344\243\317\76\374\264\104\325\77"
193
194"cp1255\0"
195"windows1255\0"
196"\0\40"
197"\44\3\120\61\135\30\163\234\261\306\175\165\14\200\307\0\0\0\0\0"
198"\0\114\114\261\305\27\157\374\60\304\202\235\14\300\307\0\0\0\0\0"
199"\240\204\42\312\50\42\227\142\312\51\250\244\162\315\52\254\264\342\312\53"
200"\260\304\42\313\54\264\324\142\313\55\270\344\162\317\56\274\364\342\313\57"
201"\57\302\30\243\214\63\322\130\243\215\67\342\10\100\216\72\356\310\143\217"
202"\76\376\10\144\220\135\172\371\45\230\141\2\0\0\0\0\0\0\0\0\102\16\111\144\221"
203"\106\36\211\144\222\112\56\311\144\223\116\76\11\145\224\122\116\111\145\225"
204"\126\136\211\145\226\132\156\311\45\0\0\64\354\60\0"
205
206"cp1256\0"
207"windows1256\0"
208"\0\40"
209"\44\117\132\61\135\30\163\234\261\306\175\165\54\251\307\107\121\172\151\245"
210"\231\116\114\261\305\27\157\374\60\304\230\236\154\351\307\110\55\314\260\246"
211"\240\210\51\312\50\244\224\142\312\51\250\244\262\351\52\254\264\342\312\53"
212"\260\304\42\313\54\264\324\142\313\55\270\344\62\346\56\274\364\342\13\231"
213"\234\226\151\346\231\150\246\251\346\232\154\266\351\346\233"
214"\160\306\51\347\234\164\326\151\347\235\170\346\251\347\65\173\362\331\247\237"
215"\177\2\32\250\240\340\14\52\16\241\205\32\172\350\71\350\244\243\316\72"
216"\210\46\352\316\73\212\56\312\150\243\364\70\372\350\75\220\346\23\351\76"
217"\374\64\354\160\247"
218
219"cp1257\0"
220"windows1257\0"
221"\0\40"
222"\44\3\120\61\0\30\163\234\261\306\0\164\14\200\307\0\240\342\27\56"
223"\0\114\114\261\305\27\157\374\60\304\0\234\14\300\307\0\274\22\30\0"
224"\240\0\40\312\50\244\0\140\312\51\330\244\262\324\52\254\264\342\212\61"
225"\260\304\42\313\54\264\324\142\313\55\370\344\302\324\56\274\364\342\213\71"
226"\4\251\4\220\101\304\24\143\221\104\14\45\343\26\105\40\301\204\122\115"
227"\125\355\324\323\64\103\125\143\315\65\147\345\364\324\127\334\300\45\327\67"
228"\5\255\24\320\101\344\224\163\321\104\15\245\363\126\105\41\305\224\222\115"
229"\126\361\344\323\74\104\325\143\317\75\150\351\4\25\130\374\304\65\27\140"
230
231"cp1258\0"
232"windows1258\0"
233"\0\40"
234"\44\3\120\61\135\30\163\234\261\306\175\165\14\200\307\107\1\0\0\0"
235"\0\114\114\261\305\27\157\374\60\304\202\235\14\300\307\110\1\0\100\133"
236"\240\204\42\312\50\244\224\142\312\51\250\244\242\312\52\254\264\342\312\53"
237"\260\304\42\313\54\264\324\142\313\55\270\344\242\313\56\274\364\342\313\57"
238"\300\4\43\214\100\304\24\143\314\61\310\44\243\314\62\204\65\343\314\63"
239"\20\105\163\330\64\324\324\145\315\65\330\144\243\315\66\334\334\145\330\67"
240"\340\204\43\316\100\344\224\143\316\71\350\244\243\316\72\205\265\343\316\73"
241"\21\305\203\330\74\364\330\145\317\75\370\344\243\317\76\374\340\65\362\77"
242
243"koi8r\0"
244"\0\40"
245"\63\323\134\263\315\67\343\234\263\316\73\363\334\363\326\134\167\355\365\327"
246"\140\207\55\166\314\143\243\234\62\313\56\277\14\212\314\260\310\162\313\75"
247"\76\377\14\364\207\101\13\75\64\321\105\33\175\64\322\111\53\275\64\323"
248"\115\73\375\164\164\120\107\55\365\324\124\127\155\365\325\130\147\255\165\52"
249"\35\376\7\140\205\3\22\70\241\200\24\36\210\140\202\12\56\310\140\203"
250"\16\172\370\40\204\21\112\130\140\200\33\152\150\340\205\34\142\150\141\206"
251"\375\175\7\136\175\343\221\67\237\170\364\235\207\136\172\352\255\307\136\173"
252"\356\371\367\36\174\361\311\127\136\170\373\351\147\336\175"
253"\374\341\147\137\176"
254
255"koi8u\0"
256"\0\40"
257"\63\323\134\263\315\67\343\234\263\316\73\363\334\363\326\134\167\355\365\327"
258"\140\207\55\166\314\143\243\234\62\313\56\277\14\212\314\260\310\162\313\75"
259"\76\377\14\364\207\42\12\115\142\211\105\33\175\64\322\111\273\270\64\323"
260"\115\73\375\164\164\324\105\155\335\165\124\127\155\365\325\130\267\250\165\52"
261"\35\376\7\140\205\3\22\70\241\200\24\36\210\140\202\12\56\310\140\203"
262"\16\172\370\40\204\21\112\130\140\200\33\152\150\340\205\34\142\150\141\206"
263"\375\175\7\136\175\343\221\67\237\170\364\235\207\136\172\352\255\307\136\173"
264"\356\371\367\36\174\361\311\127\136\170\373\351\147\336\175"
265"\374\341\147\137\176"
266
267"cp437\0"
268"\0\40"
269"\307\360\223\216\70\344\200\123\316\71\352\254\203\316\73\356\260\103\114\61"
270"\311\230\143\14\75\366\310\263\117\76\377\130\303\215\50\243\224\22\62\135"
271"\341\264\63\217\76\361\104\243\212\56\277\300\314\112\57\274\204\262\312\56"
272"\140\207\55\66\315\72\77\15\65\321\103\107\375\163\321\113\53\235\264\315"
273"\67\363\274\163\316\63\367\314\164\323\110\13\175\65\325\116\373\254\165\325"
274"\126\113\75\365\321\106\3\35\164\326\130\343\134\163\327\134\173\375\365\326"
275"\263\175\143\231\160\245\25\127\213\161\250\155\266\232\155\52\43\167\333\312"
276"\55\307\362\262\313\61\313\174\17\313\260\240\174\113\312\40\313\62\66\50"
277
278"cp850\0"
279"\0\40"
280"\307\360\223\216\70\344\200\123\316\71\352\254\203\316\73\356\260\103\114\61"
281"\311\230\143\14\75\366\310\263\117\76\377\130\303\15\76\243\140\163\15\135"
282"\341\264\63\217\76\361\104\243\212\56\277\270\302\112\57\274\204\262\312\56"
283"\140\207\55\66\315\72\7\43\14\60\251\104\375\163\321\113\213\122\212\315"
284"\67\363\274\163\316\63\367\74\316\60\110\13\175\65\325\116\373\254\65\51"
285"\360\100\243\314\62\310\264\324\214\63\317\340\134\163\327\134\233\302\314\326"
286"\323\174\103\215\64\365\124\123\213\77\336\150\263\115\66\375\164\363\12\55"
287"\255\304\42\261\57\266\234\162\17\56\260\240\162\113\56\263\310\62\66\50"
288
289"cp866\0"
290"\0\40"
291"\337\201\27\236\170\343\221\127\236\171\347\241\227\236\172"
292"\353\261\327\236\173\357\301\27\237\174\363\321\127\237\175"
293"\367\341\227\237\176\373\361\327\237\177\377\1\30\240\200\3\22\130\240\201"
294"\7\42\230\240\202\13\62\330\240\203\140\207\55\66\315\72\77\15\65\321"
295"\103\107\375\163\321\113\53\235\264\315\67\363\274\163\316\63\367\314\164\323"
296"\110\13\175\65\325\116\373\254\165\325\126\113\75\365\321\106\3\35\164\326"
297"\130\343\134\163\327\134\173\375\365\326\17\102\30\241\204\23\122\130\241\205"
298"\27\142\230\241\206\33\162\330\241\207\321\175\110\235\210\327\225\330\335\212"
299"\260\240\174\113\312\46\223\62\66\50"
300
301"ibm1047\0"
302"cp1047\0"
303"\0\1"
304"\234\44\140\310\37\227\64\342\310\2\14\64\340\300\3\20\104\40\301\4"
305"\235\24\202\300\41\30\144\40\311\43\34\164\340\301\7\200\4\42\310\40"
306"\204\50\160\301\6\210\44\242\310\42\214\24\140\300\1\220\104\142\301\44"
307"\224\124\142\11\1\230\144\242\311\46\24\124\340\211\6\40\200\42\16\71"
308"\340\204\63\116\71\347\304\43\212\13\74\240\260\2\37\46\244\243\316\72"
309"\350\264\343\316\73\354\174\23\2\11\52\244\260\203\27\55\274\40\14\61"
310"\300\4\63\114\61\307\104\143\12\13\45\174\341\303\17\370\44\243\314\62"
311"\310\64\343\314\63\314\200\241\303\10\100\234\320\203\10\330\204\41\306\30"
312"\144\224\141\306\31\150\244\261\312\56\360\364\343\117\54\260\250\261\6\33"
313"\155\270\361\6\34\161\310\241\212\56\346\340\142\14\51\265\370\61\7\35"
314"\165\330\161\7\36\171\350\21\312\57\320\154\341\215\53\254\214\122\312\55"
315"\251\234\142\13\57\275\370\322\15\52\257\164\101\313\65\173\4\41\304\20"
316"\104\24\141\304\21\110\44\321\12\75\366\310\63\117\75\175\50\261\4\23"
317"\115\70\361\4\24\121\110\221\313\76\374\344\243\317\77\134\334\63\5\25"
318"\125\130\161\5\26\131\150\41\13\65\326\110\63\115\65\60\304\40\303\14"
319"\64\324\140\303\15\70\344\60\313\66\334\144\243\315\47"
320
libc/musl/src/locale/dcngettext.c created+269
......@@ -0,0 +1,269 @@
1#include <libintl.h>
2#include <stdlib.h>
3#include <string.h>
4#include <errno.h>
5#include <limits.h>
6#include <sys/stat.h>
7#include <sys/mman.h>
8#include <ctype.h>
9#include "locale_impl.h"
10#include "atomic.h"
11#include "pleval.h"
12#include "lock.h"
13
14struct binding {
15 struct binding *next;
16 int dirlen;
17 volatile int active;
18 char *domainname;
19 char *dirname;
20 char buf[];
21};
22
23static void *volatile bindings;
24
25static char *gettextdir(const char *domainname, size_t *dirlen)
26{
27 struct binding *p;
28 for (p=bindings; p; p=p->next) {
29 if (!strcmp(p->domainname, domainname) && p->active) {
30 *dirlen = p->dirlen;
31 return (char *)p->dirname;
32 }
33 }
34 return 0;
35}
36
37char *bindtextdomain(const char *domainname, const char *dirname)
38{
39 static volatile int lock[1];
40 struct binding *p, *q;
41
42 if (!domainname) return 0;
43 if (!dirname) return gettextdir(domainname, &(size_t){0});
44
45 size_t domlen = strnlen(domainname, NAME_MAX+1);
46 size_t dirlen = strnlen(dirname, PATH_MAX);
47 if (domlen > NAME_MAX || dirlen >= PATH_MAX) {
48 errno = EINVAL;
49 return 0;
50 }
51
52 LOCK(lock);
53
54 for (p=bindings; p; p=p->next) {
55 if (!strcmp(p->domainname, domainname) &&
56 !strcmp(p->dirname, dirname)) {
57 break;
58 }
59 }
60
61 if (!p) {
62 p = calloc(sizeof *p + domlen + dirlen + 2, 1);
63 if (!p) {
64 UNLOCK(lock);
65 return 0;
66 }
67 p->next = bindings;
68 p->dirlen = dirlen;
69 p->domainname = p->buf;
70 p->dirname = p->buf + domlen + 1;
71 memcpy(p->domainname, domainname, domlen+1);
72 memcpy(p->dirname, dirname, dirlen+1);
73 a_cas_p(&bindings, bindings, p);
74 }
75
76 a_store(&p->active, 1);
77
78 for (q=bindings; q; q=q->next) {
79 if (!strcmp(q->domainname, domainname) && q != p)
80 a_store(&q->active, 0);
81 }
82
83 UNLOCK(lock);
84
85 return (char *)p->dirname;
86}
87
88static const char catnames[][12] = {
89 "LC_CTYPE",
90 "LC_NUMERIC",
91 "LC_TIME",
92 "LC_COLLATE",
93 "LC_MONETARY",
94 "LC_MESSAGES",
95};
96
97static const char catlens[] = { 8, 10, 7, 10, 11, 11 };
98
99struct msgcat {
100 struct msgcat *next;
101 const void *map;
102 size_t map_size;
103 const char *plural_rule;
104 int nplurals;
105 struct binding *binding;
106 const struct __locale_map *lm;
107 int cat;
108};
109
110static char *dummy_gettextdomain()
111{
112 return "messages";
113}
114
115weak_alias(dummy_gettextdomain, __gettextdomain);
116
117char *dcngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n, int category)
118{
119 static struct msgcat *volatile cats;
120 struct msgcat *p;
121 struct __locale_struct *loc = CURRENT_LOCALE;
122 const struct __locale_map *lm;
123 size_t domlen;
124 struct binding *q;
125
126 if ((unsigned)category >= LC_ALL) goto notrans;
127
128 if (!domainname) domainname = __gettextdomain();
129
130 domlen = strnlen(domainname, NAME_MAX+1);
131 if (domlen > NAME_MAX) goto notrans;
132
133 for (q=bindings; q; q=q->next)
134 if (!strcmp(q->domainname, domainname) && q->active)
135 break;
136 if (!q) goto notrans;
137
138 lm = loc->cat[category];
139 if (!lm) {
140notrans:
141 return (char *) ((n == 1) ? msgid1 : msgid2);
142 }
143
144 for (p=cats; p; p=p->next)
145 if (p->binding == q && p->lm == lm && p->cat == category)
146 break;
147
148 if (!p) {
149 const char *dirname, *locname, *catname, *modname, *locp;
150 size_t dirlen, loclen, catlen, modlen, alt_modlen;
151 void *old_cats;
152 size_t map_size;
153
154 dirname = q->dirname;
155 locname = lm->name;
156 catname = catnames[category];
157
158 dirlen = q->dirlen;
159 loclen = strlen(locname);
160 catlen = catlens[category];
161
162 /* Logically split @mod suffix from locale name. */
163 modname = memchr(locname, '@', loclen);
164 if (!modname) modname = locname + loclen;
165 alt_modlen = modlen = loclen - (modname-locname);
166 loclen = modname-locname;
167
168 /* Drop .charset identifier; it is not used. */
169 const char *csp = memchr(locname, '.', loclen);
170 if (csp) loclen = csp-locname;
171
172 char name[dirlen+1 + loclen+modlen+1 + catlen+1 + domlen+3 + 1];
173 const void *map;
174
175 for (;;) {
176 snprintf(name, sizeof name, "%s/%.*s%.*s/%s/%s.mo\0",
177 dirname, (int)loclen, locname,
178 (int)alt_modlen, modname, catname, domainname);
179 if (map = __map_file(name, &map_size)) break;
180
181 /* Try dropping @mod, _YY, then both. */
182 if (alt_modlen) {
183 alt_modlen = 0;
184 } else if ((locp = memchr(locname, '_', loclen))) {
185 loclen = locp-locname;
186 alt_modlen = modlen;
187 } else {
188 break;
189 }
190 }
191 if (!map) goto notrans;
192
193 p = calloc(sizeof *p, 1);
194 if (!p) {
195 __munmap((void *)map, map_size);
196 goto notrans;
197 }
198 p->cat = category;
199 p->binding = q;
200 p->lm = lm;
201 p->map = map;
202 p->map_size = map_size;
203
204 const char *rule = "n!=1;";
205 unsigned long np = 2;
206 const char *r = __mo_lookup(p->map, p->map_size, "");
207 char *z;
208 while (r && strncmp(r, "Plural-Forms:", 13)) {
209 z = strchr(r, '\n');
210 r = z ? z+1 : 0;
211 }
212 if (r) {
213 r += 13;
214 while (isspace(*r)) r++;
215 if (!strncmp(r, "nplurals=", 9)) {
216 np = strtoul(r+9, &z, 10);
217 r = z;
218 }
219 while (*r && *r != ';') r++;
220 if (*r) {
221 r++;
222 while (isspace(*r)) r++;
223 if (!strncmp(r, "plural=", 7))
224 rule = r+7;
225 }
226 }
227 p->nplurals = np;
228 p->plural_rule = rule;
229
230 do {
231 old_cats = cats;
232 p->next = old_cats;
233 } while (a_cas_p(&cats, old_cats, p) != old_cats);
234 }
235
236 const char *trans = __mo_lookup(p->map, p->map_size, msgid1);
237 if (!trans) goto notrans;
238
239 /* Non-plural-processing gettext forms pass a null pointer as
240 * msgid2 to request that dcngettext suppress plural processing. */
241
242 if (msgid2 && p->nplurals) {
243 unsigned long plural = __pleval(p->plural_rule, n);
244 if (plural > p->nplurals) goto notrans;
245 while (plural--) {
246 size_t rem = p->map_size - (trans - (char *)p->map);
247 size_t l = strnlen(trans, rem);
248 if (l+1 >= rem)
249 goto notrans;
250 trans += l+1;
251 }
252 }
253 return (char *)trans;
254}
255
256char *dcgettext(const char *domainname, const char *msgid, int category)
257{
258 return dcngettext(domainname, msgid, 0, 1, category);
259}
260
261char *dngettext(const char *domainname, const char *msgid1, const char *msgid2, unsigned long int n)
262{
263 return dcngettext(domainname, msgid1, msgid2, n, LC_MESSAGES);
264}
265
266char *dgettext(const char *domainname, const char *msgid)
267{
268 return dcngettext(domainname, msgid, 0, 1, LC_MESSAGES);
269}
libc/musl/src/locale/duplocale.c created+15
......@@ -0,0 +1,15 @@
1#include <stdlib.h>
2#include <string.h>
3#include "locale_impl.h"
4#include "libc.h"
5
6locale_t __duplocale(locale_t old)
7{
8 locale_t new = malloc(sizeof *new);
9 if (!new) return 0;
10 if (old == LC_GLOBAL_LOCALE) old = &libc.global_locale;
11 *new = *old;
12 return new;
13}
14
15weak_alias(__duplocale, duplocale);
libc/musl/src/locale/freelocale.c created+9
......@@ -0,0 +1,9 @@
1#include <stdlib.h>
2#include "locale_impl.h"
3
4void freelocale(locale_t l)
5{
6 if (__loc_is_allocated(l)) free(l);
7}
8
9weak_alias(freelocale, __freelocale);
libc/musl/src/locale/gb18030.h created+1866
......@@ -0,0 +1,1866 @@
119970,19972,19973,19974,19983,19986,19991,19999,20000,20001,20003,20006,20009,
220014,20015,20017,20019,20021,20023,20028,20032,20033,20034,20036,20038,20042,
320049,20053,20055,20058,20059,20066,20067,20068,20069,20071,20072,20074,20075,
420076,20077,20078,20079,20082,20084,20085,20086,20087,20088,20089,20090,20091,
520092,20093,20095,20096,20097,20098,20099,20100,20101,20103,20106,20112,20118,
620119,20121,20124,20125,20126,20131,20138,20143,20144,20145,20148,20150,20151,
720152,20153,20156,20157,20158,20168,20172,20175,20176,20178,20186,20187,20188,
820192,20194,20198,20199,20201,20205,20206,20207,20209,20212,20216,20217,20218,
920220,20222,20224,20226,20227,20228,20229,20230,20231,20232,20235,20236,20242,
1020243,20244,20245,20246,20252,20253,20257,20259,20264,20265,20268,20269,20270,
1120273,20275,20277,20279,20281,20283,20286,20287,20288,20289,20290,20292,20293,
1220295,20296,20297,20298,20299,20300,20306,20308,20310,20321,20322,20326,20328,
1320330,20331,20333,20334,20337,20338,20341,20343,20344,20345,20346,20349,20352,
1420353,20354,20357,20358,20359,20362,20364,20366,20368,20370,20371,20373,20374,
1520376,20377,20378,20380,20382,20383,20385,20386,20388,20395,20397,20400,20401,
1620402,20403,20404,20406,20407,20408,20409,20410,20411,20412,20413,20414,20416,
1720417,20418,20422,20423,20424,20425,20427,20428,20429,20434,20435,20436,20437,
1820438,20441,20443,20448,20450,20452,20453,20455,20459,20460,20464,20466,20468,
1920469,20470,20471,20473,20475,20476,20477,20479,20480,20481,20482,20483,20484,
2020485,20486,20487,20488,20489,20490,20491,20494,
2120496,20497,20499,20501,20502,20503,20507,20509,20510,20512,20514,20515,20516,
2220519,20523,20527,20528,20529,20530,20531,20532,20533,20534,20535,20536,20537,
2320539,20541,20543,20544,20545,20546,20548,20549,20550,20553,20554,20555,20557,
2420560,20561,20562,20563,20564,20566,20567,20568,20569,20571,20573,20574,20575,
2520576,20577,20578,20579,20580,20582,20583,20584,20585,20586,20587,20589,20590,
2620591,20592,20593,20594,20595,20596,20597,20600,20601,20602,20604,20605,20609,
2720610,20611,20612,20614,20615,20617,20618,20619,20620,20622,20623,20624,20625,
2820626,20627,20628,20629,20630,20631,20632,20633,20634,20635,20636,20637,20638,
2920639,20640,20641,20642,20644,20646,20650,20651,20653,20654,20655,20656,20657,
3020659,20660,20661,20662,20663,20664,20665,20668,20669,20670,20671,20672,20673,
3120674,20675,20676,20677,20678,20679,20680,20681,20682,20683,20684,20685,20686,
3220688,20689,20690,20691,20692,20693,20695,20696,20697,20699,20700,20701,20702,
3320703,20704,20705,20706,20707,20708,20709,20712,20713,20714,20715,20719,20720,
3420721,20722,20724,20726,20727,20728,20729,20730,20732,20733,20734,20735,20736,
3520737,20738,20739,20740,20741,20744,20745,20746,20748,20749,20750,20751,20752,
3620753,20755,20756,20757,20758,20759,20760,20761,20762,20763,20764,20765,20766,
3720767,20768,20770,20771,20772,20773,20774,20775,20776,20777,20778,20779,20780,
3820781,20782,20783,20784,20785,20786,20787,20788,20789,20790,20791,20792,20793,
3920794,20795,20796,20797,20798,20802,20807,20810,20812,20814,20815,20816,20818,
4020819,20823,20824,20825,20827,20829,20830,20831,20832,
4120833,20835,20836,20838,20839,20841,20842,20847,20850,20858,20862,20863,20867,
4220868,20870,20871,20874,20875,20878,20879,20880,20881,20883,20884,20888,20890,
4320893,20894,20895,20897,20899,20902,20903,20904,20905,20906,20909,20910,20916,
4420920,20921,20922,20926,20927,20929,20930,20931,20933,20936,20938,20941,20942,
4520944,20946,20947,20948,20949,20950,20951,20952,20953,20954,20956,20958,20959,
4620962,20963,20965,20966,20967,20968,20969,20970,20972,20974,20977,20978,20980,
4720983,20990,20996,20997,21001,21003,21004,21007,21008,21011,21012,21013,21020,
4821022,21023,21025,21026,21027,21029,21030,21031,21034,21036,21039,21041,21042,
4921044,21045,21052,21054,21060,21061,21062,21063,21064,21065,21067,21070,21071,
5021074,21075,21077,21079,21080,21081,21082,21083,21085,21087,21088,21090,21091,
5121092,21094,21096,21099,21100,21101,21102,21104,21105,21107,21108,21109,21110,
5221111,21112,21113,21114,21115,21116,21118,21120,21123,21124,21125,21126,21127,
5321129,21130,21131,21132,21133,21134,21135,21137,21138,21140,21141,21142,21143,
5421144,21145,21146,21148,21156,21157,21158,21159,21166,21167,21168,21172,21173,
5521174,21175,21176,21177,21178,21179,21180,21181,21184,21185,21186,21188,21189,
5621190,21192,21194,21196,21197,21198,21199,21201,21203,21204,21205,21207,21209,
5721210,21211,21212,21213,21214,21216,21217,21218,21219,21221,21222,21223,21224,
5821225,21226,21227,21228,21229,21230,21231,21233,21234,21235,21236,21237,21238,
5921239,21240,21243,21244,21245,21249,21250,21251,21252,21255,21257,21258,21259,
6021260,21262,21265,21266,21267,21268,21272,21275,21276,
6121278,21279,21282,21284,21285,21287,21288,21289,21291,21292,21293,21295,21296,
6221297,21298,21299,21300,21301,21302,21303,21304,21308,21309,21312,21314,21316,
6321318,21323,21324,21325,21328,21332,21336,21337,21339,21341,21349,21352,21354,
6421356,21357,21362,21366,21369,21371,21372,21373,21374,21376,21377,21379,21383,
6521384,21386,21390,21391,21392,21393,21394,21395,21396,21398,21399,21401,21403,
6621404,21406,21408,21409,21412,21415,21418,21419,21420,21421,21423,21424,21425,
6721426,21427,21428,21429,21431,21432,21433,21434,21436,21437,21438,21440,21443,
6821444,21445,21446,21447,21454,21455,21456,21458,21459,21461,21466,21468,21469,
6921470,21473,21474,21479,21492,21498,21502,21503,21504,21506,21509,21511,21515,
7021524,21528,21529,21530,21532,21538,21540,21541,21546,21552,21555,21558,21559,
7121562,21565,21567,21569,21570,21572,21573,21575,21577,21580,21581,21582,21583,
7221585,21594,21597,21598,21599,21600,21601,21603,21605,21607,21609,21610,21611,
7321612,21613,21614,21615,21616,21620,21625,21626,21630,21631,21633,21635,21637,
7421639,21640,21641,21642,21645,21649,21651,21655,21656,21660,21662,21663,21664,
7521665,21666,21669,21678,21680,21682,21685,21686,21687,21689,21690,21692,21694,
7621699,21701,21706,21707,21718,21720,21723,21728,21729,21730,21731,21732,21739,
7721740,21743,21744,21745,21748,21749,21750,21751,21752,21753,21755,21758,21760,
7821762,21763,21764,21765,21768,21770,21771,21772,21773,21774,21778,21779,21781,
7921782,21783,21784,21785,21786,21788,21789,21790,21791,21793,21797,21798,21800,
8021801,21803,21805,21810,21812,21813,21814,21816,21817,
8121818,21819,21821,21824,21826,21829,21831,21832,21835,21836,21837,21838,21839,
8221841,21842,21843,21844,21847,21848,21849,21850,21851,21853,21854,21855,21856,
8321858,21859,21864,21865,21867,21871,21872,21873,21874,21875,21876,21881,21882,
8421885,21887,21893,21894,21900,21901,21902,21904,21906,21907,21909,21910,21911,
8521914,21915,21918,21920,21921,21922,21923,21924,21925,21926,21928,21929,21930,
8621931,21932,21933,21934,21935,21936,21938,21940,21942,21944,21946,21948,21951,
8721952,21953,21954,21955,21958,21959,21960,21962,21963,21966,21967,21968,21973,
8821975,21976,21977,21978,21979,21982,21984,21986,21991,21993,21997,21998,22000,
8922001,22004,22006,22008,22009,22010,22011,22012,22015,22018,22019,22020,22021,
9022022,22023,22026,22027,22029,22032,22033,22034,22035,22036,22037,22038,22039,
9122041,22042,22044,22045,22048,22049,22050,22053,22054,22056,22057,22058,22059,
9222062,22063,22064,22067,22069,22071,22072,22074,22076,22077,22078,22080,22081,
9322082,22083,22084,22085,22086,22087,22088,22089,22090,22091,22095,22096,22097,
9422098,22099,22101,22102,22106,22107,22109,22110,22111,22112,22113,22115,22117,
9522118,22119,22125,22126,22127,22128,22130,22131,22132,22133,22135,22136,22137,
9622138,22141,22142,22143,22144,22145,22146,22147,22148,22151,22152,22153,22154,
9722155,22156,22157,22160,22161,22162,22164,22165,22166,22167,22168,22169,22170,
9822171,22172,22173,22174,22175,22176,22177,22178,22180,22181,22182,22183,22184,
9922185,22186,22187,22188,22189,22190,22192,22193,22194,22195,22196,22197,22198,
10022200,22201,22202,22203,22205,22206,22207,22208,22209,
10122210,22211,22212,22213,22214,22215,22216,22217,22219,22220,22221,22222,22223,
10222224,22225,22226,22227,22229,22230,22232,22233,22236,22243,22245,22246,22247,
10322248,22249,22250,22252,22254,22255,22258,22259,22262,22263,22264,22267,22268,
10422272,22273,22274,22277,22279,22283,22284,22285,22286,22287,22288,22289,22290,
10522291,22292,22293,22294,22295,22296,22297,22298,22299,22301,22302,22304,22305,
10622306,22308,22309,22310,22311,22315,22321,22322,22324,22325,22326,22327,22328,
10722332,22333,22335,22337,22339,22340,22341,22342,22344,22345,22347,22354,22355,
10822356,22357,22358,22360,22361,22370,22371,22373,22375,22380,22382,22384,22385,
10922386,22388,22389,22392,22393,22394,22397,22398,22399,22400,22401,22407,22408,
11022409,22410,22413,22414,22415,22416,22417,22420,22421,22422,22423,22424,22425,
11122426,22428,22429,22430,22431,22437,22440,22442,22444,22447,22448,22449,22451,
11222453,22454,22455,22457,22458,22459,22460,22461,22462,22463,22464,22465,22468,
11322469,22470,22471,22472,22473,22474,22476,22477,22480,22481,22483,22486,22487,
11422491,22492,22494,22497,22498,22499,22501,22502,22503,22504,22505,22506,22507,
11522508,22510,22512,22513,22514,22515,22517,22518,22519,22523,22524,22526,22527,
11622529,22531,22532,22533,22536,22537,22538,22540,22542,22543,22544,22546,22547,
11722548,22550,22551,22552,22554,22555,22556,22557,22559,22562,22563,22565,22566,
11822567,22568,22569,22571,22572,22573,22574,22575,22577,22578,22579,22580,22582,
11922583,22584,22585,22586,22587,22588,22589,22590,22591,22592,22593,22594,22595,
12022597,22598,22599,22600,22601,22602,22603,22606,22607,
12122608,22610,22611,22613,22614,22615,22617,22618,22619,22620,22621,22623,22624,
12222625,22626,22627,22628,22630,22631,22632,22633,22634,22637,22638,22639,22640,
12322641,22642,22643,22644,22645,22646,22647,22648,22649,22650,22651,22652,22653,
12422655,22658,22660,22662,22663,22664,22666,22667,22668,22669,22670,22671,22672,
12522673,22676,22677,22678,22679,22680,22683,22684,22685,22688,22689,22690,22691,
12622692,22693,22694,22695,22698,22699,22700,22701,22702,22703,22704,22705,22706,
12722707,22708,22709,22710,22711,22712,22713,22714,22715,22717,22718,22719,22720,
12822722,22723,22724,22726,22727,22728,22729,22730,22731,22732,22733,22734,22735,
12922736,22738,22739,22740,22742,22743,22744,22745,22746,22747,22748,22749,22750,
13022751,22752,22753,22754,22755,22757,22758,22759,22760,22761,22762,22765,22767,
13122769,22770,22772,22773,22775,22776,22778,22779,22780,22781,22782,22783,22784,
13222785,22787,22789,22790,22792,22793,22794,22795,22796,22798,22800,22801,22802,
13322803,22807,22808,22811,22813,22814,22816,22817,22818,22819,22822,22824,22828,
13422832,22834,22835,22837,22838,22843,22845,22846,22847,22848,22851,22853,22854,
13522858,22860,22861,22864,22866,22867,22873,22875,22876,22877,22878,22879,22881,
13622883,22884,22886,22887,22888,22889,22890,22891,22892,22893,22894,22895,22896,
13722897,22898,22901,22903,22906,22907,22908,22910,22911,22912,22917,22921,22923,
13822924,22926,22927,22928,22929,22932,22933,22936,22938,22939,22940,22941,22943,
13922944,22945,22946,22950,22951,22956,22957,22960,22961,22963,22964,22965,22966,
14022967,22968,22970,22972,22973,22975,22976,22977,22978,
14122979,22980,22981,22983,22984,22985,22988,22989,22990,22991,22997,22998,23001,
14223003,23006,23007,23008,23009,23010,23012,23014,23015,23017,23018,23019,23021,
14323022,23023,23024,23025,23026,23027,23028,23029,23030,23031,23032,23034,23036,
14423037,23038,23040,23042,23050,23051,23053,23054,23055,23056,23058,23060,23061,
14523062,23063,23065,23066,23067,23069,23070,23073,23074,23076,23078,23079,23080,
14623082,23083,23084,23085,23086,23087,23088,23091,23093,23095,23096,23097,23098,
14723099,23101,23102,23103,23105,23106,23107,23108,23109,23111,23112,23115,23116,
14823117,23118,23119,23120,23121,23122,23123,23124,23126,23127,23128,23129,23131,
14923132,23133,23134,23135,23136,23137,23139,23140,23141,23142,23144,23145,23147,
15023148,23149,23150,23151,23152,23153,23154,23155,23160,23161,23163,23164,23165,
15123166,23168,23169,23170,23171,23172,23173,23174,23175,23176,23177,23178,23179,
15223180,23181,23182,23183,23184,23185,23187,23188,23189,23190,23191,23192,23193,
15323196,23197,23198,23199,23200,23201,23202,23203,23204,23205,23206,23207,23208,
15423209,23211,23212,23213,23214,23215,23216,23217,23220,23222,23223,23225,23226,
15523227,23228,23229,23231,23232,23235,23236,23237,23238,23239,23240,23242,23243,
15623245,23246,23247,23248,23249,23251,23253,23255,23257,23258,23259,23261,23262,
15723263,23266,23268,23269,23271,23272,23274,23276,23277,23278,23279,23280,23282,
15823283,23284,23285,23286,23287,23288,23289,23290,23291,23292,23293,23294,23295,
15923296,23297,23298,23299,23300,23301,23302,23303,23304,23306,23307,23308,23309,
16023310,23311,23312,23313,23314,23315,23316,23317,23320,
16123321,23322,23323,23324,23325,23326,23327,23328,23329,23330,23331,23332,23333,
16223334,23335,23336,23337,23338,23339,23340,23341,23342,23343,23344,23345,23347,
16323349,23350,23352,23353,23354,23355,23356,23357,23358,23359,23361,23362,23363,
16423364,23365,23366,23367,23368,23369,23370,23371,23372,23373,23374,23375,23378,
16523382,23390,23392,23393,23399,23400,23403,23405,23406,23407,23410,23412,23414,
16623415,23416,23417,23419,23420,23422,23423,23426,23430,23434,23437,23438,23440,
16723441,23442,23444,23446,23455,23463,23464,23465,23468,23469,23470,23471,23473,
16823474,23479,23482,23483,23484,23488,23489,23491,23496,23497,23498,23499,23501,
16923502,23503,23505,23508,23509,23510,23511,23512,23513,23514,23515,23516,23520,
17023522,23523,23526,23527,23529,23530,23531,23532,23533,23535,23537,23538,23539,
17123540,23541,23542,23543,23549,23550,23552,23554,23555,23557,23559,23560,23563,
17223564,23565,23566,23568,23570,23571,23575,23577,23579,23582,23583,23584,23585,
17323587,23590,23592,23593,23594,23595,23597,23598,23599,23600,23602,23603,23605,
17423606,23607,23619,23620,23622,23623,23628,23629,23634,23635,23636,23638,23639,
17523640,23642,23643,23644,23645,23647,23650,23652,23655,23656,23657,23658,23659,
17623660,23661,23664,23666,23667,23668,23669,23670,23671,23672,23675,23676,23677,
17723678,23680,23683,23684,23685,23686,23687,23689,23690,23691,23694,23695,23698,
17823699,23701,23709,23710,23711,23712,23713,23716,23717,23718,23719,23720,23722,
17923726,23727,23728,23730,23732,23734,23737,23738,23739,23740,23742,23744,23746,
18023747,23749,23750,23751,23752,23753,23754,23756,23757,
18123758,23759,23760,23761,23763,23764,23765,23766,23767,23768,23770,23771,23772,
18223773,23774,23775,23776,23778,23779,23783,23785,23787,23788,23790,23791,23793,
18323794,23795,23796,23797,23798,23799,23800,23801,23802,23804,23805,23806,23807,
18423808,23809,23812,23813,23816,23817,23818,23819,23820,23821,23823,23824,23825,
18523826,23827,23829,23831,23832,23833,23834,23836,23837,23839,23840,23841,23842,
18623843,23845,23848,23850,23851,23852,23855,23856,23857,23858,23859,23861,23862,
18723863,23864,23865,23866,23867,23868,23871,23872,23873,23874,23875,23876,23877,
18823878,23880,23881,23885,23886,23887,23888,23889,23890,23891,23892,23893,23894,
18923895,23897,23898,23900,23902,23903,23904,23905,23906,23907,23908,23909,23910,
19023911,23912,23914,23917,23918,23920,23921,23922,23923,23925,23926,23927,23928,
19123929,23930,23931,23932,23933,23934,23935,23936,23937,23939,23940,23941,23942,
19223943,23944,23945,23946,23947,23948,23949,23950,23951,23952,23953,23954,23955,
19323956,23957,23958,23959,23960,23962,23963,23964,23966,23967,23968,23969,23970,
19423971,23972,23973,23974,23975,23976,23977,23978,23979,23980,23981,23982,23983,
19523984,23985,23986,23987,23988,23989,23990,23992,23993,23994,23995,23996,23997,
19623998,23999,24000,24001,24002,24003,24004,24006,24007,24008,24009,24010,24011,
19724012,24014,24015,24016,24017,24018,24019,24020,24021,24022,24023,24024,24025,
19824026,24028,24031,24032,24035,24036,24042,24044,24045,24048,24053,24054,24056,
19924057,24058,24059,24060,24063,24064,24068,24071,24073,24074,24075,24077,24078,
20024082,24083,24087,24094,24095,24096,24097,24098,24099,
20124100,24101,24104,24105,24106,24107,24108,24111,24112,24114,24115,24116,24117,
20224118,24121,24122,24126,24127,24128,24129,24131,24134,24135,24136,24137,24138,
20324139,24141,24142,24143,24144,24145,24146,24147,24150,24151,24152,24153,24154,
20424156,24157,24159,24160,24163,24164,24165,24166,24167,24168,24169,24170,24171,
20524172,24173,24174,24175,24176,24177,24181,24183,24185,24190,24193,24194,24195,
20624197,24200,24201,24204,24205,24206,24210,24216,24219,24221,24225,24226,24227,
20724228,24232,24233,24234,24235,24236,24238,24239,24240,24241,24242,24244,24250,
20824251,24252,24253,24255,24256,24257,24258,24259,24260,24261,24262,24263,24264,
20924267,24268,24269,24270,24271,24272,24276,24277,24279,24280,24281,24282,24284,
21024285,24286,24287,24288,24289,24290,24291,24292,24293,24294,24295,24297,24299,
21124300,24301,24302,24303,24304,24305,24306,24307,24309,24312,24313,24315,24316,
21224317,24325,24326,24327,24329,24332,24333,24334,24336,24338,24340,24342,24345,
21324346,24348,24349,24350,24353,24354,24355,24356,24360,24363,24364,24366,24368,
21424370,24371,24372,24373,24374,24375,24376,24379,24381,24382,24383,24385,24386,
21524387,24388,24389,24390,24391,24392,24393,24394,24395,24396,24397,24398,24399,
21624401,24404,24409,24410,24411,24412,24414,24415,24416,24419,24421,24423,24424,
21724427,24430,24431,24434,24436,24437,24438,24440,24442,24445,24446,24447,24451,
21824454,24461,24462,24463,24465,24467,24468,24470,24474,24475,24477,24478,24479,
21924480,24482,24483,24484,24485,24486,24487,24489,24491,24492,24495,24496,24497,
22024498,24499,24500,24502,24504,24505,24506,24507,24510,
22124511,24512,24513,24514,24519,24520,24522,24523,24526,24531,24532,24533,24538,
22224539,24540,24542,24543,24546,24547,24549,24550,24552,24553,24556,24559,24560,
22324562,24563,24564,24566,24567,24569,24570,24572,24583,24584,24585,24587,24588,
22424592,24593,24595,24599,24600,24602,24606,24607,24610,24611,24612,24620,24621,
22524622,24624,24625,24626,24627,24628,24630,24631,24632,24633,24634,24637,24638,
22624640,24644,24645,24646,24647,24648,24649,24650,24652,24654,24655,24657,24659,
22724660,24662,24663,24664,24667,24668,24670,24671,24672,24673,24677,24678,24686,
22824689,24690,24692,24693,24695,24702,24704,24705,24706,24709,24710,24711,24712,
22924714,24715,24718,24719,24720,24721,24723,24725,24727,24728,24729,24732,24734,
23024737,24738,24740,24741,24743,24745,24746,24750,24752,24755,24757,24758,24759,
23124761,24762,24765,24766,24767,24768,24769,24770,24771,24772,24775,24776,24777,
23224780,24781,24782,24783,24784,24786,24787,24788,24790,24791,24793,24795,24798,
23324801,24802,24803,24804,24805,24810,24817,24818,24821,24823,24824,24827,24828,
23424829,24830,24831,24834,24835,24836,24837,24839,24842,24843,24844,24848,24849,
23524850,24851,24852,24854,24855,24856,24857,24859,24860,24861,24862,24865,24866,
23624869,24872,24873,24874,24876,24877,24878,24879,24880,24881,24882,24883,24884,
23724885,24886,24887,24888,24889,24890,24891,24892,24893,24894,24896,24897,24898,
23824899,24900,24901,24902,24903,24905,24907,24909,24911,24912,24914,24915,24916,
23924918,24919,24920,24921,24922,24923,24924,24926,24927,24928,24929,24931,24932,
24024933,24934,24937,24938,24939,24940,24941,24942,24943,
24124945,24946,24947,24948,24950,24952,24953,24954,24955,24956,24957,24958,24959,
24224960,24961,24962,24963,24964,24965,24966,24967,24968,24969,24970,24972,24973,
24324975,24976,24977,24978,24979,24981,24982,24983,24984,24985,24986,24987,24988,
24424990,24991,24992,24993,24994,24995,24996,24997,24998,25002,25003,25005,25006,
24525007,25008,25009,25010,25011,25012,25013,25014,25016,25017,25018,25019,25020,
24625021,25023,25024,25025,25027,25028,25029,25030,25031,25033,25036,25037,25038,
24725039,25040,25043,25045,25046,25047,25048,25049,25050,25051,25052,25053,25054,
24825055,25056,25057,25058,25059,25060,25061,25063,25064,25065,25066,25067,25068,
24925069,25070,25071,25072,25073,25074,25075,25076,25078,25079,25080,25081,25082,
25025083,25084,25085,25086,25088,25089,25090,25091,25092,25093,25095,25097,25107,
25125108,25113,25116,25117,25118,25120,25123,25126,25127,25128,25129,25131,25133,
25225135,25136,25137,25138,25141,25142,25144,25145,25146,25147,25148,25154,25156,
25325157,25158,25162,25167,25168,25173,25174,25175,25177,25178,25180,25181,25182,
25425183,25184,25185,25186,25188,25189,25192,25201,25202,25204,25205,25207,25208,
25525210,25211,25213,25217,25218,25219,25221,25222,25223,25224,25227,25228,25229,
25625230,25231,25232,25236,25241,25244,25245,25246,25251,25254,25255,25257,25258,
25725261,25262,25263,25264,25266,25267,25268,25270,25271,25272,25274,25278,25280,
25825281,25283,25291,25295,25297,25301,25309,25310,25312,25313,25316,25322,25323,
25925328,25330,25333,25336,25337,25338,25339,25344,25347,25348,25349,25350,25354,
26025355,25356,25357,25359,25360,25362,25363,25364,25365,
26125367,25368,25369,25372,25382,25383,25385,25388,25389,25390,25392,25393,25395,
26225396,25397,25398,25399,25400,25403,25404,25406,25407,25408,25409,25412,25415,
26325416,25418,25425,25426,25427,25428,25430,25431,25432,25433,25434,25435,25436,
26425437,25440,25444,25445,25446,25448,25450,25451,25452,25455,25456,25458,25459,
26525460,25461,25464,25465,25468,25469,25470,25471,25473,25475,25476,25477,25478,
26625483,25485,25489,25491,25492,25493,25495,25497,25498,25499,25500,25501,25502,
26725503,25505,25508,25510,25515,25519,25521,25522,25525,25526,25529,25531,25533,
26825535,25536,25537,25538,25539,25541,25543,25544,25546,25547,25548,25553,25555,
26925556,25557,25559,25560,25561,25562,25563,25564,25565,25567,25570,25572,25573,
27025574,25575,25576,25579,25580,25582,25583,25584,25585,25587,25589,25591,25593,
27125594,25595,25596,25598,25603,25604,25606,25607,25608,25609,25610,25613,25614,
27225617,25618,25621,25622,25623,25624,25625,25626,25629,25631,25634,25635,25636,
27325637,25639,25640,25641,25643,25646,25647,25648,25649,25650,25651,25653,25654,
27425655,25656,25657,25659,25660,25662,25664,25666,25667,25673,25675,25676,25677,
27525678,25679,25680,25681,25683,25685,25686,25687,25689,25690,25691,25692,25693,
27625695,25696,25697,25698,25699,25700,25701,25702,25704,25706,25707,25708,25710,
27725711,25712,25713,25714,25715,25716,25717,25718,25719,25723,25724,25725,25726,
27825727,25728,25729,25731,25734,25736,25737,25738,25739,25740,25741,25742,25743,
27925744,25747,25748,25751,25752,25754,25755,25756,25757,25759,25760,25761,25762,
28025763,25765,25766,25767,25768,25770,25771,25775,25777,
28125778,25779,25780,25782,25785,25787,25789,25790,25791,25793,25795,25796,25798,
28225799,25800,25801,25802,25803,25804,25807,25809,25811,25812,25813,25814,25817,
28325818,25819,25820,25821,25823,25824,25825,25827,25829,25831,25832,25833,25834,
28425835,25836,25837,25838,25839,25840,25841,25842,25843,25844,25845,25846,25847,
28525848,25849,25850,25851,25852,25853,25854,25855,25857,25858,25859,25860,25861,
28625862,25863,25864,25866,25867,25868,25869,25870,25871,25872,25873,25875,25876,
28725877,25878,25879,25881,25882,25883,25884,25885,25886,25887,25888,25889,25890,
28825891,25892,25894,25895,25896,25897,25898,25900,25901,25904,25905,25906,25907,
28925911,25914,25916,25917,25920,25921,25922,25923,25924,25926,25927,25930,25931,
29025933,25934,25936,25938,25939,25940,25943,25944,25946,25948,25951,25952,25953,
29125956,25957,25959,25960,25961,25962,25965,25966,25967,25969,25971,25973,25974,
29225976,25977,25978,25979,25980,25981,25982,25983,25984,25985,25986,25987,25988,
29325989,25990,25992,25993,25994,25997,25998,25999,26002,26004,26005,26006,26008,
29426010,26013,26014,26016,26018,26019,26022,26024,26026,26028,26030,26033,26034,
29526035,26036,26037,26038,26039,26040,26042,26043,26046,26047,26048,26050,26055,
29626056,26057,26058,26061,26064,26065,26067,26068,26069,26072,26073,26074,26075,
29726076,26077,26078,26079,26081,26083,26084,26090,26091,26098,26099,26100,26101,
29826104,26105,26107,26108,26109,26110,26111,26113,26116,26117,26119,26120,26121,
29926123,26125,26128,26129,26130,26134,26135,26136,26138,26139,26140,26142,26145,
30026146,26147,26148,26150,26153,26154,26155,26156,26158,
30126160,26162,26163,26167,26168,26169,26170,26171,26173,26175,26176,26178,26180,
30226181,26182,26183,26184,26185,26186,26189,26190,26192,26193,26200,26201,26203,
30326204,26205,26206,26208,26210,26211,26213,26215,26217,26218,26219,26220,26221,
30426225,26226,26227,26229,26232,26233,26235,26236,26237,26239,26240,26241,26243,
30526245,26246,26248,26249,26250,26251,26253,26254,26255,26256,26258,26259,26260,
30626261,26264,26265,26266,26267,26268,26270,26271,26272,26273,26274,26275,26276,
30726277,26278,26281,26282,26283,26284,26285,26287,26288,26289,26290,26291,26293,
30826294,26295,26296,26298,26299,26300,26301,26303,26304,26305,26306,26307,26308,
30926309,26310,26311,26312,26313,26314,26315,26316,26317,26318,26319,26320,26321,
31026322,26323,26324,26325,26326,26327,26328,26330,26334,26335,26336,26337,26338,
31126339,26340,26341,26343,26344,26346,26347,26348,26349,26350,26351,26353,26357,
31226358,26360,26362,26363,26365,26369,26370,26371,26372,26373,26374,26375,26380,
31326382,26383,26385,26386,26387,26390,26392,26393,26394,26396,26398,26400,26401,
31426402,26403,26404,26405,26407,26409,26414,26416,26418,26419,26422,26423,26424,
31526425,26427,26428,26430,26431,26433,26436,26437,26439,26442,26443,26445,26450,
31626452,26453,26455,26456,26457,26458,26459,26461,26466,26467,26468,26470,26471,
31726475,26476,26478,26481,26484,26486,26488,26489,26490,26491,26493,26496,26498,
31826499,26501,26502,26504,26506,26508,26509,26510,26511,26513,26514,26515,26516,
31926518,26521,26523,26527,26528,26529,26532,26534,26537,26540,26542,26545,26546,
32026548,26553,26554,26555,26556,26557,26558,26559,26560,
32126562,26565,26566,26567,26568,26569,26570,26571,26572,26573,26574,26581,26582,
32226583,26587,26591,26593,26595,26596,26598,26599,26600,26602,26603,26605,26606,
32326610,26613,26614,26615,26616,26617,26618,26619,26620,26622,26625,26626,26627,
32426628,26630,26637,26640,26642,26644,26645,26648,26649,26650,26651,26652,26654,
32526655,26656,26658,26659,26660,26661,26662,26663,26664,26667,26668,26669,26670,
32626671,26672,26673,26676,26677,26678,26682,26683,26687,26695,26699,26701,26703,
32726706,26710,26711,26712,26713,26714,26715,26716,26717,26718,26719,26730,26732,
32826733,26734,26735,26736,26737,26738,26739,26741,26744,26745,26746,26747,26748,
32926749,26750,26751,26752,26754,26756,26759,26760,26761,26762,26763,26764,26765,
33026766,26768,26769,26770,26772,26773,26774,26776,26777,26778,26779,26780,26781,
33126782,26783,26784,26785,26787,26788,26789,26793,26794,26795,26796,26798,26801,
33226802,26804,26806,26807,26808,26809,26810,26811,26812,26813,26814,26815,26817,
33326819,26820,26821,26822,26823,26824,26826,26828,26830,26831,26832,26833,26835,
33426836,26838,26839,26841,26843,26844,26845,26846,26847,26849,26850,26852,26853,
33526854,26855,26856,26857,26858,26859,26860,26861,26863,26866,26867,26868,26870,
33626871,26872,26875,26877,26878,26879,26880,26882,26883,26884,26886,26887,26888,
33726889,26890,26892,26895,26897,26899,26900,26901,26902,26903,26904,26905,26906,
33826907,26908,26909,26910,26913,26914,26915,26917,26918,26919,26920,26921,26922,
33926923,26924,26926,26927,26929,26930,26931,26933,26934,26935,26936,26938,26939,
34026940,26942,26944,26945,26947,26948,26949,26950,26951,
34126952,26953,26954,26955,26956,26957,26958,26959,26960,26961,26962,26963,26965,
34226966,26968,26969,26971,26972,26975,26977,26978,26980,26981,26983,26984,26985,
34326986,26988,26989,26991,26992,26994,26995,26996,26997,26998,27002,27003,27005,
34427006,27007,27009,27011,27013,27018,27019,27020,27022,27023,27024,27025,27026,
34527027,27030,27031,27033,27034,27037,27038,27039,27040,27041,27042,27043,27044,
34627045,27046,27049,27050,27052,27054,27055,27056,27058,27059,27061,27062,27064,
34727065,27066,27068,27069,27070,27071,27072,27074,27075,27076,27077,27078,27079,
34827080,27081,27083,27085,27087,27089,27090,27091,27093,27094,27095,27096,27097,
34927098,27100,27101,27102,27105,27106,27107,27108,27109,27110,27111,27112,27113,
35027114,27115,27116,27118,27119,27120,27121,27123,27124,27125,27126,27127,27128,
35127129,27130,27131,27132,27134,27136,27137,27138,27139,27140,27141,27142,27143,
35227144,27145,27147,27148,27149,27150,27151,27152,27153,27154,27155,27156,27157,
35327158,27161,27162,27163,27164,27165,27166,27168,27170,27171,27172,27173,27174,
35427175,27177,27179,27180,27181,27182,27184,27186,27187,27188,27190,27191,27192,
35527193,27194,27195,27196,27199,27200,27201,27202,27203,27205,27206,27208,27209,
35627210,27211,27212,27213,27214,27215,27217,27218,27219,27220,27221,27222,27223,
35727226,27228,27229,27230,27231,27232,27234,27235,27236,27238,27239,27240,27241,
35827242,27243,27244,27245,27246,27247,27248,27250,27251,27252,27253,27254,27255,
35927256,27258,27259,27261,27262,27263,27265,27266,27267,27269,27270,27271,27272,
36027273,27274,27275,27276,27277,27279,27282,27283,27284,
36127285,27286,27288,27289,27290,27291,27292,27293,27294,27295,27297,27298,27299,
36227300,27301,27302,27303,27304,27306,27309,27310,27311,27312,27313,27314,27315,
36327316,27317,27318,27319,27320,27321,27322,27323,27324,27325,27326,27327,27328,
36427329,27330,27331,27332,27333,27334,27335,27336,27337,27338,27339,27340,27341,
36527342,27343,27344,27345,27346,27347,27348,27349,27350,27351,27352,27353,27354,
36627355,27356,27357,27358,27359,27360,27361,27362,27363,27364,27365,27366,27367,
36727368,27369,27370,27371,27372,27373,27374,27375,27376,27377,27378,27379,27380,
36827381,27382,27383,27384,27385,27386,27387,27388,27389,27390,27391,27392,27393,
36927394,27395,27396,27397,27398,27399,27400,27401,27402,27403,27404,27405,27406,
37027407,27408,27409,27410,27411,27412,27413,27414,27415,27416,27417,27418,27419,
37127420,27421,27422,27423,27429,27430,27432,27433,27434,27435,27436,27437,27438,
37227439,27440,27441,27443,27444,27445,27446,27448,27451,27452,27453,27455,27456,
37327457,27458,27460,27461,27464,27466,27467,27469,27470,27471,27472,27473,27474,
37427475,27476,27477,27478,27479,27480,27482,27483,27484,27485,27486,27487,27488,
37527489,27496,27497,27499,27500,27501,27502,27503,27504,27505,27506,27507,27508,
37627509,27510,27511,27512,27514,27517,27518,27519,27520,27525,27528,27532,27534,
37727535,27536,27537,27540,27541,27543,27544,27545,27548,27549,27550,27551,27552,
37827554,27555,27556,27557,27558,27559,27560,27561,27563,27564,27565,27566,27567,
37927568,27569,27570,27574,27576,27577,27578,27579,27580,27581,27582,27584,27587,
38027588,27590,27591,27592,27593,27594,27596,27598,27600,
38127601,27608,27610,27612,27613,27614,27615,27616,27618,27619,27620,27621,27622,
38227623,27624,27625,27628,27629,27630,27632,27633,27634,27636,27638,27639,27640,
38327642,27643,27644,27646,27647,27648,27649,27650,27651,27652,27656,27657,27658,
38427659,27660,27662,27666,27671,27676,27677,27678,27680,27683,27685,27691,27692,
38527693,27697,27699,27702,27703,27705,27706,27707,27708,27710,27711,27715,27716,
38627717,27720,27723,27724,27725,27726,27727,27729,27730,27731,27734,27736,27737,
38727738,27746,27747,27749,27750,27751,27755,27756,27757,27758,27759,27761,27763,
38827765,27767,27768,27770,27771,27772,27775,27776,27780,27783,27786,27787,27789,
38927790,27793,27794,27797,27798,27799,27800,27802,27804,27805,27806,27808,27810,
39027816,27820,27823,27824,27828,27829,27830,27831,27834,27840,27841,27842,27843,
39127846,27847,27848,27851,27853,27854,27855,27857,27858,27864,27865,27866,27868,
39227869,27871,27876,27878,27879,27881,27884,27885,27890,27892,27897,27903,27904,
39327906,27907,27909,27910,27912,27913,27914,27917,27919,27920,27921,27923,27924,
39427925,27926,27928,27932,27933,27935,27936,27937,27938,27939,27940,27942,27944,
39527945,27948,27949,27951,27952,27956,27958,27959,27960,27962,27967,27968,27970,
39627972,27977,27980,27984,27989,27990,27991,27992,27995,27997,27999,28001,28002,
39728004,28005,28007,28008,28011,28012,28013,28016,28017,28018,28019,28021,28022,
39828025,28026,28027,28029,28030,28031,28032,28033,28035,28036,28038,28039,28042,
39928043,28045,28047,28048,28050,28054,28055,28056,28057,28058,28060,28066,28069,
40028076,28077,28080,28081,28083,28084,28086,28087,28089,
40128090,28091,28092,28093,28094,28097,28098,28099,28104,28105,28106,28109,28110,
40228111,28112,28114,28115,28116,28117,28119,28122,28123,28124,28127,28130,28131,
40328133,28135,28136,28137,28138,28141,28143,28144,28146,28148,28149,28150,28152,
40428154,28157,28158,28159,28160,28161,28162,28163,28164,28166,28167,28168,28169,
40528171,28175,28178,28179,28181,28184,28185,28187,28188,28190,28191,28194,28198,
40628199,28200,28202,28204,28206,28208,28209,28211,28213,28214,28215,28217,28219,
40728220,28221,28222,28223,28224,28225,28226,28229,28230,28231,28232,28233,28234,
40828235,28236,28239,28240,28241,28242,28245,28247,28249,28250,28252,28253,28254,
40928256,28257,28258,28259,28260,28261,28262,28263,28264,28265,28266,28268,28269,
41028271,28272,28273,28274,28275,28276,28277,28278,28279,28280,28281,28282,28283,
41128284,28285,28288,28289,28290,28292,28295,28296,28298,28299,28300,28301,28302,
41228305,28306,28307,28308,28309,28310,28311,28313,28314,28315,28317,28318,28320,
41328321,28323,28324,28326,28328,28329,28331,28332,28333,28334,28336,28339,28341,
41428344,28345,28348,28350,28351,28352,28355,28356,28357,28358,28360,28361,28362,
41528364,28365,28366,28368,28370,28374,28376,28377,28379,28380,28381,28387,28391,
41628394,28395,28396,28397,28398,28399,28400,28401,28402,28403,28405,28406,28407,
41728408,28410,28411,28412,28413,28414,28415,28416,28417,28419,28420,28421,28423,
41828424,28426,28427,28428,28429,28430,28432,28433,28434,28438,28439,28440,28441,
41928442,28443,28444,28445,28446,28447,28449,28450,28451,28453,28454,28455,28456,
42028460,28462,28464,28466,28468,28469,28471,28472,28473,
42128474,28475,28476,28477,28479,28480,28481,28482,28483,28484,28485,28488,28489,
42228490,28492,28494,28495,28496,28497,28498,28499,28500,28501,28502,28503,28505,
42328506,28507,28509,28511,28512,28513,28515,28516,28517,28519,28520,28521,28522,
42428523,28524,28527,28528,28529,28531,28533,28534,28535,28537,28539,28541,28542,
42528543,28544,28545,28546,28547,28549,28550,28551,28554,28555,28559,28560,28561,
42628562,28563,28564,28565,28566,28567,28568,28569,28570,28571,28573,28574,28575,
42728576,28578,28579,28580,28581,28582,28584,28585,28586,28587,28588,28589,28590,
42828591,28592,28593,28594,28596,28597,28599,28600,28602,28603,28604,28605,28606,
42928607,28609,28611,28612,28613,28614,28615,28616,28618,28619,28620,28621,28622,
43028623,28624,28627,28628,28629,28630,28631,28632,28633,28634,28635,28636,28637,
43128639,28642,28643,28644,28645,28646,28647,28648,28649,28650,28651,28652,28653,
43228656,28657,28658,28659,28660,28661,28662,28663,28664,28665,28666,28667,28668,
43328669,28670,28671,28672,28673,28674,28675,28676,28677,28678,28679,28680,28681,
43428682,28683,28684,28685,28686,28687,28688,28690,28691,28692,28693,28694,28695,
43528696,28697,28700,28701,28702,28703,28704,28705,28706,28708,28709,28710,28711,
43628712,28713,28714,28715,28716,28717,28718,28719,28720,28721,28722,28723,28724,
43728726,28727,28728,28730,28731,28732,28733,28734,28735,28736,28737,28738,28739,
43828740,28741,28742,28743,28744,28745,28746,28747,28749,28750,28752,28753,28754,
43928755,28756,28757,28758,28759,28760,28761,28762,28763,28764,28765,28767,28768,
44028769,28770,28771,28772,28773,28774,28775,28776,28777,
44128778,28782,28785,28786,28787,28788,28791,28793,28794,28795,28797,28801,28802,
44228803,28804,28806,28807,28808,28811,28812,28813,28815,28816,28817,28819,28823,
44328824,28826,28827,28830,28831,28832,28833,28834,28835,28836,28837,28838,28839,
44428840,28841,28842,28848,28850,28852,28853,28854,28858,28862,28863,28868,28869,
44528870,28871,28873,28875,28876,28877,28878,28879,28880,28881,28882,28883,28884,
44628885,28886,28887,28890,28892,28893,28894,28896,28897,28898,28899,28901,28906,
44728910,28912,28913,28914,28915,28916,28917,28918,28920,28922,28923,28924,28926,
44828927,28928,28929,28930,28931,28932,28933,28934,28935,28936,28939,28940,28941,
44928942,28943,28945,28946,28948,28951,28955,28956,28957,28958,28959,28960,28961,
45028962,28963,28964,28965,28967,28968,28969,28970,28971,28972,28973,28974,28978,
45128979,28980,28981,28983,28984,28985,28986,28987,28988,28989,28990,28991,28992,
45228993,28994,28995,28996,28998,28999,29000,29001,29003,29005,29007,29008,29009,
45329010,29011,29012,29013,29014,29015,29016,29017,29018,29019,29021,29023,29024,
45429025,29026,29027,29029,29033,29034,29035,29036,29037,29039,29040,29041,29044,
45529045,29046,29047,29049,29051,29052,29054,29055,29056,29057,29058,29059,29061,
45629062,29063,29064,29065,29067,29068,29069,29070,29072,29073,29074,29075,29077,
45729078,29079,29082,29083,29084,29085,29086,29089,29090,29091,29092,29093,29094,
45829095,29097,29098,29099,29101,29102,29103,29104,29105,29106,29108,29110,29111,
45929112,29114,29115,29116,29117,29118,29119,29120,29121,29122,29124,29125,29126,
46029127,29128,29129,29130,29131,29132,29133,29135,29136,
46129137,29138,29139,29142,29143,29144,29145,29146,29147,29148,29149,29150,29151,
46229153,29154,29155,29156,29158,29160,29161,29162,29163,29164,29165,29167,29168,
46329169,29170,29171,29172,29173,29174,29175,29176,29178,29179,29180,29181,29182,
46429183,29184,29185,29186,29187,29188,29189,29191,29192,29193,29194,29195,29196,
46529197,29198,29199,29200,29201,29202,29203,29204,29205,29206,29207,29208,29209,
46629210,29211,29212,29214,29215,29216,29217,29218,29219,29220,29221,29222,29223,
46729225,29227,29229,29230,29231,29234,29235,29236,29242,29244,29246,29248,29249,
46829250,29251,29252,29253,29254,29257,29258,29259,29262,29263,29264,29265,29267,
46929268,29269,29271,29272,29274,29276,29278,29280,29283,29284,29285,29288,29290,
47029291,29292,29293,29296,29297,29299,29300,29302,29303,29304,29307,29308,29309,
47129314,29315,29317,29318,29319,29320,29321,29324,29326,29328,29329,29331,29332,
47229333,29334,29335,29336,29337,29338,29339,29340,29341,29342,29344,29345,29346,
47329347,29348,29349,29350,29351,29352,29353,29354,29355,29358,29361,29362,29363,
47429365,29370,29371,29372,29373,29374,29375,29376,29381,29382,29383,29385,29386,
47529387,29388,29391,29393,29395,29396,29397,29398,29400,29402,29403,58566,58567,
47658568,58569,58570,58571,58572,58573,58574,58575,58576,58577,58578,58579,58580,
47758581,58582,58583,58584,58585,58586,58587,58588,58589,58590,58591,58592,58593,
47858594,58595,58596,58597,58598,58599,58600,58601,58602,58603,58604,58605,58606,
47958607,58608,58609,58610,58611,58612,58613,58614,58615,58616,58617,58618,58619,
48058620,58621,58622,58623,58624,58625,58626,58627,58628,
48158629,58630,58631,58632,58633,58634,58635,58636,58637,58638,58639,58640,58641,
48258642,58643,58644,58645,58646,58647,58648,58649,58650,58651,58652,58653,58654,
48358655,58656,58657,58658,58659,58660,58661,12288,12289,12290,183,713,711,168,
48412291,12293,8212,65374,8214,8230,8216,8217,8220,8221,12308,12309,12296,12297,
48512298,12299,12300,12301,12302,12303,12310,12311,12304,12305,177,215,247,8758,
4868743,8744,8721,8719,8746,8745,8712,8759,8730,8869,8741,8736,8978,8857,8747,
4878750,8801,8780,8776,8765,8733,8800,8814,8815,8804,8805,8734,8757,8756,9794,
4889792,176,8242,8243,8451,65284,164,65504,65505,8240,167,8470,9734,9733,9675,
4899679,9678,9671,9670,9633,9632,9651,9650,8251,8594,8592,8593,8595,12307,58662,
49058663,58664,58665,58666,58667,58668,58669,58670,58671,58672,58673,58674,58675,
49158676,58677,58678,58679,58680,58681,58682,58683,58684,58685,58686,58687,58688,
49258689,58690,58691,58692,58693,58694,58695,58696,58697,58698,58699,58700,58701,
49358702,58703,58704,58705,58706,58707,58708,58709,58710,58711,58712,58713,58714,
49458715,58716,58717,58718,58719,58720,58721,58722,58723,58724,58725,58726,58727,
49558728,58729,58730,58731,58732,58733,58734,58735,58736,58737,58738,58739,58740,
49658741,58742,58743,58744,58745,58746,58747,58748,58749,58750,58751,58752,58753,
49758754,58755,58756,58757,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,
49859238,59239,59240,59241,59242,59243,9352,9353,9354,9355,9356,9357,9358,9359,
4999360,9361,9362,9363,9364,9365,9366,9367,9368,
5009369,9370,9371,9332,9333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,
5019344,9345,9346,9347,9348,9349,9350,9351,9312,9313,9314,9315,9316,9317,9318,
5029319,9320,9321,8364,59245,12832,12833,12834,12835,12836,12837,12838,12839,
50312840,12841,59246,59247,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,
5048554,8555,59248,59249,58758,58759,58760,58761,58762,58763,58764,58765,58766,
50558767,58768,58769,58770,58771,58772,58773,58774,58775,58776,58777,58778,58779,
50658780,58781,58782,58783,58784,58785,58786,58787,58788,58789,58790,58791,58792,
50758793,58794,58795,58796,58797,58798,58799,58800,58801,58802,58803,58804,58805,
50858806,58807,58808,58809,58810,58811,58812,58813,58814,58815,58816,58817,58818,
50958819,58820,58821,58822,58823,58824,58825,58826,58827,58828,58829,58830,58831,
51058832,58833,58834,58835,58836,58837,58838,58839,58840,58841,58842,58843,58844,
51158845,58846,58847,58848,58849,58850,58851,58852,58853,65281,65282,65283,65509,
51265285,65286,65287,65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,
51365298,65299,65300,65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,
51465311,65312,65313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,
51565324,65325,65326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,
51665337,65338,65339,65340,65341,65342,65343,65344,65345,65346,65347,65348,65349,
51765350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,65361,65362,
51865363,65364,65365,65366,65367,65368,65369,65370,65371,65372,65373,65507,58854,
51958855,58856,58857,58858,
52058859,58860,58861,58862,58863,58864,58865,58866,58867,58868,58869,58870,58871,
52158872,58873,58874,58875,58876,58877,58878,58879,58880,58881,58882,58883,58884,
52258885,58886,58887,58888,58889,58890,58891,58892,58893,58894,58895,58896,58897,
52358898,58899,58900,58901,58902,58903,58904,58905,58906,58907,58908,58909,58910,
52458911,58912,58913,58914,58915,58916,58917,58918,58919,58920,58921,58922,58923,
52558924,58925,58926,58927,58928,58929,58930,58931,58932,58933,58934,58935,58936,
52658937,58938,58939,58940,58941,58942,58943,58944,58945,58946,58947,58948,58949,
52712353,12354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,
52812366,12367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,
52912379,12380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,
53012392,12393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,
53112405,12406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,
53212418,12419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,
53312431,12432,12433,12434,12435,59250,59251,59252,59253,59254,59255,59256,59257,
53459258,59259,59260,58950,58951,58952,58953,58954,58955,58956,58957,58958,58959,
53558960,58961,58962,58963,58964,58965,58966,58967,58968,58969,58970,58971,58972,
53658973,58974,58975,58976,58977,58978,58979,58980,58981,58982,58983,58984,58985,
53758986,58987,58988,58989,58990,58991,58992,58993,58994,58995,58996,58997,58998,
53858999,59000,59001,59002,59003,59004,59005,59006,59007,59008,59009,59010,59011,
53959012,59013,59014,59015,59016,59017,59018,59019,59020,
54059021,59022,59023,59024,59025,59026,59027,59028,59029,59030,59031,59032,59033,
54159034,59035,59036,59037,59038,59039,59040,59041,59042,59043,59044,59045,12449,
54212450,12451,12452,12453,12454,12455,12456,12457,12458,12459,12460,12461,12462,
54312463,12464,12465,12466,12467,12468,12469,12470,12471,12472,12473,12474,12475,
54412476,12477,12478,12479,12480,12481,12482,12483,12484,12485,12486,12487,12488,
54512489,12490,12491,12492,12493,12494,12495,12496,12497,12498,12499,12500,12501,
54612502,12503,12504,12505,12506,12507,12508,12509,12510,12511,12512,12513,12514,
54712515,12516,12517,12518,12519,12520,12521,12522,12523,12524,12525,12526,12527,
54812528,12529,12530,12531,12532,12533,12534,59261,59262,59263,59264,59265,59266,
54959267,59268,59046,59047,59048,59049,59050,59051,59052,59053,59054,59055,59056,
55059057,59058,59059,59060,59061,59062,59063,59064,59065,59066,59067,59068,59069,
55159070,59071,59072,59073,59074,59075,59076,59077,59078,59079,59080,59081,59082,
55259083,59084,59085,59086,59087,59088,59089,59090,59091,59092,59093,59094,59095,
55359096,59097,59098,59099,59100,59101,59102,59103,59104,59105,59106,59107,59108,
55459109,59110,59111,59112,59113,59114,59115,59116,59117,59118,59119,59120,59121,
55559122,59123,59124,59125,59126,59127,59128,59129,59130,59131,59132,59133,59134,
55659135,59136,59137,59138,59139,59140,59141,913,914,915,916,917,918,919,920,921,
557922,923,924,925,926,927,928,929,931,932,933,934,935,936,937,59269,59270,59271,
55859272,59273,59274,59275,59276,945,946,947,948,949,950,951,952,953,
559954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,59277,59278,59279,
56059280,59281,59282,59283,65077,65078,65081,65082,65087,65088,65085,65086,65089,
56165090,65091,65092,59284,59285,65083,65084,65079,65080,65073,59286,65075,65076,
56259287,59288,59289,59290,59291,59292,59293,59294,59295,59142,59143,59144,59145,
56359146,59147,59148,59149,59150,59151,59152,59153,59154,59155,59156,59157,59158,
56459159,59160,59161,59162,59163,59164,59165,59166,59167,59168,59169,59170,59171,
56559172,59173,59174,59175,59176,59177,59178,59179,59180,59181,59182,59183,59184,
56659185,59186,59187,59188,59189,59190,59191,59192,59193,59194,59195,59196,59197,
56759198,59199,59200,59201,59202,59203,59204,59205,59206,59207,59208,59209,59210,
56859211,59212,59213,59214,59215,59216,59217,59218,59219,59220,59221,59222,59223,
56959224,59225,59226,59227,59228,59229,59230,59231,59232,59233,59234,59235,59236,
57059237,1040,1041,1042,1043,1044,1045,1025,1046,1047,1048,1049,1050,1051,1052,
5711053,1054,1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,
5721068,1069,1070,1071,59296,59297,59298,59299,59300,59301,59302,59303,59304,
57359305,59306,59307,59308,59309,59310,1072,1073,1074,1075,1076,1077,1105,1078,
5741079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,
5751094,1095,1096,1097,1098,1099,1100,1101,1102,1103,59311,59312,59313,59314,
57659315,59316,59317,59318,59319,59320,59321,59322,59323,714,715,729,8211,8213,
5778229,8245,8453,8457,8598,8599,8600,8601,
5788725,8735,8739,8786,8806,8807,8895,9552,9553,9554,9555,9556,9557,9558,9559,
5799560,9561,9562,9563,9564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,
5809575,9576,9577,9578,9579,9580,9581,9582,9583,9584,9585,9586,9587,9601,9602,
5819603,9604,9605,9606,9607,9608,9609,9610,9611,9612,9613,9614,9615,9619,9620,
5829621,9660,9661,9698,9699,9700,9701,9737,8853,12306,12317,12318,59324,59325,
58359326,59327,59328,59329,59330,59331,59332,59333,59334,257,225,462,224,275,233,
584283,232,299,237,464,236,333,243,466,242,363,250,468,249,470,472,474,476,252,
585234,593,59335,324,328,505,609,59337,59338,59339,59340,12549,12550,12551,12552,
58612553,12554,12555,12556,12557,12558,12559,12560,12561,12562,12563,12564,12565,
58712566,12567,12568,12569,12570,12571,12572,12573,12574,12575,12576,12577,12578,
58812579,12580,12581,12582,12583,12584,12585,59341,59342,59343,59344,59345,59346,
58959347,59348,59349,59350,59351,59352,59353,59354,59355,59356,59357,59358,59359,
59059360,59361,12321,12322,12323,12324,12325,12326,12327,12328,12329,12963,13198,
59113199,13212,13213,13214,13217,13252,13262,13265,13266,13269,65072,65506,65508,
59259362,8481,12849,59363,8208,59364,59365,59366,12540,12443,12444,12541,12542,
59312294,12445,12446,65097,65098,65099,65100,65101,65102,65103,65104,65105,65106,
59465108,65109,65110,65111,65113,65114,65115,65116,65117,65118,65119,65120,65121,
59565122,65123,65124,65125,65126,65128,65129,65130,65131,12350,12272,12273,12274,
59612275,12276,12277,
59712278,12279,12280,12281,12282,12283,12295,59380,59381,59382,59383,59384,59385,
59859386,59387,59388,59389,59390,59391,59392,9472,9473,9474,9475,9476,9477,9478,
5999479,9480,9481,9482,9483,9484,9485,9486,9487,9488,9489,9490,9491,9492,9493,
6009494,9495,9496,9497,9498,9499,9500,9501,9502,9503,9504,9505,9506,9507,9508,
6019509,9510,9511,9512,9513,9514,9515,9516,9517,9518,9519,9520,9521,9522,9523,
6029524,9525,9526,9527,9528,9529,9530,9531,9532,9533,9534,9535,9536,9537,9538,
6039539,9540,9541,9542,9543,9544,9545,9546,9547,59393,59394,59395,59396,59397,
60459398,59399,59400,59401,59402,59403,59404,59405,59406,59407,29404,29405,29407,
60529410,29411,29412,29413,29414,29415,29418,29419,29429,29430,29433,29437,29438,
60629439,29440,29442,29444,29445,29446,29447,29448,29449,29451,29452,29453,29455,
60729456,29457,29458,29460,29464,29465,29466,29471,29472,29475,29476,29478,29479,
60829480,29485,29487,29488,29490,29491,29493,29494,29498,29499,29500,29501,29504,
60929505,29506,29507,29508,29509,29510,29511,29512,29513,29514,29515,29516,29518,
61029519,29521,29523,29524,29525,29526,29528,29529,29530,29531,29532,29533,29534,
61129535,29537,29538,29539,29540,29541,29542,29543,29544,29545,29546,29547,29550,
61229552,29553,57344,57345,57346,57347,57348,57349,57350,57351,57352,57353,57354,
61357355,57356,57357,57358,57359,57360,57361,57362,57363,57364,57365,57366,57367,
61457368,57369,57370,57371,57372,57373,57374,57375,57376,57377,57378,57379,57380,
61557381,57382,57383,57384,57385,57386,57387,57388,57389,57390,57391,57392,
61657393,57394,57395,57396,57397,57398,57399,57400,57401,57402,57403,57404,57405,
61757406,57407,57408,57409,57410,57411,57412,57413,57414,57415,57416,57417,57418,
61857419,57420,57421,57422,57423,57424,57425,57426,57427,57428,57429,57430,57431,
61957432,57433,57434,57435,57436,57437,29554,29555,29556,29557,29558,29559,29560,
62029561,29562,29563,29564,29565,29567,29568,29569,29570,29571,29573,29574,29576,
62129578,29580,29581,29583,29584,29586,29587,29588,29589,29591,29592,29593,29594,
62229596,29597,29598,29600,29601,29603,29604,29605,29606,29607,29608,29610,29612,
62329613,29617,29620,29621,29622,29624,29625,29628,29629,29630,29631,29633,29635,
62429636,29637,29638,29639,29643,29644,29646,29650,29651,29652,29653,29654,29655,
62529656,29658,29659,29660,29661,29663,29665,29666,29667,29668,29670,29672,29674,
62629675,29676,29678,29679,29680,29681,29683,29684,29685,29686,29687,57438,57439,
62757440,57441,57442,57443,57444,57445,57446,57447,57448,57449,57450,57451,57452,
62857453,57454,57455,57456,57457,57458,57459,57460,57461,57462,57463,57464,57465,
62957466,57467,57468,57469,57470,57471,57472,57473,57474,57475,57476,57477,57478,
63057479,57480,57481,57482,57483,57484,57485,57486,57487,57488,57489,57490,57491,
63157492,57493,57494,57495,57496,57497,57498,57499,57500,57501,57502,57503,57504,
63257505,57506,57507,57508,57509,57510,57511,57512,57513,57514,57515,57516,57517,
63357518,57519,57520,57521,57522,57523,57524,57525,57526,57527,57528,57529,57530,
63457531,29688,29689,29690,29691,29692,29693,29694,29695,29696,29697,29698,29700,
63529703,29704,29707,29708,29709,29710,29713,29714,29715,
63629716,29717,29718,29719,29720,29721,29724,29725,29726,29727,29728,29729,29731,
63729732,29735,29737,29739,29741,29743,29745,29746,29751,29752,29753,29754,29755,
63829757,29758,29759,29760,29762,29763,29764,29765,29766,29767,29768,29769,29770,
63929771,29772,29773,29774,29775,29776,29777,29778,29779,29780,29782,29784,29789,
64029792,29793,29794,29795,29796,29797,29798,29799,29800,29801,29802,29803,29804,
64129806,29807,29809,29810,29811,29812,29813,29816,29817,29818,57532,57533,57534,
64257535,57536,57537,57538,57539,57540,57541,57542,57543,57544,57545,57546,57547,
64357548,57549,57550,57551,57552,57553,57554,57555,57556,57557,57558,57559,57560,
64457561,57562,57563,57564,57565,57566,57567,57568,57569,57570,57571,57572,57573,
64557574,57575,57576,57577,57578,57579,57580,57581,57582,57583,57584,57585,57586,
64657587,57588,57589,57590,57591,57592,57593,57594,57595,57596,57597,57598,57599,
64757600,57601,57602,57603,57604,57605,57606,57607,57608,57609,57610,57611,57612,
64857613,57614,57615,57616,57617,57618,57619,57620,57621,57622,57623,57624,57625,
64929819,29820,29821,29823,29826,29828,29829,29830,29832,29833,29834,29836,29837,
65029839,29841,29842,29843,29844,29845,29846,29847,29848,29849,29850,29851,29853,
65129855,29856,29857,29858,29859,29860,29861,29862,29866,29867,29868,29869,29870,
65229871,29872,29873,29874,29875,29876,29877,29878,29879,29880,29881,29883,29884,
65329885,29886,29887,29888,29889,29890,29891,29892,29893,29894,29895,29896,29897,
65429898,29899,29900,29901,29902,29903,29904,29905,29907,29908,29909,29910,29911,
65529912,29913,29914,29915,29917,29919,29921,29925,29927,
65629928,29929,29930,29931,29932,29933,29936,29937,29938,57626,57627,57628,57629,
65757630,57631,57632,57633,57634,57635,57636,57637,57638,57639,57640,57641,57642,
65857643,57644,57645,57646,57647,57648,57649,57650,57651,57652,57653,57654,57655,
65957656,57657,57658,57659,57660,57661,57662,57663,57664,57665,57666,57667,57668,
66057669,57670,57671,57672,57673,57674,57675,57676,57677,57678,57679,57680,57681,
66157682,57683,57684,57685,57686,57687,57688,57689,57690,57691,57692,57693,57694,
66257695,57696,57697,57698,57699,57700,57701,57702,57703,57704,57705,57706,57707,
66357708,57709,57710,57711,57712,57713,57714,57715,57716,57717,57718,57719,29939,
66429941,29944,29945,29946,29947,29948,29949,29950,29952,29953,29954,29955,29957,
66529958,29959,29960,29961,29962,29963,29964,29966,29968,29970,29972,29973,29974,
66629975,29979,29981,29982,29984,29985,29986,29987,29988,29990,29991,29994,29998,
66730004,30006,30009,30012,30013,30015,30017,30018,30019,30020,30022,30023,30025,
66830026,30029,30032,30033,30034,30035,30037,30038,30039,30040,30045,30046,30047,
66930048,30049,30050,30051,30052,30055,30056,30057,30059,30060,30061,30062,30063,
67030064,30065,30067,30069,30070,30071,30074,30075,30076,30077,30078,30080,30081,
67130082,30084,30085,30087,57720,57721,57722,57723,57724,57725,57726,57727,57728,
67257729,57730,57731,57732,57733,57734,57735,57736,57737,57738,57739,57740,57741,
67357742,57743,57744,57745,57746,57747,57748,57749,57750,57751,57752,57753,57754,
67457755,57756,57757,57758,57759,57760,57761,57762,57763,57764,57765,57766,57767,
67557768,57769,57770,57771,57772,57773,57774,57775,57776,
67657777,57778,57779,57780,57781,57782,57783,57784,57785,57786,57787,57788,57789,
67757790,57791,57792,57793,57794,57795,57796,57797,57798,57799,57800,57801,57802,
67857803,57804,57805,57806,57807,57808,57809,57810,57811,57812,57813,30088,30089,
67930090,30092,30093,30094,30096,30099,30101,30104,30107,30108,30110,30114,30118,
68030119,30120,30121,30122,30125,30134,30135,30138,30139,30143,30144,30145,30150,
68130155,30156,30158,30159,30160,30161,30163,30167,30169,30170,30172,30173,30175,
68230176,30177,30181,30185,30188,30189,30190,30191,30194,30195,30197,30198,30199,
68330200,30202,30203,30205,30206,30210,30212,30214,30215,30216,30217,30219,30221,
68430222,30223,30225,30226,30227,30228,30230,30234,30236,30237,30238,30241,30243,
68530247,30248,30252,30254,30255,30257,30258,30262,30263,30265,30266,30267,30269,
68630273,30274,30276,57814,57815,57816,57817,57818,57819,57820,57821,57822,57823,
68757824,57825,57826,57827,57828,57829,57830,57831,57832,57833,57834,57835,57836,
68857837,57838,57839,57840,57841,57842,57843,57844,57845,57846,57847,57848,57849,
68957850,57851,57852,57853,57854,57855,57856,57857,57858,57859,57860,57861,57862,
69057863,57864,57865,57866,57867,57868,57869,57870,57871,57872,57873,57874,57875,
69157876,57877,57878,57879,57880,57881,57882,57883,57884,57885,57886,57887,57888,
69257889,57890,57891,57892,57893,57894,57895,57896,57897,57898,57899,57900,57901,
69357902,57903,57904,57905,57906,57907,30277,30278,30279,30280,30281,30282,30283,
69430286,30287,30288,30289,30290,30291,30293,30295,30296,30297,30298,30299,30301,
69530303,30304,30305,30306,30308,30309,30310,30311,30312,
69630313,30314,30316,30317,30318,30320,30321,30322,30323,30324,30325,30326,30327,
69730329,30330,30332,30335,30336,30337,30339,30341,30345,30346,30348,30349,30351,
69830352,30354,30356,30357,30359,30360,30362,30363,30364,30365,30366,30367,30368,
69930369,30370,30371,30373,30374,30375,30376,30377,30378,30379,30380,30381,30383,
70030384,30387,30389,30390,30391,30392,30393,30394,30395,30396,30397,30398,30400,
70130401,30403,21834,38463,22467,25384,21710,21769,21696,30353,30284,34108,30702,
70233406,30861,29233,38552,38797,27688,23433,20474,25353,26263,23736,33018,26696,
70332942,26114,30414,20985,25942,29100,32753,34948,20658,22885,25034,28595,33453,
70425420,25170,21485,21543,31494,20843,30116,24052,25300,36299,38774,25226,32793,
70522365,38712,32610,29240,30333,26575,30334,25670,20336,36133,25308,31255,26001,
70629677,25644,25203,33324,39041,26495,29256,25198,25292,20276,29923,21322,21150,
70732458,37030,24110,26758,27036,33152,32465,26834,30917,34444,38225,20621,35876,
70833502,32990,21253,35090,21093,30404,30407,30409,30411,30412,30419,30421,30425,
70930426,30428,30429,30430,30432,30433,30434,30435,30436,30438,30439,30440,30441,
71030442,30443,30444,30445,30448,30451,30453,30454,30455,30458,30459,30461,30463,
71130464,30466,30467,30469,30470,30474,30476,30478,30479,30480,30481,30482,30483,
71230484,30485,30486,30487,30488,30491,30492,30493,30494,30497,30499,30500,30501,
71330503,30506,30507,30508,30510,30512,30513,30514,30515,30516,30521,30523,30525,
71430526,30527,30530,30532,30533,30534,30536,30537,30538,30539,30540,30541,30542,
71530543,30546,30547,30548,30549,30550,30551,30552,30553,
71630556,34180,38649,20445,22561,39281,23453,25265,25253,26292,35961,40077,29190,
71726479,30865,24754,21329,21271,36744,32972,36125,38049,20493,29384,22791,24811,
71828953,34987,22868,33519,26412,31528,23849,32503,29997,27893,36454,36856,36924,
71940763,27604,37145,31508,24444,30887,34006,34109,27605,27609,27606,24065,24199,
72030201,38381,25949,24330,24517,36767,22721,33218,36991,38491,38829,36793,32534,
72136140,25153,20415,21464,21342,36776,36777,36779,36941,26631,24426,33176,34920,
72240150,24971,21035,30250,24428,25996,28626,28392,23486,25672,20853,20912,26564,
72319993,31177,39292,28851,30557,30558,30559,30560,30564,30567,30569,30570,30573,
72430574,30575,30576,30577,30578,30579,30580,30581,30582,30583,30584,30586,30587,
72530588,30593,30594,30595,30598,30599,30600,30601,30602,30603,30607,30608,30611,
72630612,30613,30614,30615,30616,30617,30618,30619,30620,30621,30622,30625,30627,
72730628,30630,30632,30635,30637,30638,30639,30641,30642,30644,30646,30647,30648,
72830649,30650,30652,30654,30656,30657,30658,30659,30660,30661,30662,30663,30664,
72930665,30666,30667,30668,30670,30671,30672,30673,30674,30675,30676,30677,30678,
73030680,30681,30682,30685,30686,30687,30688,30689,30692,30149,24182,29627,33760,
73125773,25320,38069,27874,21338,21187,25615,38082,31636,20271,24091,33334,33046,
73233162,28196,27850,39539,25429,21340,21754,34917,22496,19981,24067,27493,31807,
73337096,24598,25830,29468,35009,26448,25165,36130,30572,36393,37319,24425,33756,
73434081,39184,21442,34453,27531,24813,24808,28799,33485,33329,20179,27815,34255,
73525805,31961,27133,26361,33609,21397,31574,20391,20876,
73627979,23618,36461,25554,21449,33580,33590,26597,30900,25661,23519,23700,24046,
73735815,25286,26612,35962,25600,25530,34633,39307,35863,32544,38130,20135,38416,
73839076,26124,29462,30694,30696,30698,30703,30704,30705,30706,30708,30709,30711,
73930713,30714,30715,30716,30723,30724,30725,30726,30727,30728,30730,30731,30734,
74030735,30736,30739,30741,30745,30747,30750,30752,30753,30754,30756,30760,30762,
74130763,30766,30767,30769,30770,30771,30773,30774,30781,30783,30785,30786,30787,
74230788,30790,30792,30793,30794,30795,30797,30799,30801,30803,30804,30808,30809,
74330810,30811,30812,30814,30815,30816,30817,30818,30819,30820,30821,30822,30823,
74430824,30825,30831,30832,30833,30834,30835,30836,30837,30838,30840,30841,30842,
74530843,30845,30846,30847,30848,30849,30850,30851,22330,23581,24120,38271,20607,
74632928,21378,25950,30021,21809,20513,36229,25220,38046,26397,22066,28526,24034,
74721557,28818,36710,25199,25764,25507,24443,28552,37108,33251,36784,23576,26216,
74824561,27785,38472,36225,34924,25745,31216,22478,27225,25104,21576,20056,31243,
74924809,28548,35802,25215,36894,39563,31204,21507,30196,25345,21273,27744,36831,
75024347,39536,32827,40831,20360,23610,36196,32709,26021,28861,20805,20914,34411,
75123815,23456,25277,37228,30068,36364,31264,24833,31609,20167,32504,30597,19985,
75233261,21021,20986,27249,21416,36487,38148,38607,28353,38500,26970,30852,30853,
75330854,30856,30858,30859,30863,30864,30866,30868,30869,30870,30873,30877,30878,
75430880,30882,30884,30886,30888,30889,30890,30891,30892,30893,30894,30895,30901,
75530902,30903,30904,30906,30907,30908,30909,30911,30912,
75630914,30915,30916,30918,30919,30920,30924,30925,30926,30927,30929,30930,30931,
75730934,30935,30936,30938,30939,30940,30941,30942,30943,30944,30945,30946,30947,
75830948,30949,30950,30951,30953,30954,30955,30957,30958,30959,30960,30961,30963,
75930965,30966,30968,30969,30971,30972,30973,30974,30975,30976,30978,30979,30980,
76030982,30983,30984,30985,30986,30987,30988,30784,20648,30679,25616,35302,22788,
76125571,24029,31359,26941,20256,33337,21912,20018,30126,31383,24162,24202,38383,
76221019,21561,28810,25462,38180,22402,26149,26943,37255,21767,28147,32431,34850,
76325139,32496,30133,33576,30913,38604,36766,24904,29943,35789,27492,21050,36176,
76427425,32874,33905,22257,21254,20174,19995,20945,31895,37259,31751,20419,36479,
76531713,31388,25703,23828,20652,33030,30209,31929,28140,32736,26449,23384,23544,
76630923,25774,25619,25514,25387,38169,25645,36798,31572,30249,25171,22823,21574,
76727513,20643,25140,24102,27526,20195,36151,34955,24453,36910,30989,30990,30991,
76830992,30993,30994,30996,30997,30998,30999,31000,31001,31002,31003,31004,31005,
76931007,31008,31009,31010,31011,31013,31014,31015,31016,31017,31018,31019,31020,
77031021,31022,31023,31024,31025,31026,31027,31029,31030,31031,31032,31033,31037,
77131039,31042,31043,31044,31045,31047,31050,31051,31052,31053,31054,31055,31056,
77231057,31058,31060,31061,31064,31065,31073,31075,31076,31078,31081,31082,31083,
77331084,31086,31088,31089,31090,31091,31092,31093,31094,31097,31099,31100,31101,
77431102,31103,31106,31107,31110,31111,31112,31113,31115,31116,31117,31118,31120,
77531121,31122,24608,32829,25285,20025,21333,37112,25528,
77632966,26086,27694,20294,24814,28129,35806,24377,34507,24403,25377,20826,33633,
77726723,20992,25443,36424,20498,23707,31095,23548,21040,31291,24764,36947,30423,
77824503,24471,30340,36460,28783,30331,31561,30634,20979,37011,22564,20302,28404,
77936842,25932,31515,29380,28068,32735,23265,25269,24213,22320,33922,31532,24093,
78024351,36882,32532,39072,25474,28359,30872,28857,20856,38747,22443,30005,20291,
78130008,24215,24806,22880,28096,27583,30857,21500,38613,20939,20993,25481,21514,
78238035,35843,36300,29241,30879,34678,36845,35853,21472,31123,31124,31125,31126,
78331127,31128,31129,31131,31132,31133,31134,31135,31136,31137,31138,31139,31140,
78431141,31142,31144,31145,31146,31147,31148,31149,31150,31151,31152,31153,31154,
78531156,31157,31158,31159,31160,31164,31167,31170,31172,31173,31175,31176,31178,
78631180,31182,31183,31184,31187,31188,31190,31191,31193,31194,31195,31196,31197,
78731198,31200,31201,31202,31205,31208,31210,31212,31214,31217,31218,31219,31220,
78831221,31222,31223,31225,31226,31228,31230,31231,31233,31236,31237,31239,31240,
78931241,31242,31244,31247,31248,31249,31250,31251,31253,31254,31256,31257,31259,
79031260,19969,30447,21486,38025,39030,40718,38189,23450,35746,20002,19996,20908,
79133891,25026,21160,26635,20375,24683,20923,27934,20828,25238,26007,38497,35910,
79236887,30168,37117,30563,27602,29322,29420,35835,22581,30585,36172,26460,38208,
79332922,24230,28193,22930,31471,30701,38203,27573,26029,32526,22534,20817,38431,
79423545,22697,21544,36466,25958,39039,22244,38045,30462,36929,25479,21702,22810,
79522842,22427,36530,26421,36346,33333,21057,24816,22549,
79634558,23784,40517,20420,39069,35769,23077,24694,21380,25212,36943,37122,39295,
79724681,32780,20799,32819,23572,39285,27953,20108,31261,31263,31265,31266,31268,
79831269,31270,31271,31272,31273,31274,31275,31276,31277,31278,31279,31280,31281,
79931282,31284,31285,31286,31288,31290,31294,31296,31297,31298,31299,31300,31301,
80031303,31304,31305,31306,31307,31308,31309,31310,31311,31312,31314,31315,31316,
80131317,31318,31320,31321,31322,31323,31324,31325,31326,31327,31328,31329,31330,
80231331,31332,31333,31334,31335,31336,31337,31338,31339,31340,31341,31342,31343,
80331345,31346,31347,31349,31355,31356,31357,31358,31362,31365,31367,31369,31370,
80431371,31372,31374,31375,31376,31379,31380,31385,31386,31387,31390,31393,31394,
80536144,21457,32602,31567,20240,20047,38400,27861,29648,34281,24070,30058,32763,
80627146,30718,38034,32321,20961,28902,21453,36820,33539,36137,29359,39277,27867,
80722346,33459,26041,32938,25151,38450,22952,20223,35775,32442,25918,33778,38750,
80821857,39134,32933,21290,35837,21536,32954,24223,27832,36153,33452,37210,21545,
80927675,20998,32439,22367,28954,27774,31881,22859,20221,24575,24868,31914,20016,
81023553,26539,34562,23792,38155,39118,30127,28925,36898,20911,32541,35773,22857,
81120964,20315,21542,22827,25975,32932,23413,25206,25282,36752,24133,27679,31526,
81220239,20440,26381,31395,31396,31399,31401,31402,31403,31406,31407,31408,31409,
81331410,31412,31413,31414,31415,31416,31417,31418,31419,31420,31421,31422,31424,
81431425,31426,31427,31428,31429,31430,31431,31432,31433,31434,31436,31437,31438,
81531439,31440,31441,31442,31443,31444,31445,31447,31448,
81631450,31451,31452,31453,31457,31458,31460,31463,31464,31465,31466,31467,31468,
81731470,31472,31473,31474,31475,31476,31477,31478,31479,31480,31483,31484,31486,
81831488,31489,31490,31493,31495,31497,31500,31501,31502,31504,31506,31507,31510,
81931511,31512,31514,31516,31517,31519,31521,31522,31523,31527,31529,31533,28014,
82028074,31119,34993,24343,29995,25242,36741,20463,37340,26023,33071,33105,24220,
82133104,36212,21103,35206,36171,22797,20613,20184,38428,29238,33145,36127,23500,
82235747,38468,22919,32538,21648,22134,22030,35813,25913,27010,38041,30422,28297,
82324178,29976,26438,26577,31487,32925,36214,24863,31174,25954,36195,20872,21018,
82438050,32568,32923,32434,23703,28207,26464,31705,30347,39640,33167,32660,31957,
82525630,38224,31295,21578,21733,27468,25601,25096,40509,33011,30105,21106,38761,
82633883,26684,34532,38401,38548,38124,20010,21508,32473,26681,36319,32789,26356,
82724218,32697,31535,31536,31538,31540,31541,31542,31543,31545,31547,31549,31551,
82831552,31553,31554,31555,31556,31558,31560,31562,31565,31566,31571,31573,31575,
82931577,31580,31582,31583,31585,31587,31588,31589,31590,31591,31592,31593,31594,
83031595,31596,31597,31599,31600,31603,31604,31606,31608,31610,31612,31613,31615,
83131617,31618,31619,31620,31622,31623,31624,31625,31626,31627,31628,31630,31631,
83231633,31634,31635,31638,31640,31641,31642,31643,31646,31647,31648,31651,31652,
83331653,31662,31663,31664,31666,31667,31669,31670,31671,31673,31674,31675,31676,
83431677,31678,31679,31680,31682,31683,31684,22466,32831,26775,24037,25915,21151,
83524685,40858,20379,36524,20844,23467,24339,24041,27742,
83625329,36129,20849,38057,21246,27807,33503,29399,22434,26500,36141,22815,36764,
83733735,21653,31629,20272,27837,23396,22993,40723,21476,34506,39592,35895,32929,
83825925,39038,22266,38599,21038,29916,21072,23521,25346,35074,20054,25296,24618,
83926874,20851,23448,20896,35266,31649,39302,32592,24815,28748,36143,20809,24191,
84036891,29808,35268,22317,30789,24402,40863,38394,36712,39740,35809,30328,26690,
84126588,36330,36149,21053,36746,28378,26829,38149,37101,22269,26524,35065,36807,
84221704,31685,31688,31689,31690,31691,31693,31694,31695,31696,31698,31700,31701,
84331702,31703,31704,31707,31708,31710,31711,31712,31714,31715,31716,31719,31720,
84431721,31723,31724,31725,31727,31728,31730,31731,31732,31733,31734,31736,31737,
84531738,31739,31741,31743,31744,31745,31746,31747,31748,31749,31750,31752,31753,
84631754,31757,31758,31760,31761,31762,31763,31764,31765,31767,31768,31769,31770,
84731771,31772,31773,31774,31776,31777,31778,31779,31780,31781,31784,31785,31787,
84831788,31789,31790,31791,31792,31793,31794,31795,31796,31797,31798,31799,31801,
84931802,31803,31804,31805,31806,31810,39608,23401,28023,27686,20133,23475,39559,
85037219,25000,37039,38889,21547,28085,23506,20989,21898,32597,32752,25788,25421,
85126097,25022,24717,28938,27735,27721,22831,26477,33322,22741,22158,35946,27627,
85237085,22909,32791,21495,28009,21621,21917,33655,33743,26680,31166,21644,20309,
85321512,30418,35977,38402,27827,28088,36203,35088,40548,36154,22079,40657,30165,
85424456,29408,24680,21756,20136,27178,34913,24658,36720,21700,28888,34425,40511,
85527946,23439,24344,32418,21897,20399,29492,21564,21402,
85620505,21518,21628,20046,24573,29786,22774,33899,32993,34676,29392,31946,28246,
85731811,31812,31813,31814,31815,31816,31817,31818,31819,31820,31822,31823,31824,
85831825,31826,31827,31828,31829,31830,31831,31832,31833,31834,31835,31836,31837,
85931838,31839,31840,31841,31842,31843,31844,31845,31846,31847,31848,31849,31850,
86031851,31852,31853,31854,31855,31856,31857,31858,31861,31862,31863,31864,31865,
86131866,31870,31871,31872,31873,31874,31875,31876,31877,31878,31879,31880,31882,
86231883,31884,31885,31886,31887,31888,31891,31892,31894,31897,31898,31899,31904,
86331905,31907,31910,31911,31912,31913,31915,31916,31917,31919,31920,31924,31925,
86431926,31927,31928,31930,31931,24359,34382,21804,25252,20114,27818,25143,33457,
86521719,21326,29502,28369,30011,21010,21270,35805,27088,24458,24576,28142,22351,
86627426,29615,26707,36824,32531,25442,24739,21796,30186,35938,28949,28067,23462,
86724187,33618,24908,40644,30970,34647,31783,30343,20976,24822,29004,26179,24140,
86824653,35854,28784,25381,36745,24509,24674,34516,22238,27585,24724,24935,21321,
86924800,26214,36159,31229,20250,28905,27719,35763,35826,32472,33636,26127,23130,
87039746,27985,28151,35905,27963,20249,28779,33719,25110,24785,38669,36135,31096,
87120987,22334,22522,26426,30072,31293,31215,31637,31935,31936,31938,31939,31940,
87231942,31945,31947,31950,31951,31952,31953,31954,31955,31956,31960,31962,31963,
87331965,31966,31969,31970,31971,31972,31973,31974,31975,31977,31978,31979,31980,
87431981,31982,31984,31985,31986,31987,31988,31989,31990,31991,31993,31994,31996,
87531997,31998,31999,32000,32001,32002,32003,32004,32005,
87632006,32007,32008,32009,32011,32012,32013,32014,32015,32016,32017,32018,32019,
87732020,32021,32022,32023,32024,32025,32026,32027,32028,32029,32030,32031,32033,
87832035,32036,32037,32038,32040,32041,32042,32044,32045,32046,32048,32049,32050,
87932051,32052,32053,32054,32908,39269,36857,28608,35749,40481,23020,32489,32521,
88021513,26497,26840,36753,31821,38598,21450,24613,30142,27762,21363,23241,32423,
88125380,20960,33034,24049,34015,25216,20864,23395,20238,31085,21058,24760,27982,
88223492,23490,35745,35760,26082,24524,38469,22931,32487,32426,22025,26551,22841,
88320339,23478,21152,33626,39050,36158,30002,38078,20551,31292,20215,26550,39550,
88423233,27516,30417,22362,23574,31546,38388,29006,20860,32937,33392,22904,32516,
88533575,26816,26604,30897,30839,25315,25441,31616,20461,21098,20943,33616,27099,
88637492,36341,36145,35265,38190,31661,20214,32055,32056,32057,32058,32059,32060,
88732061,32062,32063,32064,32065,32066,32067,32068,32069,32070,32071,32072,32073,
88832074,32075,32076,32077,32078,32079,32080,32081,32082,32083,32084,32085,32086,
88932087,32088,32089,32090,32091,32092,32093,32094,32095,32096,32097,32098,32099,
89032100,32101,32102,32103,32104,32105,32106,32107,32108,32109,32111,32112,32113,
89132114,32115,32116,32117,32118,32120,32121,32122,32123,32124,32125,32126,32127,
89232128,32129,32130,32131,32132,32133,32134,32135,32136,32137,32138,32139,32140,
89332141,32142,32143,32144,32145,32146,32147,32148,32149,32150,32151,32152,20581,
89433328,21073,39279,28176,28293,28071,24314,20725,23004,23558,27974,27743,30086,
89533931,26728,22870,35762,21280,37233,38477,34121,26898,
89630977,28966,33014,20132,37066,27975,39556,23047,22204,25605,38128,30699,20389,
89733050,29409,35282,39290,32564,32478,21119,25945,37237,36735,36739,21483,31382,
89825581,25509,30342,31224,34903,38454,25130,21163,33410,26708,26480,25463,30571,
89931469,27905,32467,35299,22992,25106,34249,33445,30028,20511,20171,30117,35819,
90023626,24062,31563,26020,37329,20170,27941,35167,32039,38182,20165,35880,36827,
90138771,26187,31105,36817,28908,28024,32153,32154,32155,32156,32157,32158,32159,
90232160,32161,32162,32163,32164,32165,32167,32168,32169,32170,32171,32172,32173,
90332175,32176,32177,32178,32179,32180,32181,32182,32183,32184,32185,32186,32187,
90432188,32189,32190,32191,32192,32193,32194,32195,32196,32197,32198,32199,32200,
90532201,32202,32203,32204,32205,32206,32207,32208,32209,32210,32211,32212,32213,
90632214,32215,32216,32217,32218,32219,32220,32221,32222,32223,32224,32225,32226,
90732227,32228,32229,32230,32231,32232,32233,32234,32235,32236,32237,32238,32239,
90832240,32241,32242,32243,32244,32245,32246,32247,32248,32249,32250,23613,21170,
90933606,20834,33550,30555,26230,40120,20140,24778,31934,31923,32463,20117,35686,
91026223,39048,38745,22659,25964,38236,24452,30153,38742,31455,31454,20928,28847,
91131384,25578,31350,32416,29590,38893,20037,28792,20061,37202,21417,25937,26087,
91233276,33285,21646,23601,30106,38816,25304,29401,30141,23621,39545,33738,23616,
91321632,30697,20030,27822,32858,25298,25454,24040,20855,36317,36382,38191,20465,
91421477,24807,28844,21095,25424,40515,23071,20518,30519,21367,32482,25733,25899,
91525225,25496,20500,29237,35273,20915,35776,32477,22343,
91633740,38055,20891,21531,23803,32251,32252,32253,32254,32255,32256,32257,32258,
91732259,32260,32261,32262,32263,32264,32265,32266,32267,32268,32269,32270,32271,
91832272,32273,32274,32275,32276,32277,32278,32279,32280,32281,32282,32283,32284,
91932285,32286,32287,32288,32289,32290,32291,32292,32293,32294,32295,32296,32297,
92032298,32299,32300,32301,32302,32303,32304,32305,32306,32307,32308,32309,32310,
92132311,32312,32313,32314,32316,32317,32318,32319,32320,32322,32323,32324,32325,
92232326,32328,32329,32330,32331,32332,32333,32334,32335,32336,32337,32338,32339,
92332340,32341,32342,32343,32344,32345,32346,32347,32348,32349,20426,31459,27994,
92437089,39567,21888,21654,21345,21679,24320,25577,26999,20975,24936,21002,22570,
92521208,22350,30733,30475,24247,24951,31968,25179,25239,20130,28821,32771,25335,
92628900,38752,22391,33499,26607,26869,30933,39063,31185,22771,21683,21487,28212,
92720811,21051,23458,35838,32943,21827,22438,24691,22353,21549,31354,24656,23380,
92825511,25248,21475,25187,23495,26543,21741,31391,33510,37239,24211,35044,22840,
92922446,25358,36328,33007,22359,31607,20393,24555,23485,27454,21281,31568,29378,
93026694,30719,30518,26103,20917,20111,30420,23743,31397,33909,22862,39745,20608,
93132350,32351,32352,32353,32354,32355,32356,32357,32358,32359,32360,32361,32362,
93232363,32364,32365,32366,32367,32368,32369,32370,32371,32372,32373,32374,32375,
93332376,32377,32378,32379,32380,32381,32382,32383,32384,32385,32387,32388,32389,
93432390,32391,32392,32393,32394,32395,32396,32397,32398,32399,32400,32401,32402,
93532403,32404,32405,32406,32407,32408,32409,32410,32412,
93632413,32414,32430,32436,32443,32444,32470,32484,32492,32505,32522,32528,32542,
93732567,32569,32571,32572,32573,32574,32575,32576,32577,32579,32582,32583,32584,
93832585,32586,32587,32588,32589,32590,32591,32594,32595,39304,24871,28291,22372,
93926118,25414,22256,25324,25193,24275,38420,22403,25289,21895,34593,33098,36771,
94021862,33713,26469,36182,34013,23146,26639,25318,31726,38417,20848,28572,35888,
94125597,35272,25042,32518,28866,28389,29701,27028,29436,24266,37070,26391,28010,
94225438,21171,29282,32769,20332,23013,37226,28889,28061,21202,20048,38647,38253,
94334174,30922,32047,20769,22418,25794,32907,31867,27882,26865,26974,20919,21400,
94426792,29313,40654,31729,29432,31163,28435,29702,26446,37324,40100,31036,33673,
94533620,21519,26647,20029,21385,21169,30782,21382,21033,20616,20363,20432,32598,
94632601,32603,32604,32605,32606,32608,32611,32612,32613,32614,32615,32619,32620,
94732621,32623,32624,32627,32629,32630,32631,32632,32634,32635,32636,32637,32639,
94832640,32642,32643,32644,32645,32646,32647,32648,32649,32651,32653,32655,32656,
94932657,32658,32659,32661,32662,32663,32664,32665,32667,32668,32672,32674,32675,
95032677,32678,32680,32681,32682,32683,32684,32685,32686,32689,32691,32692,32693,
95132694,32695,32698,32699,32702,32704,32706,32707,32708,32710,32711,32712,32713,
95232715,32717,32719,32720,32721,32722,32723,32726,32727,32729,32730,32731,32732,
95332733,32734,32738,32739,30178,31435,31890,27813,38582,21147,29827,21737,20457,
95432852,33714,36830,38256,24265,24604,28063,24088,25947,33080,38142,24651,28860,
95532451,31918,20937,26753,31921,33391,20004,36742,37327,
95626238,20142,35845,25769,32842,20698,30103,29134,23525,36797,28518,20102,25730,
95738243,24278,26009,21015,35010,28872,21155,29454,29747,26519,30967,38678,20020,
95837051,40158,28107,20955,36161,21533,25294,29618,33777,38646,40836,38083,20278,
95932666,20940,28789,38517,23725,39046,21478,20196,28316,29705,27060,30827,39311,
96030041,21016,30244,27969,26611,20845,40857,32843,21657,31548,31423,32740,32743,
96132744,32746,32747,32748,32749,32751,32754,32756,32757,32758,32759,32760,32761,
96232762,32765,32766,32767,32770,32775,32776,32777,32778,32782,32783,32785,32787,
96332794,32795,32797,32798,32799,32801,32803,32804,32811,32812,32813,32814,32815,
96432816,32818,32820,32825,32826,32828,32830,32832,32833,32836,32837,32839,32840,
96532841,32846,32847,32848,32849,32851,32853,32854,32855,32857,32859,32860,32861,
96632862,32863,32864,32865,32866,32867,32868,32869,32870,32871,32872,32875,32876,
96732877,32878,32879,32880,32882,32883,32884,32885,32886,32887,32888,32889,32890,
96832891,32892,32893,38534,22404,25314,38471,27004,23044,25602,31699,28431,38475,
96933446,21346,39045,24208,28809,25523,21348,34383,40065,40595,30860,38706,36335,
97036162,40575,28510,31108,24405,38470,25134,39540,21525,38109,20387,26053,23653,
97123649,32533,34385,27695,24459,29575,28388,32511,23782,25371,23402,28390,21365,
97220081,25504,30053,25249,36718,20262,20177,27814,32438,35770,33821,34746,32599,
97336923,38179,31657,39585,35064,33853,27931,39558,32476,22920,40635,29595,30721,
97434434,39532,39554,22043,21527,22475,20080,40614,21334,36808,33033,30610,39314,
97534542,28385,34067,26364,24930,28459,32894,32897,32898,
97632901,32904,32906,32909,32910,32911,32912,32913,32914,32916,32917,32919,32921,
97732926,32931,32934,32935,32936,32940,32944,32947,32949,32950,32952,32953,32955,
97832965,32967,32968,32969,32970,32971,32975,32976,32977,32978,32979,32980,32981,
97932984,32991,32992,32994,32995,32998,33006,33013,33015,33017,33019,33022,33023,
98033024,33025,33027,33028,33029,33031,33032,33035,33036,33045,33047,33049,33051,
98133052,33053,33055,33056,33057,33058,33059,33060,33061,33062,33063,33064,33065,
98233066,33067,33069,33070,33072,33075,33076,33077,33079,33081,33082,33083,33084,
98333085,33087,35881,33426,33579,30450,27667,24537,33725,29483,33541,38170,27611,
98430683,38086,21359,33538,20882,24125,35980,36152,20040,29611,26522,26757,37238,
98538665,29028,27809,30473,23186,38209,27599,32654,26151,23504,22969,23194,38376,
98638391,20204,33804,33945,27308,30431,38192,29467,26790,23391,30511,37274,38753,
98731964,36855,35868,24357,31859,31192,35269,27852,34588,23494,24130,26825,30496,
98832501,20885,20813,21193,23081,32517,38754,33495,25551,30596,34256,31186,28218,
98924217,22937,34065,28781,27665,25279,30399,25935,24751,38397,26126,34719,40483,
99038125,21517,21629,35884,25720,33088,33089,33090,33091,33092,33093,33095,33097,
99133101,33102,33103,33106,33110,33111,33112,33115,33116,33117,33118,33119,33121,
99233122,33123,33124,33126,33128,33130,33131,33132,33135,33138,33139,33141,33142,
99333143,33144,33153,33155,33156,33157,33158,33159,33161,33163,33164,33165,33166,
99433168,33170,33171,33172,33173,33174,33175,33177,33178,33182,33183,33184,33185,
99533186,33188,33189,33191,33193,33195,33196,33197,33198,
99633199,33200,33201,33202,33204,33205,33206,33207,33208,33209,33212,33213,33214,
99733215,33220,33221,33223,33224,33225,33227,33229,33230,33231,33232,33233,33234,
99833235,25721,34321,27169,33180,30952,25705,39764,25273,26411,33707,22696,40664,
99927819,28448,23518,38476,35851,29279,26576,25287,29281,20137,22982,27597,22675,
100026286,24149,21215,24917,26408,30446,30566,29287,31302,25343,21738,21584,38048,
100137027,23068,32435,27670,20035,22902,32784,22856,21335,30007,38590,22218,25376,
100233041,24700,38393,28118,21602,39297,20869,23273,33021,22958,38675,20522,27877,
100323612,25311,20320,21311,33147,36870,28346,34091,25288,24180,30910,25781,25467,
100424565,23064,37247,40479,23615,25423,32834,23421,21870,38218,38221,28037,24744,
100526592,29406,20957,23425,33236,33237,33238,33239,33240,33241,33242,33243,33244,
100633245,33246,33247,33248,33249,33250,33252,33253,33254,33256,33257,33259,33262,
100733263,33264,33265,33266,33269,33270,33271,33272,33273,33274,33277,33279,33283,
100833287,33288,33289,33290,33291,33294,33295,33297,33299,33301,33302,33303,33304,
100933305,33306,33309,33312,33316,33317,33318,33319,33321,33326,33330,33338,33340,
101033341,33343,33344,33345,33346,33347,33349,33350,33352,33354,33356,33357,33358,
101133360,33361,33362,33363,33364,33365,33366,33367,33369,33371,33372,33373,33374,
101233376,33377,33378,33379,33380,33381,33382,33383,33385,25319,27870,29275,25197,
101338062,32445,33043,27987,20892,24324,22900,21162,24594,22899,26262,34384,30111,
101425386,25062,31983,35834,21734,27431,40485,27572,34261,21589,20598,27812,21866,
101536276,29228,24085,24597,29750,25293,25490,29260,24472,
101628227,27966,25856,28504,30424,30928,30460,30036,21028,21467,20051,24222,26049,
101732810,32982,25243,21638,21032,28846,34957,36305,27873,21624,32986,22521,35060,
101836180,38506,37197,20329,27803,21943,30406,30768,25256,28921,28558,24429,34028,
101926842,30844,31735,33192,26379,40527,25447,30896,22383,30738,38713,25209,25259,
102021128,29749,27607,33386,33387,33388,33389,33393,33397,33398,33399,33400,33403,
102133404,33408,33409,33411,33413,33414,33415,33417,33420,33424,33427,33428,33429,
102233430,33434,33435,33438,33440,33442,33443,33447,33458,33461,33462,33466,33467,
102333468,33471,33472,33474,33475,33477,33478,33481,33488,33494,33497,33498,33501,
102433506,33511,33512,33513,33514,33516,33517,33518,33520,33522,33523,33525,33526,
102533528,33530,33532,33533,33534,33535,33536,33546,33547,33549,33552,33554,33555,
102633558,33560,33561,33565,33566,33567,33568,33569,33570,33571,33572,33573,33574,
102733577,33578,33582,33584,33586,33591,33595,33597,21860,33086,30130,30382,21305,
102830174,20731,23617,35692,31687,20559,29255,39575,39128,28418,29922,31080,25735,
102930629,25340,39057,36139,21697,32856,20050,22378,33529,33805,24179,20973,29942,
103035780,23631,22369,27900,39047,23110,30772,39748,36843,31893,21078,25169,38138,
103120166,33670,33889,33769,33970,22484,26420,22275,26222,28006,35889,26333,28689,
103226399,27450,26646,25114,22971,19971,20932,28422,26578,27791,20854,26827,22855,
103327495,30054,23822,33040,40784,26071,31048,31041,39569,36215,23682,20062,20225,
103421551,22865,30732,22120,27668,36804,24323,27773,27875,35755,25488,33598,33599,
103533601,33602,33604,33605,33608,33610,33611,33612,33613,
103633614,33619,33621,33622,33623,33624,33625,33629,33634,33648,33649,33650,33651,
103733652,33653,33654,33657,33658,33662,33663,33664,33665,33666,33667,33668,33671,
103833672,33674,33675,33676,33677,33679,33680,33681,33684,33685,33686,33687,33689,
103933690,33693,33695,33697,33698,33699,33700,33701,33702,33703,33708,33709,33710,
104033711,33717,33723,33726,33727,33730,33731,33732,33734,33736,33737,33739,33741,
104133742,33744,33745,33746,33747,33749,33751,33753,33754,33755,33758,33762,33763,
104233764,33766,33767,33768,33771,33772,33773,24688,27965,29301,25190,38030,38085,
104321315,36801,31614,20191,35878,20094,40660,38065,38067,21069,28508,36963,27973,
104435892,22545,23884,27424,27465,26538,21595,33108,32652,22681,34103,24378,25250,
104527207,38201,25970,24708,26725,30631,20052,20392,24039,38808,25772,32728,23789,
104620431,31373,20999,33540,19988,24623,31363,38054,20405,20146,31206,29748,21220,
104733465,25810,31165,23517,27777,38738,36731,27682,20542,21375,28165,25806,26228,
104827696,24773,39031,35831,24198,29756,31351,31179,19992,37041,29699,27714,22234,
104937195,27845,36235,21306,34502,26354,36527,23624,39537,28192,33774,33775,33779,
105033780,33781,33782,33783,33786,33787,33788,33790,33791,33792,33794,33797,33799,
105133800,33801,33802,33808,33810,33811,33812,33813,33814,33815,33817,33818,33819,
105233822,33823,33824,33825,33826,33827,33833,33834,33835,33836,33837,33838,33839,
105333840,33842,33843,33844,33845,33846,33847,33849,33850,33851,33854,33855,33856,
105433857,33858,33859,33860,33861,33863,33864,33865,33866,33867,33868,33869,33870,
105533871,33872,33874,33875,33876,33877,33878,33880,33885,
105633886,33887,33888,33890,33892,33893,33894,33895,33896,33898,33902,33903,33904,
105733906,33908,33911,33913,33915,33916,21462,23094,40843,36259,21435,22280,39079,
105826435,37275,27849,20840,30154,25331,29356,21048,21149,32570,28820,30264,21364,
105940522,27063,30830,38592,35033,32676,28982,29123,20873,26579,29924,22756,25880,
106022199,35753,39286,25200,32469,24825,28909,22764,20161,20154,24525,38887,20219,
106135748,20995,22922,32427,25172,20173,26085,25102,33592,33993,33635,34701,29076,
106228342,23481,32466,20887,25545,26580,32905,33593,34837,20754,23418,22914,36785,
106320083,27741,20837,35109,36719,38446,34122,29790,38160,38384,28070,33509,24369,
106425746,27922,33832,33134,40131,22622,36187,19977,21441,33917,33918,33919,33920,
106533921,33923,33924,33925,33926,33930,33933,33935,33936,33937,33938,33939,33940,
106633941,33942,33944,33946,33947,33949,33950,33951,33952,33954,33955,33956,33957,
106733958,33959,33960,33961,33962,33963,33964,33965,33966,33968,33969,33971,33973,
106833974,33975,33979,33980,33982,33984,33986,33987,33989,33990,33991,33992,33995,
106933996,33998,33999,34002,34004,34005,34007,34008,34009,34010,34011,34012,34014,
107034017,34018,34020,34023,34024,34025,34026,34027,34029,34030,34031,34033,34034,
107134035,34036,34037,34038,34039,34040,34041,34042,34043,34045,34046,34048,34049,
107234050,20254,25955,26705,21971,20007,25620,39578,25195,23234,29791,33394,28073,
107326862,20711,33678,30722,26432,21049,27801,32433,20667,21861,29022,31579,26194,
107429642,33515,26441,23665,21024,29053,34923,38378,38485,25797,36193,33203,21892,
107527733,25159,32558,22674,20260,21830,36175,26188,19978,
107623578,35059,26786,25422,31245,28903,33421,21242,38902,23569,21736,37045,32461,
107722882,36170,34503,33292,33293,36198,25668,23556,24913,28041,31038,35774,30775,
107830003,21627,20280,36523,28145,23072,32453,31070,27784,23457,23158,29978,32958,
107924910,28183,22768,29983,29989,29298,21319,32499,34051,34052,34053,34054,34055,
108034056,34057,34058,34059,34061,34062,34063,34064,34066,34068,34069,34070,34072,
108134073,34075,34076,34077,34078,34080,34082,34083,34084,34085,34086,34087,34088,
108234089,34090,34093,34094,34095,34096,34097,34098,34099,34100,34101,34102,34110,
108334111,34112,34113,34114,34116,34117,34118,34119,34123,34124,34125,34126,34127,
108434128,34129,34130,34131,34132,34133,34135,34136,34138,34139,34140,34141,34143,
108534144,34145,34146,34147,34149,34150,34151,34153,34154,34155,34156,34157,34158,
108634159,34160,34161,34163,34165,34166,34167,34168,34172,34173,34175,34176,34177,
108730465,30427,21097,32988,22307,24072,22833,29422,26045,28287,35799,23608,34417,
108821313,30707,25342,26102,20160,39135,34432,23454,35782,21490,30690,20351,23630,
108939542,22987,24335,31034,22763,19990,26623,20107,25325,35475,36893,21183,26159,
109021980,22124,36866,20181,20365,37322,39280,27663,24066,24643,23460,35270,35797,
109125910,25163,39318,23432,23551,25480,21806,21463,30246,20861,34092,26530,26803,
109227530,25234,36755,21460,33298,28113,30095,20070,36174,23408,29087,34223,26257,
109326329,32626,34560,40653,40736,23646,26415,36848,26641,26463,25101,31446,22661,
109424246,25968,28465,34178,34179,34182,34184,34185,34186,34187,34188,34189,34190,
109534192,34193,34194,34195,34196,34197,34198,34199,34200,
109634201,34202,34205,34206,34207,34208,34209,34210,34211,34213,34214,34215,34217,
109734219,34220,34221,34225,34226,34227,34228,34229,34230,34232,34234,34235,34236,
109834237,34238,34239,34240,34242,34243,34244,34245,34246,34247,34248,34250,34251,
109934252,34253,34254,34257,34258,34260,34262,34263,34264,34265,34266,34267,34269,
110034270,34271,34272,34273,34274,34275,34277,34278,34279,34280,34282,34283,34284,
110134285,34286,34287,34288,34289,34290,34291,34292,34293,34294,34295,34296,24661,
110221047,32781,25684,34928,29993,24069,26643,25332,38684,21452,29245,35841,27700,
110330561,31246,21550,30636,39034,33308,35828,30805,26388,28865,26031,25749,22070,
110424605,31169,21496,19997,27515,32902,23546,21987,22235,20282,20284,39282,24051,
110526494,32824,24578,39042,36865,23435,35772,35829,25628,33368,25822,22013,33487,
110637221,20439,32032,36895,31903,20723,22609,28335,23487,35785,32899,37240,33948,
110731639,34429,38539,38543,32485,39635,30862,23681,31319,36930,38567,31071,23385,
110825439,31499,34001,26797,21766,32553,29712,32034,38145,25152,22604,20182,23427,
110922905,22612,34297,34298,34300,34301,34302,34304,34305,34306,34307,34308,34310,
111034311,34312,34313,34314,34315,34316,34317,34318,34319,34320,34322,34323,34324,
111134325,34327,34328,34329,34330,34331,34332,34333,34334,34335,34336,34337,34338,
111234339,34340,34341,34342,34344,34346,34347,34348,34349,34350,34351,34352,34353,
111334354,34355,34356,34357,34358,34359,34361,34362,34363,34365,34366,34367,34368,
111434369,34370,34371,34372,34373,34374,34375,34376,34377,34378,34379,34380,34386,
111534387,34389,34390,34391,34392,34393,34395,34396,34397,
111634399,34400,34401,34403,34404,34405,34406,34407,34408,34409,34410,29549,25374,
111736427,36367,32974,33492,25260,21488,27888,37214,22826,24577,27760,22349,25674,
111836138,30251,28393,22363,27264,30192,28525,35885,35848,22374,27631,34962,30899,
111925506,21497,28845,27748,22616,25642,22530,26848,33179,21776,31958,20504,36538,
112028108,36255,28907,25487,28059,28372,32486,33796,26691,36867,28120,38518,35752,
112122871,29305,34276,33150,30140,35466,26799,21076,36386,38161,25552,39064,36420,
112221884,20307,26367,22159,24789,28053,21059,23625,22825,28155,22635,30000,29980,
112324684,33300,33094,25361,26465,36834,30522,36339,36148,38081,24086,21381,21548,
112428867,34413,34415,34416,34418,34419,34420,34421,34422,34423,34424,34435,34436,
112534437,34438,34439,34440,34441,34446,34447,34448,34449,34450,34452,34454,34455,
112634456,34457,34458,34459,34462,34463,34464,34465,34466,34469,34470,34475,34477,
112734478,34482,34483,34487,34488,34489,34491,34492,34493,34494,34495,34497,34498,
112834499,34501,34504,34508,34509,34514,34515,34517,34518,34519,34522,34524,34525,
112934528,34529,34530,34531,34533,34534,34535,34536,34538,34539,34540,34543,34549,
113034550,34551,34554,34555,34556,34557,34559,34561,34564,34565,34566,34571,34572,
113134574,34575,34576,34577,34580,34582,27712,24311,20572,20141,24237,25402,33351,
113236890,26704,37230,30643,21516,38108,24420,31461,26742,25413,31570,32479,30171,
113320599,25237,22836,36879,20984,31171,31361,22270,24466,36884,28034,23648,22303,
113421520,20820,28237,22242,25512,39059,33151,34581,35114,36864,21534,23663,33216,
113525302,25176,33073,40501,38464,39534,39548,26925,22949,
113625299,21822,25366,21703,34521,27964,23043,29926,34972,27498,22806,35916,24367,
113728286,29609,39037,20024,28919,23436,30871,25405,26202,30358,24779,23451,23113,
113819975,33109,27754,29579,20129,26505,32593,24448,26106,26395,24536,22916,23041,
113934585,34587,34589,34591,34592,34596,34598,34599,34600,34602,34603,34604,34605,
114034607,34608,34610,34611,34613,34614,34616,34617,34618,34620,34621,34624,34625,
114134626,34627,34628,34629,34630,34634,34635,34637,34639,34640,34641,34642,34644,
114234645,34646,34648,34650,34651,34652,34653,34654,34655,34657,34658,34662,34663,
114334664,34665,34666,34667,34668,34669,34671,34673,34674,34675,34677,34679,34680,
114434681,34682,34687,34688,34689,34692,34694,34695,34697,34698,34700,34702,34703,
114534704,34705,34706,34708,34709,34710,34712,34713,34714,34715,34716,34717,34718,
114634720,34721,34722,34723,34724,24013,24494,21361,38886,36829,26693,22260,21807,
114724799,20026,28493,32500,33479,33806,22996,20255,20266,23614,32428,26410,34074,
114821619,30031,32963,21890,39759,20301,28205,35859,23561,24944,21355,30239,28201,
114934442,25991,38395,32441,21563,31283,32010,38382,21985,32705,29934,25373,34583,
115028065,31389,25105,26017,21351,25569,27779,24043,21596,38056,20044,27745,35820,
115123627,26080,33436,26791,21566,21556,27595,27494,20116,25410,21320,33310,20237,
115220398,22366,25098,38654,26212,29289,21247,21153,24735,35823,26132,29081,26512,
115335199,30802,30717,26224,22075,21560,38177,29306,34725,34726,34727,34729,34730,
115434734,34736,34737,34738,34740,34742,34743,34744,34745,34747,34748,34750,34751,
115534753,34754,34755,34756,34757,34759,34760,34761,34764,
115634765,34766,34767,34768,34772,34773,34774,34775,34776,34777,34778,34780,34781,
115734782,34783,34785,34786,34787,34788,34790,34791,34792,34793,34795,34796,34797,
115834799,34800,34801,34802,34803,34804,34805,34806,34807,34808,34810,34811,34812,
115934813,34815,34816,34817,34818,34820,34821,34822,34823,34824,34825,34827,34828,
116034829,34830,34831,34832,34833,34834,34836,34839,34840,34841,34842,34844,34845,
116134846,34847,34848,34851,31232,24687,24076,24713,33181,22805,24796,29060,28911,
116228330,27728,29312,27268,34989,24109,20064,23219,21916,38115,27927,31995,38553,
116325103,32454,30606,34430,21283,38686,36758,26247,23777,20384,29421,19979,21414,
116422799,21523,25472,38184,20808,20185,40092,32420,21688,36132,34900,33335,38386,
116528046,24358,23244,26174,38505,29616,29486,21439,33146,39301,32673,23466,38519,
116638480,32447,30456,21410,38262,39321,31665,35140,28248,20065,32724,31077,35814,
116724819,21709,20139,39033,24055,27233,20687,21521,35937,33831,30813,38660,21066,
116821742,22179,38144,28040,23477,28102,26195,34852,34853,34854,34855,34856,34857,
116934858,34859,34860,34861,34862,34863,34864,34865,34867,34868,34869,34870,34871,
117034872,34874,34875,34877,34878,34879,34881,34882,34883,34886,34887,34888,34889,
117134890,34891,34894,34895,34896,34897,34898,34899,34901,34902,34904,34906,34907,
117234908,34909,34910,34911,34912,34918,34919,34922,34925,34927,34929,34931,34932,
117334933,34934,34936,34937,34938,34939,34940,34944,34947,34950,34951,34953,34954,
117434956,34958,34959,34960,34961,34963,34964,34965,34967,34968,34969,34970,34971,
117534973,34974,34975,34976,34977,34979,34981,34982,34983,
117634984,34985,34986,23567,23389,26657,32918,21880,31505,25928,26964,20123,27463,
117734638,38795,21327,25375,25658,37034,26012,32961,35856,20889,26800,21368,34809,
117825032,27844,27899,35874,23633,34218,33455,38156,27427,36763,26032,24571,24515,
117920449,34885,26143,33125,29481,24826,20852,21009,22411,24418,37026,34892,37266,
118024184,26447,24615,22995,20804,20982,33016,21256,27769,38596,29066,20241,20462,
118132670,26429,21957,38152,31168,34966,32483,22687,25100,38656,34394,22040,39035,
118224464,35768,33988,37207,21465,26093,24207,30044,24676,32110,23167,32490,32493,
118336713,21927,23459,24748,26059,29572,34988,34990,34991,34992,34994,34995,34996,
118434997,34998,35000,35001,35002,35003,35005,35006,35007,35008,35011,35012,35015,
118535016,35018,35019,35020,35021,35023,35024,35025,35027,35030,35031,35034,35035,
118635036,35037,35038,35040,35041,35046,35047,35049,35050,35051,35052,35053,35054,
118735055,35058,35061,35062,35063,35066,35067,35069,35071,35072,35073,35075,35076,
118835077,35078,35079,35080,35081,35083,35084,35085,35086,35087,35089,35092,35093,
118935094,35095,35096,35100,35101,35102,35103,35104,35106,35107,35108,35110,35111,
119035112,35113,35116,35117,35118,35119,35121,35122,35123,35125,35127,36873,30307,
119130505,32474,38772,34203,23398,31348,38634,34880,21195,29071,24490,26092,35810,
119223547,39535,24033,27529,27739,35757,35759,36874,36805,21387,25276,40486,40493,
119321568,20011,33469,29273,34460,23830,34905,28079,38597,21713,20122,35766,28937,
119421693,38409,28895,28153,30416,20005,30740,34578,23721,24310,35328,39068,38414,
119528814,27839,22852,25513,30524,34893,28436,33395,22576,
119629141,21388,30746,38593,21761,24422,28976,23476,35866,39564,27523,22830,40495,
119731207,26472,25196,20335,30113,32650,27915,38451,27687,20208,30162,20859,26679,
119828478,36992,33136,22934,29814,35128,35129,35130,35131,35132,35133,35134,35135,
119935136,35138,35139,35141,35142,35143,35144,35145,35146,35147,35148,35149,35150,
120035151,35152,35153,35154,35155,35156,35157,35158,35159,35160,35161,35162,35163,
120135164,35165,35168,35169,35170,35171,35172,35173,35175,35176,35177,35178,35179,
120235180,35181,35182,35183,35184,35185,35186,35187,35188,35189,35190,35191,35192,
120335193,35194,35196,35197,35198,35200,35202,35204,35205,35207,35208,35209,35210,
120435211,35212,35213,35214,35215,35216,35217,35218,35219,35220,35221,35222,35223,
120535224,35225,35226,35227,35228,35229,35230,35231,35232,35233,25671,23591,36965,
120631377,35875,23002,21676,33280,33647,35201,32768,26928,22094,32822,29239,37326,
120720918,20063,39029,25494,19994,21494,26355,33099,22812,28082,19968,22777,21307,
120825558,38129,20381,20234,34915,39056,22839,36951,31227,20202,33008,30097,27778,
120923452,23016,24413,26885,34433,20506,24050,20057,30691,20197,33402,25233,26131,
121037009,23673,20159,24441,33222,36920,32900,30123,20134,35028,24847,27589,24518,
121120041,30410,28322,35811,35758,35850,35793,24322,32764,32716,32462,33589,33643,
121222240,27575,38899,38452,23035,21535,38134,28139,23493,39278,23609,24341,38544,
121335234,35235,35236,35237,35238,35239,35240,35241,35242,35243,35244,35245,35246,
121435247,35248,35249,35250,35251,35252,35253,35254,35255,35256,35257,35258,35259,
121535260,35261,35262,35263,35264,35267,35277,35283,35284,
121635285,35287,35288,35289,35291,35293,35295,35296,35297,35298,35300,35303,35304,
121735305,35306,35308,35309,35310,35312,35313,35314,35316,35317,35318,35319,35320,
121835321,35322,35323,35324,35325,35326,35327,35329,35330,35331,35332,35333,35334,
121935336,35337,35338,35339,35340,35341,35342,35343,35344,35345,35346,35347,35348,
122035349,35350,35351,35352,35353,35354,35355,35356,35357,21360,33521,27185,23156,
122140560,24212,32552,33721,33828,33829,33639,34631,36814,36194,30408,24433,39062,
122230828,26144,21727,25317,20323,33219,30152,24248,38605,36362,34553,21647,27891,
122328044,27704,24703,21191,29992,24189,20248,24736,24551,23588,30001,37038,38080,
122429369,27833,28216,37193,26377,21451,21491,20305,37321,35825,21448,24188,36802,
122528132,20110,30402,27014,34398,24858,33286,20313,20446,36926,40060,24841,28189,
122628180,38533,20104,23089,38632,19982,23679,31161,23431,35821,32701,29577,22495,
122733419,37057,21505,36935,21947,23786,24481,24840,27442,29425,32946,35465,35358,
122835359,35360,35361,35362,35363,35364,35365,35366,35367,35368,35369,35370,35371,
122935372,35373,35374,35375,35376,35377,35378,35379,35380,35381,35382,35383,35384,
123035385,35386,35387,35388,35389,35391,35392,35393,35394,35395,35396,35397,35398,
123135399,35401,35402,35403,35404,35405,35406,35407,35408,35409,35410,35411,35412,
123235413,35414,35415,35416,35417,35418,35419,35420,35421,35422,35423,35424,35425,
123335426,35427,35428,35429,35430,35431,35432,35433,35434,35435,35436,35437,35438,
123435439,35440,35441,35442,35443,35444,35445,35446,35447,35448,35450,35451,35452,
123535453,35454,35455,35456,28020,23507,35029,39044,35947,
123639533,40499,28170,20900,20803,22435,34945,21407,25588,36757,22253,21592,22278,
123729503,28304,32536,36828,33489,24895,24616,38498,26352,32422,36234,36291,38053,
123823731,31908,26376,24742,38405,32792,20113,37095,21248,38504,20801,36816,34164,
123937213,26197,38901,23381,21277,30776,26434,26685,21705,28798,23472,36733,20877,
124022312,21681,25874,26242,36190,36163,33039,33900,36973,31967,20991,34299,26531,
124126089,28577,34468,36481,22122,36896,30338,28790,29157,36131,25321,21017,27901,
124236156,24590,22686,24974,26366,36192,25166,21939,28195,26413,36711,35457,35458,
124335459,35460,35461,35462,35463,35464,35467,35468,35469,35470,35471,35472,35473,
124435474,35476,35477,35478,35479,35480,35481,35482,35483,35484,35485,35486,35487,
124535488,35489,35490,35491,35492,35493,35494,35495,35496,35497,35498,35499,35500,
124635501,35502,35503,35504,35505,35506,35507,35508,35509,35510,35511,35512,35513,
124735514,35515,35516,35517,35518,35519,35520,35521,35522,35523,35524,35525,35526,
124835527,35528,35529,35530,35531,35532,35533,35534,35535,35536,35537,35538,35539,
124935540,35541,35542,35543,35544,35545,35546,35547,35548,35549,35550,35551,35552,
125035553,35554,35555,38113,38392,30504,26629,27048,21643,20045,28856,35784,25688,
125125995,23429,31364,20538,23528,30651,27617,35449,31896,27838,30415,26025,36759,
125223853,23637,34360,26632,21344,25112,31449,28251,32509,27167,31456,24432,28467,
125324352,25484,28072,26454,19976,24080,36134,20183,32960,30260,38556,25307,26157,
125425214,27836,36213,29031,32617,20806,32903,21484,36974,25240,21746,34544,36761,
125532773,38167,34071,36825,27993,29645,26015,30495,29956,
125630759,33275,36126,38024,20390,26517,30137,35786,38663,25391,38215,38453,33976,
125725379,30529,24449,29424,20105,24596,25972,25327,27491,25919,35556,35557,35558,
125835559,35560,35561,35562,35563,35564,35565,35566,35567,35568,35569,35570,35571,
125935572,35573,35574,35575,35576,35577,35578,35579,35580,35581,35582,35583,35584,
126035585,35586,35587,35588,35589,35590,35592,35593,35594,35595,35596,35597,35598,
126135599,35600,35601,35602,35603,35604,35605,35606,35607,35608,35609,35610,35611,
126235612,35613,35614,35615,35616,35617,35618,35619,35620,35621,35623,35624,35625,
126335626,35627,35628,35629,35630,35631,35632,35633,35634,35635,35636,35637,35638,
126435639,35640,35641,35642,35643,35644,35645,35646,35647,35648,35649,35650,35651,
126535652,35653,24103,30151,37073,35777,33437,26525,25903,21553,34584,30693,32930,
126633026,27713,20043,32455,32844,30452,26893,27542,25191,20540,20356,22336,25351,
126727490,36286,21482,26088,32440,24535,25370,25527,33267,33268,32622,24092,23769,
126821046,26234,31209,31258,36136,28825,30164,28382,27835,31378,20013,30405,24544,
126938047,34935,32456,31181,32959,37325,20210,20247,33311,21608,24030,27954,35788,
127031909,36724,32920,24090,21650,30385,23449,26172,39588,29664,26666,34523,26417,
127129482,35832,35803,36880,31481,28891,29038,25284,30633,22065,20027,33879,26609,
127221161,34496,36142,38136,31569,35654,35655,35656,35657,35658,35659,35660,35661,
127335662,35663,35664,35665,35666,35667,35668,35669,35670,35671,35672,35673,35674,
127435675,35676,35677,35678,35679,35680,35681,35682,35683,35684,35685,35687,35688,
127535689,35690,35691,35693,35694,35695,35696,35697,35698,
127635699,35700,35701,35702,35703,35704,35705,35706,35707,35708,35709,35710,35711,
127735712,35713,35714,35715,35716,35717,35718,35719,35720,35721,35722,35723,35724,
127835725,35726,35727,35728,35729,35730,35731,35732,35733,35734,35735,35736,35737,
127935738,35739,35740,35741,35742,35743,35756,35761,35771,35783,35792,35818,35849,
128035870,20303,27880,31069,39547,25235,29226,25341,19987,30742,36716,25776,36186,
128131686,26729,24196,35013,22918,25758,22766,29366,26894,38181,36861,36184,22368,
128232512,35846,20934,25417,25305,21331,26700,29730,33537,37196,21828,30528,28796,
128327978,20857,21672,36164,23039,28363,28100,23388,32043,20180,31869,28371,23376,
128433258,28173,23383,39683,26837,36394,23447,32508,24635,32437,37049,36208,22863,
128525549,31199,36275,21330,26063,31062,35781,38459,32452,38075,32386,22068,37257,
128626368,32618,23562,36981,26152,24038,20304,26590,20570,20316,22352,24231,59408,
128759409,59410,59411,59412,35896,35897,35898,35899,35900,35901,35902,35903,35904,
128835906,35907,35908,35909,35912,35914,35915,35917,35918,35919,35920,35921,35922,
128935923,35924,35926,35927,35928,35929,35931,35932,35933,35934,35935,35936,35939,
129035940,35941,35942,35943,35944,35945,35948,35949,35950,35951,35952,35953,35954,
129135956,35957,35958,35959,35963,35964,35965,35966,35967,35968,35969,35971,35972,
129235974,35975,35976,35979,35981,35982,35983,35984,35985,35986,35987,35989,35990,
129335991,35993,35994,35995,35996,35997,35998,35999,36000,36001,36002,36003,36004,
129436005,36006,36007,36008,36009,36010,36011,36012,36013,20109,19980,20800,19984,
129524319,21317,19989,20120,19998,39730,23404,22121,20008,
129631162,20031,21269,20039,22829,29243,21358,27664,22239,32996,39319,27603,30590,
129740727,20022,20127,40720,20060,20073,20115,33416,23387,21868,22031,20164,21389,
129821405,21411,21413,21422,38757,36189,21274,21493,21286,21294,21310,36188,21350,
129921347,20994,21000,21006,21037,21043,21055,21056,21068,21086,21089,21084,33967,
130021117,21122,21121,21136,21139,20866,32596,20155,20163,20169,20162,20200,20193,
130120203,20190,20251,20211,20258,20324,20213,20261,20263,20233,20267,20318,20327,
130225912,20314,20317,36014,36015,36016,36017,36018,36019,36020,36021,36022,36023,
130336024,36025,36026,36027,36028,36029,36030,36031,36032,36033,36034,36035,36036,
130436037,36038,36039,36040,36041,36042,36043,36044,36045,36046,36047,36048,36049,
130536050,36051,36052,36053,36054,36055,36056,36057,36058,36059,36060,36061,36062,
130636063,36064,36065,36066,36067,36068,36069,36070,36071,36072,36073,36074,36075,
130736076,36077,36078,36079,36080,36081,36082,36083,36084,36085,36086,36087,36088,
130836089,36090,36091,36092,36093,36094,36095,36096,36097,36098,36099,36100,36101,
130936102,36103,36104,36105,36106,36107,36108,36109,20319,20311,20274,20285,20342,
131020340,20369,20361,20355,20367,20350,20347,20394,20348,20396,20372,20454,20456,
131120458,20421,20442,20451,20444,20433,20447,20472,20521,20556,20467,20524,20495,
131220526,20525,20478,20508,20492,20517,20520,20606,20547,20565,20552,20558,20588,
131320603,20645,20647,20649,20666,20694,20742,20717,20716,20710,20718,20743,20747,
131420189,27709,20312,20325,20430,40864,27718,31860,20846,24061,40649,39320,20865,
131522804,21241,21261,35335,21264,20971,22809,20821,20128,
131620822,20147,34926,34980,20149,33044,35026,31104,23348,34819,32696,20907,20913,
131720925,20924,36110,36111,36112,36113,36114,36115,36116,36117,36118,36119,36120,
131836121,36122,36123,36124,36128,36177,36178,36183,36191,36197,36200,36201,36202,
131936204,36206,36207,36209,36210,36216,36217,36218,36219,36220,36221,36222,36223,
132036224,36226,36227,36230,36231,36232,36233,36236,36237,36238,36239,36240,36242,
132136243,36245,36246,36247,36248,36249,36250,36251,36252,36253,36254,36256,36257,
132236258,36260,36261,36262,36263,36264,36265,36266,36267,36268,36269,36270,36271,
132336272,36274,36278,36279,36281,36283,36285,36288,36289,36290,36293,36295,36296,
132436297,36298,36301,36304,36306,36307,36308,20935,20886,20898,20901,35744,35750,
132535751,35754,35764,35765,35767,35778,35779,35787,35791,35790,35794,35795,35796,
132635798,35800,35801,35804,35807,35808,35812,35816,35817,35822,35824,35827,35830,
132735833,35836,35839,35840,35842,35844,35847,35852,35855,35857,35858,35860,35861,
132835862,35865,35867,35864,35869,35871,35872,35873,35877,35879,35882,35883,35886,
132935887,35890,35891,35893,35894,21353,21370,38429,38434,38433,38449,38442,38461,
133038460,38466,38473,38484,38495,38503,38508,38514,38516,38536,38541,38551,38576,
133137015,37019,37021,37017,37036,37025,37044,37043,37046,37050,36309,36312,36313,
133236316,36320,36321,36322,36325,36326,36327,36329,36333,36334,36336,36337,36338,
133336340,36342,36348,36350,36351,36352,36353,36354,36355,36356,36358,36359,36360,
133436363,36365,36366,36368,36369,36370,36371,36373,36374,36375,36376,36377,36378,
133536379,36380,36384,36385,36388,36389,36390,36391,36392,
133636395,36397,36400,36402,36403,36404,36406,36407,36408,36411,36412,36414,36415,
133736419,36421,36422,36428,36429,36430,36431,36432,36435,36436,36437,36438,36439,
133836440,36442,36443,36444,36445,36446,36447,36448,36449,36450,36451,36452,36453,
133936455,36456,36458,36459,36462,36465,37048,37040,37071,37061,37054,37072,37060,
134037063,37075,37094,37090,37084,37079,37083,37099,37103,37118,37124,37154,37150,
134137155,37169,37167,37177,37187,37190,21005,22850,21154,21164,21165,21182,21759,
134221200,21206,21232,21471,29166,30669,24308,20981,20988,39727,21430,24321,30042,
134324047,22348,22441,22433,22654,22716,22725,22737,22313,22316,22314,22323,22329,
134422318,22319,22364,22331,22338,22377,22405,22379,22406,22396,22395,22376,22381,
134522390,22387,22445,22436,22412,22450,22479,22439,22452,22419,22432,22485,22488,
134622490,22489,22482,22456,22516,22511,22520,22500,22493,36467,36469,36471,36472,
134736473,36474,36475,36477,36478,36480,36482,36483,36484,36486,36488,36489,36490,
134836491,36492,36493,36494,36497,36498,36499,36501,36502,36503,36504,36505,36506,
134936507,36509,36511,36512,36513,36514,36515,36516,36517,36518,36519,36520,36521,
135036522,36525,36526,36528,36529,36531,36532,36533,36534,36535,36536,36537,36539,
135136540,36541,36542,36543,36544,36545,36546,36547,36548,36549,36550,36551,36552,
135236553,36554,36555,36556,36557,36559,36560,36561,36562,36563,36564,36565,36566,
135336567,36568,36569,36570,36571,36572,36573,36574,36575,36576,36577,36578,36579,
135436580,22539,22541,22525,22509,22528,22558,22553,22596,22560,22629,22636,22657,
135522665,22682,22656,39336,40729,25087,33401,33405,33407,
135633423,33418,33448,33412,33422,33425,33431,33433,33451,33464,33470,33456,33480,
135733482,33507,33432,33463,33454,33483,33484,33473,33449,33460,33441,33450,33439,
135833476,33486,33444,33505,33545,33527,33508,33551,33543,33500,33524,33490,33496,
135933548,33531,33491,33553,33562,33542,33556,33557,33504,33493,33564,33617,33627,
136033628,33544,33682,33596,33588,33585,33691,33630,33583,33615,33607,33603,33631,
136133600,33559,33632,33581,33594,33587,33638,33637,36581,36582,36583,36584,36585,
136236586,36587,36588,36589,36590,36591,36592,36593,36594,36595,36596,36597,36598,
136336599,36600,36601,36602,36603,36604,36605,36606,36607,36608,36609,36610,36611,
136436612,36613,36614,36615,36616,36617,36618,36619,36620,36621,36622,36623,36624,
136536625,36626,36627,36628,36629,36630,36631,36632,36633,36634,36635,36636,36637,
136636638,36639,36640,36641,36642,36643,36644,36645,36646,36647,36648,36649,36650,
136736651,36652,36653,36654,36655,36656,36657,36658,36659,36660,36661,36662,36663,
136836664,36665,36666,36667,36668,36669,36670,36671,36672,36673,36674,36675,36676,
136933640,33563,33641,33644,33642,33645,33646,33712,33656,33715,33716,33696,33706,
137033683,33692,33669,33660,33718,33705,33661,33720,33659,33688,33694,33704,33722,
137133724,33729,33793,33765,33752,22535,33816,33803,33757,33789,33750,33820,33848,
137233809,33798,33748,33759,33807,33795,33784,33785,33770,33733,33728,33830,33776,
137333761,33884,33873,33882,33881,33907,33927,33928,33914,33929,33912,33852,33862,
137433897,33910,33932,33934,33841,33901,33985,33997,34000,34022,33981,34003,33994,
137533983,33978,34016,33953,33977,33972,33943,34021,34019,
137634060,29965,34104,34032,34105,34079,34106,36677,36678,36679,36680,36681,36682,
137736683,36684,36685,36686,36687,36688,36689,36690,36691,36692,36693,36694,36695,
137836696,36697,36698,36699,36700,36701,36702,36703,36704,36705,36706,36707,36708,
137936709,36714,36736,36748,36754,36765,36768,36769,36770,36772,36773,36774,36775,
138036778,36780,36781,36782,36783,36786,36787,36788,36789,36791,36792,36794,36795,
138136796,36799,36800,36803,36806,36809,36810,36811,36812,36813,36815,36818,36822,
138236823,36826,36832,36833,36835,36839,36844,36847,36849,36850,36852,36853,36854,
138336858,36859,36860,36862,36863,36871,36872,36876,36878,36883,36885,36888,34134,
138434107,34047,34044,34137,34120,34152,34148,34142,34170,30626,34115,34162,34171,
138534212,34216,34183,34191,34169,34222,34204,34181,34233,34231,34224,34259,34241,
138634268,34303,34343,34309,34345,34326,34364,24318,24328,22844,22849,32823,22869,
138722874,22872,21263,23586,23589,23596,23604,25164,25194,25247,25275,25290,25306,
138825303,25326,25378,25334,25401,25419,25411,25517,25590,25457,25466,25486,25524,
138925453,25516,25482,25449,25518,25532,25586,25592,25568,25599,25540,25566,25550,
139025682,25542,25534,25669,25665,25611,25627,25632,25612,25638,25633,25694,25732,
139125709,25750,36889,36892,36899,36900,36901,36903,36904,36905,36906,36907,36908,
139236912,36913,36914,36915,36916,36919,36921,36922,36925,36927,36928,36931,36933,
139336934,36936,36937,36938,36939,36940,36942,36948,36949,36950,36953,36954,36956,
139436957,36958,36959,36960,36961,36964,36966,36967,36969,36970,36971,36972,36975,
139536976,36977,36978,36979,36982,36983,36984,36985,36986,
139636987,36988,36990,36993,36996,36997,36998,36999,37001,37002,37004,37005,37006,
139737007,37008,37010,37012,37014,37016,37018,37020,37022,37023,37024,37028,37029,
139837031,37032,37033,37035,37037,37042,37047,37052,37053,37055,37056,25722,25783,
139925784,25753,25786,25792,25808,25815,25828,25826,25865,25893,25902,24331,24530,
140029977,24337,21343,21489,21501,21481,21480,21499,21522,21526,21510,21579,21586,
140121587,21588,21590,21571,21537,21591,21593,21539,21554,21634,21652,21623,21617,
140221604,21658,21659,21636,21622,21606,21661,21712,21677,21698,21684,21714,21671,
140321670,21715,21716,21618,21667,21717,21691,21695,21708,21721,21722,21724,21673,
140421674,21668,21725,21711,21726,21787,21735,21792,21757,21780,21747,21794,21795,
140521775,21777,21799,21802,21863,21903,21941,21833,21869,21825,21845,21823,21840,
140621820,37058,37059,37062,37064,37065,37067,37068,37069,37074,37076,37077,37078,
140737080,37081,37082,37086,37087,37088,37091,37092,37093,37097,37098,37100,37102,
140837104,37105,37106,37107,37109,37110,37111,37113,37114,37115,37116,37119,37120,
140937121,37123,37125,37126,37127,37128,37129,37130,37131,37132,37133,37134,37135,
141037136,37137,37138,37139,37140,37141,37142,37143,37144,37146,37147,37148,37149,
141137151,37152,37153,37156,37157,37158,37159,37160,37161,37162,37163,37164,37165,
141237166,37168,37170,37171,37172,37173,37174,37175,37176,37178,37179,37180,37181,
141337182,37183,37184,37185,37186,37188,21815,21846,21877,21878,21879,21811,21808,
141421852,21899,21970,21891,21937,21945,21896,21889,21919,21886,21974,21905,21883,
141521983,21949,21950,21908,21913,21994,22007,21961,22047,
141621969,21995,21996,21972,21990,21981,21956,21999,21989,22002,22003,21964,21965,
141721992,22005,21988,36756,22046,22024,22028,22017,22052,22051,22014,22016,22055,
141822061,22104,22073,22103,22060,22093,22114,22105,22108,22092,22100,22150,22116,
141922129,22123,22139,22140,22149,22163,22191,22228,22231,22237,22241,22261,22251,
142022265,22271,22276,22282,22281,22300,24079,24089,24084,24081,24113,24123,24124,
142137189,37191,37192,37201,37203,37204,37205,37206,37208,37209,37211,37212,37215,
142237216,37222,37223,37224,37227,37229,37235,37242,37243,37244,37248,37249,37250,
142337251,37252,37254,37256,37258,37262,37263,37267,37268,37269,37270,37271,37272,
142437273,37276,37277,37278,37279,37280,37281,37284,37285,37286,37287,37288,37289,
142537291,37292,37296,37297,37298,37299,37302,37303,37304,37305,37307,37308,37309,
142637310,37311,37312,37313,37314,37315,37316,37317,37318,37320,37323,37328,37330,
142737331,37332,37333,37334,37335,37336,37337,37338,37339,37341,37342,37343,37344,
142837345,37346,37347,37348,37349,24119,24132,24148,24155,24158,24161,23692,23674,
142923693,23696,23702,23688,23704,23705,23697,23706,23708,23733,23714,23741,23724,
143023723,23729,23715,23745,23735,23748,23762,23780,23755,23781,23810,23811,23847,
143123846,23854,23844,23838,23814,23835,23896,23870,23860,23869,23916,23899,23919,
143223901,23915,23883,23882,23913,23924,23938,23961,23965,35955,23991,24005,24435,
143324439,24450,24455,24457,24460,24469,24473,24476,24488,24493,24501,24508,34914,
143424417,29357,29360,29364,29367,29368,29379,29377,29390,29389,29394,29416,29423,
143529417,29426,29428,29431,29441,29427,29443,29434,37350,
143637351,37352,37353,37354,37355,37356,37357,37358,37359,37360,37361,37362,37363,
143737364,37365,37366,37367,37368,37369,37370,37371,37372,37373,37374,37375,37376,
143837377,37378,37379,37380,37381,37382,37383,37384,37385,37386,37387,37388,37389,
143937390,37391,37392,37393,37394,37395,37396,37397,37398,37399,37400,37401,37402,
144037403,37404,37405,37406,37407,37408,37409,37410,37411,37412,37413,37414,37415,
144137416,37417,37418,37419,37420,37421,37422,37423,37424,37425,37426,37427,37428,
144237429,37430,37431,37432,37433,37434,37435,37436,37437,37438,37439,37440,37441,
144337442,37443,37444,37445,29435,29463,29459,29473,29450,29470,29469,29461,29474,
144429497,29477,29484,29496,29489,29520,29517,29527,29536,29548,29551,29566,33307,
144522821,39143,22820,22786,39267,39271,39272,39273,39274,39275,39276,39284,39287,
144639293,39296,39300,39303,39306,39309,39312,39313,39315,39316,39317,24192,24209,
144724203,24214,24229,24224,24249,24245,24254,24243,36179,24274,24273,24283,24296,
144824298,33210,24516,24521,24534,24527,24579,24558,24580,24545,24548,24574,24581,
144924582,24554,24557,24568,24601,24629,24614,24603,24591,24589,24617,24619,24586,
145024639,24609,24696,24697,24699,24698,24642,37446,37447,37448,37449,37450,37451,
145137452,37453,37454,37455,37456,37457,37458,37459,37460,37461,37462,37463,37464,
145237465,37466,37467,37468,37469,37470,37471,37472,37473,37474,37475,37476,37477,
145337478,37479,37480,37481,37482,37483,37484,37485,37486,37487,37488,37489,37490,
145437491,37493,37494,37495,37496,37497,37498,37499,37500,37501,37502,37503,37504,
145537505,37506,37507,37508,37509,37510,37511,37512,37513,
145637514,37515,37516,37517,37519,37520,37521,37522,37523,37524,37525,37526,37527,
145737528,37529,37530,37531,37532,37533,37534,37535,37536,37537,37538,37539,37540,
145837541,37542,37543,24682,24701,24726,24730,24749,24733,24707,24722,24716,24731,
145924812,24763,24753,24797,24792,24774,24794,24756,24864,24870,24853,24867,24820,
146024832,24846,24875,24906,24949,25004,24980,24999,25015,25044,25077,24541,38579,
146138377,38379,38385,38387,38389,38390,38396,38398,38403,38404,38406,38408,38410,
146238411,38412,38413,38415,38418,38421,38422,38423,38425,38426,20012,29247,25109,
146327701,27732,27740,27722,27811,27781,27792,27796,27788,27752,27753,27764,27766,
146427782,27817,27856,27860,27821,27895,27896,27889,27863,27826,27872,27862,27898,
146527883,27886,27825,27859,27887,27902,37544,37545,37546,37547,37548,37549,37551,
146637552,37553,37554,37555,37556,37557,37558,37559,37560,37561,37562,37563,37564,
146737565,37566,37567,37568,37569,37570,37571,37572,37573,37574,37575,37577,37578,
146837579,37580,37581,37582,37583,37584,37585,37586,37587,37588,37589,37590,37591,
146937592,37593,37594,37595,37596,37597,37598,37599,37600,37601,37602,37603,37604,
147037605,37606,37607,37608,37609,37610,37611,37612,37613,37614,37615,37616,37617,
147137618,37619,37620,37621,37622,37623,37624,37625,37626,37627,37628,37629,37630,
147237631,37632,37633,37634,37635,37636,37637,37638,37639,37640,37641,27961,27943,
147327916,27971,27976,27911,27908,27929,27918,27947,27981,27950,27957,27930,27983,
147427986,27988,27955,28049,28015,28062,28064,27998,28051,28052,27996,28000,28028,
147528003,28186,28103,28101,28126,28174,28095,28128,28177,
147628134,28125,28121,28182,28075,28172,28078,28203,28270,28238,28267,28338,28255,
147728294,28243,28244,28210,28197,28228,28383,28337,28312,28384,28461,28386,28325,
147828327,28349,28347,28343,28375,28340,28367,28303,28354,28319,28514,28486,28487,
147928452,28437,28409,28463,28470,28491,28532,28458,28425,28457,28553,28557,28556,
148028536,28530,28540,28538,28625,37642,37643,37644,37645,37646,37647,37648,37649,
148137650,37651,37652,37653,37654,37655,37656,37657,37658,37659,37660,37661,37662,
148237663,37664,37665,37666,37667,37668,37669,37670,37671,37672,37673,37674,37675,
148337676,37677,37678,37679,37680,37681,37682,37683,37684,37685,37686,37687,37688,
148437689,37690,37691,37692,37693,37695,37696,37697,37698,37699,37700,37701,37702,
148537703,37704,37705,37706,37707,37708,37709,37710,37711,37712,37713,37714,37715,
148637716,37717,37718,37719,37720,37721,37722,37723,37724,37725,37726,37727,37728,
148737729,37730,37731,37732,37733,37734,37735,37736,37737,37739,28617,28583,28601,
148828598,28610,28641,28654,28638,28640,28655,28698,28707,28699,28729,28725,28751,
148928766,23424,23428,23445,23443,23461,23480,29999,39582,25652,23524,23534,35120,
149023536,36423,35591,36790,36819,36821,36837,36846,36836,36841,36838,36851,36840,
149136869,36868,36875,36902,36881,36877,36886,36897,36917,36918,36909,36911,36932,
149236945,36946,36944,36968,36952,36962,36955,26297,36980,36989,36994,37000,36995,
149337003,24400,24407,24406,24408,23611,21675,23632,23641,23409,23651,23654,32700,
149424362,24361,24365,33396,24380,39739,23662,22913,22915,22925,22953,22954,22947,
149537740,37741,37742,37743,37744,37745,37746,37747,37748,
149637749,37750,37751,37752,37753,37754,37755,37756,37757,37758,37759,37760,37761,
149737762,37763,37764,37765,37766,37767,37768,37769,37770,37771,37772,37773,37774,
149837776,37777,37778,37779,37780,37781,37782,37783,37784,37785,37786,37787,37788,
149937789,37790,37791,37792,37793,37794,37795,37796,37797,37798,37799,37800,37801,
150037802,37803,37804,37805,37806,37807,37808,37809,37810,37811,37812,37813,37814,
150137815,37816,37817,37818,37819,37820,37821,37822,37823,37824,37825,37826,37827,
150237828,37829,37830,37831,37832,37833,37835,37836,37837,22935,22986,22955,22942,
150322948,22994,22962,22959,22999,22974,23045,23046,23005,23048,23011,23000,23033,
150423052,23049,23090,23092,23057,23075,23059,23104,23143,23114,23125,23100,23138,
150523157,33004,23210,23195,23159,23162,23230,23275,23218,23250,23252,23224,23264,
150623267,23281,23254,23270,23256,23260,23305,23319,23318,23346,23351,23360,23573,
150723580,23386,23397,23411,23377,23379,23394,39541,39543,39544,39546,39551,39549,
150839552,39553,39557,39560,39562,39568,39570,39571,39574,39576,39579,39580,39581,
150939583,39584,39586,39587,39589,39591,32415,32417,32419,32421,32424,32425,37838,
151037839,37840,37841,37842,37843,37844,37845,37847,37848,37849,37850,37851,37852,
151137853,37854,37855,37856,37857,37858,37859,37860,37861,37862,37863,37864,37865,
151237866,37867,37868,37869,37870,37871,37872,37873,37874,37875,37876,37877,37878,
151337879,37880,37881,37882,37883,37884,37885,37886,37887,37888,37889,37890,37891,
151437892,37893,37894,37895,37896,37897,37898,37899,37900,37901,37902,37903,37904,
151537905,37906,37907,37908,37909,37910,37911,37912,37913,
151637914,37915,37916,37917,37918,37919,37920,37921,37922,37923,37924,37925,37926,
151737927,37928,37929,37930,37931,37932,37933,37934,32429,32432,32446,32448,32449,
151832450,32457,32459,32460,32464,32468,32471,32475,32480,32481,32488,32491,32494,
151932495,32497,32498,32525,32502,32506,32507,32510,32513,32514,32515,32519,32520,
152032523,32524,32527,32529,32530,32535,32537,32540,32539,32543,32545,32546,32547,
152132548,32549,32550,32551,32554,32555,32556,32557,32559,32560,32561,32562,32563,
152232565,24186,30079,24027,30014,37013,29582,29585,29614,29602,29599,29647,29634,
152329649,29623,29619,29632,29641,29640,29669,29657,39036,29706,29673,29671,29662,
152429626,29682,29711,29738,29787,29734,29733,29736,29744,29742,29740,37935,37936,
152537937,37938,37939,37940,37941,37942,37943,37944,37945,37946,37947,37948,37949,
152637951,37952,37953,37954,37955,37956,37957,37958,37959,37960,37961,37962,37963,
152737964,37965,37966,37967,37968,37969,37970,37971,37972,37973,37974,37975,37976,
152837977,37978,37979,37980,37981,37982,37983,37984,37985,37986,37987,37988,37989,
152937990,37991,37992,37993,37994,37996,37997,37998,37999,38000,38001,38002,38003,
153038004,38005,38006,38007,38008,38009,38010,38011,38012,38013,38014,38015,38016,
153138017,38018,38019,38020,38033,38038,38040,38087,38095,38099,38100,38106,38118,
153238139,38172,38176,29723,29722,29761,29788,29783,29781,29785,29815,29805,29822,
153329852,29838,29824,29825,29831,29835,29854,29864,29865,29840,29863,29906,29882,
153438890,38891,38892,26444,26451,26462,26440,26473,26533,26503,26474,26483,26520,
153526535,26485,26536,26526,26541,26507,26487,26492,26608,
153626633,26584,26634,26601,26544,26636,26585,26549,26586,26547,26589,26624,26563,
153726552,26594,26638,26561,26621,26674,26675,26720,26721,26702,26722,26692,26724,
153826755,26653,26709,26726,26689,26727,26688,26686,26698,26697,26665,26805,26767,
153926740,26743,26771,26731,26818,26990,26876,26911,26912,26873,38183,38195,38205,
154038211,38216,38219,38229,38234,38240,38254,38260,38261,38263,38264,38265,38266,
154138267,38268,38269,38270,38272,38273,38274,38275,38276,38277,38278,38279,38280,
154238281,38282,38283,38284,38285,38286,38287,38288,38289,38290,38291,38292,38293,
154338294,38295,38296,38297,38298,38299,38300,38301,38302,38303,38304,38305,38306,
154438307,38308,38309,38310,38311,38312,38313,38314,38315,38316,38317,38318,38319,
154538320,38321,38322,38323,38324,38325,38326,38327,38328,38329,38330,38331,38332,
154638333,38334,38335,38336,38337,38338,38339,38340,38341,38342,38343,38344,38345,
154738346,38347,26916,26864,26891,26881,26967,26851,26896,26993,26937,26976,26946,
154826973,27012,26987,27008,27032,27000,26932,27084,27015,27016,27086,27017,26982,
154926979,27001,27035,27047,27067,27051,27053,27092,27057,27073,27082,27103,27029,
155027104,27021,27135,27183,27117,27159,27160,27237,27122,27204,27198,27296,27216,
155127227,27189,27278,27257,27197,27176,27224,27260,27281,27280,27305,27287,27307,
155229495,29522,27521,27522,27527,27524,27538,27539,27533,27546,27547,27553,27562,
155336715,36717,36721,36722,36723,36725,36726,36728,36727,36729,36730,36732,36734,
155436737,36738,36740,36743,36747,38348,38349,38350,38351,38352,38353,38354,38355,
155538356,38357,38358,38359,38360,38361,38362,38363,38364,
155638365,38366,38367,38368,38369,38370,38371,38372,38373,38374,38375,38380,38399,
155738407,38419,38424,38427,38430,38432,38435,38436,38437,38438,38439,38440,38441,
155838443,38444,38445,38447,38448,38455,38456,38457,38458,38462,38465,38467,38474,
155938478,38479,38481,38482,38483,38486,38487,38488,38489,38490,38492,38493,38494,
156038496,38499,38501,38502,38507,38509,38510,38511,38512,38513,38515,38520,38521,
156138522,38523,38524,38525,38526,38527,38528,38529,38530,38531,38532,38535,38537,
156238538,36749,36750,36751,36760,36762,36558,25099,25111,25115,25119,25122,25121,
156325125,25124,25132,33255,29935,29940,29951,29967,29969,29971,25908,26094,26095,
156426096,26122,26137,26482,26115,26133,26112,28805,26359,26141,26164,26161,26166,
156526165,32774,26207,26196,26177,26191,26198,26209,26199,26231,26244,26252,26279,
156626269,26302,26331,26332,26342,26345,36146,36147,36150,36155,36157,36160,36165,
156736166,36168,36169,36167,36173,36181,36185,35271,35274,35275,35276,35278,35279,
156835280,35281,29294,29343,29277,29286,29295,29310,29311,29316,29323,29325,29327,
156929330,25352,25394,25520,38540,38542,38545,38546,38547,38549,38550,38554,38555,
157038557,38558,38559,38560,38561,38562,38563,38564,38565,38566,38568,38569,38570,
157138571,38572,38573,38574,38575,38577,38578,38580,38581,38583,38584,38586,38587,
157238591,38594,38595,38600,38602,38603,38608,38609,38611,38612,38614,38615,38616,
157338617,38618,38619,38620,38621,38622,38623,38625,38626,38627,38628,38629,38630,
157438631,38635,38636,38637,38638,38640,38641,38642,38644,38645,38648,38650,38651,
157538652,38653,38655,38658,38659,38661,38666,38667,38668,
157638672,38673,38674,38676,38677,38679,38680,38681,38682,38683,38685,38687,38688,
157725663,25816,32772,27626,27635,27645,27637,27641,27653,27655,27654,27661,27669,
157827672,27673,27674,27681,27689,27684,27690,27698,25909,25941,25963,29261,29266,
157929270,29232,34402,21014,32927,32924,32915,32956,26378,32957,32945,32939,32941,
158032948,32951,32999,33000,33001,33002,32987,32962,32964,32985,32973,32983,26384,
158132989,33003,33009,33012,33005,33037,33038,33010,33020,26389,33042,35930,33078,
158233054,33068,33048,33074,33096,33100,33107,33140,33113,33114,33137,33120,33129,
158333148,33149,33133,33127,22605,23221,33160,33154,33169,28373,33187,33194,33228,
158426406,33226,33211,38689,38690,38691,38692,38693,38694,38695,38696,38697,38699,
158538700,38702,38703,38705,38707,38708,38709,38710,38711,38714,38715,38716,38717,
158638719,38720,38721,38722,38723,38724,38725,38726,38727,38728,38729,38730,38731,
158738732,38733,38734,38735,38736,38737,38740,38741,38743,38744,38746,38748,38749,
158838751,38755,38756,38758,38759,38760,38762,38763,38764,38765,38766,38767,38768,
158938769,38770,38773,38775,38776,38777,38778,38779,38781,38782,38783,38784,38785,
159038786,38787,38788,38790,38791,38792,38793,38794,38796,38798,38799,38800,38803,
159138805,38806,38807,38809,38810,38811,38812,38813,33217,33190,27428,27447,27449,
159227459,27462,27481,39121,39122,39123,39125,39129,39130,27571,24384,27586,35315,
159326000,40785,26003,26044,26054,26052,26051,26060,26062,26066,26070,28800,28828,
159428822,28829,28859,28864,28855,28843,28849,28904,28874,28944,28947,28950,28975,
159528977,29043,29020,29032,28997,29042,29002,29048,29050,
159629080,29107,29109,29096,29088,29152,29140,29159,29177,29213,29224,28780,28952,
159729030,29113,25150,25149,25155,25160,25161,31035,31040,31046,31049,31067,31068,
159831059,31066,31074,31063,31072,31087,31079,31098,31109,31114,31130,31143,31155,
159924529,24528,38814,38815,38817,38818,38820,38821,38822,38823,38824,38825,38826,
160038828,38830,38832,38833,38835,38837,38838,38839,38840,38841,38842,38843,38844,
160138845,38846,38847,38848,38849,38850,38851,38852,38853,38854,38855,38856,38857,
160238858,38859,38860,38861,38862,38863,38864,38865,38866,38867,38868,38869,38870,
160338871,38872,38873,38874,38875,38876,38877,38878,38879,38880,38881,38882,38883,
160438884,38885,38888,38894,38895,38896,38897,38898,38900,38903,38904,38905,38906,
160538907,38908,38909,38910,38911,38912,38913,38914,38915,38916,38917,38918,38919,
160638920,38921,38922,38923,38924,38925,38926,24636,24669,24666,24679,24641,24665,
160724675,24747,24838,24845,24925,25001,24989,25035,25041,25094,32896,32895,27795,
160827894,28156,30710,30712,30720,30729,30743,30744,30737,26027,30765,30748,30749,
160930777,30778,30779,30751,30780,30757,30764,30755,30761,30798,30829,30806,30807,
161030758,30800,30791,30796,30826,30875,30867,30874,30855,30876,30881,30883,30898,
161130905,30885,30932,30937,30921,30956,30962,30981,30964,30995,31012,31006,31028,
161240859,40697,40699,40700,30449,30468,30477,30457,30471,30472,30490,30498,30489,
161330509,30502,30517,30520,30544,30545,30535,30531,30554,30568,38927,38928,38929,
161438930,38931,38932,38933,38934,38935,38936,38937,38938,38939,38940,38941,38942,
161538943,38944,38945,38946,38947,38948,38949,38950,38951,
161638952,38953,38954,38955,38956,38957,38958,38959,38960,38961,38962,38963,38964,
161738965,38966,38967,38968,38969,38970,38971,38972,38973,38974,38975,38976,38977,
161838978,38979,38980,38981,38982,38983,38984,38985,38986,38987,38988,38989,38990,
161938991,38992,38993,38994,38995,38996,38997,38998,38999,39000,39001,39002,39003,
162039004,39005,39006,39007,39008,39009,39010,39011,39012,39013,39014,39015,39016,
162139017,39018,39019,39020,39021,39022,30562,30565,30591,30605,30589,30592,30604,
162230609,30623,30624,30640,30645,30653,30010,30016,30030,30027,30024,30043,30066,
162330073,30083,32600,32609,32607,35400,32616,32628,32625,32633,32641,32638,30413,
162430437,34866,38021,38022,38023,38027,38026,38028,38029,38031,38032,38036,38039,
162538037,38042,38043,38044,38051,38052,38059,38058,38061,38060,38063,38064,38066,
162638068,38070,38071,38072,38073,38074,38076,38077,38079,38084,38088,38089,38090,
162738091,38092,38093,38094,38096,38097,38098,38101,38102,38103,38105,38104,38107,
162838110,38111,38112,38114,38116,38117,38119,38120,38122,39023,39024,39025,39026,
162939027,39028,39051,39054,39058,39061,39065,39075,39080,39081,39082,39083,39084,
163039085,39086,39087,39088,39089,39090,39091,39092,39093,39094,39095,39096,39097,
163139098,39099,39100,39101,39102,39103,39104,39105,39106,39107,39108,39109,39110,
163239111,39112,39113,39114,39115,39116,39117,39119,39120,39124,39126,39127,39131,
163339132,39133,39136,39137,39138,39139,39140,39141,39142,39145,39146,39147,39148,
163439149,39150,39151,39152,39153,39154,39155,39156,39157,39158,39159,39160,39161,
163539162,39163,39164,39165,39166,39167,39168,39169,39170,
163639171,39172,39173,39174,39175,38121,38123,38126,38127,38131,38132,38133,38135,
163738137,38140,38141,38143,38147,38146,38150,38151,38153,38154,38157,38158,38159,
163838162,38163,38164,38165,38166,38168,38171,38173,38174,38175,38178,38186,38187,
163938185,38188,38193,38194,38196,38198,38199,38200,38204,38206,38207,38210,38197,
164038212,38213,38214,38217,38220,38222,38223,38226,38227,38228,38230,38231,38232,
164138233,38235,38238,38239,38237,38241,38242,38244,38245,38246,38247,38248,38249,
164238250,38251,38252,38255,38257,38258,38259,38202,30695,30700,38601,31189,31213,
164331203,31211,31238,23879,31235,31234,31262,31252,39176,39177,39178,39179,39180,
164439182,39183,39185,39186,39187,39188,39189,39190,39191,39192,39193,39194,39195,
164539196,39197,39198,39199,39200,39201,39202,39203,39204,39205,39206,39207,39208,
164639209,39210,39211,39212,39213,39215,39216,39217,39218,39219,39220,39221,39222,
164739223,39224,39225,39226,39227,39228,39229,39230,39231,39232,39233,39234,39235,
164839236,39237,39238,39239,39240,39241,39242,39243,39244,39245,39246,39247,39248,
164939249,39250,39251,39254,39255,39256,39257,39258,39259,39260,39261,39262,39263,
165039264,39265,39266,39268,39270,39283,39288,39289,39291,39294,39298,39299,39305,
165131289,31287,31313,40655,39333,31344,30344,30350,30355,30361,30372,29918,29920,
165229996,40480,40482,40488,40489,40490,40491,40492,40498,40497,40502,40504,40503,
165340505,40506,40510,40513,40514,40516,40518,40519,40520,40521,40523,40524,40526,
165440529,40533,40535,40538,40539,40540,40542,40547,40550,40551,40552,40553,40554,
165540555,40556,40561,40557,40563,30098,30100,30102,30112,
165630109,30124,30115,30131,30132,30136,30148,30129,30128,30147,30146,30166,30157,
165730179,30184,30182,30180,30187,30183,30211,30193,30204,30207,30224,30208,30213,
165830220,30231,30218,30245,30232,30229,30233,39308,39310,39322,39323,39324,39325,
165939326,39327,39328,39329,39330,39331,39332,39334,39335,39337,39338,39339,39340,
166039341,39342,39343,39344,39345,39346,39347,39348,39349,39350,39351,39352,39353,
166139354,39355,39356,39357,39358,39359,39360,39361,39362,39363,39364,39365,39366,
166239367,39368,39369,39370,39371,39372,39373,39374,39375,39376,39377,39378,39379,
166339380,39381,39382,39383,39384,39385,39386,39387,39388,39389,39390,39391,39392,
166439393,39394,39395,39396,39397,39398,39399,39400,39401,39402,39403,39404,39405,
166539406,39407,39408,39409,39410,39411,39412,39413,39414,39415,39416,39417,30235,
166630268,30242,30240,30272,30253,30256,30271,30261,30275,30270,30259,30285,30302,
166730292,30300,30294,30315,30319,32714,31462,31352,31353,31360,31366,31368,31381,
166831398,31392,31404,31400,31405,31411,34916,34921,34930,34941,34943,34946,34978,
166935014,34999,35004,35017,35042,35022,35043,35045,35057,35098,35068,35048,35070,
167035056,35105,35097,35091,35099,35082,35124,35115,35126,35137,35174,35195,30091,
167132997,30386,30388,30684,32786,32788,32790,32796,32800,32802,32805,32806,32807,
167232809,32808,32817,32779,32821,32835,32838,32845,32850,32873,32881,35203,39032,
167339040,39043,39418,39419,39420,39421,39422,39423,39424,39425,39426,39427,39428,
167439429,39430,39431,39432,39433,39434,39435,39436,39437,39438,39439,39440,39441,
167539442,39443,39444,39445,39446,39447,39448,39449,39450,
167639451,39452,39453,39454,39455,39456,39457,39458,39459,39460,39461,39462,39463,
167739464,39465,39466,39467,39468,39469,39470,39471,39472,39473,39474,39475,39476,
167839477,39478,39479,39480,39481,39482,39483,39484,39485,39486,39487,39488,39489,
167939490,39491,39492,39493,39494,39495,39496,39497,39498,39499,39500,39501,39502,
168039503,39504,39505,39506,39507,39508,39509,39510,39511,39512,39513,39049,39052,
168139053,39055,39060,39066,39067,39070,39071,39073,39074,39077,39078,34381,34388,
168234412,34414,34431,34426,34428,34427,34472,34445,34443,34476,34461,34471,34467,
168334474,34451,34473,34486,34500,34485,34510,34480,34490,34481,34479,34505,34511,
168434484,34537,34545,34546,34541,34547,34512,34579,34526,34548,34527,34520,34513,
168534563,34567,34552,34568,34570,34573,34569,34595,34619,34590,34597,34606,34586,
168634622,34632,34612,34609,34601,34615,34623,34690,34594,34685,34686,34683,34656,
168734672,34636,34670,34699,34643,34659,34684,34660,34649,34661,34707,34735,34728,
168834770,39514,39515,39516,39517,39518,39519,39520,39521,39522,39523,39524,39525,
168939526,39527,39528,39529,39530,39531,39538,39555,39561,39565,39566,39572,39573,
169039577,39590,39593,39594,39595,39596,39597,39598,39599,39602,39603,39604,39605,
169139609,39611,39613,39614,39615,39619,39620,39622,39623,39624,39625,39626,39629,
169239630,39631,39632,39634,39636,39637,39638,39639,39641,39642,39643,39644,39645,
169339646,39648,39650,39651,39652,39653,39655,39656,39657,39658,39660,39662,39664,
169439665,39666,39667,39668,39669,39670,39671,39672,39674,39676,39677,39678,39679,
169539680,39681,39682,39684,39685,39686,34758,34696,34693,
169634733,34711,34691,34731,34789,34732,34741,34739,34763,34771,34749,34769,34752,
169734762,34779,34794,34784,34798,34838,34835,34814,34826,34843,34849,34873,34876,
169832566,32578,32580,32581,33296,31482,31485,31496,31491,31492,31509,31498,31531,
169931503,31559,31544,31530,31513,31534,31537,31520,31525,31524,31539,31550,31518,
170031576,31578,31557,31605,31564,31581,31584,31598,31611,31586,31602,31601,31632,
170131654,31655,31672,31660,31645,31656,31621,31658,31644,31650,31659,31668,31697,
170231681,31692,31709,31706,31717,31718,31722,31756,31742,31740,31759,31766,31755,
170339687,39689,39690,39691,39692,39693,39694,39696,39697,39698,39700,39701,39702,
170439703,39704,39705,39706,39707,39708,39709,39710,39712,39713,39714,39716,39717,
170539718,39719,39720,39721,39722,39723,39724,39725,39726,39728,39729,39731,39732,
170639733,39734,39735,39736,39737,39738,39741,39742,39743,39744,39750,39754,39755,
170739756,39758,39760,39762,39763,39765,39766,39767,39768,39769,39770,39771,39772,
170839773,39774,39775,39776,39777,39778,39779,39780,39781,39782,39783,39784,39785,
170939786,39787,39788,39789,39790,39791,39792,39793,39794,39795,39796,39797,39798,
171039799,39800,39801,39802,39803,31775,31786,31782,31800,31809,31808,33278,33281,
171133282,33284,33260,34884,33313,33314,33315,33325,33327,33320,33323,33336,33339,
171233331,33332,33342,33348,33353,33355,33359,33370,33375,33384,34942,34949,34952,
171335032,35039,35166,32669,32671,32679,32687,32688,32690,31868,25929,31889,31901,
171431900,31902,31906,31922,31932,31933,31937,31943,31948,31949,31944,31941,31959,
171531976,33390,26280,32703,32718,32725,32741,32737,32742,
171632745,32750,32755,31992,32119,32166,32174,32327,32411,40632,40628,36211,36228,
171736244,36241,36273,36199,36205,35911,35913,37194,37200,37198,37199,37220,39804,
171839805,39806,39807,39808,39809,39810,39811,39812,39813,39814,39815,39816,39817,
171939818,39819,39820,39821,39822,39823,39824,39825,39826,39827,39828,39829,39830,
172039831,39832,39833,39834,39835,39836,39837,39838,39839,39840,39841,39842,39843,
172139844,39845,39846,39847,39848,39849,39850,39851,39852,39853,39854,39855,39856,
172239857,39858,39859,39860,39861,39862,39863,39864,39865,39866,39867,39868,39869,
172339870,39871,39872,39873,39874,39875,39876,39877,39878,39879,39880,39881,39882,
172439883,39884,39885,39886,39887,39888,39889,39890,39891,39892,39893,39894,39895,
172539896,39897,39898,39899,37218,37217,37232,37225,37231,37245,37246,37234,37236,
172637241,37260,37253,37264,37261,37265,37282,37283,37290,37293,37294,37295,37301,
172737300,37306,35925,40574,36280,36331,36357,36441,36457,36277,36287,36284,36282,
172836292,36310,36311,36314,36318,36302,36303,36315,36294,36332,36343,36344,36323,
172936345,36347,36324,36361,36349,36372,36381,36383,36396,36398,36387,36399,36410,
173036416,36409,36405,36413,36401,36425,36417,36418,36433,36434,36426,36464,36470,
173136476,36463,36468,36485,36495,36500,36496,36508,36510,35960,35970,35978,35973,
173235992,35988,26011,35286,35294,35290,35292,39900,39901,39902,39903,39904,39905,
173339906,39907,39908,39909,39910,39911,39912,39913,39914,39915,39916,39917,39918,
173439919,39920,39921,39922,39923,39924,39925,39926,39927,39928,39929,39930,39931,
173539932,39933,39934,39935,39936,39937,39938,39939,39940,
173639941,39942,39943,39944,39945,39946,39947,39948,39949,39950,39951,39952,39953,
173739954,39955,39956,39957,39958,39959,39960,39961,39962,39963,39964,39965,39966,
173839967,39968,39969,39970,39971,39972,39973,39974,39975,39976,39977,39978,39979,
173939980,39981,39982,39983,39984,39985,39986,39987,39988,39989,39990,39991,39992,
174039993,39994,39995,35301,35307,35311,35390,35622,38739,38633,38643,38639,38662,
174138657,38664,38671,38670,38698,38701,38704,38718,40832,40835,40837,40838,40839,
174240840,40841,40842,40844,40702,40715,40717,38585,38588,38589,38606,38610,30655,
174338624,37518,37550,37576,37694,37738,37834,37775,37950,37995,40063,40066,40069,
174440070,40071,40072,31267,40075,40078,40080,40081,40082,40084,40085,40090,40091,
174540094,40095,40096,40097,40098,40099,40101,40102,40103,40104,40105,40107,40109,
174640110,40112,40113,40114,40115,40116,40117,40118,40119,40122,40123,40124,40125,
174740132,40133,40134,40135,40138,40139,39996,39997,39998,39999,40000,40001,40002,
174840003,40004,40005,40006,40007,40008,40009,40010,40011,40012,40013,40014,40015,
174940016,40017,40018,40019,40020,40021,40022,40023,40024,40025,40026,40027,40028,
175040029,40030,40031,40032,40033,40034,40035,40036,40037,40038,40039,40040,40041,
175140042,40043,40044,40045,40046,40047,40048,40049,40050,40051,40052,40053,40054,
175240055,40056,40057,40058,40059,40061,40062,40064,40067,40068,40073,40074,40076,
175340079,40083,40086,40087,40088,40089,40093,40106,40108,40111,40121,40126,40127,
175440128,40129,40130,40136,40137,40145,40146,40154,40155,40160,40161,40140,40141,
175540142,40143,40144,40147,40148,40149,40151,40152,40153,
175640156,40157,40159,40162,38780,38789,38801,38802,38804,38831,38827,38819,38834,
175738836,39601,39600,39607,40536,39606,39610,39612,39617,39616,39621,39618,39627,
175839628,39633,39749,39747,39751,39753,39752,39757,39761,39144,39181,39214,39253,
175939252,39647,39649,39654,39663,39659,39675,39661,39673,39688,39695,39699,39711,
176039715,40637,40638,32315,40578,40583,40584,40587,40594,37846,40605,40607,40667,
176140668,40669,40672,40671,40674,40681,40679,40677,40682,40687,40738,40748,40751,
176240761,40759,40765,40766,40772,40163,40164,40165,40166,40167,40168,40169,40170,
176340171,40172,40173,40174,40175,40176,40177,40178,40179,40180,40181,40182,40183,
176440184,40185,40186,40187,40188,40189,40190,40191,40192,40193,40194,40195,40196,
176540197,40198,40199,40200,40201,40202,40203,40204,40205,40206,40207,40208,40209,
176640210,40211,40212,40213,40214,40215,40216,40217,40218,40219,40220,40221,40222,
176740223,40224,40225,40226,40227,40228,40229,40230,40231,40232,40233,40234,40235,
176840236,40237,40238,40239,40240,40241,40242,40243,40244,40245,40246,40247,40248,
176940249,40250,40251,40252,40253,40254,40255,40256,40257,40258,57908,57909,57910,
177057911,57912,57913,57914,57915,57916,57917,57918,57919,57920,57921,57922,57923,
177157924,57925,57926,57927,57928,57929,57930,57931,57932,57933,57934,57935,57936,
177257937,57938,57939,57940,57941,57942,57943,57944,57945,57946,57947,57948,57949,
177357950,57951,57952,57953,57954,57955,57956,57957,57958,57959,57960,57961,57962,
177457963,57964,57965,57966,57967,57968,57969,57970,57971,57972,57973,57974,57975,
177557976,57977,57978,57979,57980,57981,57982,57983,57984,
177657985,57986,57987,57988,57989,57990,57991,57992,57993,57994,57995,57996,57997,
177757998,57999,58000,58001,40259,40260,40261,40262,40263,40264,40265,40266,40267,
177840268,40269,40270,40271,40272,40273,40274,40275,40276,40277,40278,40279,40280,
177940281,40282,40283,40284,40285,40286,40287,40288,40289,40290,40291,40292,40293,
178040294,40295,40296,40297,40298,40299,40300,40301,40302,40303,40304,40305,40306,
178140307,40308,40309,40310,40311,40312,40313,40314,40315,40316,40317,40318,40319,
178240320,40321,40322,40323,40324,40325,40326,40327,40328,40329,40330,40331,40332,
178340333,40334,40335,40336,40337,40338,40339,40340,40341,40342,40343,40344,40345,
178440346,40347,40348,40349,40350,40351,40352,40353,40354,58002,58003,58004,58005,
178558006,58007,58008,58009,58010,58011,58012,58013,58014,58015,58016,58017,58018,
178658019,58020,58021,58022,58023,58024,58025,58026,58027,58028,58029,58030,58031,
178758032,58033,58034,58035,58036,58037,58038,58039,58040,58041,58042,58043,58044,
178858045,58046,58047,58048,58049,58050,58051,58052,58053,58054,58055,58056,58057,
178958058,58059,58060,58061,58062,58063,58064,58065,58066,58067,58068,58069,58070,
179058071,58072,58073,58074,58075,58076,58077,58078,58079,58080,58081,58082,58083,
179158084,58085,58086,58087,58088,58089,58090,58091,58092,58093,58094,58095,40355,
179240356,40357,40358,40359,40360,40361,40362,40363,40364,40365,40366,40367,40368,
179340369,40370,40371,40372,40373,40374,40375,40376,40377,40378,40379,40380,40381,
179440382,40383,40384,40385,40386,40387,40388,40389,40390,40391,40392,40393,40394,
179540395,40396,40397,40398,40399,40400,40401,40402,40403,
179640404,40405,40406,40407,40408,40409,40410,40411,40412,40413,40414,40415,40416,
179740417,40418,40419,40420,40421,40422,40423,40424,40425,40426,40427,40428,40429,
179840430,40431,40432,40433,40434,40435,40436,40437,40438,40439,40440,40441,40442,
179940443,40444,40445,40446,40447,40448,40449,40450,58096,58097,58098,58099,58100,
180058101,58102,58103,58104,58105,58106,58107,58108,58109,58110,58111,58112,58113,
180158114,58115,58116,58117,58118,58119,58120,58121,58122,58123,58124,58125,58126,
180258127,58128,58129,58130,58131,58132,58133,58134,58135,58136,58137,58138,58139,
180358140,58141,58142,58143,58144,58145,58146,58147,58148,58149,58150,58151,58152,
180458153,58154,58155,58156,58157,58158,58159,58160,58161,58162,58163,58164,58165,
180558166,58167,58168,58169,58170,58171,58172,58173,58174,58175,58176,58177,58178,
180658179,58180,58181,58182,58183,58184,58185,58186,58187,58188,58189,40451,40452,
180740453,40454,40455,40456,40457,40458,40459,40460,40461,40462,40463,40464,40465,
180840466,40467,40468,40469,40470,40471,40472,40473,40474,40475,40476,40477,40478,
180940484,40487,40494,40496,40500,40507,40508,40512,40525,40528,40530,40531,40532,
181040534,40537,40541,40543,40544,40545,40546,40549,40558,40559,40562,40564,40565,
181140566,40567,40568,40569,40570,40571,40572,40573,40576,40577,40579,40580,40581,
181240582,40585,40586,40588,40589,40590,40591,40592,40593,40596,40597,40598,40599,
181340600,40601,40602,40603,40604,40606,40608,40609,40610,40611,40612,40613,40615,
181440616,40617,40618,58190,58191,58192,58193,58194,58195,58196,58197,58198,58199,
181558200,58201,58202,58203,58204,58205,58206,58207,58208,
181658209,58210,58211,58212,58213,58214,58215,58216,58217,58218,58219,58220,58221,
181758222,58223,58224,58225,58226,58227,58228,58229,58230,58231,58232,58233,58234,
181858235,58236,58237,58238,58239,58240,58241,58242,58243,58244,58245,58246,58247,
181958248,58249,58250,58251,58252,58253,58254,58255,58256,58257,58258,58259,58260,
182058261,58262,58263,58264,58265,58266,58267,58268,58269,58270,58271,58272,58273,
182158274,58275,58276,58277,58278,58279,58280,58281,58282,58283,40619,40620,40621,
182240622,40623,40624,40625,40626,40627,40629,40630,40631,40633,40634,40636,40639,
182340640,40641,40642,40643,40645,40646,40647,40648,40650,40651,40652,40656,40658,
182440659,40661,40662,40663,40665,40666,40670,40673,40675,40676,40678,40680,40683,
182540684,40685,40686,40688,40689,40690,40691,40692,40693,40694,40695,40696,40698,
182640701,40703,40704,40705,40706,40707,40708,40709,40710,40711,40712,40713,40714,
182740716,40719,40721,40722,40724,40725,40726,40728,40730,40731,40732,40733,40734,
182840735,40737,40739,40740,40741,40742,40743,40744,40745,40746,40747,40749,40750,
182940752,40753,58284,58285,58286,58287,58288,58289,58290,58291,58292,58293,58294,
183058295,58296,58297,58298,58299,58300,58301,58302,58303,58304,58305,58306,58307,
183158308,58309,58310,58311,58312,58313,58314,58315,58316,58317,58318,58319,58320,
183258321,58322,58323,58324,58325,58326,58327,58328,58329,58330,58331,58332,58333,
183358334,58335,58336,58337,58338,58339,58340,58341,58342,58343,58344,58345,58346,
183458347,58348,58349,58350,58351,58352,58353,58354,58355,58356,58357,58358,58359,
183558360,58361,58362,58363,58364,58365,58366,58367,58368,
183658369,58370,58371,58372,58373,58374,58375,58376,58377,40754,40755,40756,40757,
183740758,40760,40762,40764,40767,40768,40769,40770,40771,40773,40774,40775,40776,
183840777,40778,40779,40780,40781,40782,40783,40786,40787,40788,40789,40790,40791,
183940792,40793,40794,40795,40796,40797,40798,40799,40800,40801,40802,40803,40804,
184040805,40806,40807,40808,40809,40810,40811,40812,40813,40814,40815,40816,40817,
184140818,40819,40820,40821,40822,40823,40824,40825,40826,40827,40828,40829,40830,
184240833,40834,40845,40846,40847,40848,40849,40850,40851,40852,40853,40854,40855,
184340856,40860,40861,40862,40865,40866,40867,40868,40869,63788,63865,63893,63975,
184463985,58378,58379,58380,58381,58382,58383,58384,58385,58386,58387,58388,58389,
184558390,58391,58392,58393,58394,58395,58396,58397,58398,58399,58400,58401,58402,
184658403,58404,58405,58406,58407,58408,58409,58410,58411,58412,58413,58414,58415,
184758416,58417,58418,58419,58420,58421,58422,58423,58424,58425,58426,58427,58428,
184858429,58430,58431,58432,58433,58434,58435,58436,58437,58438,58439,58440,58441,
184958442,58443,58444,58445,58446,58447,58448,58449,58450,58451,58452,58453,58454,
185058455,58456,58457,58458,58459,58460,58461,58462,58463,58464,58465,58466,58467,
185158468,58469,58470,58471,64012,64013,64014,64015,64017,64019,64020,64024,64031,
185264032,64033,64035,64036,64039,64040,64041,11905,59414,59415,59416,11908,13427,
185313383,11912,11915,59422,13726,13850,13838,11916,11927,14702,14616,59430,14799,
185414815,14963,14800,59435,59436,15182,15470,15584,11943,59441,59442,11946,16470,
185516735,11950,17207,11955,11958,11959,59451,17329,17324,
185611963,17373,17622,18017,17996,59459,18211,18217,18300,18317,11978,18759,18810,
185718813,18818,18819,18821,18822,18847,18843,18871,18870,59476,59477,19619,19615,
185819616,19617,19575,19618,19731,19732,19733,19734,19735,19736,19737,19886,59492,
185958472,58473,58474,58475,58476,58477,58478,58479,58480,58481,58482,58483,58484,
186058485,58486,58487,58488,58489,58490,58491,58492,58493,58494,58495,58496,58497,
186158498,58499,58500,58501,58502,58503,58504,58505,58506,58507,58508,58509,58510,
186258511,58512,58513,58514,58515,58516,58517,58518,58519,58520,58521,58522,58523,
186358524,58525,58526,58527,58528,58529,58530,58531,58532,58533,58534,58535,58536,
186458537,58538,58539,58540,58541,58542,58543,58544,58545,58546,58547,58548,58549,
186558550,58551,58552,58553,58554,58555,58556,58557,58558,58559,58560,58561,58562,
186658563,58564,58565,
libc/musl/src/locale/hkscs.h created+390
......@@ -0,0 +1,390 @@
117392,19506,17923,17830,17784,29287,19831,17843,31921,19682,31941,15253,18230,
218244,19527,19520,17087,13847,29522,28299,28882,19543,41809,18255,17882,19589,
331852,19719,19108,18081,27427,29221,23124,6755,15878,16225,26189,22267,0,
432149,22813,35769,15860,38708,31727,23515,7518,23204,13861,40624,23249,23479,
523804,26478,34195,39237,29793,29853,14453,7507,13982,24609,16108,22750,15093,
631484,40855,16737,35085,12778,2698,12894,17162,33924,40854,37935,18736,34323,
722678,38730,37400,31184,31282,26208,27177,34973,29772,31685,26498,31276,21071,
836934,13542,29636,23993,29894,40903,22451,18735,21580,16689,13966,22552,31346,
931589,35727,18094,28296,16769,23961,31662,9404,40904,9409,9417,9420,40905,
1034052,13755,16564,40906,17633,44543,25281,28782,40907,0,0,0,0,0,0,0,0,0,0,0,0,
110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12736,12737,12738,12739,12740,268,12741,
12209,205,12742,12743,203,8168,12744,202,12745,12746,12747,12748,270,12749,
1312750,256,193,461,192,274,201,282,200,332,211,465,210,56320,7870,56324,7872,
14202,257,225,462,224,593,275,233,283,232,299,237,464,236,333,243,466,242,363,
15250,468,249,470,472,474,476,252,56328,7871,56332,7873,234,609,9178,9179,0,0,0,
160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
170,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
180,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41897,4421,0,25866,0,0,20029,28381,
1940270,37343,0,0,30517,25745,20250,20264,20392,20822,20852,20892,20964,21153,
2021160,21307,21326,21457,21464,22242,22768,22788,22791,22834,22836,23398,23454,
2123455,23706,24198,24635,25993,26622,26628,26725,27982,28860,30005,32420,32428,
2232442,32455,32463,32479,32518,32567,33402,33487,33647,35270,35774,35810,36710,
2336711,36718,29713,31996,32205,26950,31433,21031,0,0,0,0,37260,30904,37214,
2432956,0,36107,33014,2535,0,0,32927,40647,19661,40393,40460,19518,40438,28686,
2540458,41267,13761,0,28314,33342,29977,0,18705,39532,39567,40857,31111,33900,
267626,1488,10982,20004,20097,20096,20103,20159,20203,20279,13388,20413,15944,
2720483,20616,13437,13459,13477,20870,22789,20955,20988,20997,20105,21113,21136,
2821287,13767,21417,13649,21424,13651,21442,21539,13677,13682,13953,21651,21667,
2921684,21689,21712,21743,21784,21795,21800,13720,21823,13733,13759,21975,13765,
3032132,21797,0,3138,3349,20779,21904,11462,14828,833,36422,19896,38117,16467,
3132958,30586,11320,14900,18389,33117,27122,19946,25821,3452,4020,3285,4340,
3225741,36478,3734,3083,3940,11433,33366,17619,0,3398,39501,33001,18420,
3320135,11458,39602,14951,38388,16365,13574,21191,38868,30920,11588,40302,38933,
340,17369,24741,25780,21731,11596,11210,4215,14843,4207,26330,26390,31136,25834,
3520562,3139,36456,8609,35660,1841,0,18443,425,16378,22643,11661,0,17864,1276,
3624727,3916,3478,21881,16571,17338,0,19124,10854,4253,33194,39157,3484,25465,
3714846,10101,36288,22177,25724,15939,0,42497,3593,10959,11465,0,4296,14786,
3814738,14854,33435,13688,24137,8391,22098,3889,11442,38688,13500,27709,20027,0,
390,30068,11915,8712,42587,36045,3706,3124,26652,32659,4303,10243,10553,13819,
4020963,3724,3981,3754,16275,3888,3399,4431,3660,0,3755,2985,3400,4288,4413,
4116377,9878,25650,4013,13300,30265,11214,3454,3455,11345,11349,14872,3736,4295,
423886,42546,27472,36050,36249,36042,38314,21708,33476,21945,0,40643,39974,
4339606,30558,11758,28992,33133,33004,23580,25970,33076,14231,21343,32957,37302,
443834,3599,3703,3835,13789,19947,13833,3286,22191,10165,4297,3600,3704,4216,
454424,33287,5205,3705,20048,11684,23124,4125,4126,4341,4342,22428,3601,30356,
4633485,4021,3707,20862,14083,4022,4480,21208,41661,18906,6202,16759,33404,
4722681,21096,13850,22333,31666,23400,18432,19244,40743,18919,39967,39821,23412,
4812605,22011,13810,22153,20008,22786,7105,63608,38737,134,20059,20155,13630,
4923587,24401,24516,14586,25164,25909,27514,27701,27706,28780,29227,20012,29357,
5018665,32594,31035,31993,32595,25194,13505,0,25419,32770,32896,26130,26961,
5121341,34916,35265,30898,35744,36125,38021,38264,38271,38376,
5236367,38886,39029,39118,39134,39267,38928,40060,40479,40644,27503,63751,20023,
53135,38429,25143,38050,0,20539,28158,40051,40870,15817,34959,16718,28791,23797,
5419232,20941,13657,23856,24866,35378,36775,37366,29073,26393,29626,12929,41223,
5515499,6528,19216,30948,29698,20910,34575,16393,27235,41658,16931,34319,2671,
5631274,39239,35562,38741,28749,21284,8318,37876,30425,35299,40871,30685,20131,
5720464,20668,20015,20247,40872,21556,32139,22674,22736,7606,24210,24217,24514,
5810002,25995,13305,26905,27203,15459,27903,0,29184,17669,29580,16091,18963,
5923317,29881,35715,23716,22165,31379,31724,31939,32364,33528,34199,40873,34960,
6040874,36537,40875,36815,34143,39392,37409,40876,36281,5183,16497,17058,23066,
610,0,0,39016,26475,17014,22333,0,34262,18811,33471,28941,19585,28020,23931,
6227413,28606,40877,40878,23446,40879,26343,32347,28247,31178,15752,17603,12886,
6310134,17306,17718,0,23765,15130,35577,23672,15634,13649,23928,40882,29015,
6417752,16620,7715,19575,14712,13386,420,27713,35532,20404,569,22975,33132,
6538998,39162,24379,2975,0,8641,35181,16642,18107,36985,16135,40883,41397,16632,
6614294,18167,27718,16764,34482,29695,17773,14548,21658,17761,17691,19849,19579,
6719830,17898,16328,19215,13921,17630,17597,16877,23870,23880,23894,15868,14351,
6823972,23993,14368,14392,24130,24253,24357,24451,14600,14612,14655,14669,24791,
6924893,23781,14729,25015,25017,25039,14776,25132,25232,25317,25368,14840,22193,
7014851,25570,25595,25607,25690,14923,25792,23829,22049,40863,14999,25990,15037,
7126111,26195,15090,26258,15138,
7226390,15170,26532,26624,15192,26698,26756,15218,15217,15227,26889,26947,29276,
7326980,27039,27013,15292,27094,15325,27237,27252,27249,27266,15340,27289,15346,
7427307,27317,27348,27382,27521,27585,27626,27765,27818,15563,27906,27910,27942,
7528033,15599,28068,28081,28181,28184,28201,28294,35264,28347,28386,28378,40831,
7628392,28393,28452,28468,15686,16193,28545,28606,15722,15733,29111,23705,15754,
7728716,15761,28752,28756,28783,28799,28809,805,17345,13809,3800,16087,22462,
7828371,28990,22496,13902,27042,35817,23412,31305,22753,38105,31333,31357,22956,
7931419,31408,31426,31427,29137,25741,16842,31450,31453,31466,16879,21682,23553,
8031499,31573,31529,21262,23806,31650,31599,33692,23476,27775,31696,33825,31634,
810,23840,15789,23653,33938,31738,0,31797,23745,31812,31875,18562,31910,26237,
8217784,31945,31943,31974,31860,31987,31989,0,32359,17693,28228,32093,28374,
8329837,32137,32171,28981,32179,0,16471,24617,32228,15635,32245,6137,32229,
8433645,0,24865,24922,32366,32402,17195,37996,32295,32576,32577,32583,31030,
8525296,39393,32663,25425,32675,5729,104,17756,14182,17667,33594,32762,25737,0,
8632776,32797,0,32815,41095,27843,32827,32828,32865,10004,18825,26150,15843,
8726344,26405,32935,35400,33031,33050,22704,9974,27775,25752,20408,25831,5258,
8833304,6238,27219,19045,19093,17530,33321,2829,27218,15742,20473,5373,34018,
8933634,27402,18855,13616,6003,15864,33450,26907,63892,16859,34123,33488,33562,
903606,6068,14017,12669,13658,33403,33506,33560,16011,28067,27397,27543,13774,
9115807,33565,21996,33669,17675,28069,33708,
920,33747,13438,28372,27223,34138,13462,28226,12015,33880,23524,33905,15827,
9317636,27303,33866,15541,31064,0,27542,28279,28227,34014,0,33681,17568,33939,
9434020,23697,16960,23744,17731,34100,23282,28313,17703,34163,17686,26559,34326,
9534341,34363,34241,28808,34306,5506,28877,63922,17770,34344,13896,6306,21495,
9629594,34430,34673,41208,34798,11303,34737,34778,34831,22113,34412,26710,17935,
9734885,34886,30176,15801,30180,34910,34972,18011,34996,34997,25537,35013,30583,
9830479,35207,35210,0,0,35239,35260,35365,35303,31012,31421,35484,30611,37374,
9935472,31321,31465,31546,16271,18195,31544,29052,35596,35615,21552,21861,35647,
10035660,35661,35497,19066,35728,35739,35503,5855,17941,34895,35995,32084,32143,
10163956,14117,32083,36054,32152,32189,36114,36099,6416,36059,28764,36113,19657,
10216080,0,36265,32770,4116,18826,15228,33212,28940,31463,36525,36534,36547,
10337588,36633,36653,33637,33810,36773,37635,41631,2640,36787,18730,35294,34109,
10415803,24312,12898,36857,40980,34492,34049,8997,14720,28375,36919,34108,31422,
10536961,34156,34315,37032,34579,37060,34534,37038,0,37223,15088,37289,37316,
10631916,35123,7817,37390,27807,37441,37474,21945,0,35526,15515,35596,21979,3377,
10737676,37739,35553,35819,28815,23235,35554,35557,18789,37444,35820,35897,35839,
10837747,37979,36540,38277,38310,37926,38304,28662,17081,9850,34520,4732,15918,
10918911,27676,38523,38550,16748,38563,28373,25050,38582,30965,35552,38589,21452,
11018849,27832,628,25616,37039,37093,19153,6421,13066,38705,34370,38710,18959,
11117725,17797,19177,28789,23361,38683,
1120,37333,38743,23370,37355,38751,37925,20688,12471,12476,38793,38815,38833,
11338846,38848,38866,38880,21612,38894,29724,37939,0,38901,37917,31098,19153,
11438964,38963,38987,39014,15118,29045,15697,1584,16732,22278,39114,39095,39112,
11539111,19199,27943,5843,21936,39137,39142,39148,37752,39225,18985,19314,38999,
11639173,39413,39436,39483,39440,39512,22309,14020,37041,39893,39648,39650,39685,
11739668,19470,39700,39725,34304,20532,39732,27048,14531,12413,39760,39744,40254,
11823109,6243,39822,16971,39938,39935,39948,40552,40404,40887,41362,41387,41185,
11941251,41439,40318,40323,41268,40462,26760,40388,8539,41363,41504,6459,41523,
12040249,41145,41652,40592,40597,40606,40610,19764,40618,40623,17252,40641,15200,
12114821,15645,20274,14270,35883,40706,40712,19350,37924,28066,40727,0,40761,
12222175,22154,40773,39352,37003,38898,33919,40802,40809,31452,40846,29206,19390,
12318805,18875,29047,18936,17224,19025,29598,35802,6394,31135,35198,36406,37737,
12437875,35396,37612,37761,37835,35180,17593,29207,16107,30578,31299,28880,17523,
12517400,29054,6127,28835,6334,13721,16071,6277,21551,6136,14114,5883,6201,14049,
1266004,6353,24395,14115,5824,22363,18981,5118,4776,5062,5302,34051,13990,0,
12733877,18836,29029,15921,21852,16123,28754,17652,14062,39325,28454,26617,14131,
12815381,15847,22636,6434,26640,16471,14143,16609,16523,16655,27681,21707,22174,
12926289,22162,4063,2984,3597,37830,35603,37788,20216,20779,14361,17462,20156,
1301125,895,20299,20362,22097,23144,427,971,14745,778,1044,13365,20265,704,36531,
131629,35546,524,20120,20685,
13220749,20386,20227,18958,16010,20290,20526,20588,20609,20428,20453,20568,20732,
1330,0,0,0,28278,13717,15929,16063,28018,6276,16009,20904,20931,1504,17629,1187,
1341170,1169,36218,35484,1806,21081,21156,2163,21217,0,18042,29068,17292,3104,
13518860,4324,27089,3613,0,16094,29849,29716,29782,29592,19342,19132,16525,21456,
13613700,29199,16585,21940,837,21709,3014,22301,37469,38644,37734,22493,22413,
13722399,13886,22731,23193,35398,5882,5999,5904,23084,22968,37519,23166,23247,
13823058,22854,6643,6241,17045,14069,27909,29763,23073,24195,23169,35799,1043,
13937856,29836,4867,28933,18802,37896,35323,37821,14240,23582,23710,24158,24136,
1406550,6524,15086,24269,23375,6403,6404,14081,6304,14045,5886,14035,33066,35399,
1417610,13426,35240,24332,24334,6439,6059,23147,5947,23364,34324,30205,34912,
14224702,10336,9771,24539,16056,9647,9662,37000,28531,25024,62,70,9755,24985,
14324984,24693,11419,11527,18132,37197,25713,18021,11114,14889,11042,13392,39146,
14411896,25399,42075,25782,25393,25553,18915,11623,25252,11425,25659,25963,26994,
14515348,12430,12973,18825,12971,21773,13024,6361,37951,26318,12937,12723,15072,
14616784,21892,35618,21903,5884,21851,21541,30958,12547,6186,12852,13412,12815,
14712674,17097,26254,27940,26219,19347,26160,30832,7659,26211,13010,13025,26142,
14822642,14545,14394,14268,15257,14242,13310,29904,15254,26511,17962,26806,26654,
14915300,27326,14435,14293,17543,27187,27218,27337,27397,6418,25873,26776,27212,
15015319,27258,27479,16320,15514,37792,37618,35818,35531,37513,32798,35292,37991,
15128069,28427,
15218924,0,16255,15759,28164,16444,23101,28170,22599,27940,30786,28987,17178,
15317014,28913,29264,29319,29332,18319,18213,20857,19108,1515,29818,16120,13919,
15419018,18711,24545,16134,16049,19167,35875,16181,24743,16115,29900,29756,37767,
15529751,17567,28138,17745,30083,16227,19673,19718,16216,30037,30323,42438,15129,
15629800,35532,18859,18830,15099,15821,19022,16127,18885,18675,37370,22322,37698,
15735555,6244,20703,21025,20967,30584,12850,30478,30479,30587,18071,14209,14942,
15818672,29752,29851,16063,19130,19143,16584,19094,25006,37639,21889,30750,30861,
15930856,30930,29648,31065,30529,22243,16654,0,33942,31141,27181,16122,31290,
16031220,16750,5862,16690,37429,31217,3404,18828,665,15802,5998,13719,21867,
16113680,13994,468,3085,31458,23129,9973,23215,23196,23053,603,30960,23082,23494,
16231486,16889,31837,31853,16913,23475,24252,24230,31949,18937,6064,31886,31868,
16331918,27314,32220,32263,32211,32590,25185,24924,31560,32151,24194,17002,27509,
1642326,26582,78,13775,22468,25618,25592,18786,32733,31527,2092,23273,23875,
16531500,24078,39398,34373,39523,27164,13375,14818,18935,26029,39455,26016,33920,
16628967,27857,17642,33079,17410,32966,33033,33090,26548,39107,27202,33378,33381,
16727217,33875,28071,34320,29211,23174,16767,6208,23339,6305,23268,6360,34464,
16863932,15759,34861,29730,23042,34926,20293,34951,35007,35046,35173,35149,22147,
16935156,30597,30596,35829,35801,35740,35321,16045,33955,18165,18127,14322,35389,
17035356,37960,24397,37419,17028,26068,28969,28868,6213,40301,35999,36073,32220,
17122938,30659,23024,17262,14036,36394,36519,19465,
17236656,36682,17140,27736,28603,8993,18587,28537,28299,6106,39913,14005,18735,
17337051,0,21873,18694,37307,37892,35403,16482,35580,37927,35869,35899,34021,
17435371,38297,38311,38295,38294,36148,29765,16066,18687,19010,17386,16103,12837,
17538543,36583,36454,36453,16076,18925,19064,16366,29714,29803,16124,38721,37040,
17626695,18973,37011,22495,0,37736,35209,35878,35631,25534,37562,23313,35689,
17718748,29689,16923,38811,38769,39224,3878,24001,35781,19122,38943,38106,37622,
17838359,37349,17600,35664,19047,35684,39132,35397,16128,37418,18725,33812,39227,
17939245,31494,15869,39323,19311,39338,39516,35685,22728,27279,39457,23294,39471,
18039153,19344,39240,39356,19389,19351,37757,22642,4866,22562,18872,5352,30788,
18110015,15800,26821,15741,37976,14631,24912,10113,10603,24839,40015,40019,40059,
18239989,39952,39807,39887,40493,39839,41461,41214,40225,19630,16644,40472,19632,
18340204,41396,41197,41203,39215,40357,33981,28178,28639,27522,34300,17715,28068,
18428292,28144,33824,34286,28160,14295,24676,31202,13724,13888,18733,18910,15714,
18537851,37566,37704,703,30905,37495,37965,20452,13376,36964,21853,30781,30804,
18630902,30795,5975,12745,18753,13978,20338,28634,28633,0,28702,21524,16821,
18722459,22771,22410,40214,22487,28980,13487,16812,29163,27712,20375,0,6069,
18835401,24844,23246,23051,17084,17544,14124,19323,35324,37819,37816,6358,3869,
18933906,27840,5139,17146,11302,17345,22932,15799,26433,32168,24923,24740,18873,
19018827,35322,37605,29666,16105,29876,35683,6303,16097,19123,27352,29683,29691,
19116086,19006,19092,6105,19046,935,5156,18917,29768,
19218710,28837,18806,37508,29670,37727,1278,37681,35534,35350,37766,35815,21973,
19318741,35458,29035,18755,3327,22180,1562,3051,3256,21762,31172,6138,32254,5826,
19419024,6226,17710,37889,14090,35520,18861,22960,6335,6275,29828,23201,14050,
19515707,14000,37471,23161,35457,6242,37748,15565,2740,19094,14730,20724,15721,
19615692,5020,29045,17147,33304,28175,37092,17643,27991,32335,28775,27823,15574,
19716365,15917,28162,28428,15727,1013,30033,14012,13512,18048,16090,18545,22980,
19837486,18750,36673,35868,27584,22546,22472,14038,5202,28926,17250,19057,12259,
1994784,9149,26809,26983,5016,13541,31732,14047,35459,14294,13306,19615,27162,
20013997,27831,33854,17631,17614,27942,27985,27778,28638,28439,28937,33597,5946,
20133773,27776,28755,6107,22921,23170,6067,23137,23153,6405,16892,14125,23023,
2025948,14023,29070,37776,26266,17061,23150,23083,17043,27179,16121,30518,17499,
20317098,28957,16985,35297,20400,27944,23746,17614,32333,17341,27148,16982,4868,
20428838,28979,17385,15781,27871,63525,19023,32357,23019,23855,15859,24412,19037,
2056111,32164,33830,21637,15098,13056,532,22398,2261,1561,16357,8094,41654,28675,
20637211,23920,29583,31955,35417,37920,20424,32743,29389,29456,31476,29496,29497,
20722262,29505,29512,16041,31512,36972,29173,18674,29665,33270,16074,30476,16081,
20827810,22269,29721,29726,29727,16098,16112,16116,16122,29907,16142,16211,30018,
20930061,30066,30093,16252,30152,30172,16320,30285,16343,30324,16348,30330,20316,
21029064,22051,35200,22633,16413,30531,16441,26465,16453,13787,30616,16490,16495,
21123646,30654,30667,22770,30744,28857,30748,
21216552,30777,30791,30801,30822,33864,21813,31027,26627,31026,16643,16649,31121,
21331129,36795,31238,36796,16743,31377,16818,31420,33401,16836,31439,31451,16847,
21420001,31586,31596,31611,31762,31771,16992,17018,31867,31900,17036,31928,17044,
21531981,36755,28864,3279,32207,32212,32208,32253,32686,32692,29343,17303,32800,
21632805,31545,32814,32817,32852,15820,22452,28832,32951,33001,17389,33036,29482,
21733038,33042,30048,33044,17409,15161,33110,33113,33114,17427,22586,33148,33156,
21817445,33171,17453,33189,22511,33217,33252,33364,17551,33446,33398,33482,33496,
21933535,17584,33623,38505,27018,33797,28917,33892,24803,33928,17668,33982,34017,
22034040,34064,34104,34130,17723,34159,34160,34272,17783,34418,34450,34482,34543,
22138469,34699,17926,17943,34990,35071,35108,35143,35217,31079,35369,35384,35476,
22235508,35921,36052,36082,36124,18328,22623,36291,18413,20206,36410,21976,22356,
22336465,22005,36528,18487,36558,36578,36580,36589,36594,36791,36801,36810,36812,
22436915,39364,18605,39136,37395,18718,37416,37464,37483,37553,37550,37567,37603,
22537611,37619,37620,37629,37699,37764,37805,18757,18769,40639,37911,21249,37917,
22637933,37950,18794,37972,38009,38189,38306,18855,38388,38451,18917,26528,18980,
22738720,18997,38834,38850,22100,19172,24808,39097,19225,39153,22596,39182,39193,
22820916,39196,39223,39234,39261,39266,19312,39365,19357,39484,39695,31363,39785,
22939809,39901,39921,39924,19565,39968,14191,7106,40265,39994,40702,22096,40339,
23040381,40384,40444,38134,36790,40571,40620,40625,40637,40646,38108,40674,40689,
23140696,31432,40772,148,695,928,26906,38083,22956,
2321239,22592,38081,14265,1493,1557,1654,5818,22359,29043,2754,2765,3007,21610,
23363547,3019,21662,3067,3131,3155,3173,3196,24807,3213,22138,3253,3293,3309,
2343439,3506,3528,26965,39983,34725,3588,3598,3799,3984,3885,3699,23584,4028,
23524075,4188,4175,4214,26398,4219,4232,4246,13895,4287,4307,4399,4411,21348,
23633965,4835,4981,4918,35713,5495,5657,6083,6087,20088,28859,6189,6506,6701,
2376725,7210,7280,7340,7880,25283,7893,7957,29080,26709,8261,27113,14024,8828,
2389175,9210,10026,10353,10575,33533,10599,10643,10965,35237,10984,36768,11022,
23938840,11071,38983,39613,11340,0,11400,11447,23528,11528,11538,11703,11669,
24011842,12148,12236,12339,12390,13087,13278,24497,26184,26303,31353,13671,13811,
2410,18874,0,13850,14102,0,838,22709,26382,26904,15015,30295,24546,15889,16057,
24230206,8346,18640,19128,16665,35482,17134,17165,16443,17204,17302,19013,1482,
24320946,1553,22943,7848,15294,15615,17412,17622,22408,18036,14747,18223,34280,
24439369,14178,8643,35678,35662,0,18450,18683,18965,29193,19136,3192,22885,20133,
24520358,1913,36570,20524,21135,22335,29041,21145,21529,16202,19111,21948,21574,
24621614,27474,0,13427,21823,30258,21854,18200,21858,21862,22471,18751,22621,
24720582,13563,13260,0,22787,18300,35144,23214,23433,23558,7568,22433,29009,0,
24824834,31762,36950,25010,20378,35682,25602,25674,23899,27639,0,25732,6428,
24935562,18934,25736,16367,25874,19392,26047,26293,10011,37989,22497,24981,23079,
25063693,0,22201,17697,26364,20074,18740,38486,28047,27837,13848,35191,
25126521,26734,25617,26718,0,26823,31554,37056,2577,26918,0,26937,31301,0,27130,
25239462,27181,13919,25705,33,31107,27188,27483,23852,13593,0,27549,18128,27812,
25330011,34917,28078,22710,14108,9613,28747,29133,15444,29312,29317,37505,8570,
25429323,37680,29414,18896,27705,38047,29776,3832,34855,35061,10534,33907,6065,
25528344,18986,6176,14756,14009,0,0,17727,26294,40109,39076,35139,30668,30808,
25622230,16607,5642,14753,14127,33000,5061,29101,33638,31197,37288,0,19639,28847,
25735243,31229,31242,31499,32102,16762,31555,31102,32777,28597,41695,27139,33560,
25821410,28167,37823,26678,38749,33135,32803,27061,5101,12847,32840,23941,35888,
25932899,22293,38947,35145,23979,18824,26046,27093,21458,19109,16257,15377,26422,
26032912,33012,33070,8097,33103,33161,33199,33306,33542,33583,33674,13770,33896,
26134474,18682,25574,35158,30728,37461,35256,17394,35303,17375,35304,35654,35796,
26223032,35849,0,36805,37100,0,37136,37180,15863,37214,19146,36816,29327,22155,
26338119,38377,38320,38328,38706,39121,39241,39274,39363,39464,39694,40282,40347,
26432415,40696,40739,19620,38215,41619,29090,41727,19857,36882,42443,19868,3228,
26536798,21953,36794,9392,36793,19091,17673,32383,28502,27313,20202,13540,35628,
26630877,14138,36480,6133,32804,35692,35737,31294,26287,15851,30293,15543,22069,
26722870,20122,24193,25176,22207,3693,36366,23405,16008,19614,25566,0,6134,6267,
26825904,22061,23626,21530,21265,15814,40344,19581,22050,22046,32585,24280,22901,
26915680,34672,19996,4074,3401,14010,33047,40286,36120,30267,40005,30286,30649,
27037701,21554,
27133096,33527,22053,33074,33816,32957,21994,31074,22083,21526,3741,13774,22021,
27222001,26353,33506,13869,30004,22000,21946,21655,21874,3137,3222,24272,20808,
2733702,11362,3746,40619,32090,21982,4213,25245,38765,21652,36045,29174,37238,
27425596,25529,25598,21865,11075,40050,11955,20890,13535,3495,20903,21581,21790,
27521779,30310,36397,26762,30129,32950,34820,34694,35015,33206,33820,4289,17644,
27629444,18182,23440,33547,26771,22139,9972,32047,16803,32115,28368,29366,37232,
2774569,37384,15612,42665,3756,3833,29286,7330,18254,20418,32761,4075,16634,
27840029,25887,11680,18675,18400,40316,4076,3594,0,30115,4077,0,24648,4487,29091,
27932398,40272,19994,19972,13687,23309,27826,21351,13996,14812,21373,13989,17944,
28022682,19310,33325,21579,22442,23189,2425,0,14930,9317,29556,40620,19721,39917,
28115614,40752,19547,20393,38302,40926,33884,15798,29362,26547,14112,25390,32037,
28216119,15916,14890,36872,21196,15988,13946,17897,1166,30272,23280,3766,30842,
28332558,22695,16575,22140,39819,23924,30292,42036,40581,19681,0,14331,24857,
28412506,17394,0,22109,4777,22439,18787,40454,21044,28846,13741,0,40316,31830,
28539737,22494,5996,23635,25811,38096,25397,29028,34477,3368,27938,19170,3441,0,
28620990,7951,23950,38659,7633,40577,36940,31519,39682,23761,31651,25192,25397,
28739679,31695,39722,31870,0,31810,31878,39957,31740,39689,0,39963,18750,40794,
28821875,23491,20477,40600,20466,21088,15878,21201,22375,20566,22967,24082,38856,
28940363,36700,21609,38836,39232,38842,21292,24880,26924,21466,39946,40194,19515,
29038465,27008,20646,
29130022,5997,39386,21107,0,37209,38529,37212,0,37201,36503,25471,27939,27338,
29222033,37262,30074,25221,1020,29519,31856,23585,15613,0,18713,30422,39837,
29320010,3284,33726,34882,0,23626,27072,0,22394,21023,24053,20174,27697,498,
29420281,21660,21722,21146,36226,13822,0,13811,0,27474,37244,40869,39831,38958,
29539092,39610,40616,40580,29050,31508,0,27642,34840,32632,0,22048,42570,36471,
29640787,0,36308,36431,40476,36353,25218,33661,36392,36469,31443,19063,31294,
29730936,27882,35431,30215,35418,40742,27854,34774,30147,41650,30803,63552,36108,
29829410,29553,35629,29442,29937,36075,19131,34351,24506,34976,17591,0,6203,
29928165,0,35454,9499,0,24829,30311,39639,40260,37742,39823,34805,0,0,36087,
30029484,38689,39856,13782,29362,19463,31825,39242,24921,24921,19460,40598,24957,
3010,22367,24943,25254,25145,0,14940,25058,21418,13301,25444,26626,13778,23895,
30235778,36826,36409,0,20697,7494,30982,21298,38456,3899,16485,0,30718,0,31938,
30324346,31962,31277,32870,32867,32077,29957,29938,35220,33306,26380,32866,29830,
30432859,29936,33027,30500,35209,26572,30035,28369,34729,34766,33224,34700,35401,
30536013,35651,30507,29944,34010,13877,27058,36262,0,35241,0,28089,34753,16401,
30629927,15835,29046,24740,24988,15569,0,24695,0,32625,35629,0,24809,19326,21024,
30715384,15559,24279,30294,21809,6468,4862,39171,28124,28845,23745,25005,35343,
30813943,238,26694,20238,17762,23327,25420,40784,40614,25195,1351,37595,1503,
30916325,34124,17077,29679,20917,13897,18754,35300,37700,6619,
31033518,15560,30780,26436,25311,18739,35242,672,27571,4869,20395,9453,20488,
31127945,31364,13824,19121,9491,0,894,24484,896,839,28379,1055,0,20737,13434,
31220750,39020,14147,33814,18852,1159,20832,13236,20842,3071,8444,741,9520,1422,
31312851,6531,23426,34685,1459,15513,20914,20920,40244,20937,20943,20945,15580,
31420947,19110,20915,20962,21314,20973,33741,26942,14125,24443,21003,21030,21052,
31521173,21079,21140,21177,21189,31765,34114,21216,34317,27411,0,35550,21833,
31628377,16256,2388,16364,21299,0,3042,27851,5926,26651,29653,24650,16042,14540,
3175864,29149,17570,21357,21364,34475,21374,0,5526,5651,30694,21395,35483,21408,
31821419,21422,29607,22386,16217,29596,21441,21445,27721,20041,22526,21465,15019,
3192959,21472,16363,11683,21494,3191,21523,28793,21803,26199,27995,21613,27475,
3203444,21853,21647,21668,18342,5901,3805,15796,3405,35260,9880,21831,19693,
32121551,29719,21894,21929,0,6359,16442,17746,17461,26291,4276,22071,26317,12938,
32226276,26285,22093,22095,30961,22257,38791,21502,22272,22255,22253,35686,13859,
3234687,22342,16805,27758,28811,22338,14001,27774,22502,5142,22531,5204,17251,
32422566,19445,22620,22698,13665,22752,22748,4668,22779,23551,22339,41296,17016,
32537843,13729,22815,26790,14019,28249,5694,23076,21843,5778,34053,22985,3406,
32627777,27946,6108,23001,6139,6066,28070,28017,6184,5845,23033,28229,23211,
32723139,14054,18857,0,14088,23190,29797,23251,28577,9556,15749,6417,14130,5816,
32824195,21200,23414,25992,23420,31246,16388,18525,516,23509,24928,6708,22988,
3291445,23539,
33023453,19728,23557,6980,23571,29646,23572,7333,27432,23625,18653,23685,23785,
33123791,23947,7673,7735,23824,23832,23878,7844,23738,24023,33532,14381,18689,
3328265,8563,33415,14390,15298,24110,27274,0,24186,17596,3283,21414,20151,0,
33321416,6001,24073,24308,33922,24313,24315,14496,24316,26686,37915,24333,449,
33463636,15070,18606,4922,24378,26760,9168,0,9329,24419,38845,28270,24434,37696,
33535382,24487,23990,15711,21072,8042,28920,9832,37334,670,35369,24625,26245,
3366263,14691,15815,13881,22416,10164,31089,15936,24734,0,24755,18818,18831,
33731315,29860,20705,23200,24932,33828,24898,63654,28370,24961,20980,1622,24967,
33823466,16311,10335,25043,35741,39261,25040,14642,10624,10433,24611,24924,25886,
33925483,280,25285,6000,25301,11789,25452,18911,14871,25656,25592,5006,6140,0,
34028554,11830,38932,16524,22301,25825,25829,38011,14950,25658,14935,25933,28438,
34118984,18979,25989,25965,25951,12414,26037,18752,19255,26065,16600,6185,26080,
34226083,24543,13312,26136,12791,12792,26180,12708,12709,26187,3701,26215,20966,
34326227,0,7741,12849,34292,12744,21267,30661,10487,39332,26370,17308,18977,
34415147,27130,14274,0,26471,26466,16845,37101,26583,17641,26658,28240,37436,
34526625,13286,28064,26717,13423,27105,27147,35551,26995,26819,13773,26881,26880,
34615666,14849,13884,15232,26540,26977,35402,17148,26934,27032,15265,969,33635,
34720624,27129,13913,8490,27205,14083,27293,15347,26545,27336,37276,15373,27421,
3482339,24798,27445,27508,10189,28341,15067,949,6488,14144,21537,15194,27617,
34916124,27612,27703,9355,18673,27473,
35027738,33318,27769,15804,17605,15805,16804,18700,18688,15561,14053,15595,3378,
35139811,12793,9361,32655,26679,27941,28065,28139,28054,27996,28284,28420,18815,
35216517,28274,34099,28532,20935,0,0,33838,35617,0,15919,29779,16258,31180,28239,
35323185,12363,28664,14093,28573,15920,28410,5271,16445,17749,37872,28484,28508,
35415694,28532,37232,15675,28575,16708,28627,16529,16725,16441,16368,16308,16703,
35520959,16726,16727,16704,25053,28747,28798,28839,28801,28876,28885,28886,28895,
35616644,15848,29108,29078,17015,28971,28997,23176,29002,0,23708,17253,29007,
35737730,17089,28972,17498,18983,18978,29114,35816,28861,29198,37954,29205,22801,
35837955,29220,37697,22021,29230,29248,18804,26813,29269,29271,15957,12356,26637,
35928477,29314,0,29483,18467,34859,18669,34820,29480,29486,29647,29610,3130,
36027182,29641,29769,16866,5863,18980,26147,14021,18871,18829,18939,29687,29717,
36126883,18982,29753,1475,16087,0,10413,29792,36530,29767,29668,29814,33721,
36229804,14128,29812,37873,27180,29826,18771,19084,16735,19065,35727,23366,35843,
3636302,29896,6536,29966,0,29982,36569,6731,23511,36524,37765,30029,30026,30055,
36430062,20354,16132,19731,30094,29789,30110,30132,30210,30252,30289,30287,30319,
36530326,25589,30352,33263,14328,26897,26894,30369,30373,30391,30412,28575,33890,
36620637,20861,7708,30494,30502,30528,25775,21024,30552,12972,30639,35172,35176,
3675825,30708,0,4982,18962,26826,30895,30919,30931,38565,31022,21984,30935,31028,
36830897,30220,36792,34948,35627,24707,9756,31110,35072,26882,31104,22615,31133,
36931545,31036,31145,28202,28966,
37016040,31174,37133,31188,1312,17503,21007,47234,248,16384,43296,1102,0,0,2868,
3711,0,0,0,0,0,0,0,3072,64,0,0,0,1024,88,60,0,0,23680,56493,48115,17353,60910,
3724004,49446,30363,61426,64478,63482,12815,44868,61438,65277,24593,176,8448,
37333049,4128,43144,8544,9321,17408,50313,0,16387,53,33859,20785,26771,514,0,0,0,
3740,0,16384,256,44160,33380,35904,37025,20484,54368,53760,6186,26781,38709,
37555375,8440,33476,10268,30082,660,16440,41376,4293,19825,3524,47512,23390,
37617153,39327,30723,57888,2079,393,16585,775,39437,21136,20433,892,8450,49184,
3774974,46467,62939,30693,20368,39447,5942,12,47726,12041,21600,7680,26744,28706,
37840534,62245,46990,2839,59119,6007,7003,4289,36248,6162,53174,12545,6770,11355,
37949334,57888,23747,7042,56032,34254,16598,21673,53259,18447,16452,2320,16596,
38015278,7780,11076,2071,33414,6198,35232,40167,2139,900,55810,60560,34779,49029,
38144450,36509,39069,9504,70,40774,58239,51669,62596,19926,58118,6326,2322,0,
3821024,0,32,0,512,0,0,0,0,8192,0,0,0,0,0,0,8,36352,28280,16223,56702,63293,
38339932,44796,65490,27535,59377,47807,28334,61207,42972,46654,30645,37577,42455,
38419126,39790,33209,26445,21758,39921,65122,21103,14039,49150,17705,63873,26045,
38517062,57,16896,36704,37888,16448,45010,53719,219,39072,31666,20998,38944,
38651222,2365,0,1,0,2561,2226,128,0,34820,5152,19472,0,4,17569,16,321,
3872048,61504,20447,22582,62961,32949,26613,16512,20480,16718,33992,23040,55392,
38811009,20481,5793,16580,28402,44049,14624,49348,1800,2316,38552,39876,7184,
38927800,10886,422,4422,58733,50379,37568,8464,4630,29341,27124,5902,41514,62593,
390123,41992,36875,11280,14796,330,5872,2571,3136,59933,17420,17678,2,
libc/musl/src/locale/iconv.c created+685
......@@ -0,0 +1,685 @@
1#include <iconv.h>
2#include <errno.h>
3#include <wchar.h>
4#include <string.h>
5#include <stdlib.h>
6#include <limits.h>
7#include <stdint.h>
8#include "locale_impl.h"
9
10#define UTF_32BE 0300
11#define UTF_16LE 0301
12#define UTF_16BE 0302
13#define UTF_32LE 0303
14#define UCS2BE 0304
15#define UCS2LE 0305
16#define WCHAR_T 0306
17#define US_ASCII 0307
18#define UTF_8 0310
19#define UTF_16 0312
20#define UTF_32 0313
21#define UCS2 0314
22#define EUC_JP 0320
23#define SHIFT_JIS 0321
24#define ISO2022_JP 0322
25#define GB18030 0330
26#define GBK 0331
27#define GB2312 0332
28#define BIG5 0340
29#define EUC_KR 0350
30
31/* Definitions of charmaps. Each charmap consists of:
32 * 1. Empty-string-terminated list of null-terminated aliases.
33 * 2. Special type code or number of elided quads of entries.
34 * 3. Character table (size determined by field 2), consisting
35 * of 5 bytes for every 4 characters, interpreted as 10-bit
36 * indices into the legacy_chars table. */
37
38static const unsigned char charmaps[] =
39"utf8\0char\0\0\310"
40"wchart\0\0\306"
41"ucs2be\0\0\304"
42"ucs2le\0\0\305"
43"utf16be\0\0\302"
44"utf16le\0\0\301"
45"ucs4be\0utf32be\0\0\300"
46"ucs4le\0utf32le\0\0\303"
47"ascii\0usascii\0iso646\0iso646us\0\0\307"
48"utf16\0\0\312"
49"ucs4\0utf32\0\0\313"
50"ucs2\0\0\314"
51"eucjp\0\0\320"
52"shiftjis\0sjis\0\0\321"
53"iso2022jp\0\0\322"
54"gb18030\0\0\330"
55"gbk\0\0\331"
56"gb2312\0\0\332"
57"big5\0bigfive\0cp950\0big5hkscs\0\0\340"
58"euckr\0ksc5601\0ksx1001\0cp949\0\0\350"
59#include "codepages.h"
60;
61
62/* Table of characters that appear in legacy 8-bit codepages,
63 * limited to 1024 slots (10 bit indices). The first 256 entries
64 * are elided since those characters are obviously all included. */
65static const unsigned short legacy_chars[] = {
66#include "legacychars.h"
67};
68
69static const unsigned short jis0208[84][94] = {
70#include "jis0208.h"
71};
72
73static const unsigned short gb18030[126][190] = {
74#include "gb18030.h"
75};
76
77static const unsigned short big5[89][157] = {
78#include "big5.h"
79};
80
81static const unsigned short hkscs[] = {
82#include "hkscs.h"
83};
84
85static const unsigned short ksc[93][94] = {
86#include "ksc.h"
87};
88
89static const unsigned short rev_jis[] = {
90#include "revjis.h"
91};
92
93static int fuzzycmp(const unsigned char *a, const unsigned char *b)
94{
95 for (; *a && *b; a++, b++) {
96 while (*a && (*a|32U)-'a'>26 && *a-'0'>10U) a++;
97 if ((*a|32U) != *b) return 1;
98 }
99 return *a != *b;
100}
101
102static size_t find_charmap(const void *name)
103{
104 const unsigned char *s;
105 if (!*(char *)name) name=charmaps; /* "utf8" */
106 for (s=charmaps; *s; ) {
107 if (!fuzzycmp(name, s)) {
108 for (; *s; s+=strlen((void *)s)+1);
109 return s+1-charmaps;
110 }
111 s += strlen((void *)s)+1;
112 if (!*s) {
113 if (s[1] > 0200) s+=2;
114 else s+=2+(64U-s[1])*5;
115 }
116 }
117 return -1;
118}
119
120struct stateful_cd {
121 iconv_t base_cd;
122 unsigned state;
123};
124
125static iconv_t combine_to_from(size_t t, size_t f)
126{
127 return (void *)(f<<16 | t<<1 | 1);
128}
129
130static size_t extract_from(iconv_t cd)
131{
132 return (size_t)cd >> 16;
133}
134
135static size_t extract_to(iconv_t cd)
136{
137 return (size_t)cd >> 1 & 0x7fff;
138}
139
140iconv_t iconv_open(const char *to, const char *from)
141{
142 size_t f, t;
143 struct stateful_cd *scd;
144
145 if ((t = find_charmap(to))==-1
146 || (f = find_charmap(from))==-1
147 || (charmaps[t] >= 0330)) {
148 errno = EINVAL;
149 return (iconv_t)-1;
150 }
151 iconv_t cd = combine_to_from(t, f);
152
153 switch (charmaps[f]) {
154 case UTF_16:
155 case UTF_32:
156 case UCS2:
157 case ISO2022_JP:
158 scd = malloc(sizeof *scd);
159 if (!scd) return (iconv_t)-1;
160 scd->base_cd = cd;
161 scd->state = 0;
162 cd = (iconv_t)scd;
163 }
164
165 return cd;
166}
167
168static unsigned get_16(const unsigned char *s, int e)
169{
170 e &= 1;
171 return s[e]<<8 | s[1-e];
172}
173
174static void put_16(unsigned char *s, unsigned c, int e)
175{
176 e &= 1;
177 s[e] = c>>8;
178 s[1-e] = c;
179}
180
181static unsigned get_32(const unsigned char *s, int e)
182{
183 e &= 3;
184 return s[e]+0U<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3];
185}
186
187static void put_32(unsigned char *s, unsigned c, int e)
188{
189 e &= 3;
190 s[e^0] = c>>24;
191 s[e^1] = c>>16;
192 s[e^2] = c>>8;
193 s[e^3] = c;
194}
195
196/* Adapt as needed */
197#define mbrtowc_utf8 mbrtowc
198#define wctomb_utf8 wctomb
199
200static unsigned legacy_map(const unsigned char *map, unsigned c)
201{
202 if (c < 4*map[-1]) return c;
203 unsigned x = c - 4*map[-1];
204 x = map[x*5/4]>>2*x%8 | map[x*5/4+1]<<8-2*x%8 & 1023;
205 return x < 256 ? x : legacy_chars[x-256];
206}
207
208static unsigned uni_to_jis(unsigned c)
209{
210 unsigned nel = sizeof rev_jis / sizeof *rev_jis;
211 unsigned d, j, i, b = 0;
212 for (;;) {
213 i = nel/2;
214 j = rev_jis[b+i];
215 d = jis0208[j/256][j%256];
216 if (d==c) return j + 0x2121;
217 else if (nel == 1) return 0;
218 else if (c < d)
219 nel /= 2;
220 else {
221 b += i;
222 nel -= nel/2;
223 }
224 }
225}
226
227size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb)
228{
229 size_t x=0;
230 struct stateful_cd *scd=0;
231 if (!((size_t)cd & 1)) {
232 scd = (void *)cd;
233 cd = scd->base_cd;
234 }
235 unsigned to = extract_to(cd);
236 unsigned from = extract_from(cd);
237 const unsigned char *map = charmaps+from+1;
238 const unsigned char *tomap = charmaps+to+1;
239 mbstate_t st = {0};
240 wchar_t wc;
241 unsigned c, d;
242 size_t k, l;
243 int err;
244 unsigned char type = map[-1];
245 unsigned char totype = tomap[-1];
246 locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
247
248 if (!in || !*in || !*inb) return 0;
249
250 *ploc = UTF8_LOCALE;
251
252 for (; *inb; *in+=l, *inb-=l) {
253 c = *(unsigned char *)*in;
254 l = 1;
255
256 switch (type) {
257 case UTF_8:
258 if (c < 128) break;
259 l = mbrtowc_utf8(&wc, *in, *inb, &st);
260 if (l == (size_t)-1) goto ilseq;
261 if (l == (size_t)-2) goto starved;
262 c = wc;
263 break;
264 case US_ASCII:
265 if (c >= 128) goto ilseq;
266 break;
267 case WCHAR_T:
268 l = sizeof(wchar_t);
269 if (*inb < l) goto starved;
270 c = *(wchar_t *)*in;
271 if (0) {
272 case UTF_32BE:
273 case UTF_32LE:
274 l = 4;
275 if (*inb < 4) goto starved;
276 c = get_32((void *)*in, type);
277 }
278 if (c-0xd800u < 0x800u || c >= 0x110000u) goto ilseq;
279 break;
280 case UCS2BE:
281 case UCS2LE:
282 case UTF_16BE:
283 case UTF_16LE:
284 l = 2;
285 if (*inb < 2) goto starved;
286 c = get_16((void *)*in, type);
287 if ((unsigned)(c-0xdc00) < 0x400) goto ilseq;
288 if ((unsigned)(c-0xd800) < 0x400) {
289 if (type-UCS2BE < 2U) goto ilseq;
290 l = 4;
291 if (*inb < 4) goto starved;
292 d = get_16((void *)(*in + 2), type);
293 if ((unsigned)(d-0xdc00) >= 0x400) goto ilseq;
294 c = ((c-0xd7c0)<<10) + (d-0xdc00);
295 }
296 break;
297 case UCS2:
298 case UTF_16:
299 l = 0;
300 if (!scd->state) {
301 if (*inb < 2) goto starved;
302 c = get_16((void *)*in, 0);
303 scd->state = type==UCS2
304 ? c==0xfffe ? UCS2LE : UCS2BE
305 : c==0xfffe ? UTF_16LE : UTF_16BE;
306 if (c == 0xfffe || c == 0xfeff)
307 l = 2;
308 }
309 type = scd->state;
310 continue;
311 case UTF_32:
312 l = 0;
313 if (!scd->state) {
314 if (*inb < 4) goto starved;
315 c = get_32((void *)*in, 0);
316 scd->state = c==0xfffe0000 ? UTF_32LE : UTF_32BE;
317 if (c == 0xfffe0000 || c == 0xfeff)
318 l = 4;
319 }
320 type = scd->state;
321 continue;
322 case SHIFT_JIS:
323 if (c < 128) break;
324 if (c-0xa1 <= 0xdf-0xa1) {
325 c += 0xff61-0xa1;
326 break;
327 }
328 l = 2;
329 if (*inb < 2) goto starved;
330 d = *((unsigned char *)*in + 1);
331 if (c-129 <= 159-129) c -= 129;
332 else if (c-224 <= 239-224) c -= 193;
333 else goto ilseq;
334 c *= 2;
335 if (d-64 <= 158-64) {
336 if (d==127) goto ilseq;
337 if (d>127) d--;
338 d -= 64;
339 } else if (d-159 <= 252-159) {
340 c++;
341 d -= 159;
342 }
343 c = jis0208[c][d];
344 if (!c) goto ilseq;
345 break;
346 case EUC_JP:
347 if (c < 128) break;
348 l = 2;
349 if (*inb < 2) goto starved;
350 d = *((unsigned char *)*in + 1);
351 if (c==0x8e) {
352 c = d;
353 if (c-0xa1 > 0xdf-0xa1) goto ilseq;
354 c += 0xff61 - 0xa1;
355 break;
356 }
357 c -= 0xa1;
358 d -= 0xa1;
359 if (c >= 84 || d >= 94) goto ilseq;
360 c = jis0208[c][d];
361 if (!c) goto ilseq;
362 break;
363 case ISO2022_JP:
364 if (c >= 128) goto ilseq;
365 if (c == '\033') {
366 l = 3;
367 if (*inb < 3) goto starved;
368 c = *((unsigned char *)*in + 1);
369 d = *((unsigned char *)*in + 2);
370 if (c != '(' && c != '$') goto ilseq;
371 switch (128*(c=='$') + d) {
372 case 'B': scd->state=0; continue;
373 case 'J': scd->state=1; continue;
374 case 'I': scd->state=4; continue;
375 case 128+'@': scd->state=2; continue;
376 case 128+'B': scd->state=3; continue;
377 }
378 goto ilseq;
379 }
380 switch (scd->state) {
381 case 1:
382 if (c=='\\') c = 0xa5;
383 if (c=='~') c = 0x203e;
384 break;
385 case 2:
386 case 3:
387 l = 2;
388 if (*inb < 2) goto starved;
389 d = *((unsigned char *)*in + 1);
390 c -= 0x21;
391 d -= 0x21;
392 if (c >= 84 || d >= 94) goto ilseq;
393 c = jis0208[c][d];
394 if (!c) goto ilseq;
395 break;
396 case 4:
397 if (c-0x60 < 0x1f) goto ilseq;
398 if (c-0x21 < 0x5e) c += 0xff61-0x21;
399 break;
400 }
401 break;
402 case GB2312:
403 if (c < 128) break;
404 if (c < 0xa1) goto ilseq;
405 case GBK:
406 case GB18030:
407 if (c < 128) break;
408 c -= 0x81;
409 if (c >= 126) goto ilseq;
410 l = 2;
411 if (*inb < 2) goto starved;
412 d = *((unsigned char *)*in + 1);
413 if (d < 0xa1 && type == GB2312) goto ilseq;
414 if (d-0x40>=191 || d==127) {
415 if (d-'0'>9 || type != GB18030)
416 goto ilseq;
417 l = 4;
418 if (*inb < 4) goto starved;
419 c = (10*c + d-'0') * 1260;
420 d = *((unsigned char *)*in + 2);
421 if (d-0x81>126) goto ilseq;
422 c += 10*(d-0x81);
423 d = *((unsigned char *)*in + 3);
424 if (d-'0'>9) goto ilseq;
425 c += d-'0';
426 c += 128;
427 for (d=0; d<=c; ) {
428 k = 0;
429 for (int i=0; i<126; i++)
430 for (int j=0; j<190; j++)
431 if (gb18030[i][j]-d <= c-d)
432 k++;
433 d = c+1;
434 c += k;
435 }
436 break;
437 }
438 d -= 0x40;
439 if (d>63) d--;
440 c = gb18030[c][d];
441 break;
442 case BIG5:
443 if (c < 128) break;
444 l = 2;
445 if (*inb < 2) goto starved;
446 d = *((unsigned char *)*in + 1);
447 if (d-0x40>=0xff-0x40 || d-0x7f<0xa1-0x7f) goto ilseq;
448 d -= 0x40;
449 if (d > 0x3e) d -= 0x22;
450 if (c-0xa1>=0xfa-0xa1) {
451 if (c-0x87>=0xff-0x87) goto ilseq;
452 if (c < 0xa1) c -= 0x87;
453 else c -= 0x87 + (0xfa-0xa1);
454 c = (hkscs[4867+(c*157+d)/16]>>(c*157+d)%16)%2<<17
455 | hkscs[c*157+d];
456 /* A few HKSCS characters map to pairs of UCS
457 * characters. These are mapped to surrogate
458 * range in the hkscs table then hard-coded
459 * here. Ugly, yes. */
460 if (c/256 == 0xdc) {
461 union {
462 char c[8];
463 wchar_t wc[2];
464 } tmp;
465 char *ptmp = tmp.c;
466 size_t tmpx = iconv(combine_to_from(to, find_charmap("utf8")),
467 &(char *){"\303\212\314\204"
468 "\303\212\314\214"
469 "\303\252\314\204"
470 "\303\252\314\214"
471 +c%256}, &(size_t){4},
472 &ptmp, &(size_t){sizeof tmp});
473 size_t tmplen = ptmp - tmp.c;
474 if (tmplen > *outb) goto toobig;
475 if (tmpx) x++;
476 memcpy(*out, &tmp, tmplen);
477 *out += tmplen;
478 *outb -= tmplen;
479 continue;
480 }
481 if (!c) goto ilseq;
482 break;
483 }
484 c -= 0xa1;
485 c = big5[c][d]|(c==0x27&&(d==0x3a||d==0x3c||d==0x42))<<17;
486 if (!c) goto ilseq;
487 break;
488 case EUC_KR:
489 if (c < 128) break;
490 l = 2;
491 if (*inb < 2) goto starved;
492 d = *((unsigned char *)*in + 1);
493 c -= 0xa1;
494 d -= 0xa1;
495 if (c >= 93 || d >= 94) {
496 c += (0xa1-0x81);
497 d += 0xa1;
498 if (c >= 93 || c>=0xc6-0x81 && d>0x52)
499 goto ilseq;
500 if (d-'A'<26) d = d-'A';
501 else if (d-'a'<26) d = d-'a'+26;
502 else if (d-0x81<0xff-0x81) d = d-0x81+52;
503 else goto ilseq;
504 if (c < 0x20) c = 178*c + d;
505 else c = 178*0x20 + 84*(c-0x20) + d;
506 c += 0xac00;
507 for (d=0xac00; d<=c; ) {
508 k = 0;
509 for (int i=0; i<93; i++)
510 for (int j=0; j<94; j++)
511 if (ksc[i][j]-d <= c-d)
512 k++;
513 d = c+1;
514 c += k;
515 }
516 break;
517 }
518 c = ksc[c][d];
519 if (!c) goto ilseq;
520 break;
521 default:
522 if (!c) break;
523 c = legacy_map(map, c);
524 if (!c) goto ilseq;
525 }
526
527 switch (totype) {
528 case WCHAR_T:
529 if (*outb < sizeof(wchar_t)) goto toobig;
530 *(wchar_t *)*out = c;
531 *out += sizeof(wchar_t);
532 *outb -= sizeof(wchar_t);
533 break;
534 case UTF_8:
535 if (*outb < 4) {
536 char tmp[4];
537 k = wctomb_utf8(tmp, c);
538 if (*outb < k) goto toobig;
539 memcpy(*out, tmp, k);
540 } else k = wctomb_utf8(*out, c);
541 *out += k;
542 *outb -= k;
543 break;
544 case US_ASCII:
545 if (c > 0x7f) subst: x++, c='*';
546 default:
547 if (*outb < 1) goto toobig;
548 if (c<256 && c==legacy_map(tomap, c)) {
549 revout:
550 if (*outb < 1) goto toobig;
551 *(*out)++ = c;
552 *outb -= 1;
553 break;
554 }
555 d = c;
556 for (c=4*totype; c<256; c++) {
557 if (d == legacy_map(tomap, c)) {
558 goto revout;
559 }
560 }
561 goto subst;
562 case SHIFT_JIS:
563 if (c < 128) goto revout;
564 if (c == 0xa5) {
565 x++;
566 c = '\\';
567 goto revout;
568 }
569 if (c == 0x203e) {
570 x++;
571 c = '~';
572 goto revout;
573 }
574 if (c-0xff61 <= 0xdf-0xa1) {
575 c += 0xa1 - 0xff61;
576 goto revout;
577 }
578 c = uni_to_jis(c);
579 if (!c) goto subst;
580 if (*outb < 2) goto toobig;
581 d = c%256;
582 c = c/256;
583 *(*out)++ = (c+1)/2 + (c<95 ? 112 : 176);
584 *(*out)++ = c%2 ? d + 31 + d/96 : d + 126;
585 *outb -= 2;
586 break;
587 case EUC_JP:
588 if (c < 128) goto revout;
589 if (c-0xff61 <= 0xdf-0xa1) {
590 c += 0x0e00 + 0x21 - 0xff61;
591 } else {
592 c = uni_to_jis(c);
593 }
594 if (!c) goto subst;
595 if (*outb < 2) goto toobig;
596 *(*out)++ = c/256 + 0x80;
597 *(*out)++ = c%256 + 0x80;
598 *outb -= 2;
599 break;
600 case ISO2022_JP:
601 if (c < 128) goto revout;
602 if (c-0xff61 <= 0xdf-0xa1 || c==0xa5 || c==0x203e) {
603 if (*outb < 7) goto toobig;
604 *(*out)++ = '\033';
605 *(*out)++ = '(';
606 if (c==0xa5) {
607 *(*out)++ = 'J';
608 *(*out)++ = '\\';
609 } else if (c==0x203e) {
610 *(*out)++ = 'J';
611 *(*out)++ = '~';
612 } else {
613 *(*out)++ = 'I';
614 *(*out)++ = c-0xff61+0x21;
615 }
616 *(*out)++ = '\033';
617 *(*out)++ = '(';
618 *(*out)++ = 'B';
619 *outb -= 7;
620 break;
621 }
622 c = uni_to_jis(c);
623 if (!c) goto subst;
624 if (*outb < 8) goto toobig;
625 *(*out)++ = '\033';
626 *(*out)++ = '$';
627 *(*out)++ = 'B';
628 *(*out)++ = c/256;
629 *(*out)++ = c%256;
630 *(*out)++ = '\033';
631 *(*out)++ = '(';
632 *(*out)++ = 'B';
633 *outb -= 8;
634 break;
635 case UCS2:
636 totype = UCS2BE;
637 case UCS2BE:
638 case UCS2LE:
639 case UTF_16:
640 case UTF_16BE:
641 case UTF_16LE:
642 if (c < 0x10000 || totype-UCS2BE < 2U) {
643 if (c >= 0x10000) c = 0xFFFD;
644 if (*outb < 2) goto toobig;
645 put_16((void *)*out, c, totype);
646 *out += 2;
647 *outb -= 2;
648 break;
649 }
650 if (*outb < 4) goto toobig;
651 c -= 0x10000;
652 put_16((void *)*out, (c>>10)|0xd800, totype);
653 put_16((void *)(*out + 2), (c&0x3ff)|0xdc00, totype);
654 *out += 4;
655 *outb -= 4;
656 break;
657 case UTF_32:
658 totype = UTF_32BE;
659 case UTF_32BE:
660 case UTF_32LE:
661 if (*outb < 4) goto toobig;
662 put_32((void *)*out, c, totype);
663 *out += 4;
664 *outb -= 4;
665 break;
666 }
667 }
668 *ploc = loc;
669 return x;
670ilseq:
671 err = EILSEQ;
672 x = -1;
673 goto end;
674toobig:
675 err = E2BIG;
676 x = -1;
677 goto end;
678starved:
679 err = EINVAL;
680 x = -1;
681end:
682 errno = err;
683 *ploc = loc;
684 return x;
685}
libc/musl/src/locale/iconv_close.c created+8
......@@ -0,0 +1,8 @@
1#include <iconv.h>
2#include <stdlib.h>
3
4int iconv_close(iconv_t cd)
5{
6 if (!((size_t)cd & 1)) free((void *)cd);
7 return 0;
8}
libc/musl/src/locale/jis0208.h created+563
......@@ -0,0 +1,563 @@
112288,12289,12290,65292,65294,12539,65306,65307,65311,65281,12443,12444,180,
265344,168,65342,65507,65343,12541,12542,12445,12446,12291,20189,12293,12294,
312295,12540,8213,8208,65295,92,12316,8214,65372,8230,8229,8216,8217,8220,8221,
465288,65289,12308,12309,65339,65341,65371,65373,12296,12297,12298,12299,12300,
512301,12302,12303,12304,12305,65291,8722,177,215,247,65309,8800,65308,65310,
68806,8807,8734,8756,9794,9792,176,8242,8243,8451,65509,65284,162,163,65285,
765283,65286,65290,65312,167,9734,9733,9675,9679,9678,9671,9670,9633,9632,9651,
89650,9661,9660,8251,12306,8594,8592,8593,8595,12307,0,0,0,0,0,0,0,0,0,0,0,
98712,8715,8838,8839,8834,8835,8746,8745,0,0,0,0,0,0,0,0,8743,8744,172,8658,
108660,8704,8707,0,0,0,0,0,0,0,0,0,0,0,8736,8869,8978,8706,8711,8801,8786,8810,
118811,8730,8765,8733,8757,8747,8748,0,0,0,0,0,0,0,8491,8240,9839,9837,9834,
128224,8225,182,0,0,0,0,9711,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65296,65297,65298,
1365299,65300,65301,65302,65303,65304,65305,0,0,0,0,0,0,0,65313,65314,65315,
1465316,65317,65318,65319,65320,65321,65322,65323,65324,65325,65326,65327,65328,
1565329,65330,65331,65332,65333,65334,65335,65336,65337,65338,0,0,0,0,0,0,65345,
1665346,65347,
1765348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,
1865361,65362,65363,65364,65365,65366,65367,65368,65369,65370,0,0,0,0,12353,
1912354,12355,12356,12357,12358,12359,12360,12361,12362,12363,12364,12365,12366,
2012367,12368,12369,12370,12371,12372,12373,12374,12375,12376,12377,12378,12379,
2112380,12381,12382,12383,12384,12385,12386,12387,12388,12389,12390,12391,12392,
2212393,12394,12395,12396,12397,12398,12399,12400,12401,12402,12403,12404,12405,
2312406,12407,12408,12409,12410,12411,12412,12413,12414,12415,12416,12417,12418,
2412419,12420,12421,12422,12423,12424,12425,12426,12427,12428,12429,12430,12431,
2512432,12433,12434,12435,0,0,0,0,0,0,0,0,0,0,0,12449,12450,12451,12452,12453,
2612454,12455,12456,12457,12458,12459,12460,12461,12462,12463,12464,12465,12466,
2712467,12468,12469,12470,12471,12472,12473,12474,12475,12476,12477,12478,12479,
2812480,12481,12482,12483,12484,12485,12486,12487,12488,12489,12490,12491,12492,
2912493,12494,12495,12496,12497,12498,12499,12500,12501,12502,12503,12504,12505,
3012506,12507,12508,12509,12510,12511,12512,12513,12514,12515,12516,12517,12518,
3112519,12520,12521,12522,12523,12524,12525,12526,12527,12528,12529,12530,12531,
3212532,12533,12534,0,0,0,0,0,0,0,0,913,914,915,916,917,918,919,920,921,922,923,
33924,925,926,927,928,929,931,932,933,934,935,936,937,0,0,0,0,0,0,0,0,945,946,
34947,948,949,950,951,952,953,
35954,955,956,957,958,959,960,961,963,964,965,966,967,968,969,0,0,0,0,0,0,0,0,0,
360,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1040,1041,1042,1043,
371044,1045,1025,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,
381058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,0,0,0,0,
390,0,0,0,0,0,0,0,0,0,0,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,
401082,1083,1084,1085,1086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,
411097,1098,1099,1100,1101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,9472,9474,9484,
429488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,
439523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,0,0,0,0,
440,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
450,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
460,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
470,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
490,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
500,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
510,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
520,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
530,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
540,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
550,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
560,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
570,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
580,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
590,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
610,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
620,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
630,0,0,0,0,0,0,0,0,0,0,0,0,0,20124,21782,23043,38463,21696,24859,25384,23030,
6436898,33909,33564,31312,24746,25569,28197,26093,33894,33446,39925,26771,22311,
6526017,25201,23451,22992,34427,39156,32098,32190,39822,25110,31903,34999,23433,
6624245,25353,26263,26696,38343,38797,26447,20197,20234,20301,20381,20553,22258,
6722839,22996,23041,23561,24799,24847,24944,26131,26885,28858,30031,30064,31227,
6832173,32239,32963,33806,34915,35586,36949,36986,21307,20117,20133,22495,32946,
6937057,30959,19968,22769,28322,36920,31282,33576,33419,39983,20801,21360,21693,
7021729,22240,23035,24341,39154,28139,32996,34093,38498,38512,38560,38907,21515,
7121491,23431,28879,32701,36802,38632,21359,40284,31418,19985,30867,33276,28198,
7222040,21764,27421,34074,39995,23013,21417,28006,29916,38287,22082,20113,36939,
7338642,33615,39180,21473,21942,23344,24433,26144,26355,26628,27704,27891,27945,
7429787,30408,31310,38964,33521,34907,35424,37613,28082,30123,30410,39365,24742,
7535585,36234,38322,27022,21421,20870,22290,22576,22852,23476,24310,24616,25513,
7625588,27839,28436,28814,28948,29017,29141,29503,32257,33398,33489,34199,36960,
7737467,40219,22633,26044,27738,29989,20985,22830,22885,24448,24540,25276,26106,
7827178,27431,27572,29579,32705,35158,40236,40206,40644,23713,27798,33659,20740,
7923627,25014,33222,26742,29281,20057,20474,21368,24681,28201,31311,38899,19979,
8021270,20206,20309,20285,20385,20339,21152,21487,22025,22799,23233,23478,23521,
8131185,26247,26524,26550,27468,27827,28779,29634,31117,31166,31292,31623,33457,
8233499,33540,33655,33775,33747,34662,35506,22057,36008,36838,36942,38686,34442,
8320420,23784,25105,29273,30011,33253,33469,34558,36032,38597,39187,39381,20171,
8420250,35299,22238,22602,22730,24315,24555,24618,24724,24674,25040,25106,25296,
8525913,39745,26214,26800,28023,28784,30028,30342,32117,33445,34809,38283,38542,
8635997,20977,21182,22806,21683,23475,23830,24936,27010,28079,30861,33995,34903,
8735442,37799,39608,28012,39336,34521,22435,26623,34510,37390,21123,22151,21508,
8824275,25313,25785,26684,26680,27579,29554,30906,31339,35226,35282,36203,36611,
8937101,38307,38548,38761,23398,23731,27005,38989,38990,25499,31520,27179,27263,
9026806,39949,28511,21106,21917,24688,25324,27963,28167,28369,33883,35088,36676,
9119988,39993,21494,26907,27194,38788,26666,20828,31427,33970,37340,37772,22107,
9240232,26658,33541,33841,31909,21000,33477,29926,20094,
9320355,20896,23506,21002,21208,21223,24059,21914,22570,23014,23436,23448,23515,
9424178,24185,24739,24863,24931,25022,25563,25954,26577,26707,26874,27454,27475,
9527735,28450,28567,28485,29872,29976,30435,30475,31487,31649,31777,32233,32566,
9632752,32925,33382,33694,35251,35532,36011,36996,37969,38291,38289,38306,38501,
9738867,39208,33304,20024,21547,23736,24012,29609,30284,30524,23721,32747,36107,
9838593,38929,38996,39000,20225,20238,21361,21916,22120,22522,22855,23305,23492,
9923696,24076,24190,24524,25582,26426,26071,26082,26399,26827,26820,27231,24112,
10027589,27671,27773,30079,31048,23395,31232,32000,24509,35215,35352,36020,36215,
10136556,36637,39138,39438,39740,20096,20605,20736,22931,23452,25135,25216,25836,
10227450,29344,30097,31047,32681,34811,35516,35696,25516,33738,38816,21513,21507,
10321931,26708,27224,35440,30759,26485,40653,21364,23458,33050,34384,36870,19992,
10420037,20167,20241,21450,21560,23470,24339,24613,25937,26429,27714,27762,27875,
10528792,29699,31350,31406,31496,32026,31998,32102,26087,29275,21435,23621,24040,
10625298,25312,25369,28192,34394,35377,36317,37624,28417,31142,39770,20136,20139,
10720140,20379,20384,20689,20807,31478,20849,20982,21332,21281,21375,21483,21932,
10822659,23777,24375,24394,24623,24656,24685,25375,25945,27211,27841,29378,29421,
10930703,33016,33029,33288,34126,37111,37857,38911,39255,39514,20208,20957,23597,
11026241,26989,23616,26354,26997,29577,26704,31873,20677,21220,22343,24062,37670,
11126020,27427,27453,29748,31105,31165,31563,32202,33465,33740,34943,35167,35641,
11236817,37329,21535,37504,20061,20534,21477,21306,29399,
11329590,30697,33510,36527,39366,39368,39378,20855,24858,34398,21936,31354,20598,
11423507,36935,38533,20018,27355,37351,23633,23624,25496,31391,27795,38772,36705,
11531402,29066,38536,31874,26647,32368,26705,37740,21234,21531,34219,35347,32676,
11636557,37089,21350,34952,31041,20418,20670,21009,20804,21843,22317,29674,22411,
11722865,24418,24452,24693,24950,24935,25001,25522,25658,25964,26223,26690,28179,
11830054,31293,31995,32076,32153,32331,32619,33550,33610,34509,35336,35427,35686,
11936605,38938,40335,33464,36814,39912,21127,25119,25731,28608,38553,26689,20625,
12027424,27770,28500,31348,32080,34880,35363,26376,20214,20537,20518,20581,20860,
12121048,21091,21927,22287,22533,23244,24314,25010,25080,25331,25458,26908,27177,
12229309,29356,29486,30740,30831,32121,30476,32937,35211,35609,36066,36562,36963,
12337749,38522,38997,39443,40568,20803,21407,21427,24187,24358,28187,28304,29572,
12429694,32067,33335,35328,35578,38480,20046,20491,21476,21628,22266,22993,23396,
12524049,24235,24359,25144,25925,26543,28246,29392,31946,34996,32929,32993,33776,
12634382,35463,36328,37431,38599,39015,40723,20116,20114,20237,21320,21577,21566,
12723087,24460,24481,24735,26791,27278,29786,30849,35486,35492,35703,37264,20062,
12839881,20132,20348,20399,20505,20502,20809,20844,21151,21177,21246,21402,21475,
12921521,21518,21897,22353,22434,22909,23380,23389,23439,24037,24039,24055,24184,
13024195,24218,24247,24344,24658,24908,25239,25304,25511,25915,26114,26179,26356,
13126477,26657,26775,27083,27743,27946,28009,28207,28317,30002,30343,30828,31295,
13231968,32005,32024,32094,32177,32789,32771,32943,32945,
13333108,33167,33322,33618,34892,34913,35611,36002,36092,37066,37237,37489,30783,
13437628,38308,38477,38917,39321,39640,40251,21083,21163,21495,21512,22741,25335,
13528640,35946,36703,40633,20811,21051,21578,22269,31296,37239,40288,40658,29508,
13628425,33136,29969,24573,24794,39592,29403,36796,27492,38915,20170,22256,22372,
13722718,23130,24680,25031,26127,26118,26681,26801,28151,30165,32058,33390,39746,
13820123,20304,21449,21766,23919,24038,24046,26619,27801,29811,30722,35408,37782,
13935039,22352,24231,25387,20661,20652,20877,26368,21705,22622,22971,23472,24425,
14025165,25505,26685,27507,28168,28797,37319,29312,30741,30758,31085,25998,32048,
14133756,35009,36617,38555,21092,22312,26448,32618,36001,20916,22338,38442,22586,
14227018,32948,21682,23822,22524,30869,40442,20316,21066,21643,25662,26152,26388,
14326613,31364,31574,32034,37679,26716,39853,31545,21273,20874,21047,23519,25334,
14425774,25830,26413,27578,34217,38609,30352,39894,25420,37638,39851,30399,26194,
14519977,20632,21442,23665,24808,25746,25955,26719,29158,29642,29987,31639,32386,
14634453,35715,36059,37240,39184,26028,26283,27531,20181,20180,20282,20351,21050,
14721496,21490,21987,22235,22763,22987,22985,23039,23376,23629,24066,24107,24535,
14824605,25351,25903,23388,26031,26045,26088,26525,27490,27515,27663,29509,31049,
14931169,31992,32025,32043,32930,33026,33267,35222,35422,35433,35430,35468,35566,
15036039,36060,38604,39164,27503,20107,20284,20365,20816,23383,23546,24904,25345,
15126178,27425,28363,27835,29246,29885,30164,30913,31034,32780,32819,33258,33940,
15236766,27728,40575,24335,35672,40235,31482,36600,23437,
15338635,19971,21489,22519,22833,23241,23460,24713,28287,28422,30142,36074,23455,
15434048,31712,20594,26612,33437,23649,34122,32286,33294,20889,23556,25448,36198,
15526012,29038,31038,32023,32773,35613,36554,36974,34503,37034,20511,21242,23610,
15626451,28796,29237,37196,37320,37675,33509,23490,24369,24825,20027,21462,23432,
15725163,26417,27530,29417,29664,31278,33131,36259,37202,39318,20754,21463,21610,
15823551,25480,27193,32172,38656,22234,21454,21608,23447,23601,24030,20462,24833,
15925342,27954,31168,31179,32066,32333,32722,33261,33311,33936,34886,35186,35728,
16036468,36655,36913,37195,37228,38598,37276,20160,20303,20805,21313,24467,25102,
16126580,27713,28171,29539,32294,37325,37507,21460,22809,23487,28113,31069,32302,
16231899,22654,29087,20986,34899,36848,20426,23803,26149,30636,31459,33308,39423,
16320934,24490,26092,26991,27529,28147,28310,28516,30462,32020,24033,36981,37255,
16438918,20966,21021,25152,26257,26329,28186,24246,32210,32626,26360,34223,34295,
16535576,21161,21465,22899,24207,24464,24661,37604,38500,20663,20767,21213,21280,
16621319,21484,21736,21830,21809,22039,22888,22974,23100,23477,23558,23567,23569,
16723578,24196,24202,24288,24432,25215,25220,25307,25484,25463,26119,26124,26157,
16826230,26494,26786,27167,27189,27836,28040,28169,28248,28988,28966,29031,30151,
16930465,30813,30977,31077,31216,31456,31505,31911,32057,32918,33750,33931,34121,
17034909,35059,35359,35388,35412,35443,35937,36062,37284,37478,37758,37912,38556,
17138808,19978,19976,19998,20055,20887,21104,22478,22580,22732,23330,24120,24773,
17225854,26465,26454,27972,29366,30067,31331,33976,35698,
17337304,37664,22065,22516,39166,25325,26893,27542,29165,32340,32887,33394,35302,
17439135,34645,36785,23611,20280,20449,20405,21767,23072,23517,23529,24515,24910,
17525391,26032,26187,26862,27035,28024,28145,30003,30137,30495,31070,31206,32051,
17633251,33455,34218,35242,35386,36523,36763,36914,37341,38663,20154,20161,20995,
17722645,22764,23563,29978,23613,33102,35338,36805,38499,38765,31525,35535,38920,
17837218,22259,21416,36887,21561,22402,24101,25512,27700,28810,30561,31883,32736,
17934928,36930,37204,37648,37656,38543,29790,39620,23815,23913,25968,26530,36264,
18038619,25454,26441,26905,33733,38935,38592,35070,28548,25722,23544,19990,28716,
18130045,26159,20932,21046,21218,22995,24449,24615,25104,25919,25972,26143,26228,
18226866,26646,27491,28165,29298,29983,30427,31934,32854,22768,35069,35199,35488,
18335475,35531,36893,37266,38738,38745,25993,31246,33030,38587,24109,24796,25114,
18426021,26132,26512,30707,31309,31821,32318,33034,36012,36196,36321,36447,30889,
18520999,25305,25509,25666,25240,35373,31363,31680,35500,38634,32118,33292,34633,
18620185,20808,21315,21344,23459,23554,23574,24029,25126,25159,25776,26643,26676,
18727849,27973,27927,26579,28508,29006,29053,26059,31359,31661,32218,32330,32680,
18833146,33307,33337,34214,35438,36046,36341,36984,36983,37549,37521,38275,39854,
18921069,21892,28472,28982,20840,31109,32341,33203,31950,22092,22609,23720,25514,
19026366,26365,26970,29401,30095,30094,30990,31062,31199,31895,32032,32068,34311,
19135380,38459,36961,40736,20711,21109,21452,21474,20489,21930,22766,22863,29245,
19223435,23652,21277,24803,24819,25436,25475,25407,25531,
19325805,26089,26361,24035,27085,27133,28437,29157,20105,30185,30456,31379,31967,
19432207,32156,32865,33609,33624,33900,33980,34299,35013,36208,36865,36973,37783,
19538684,39442,20687,22679,24974,33235,34101,36104,36896,20419,20596,21063,21363,
19624687,25417,26463,28204,36275,36895,20439,23646,36042,26063,32154,21330,34966,
19720854,25539,23384,23403,23562,25613,26449,36956,20182,22810,22826,27760,35409,
19821822,22549,22949,24816,25171,26561,33333,26965,38464,39364,39464,20307,22534,
19923550,32784,23729,24111,24453,24608,24907,25140,26367,27888,28382,32974,33151,
20033492,34955,36024,36864,36910,38538,40667,39899,20195,21488,22823,31532,37261,
20138988,40441,28381,28711,21331,21828,23429,25176,25246,25299,27810,28655,29730,
20235351,37944,28609,35582,33592,20967,34552,21482,21481,20294,36948,36784,22890,
20333073,24061,31466,36799,26842,35895,29432,40008,27197,35504,20025,21336,22022,
20422374,25285,25506,26086,27470,28129,28251,28845,30701,31471,31658,32187,32829,
20532966,34507,35477,37723,22243,22727,24382,26029,26262,27264,27573,30007,35527,
20620516,30693,22320,24347,24677,26234,27744,30196,31258,32622,33268,34584,36933,
20739347,31689,30044,31481,31569,33988,36880,31209,31378,33590,23265,30528,20013,
20820210,23449,24544,25277,26172,26609,27880,34411,34935,35387,37198,37619,39376,
20927159,28710,29482,33511,33879,36015,19969,20806,20939,21899,23541,24086,24115,
21024193,24340,24373,24427,24500,25074,25361,26274,26397,28526,29266,30010,30522,
21132884,33081,33144,34678,35519,35548,36229,36339,37530,38263,38914,40165,21189,
21225431,30452,26389,27784,29645,36035,37806,38515,27941,
21322684,26894,27084,36861,37786,30171,36890,22618,26626,25524,27131,20291,28460,
21426584,36795,34086,32180,37716,26943,28528,22378,22775,23340,32044,29226,21514,
21537347,40372,20141,20302,20572,20597,21059,35998,21576,22564,23450,24093,24213,
21624237,24311,24351,24716,25269,25402,25552,26799,27712,30855,31118,31243,32224,
21733351,35330,35558,36420,36883,37048,37165,37336,40718,27877,25688,25826,25973,
21828404,30340,31515,36969,37841,28346,21746,24505,25764,36685,36845,37444,20856,
21922635,22825,23637,24215,28155,32399,29980,36028,36578,39003,28857,20253,27583,
22028593,30000,38651,20814,21520,22581,22615,22956,23648,24466,26007,26460,28193,
22130331,33759,36077,36884,37117,37709,30757,30778,21162,24230,22303,22900,24594,
22220498,20826,20908,20941,20992,21776,22612,22616,22871,23445,23798,23947,24764,
22325237,25645,26481,26691,26812,26847,30423,28120,28271,28059,28783,29128,24403,
22430168,31095,31561,31572,31570,31958,32113,21040,33891,34153,34276,35342,35588,
22535910,36367,36867,36879,37913,38518,38957,39472,38360,20685,21205,21516,22530,
22623566,24999,25758,27934,30643,31461,33012,33796,36947,37509,23776,40199,21311,
22724471,24499,28060,29305,30563,31167,31716,27602,29420,35501,26627,27233,20984,
22831361,26932,23626,40182,33515,23493,37193,28702,22136,23663,24775,25958,27788,
22935930,36929,38931,21585,26311,37389,22856,37027,20869,20045,20970,34201,35598,
23028760,25466,37707,26978,39348,32260,30071,21335,26976,36575,38627,27741,20108,
23123612,24336,36841,21250,36049,32905,34425,24319,26085,20083,20837,22914,23615,
23238894,20219,22922,24525,35469,28641,31152,31074,23527,
23333905,29483,29105,24180,24565,25467,25754,29123,31896,20035,24316,20043,22492,
23422178,24745,28611,32013,33021,33075,33215,36786,35223,34468,24052,25226,25773,
23535207,26487,27874,27966,29750,30772,23110,32629,33453,39340,20467,24259,25309,
23625490,25943,26479,30403,29260,32972,32954,36649,37197,20493,22521,23186,26757,
23726995,29028,29437,36023,22770,36064,38506,36889,34687,31204,30695,33833,20271,
23821093,21338,25293,26575,27850,30333,31636,31893,33334,34180,36843,26333,28448,
23929190,32283,33707,39361,40614,20989,31665,30834,31672,32903,31560,27368,24161,
24032908,30033,30048,20843,37474,28300,30330,37271,39658,20240,32624,25244,31567,
24138309,40169,22138,22617,34532,38588,20276,21028,21322,21453,21467,24070,25644,
24226001,26495,27710,27726,29256,29359,29677,30036,32321,33324,34281,36009,31684,
24337318,29033,38930,39151,25405,26217,30058,30436,30928,34115,34542,21290,21329,
24421542,22915,24199,24444,24754,25161,25209,25259,26000,27604,27852,30130,30382,
24530865,31192,32203,32631,32933,34987,35513,36027,36991,38750,39131,27147,31800,
24620633,23614,24494,26503,27608,29749,30473,32654,40763,26570,31255,21305,30091,
24739661,24422,33181,33777,32920,24380,24517,30050,31558,36924,26727,23019,23195,
24832016,30334,35628,20469,24426,27161,27703,28418,29922,31080,34920,35413,35961,
24924287,25551,30149,31186,33495,37672,37618,33948,34541,39981,21697,24428,25996,
25027996,28693,36007,36051,38971,25935,29942,19981,20184,22496,22827,23142,23500,
25120904,24067,24220,24598,25206,25975,26023,26222,28014,29238,31526,33104,33178,
25233433,35676,36000,36070,36212,38428,38468,20398,25771,
25327494,33310,33889,34154,37096,23553,26963,39080,33914,34135,20239,21103,24489,
25424133,26381,31119,33145,35079,35206,28149,24343,25173,27832,20175,29289,39826,
25520998,21563,22132,22707,24996,25198,28954,22894,31881,31966,32027,38640,25991,
25632862,19993,20341,20853,22592,24163,24179,24330,26564,20006,34109,38281,38491,
25731859,38913,20731,22721,30294,30887,21029,30629,34065,31622,20559,22793,29255,
25831687,32232,36794,36820,36941,20415,21193,23081,24321,38829,20445,33303,37610,
25922275,25429,27497,29995,35036,36628,31298,21215,22675,24917,25098,26286,27597,
26031807,33769,20515,20472,21253,21574,22577,22857,23453,23792,23791,23849,24214,
26125265,25447,25918,26041,26379,27861,27873,28921,30770,32299,32990,33459,33804,
26234028,34562,35090,35370,35914,37030,37586,39165,40179,40300,20047,20129,20621,
26321078,22346,22952,24125,24536,24537,25151,26292,26395,26576,26834,20882,32033,
26432938,33192,35584,35980,36031,37502,38450,21536,38956,21271,20693,21340,22696,
26525778,26420,29287,30566,31302,37350,21187,27809,27526,22528,24140,22868,26412,
26632763,20961,30406,25705,30952,39764,40635,22475,22969,26151,26522,27598,21737,
26727097,24149,33180,26517,39850,26622,40018,26717,20134,20451,21448,25273,26411,
26827819,36804,20397,32365,40639,19975,24930,28288,28459,34067,21619,26410,39749,
26924051,31637,23724,23494,34588,28234,34001,31252,33032,22937,31885,27665,30496,
27021209,22818,28961,29279,30683,38695,40289,26891,23167,23064,20901,21517,21629,
27126126,30431,36855,37528,40180,23018,29277,28357,20813,26825,32191,32236,38754,
27240634,25720,27169,33538,22916,23391,27611,29467,30450,
27332178,32791,33945,20786,26408,40665,30446,26466,21247,39173,23588,25147,31870,
27436016,21839,24758,32011,38272,21249,20063,20918,22812,29242,32822,37326,24357,
27530690,21380,24441,32004,34220,35379,36493,38742,26611,34222,37971,24841,24840,
27627833,30290,35565,36664,21807,20305,20778,21191,21451,23461,24189,24736,24962,
27725558,26377,26586,28263,28044,29494,29495,30001,31056,35029,35480,36938,37009,
27837109,38596,34701,22805,20104,20313,19982,35465,36671,38928,20653,24188,22934,
27923481,24248,25562,25594,25793,26332,26954,27096,27915,28342,29076,29992,31407,
28032650,32768,33865,33993,35201,35617,36362,36965,38525,39178,24958,25233,27442,
28127779,28020,32716,32764,28096,32645,34746,35064,26469,33713,38972,38647,27931,
28232097,33853,37226,20081,21365,23888,27396,28651,34253,34349,35239,21033,21519,
28323653,26446,26792,29702,29827,30178,35023,35041,37324,38626,38520,24459,29575,
28431435,33870,25504,30053,21129,27969,28316,29705,30041,30827,31890,38534,31452,
28540845,20406,24942,26053,34396,20102,20142,20698,20001,20940,23534,26009,26753,
28628092,29471,30274,30637,31260,31975,33391,35538,36988,37327,38517,38936,21147,
28732209,20523,21400,26519,28107,29136,29747,33256,36650,38563,40023,40607,29792,
28822593,28057,32047,39006,20196,20278,20363,20919,21169,23994,24604,29618,31036,
28933491,37428,38583,38646,38666,40599,40802,26278,27508,21015,21155,28872,35010,
29024265,24651,24976,28451,29001,31806,32244,32879,34030,36899,37676,21570,39791,
29127347,28809,36034,36335,38706,21172,23105,24266,24324,26391,27004,27028,28010,
29228431,29282,29436,31725,32769,32894,34635,37070,20845,
29340595,31108,32907,37682,35542,20525,21644,35441,27498,36036,33031,24785,26528,
29440434,20121,20120,39952,35435,34241,34152,26880,28286,30871,33109,0,0,0,0,0,0,
2950,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
29624332,19984,19989,20010,20017,20022,20028,20031,20034,20054,20056,20098,20101,
29735947,20106,33298,24333,20110,20126,20127,20128,20130,20144,20147,20150,20174,
29820173,20164,20166,20162,20183,20190,20205,20191,20215,20233,20314,20272,20315,
29920317,20311,20295,20342,20360,20367,20376,20347,20329,20336,20369,20335,20358,
30020374,20760,20436,20447,20430,20440,20443,20433,20442,20432,20452,20453,20506,
30120520,20500,20522,20517,20485,20252,20470,20513,20521,20524,20478,20463,20497,
30220486,20547,20551,26371,20565,20560,20552,20570,20566,20588,20600,20608,20634,
30320613,20660,20658,20681,20682,20659,20674,20694,20702,20709,20717,20707,20718,
30420729,20725,20745,20737,20738,20758,20757,20756,20762,20769,20794,20791,20796,
30520795,20799,20800,20818,20812,20820,20834,31480,20841,20842,20846,20864,20866,
30622232,20876,20873,20879,20881,20883,20885,20886,20900,20902,20898,20905,20906,
30720907,20915,20913,20914,20912,20917,20925,20933,20937,20955,20960,34389,20969,
30820973,20976,20981,20990,20996,21003,21012,21006,21031,21034,21038,21043,21049,
30921071,21060,21067,21068,21086,21076,21098,21108,21097,21107,21119,21117,21133,
31021140,21138,21105,21128,21137,36776,36775,
31121164,21165,21180,21173,21185,21197,21207,21214,21219,21222,39149,21216,21235,
31221237,21240,21241,21254,21256,30008,21261,21264,21263,21269,21274,21283,21295,
31321297,21299,21304,21312,21318,21317,19991,21321,21325,20950,21342,21353,21358,
31422808,21371,21367,21378,21398,21408,21414,21413,21422,21424,21430,21443,31762,
31538617,21471,26364,29166,21486,21480,21485,21498,21505,21565,21568,21548,21549,
31621564,21550,21558,21545,21533,21582,21647,21621,21646,21599,21617,21623,21616,
31721650,21627,21632,21622,21636,21648,21638,21703,21666,21688,21669,21676,21700,
31821704,21672,21675,21698,21668,21694,21692,21720,21733,21734,21775,21780,21757,
31921742,21741,21754,21730,21817,21824,21859,21836,21806,21852,21829,21846,21847,
32021816,21811,21853,21913,21888,21679,21898,21919,21883,21886,21912,21918,21934,
32121884,21891,21929,21895,21928,21978,21957,21983,21956,21980,21988,21972,22036,
32222007,22038,22014,22013,22043,22009,22094,22096,29151,22068,22070,22066,22072,
32322123,22116,22063,22124,22122,22150,22144,22154,22176,22164,22159,22181,22190,
32422198,22196,22210,22204,22209,22211,22208,22216,22222,22225,22227,22231,22254,
32522265,22272,22271,22276,22281,22280,22283,22285,22291,22296,22294,21959,22300,
32622310,22327,22328,22350,22331,22336,22351,22377,22464,22408,22369,22399,22409,
32722419,22432,22451,22436,22442,22448,22467,22470,22484,22482,22483,22538,22486,
32822499,22539,22553,22557,22642,22561,22626,22603,22640,27584,22610,22589,22649,
32922661,22713,22687,22699,22714,22750,22715,22712,22702,22725,22739,22737,22743,
33022745,22744,22757,22748,22756,22751,22767,22778,22777,
33122779,22780,22781,22786,22794,22800,22811,26790,22821,22828,22829,22834,22840,
33222846,31442,22869,22864,22862,22874,22872,22882,22880,22887,22892,22889,22904,
33322913,22941,20318,20395,22947,22962,22982,23016,23004,22925,23001,23002,23077,
33423071,23057,23068,23049,23066,23104,23148,23113,23093,23094,23138,23146,23194,
33523228,23230,23243,23234,23229,23267,23255,23270,23273,23254,23290,23291,23308,
33623307,23318,23346,23248,23338,23350,23358,23363,23365,23360,23377,23381,23386,
33723387,23397,23401,23408,23411,23413,23416,25992,23418,23424,23427,23462,23480,
33823491,23495,23497,23508,23504,23524,23526,23522,23518,23525,23531,23536,23542,
33923539,23557,23559,23560,23565,23571,23584,23586,23592,23608,23609,23617,23622,
34023630,23635,23632,23631,23409,23660,23662,20066,23670,23673,23692,23697,23700,
34122939,23723,23739,23734,23740,23735,23749,23742,23751,23769,23785,23805,23802,
34223789,23948,23786,23819,23829,23831,23900,23839,23835,23825,23828,23842,23834,
34323833,23832,23884,23890,23886,23883,23916,23923,23926,23943,23940,23938,23970,
34423965,23980,23982,23997,23952,23991,23996,24009,24013,24019,24018,24022,24027,
34524043,24050,24053,24075,24090,24089,24081,24091,24118,24119,24132,24131,24128,
34624142,24151,24148,24159,24162,24164,24135,24181,24182,24186,40636,24191,24224,
34724257,24258,24264,24272,24271,24278,24291,24285,24282,24283,24290,24289,24296,
34824297,24300,24305,24307,24304,24308,24312,24318,24323,24329,24413,24412,24331,
34924337,24342,24361,24365,24376,24385,24392,24396,24398,24367,24401,24406,24407,
35024409,24417,24429,24435,24439,24451,24450,24447,24458,
35124456,24465,24455,24478,24473,24472,24480,24488,24493,24508,24534,24571,24548,
35224568,24561,24541,24755,24575,24609,24672,24601,24592,24617,24590,24625,24603,
35324597,24619,24614,24591,24634,24666,24641,24682,24695,24671,24650,24646,24653,
35424675,24643,24676,24642,24684,24683,24665,24705,24717,24807,24707,24730,24708,
35524731,24726,24727,24722,24743,24715,24801,24760,24800,24787,24756,24560,24765,
35624774,24757,24792,24909,24853,24838,24822,24823,24832,24820,24826,24835,24865,
35724827,24817,24845,24846,24903,24894,24872,24871,24906,24895,24892,24876,24884,
35824893,24898,24900,24947,24951,24920,24921,24922,24939,24948,24943,24933,24945,
35924927,24925,24915,24949,24985,24982,24967,25004,24980,24986,24970,24977,25003,
36025006,25036,25034,25033,25079,25032,25027,25030,25018,25035,32633,25037,25062,
36125059,25078,25082,25076,25087,25085,25084,25086,25088,25096,25097,25101,25100,
36225108,25115,25118,25121,25130,25134,25136,25138,25139,25153,25166,25182,25187,
36325179,25184,25192,25212,25218,25225,25214,25234,25235,25238,25300,25219,25236,
36425303,25297,25275,25295,25343,25286,25812,25288,25308,25292,25290,25282,25287,
36525243,25289,25356,25326,25329,25383,25346,25352,25327,25333,25424,25406,25421,
36625628,25423,25494,25486,25472,25515,25462,25507,25487,25481,25503,25525,25451,
36725449,25534,25577,25536,25542,25571,25545,25554,25590,25540,25622,25652,25606,
36825619,25638,25654,25885,25623,25640,25615,25703,25711,25718,25678,25898,25749,
36925747,25765,25769,25736,25788,25818,25810,25797,25799,25787,25816,25794,25841,
37025831,33289,25824,25825,25260,25827,25839,25900,25846,
37125844,25842,25850,25856,25853,25880,25884,25861,25892,25891,25899,25908,25909,
37225911,25910,25912,30027,25928,25942,25941,25933,25944,25950,25949,25970,25976,
37325986,25987,35722,26011,26015,26027,26039,26051,26054,26049,26052,26060,26066,
37426075,26073,26080,26081,26097,26482,26122,26115,26107,26483,26165,26166,26164,
37526140,26191,26180,26185,26177,26206,26205,26212,26215,26216,26207,26210,26224,
37626243,26248,26254,26249,26244,26264,26269,26305,26297,26313,26302,26300,26308,
37726296,26326,26330,26336,26175,26342,26345,26352,26357,26359,26383,26390,26398,
37826406,26407,38712,26414,26431,26422,26433,26424,26423,26438,26462,26464,26457,
37926467,26468,26505,26480,26537,26492,26474,26508,26507,26534,26529,26501,26551,
38026607,26548,26604,26547,26601,26552,26596,26590,26589,26594,26606,26553,26574,
38126566,26599,27292,26654,26694,26665,26688,26701,26674,26702,26803,26667,26713,
38226723,26743,26751,26783,26767,26797,26772,26781,26779,26755,27310,26809,26740,
38326805,26784,26810,26895,26765,26750,26881,26826,26888,26840,26914,26918,26849,
38426892,26829,26836,26855,26837,26934,26898,26884,26839,26851,26917,26873,26848,
38526863,26920,26922,26906,26915,26913,26822,27001,26999,26972,27000,26987,26964,
38627006,26990,26937,26996,26941,26969,26928,26977,26974,26973,27009,26986,27058,
38727054,27088,27071,27073,27091,27070,27086,23528,27082,27101,27067,27075,27047,
38827182,27025,27040,27036,27029,27060,27102,27112,27138,27163,27135,27402,27129,
38927122,27111,27141,27057,27166,27117,27156,27115,27146,27154,27329,27171,27155,
39027204,27148,27250,27190,27256,27207,27234,27225,27238,
39127208,27192,27170,27280,27277,27296,27268,27298,27299,27287,34327,27323,27331,
39227330,27320,27315,27308,27358,27345,27359,27306,27354,27370,27387,27397,34326,
39327386,27410,27414,39729,27423,27448,27447,30428,27449,39150,27463,27459,27465,
39427472,27481,27476,27483,27487,27489,27512,27513,27519,27520,27524,27523,27533,
39527544,27541,27550,27556,27562,27563,27567,27570,27569,27571,27575,27580,27590,
39627595,27603,27615,27628,27627,27635,27631,40638,27656,27667,27668,27675,27684,
39727683,27742,27733,27746,27754,27778,27789,27802,27777,27803,27774,27752,27763,
39827794,27792,27844,27889,27859,27837,27863,27845,27869,27822,27825,27838,27834,
39927867,27887,27865,27882,27935,34893,27958,27947,27965,27960,27929,27957,27955,
40027922,27916,28003,28051,28004,27994,28025,27993,28046,28053,28644,28037,28153,
40128181,28170,28085,28103,28134,28088,28102,28140,28126,28108,28136,28114,28101,
40228154,28121,28132,28117,28138,28142,28205,28270,28206,28185,28274,28255,28222,
40328195,28267,28203,28278,28237,28191,28227,28218,28238,28196,28415,28189,28216,
40428290,28330,28312,28361,28343,28371,28349,28335,28356,28338,28372,28373,28303,
40528325,28354,28319,28481,28433,28748,28396,28408,28414,28479,28402,28465,28399,
40628466,28364,28478,28435,28407,28550,28538,28536,28545,28544,28527,28507,28659,
40728525,28546,28540,28504,28558,28561,28610,28518,28595,28579,28577,28580,28601,
40828614,28586,28639,28629,28652,28628,28632,28657,28654,28635,28681,28683,28666,
40928689,28673,28687,28670,28699,28698,28532,28701,28696,28703,28720,28734,28722,
41028753,28771,28825,28818,28847,28913,28844,28856,28851,
41128846,28895,28875,28893,28889,28937,28925,28956,28953,29029,29013,29064,29030,
41229026,29004,29014,29036,29071,29179,29060,29077,29096,29100,29143,29113,29118,
41329138,29129,29140,29134,29152,29164,29159,29173,29180,29177,29183,29197,29200,
41429211,29224,29229,29228,29232,29234,29243,29244,29247,29248,29254,29259,29272,
41529300,29310,29314,29313,29319,29330,29334,29346,29351,29369,29362,29379,29382,
41629380,29390,29394,29410,29408,29409,29433,29431,20495,29463,29450,29468,29462,
41729469,29492,29487,29481,29477,29502,29518,29519,40664,29527,29546,29544,29552,
41829560,29557,29563,29562,29640,29619,29646,29627,29632,29669,29678,29662,29858,
41929701,29807,29733,29688,29746,29754,29781,29759,29791,29785,29761,29788,29801,
42029808,29795,29802,29814,29822,29835,29854,29863,29898,29903,29908,29681,29920,
42129923,29927,29929,29934,29938,29936,29937,29944,29943,29956,29955,29957,29964,
42229966,29965,29973,29971,29982,29990,29996,30012,30020,30029,30026,30025,30043,
42330022,30042,30057,30052,30055,30059,30061,30072,30070,30086,30087,30068,30090,
42430089,30082,30100,30106,30109,30117,30115,30146,30131,30147,30133,30141,30136,
42530140,30129,30157,30154,30162,30169,30179,30174,30206,30207,30204,30209,30192,
42630202,30194,30195,30219,30221,30217,30239,30247,30240,30241,30242,30244,30260,
42730256,30267,30279,30280,30278,30300,30296,30305,30306,30312,30313,30314,30311,
42830316,30320,30322,30326,30328,30332,30336,30339,30344,30347,30350,30358,30355,
42930361,30362,30384,30388,30392,30393,30394,30402,30413,30422,30418,30430,30433,
43030437,30439,30442,34351,30459,30472,30471,30468,30505,
43130500,30494,30501,30502,30491,30519,30520,30535,30554,30568,30571,30555,30565,
43230591,30590,30585,30606,30603,30609,30624,30622,30640,30646,30649,30655,30652,
43330653,30651,30663,30669,30679,30682,30684,30691,30702,30716,30732,30738,31014,
43430752,31018,30789,30862,30836,30854,30844,30874,30860,30883,30901,30890,30895,
43530929,30918,30923,30932,30910,30908,30917,30922,30956,30951,30938,30973,30964,
43630983,30994,30993,31001,31020,31019,31040,31072,31063,31071,31066,31061,31059,
43731098,31103,31114,31133,31143,40779,31146,31150,31155,31161,31162,31177,31189,
43831207,31212,31201,31203,31240,31245,31256,31257,31264,31263,31104,31281,31291,
43931294,31287,31299,31319,31305,31329,31330,31337,40861,31344,31353,31357,31368,
44031383,31381,31384,31382,31401,31432,31408,31414,31429,31428,31423,36995,31431,
44131434,31437,31439,31445,31443,31449,31450,31453,31457,31458,31462,31469,31472,
44231490,31503,31498,31494,31539,31512,31513,31518,31541,31528,31542,31568,31610,
44331492,31565,31499,31564,31557,31605,31589,31604,31591,31600,31601,31596,31598,
44431645,31640,31647,31629,31644,31642,31627,31634,31631,31581,31641,31691,31681,
44531692,31695,31668,31686,31709,31721,31761,31764,31718,31717,31840,31744,31751,
44631763,31731,31735,31767,31757,31734,31779,31783,31786,31775,31799,31787,31805,
44731820,31811,31828,31823,31808,31824,31832,31839,31844,31830,31845,31852,31861,
44831875,31888,31908,31917,31906,31915,31905,31912,31923,31922,31921,31918,31929,
44931933,31936,31941,31938,31960,31954,31964,31970,39739,31983,31986,31988,31990,
45031994,32006,32002,32028,32021,32010,32069,32075,32046,
45132050,32063,32053,32070,32115,32086,32078,32114,32104,32110,32079,32099,32147,
45232137,32091,32143,32125,32155,32186,32174,32163,32181,32199,32189,32171,32317,
45332162,32175,32220,32184,32159,32176,32216,32221,32228,32222,32251,32242,32225,
45432261,32266,32291,32289,32274,32305,32287,32265,32267,32290,32326,32358,32315,
45532309,32313,32323,32311,32306,32314,32359,32349,32342,32350,32345,32346,32377,
45632362,32361,32380,32379,32387,32213,32381,36782,32383,32392,32393,32396,32402,
45732400,32403,32404,32406,32398,32411,32412,32568,32570,32581,32588,32589,32590,
45832592,32593,32597,32596,32600,32607,32608,32616,32617,32615,32632,32642,32646,
45932643,32648,32647,32652,32660,32670,32669,32666,32675,32687,32690,32697,32686,
46032694,32696,35697,32709,32710,32714,32725,32724,32737,32742,32745,32755,32761,
46139132,32774,32772,32779,32786,32792,32793,32796,32801,32808,32831,32827,32842,
46232838,32850,32856,32858,32863,32866,32872,32883,32882,32880,32886,32889,32893,
46332895,32900,32902,32901,32923,32915,32922,32941,20880,32940,32987,32997,32985,
46432989,32964,32986,32982,33033,33007,33009,33051,33065,33059,33071,33099,38539,
46533094,33086,33107,33105,33020,33137,33134,33125,33126,33140,33155,33160,33162,
46633152,33154,33184,33173,33188,33187,33119,33171,33193,33200,33205,33214,33208,
46733213,33216,33218,33210,33225,33229,33233,33241,33240,33224,33242,33247,33248,
46833255,33274,33275,33278,33281,33282,33285,33287,33290,33293,33296,33302,33321,
46933323,33336,33331,33344,33369,33368,33373,33370,33375,33380,33378,33384,33386,
47033387,33326,33393,33399,33400,33406,33421,33426,33451,
47133439,33467,33452,33505,33507,33503,33490,33524,33523,33530,33683,33539,33531,
47233529,33502,33542,33500,33545,33497,33589,33588,33558,33586,33585,33600,33593,
47333616,33605,33583,33579,33559,33560,33669,33690,33706,33695,33698,33686,33571,
47433678,33671,33674,33660,33717,33651,33653,33696,33673,33704,33780,33811,33771,
47533742,33789,33795,33752,33803,33729,33783,33799,33760,33778,33805,33826,33824,
47633725,33848,34054,33787,33901,33834,33852,34138,33924,33911,33899,33965,33902,
47733922,33897,33862,33836,33903,33913,33845,33994,33890,33977,33983,33951,34009,
47833997,33979,34010,34000,33985,33990,34006,33953,34081,34047,34036,34071,34072,
47934092,34079,34069,34068,34044,34112,34147,34136,34120,34113,34306,34123,34133,
48034176,34212,34184,34193,34186,34216,34157,34196,34203,34282,34183,34204,34167,
48134174,34192,34249,34234,34255,34233,34256,34261,34269,34277,34268,34297,34314,
48234323,34315,34302,34298,34310,34338,34330,34352,34367,34381,20053,34388,34399,
48334407,34417,34451,34467,34473,34474,34443,34444,34486,34479,34500,34502,34480,
48434505,34851,34475,34516,34526,34537,34540,34527,34523,34543,34578,34566,34568,
48534560,34563,34555,34577,34569,34573,34553,34570,34612,34623,34615,34619,34597,
48634601,34586,34656,34655,34680,34636,34638,34676,34647,34664,34670,34649,34643,
48734659,34666,34821,34722,34719,34690,34735,34763,34749,34752,34768,38614,34731,
48834756,34739,34759,34758,34747,34799,34802,34784,34831,34829,34814,34806,34807,
48934830,34770,34833,34838,34837,34850,34849,34865,34870,34873,34855,34875,34884,
49034882,34898,34905,34910,34914,34923,34945,34942,34974,
49134933,34941,34997,34930,34946,34967,34962,34990,34969,34978,34957,34980,34992,
49235007,34993,35011,35012,35028,35032,35033,35037,35065,35074,35068,35060,35048,
49335058,35076,35084,35082,35091,35139,35102,35109,35114,35115,35137,35140,35131,
49435126,35128,35148,35101,35168,35166,35174,35172,35181,35178,35183,35188,35191,
49535198,35203,35208,35210,35219,35224,35233,35241,35238,35244,35247,35250,35258,
49635261,35263,35264,35290,35292,35293,35303,35316,35320,35331,35350,35344,35340,
49735355,35357,35365,35382,35393,35419,35410,35398,35400,35452,35437,35436,35426,
49835461,35458,35460,35496,35489,35473,35493,35494,35482,35491,35524,35533,35522,
49935546,35563,35571,35559,35556,35569,35604,35552,35554,35575,35550,35547,35596,
50035591,35610,35553,35606,35600,35607,35616,35635,38827,35622,35627,35646,35624,
50135649,35660,35663,35662,35657,35670,35675,35674,35691,35679,35692,35695,35700,
50235709,35712,35724,35726,35730,35731,35734,35737,35738,35898,35905,35903,35912,
50335916,35918,35920,35925,35938,35948,35960,35962,35970,35977,35973,35978,35981,
50435982,35988,35964,35992,25117,36013,36010,36029,36018,36019,36014,36022,36040,
50536033,36068,36067,36058,36093,36090,36091,36100,36101,36106,36103,36111,36109,
50636112,40782,36115,36045,36116,36118,36199,36205,36209,36211,36225,36249,36290,
50736286,36282,36303,36314,36310,36300,36315,36299,36330,36331,36319,36323,36348,
50836360,36361,36351,36381,36382,36368,36383,36418,36405,36400,36404,36426,36423,
50936425,36428,36432,36424,36441,36452,36448,36394,36451,36437,36470,36466,36476,
51036481,36487,36485,36484,36491,36490,36499,36497,36500,
51136505,36522,36513,36524,36528,36550,36529,36542,36549,36552,36555,36571,36579,
51236604,36603,36587,36606,36618,36613,36629,36626,36633,36627,36636,36639,36635,
51336620,36646,36659,36667,36665,36677,36674,36670,36684,36681,36678,36686,36695,
51436700,36706,36707,36708,36764,36767,36771,36781,36783,36791,36826,36837,36834,
51536842,36847,36999,36852,36869,36857,36858,36881,36885,36897,36877,36894,36886,
51636875,36903,36918,36917,36921,36856,36943,36944,36945,36946,36878,36937,36926,
51736950,36952,36958,36968,36975,36982,38568,36978,36994,36989,36993,36992,37002,
51837001,37007,37032,37039,37041,37045,37090,37092,25160,37083,37122,37138,37145,
51937170,37168,37194,37206,37208,37219,37221,37225,37235,37234,37259,37257,37250,
52037282,37291,37295,37290,37301,37300,37306,37312,37313,37321,37323,37328,37334,
52137343,37345,37339,37372,37365,37366,37406,37375,37396,37420,37397,37393,37470,
52237463,37445,37449,37476,37448,37525,37439,37451,37456,37532,37526,37523,37531,
52337466,37583,37561,37559,37609,37647,37626,37700,37678,37657,37666,37658,37667,
52437690,37685,37691,37724,37728,37756,37742,37718,37808,37804,37805,37780,37817,
52537846,37847,37864,37861,37848,37827,37853,37840,37832,37860,37914,37908,37907,
52637891,37895,37904,37942,37931,37941,37921,37946,37953,37970,37956,37979,37984,
52737986,37982,37994,37417,38000,38005,38007,38013,37978,38012,38014,38017,38015,
52838274,38279,38282,38292,38294,38296,38297,38304,38312,38311,38317,38332,38331,
52938329,38334,38346,28662,38339,38349,38348,38357,38356,38358,38364,38369,38373,
53038370,38433,38440,38446,38447,38466,38476,38479,38475,
53138519,38492,38494,38493,38495,38502,38514,38508,38541,38552,38549,38551,38570,
53238567,38577,38578,38576,38580,38582,38584,38585,38606,38603,38601,38605,35149,
53338620,38669,38613,38649,38660,38662,38664,38675,38670,38673,38671,38678,38681,
53438692,38698,38704,38713,38717,38718,38724,38726,38728,38722,38729,38748,38752,
53538756,38758,38760,21202,38763,38769,38777,38789,38780,38785,38778,38790,38795,
53638799,38800,38812,38824,38822,38819,38835,38836,38851,38854,38856,38859,38876,
53738893,40783,38898,31455,38902,38901,38927,38924,38968,38948,38945,38967,38973,
53838982,38991,38987,39019,39023,39024,39025,39028,39027,39082,39087,39089,39094,
53939108,39107,39110,39145,39147,39171,39177,39186,39188,39192,39201,39197,39198,
54039204,39200,39212,39214,39229,39230,39234,39241,39237,39248,39243,39249,39250,
54139244,39253,39319,39320,39333,39341,39342,39356,39391,39387,39389,39384,39377,
54239405,39406,39409,39410,39419,39416,39425,39439,39429,39394,39449,39467,39479,
54339493,39490,39488,39491,39486,39509,39501,39515,39511,39519,39522,39525,39524,
54439529,39531,39530,39597,39600,39612,39616,39631,39633,39635,39636,39646,39647,
54539650,39651,39654,39663,39659,39662,39668,39665,39671,39675,39686,39704,39706,
54639711,39714,39715,39717,39719,39720,39721,39722,39726,39727,39730,39748,39747,
54739759,39757,39758,39761,39768,39796,39827,39811,39825,39830,39831,39839,39840,
54839848,39860,39872,39882,39865,39878,39887,39889,39890,39907,39906,39908,39892,
54939905,39994,39922,39921,39920,39957,39956,39945,39955,39948,39942,39944,39954,
55039946,39940,39982,39963,39973,39972,39969,39984,40007,
55139986,40006,39998,40026,40032,40039,40054,40056,40167,40172,40176,40201,40200,
55240171,40195,40198,40234,40230,40367,40227,40223,40260,40213,40210,40257,40255,
55340254,40262,40264,40285,40286,40292,40273,40272,40281,40306,40329,40327,40363,
55440303,40314,40346,40356,40361,40370,40388,40385,40379,40376,40378,40390,40399,
55540386,40409,40403,40440,40422,40429,40431,40445,40474,40475,40478,40565,40569,
55640573,40577,40584,40587,40588,40594,40597,40593,40605,40613,40617,40632,40618,
55740621,38753,40652,40654,40655,40656,40660,40668,40670,40669,40672,40677,40680,
55840687,40692,40694,40695,40697,40699,40700,40701,40711,40712,30391,40725,40737,
55940748,40766,40778,40786,40788,40803,40799,40800,40801,40806,40807,40812,40810,
56040823,40818,40822,40853,40860,40864,22575,27079,36953,29796,20956,29081,0,0,0,
5610,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5620,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
5630,0,0,0,0,0,0,
libc/musl/src/locale/ksc.h created+650
......@@ -0,0 +1,650 @@
112288,12289,12290,183,8229,8230,168,12291,173,8213,8741,65340,8764,8216,8217,
28220,8221,12308,12309,12296,12297,12298,12299,12300,12301,12302,12303,12304,
312305,177,215,247,8800,8804,8805,8734,8756,176,8242,8243,8451,8491,65504,
465505,65509,9794,9792,8736,8869,8978,8706,8711,8801,8786,167,8251,9734,9733,
59675,9679,9678,9671,9670,9633,9632,9651,9650,9661,9660,8594,8592,8593,8595,
68596,12307,8810,8811,8730,8765,8733,8757,8747,8748,8712,8715,8838,8839,8834,
78835,8746,8745,8743,8744,65506,8658,8660,8704,8707,180,65374,711,728,733,730,
8729,184,731,161,191,720,8750,8721,8719,164,8457,8240,9665,9664,9655,9654,9828,
99824,9825,9829,9831,9827,8857,9672,9635,9680,9681,9618,9636,9637,9640,9639,
109638,9641,9832,9743,9742,9756,9758,182,8224,8225,8597,8599,8601,8598,8600,
119837,9833,9834,9836,12927,12828,8470,13255,8482,13250,13272,8481,8364,174,0,0,
120,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,65281,65282,65283,65284,65285,65286,
1365287,65288,65289,65290,65291,65292,65293,65294,65295,65296,65297,65298,65299,
1465300,65301,65302,65303,65304,65305,65306,65307,65308,65309,65310,65311,65312,
1565313,65314,65315,65316,65317,65318,65319,65320,65321,65322,65323,65324,65325,
1665326,65327,65328,65329,65330,65331,65332,65333,65334,65335,65336,65337,65338,
1765339,65510,65341,65342,65343,65344,65345,65346,65347,
1865348,65349,65350,65351,65352,65353,65354,65355,65356,65357,65358,65359,65360,
1965361,65362,65363,65364,65365,65366,65367,65368,65369,65370,65371,65372,65373,
2065507,12593,12594,12595,12596,12597,12598,12599,12600,12601,12602,12603,12604,
2112605,12606,12607,12608,12609,12610,12611,12612,12613,12614,12615,12616,12617,
2212618,12619,12620,12621,12622,12623,12624,12625,12626,12627,12628,12629,12630,
2312631,12632,12633,12634,12635,12636,12637,12638,12639,12640,12641,12642,12643,
2412644,12645,12646,12647,12648,12649,12650,12651,12652,12653,12654,12655,12656,
2512657,12658,12659,12660,12661,12662,12663,12664,12665,12666,12667,12668,12669,
2612670,12671,12672,12673,12674,12675,12676,12677,12678,12679,12680,12681,12682,
2712683,12684,12685,12686,8560,8561,8562,8563,8564,8565,8566,8567,8568,8569,0,0,
280,0,0,8544,8545,8546,8547,8548,8549,8550,8551,8552,8553,0,0,0,0,0,0,0,913,914,
29915,916,917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,
30935,936,937,0,0,0,0,0,0,0,0,945,946,947,948,949,950,951,952,953,954,955,956,
31957,958,959,960,961,963,964,965,966,967,968,969,0,0,0,0,0,0,9472,9474,9484,
329488,9496,9492,9500,9516,9508,9524,9532,9473,9475,9487,9491,9499,9495,9507,
339523,9515,9531,9547,9504,9519,9512,9527,9535,9501,9520,9509,9528,9538,9490,
349489,9498,9497,9494,9493,9486,9485,9502,
359503,9505,9506,9510,9511,9513,9514,9517,9518,9521,9522,9525,9526,9529,9530,
369533,9534,9536,9537,9539,9540,9541,9542,9543,9544,9545,9546,0,0,0,0,0,0,0,0,0,
370,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13205,13206,13207,8467,13208,13252,13219,
3813220,13221,13222,13209,13210,13211,13212,13213,13214,13215,13216,13217,13218,
3913258,13197,13198,13199,13263,13192,13193,13256,13223,13224,13232,13233,13234,
4013235,13236,13237,13238,13239,13240,13241,13184,13185,13186,13187,13188,13242,
4113243,13244,13245,13246,13247,13200,13201,13202,13203,13204,8486,13248,13249,
4213194,13195,13196,13270,13253,13229,13230,13231,13275,13225,13226,13227,13228,
4313277,13264,13267,13251,13257,13276,13254,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,198,
44208,170,294,0,306,0,319,321,216,338,186,222,358,330,0,12896,12897,12898,12899,
4512900,12901,12902,12903,12904,12905,12906,12907,12908,12909,12910,12911,12912,
4612913,12914,12915,12916,12917,12918,12919,12920,12921,12922,12923,9424,9425,
479426,9427,9428,9429,9430,9431,9432,9433,9434,9435,9436,9437,9438,9439,9440,
489441,9442,9443,9444,9445,9446,9447,9448,9449,9312,9313,9314,9315,9316,9317,
499318,9319,9320,9321,9322,9323,9324,9325,9326,189,8531,8532,188,190,8539,8540,
508541,8542,230,273,240,295,305,307,312,320,322,248,339,223,254,359,331,
51329,12800,12801,12802,12803,12804,12805,12806,12807,12808,12809,12810,12811,
5212812,12813,12814,12815,12816,12817,12818,12819,12820,12821,12822,12823,12824,
5312825,12826,12827,9372,9373,9374,9375,9376,9377,9378,9379,9380,9381,9382,9383,
549384,9385,9386,9387,9388,9389,9390,9391,9392,9393,9394,9395,9396,9397,9332,
559333,9334,9335,9336,9337,9338,9339,9340,9341,9342,9343,9344,9345,9346,185,178,
56179,8308,8319,8321,8322,8323,8324,12353,12354,12355,12356,12357,12358,12359,
5712360,12361,12362,12363,12364,12365,12366,12367,12368,12369,12370,12371,12372,
5812373,12374,12375,12376,12377,12378,12379,12380,12381,12382,12383,12384,12385,
5912386,12387,12388,12389,12390,12391,12392,12393,12394,12395,12396,12397,12398,
6012399,12400,12401,12402,12403,12404,12405,12406,12407,12408,12409,12410,12411,
6112412,12413,12414,12415,12416,12417,12418,12419,12420,12421,12422,12423,12424,
6212425,12426,12427,12428,12429,12430,12431,12432,12433,12434,12435,0,0,0,0,0,0,
630,0,0,0,0,12449,12450,12451,12452,12453,12454,12455,12456,12457,12458,12459,
6412460,12461,12462,12463,12464,12465,12466,12467,12468,12469,12470,12471,12472,
6512473,12474,12475,12476,12477,12478,12479,12480,12481,12482,12483,12484,12485,
6612486,12487,12488,12489,12490,12491,12492,12493,12494,12495,12496,12497,12498,
6712499,12500,12501,12502,12503,12504,12505,12506,12507,12508,12509,12510,12511,
6812512,12513,12514,12515,12516,12517,12518,12519,12520,12521,12522,12523,12524,
6912525,12526,12527,12528,12529,12530,12531,
7012532,12533,12534,0,0,0,0,0,0,0,0,1040,1041,1042,1043,1044,1045,1025,1046,
711047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,1061,
721062,1063,1064,1065,1066,1067,1068,1069,1070,1071,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
730,1072,1073,1074,1075,1076,1077,1105,1078,1079,1080,1081,1082,1083,1084,1085,
741086,1087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,
751101,1102,1103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
760,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
770,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
780,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
790,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
800,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
810,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
820,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
830,0,0,0,0,0,0,0,0,0,0,0,0,0,44032,44033,44036,44039,44040,44041,44042,44048,
8444049,44050,44051,44052,44053,44054,44055,44057,44058,44059,44060,44061,44064,
8544068,44076,44077,44079,44080,44081,44088,44089,44092,44096,44107,44109,44116,
8644120,44124,44144,44145,44148,44151,44152,44154,44160,44161,44163,44164,44165,
8744166,44169,44170,44171,44172,44176,44180,44188,44189,44191,44192,44193,44200,
8844201,44202,44204,44207,44208,44216,44217,44219,44220,44221,44225,44228,44232,
8944236,44245,44247,44256,44257,44260,44263,44264,44266,44268,44271,44272,44273,
9044275,44277,44278,44284,44285,44288,44292,44294,44300,44301,44303,44305,44312,
9144316,44320,44329,44332,44333,44340,44341,44344,44348,44356,44357,44359,44361,
9244368,44372,44376,44385,44387,44396,44397,44400,44403,44404,44405,44406,44411,
9344412,44413,44415,44417,44418,44424,44425,44428,44432,44444,44445,44452,44471,
9444480,44481,44484,44488,44496,44497,44499,44508,44512,44516,44536,44537,44540,
9544543,44544,44545,44552,44553,44555,44557,44564,44592,44593,44596,44599,44600,
9644602,44608,44609,44611,44613,44614,44618,44620,44621,44622,44624,44628,44630,
9744636,44637,44639,44640,44641,44645,44648,44649,44652,44656,44664,44665,44667,
9844668,44669,44676,44677,44684,44732,44733,44734,44736,44740,44748,44749,44751,
9944752,44753,44760,44761,44764,44776,44779,44781,44788,44792,44796,44807,44808,
10044813,44816,44844,44845,44848,44850,44852,44860,44861,44863,44865,44866,44867,
10144872,44873,44880,44892,44893,44900,44901,44921,44928,44932,44936,44944,44945,
10244949,44956,44984,44985,44988,44992,44999,45000,45001,45003,45005,45006,45012,
10345020,45032,45033,45040,45041,45044,45048,45056,45057,45060,45068,45072,45076,
10445084,45085,45096,45124,45125,45128,45130,45132,45134,45139,45140,45141,45143,
10545145,45149,45180,45181,45184,45188,45196,45197,45199,45201,45208,45209,45210,
10645212,45215,45216,45217,45218,45224,45225,45227,45228,45229,45230,45231,45233,
10745235,45236,45237,45240,45244,45252,45253,45255,45256,45257,45264,45265,45268,
10845272,45280,45285,45320,45321,45323,45324,45328,45330,45331,45336,45337,45339,
10945340,45341,45347,45348,45349,45352,45356,45364,45365,45367,45368,45369,45376,
11045377,45380,45384,45392,45393,45396,45397,45400,45404,45408,45432,45433,45436,
11145440,45442,45448,45449,45451,45453,45458,45459,45460,45464,45468,45480,45516,
11245520,45524,45532,45533,45535,45544,45545,45548,45552,
11345561,45563,45565,45572,45573,45576,45579,45580,45588,45589,45591,45593,45600,
11445620,45628,45656,45660,45664,45672,45673,45684,45685,45692,45700,45701,45705,
11545712,45713,45716,45720,45721,45722,45728,45729,45731,45733,45734,45738,45740,
11645744,45748,45768,45769,45772,45776,45778,45784,45785,45787,45789,45794,45796,
11745797,45798,45800,45803,45804,45805,45806,45807,45811,45812,45813,45815,45816,
11845817,45818,45819,45823,45824,45825,45828,45832,45840,45841,45843,45844,45845,
11945852,45908,45909,45910,45912,45915,45916,45918,45919,45924,45925,45927,45929,
12045931,45934,45936,45937,45940,45944,45952,45953,45955,45956,45957,45964,45968,
12145972,45984,45985,45992,45996,46020,46021,46024,46027,46028,46030,46032,46036,
12246037,46039,46041,46043,46045,46048,46052,46056,46076,46096,46104,46108,46112,
12346120,46121,46123,46132,46160,46161,46164,46168,46176,46177,46179,46181,46188,
12446208,46216,46237,46244,46248,46252,46261,46263,46265,46272,46276,46280,46288,
12546293,46300,46301,46304,46307,46308,46310,46316,46317,46319,46321,46328,46356,
12646357,46360,46363,46364,46372,46373,46375,46376,46377,46378,46384,46385,46388,
12746392,46400,46401,46403,46404,46405,46411,46412,46413,46416,46420,46428,46429,
12846431,46432,46433,46496,46497,46500,46504,46506,46507,46512,46513,46515,46516,
12946517,46523,46524,46525,46528,46532,46540,46541,46543,46544,46545,46552,46572,
13046608,46609,46612,46616,46629,46636,46644,46664,46692,46696,46748,46749,46752,
13146756,46763,46764,46769,46804,46832,46836,46840,46848,46849,46853,46888,46889,
13246892,46895,46896,46904,46905,46907,46916,46920,46924,
13346932,46933,46944,46948,46952,46960,46961,46963,46965,46972,46973,46976,46980,
13446988,46989,46991,46992,46993,46994,46998,46999,47000,47001,47004,47008,47016,
13547017,47019,47020,47021,47028,47029,47032,47047,47049,47084,47085,47088,47092,
13647100,47101,47103,47104,47105,47111,47112,47113,47116,47120,47128,47129,47131,
13747133,47140,47141,47144,47148,47156,47157,47159,47160,47161,47168,47172,47185,
13847187,47196,47197,47200,47204,47212,47213,47215,47217,47224,47228,47245,47272,
13947280,47284,47288,47296,47297,47299,47301,47308,47312,47316,47325,47327,47329,
14047336,47337,47340,47344,47352,47353,47355,47357,47364,47384,47392,47420,47421,
14147424,47428,47436,47439,47441,47448,47449,47452,47456,47464,47465,47467,47469,
14247476,47477,47480,47484,47492,47493,47495,47497,47498,47501,47502,47532,47533,
14347536,47540,47548,47549,47551,47553,47560,47561,47564,47566,47567,47568,47569,
14447570,47576,47577,47579,47581,47582,47585,47587,47588,47589,47592,47596,47604,
14547605,47607,47608,47609,47610,47616,47617,47624,47637,47672,47673,47676,47680,
14647682,47688,47689,47691,47693,47694,47699,47700,47701,47704,47708,47716,47717,
14747719,47720,47721,47728,47729,47732,47736,47747,47748,47749,47751,47756,47784,
14847785,47787,47788,47792,47794,47800,47801,47803,47805,47812,47816,47832,47833,
14947868,47872,47876,47885,47887,47889,47896,47900,47904,47913,47915,47924,47925,
15047926,47928,47931,47932,47933,47934,47940,47941,47943,47945,47949,47951,47952,
15147956,47960,47969,47971,47980,48008,48012,48016,48036,48040,48044,48052,48055,
15248064,48068,48072,48080,48083,48120,48121,48124,48127,
15348128,48130,48136,48137,48139,48140,48141,48143,48145,48148,48149,48150,48151,
15448152,48155,48156,48157,48158,48159,48164,48165,48167,48169,48173,48176,48177,
15548180,48184,48192,48193,48195,48196,48197,48201,48204,48205,48208,48221,48260,
15648261,48264,48267,48268,48270,48276,48277,48279,48281,48282,48288,48289,48292,
15748295,48296,48304,48305,48307,48308,48309,48316,48317,48320,48324,48333,48335,
15848336,48337,48341,48344,48348,48372,48373,48374,48376,48380,48388,48389,48391,
15948393,48400,48404,48420,48428,48448,48456,48457,48460,48464,48472,48473,48484,
16048488,48512,48513,48516,48519,48520,48521,48522,48528,48529,48531,48533,48537,
16148538,48540,48548,48560,48568,48596,48597,48600,48604,48617,48624,48628,48632,
16248640,48643,48645,48652,48653,48656,48660,48668,48669,48671,48708,48709,48712,
16348716,48718,48724,48725,48727,48729,48730,48731,48736,48737,48740,48744,48746,
16448752,48753,48755,48756,48757,48763,48764,48765,48768,48772,48780,48781,48783,
16548784,48785,48792,48793,48808,48848,48849,48852,48855,48856,48864,48867,48868,
16648869,48876,48897,48904,48905,48920,48921,48923,48924,48925,48960,48961,48964,
16748968,48976,48977,48981,49044,49072,49093,49100,49101,49104,49108,49116,49119,
16849121,49212,49233,49240,49244,49248,49256,49257,49296,49297,49300,49304,49312,
16949313,49315,49317,49324,49325,49327,49328,49331,49332,49333,49334,49340,49341,
17049343,49344,49345,49349,49352,49353,49356,49360,49368,49369,49371,49372,49373,
17149380,49381,49384,49388,49396,49397,49399,49401,49408,49412,49416,49424,49429,
17249436,49437,49438,49439,49440,49443,49444,49446,49447,
17349452,49453,49455,49456,49457,49462,49464,49465,49468,49472,49480,49481,49483,
17449484,49485,49492,49493,49496,49500,49508,49509,49511,49512,49513,49520,49524,
17549528,49541,49548,49549,49550,49552,49556,49558,49564,49565,49567,49569,49573,
17649576,49577,49580,49584,49597,49604,49608,49612,49620,49623,49624,49632,49636,
17749640,49648,49649,49651,49660,49661,49664,49668,49676,49677,49679,49681,49688,
17849689,49692,49695,49696,49704,49705,49707,49709,49711,49713,49714,49716,49736,
17949744,49745,49748,49752,49760,49765,49772,49773,49776,49780,49788,49789,49791,
18049793,49800,49801,49808,49816,49819,49821,49828,49829,49832,49836,49837,49844,
18149845,49847,49849,49884,49885,49888,49891,49892,49899,49900,49901,49903,49905,
18249910,49912,49913,49915,49916,49920,49928,49929,49932,49933,49939,49940,49941,
18349944,49948,49956,49957,49960,49961,49989,50024,50025,50028,50032,50034,50040,
18450041,50044,50045,50052,50056,50060,50112,50136,50137,50140,50143,50144,50146,
18550152,50153,50157,50164,50165,50168,50184,50192,50212,50220,50224,50228,50236,
18650237,50248,50276,50277,50280,50284,50292,50293,50297,50304,50324,50332,50360,
18750364,50409,50416,50417,50420,50424,50426,50431,50432,50433,50444,50448,50452,
18850460,50472,50473,50476,50480,50488,50489,50491,50493,50500,50501,50504,50505,
18950506,50508,50509,50510,50515,50516,50517,50519,50520,50521,50525,50526,50528,
19050529,50532,50536,50544,50545,50547,50548,50549,50556,50557,50560,50564,50567,
19150572,50573,50575,50577,50581,50583,50584,50588,50592,50601,50612,50613,50616,
19250617,50619,50620,50621,50622,50628,50629,50630,50631,
19350632,50633,50634,50636,50638,50640,50641,50644,50648,50656,50657,50659,50661,
19450668,50669,50670,50672,50676,50678,50679,50684,50685,50686,50687,50688,50689,
19550693,50694,50695,50696,50700,50704,50712,50713,50715,50716,50724,50725,50728,
19650732,50733,50734,50736,50739,50740,50741,50743,50745,50747,50752,50753,50756,
19750760,50768,50769,50771,50772,50773,50780,50781,50784,50796,50799,50801,50808,
19850809,50812,50816,50824,50825,50827,50829,50836,50837,50840,50844,50852,50853,
19950855,50857,50864,50865,50868,50872,50873,50874,50880,50881,50883,50885,50892,
20050893,50896,50900,50908,50909,50912,50913,50920,50921,50924,50928,50936,50937,
20150941,50948,50949,50952,50956,50964,50965,50967,50969,50976,50977,50980,50984,
20250992,50993,50995,50997,50999,51004,51005,51008,51012,51018,51020,51021,51023,
20351025,51026,51027,51028,51029,51030,51031,51032,51036,51040,51048,51051,51060,
20451061,51064,51068,51069,51070,51075,51076,51077,51079,51080,51081,51082,51086,
20551088,51089,51092,51094,51095,51096,51098,51104,51105,51107,51108,51109,51110,
20651116,51117,51120,51124,51132,51133,51135,51136,51137,51144,51145,51148,51150,
20751152,51160,51165,51172,51176,51180,51200,51201,51204,51208,51210,51216,51217,
20851219,51221,51222,51228,51229,51232,51236,51244,51245,51247,51249,51256,51260,
20951264,51272,51273,51276,51277,51284,51312,51313,51316,51320,51322,51328,51329,
21051331,51333,51334,51335,51339,51340,51341,51348,51357,51359,51361,51368,51388,
21151389,51396,51400,51404,51412,51413,51415,51417,51424,51425,51428,51445,51452,
21251453,51456,51460,51461,51462,51468,51469,51471,51473,
21351480,51500,51508,51536,51537,51540,51544,51552,51553,51555,51564,51568,51572,
21451580,51592,51593,51596,51600,51608,51609,51611,51613,51648,51649,51652,51655,
21551656,51658,51664,51665,51667,51669,51670,51673,51674,51676,51677,51680,51682,
21651684,51687,51692,51693,51695,51696,51697,51704,51705,51708,51712,51720,51721,
21751723,51724,51725,51732,51736,51753,51788,51789,51792,51796,51804,51805,51807,
21851808,51809,51816,51837,51844,51864,51900,51901,51904,51908,51916,51917,51919,
21951921,51923,51928,51929,51936,51948,51956,51976,51984,51988,51992,52000,52001,
22052033,52040,52041,52044,52048,52056,52057,52061,52068,52088,52089,52124,52152,
22152180,52196,52199,52201,52236,52237,52240,52244,52252,52253,52257,52258,52263,
22252264,52265,52268,52270,52272,52280,52281,52283,52284,52285,52286,52292,52293,
22352296,52300,52308,52309,52311,52312,52313,52320,52324,52326,52328,52336,52341,
22452376,52377,52380,52384,52392,52393,52395,52396,52397,52404,52405,52408,52412,
22552420,52421,52423,52425,52432,52436,52452,52460,52464,52481,52488,52489,52492,
22652496,52504,52505,52507,52509,52516,52520,52524,52537,52572,52576,52580,52588,
22752589,52591,52593,52600,52616,52628,52629,52632,52636,52644,52645,52647,52649,
22852656,52676,52684,52688,52712,52716,52720,52728,52729,52731,52733,52740,52744,
22952748,52756,52761,52768,52769,52772,52776,52784,52785,52787,52789,52824,52825,
23052828,52831,52832,52833,52840,52841,52843,52845,52852,52853,52856,52860,52868,
23152869,52871,52873,52880,52881,52884,52888,52896,52897,52899,52900,52901,52908,
23252909,52929,52964,52965,52968,52971,52972,52980,52981,
23352983,52984,52985,52992,52993,52996,53000,53008,53009,53011,53013,53020,53024,
23453028,53036,53037,53039,53040,53041,53048,53076,53077,53080,53084,53092,53093,
23553095,53097,53104,53105,53108,53112,53120,53125,53132,53153,53160,53168,53188,
23653216,53217,53220,53224,53232,53233,53235,53237,53244,53248,53252,53265,53272,
23753293,53300,53301,53304,53308,53316,53317,53319,53321,53328,53332,53336,53344,
23853356,53357,53360,53364,53372,53373,53377,53412,53413,53416,53420,53428,53429,
23953431,53433,53440,53441,53444,53448,53449,53456,53457,53459,53460,53461,53468,
24053469,53472,53476,53484,53485,53487,53488,53489,53496,53517,53552,53553,53556,
24153560,53562,53568,53569,53571,53572,53573,53580,53581,53584,53588,53596,53597,
24253599,53601,53608,53612,53628,53636,53640,53664,53665,53668,53672,53680,53681,
24353683,53685,53690,53692,53696,53720,53748,53752,53767,53769,53776,53804,53805,
24453808,53812,53820,53821,53823,53825,53832,53852,53860,53888,53889,53892,53896,
24553904,53905,53909,53916,53920,53924,53932,53937,53944,53945,53948,53951,53952,
24653954,53960,53961,53963,53972,53976,53980,53988,53989,54000,54001,54004,54008,
24754016,54017,54019,54021,54028,54029,54030,54032,54036,54038,54044,54045,54047,
24854048,54049,54053,54056,54057,54060,54064,54072,54073,54075,54076,54077,54084,
24954085,54140,54141,54144,54148,54156,54157,54159,54160,54161,54168,54169,54172,
25054176,54184,54185,54187,54189,54196,54200,54204,54212,54213,54216,54217,54224,
25154232,54241,54243,54252,54253,54256,54260,54268,54269,54271,54273,54280,54301,
25254336,54340,54364,54368,54372,54381,54383,54392,54393,
25354396,54399,54400,54402,54408,54409,54411,54413,54420,54441,54476,54480,54484,
25454492,54495,54504,54508,54512,54520,54523,54525,54532,54536,54540,54548,54549,
25554551,54588,54589,54592,54596,54604,54605,54607,54609,54616,54617,54620,54624,
25654629,54632,54633,54635,54637,54644,54645,54648,54652,54660,54661,54663,54664,
25754665,54672,54693,54728,54729,54732,54736,54738,54744,54745,54747,54749,54756,
25854757,54760,54764,54772,54773,54775,54777,54784,54785,54788,54792,54800,54801,
25954803,54804,54805,54812,54816,54820,54829,54840,54841,54844,54848,54853,54856,
26054857,54859,54861,54865,54868,54869,54872,54876,54887,54889,54896,54897,54900,
26154915,54917,54924,54925,54928,54932,54941,54943,54945,54952,54956,54960,54969,
26254971,54980,54981,54984,54988,54993,54996,54999,55001,55008,55012,55016,55024,
26355029,55036,55037,55040,55044,55057,55064,55065,55068,55072,55080,55081,55083,
26455085,55092,55093,55096,55100,55108,55111,55113,55120,55121,55124,55126,55127,
26555128,55129,55136,55137,55139,55141,55145,55148,55152,55156,55164,55165,55169,
26655176,55177,55180,55184,55192,55193,55195,55197,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2670,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2680,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
2690,0,0,0,0,0,0,0,0,0,0,0,0,0,0,20285,20339,20551,20729,21152,21487,21621,21733,
27022025,23233,23478,26247,26550,26551,26607,27468,29634,30146,31292,33499,33540,
27134903,34952,35382,36040,36303,36603,36838,39381,21051,21364,21508,24682,24932,
27227580,29647,33050,35258,35282,38307,20355,21002,22718,22904,23014,24178,24185,
27325031,25536,26438,26604,26751,28567,30286,30475,30965,31240,31487,31777,32925,
27433390,33393,35563,38291,20075,21917,26359,28212,30883,31469,33883,35088,34638,
27538824,21208,22350,22570,23884,24863,25022,25121,25954,26577,27204,28187,29976,
27630131,30435,30640,32058,37039,37969,37970,40853,21283,23724,30002,32987,37440,
27738296,21083,22536,23004,23713,23831,24247,24378,24394,24951,27743,30074,30086,
27831968,32115,32177,32652,33108,33313,34193,35137,35611,37628,38477,40007,20171,
27920215,20491,20977,22607,24887,24894,24936,25913,27114,28433,30117,30342,30422,
28031623,33445,33995,63744,37799,38283,21888,23458,22353,63745,31923,32697,37301,
28120520,21435,23621,24040,25298,25454,25818,25831,28192,28844,31067,36317,36382,
28263746,36989,37445,37624,20094,20214,20581,24062,24314,24838,26967,33137,34388,
28336423,37749,39467,20062,20625,26480,26688,20745,21133,21138,27298,30652,37392,
28440660,21163,24623,36850,20552,25001,25581,25802,26684,27268,28608,33160,35233,
28538548,22533,29309,29356,29956,32121,32365,32937,35211,35700,36963,40273,25225,
28627770,28500,32080,32570,35363,20860,24906,31645,35609,37463,37772,20140,20435,
28720510,20670,20742,21185,21197,21375,22384,22659,24218,24465,24950,25004,
28825806,25964,26223,26299,26356,26775,28039,28805,28913,29855,29861,29898,30169,
28930828,30956,31455,31478,32069,32147,32789,32831,33051,33686,35686,36629,36885,
29037857,38915,38968,39514,39912,20418,21843,22586,22865,23395,23622,24760,25106,
29126690,26800,26856,28330,30028,30328,30926,31293,31995,32363,32380,35336,35489,
29235903,38542,40388,21476,21481,21578,21617,22266,22993,23396,23611,24235,25335,
29325911,25925,25970,26272,26543,27073,27837,30204,30352,30590,31295,32660,32771,
29432929,33167,33510,33533,33776,34241,34865,34996,35493,63747,36764,37678,38599,
29539015,39640,40723,21741,26011,26354,26767,31296,35895,40288,22256,22372,23825,
29626118,26801,26829,28414,29736,34974,39908,27752,63748,39592,20379,20844,20849,
29721151,23380,24037,24656,24685,25329,25511,25915,29657,31354,34467,36002,38799,
29820018,23521,25096,26524,29916,31185,33747,35463,35506,36328,36942,37707,38982,
29924275,27112,34303,37101,63749,20896,23448,23532,24931,26874,27454,28748,29743,
30029912,31649,32592,33733,35264,36011,38364,39208,21038,24669,25324,36866,20362,
30120809,21281,22745,24291,26336,27960,28826,29378,29654,31568,33009,37979,21350,
30225499,32619,20054,20608,22602,22750,24618,24871,25296,27088,39745,23439,32024,
30332945,36703,20132,20689,21676,21932,23308,23968,24039,25898,25934,26657,27211,
30429409,30350,30703,32094,32761,33184,34126,34527,36611,36686,37066,39171,39509,
30539851,19992,20037,20061,20167,20465,20855,21246,21312,21475,21477,21646,22036,
30622389,22434,23495,23943,24272,25084,25304,25937,26552,26601,27083,27472,27590,
30727628,27714,28317,28792,29399,29590,29699,30655,30697,
30831350,32127,32777,33276,33285,33290,33503,34914,35635,36092,36544,36881,37041,
30937476,37558,39378,39493,40169,40407,40860,22283,23616,33738,38816,38827,40628,
31021531,31384,32676,35033,36557,37089,22528,23624,25496,31391,23470,24339,31353,
31131406,33422,36524,20518,21048,21240,21367,22280,25331,25458,27402,28099,30519,
31221413,29527,34152,36470,38357,26426,27331,28528,35437,36556,39243,63750,26231,
31327512,36020,39740,63751,21483,22317,22862,25542,27131,29674,30789,31418,31429,
31431998,33909,35215,36211,36917,38312,21243,22343,30023,31584,33740,37406,63752,
31527224,20811,21067,21127,25119,26840,26997,38553,20677,21156,21220,25027,26020,
31626681,27135,29822,31563,33465,33771,35250,35641,36817,39241,63753,20170,22935,
31725810,26129,27278,29748,31105,31165,33449,34942,34943,35167,63754,37670,20235,
31821450,24613,25201,27762,32026,32102,20120,20834,30684,32943,20225,20238,20854,
31920864,21980,22120,22331,22522,22524,22804,22855,22931,23492,23696,23822,24049,
32024190,24524,25216,26071,26083,26398,26399,26462,26827,26820,27231,27450,27683,
32127773,27778,28103,29592,29734,29738,29826,29859,30072,30079,30849,30959,31041,
32231047,31048,31098,31637,32000,32186,32648,32774,32813,32908,35352,35663,35912,
32336215,37665,37668,39138,39249,39438,39439,39525,40594,32202,20342,21513,25326,
32426708,37329,21931,20794,63755,63756,23068,25062,63757,25295,25343,63758,63759,
32563760,63761,63762,63763,37027,63764,63765,63766,63767,63768,35582,63769,63770,
32663771,63772,26262,63773,29014,63774,63775,38627,63776,25423,25466,21335,63777,
32726511,26976,28275,63778,30007,63779,63780,63781,32013,
32863782,63783,34930,22218,23064,63784,63785,63786,63787,63788,20035,63789,20839,
32922856,26608,32784,63790,22899,24180,25754,31178,24565,24684,25288,25467,23527,
33023511,21162,63791,22900,24361,24594,63792,63793,63794,29785,63795,63796,63797,
33163798,63799,63800,39377,63801,63802,63803,63804,63805,63806,63807,63808,63809,
33263810,63811,28611,63812,63813,33215,36786,24817,63814,63815,33126,63816,63817,
33323615,63818,63819,63820,63821,63822,63823,63824,63825,23273,35365,26491,32016,
33463826,63827,63828,63829,63830,63831,33021,63832,63833,23612,27877,21311,28346,
33522810,33590,20025,20150,20294,21934,22296,22727,24406,26039,26086,27264,27573,
33628237,30701,31471,31774,32222,34507,34962,37170,37723,25787,28606,29562,30136,
33736948,21846,22349,25018,25812,26311,28129,28251,28525,28601,30192,32835,33213,
33834113,35203,35527,35674,37663,27795,30035,31572,36367,36957,21776,22530,22616,
33924162,25095,25758,26848,30070,31958,34739,40680,20195,22408,22382,22823,23565,
34023729,24118,24453,25140,25825,29619,33274,34955,36024,38538,40667,23429,24503,
34124755,20498,20992,21040,22294,22581,22615,23566,23648,23798,23947,24230,24466,
34224764,25361,25481,25623,26691,26873,27330,28120,28193,28372,28644,29182,30428,
34330585,31153,31291,33796,35241,36077,36339,36424,36867,36884,36947,37117,37709,
34438518,38876,27602,28678,29272,29346,29544,30563,31167,31716,32411,35712,22697,
34524775,25958,26109,26302,27788,28958,29129,35930,38931,20077,31361,20189,20908,
34620941,21205,21516,24999,26481,26704,26847,27934,28540,30140,30643,31461,33012,
34733891,37509,20828,26007,26460,26515,30168,31431,33651,
34863834,35910,36887,38957,23663,33216,33434,36929,36975,37389,24471,23965,27225,
34929128,30331,31561,34276,35588,37159,39472,21895,25078,63835,30313,32645,34367,
35034746,35064,37007,63836,27931,28889,29662,32097,33853,63837,37226,39409,63838,
35120098,21365,27396,27410,28734,29211,34349,40478,21068,36771,23888,25829,25900,
35227414,28651,31811,32412,34253,35172,35261,25289,33240,34847,24266,26391,28010,
35329436,29701,29807,34690,37086,20358,23821,24480,33802,20919,25504,30053,20142,
35420486,20841,20937,26753,27153,31918,31921,31975,33391,35538,36635,37327,20406,
35520791,21237,21570,24300,24942,25150,26053,27354,28670,31018,34268,34851,38317,
35639522,39530,40599,40654,21147,26310,27511,28701,31019,36706,38722,24976,25088,
35725891,28451,29001,29833,32244,32879,34030,36646,36899,37706,20925,21015,21155,
35827916,28872,35010,24265,25986,27566,28610,31806,29557,20196,20278,22265,63839,
35923738,23994,24604,29618,31533,32666,32718,32838,36894,37428,38646,38728,38936,
36040801,20363,28583,31150,37300,38583,21214,63840,25736,25796,27347,28510,28696,
36129200,30439,32769,34310,34396,36335,36613,38706,39791,40442,40565,30860,31103,
36232160,33737,37636,40575,40595,35542,22751,24324,26407,28711,29903,31840,32894,
36320769,28712,29282,30922,36034,36058,36084,38647,20102,20698,23534,24278,26009,
36429134,30274,30637,32842,34044,36988,39719,40845,22744,23105,23650,27155,28122,
36528431,30267,32047,32311,34078,35128,37860,38475,21129,26066,26611,27060,27969,
36628316,28687,29705,29792,30041,30244,30827,35628,39006,20845,25134,38520,20374,
36720523,23833,28138,32184,36650,24459,24900,26647,63841,
36838534,21202,32907,20956,20940,26974,31260,32190,33777,38517,20442,21033,21400,
36921519,21774,23653,24743,26446,26792,28012,29313,29432,29702,29827,63842,30178,
37031852,32633,32696,33673,35023,35041,37324,37328,38626,39881,21533,28542,29136,
37129848,34298,36522,38563,40023,40607,26519,28107,29747,33256,38678,30764,31435,
37231520,31890,25705,29802,30194,30908,30952,39340,39764,40635,23518,24149,28448,
37333180,33707,37000,19975,21325,23081,24018,24398,24930,25405,26217,26364,28415,
37428459,28771,30622,33836,34067,34875,36627,39237,39995,21788,25273,26411,27819,
37533545,35178,38778,20129,22916,24536,24537,26395,32178,32596,33426,33579,33725,
37636638,37017,22475,22969,23186,23504,26151,26522,26757,27599,29028,32629,36023,
37736067,36993,39749,33032,35978,38476,39488,40613,23391,27667,29467,30450,30431,
37833804,20906,35219,20813,20885,21193,26825,27796,30468,30496,32191,32236,38754,
37940629,28357,34065,20901,21517,21629,26126,26269,26919,28319,30399,30609,33559,
38033986,34719,37225,37528,40180,34946,20398,20882,21215,22982,24125,24917,25720,
38125721,26286,26576,27169,27597,27611,29279,29281,29761,30520,30683,32791,33468,
38233541,35584,35624,35980,26408,27792,29287,30446,30566,31302,40361,27519,27794,
38322818,26406,33945,21359,22675,22937,24287,25551,26164,26483,28218,29483,31447,
38433495,37672,21209,24043,25006,25035,25098,25287,25771,26080,26969,27494,27595,
38528961,29687,30045,32326,33310,33538,34154,35491,36031,38695,40289,22696,40664,
38620497,21006,21563,21839,25991,27766,32010,32011,32862,34442,38272,38639,21247,
38727797,29289,21619,23194,23614,23883,24396,24494,26410,
38826806,26979,28220,28228,30473,31859,32654,34183,35598,36855,38753,40692,23735,
38924758,24845,25003,25935,26107,26108,27665,27887,29599,29641,32225,38292,23494,
39034588,35600,21085,21338,25293,25615,25778,26420,27192,27850,29632,29854,31636,
39131893,32283,33162,33334,34180,36843,38649,39361,20276,21322,21453,21467,25292,
39225644,25856,26001,27075,27886,28504,29677,30036,30242,30436,30460,30928,30971,
39331020,32070,33324,34784,36820,38930,39151,21187,25300,25765,28196,28497,30332,
39436299,37297,37474,39662,39747,20515,20621,22346,22952,23592,24135,24439,25151,
39525918,26041,26049,26121,26507,27036,28354,30917,32033,32938,33152,33323,33459,
39633953,34444,35370,35607,37030,38450,40848,20493,20467,63843,22521,24472,25308,
39725490,26479,28227,28953,30403,32972,32986,35060,35061,35097,36064,36649,37197,
39838506,20271,20336,24091,26575,26658,30333,30334,39748,24161,27146,29033,29140,
39930058,63844,32321,34115,34281,39132,20240,31567,32624,38309,20961,24070,26805,
40027710,27726,27867,29359,31684,33539,27861,29754,20731,21128,22721,25816,27287,
40129863,30294,30887,34327,38370,38713,63845,21342,24321,35722,36776,36783,37002,
40221029,30629,40009,40712,19993,20482,20853,23643,24183,26142,26170,26564,26821,
40328851,29953,30149,31177,31453,36647,39200,39432,20445,22561,22577,23542,26222,
40427493,27921,28282,28541,29668,29995,33769,35036,35091,35676,36628,20239,20693,
40521264,21340,23443,24489,26381,31119,33145,33583,34068,35079,35206,36665,36667,
40639333,39954,26412,20086,20472,22857,23553,23791,23792,25447,26834,28925,29090,
40729739,32299,34028,34562,36898,37586,40179,19981,20184,
40820463,20613,21078,21103,21542,21648,22496,22827,23142,23386,23413,23500,24220,
40963846,25206,25975,26023,28014,28325,29238,31526,31807,32566,33104,33105,33178,
41033344,33433,33705,35331,36000,36070,36091,36212,36282,37096,37340,38428,38468,
41139385,40167,21271,20998,21545,22132,22707,22868,22894,24575,24996,25198,26128,
41227774,28954,30406,31881,31966,32027,33452,36033,38640,63847,20315,24343,24447,
41325282,23849,26379,26842,30844,32323,40300,19989,20633,21269,21290,21329,22915,
41423138,24199,24754,24970,25161,25209,26000,26503,27047,27604,27606,27607,27608,
41527832,63848,29749,30202,30738,30865,31189,31192,31875,32203,32737,32933,33086,
41633218,33778,34586,35048,35513,35692,36027,37145,38750,39131,40763,22188,23338,
41724428,25996,27315,27567,27996,28657,28693,29277,29613,36007,36051,38971,24977,
41827703,32856,39425,20045,20107,20123,20181,20282,20284,20351,20447,20735,21490,
41921496,21766,21987,22235,22763,22882,23057,23531,23546,23556,24051,24107,24473,
42024605,25448,26012,26031,26614,26619,26797,27515,27801,27863,28195,28681,29509,
42130722,31038,31040,31072,31169,31721,32023,32114,32902,33293,33678,34001,34503,
42235039,35408,35422,35613,36060,36198,36781,37034,39164,39391,40605,21066,63849,
42326388,63850,20632,21034,23665,25955,27733,29642,29987,30109,31639,33948,37240,
42438704,20087,25746,27578,29022,34217,19977,63851,26441,26862,28183,33439,34072,
42534923,25591,28545,37394,39087,19978,20663,20687,20767,21830,21930,22039,23360,
42623577,23776,24120,24202,24224,24258,24819,26705,27233,28248,29245,29248,29376,
42730456,31077,31665,32724,35059,35316,35443,35937,36062,
42838684,22622,29885,36093,21959,63852,31329,32034,33394,29298,29983,29989,63853,
42931513,22661,22779,23996,24207,24246,24464,24661,25234,25471,25933,26257,26329,
43026360,26646,26866,29312,29790,31598,32110,32214,32626,32997,33298,34223,35199,
43135475,36893,37604,40653,40736,22805,22893,24109,24796,26132,26227,26512,27728,
43228101,28511,30707,30889,33990,37323,37675,20185,20682,20808,21892,23307,23459,
43325159,25982,26059,28210,29053,29697,29764,29831,29887,30316,31146,32218,32341,
43432680,33146,33203,33337,34330,34796,35445,36323,36984,37521,37925,39245,39854,
43521352,23633,26964,27844,27945,28203,33292,34203,35131,35373,35498,38634,40807,
43621089,26297,27570,32406,34814,36109,38275,38493,25885,28041,29166,63854,22478,
43722995,23468,24615,24826,25104,26143,26207,29481,29689,30427,30465,31596,32854,
43832882,33125,35488,37266,19990,21218,27506,27927,31237,31545,32048,63855,36016,
43921484,22063,22609,23477,23567,23569,24034,25152,25475,25620,26157,26803,27836,
44028040,28335,28703,28836,29138,29990,30095,30094,30233,31505,31712,31787,32032,
44132057,34092,34157,34311,35380,36877,36961,37045,37559,38902,39479,20439,23660,
44226463,28049,31903,32396,35606,36118,36895,23403,24061,25613,33984,36956,39137,
44329575,23435,24730,26494,28126,35359,35494,36865,38924,21047,63856,28753,30862,
44437782,34928,37335,20462,21463,22013,22234,22402,22781,23234,23432,23723,23744,
44524101,24833,25101,25163,25480,25628,25910,25976,27193,27530,27700,27929,28465,
44629159,29417,29560,29703,29874,30246,30561,31168,31319,31466,31929,32143,32172,
44732353,32670,33065,33585,33936,34010,34282,34966,35504,
44835728,36664,36930,36995,37228,37526,37561,38539,38567,38568,38614,38656,38920,
44939318,39635,39706,21460,22654,22809,23408,23487,28113,28506,29087,29729,29881,
45032901,33789,24033,24455,24490,24642,26092,26642,26991,27219,27529,27957,28147,
45129667,30462,30636,31565,32020,33059,33308,33600,34036,34147,35426,35524,37255,
45237662,38918,39348,25100,34899,36848,37477,23815,23847,23913,29791,33181,34664,
45328629,25342,32722,35126,35186,19998,20056,20711,21213,21319,25215,26119,32361,
45434821,38494,20365,21273,22070,22987,23204,23608,23630,23629,24066,24337,24643,
45526045,26159,26178,26558,26612,29468,30690,31034,32709,33940,33997,35222,35430,
45635433,35553,35925,35962,22516,23508,24335,24687,25325,26893,27542,28252,29060,
45731698,34645,35672,36606,39135,39166,20280,20353,20449,21627,23072,23480,24892,
45826032,26216,29180,30003,31070,32051,33102,33251,33688,34218,34254,34563,35338,
45936523,36763,63857,36805,22833,23460,23526,24713,23529,23563,24515,27777,63858,
46028145,28683,29978,33455,35574,20160,21313,63859,38617,27663,20126,20420,20818,
46121854,23077,23784,25105,29273,33469,33706,34558,34905,35357,38463,38597,39187,
46240201,40285,22538,23731,23997,24132,24801,24853,25569,27138,28197,37122,37716,
46338990,39952,40823,23433,23736,25353,26191,26696,30524,38593,38797,38996,39839,
46426017,35585,36555,38332,21813,23721,24022,24245,26263,30284,33780,38343,22739,
46525276,29390,40232,20208,22830,24591,26171,27523,31207,40230,21395,21696,22467,
46623830,24859,26326,28079,30861,33406,38552,38724,21380,25212,25494,28082,32266,
46733099,38989,27387,32588,40367,40474,20063,20539,20918,
46822812,24825,25590,26928,29242,32822,63860,37326,24369,63861,63862,32004,33509,
46933903,33979,34277,36493,63863,20335,63864,63865,22756,23363,24665,25562,25880,
47025965,26264,63866,26954,27171,27915,28673,29036,30162,30221,31155,31344,63867,
47132650,63868,35140,63869,35731,37312,38525,63870,39178,22276,24481,26044,28417,
47230208,31142,35486,39341,39770,40812,20740,25014,25233,27277,33222,20547,22576,
47324422,28937,35328,35578,23420,34326,20474,20796,22196,22852,25513,28153,23978,
47426989,20870,20104,20313,63871,63872,63873,22914,63874,63875,27487,27741,63876,
47529877,30998,63877,33287,33349,33593,36671,36701,63878,39192,63879,63880,63881,
47620134,63882,22495,24441,26131,63883,63884,30123,32377,35695,63885,36870,39515,
47722181,22567,23032,23071,23476,63886,24310,63887,63888,25424,25403,63889,26941,
47827783,27839,28046,28051,28149,28436,63890,28895,28982,29017,63891,29123,29141,
47963892,30799,30831,63893,31605,32227,63894,32303,63895,34893,36575,63896,63897,
48063898,37467,63899,40182,63900,63901,63902,24709,28037,63903,29105,63904,63905,
48138321,21421,63906,63907,63908,26579,63909,28814,28976,29744,33398,33490,63910,
48238331,39653,40573,26308,63911,29121,33865,63912,63913,22603,63914,63915,23992,
48324433,63916,26144,26254,27001,27054,27704,27891,28214,28481,28634,28699,28719,
48429008,29151,29552,63917,29787,63918,29908,30408,31310,32403,63919,63920,33521,
48535424,36814,63921,37704,63922,38681,63923,63924,20034,20522,63925,21000,21473,
48626355,27757,28618,29450,30591,31330,33454,34269,34306,63926,35028,35427,35709,
48735947,63927,37555,63928,38675,38928,20116,20237,20425,
48820658,21320,21566,21555,21978,22626,22714,22887,23067,23524,24735,63929,25034,
48925942,26111,26212,26791,27738,28595,28879,29100,29522,31613,34568,35492,39986,
49040711,23627,27779,29508,29577,37434,28331,29797,30239,31337,32277,34314,20800,
49122725,25793,29934,29973,30320,32705,37013,38605,39252,28198,29926,31401,31402,
49233253,34521,34680,35355,23113,23436,23451,26785,26880,28003,29609,29715,29740,
49330871,32233,32747,33048,33109,33694,35916,38446,38929,26352,24448,26106,26505,
49427754,29579,20525,23043,27498,30702,22806,23916,24013,29477,30031,63930,63931,
49520709,20985,22575,22829,22934,23002,23525,63932,63933,23970,25303,25622,25747,
49625854,63934,26332,63935,27208,63936,29183,29796,63937,31368,31407,32327,32350,
49732768,33136,63938,34799,35201,35616,36953,63939,36992,39250,24958,27442,28020,
49832287,35109,36785,20433,20653,20887,21191,22471,22665,23481,24248,24898,27029,
49928044,28263,28342,29076,29794,29992,29996,32883,33592,33993,36362,37780,37854,
50063940,20110,20305,20598,20778,21448,21451,21491,23431,23507,23588,24858,24962,
50126100,29275,29591,29760,30402,31056,31121,31161,32006,32701,33419,34261,34398,
50236802,36935,37109,37354,38533,38632,38633,21206,24423,26093,26161,26671,29020,
50331286,37057,38922,20113,63941,27218,27550,28560,29065,32792,33464,34131,36939,
50438549,38642,38907,34074,39729,20112,29066,38596,20803,21407,21729,22291,22290,
50522435,23195,23236,23491,24616,24895,25588,27781,27961,28274,28304,29232,29503,
50629783,33489,34945,36677,36960,63942,38498,39000,40219,26376,36234,37470,20301,
50720553,20702,21361,22285,22996,23041,23561,24944,26256,
50828205,29234,29771,32239,32963,33806,33894,34111,34655,34907,35096,35586,36949,
50938859,39759,20083,20369,20754,20842,63943,21807,21929,23418,23461,24188,24189,
51024254,24736,24799,24840,24841,25540,25912,26377,63944,26580,26586,63945,26977,
51126978,27833,27943,63946,28216,63947,28641,29494,29495,63948,29788,30001,63949,
51230290,63950,63951,32173,33278,33848,35029,35480,35547,35565,36400,36418,36938,
51336926,36986,37193,37321,37742,63952,63953,22537,63954,27603,32905,32946,63955,
51463956,20801,22891,23609,63957,63958,28516,29607,32996,36103,63959,37399,38287,
51563960,63961,63962,63963,32895,25102,28700,32104,34701,63964,22432,24681,24903,
51627575,35518,37504,38577,20057,21535,28139,34093,38512,38899,39150,25558,27875,
51737009,20957,25033,33210,40441,20381,20506,20736,23452,24847,25087,25836,26885,
51827589,30097,30691,32681,33380,34191,34811,34915,35516,35696,37291,20108,20197,
51920234,63965,63966,22839,23016,63967,24050,24347,24411,24609,63968,63969,63970,
52063971,29246,29669,63972,30064,30157,63973,31227,63974,32780,32819,32900,33505,
52133617,63975,63976,36029,36019,36999,63977,63978,39156,39180,63979,63980,28727,
52230410,32714,32716,32764,35610,20154,20161,20995,21360,63981,21693,22240,23035,
52323493,24341,24525,28270,63982,63983,32106,33589,63984,34451,35469,63985,38765,
52438775,63986,63987,19968,20314,20350,22777,26085,28322,36920,37808,39353,20219,
52522764,22922,23001,24641,63988,63989,31252,63990,33615,36035,20837,21316,63991,
52663992,63993,20173,21097,23381,33471,20180,21050,21672,22985,23039,23376,23383,
52723388,24675,24904,28363,28825,29038,29574,29943,30133,
52830913,32043,32773,33258,33576,34071,34249,35566,36039,38604,20316,21242,22204,
52926027,26152,28796,28856,29237,32189,33421,37196,38592,40306,23409,26855,27544,
53028538,30430,23697,26283,28507,31668,31786,34870,38620,19976,20183,21280,22580,
53122715,22767,22892,23559,24115,24196,24373,25484,26290,26454,27167,27299,27404,
53228479,29254,63994,29520,29835,31456,31911,33144,33247,33255,33674,33900,34083,
53334196,34255,35037,36115,37292,38263,38556,20877,21705,22312,23472,25165,26448,
53426685,26771,28221,28371,28797,32289,35009,36001,36617,40779,40782,29229,31631,
53535533,37658,20295,20302,20786,21632,22992,24213,25269,26485,26990,27159,27822,
53628186,29401,29482,30141,31672,32053,33511,33785,33879,34295,35419,36015,36487,
53736889,37048,38606,40799,21219,21514,23265,23490,25688,25973,28404,29380,63995,
53830340,31309,31515,31821,32318,32735,33659,35627,36042,36196,36321,36447,36842,
53936857,36969,37841,20291,20346,20659,20840,20856,21069,21098,22625,22652,22880,
54023560,23637,24283,24731,25136,26643,27583,27656,28593,29006,29728,30000,30008,
54130033,30322,31564,31627,31661,31686,32399,35438,36670,36681,37439,37523,37666,
54237931,38651,39002,39019,39198,20999,25130,25240,27993,30308,31434,31680,32118,
54321344,23742,24215,28472,28857,31896,38673,39822,40670,25509,25722,34678,19969,
54420117,20141,20572,20597,21576,22979,23450,24128,24237,24311,24449,24773,25402,
54525919,25972,26060,26230,26232,26622,26984,27273,27491,27712,28096,28136,28191,
54628254,28702,28833,29582,29693,30010,30555,30855,31118,31243,31357,31934,32142,
54733351,35330,35562,35998,37165,37194,37336,37478,37580,
54837664,38662,38742,38748,38914,40718,21046,21137,21884,22564,24093,24351,24716,
54925552,26799,28639,31085,31532,33229,34234,35069,35576,36420,37261,38500,38555,
55038717,38988,40778,20430,20806,20939,21161,22066,24340,24427,25514,25805,26089,
55126177,26362,26361,26397,26781,26839,27133,28437,28526,29031,29157,29226,29866,
55230522,31062,31066,31199,31264,31381,31895,31967,32068,32368,32903,34299,34468,
55335412,35519,36249,36481,36896,36973,37347,38459,38613,40165,26063,31751,36275,
55437827,23384,23562,21330,25305,29469,20519,23447,24478,24752,24939,26837,28121,
55529742,31278,32066,32156,32305,33131,36394,36405,37758,37912,20304,22352,24038,
55624231,25387,32618,20027,20303,20367,20570,23005,32964,21610,21608,22014,22863,
55723449,24030,24282,26205,26417,26609,26666,27880,27954,28234,28557,28855,29664,
55830087,31820,32002,32044,32162,33311,34523,35387,35461,36208,36490,36659,36913,
55937198,37202,37956,39376,31481,31909,20426,20737,20934,22472,23535,23803,26201,
56027197,27994,28310,28652,28940,30063,31459,34850,36897,36981,38603,39423,33537,
56120013,20210,34886,37325,21373,27355,26987,27713,33914,22686,24974,26366,25327,
56228893,29969,30151,32338,33976,35657,36104,20043,21482,21675,22320,22336,24535,
56325345,25351,25711,25903,26088,26234,26525,26547,27490,27744,27802,28460,30693,
56430757,31049,31063,32025,32930,33026,33267,33437,33463,34584,35468,63996,36100,
56536286,36978,30452,31257,31287,32340,32887,21767,21972,22645,25391,25634,26185,
56626187,26733,27035,27524,27941,28337,29645,29800,29857,30043,30137,30433,30494,
56730603,31206,32265,32285,33275,34095,34967,35386,36049,
56836587,36784,36914,37805,38499,38515,38663,20356,21489,23018,23241,24089,26702,
56929894,30142,31209,31378,33187,34541,36074,36300,36845,26015,26389,63997,22519,
57028503,32221,36655,37878,38598,24501,25074,28548,19988,20376,20511,21449,21983,
57123919,24046,27425,27492,30923,31642,63998,36425,36554,36974,25417,25662,30528,
57231364,37679,38015,40810,25776,28591,29158,29864,29914,31428,31762,32386,31922,
57332408,35738,36106,38013,39184,39244,21049,23519,25830,26413,32046,20717,21443,
57422649,24920,24921,25082,26028,31449,35730,35734,20489,20513,21109,21809,23100,
57524288,24432,24884,25950,26124,26166,26274,27085,28356,28466,29462,30241,31379,
57633081,33369,33750,33980,20661,22512,23488,23528,24425,25505,30758,32181,33756,
57734081,37319,37365,20874,26613,31574,36012,20932,22971,24765,34389,20508,63999,
57821076,23610,24957,25114,25299,25842,26021,28364,30240,33034,36448,38495,38587,
57920191,21315,21912,22825,24029,25797,27849,28154,29588,31359,33307,34214,36068,
58036368,36983,37351,38369,38433,38854,20984,21746,21894,24505,25764,28552,32180,
58136639,36685,37941,20681,23574,27838,28155,29979,30651,31805,31844,35449,35522,
58222558,22974,24086,25463,29266,30090,30571,35548,36028,36626,24307,26228,28152,
58332893,33729,35531,38737,39894,64000,21059,26367,28053,28399,32224,35558,36910,
58436958,39636,21021,21119,21736,24980,25220,25307,26786,26898,26970,27189,28818,
58528966,30813,30977,30990,31186,31245,32918,33400,33493,33609,34121,35970,36229,
58637218,37259,37294,20419,22225,29165,30679,34560,35320,23544,24534,26449,37032,
58721474,22618,23541,24740,24961,25696,32317,32880,34085,
58837507,25774,20652,23828,26368,22684,25277,25512,26894,27000,27166,28267,30394,
58931179,33467,33833,35535,36264,36861,37138,37195,37276,37648,37656,37786,38619,
59039478,39949,19985,30044,31069,31482,31569,31689,32302,33988,36441,36468,36600,
59136880,26149,26943,29763,20986,26414,40668,20805,24544,27798,34802,34909,34935,
59224756,33205,33795,36101,21462,21561,22068,23094,23601,28810,32736,32858,33030,
59333261,36259,37257,39519,40434,20596,20164,21408,24827,28204,23652,20360,20516,
59421988,23769,24159,24677,26772,27835,28100,29118,30164,30196,30305,31258,31305,
59532199,32251,32622,33268,34473,36636,38601,39347,40786,21063,21189,39149,35242,
59619971,26578,28422,20405,23522,26517,27784,28024,29723,30759,37341,37756,34756,
59731204,31281,24555,20182,21668,21822,22702,22949,24816,25171,25302,26422,26965,
59833333,38464,39345,39389,20524,21331,21828,22396,64001,25176,64002,25826,26219,
59926589,28609,28655,29730,29752,35351,37944,21585,22022,22374,24392,24986,27470,
60028760,28845,32187,35477,22890,33067,25506,30472,32829,36010,22612,25645,27067,
60123445,24081,28271,64003,34153,20812,21488,22826,24608,24907,27526,27760,27888,
60231518,32974,33492,36294,37040,39089,64004,25799,28580,25745,25860,20814,21520,
60322303,35342,24927,26742,64005,30171,31570,32113,36890,22534,27084,33151,35114,
60436864,38969,20600,22871,22956,25237,36879,39722,24925,29305,38358,22369,23110,
60524052,25226,25773,25850,26487,27874,27966,29228,29750,30772,32631,33453,36315,
60638935,21028,22338,26495,29256,29923,36009,36774,37393,38442,20843,21485,25420,
60720329,21764,24726,25943,27803,28031,29260,29437,31255,
60835207,35997,24429,28558,28921,33192,24846,20415,20559,25153,29255,31687,32232,
60932745,36941,38829,39449,36022,22378,24179,26544,33805,35413,21536,23318,24163,
61024290,24330,25987,32954,34109,38281,38491,20296,21253,21261,21263,21638,21754,
61122275,24067,24598,25243,25265,25429,64006,27873,28006,30129,30770,32990,33071,
61233502,33889,33970,34957,35090,36875,37610,39165,39825,24133,26292,26333,28689,
61329190,64007,20469,21117,24426,24915,26451,27161,28418,29922,31080,34920,35961,
61439111,39108,39491,21697,31263,26963,35575,35914,39080,39342,24444,25259,30130,
61530382,34987,36991,38466,21305,24380,24517,27852,29644,30050,30091,31558,33534,
61639325,20047,36924,19979,20309,21414,22799,24264,26160,27827,29781,33655,34662,
61736032,36944,38686,39957,22737,23416,34384,35604,40372,23506,24680,24717,26097,
61827735,28450,28579,28698,32597,32752,38289,38290,38480,38867,21106,36676,20989,
61921547,21688,21859,21898,27323,28085,32216,33382,37532,38519,40569,21512,21704,
62030418,34532,38308,38356,38492,20130,20233,23022,23270,24055,24658,25239,26477,
62126689,27782,28207,32568,32923,33322,64008,64009,38917,20133,20565,21683,22419,
62222874,23401,23475,25032,26999,28023,28707,34809,35299,35442,35559,36994,39405,
62339608,21182,26680,20502,24184,26447,33607,34892,20139,21521,22190,29670,37141,
62438911,39177,39255,39321,22099,22687,34395,35377,25010,27382,29563,36562,27463,
62538570,39511,22869,29184,36203,38761,20436,23796,24358,25080,26203,27883,28843,
62629572,29625,29694,30505,30541,32067,32098,32291,33335,34898,64010,36066,37449,
62739023,23377,31348,34880,38913,23244,20448,21332,22846,
62823805,25406,28025,29433,33029,33031,33698,37583,38960,20136,20804,21009,22411,
62924418,27842,28366,28677,28752,28847,29074,29673,29801,33610,34722,34913,36872,
63037026,37795,39336,20846,24407,24800,24935,26291,34137,36426,37295,38795,20046,
63120114,21628,22741,22778,22909,23733,24359,25142,25160,26122,26215,27627,28009,
63228111,28246,28408,28564,28640,28649,28765,29392,29733,29786,29920,30355,31068,
63331946,32286,32993,33446,33899,33983,34382,34399,34676,35703,35946,37804,38912,
63439013,24785,25110,37239,23130,26127,28151,28222,29759,39746,24573,24794,31503,
63521700,24344,27742,27859,27946,28888,32005,34425,35340,40251,21270,21644,23301,
63627194,28779,30069,31117,31166,33457,33775,35441,35649,36008,38772,64011,25844,
63725899,30906,30907,31339,20024,21914,22864,23462,24187,24739,25563,27489,26213,
63826707,28185,29029,29872,32008,36996,39529,39973,27963,28369,29502,35905,38346,
63920976,24140,24488,24653,24822,24880,24908,26179,26180,27045,27841,28255,28361,
64028514,29004,29852,30343,31681,31783,33618,34647,36945,38541,40643,21295,22238,
64124315,24458,24674,24724,25079,26214,26371,27292,28142,28590,28784,29546,32362,
64233214,33588,34516,35496,36036,21123,29554,23446,27243,37892,21742,22150,23389,
64325928,25989,26313,26783,28045,28102,29243,32948,37237,39501,20399,20505,21402,
64421518,21564,21897,21957,24127,24460,26429,29030,29661,36869,21211,21235,22628,
64522734,28932,29071,29179,34224,35347,26248,34216,21927,26244,29002,33841,21321,
64621913,27585,24409,24509,25582,26249,28999,35569,36637,40638,20241,25658,28875,
64730054,34407,24676,35662,40440,20807,20982,21256,27958,
64833016,40657,26133,27427,28824,30165,21507,23673,32007,35350,27424,27453,27462,
64921560,24688,27965,32725,33288,20694,20958,21916,22123,22221,23020,23305,24076,
65024985,24984,25137,26206,26342,29081,29113,29114,29351,31143,31232,32690,35440,
libc/musl/src/locale/langinfo.c created+73
......@@ -0,0 +1,73 @@
1#include <locale.h>
2#include <langinfo.h>
3#include "locale_impl.h"
4
5static const char c_time[] =
6 "Sun\0" "Mon\0" "Tue\0" "Wed\0" "Thu\0" "Fri\0" "Sat\0"
7 "Sunday\0" "Monday\0" "Tuesday\0" "Wednesday\0"
8 "Thursday\0" "Friday\0" "Saturday\0"
9 "Jan\0" "Feb\0" "Mar\0" "Apr\0" "May\0" "Jun\0"
10 "Jul\0" "Aug\0" "Sep\0" "Oct\0" "Nov\0" "Dec\0"
11 "January\0" "February\0" "March\0" "April\0"
12 "May\0" "June\0" "July\0" "August\0"
13 "September\0" "October\0" "November\0" "December\0"
14 "AM\0" "PM\0"
15 "%a %b %e %T %Y\0"
16 "%m/%d/%y\0"
17 "%H:%M:%S\0"
18 "%I:%M:%S %p\0"
19 "\0"
20 "\0"
21 "%m/%d/%y\0"
22 "0123456789\0"
23 "%a %b %e %T %Y\0"
24 "%H:%M:%S";
25
26static const char c_messages[] = "^[yY]\0" "^[nN]\0" "yes\0" "no";
27static const char c_numeric[] = ".\0" "";
28
29char *__nl_langinfo_l(nl_item item, locale_t loc)
30{
31 int cat = item >> 16;
32 int idx = item & 65535;
33 const char *str;
34
35 if (item == CODESET) return loc->cat[LC_CTYPE] ? "UTF-8" : "ASCII";
36
37 /* _NL_LOCALE_NAME extension */
38 if (idx == 65535 && cat < LC_ALL)
39 return loc->cat[cat] ? (char *)loc->cat[cat]->name : "C";
40
41 switch (cat) {
42 case LC_NUMERIC:
43 if (idx > 1) return "";
44 str = c_numeric;
45 break;
46 case LC_TIME:
47 if (idx > 0x31) return "";
48 str = c_time;
49 break;
50 case LC_MONETARY:
51 if (idx > 0) return "";
52 str = "";
53 break;
54 case LC_MESSAGES:
55 if (idx > 3) return "";
56 str = c_messages;
57 break;
58 default:
59 return "";
60 }
61
62 for (; idx; idx--, str++) for (; *str; str++);
63 if (cat != LC_NUMERIC && *str) str = LCTRANS(str, cat, loc);
64 return (char *)str;
65}
66
67char *__nl_langinfo(nl_item item)
68{
69 return __nl_langinfo_l(item, CURRENT_LOCALE);
70}
71
72weak_alias(__nl_langinfo, nl_langinfo);
73weak_alias(__nl_langinfo_l, nl_langinfo_l);
libc/musl/src/locale/legacychars.h created+40
......@@ -0,0 +1,40 @@
1256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,
2275,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,
3296,297,298,299,302,303,304,305,308,309,310,311,312,313,314,315,316,317,318,
4321,322,323,324,325,326,327,328,330,331,332,333,336,337,338,339,340,341,342,
5343,344,345,346,347,348,349,350,351,352,353,354,355,356,357,358,359,360,361,
6362,363,364,365,366,367,368,369,370,371,372,373,374,375,376,377,378,379,380,
7381,382,402,416,417,431,432,536,537,538,539,710,711,728,729,731,732,733,768,
8769,771,777,803,890,900,901,902,904,905,906,908,910,911,912,913,914,915,916,
9917,918,919,920,921,922,923,924,925,926,927,928,929,931,932,933,934,935,936,
10937,938,939,940,941,942,943,944,945,946,947,948,949,950,951,952,953,954,955,
11956,957,958,959,960,961,962,963,964,965,966,967,968,969,970,971,972,973,974,
121025,1026,1027,1028,1029,1030,1031,1032,1033,1034,1035,1036,1038,1039,1040,
131041,1042,1043,1044,1045,1046,1047,1048,1049,1050,1051,1052,1053,1054,1055,
141056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070,
151071,
161072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,
171087,1088,1089,1090,1091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,
181102,1103,1105,1106,1107,1108,1109,1110,1111,1112,1113,1114,1115,1116,1118,
191119,1168,1169,1456,1457,1458,1459,1460,1461,1462,1463,1464,1465,1467,1468,
201469,1470,1471,1472,1473,1474,1475,1488,1489,1490,1491,1492,1493,1494,1495,
211496,1497,1498,1499,1500,1501,1502,1503,1504,1505,1506,1507,1508,1509,1510,
221511,1512,1513,1514,1520,1521,1522,1523,1524,1548,1563,1567,1569,1570,1571,
231572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,
241587,1588,1589,1590,1591,1592,1593,1594,1600,1601,1602,1603,1604,1605,1606,
251607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1657,1662,1670,
261672,1681,1688,1705,1711,1722,1726,1729,1746,3585,3586,3587,3588,3589,3590,
273591,3592,3593,3594,3595,3596,3597,3598,3599,3600,3601,3602,3603,3604,3605,
283606,3607,3608,3609,3610,3611,3612,3613,3614,3615,3616,3617,3618,3619,3620,
293621,3622,3623,3624,3625,3626,3627,3628,3629,3630,3631,3632,3633,3634,3635,
303636,3637,3638,3639,3640,3641,3642,3647,3648,3649,3650,3651,3652,3653,3654,
313655,3656,3657,3658,3659,3660,3661,3662,3663,3664,3665,3666,3667,3668,3669,
323670,3671,3672,3673,3674,3675,7682,7683,7690,7691,7710,7711,7744,7745,7766,
337767,
347776,7777,7786,7787,7808,7809,7810,7811,7812,7813,7922,7923,8204,8205,8206,
358207,8211,8212,8213,8215,8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,
368240,8249,8250,8319,8359,8362,8363,8364,8367,8470,8482,8729,8730,8734,8745,
378776,8801,8804,8805,8976,8992,8993,9472,9474,9484,9488,9492,9496,9500,9508,
389516,9524,9532,9552,9553,9554,9555,9556,9557,9558,9559,9560,9561,9562,9563,
399564,9565,9566,9567,9568,9569,9570,9571,9572,9573,9574,9575,9576,9577,9578,
409579,9580,9600,9604,9608,9612,9616,9617,9618,9619,9632,
libc/musl/src/locale/locale_map.c created+113
......@@ -0,0 +1,113 @@
1#include <locale.h>
2#include <string.h>
3#include <sys/mman.h>
4#include "locale_impl.h"
5#include "libc.h"
6#include "lock.h"
7
8const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
9{
10 const char *trans = 0;
11 if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg);
12 return trans ? trans : msg;
13}
14
15static const char envvars[][12] = {
16 "LC_CTYPE",
17 "LC_NUMERIC",
18 "LC_TIME",
19 "LC_COLLATE",
20 "LC_MONETARY",
21 "LC_MESSAGES",
22};
23
24const struct __locale_map *__get_locale(int cat, const char *val)
25{
26 static volatile int lock[1];
27 static void *volatile loc_head;
28 const struct __locale_map *p;
29 struct __locale_map *new = 0;
30 const char *path = 0, *z;
31 char buf[256];
32 size_t l, n;
33
34 if (!*val) {
35 (val = getenv("LC_ALL")) && *val ||
36 (val = getenv(envvars[cat])) && *val ||
37 (val = getenv("LANG")) && *val ||
38 (val = "C.UTF-8");
39 }
40
41 /* Limit name length and forbid leading dot or any slashes. */
42 for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);
43 if (val[0]=='.' || val[n]) val = "C.UTF-8";
44 int builtin = (val[0]=='C' && !val[1])
45 || !strcmp(val, "C.UTF-8")
46 || !strcmp(val, "POSIX");
47
48 if (builtin) {
49 if (cat == LC_CTYPE && val[1]=='.')
50 return (void *)&__c_dot_utf8;
51 return 0;
52 }
53
54 for (p=loc_head; p; p=p->next)
55 if (!strcmp(val, p->name)) return p;
56
57 LOCK(lock);
58
59 for (p=loc_head; p; p=p->next)
60 if (!strcmp(val, p->name)) {
61 UNLOCK(lock);
62 return p;
63 }
64
65 if (!libc.secure) path = getenv("MUSL_LOCPATH");
66 /* FIXME: add a default path? */
67
68 if (path) for (; *path; path=z+!!*z) {
69 z = __strchrnul(path, ':');
70 l = z - path - !!*z;
71 if (l >= sizeof buf - n - 2) continue;
72 memcpy(buf, path, l);
73 buf[l] = '/';
74 memcpy(buf+l+1, val, n);
75 buf[l+1+n] = 0;
76 size_t map_size;
77 const void *map = __map_file(buf, &map_size);
78 if (map) {
79 new = malloc(sizeof *new);
80 if (!new) {
81 __munmap((void *)map, map_size);
82 break;
83 }
84 new->map = map;
85 new->map_size = map_size;
86 memcpy(new->name, val, n);
87 new->name[n] = 0;
88 new->next = loc_head;
89 loc_head = new;
90 break;
91 }
92 }
93
94 /* If no locale definition was found, make a locale map
95 * object anyway to store the name, which is kept for the
96 * sake of being able to do message translations at the
97 * application level. */
98 if (!new && (new = malloc(sizeof *new))) {
99 new->map = __c_dot_utf8.map;
100 new->map_size = __c_dot_utf8.map_size;
101 memcpy(new->name, val, n);
102 new->name[n] = 0;
103 new->next = loc_head;
104 loc_head = new;
105 }
106
107 /* For LC_CTYPE, never return a null pointer unless the
108 * requested name was "C" or "POSIX". */
109 if (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8;
110
111 UNLOCK(lock);
112 return new;
113}
libc/musl/src/locale/localeconv.c created+34
......@@ -0,0 +1,34 @@
1#include <locale.h>
2#include <limits.h>
3
4static const struct lconv posix_lconv = {
5 .decimal_point = ".",
6 .thousands_sep = "",
7 .grouping = "",
8 .int_curr_symbol = "",
9 .currency_symbol = "",
10 .mon_decimal_point = "",
11 .mon_thousands_sep = "",
12 .mon_grouping = "",
13 .positive_sign = "",
14 .negative_sign = "",
15 .int_frac_digits = CHAR_MAX,
16 .frac_digits = CHAR_MAX,
17 .p_cs_precedes = CHAR_MAX,
18 .p_sep_by_space = CHAR_MAX,
19 .n_cs_precedes = CHAR_MAX,
20 .n_sep_by_space = CHAR_MAX,
21 .p_sign_posn = CHAR_MAX,
22 .n_sign_posn = CHAR_MAX,
23 .int_p_cs_precedes = CHAR_MAX,
24 .int_p_sep_by_space = CHAR_MAX,
25 .int_n_cs_precedes = CHAR_MAX,
26 .int_n_sep_by_space = CHAR_MAX,
27 .int_p_sign_posn = CHAR_MAX,
28 .int_n_sign_posn = CHAR_MAX,
29};
30
31struct lconv *localeconv(void)
32{
33 return (void *)&posix_lconv;
34}
libc/musl/src/locale/newlocale.c created+58
......@@ -0,0 +1,58 @@
1#include <stdlib.h>
2#include <string.h>
3#include <pthread.h>
4#include "locale_impl.h"
5
6static pthread_once_t default_locale_once;
7static struct __locale_struct default_locale, default_ctype_locale;
8
9static void default_locale_init(void)
10{
11 for (int i=0; i<LC_ALL; i++)
12 default_locale.cat[i] = __get_locale(i, "");
13 default_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];
14}
15
16int __loc_is_allocated(locale_t loc)
17{
18 return loc && loc != C_LOCALE && loc != UTF8_LOCALE
19 && loc != &default_locale && loc != &default_ctype_locale;
20}
21
22locale_t __newlocale(int mask, const char *name, locale_t loc)
23{
24 struct __locale_struct tmp;
25
26 for (int i=0; i<LC_ALL; i++) {
27 tmp.cat[i] = (!(mask & (1<<i)) && loc) ? loc->cat[i] :
28 __get_locale(i, (mask & (1<<i)) ? name : "");
29 if (tmp.cat[i] == LOC_MAP_FAILED)
30 return 0;
31 }
32
33 /* For locales with allocated storage, modify in-place. */
34 if (__loc_is_allocated(loc)) {
35 *loc = tmp;
36 return loc;
37 }
38
39 /* Otherwise, first see if we can use one of the builtin locales.
40 * This makes the common usage case for newlocale, getting a C locale
41 * with predictable behavior, very fast, and more importantly, fail-safe. */
42 if (!memcmp(&tmp, C_LOCALE, sizeof tmp)) return C_LOCALE;
43 if (!memcmp(&tmp, UTF8_LOCALE, sizeof tmp)) return UTF8_LOCALE;
44
45 /* And provide builtins for the initial default locale, and a
46 * variant of the C locale honoring the default locale's encoding. */
47 pthread_once(&default_locale_once, default_locale_init);
48 if (!memcmp(&tmp, &default_locale, sizeof tmp)) return &default_locale;
49 if (!memcmp(&tmp, &default_ctype_locale, sizeof tmp))
50 return &default_ctype_locale;
51
52 /* If no builtin locale matched, attempt to allocate and copy. */
53 if ((loc = malloc(sizeof *loc))) *loc = tmp;
54
55 return loc;
56}
57
58weak_alias(__newlocale, newlocale);
libc/musl/src/locale/pleval.c created+158
......@@ -0,0 +1,158 @@
1#include <stdlib.h>
2#include <ctype.h>
3#include "pleval.h"
4
5/*
6grammar:
7
8Start = Expr ';'
9Expr = Or | Or '?' Expr ':' Expr
10Or = And | Or '||' And
11And = Eq | And '&&' Eq
12Eq = Rel | Eq '==' Rel | Eq '!=' Rel
13Rel = Add | Rel '<=' Add | Rel '>=' Add | Rel '<' Add | Rel '>' Add
14Add = Mul | Add '+' Mul | Add '-' Mul
15Mul = Prim | Mul '*' Prim | Mul '/' Prim | Mul '%' Prim
16Prim = '(' Expr ')' | '!' Prim | decimal | 'n'
17
18internals:
19
20recursive descent expression evaluator with stack depth limit.
21for binary operators an operator-precedence parser is used.
22eval* functions store the result of the parsed subexpression
23and return a pointer to the next non-space character.
24*/
25
26struct st {
27 unsigned long r;
28 unsigned long n;
29 int op;
30};
31
32static const char *skipspace(const char *s)
33{
34 while (isspace(*s)) s++;
35 return s;
36}
37
38static const char *evalexpr(struct st *st, const char *s, int d);
39
40static const char *evalprim(struct st *st, const char *s, int d)
41{
42 char *e;
43 if (--d < 0) return "";
44 s = skipspace(s);
45 if (isdigit(*s)) {
46 st->r = strtoul(s, &e, 10);
47 if (e == s || st->r == -1) return "";
48 return skipspace(e);
49 }
50 if (*s == 'n') {
51 st->r = st->n;
52 return skipspace(s+1);
53 }
54 if (*s == '(') {
55 s = evalexpr(st, s+1, d);
56 if (*s != ')') return "";
57 return skipspace(s+1);
58 }
59 if (*s == '!') {
60 s = evalprim(st, s+1, d);
61 st->r = !st->r;
62 return s;
63 }
64 return "";
65}
66
67static int binop(struct st *st, int op, unsigned long left)
68{
69 unsigned long a = left, b = st->r;
70 switch (op) {
71 case 0: st->r = a||b; return 0;
72 case 1: st->r = a&&b; return 0;
73 case 2: st->r = a==b; return 0;
74 case 3: st->r = a!=b; return 0;
75 case 4: st->r = a>=b; return 0;
76 case 5: st->r = a<=b; return 0;
77 case 6: st->r = a>b; return 0;
78 case 7: st->r = a<b; return 0;
79 case 8: st->r = a+b; return 0;
80 case 9: st->r = a-b; return 0;
81 case 10: st->r = a*b; return 0;
82 case 11: if (b) {st->r = a%b; return 0;} return 1;
83 case 12: if (b) {st->r = a/b; return 0;} return 1;
84 }
85 return 1;
86}
87
88static const char *parseop(struct st *st, const char *s)
89{
90 static const char opch[11] = "|&=!><+-*%/";
91 static const char opch2[6] = "|&====";
92 int i;
93 for (i=0; i<11; i++)
94 if (*s == opch[i]) {
95 /* note: >,< are accepted with or without = */
96 if (i<6 && s[1] == opch2[i]) {
97 st->op = i;
98 return s+2;
99 }
100 if (i>=4) {
101 st->op = i+2;
102 return s+1;
103 }
104 break;
105 }
106 st->op = 13;
107 return s;
108}
109
110static const char *evalbinop(struct st *st, const char *s, int minprec, int d)
111{
112 static const char prec[14] = {1,2,3,3,4,4,4,4,5,5,6,6,6,0};
113 unsigned long left;
114 int op;
115 d--;
116 s = evalprim(st, s, d);
117 s = parseop(st, s);
118 for (;;) {
119 /*
120 st->r (left hand side value) and st->op are now set,
121 get the right hand side or back out if op has low prec,
122 if op was missing then prec[op]==0
123 */
124 op = st->op;
125 if (prec[op] <= minprec)
126 return s;
127 left = st->r;
128 s = evalbinop(st, s, prec[op], d);
129 if (binop(st, op, left))
130 return "";
131 }
132}
133
134static const char *evalexpr(struct st *st, const char *s, int d)
135{
136 unsigned long a, b;
137 if (--d < 0)
138 return "";
139 s = evalbinop(st, s, 0, d);
140 if (*s != '?')
141 return s;
142 a = st->r;
143 s = evalexpr(st, s+1, d);
144 if (*s != ':')
145 return "";
146 b = st->r;
147 s = evalexpr(st, s+1, d);
148 st->r = a ? b : st->r;
149 return s;
150}
151
152unsigned long __pleval(const char *s, unsigned long n)
153{
154 struct st st;
155 st.n = n;
156 s = evalexpr(&st, s, 100);
157 return *s == ';' ? st.r : -1;
158}
libc/musl/src/locale/pleval.h created+8
......@@ -0,0 +1,8 @@
1#ifndef PLEVAL_H
2#define PLEVAL_H
3
4#include <features.h>
5
6hidden unsigned long __pleval(const char *, unsigned long);
7
8#endif
libc/musl/src/locale/revjis.h created+515
......@@ -0,0 +1,515 @@
131,80,81,87,14,299,74,61,12,344,62,63,1280,1281,1282,1283,1284,1285,1286,1287,
21288,1289,1290,1291,1292,1293,1294,1295,1296,1297,1298,1299,1300,1301,1302,
31303,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325,
41326,1327,1328,1329,1330,1331,1332,1333,1334,1335,1542,1536,1537,1538,1539,
51540,1541,1543,1544,1545,1546,1547,1548,1549,1550,1551,1552,1553,1554,1555,
61556,1557,1558,1559,1560,1561,1562,1563,1564,1565,1566,1567,1568,1584,1585,
71586,1587,1588,1589,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,
81602,1603,1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,
91590,29,28,33,37,38,39,40,342,343,36,35,338,75,76,263,77,337,266,267,265,268,
10300,301,302,318,303,319,281,282,60,324,326,70,315,297,298,288,287,328,329,71,
11327,325,321,65,320,68,69,322,323,285,286,283,284,316,317,1792,1803,1793,1804,
121794,1805,1795,1806,1797,1808,1796,1807,1798,1819,1814,1809,1800,1821,1816,
131811,1799,1815,1820,1810,1801,1817,1822,1812,1802,1818,1823,1813,258,257,260,
14259,262,261,256,93,90,92,91,349,89,88,73,72,341,340,339,0,1,2,22,24,25,26,49,
1550,51,52,53,54,55,56,57,58,264,269,43,44,32,
16768,769,770,771,772,773,774,775,776,777,778,779,780,781,782,783,784,785,786,
17787,788,789,790,791,792,793,794,795,796,797,798,799,800,801,802,803,804,805,
18806,807,808,809,810,811,812,813,814,815,816,817,818,819,820,821,822,823,824,
19825,826,827,828,829,830,831,832,833,834,835,836,837,838,839,840,841,842,843,
20844,845,846,847,848,849,850,10,11,20,21,1024,1025,1026,1027,1028,1029,1030,
211031,1032,1033,1034,1035,1036,1037,1038,1039,1040,1041,1042,1043,1044,1045,
221046,1047,1048,1049,1050,1051,1052,1053,1054,1055,1056,1057,1058,1059,1060,
231061,1062,1063,1064,1065,1066,1067,1068,1069,1070,1071,1072,1073,1074,1075,
241076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086,1087,1088,1089,1090,
251091,1092,1093,1094,1095,1096,1097,1098,1099,1100,1101,1102,1103,1104,1105,
261106,1107,1108,1109,5,27,18,19,3915,8793,6934,10843,7493,6671,7492,4379,10291,
2711294,12033,4110,4685,12034,7939,12577,5173,10521,7494,11549,10529,12035,8773,
2812036,5465,12037,4924,8719,6982,12038,12039,12040,9748,5174,9750,9538,5922,
2910770,18472,12041,7495,12042,4372,5444,5967,11080,13573,11343,9564,4868,5140,
3012043,12044,11546,11292,8263,12046,6741,9554,12049,4125,5950,5949,3909,11818,
3111817,6418,3840,12050,12051,12052,10771,12053,5969,3910,10833,5211,5212,5213,
329025,11547,12054,12055,12056,7724,7193,7725,12061,12059,12060,5175,6402,4431,
3312058,12057,10504,6693,6692,8477,12062,10292,8006,23,12063,12065,8516,11584,
343881,12064,4381,5411,8774,5710,12066,9731,4938,12067,3882,5951,4939,10329,
3510001,5176,4432,12102,9248,9803,12069,10011,11585,7692,6694,6742,4383,9008,
368705,12073,3883,9026,7194,6419,11267,8493,4382,12072,11293,12068,12070,6477,
3712071,13315,12079,12082,12080,4385,10522,12074,12078,5970,6695,4869,12083,
3812075,11586,6743,12076,12081,12084,12077,5376,3884,5377,4384,13316,10840,
3910317,5971,7694,11542,10551,5655,8452,4419,7218,12088,12093,12091,12086,8462,
4012089,12092,12090,10556,12087,7693,10834,12094,12095,7171,12108,9775,10261,
4112103,10575,4373,12107,12101,12110,8241,5923,9787,16166,12109,9276,12098,5973,
425972,12096,6969,12104,10574,8748,12100,5712,12097,12105,12099,11568,12106,
4311808,5445,5711,12111,12112,12116,3885,10543,12115,12114,12118,12117,9027,
445713,12119,6948,8453,9028,5461,12120,5141,12121,12123,10772,5701,6672,10070,
4512122,6436,11298,12125,12290,12124,6435,7260,5656,12291,5422,12288,12289,9486,
468283,5378,10796,12292,11548,12293,12296,12294,8237,12295,12297,12299,12298,
4710535,5142,12301,12302,4366,12300,6995,12305,12304,12303,12085,12306,7261,
4812307,11268,11064,12309,12308,12311,12310,12312,12313,3923,5908,5658,7195,
498794,5379,8007,5974,6221,12315,11047,9253,6744,12314,12316,9277,4692,12317,
509565,8211,12319,12320,9995,5975,11802,12321,5381,10523,8469,5456,
519236,5714,12322,12323,9537,4158,12326,6492,12325,6437,12327,17741,12328,10784,
5212329,12330,12331,7496,6955,4870,12334,12332,11036,12333,10297,12335,12336,
5312337,9278,12341,12339,12340,12338,6466,12342,11081,11587,12343,7943,12344,
547225,12345,8795,11550,9279,12580,12346,21252,5412,12347,10813,7239,8539,12349,
559539,12350,12351,4621,12352,5382,9515,4185,7215,9984,12353,9280,7726,12354,
5610507,7993,4865,4872,12355,12357,5657,12356,11602,7240,10012,10539,12358,
5711351,12359,12360,9309,12361,7944,6493,5715,12362,6696,6222,9029,12364,8454,
586478,12365,12366,8207,12363,12368,10773,6211,12367,5716,6461,9804,12371,12369,
5910330,7497,12378,4675,12372,12370,8238,12374,12373,4643,5695,12379,11532,
6012375,12380,12377,12376,11566,5976,4386,11603,7252,9271,6212,12545,12546,
6111588,11786,12548,5977,12547,4622,12549,10805,8987,11269,10552,12550,20276,
629487,12551,4873,11026,7424,12552,10566,12556,7945,12553,5423,12554,4874,5645,
6312557,12558,12559,12560,6970,5978,11069,11079,9558,10576,12561,12562,12564,
6412566,12565,12567,4380,10795,6491,12568,8248,7425,5384,12569,10042,12570,
6512571,12572,12573,10243,5447,3908,9502,12574,7196,8008,12576,12575,7426,5952,
6612578,10013,12579,10043,8467,8525,5383,9549,8720,9805,10797,12581,8009,5652,
6712582,12583,4107,3924,4940,8455,5168,11344,12586,4374,12585,5385,12587,11088,
6812588,11569,5979,5909,12589,12591,12590,7742,4120,4157,12592,12593,5910,12594,
695197,6673,12595,10835,6420,5177,11270,8239,10014,7004,7206,6983,
706996,7253,10015,12598,4130,8240,5980,5924,5446,12602,8704,8541,5386,7427,
7112603,12601,4387,8517,6935,6698,4101,4687,6213,6697,12604,12605,5160,4645,
726214,5159,9022,4100,9488,11037,6144,11352,9254,5981,5646,12614,5442,10793,
7310044,12613,4925,12608,12609,12611,12612,5178,7744,10508,12610,12606,5954,
7412607,11779,10577,9031,5953,6223,12615,9532,12619,7005,6997,12622,12620,11010,
7512617,12626,12621,12624,5925,11038,12625,12627,12629,6479,11809,12618,12616,
7612628,12623,12631,12802,12633,12637,12800,12634,12829,6472,4624,12632,12804,
773925,12803,3844,10281,12801,12635,12630,12636,6439,12805,3926,12814,12806,
7812807,7428,10824,12812,12811,9230,12813,12810,4115,6421,7695,12808,9281,12809,
793841,12819,11266,7430,12825,12824,12815,8482,12816,8526,12821,7429,12818,
8011075,5659,12822,12823,12820,12826,12817,12832,12837,12833,12828,12838,8208,
8112840,6145,12830,8796,12834,12827,4876,4941,4676,12835,12831,5717,12841,12839,
828242,5161,5387,12836,5459,4131,12845,12843,13062,12848,12842,12846,12844,6699,
8312847,12850,12855,12853,12852,8721,4388,12849,12851,7431,4114,12854,4413,
8412865,7515,12861,12859,12860,12862,4124,8216,12856,12857,4697,12864,4942,
8512867,12863,12866,10509,9524,10007,12869,12868,4644,12870,12873,12872,12871,
869752,12874,12875,12877,12876,12879,12882,12880,12878,12881,12883,12884,12885,
8712886,12887,12324,7003,6700,4434,3927,8739,12888,6403,3886,7741,12889,5926,
886224,12891,12890,10559,12892,13056,12893,13057,13058,5718,4159,13059,13061,
8913060,
9013063,9273,13064,3860,6462,5660,8750,13065,13066,13068,13069,6467,5424,10774,
9113067,13070,6432,6146,13074,6404,8722,13071,9017,13075,7745,13073,13076,5662,
9213077,13078,6147,4639,13080,13081,13082,13079,13072,13083,13084,10819,7498,
9313086,13087,13085,13089,9751,3911,10293,13090,7516,6936,9788,4943,6474,10808,
949489,5719,8494,13088,13091,8483,13092,13093,13095,9032,4877,21248,4160,10578,
957499,9255,6469,13101,10524,11580,4435,13097,8217,13100,9282,9256,9283,10008,
969004,6440,13096,4181,9237,13098,13094,7727,13102,7213,5388,13103,10567,8284,
978997,13105,10798,13106,13111,10510,13110,13104,13107,13109,6405,10536,13112,
988740,4436,7500,13114,13113,6215,13115,13117,13116,13119,13108,13121,13120,
9913118,6701,7728,8243,13122,7963,3916,9795,9018,13124,13123,13125,13126,13127,
10013128,10544,13129,4389,13130,11291,4623,12584,7207,8478,13131,11082,11027,
10113133,8518,9238,8479,10294,13134,13135,4186,6937,13136,3887,13137,13138,4161,
1024944,9535,10579,13142,8244,13141,5663,10810,13140,9284,13144,13143,13146,
10313145,4187,13147,7432,13149,8708,13148,10514,7254,9274,13312,6148,13313,9728,
10410045,11056,9732,13322,5143,11300,11022,13579,13314,13317,8484,10775,9257,
10513318,10820,6441,7433,13319,6703,6702,3864,5927,7946,3888,13323,13324,13321,
1064119,4878,13320,11044,10256,3847,3928,6704,3889,3842,13329,13327,11035,13330,
10713328,13326,7696,13325,10553,5955,13334,13335,7434,13331,11787,9771,13333,
1086406,13336,10295,13337,13332,11034,9789,13338,10257,13339,13343,
10913340,4390,13342,6938,13341,5720,13355,13348,13345,8771,13344,13346,13347,
11013349,13350,4945,13352,13351,13353,7501,13356,9019,4132,13354,13357,13358,
11113361,13359,13360,6705,13362,6149,13363,6745,8471,13364,13365,6713,6150,11057,
1125127,5928,13366,4663,13367,8472,13368,13570,13369,13370,13371,13373,13374,
11313375,8527,4102,6984,3873,8246,4879,6932,6151,9285,7168,4880,8775,9033,3863,
1145144,10580,6945,5169,8010,6939,11271,13376,5179,6442,4625,4162,7435,4391,
11513377,11301,7208,6979,13378,4946,9521,11016,13379,13380,10296,13382,4871,5462,
11613381,4881,7697,13386,6656,4392,13385,13383,13387,13384,9738,15148,7698,13388,
11711551,13389,13391,8797,13390,7938,6746,8495,6998,10324,8011,6956,13392,7436,
11813393,13394,3890,8473,7729,13395,9490,7437,7438,13396,8012,7439,13397,13398,
11911071,13399,5413,7169,13400,13401,6971,7691,9555,7731,10071,9729,5416,13402,
1205198,13403,5469,9518,4367,6706,13404,13569,13568,5468,13405,9239,8463,9258,
1216951,8247,11353,13571,13572,9525,6674,13574,13575,13576,4947,13577,13578,4363,
1228218,4931,13580,11015,8497,4664,13582,13584,4926,13581,13583,13586,13585,
12313587,13588,9500,5389,4420,13589,13594,13592,10582,10581,9286,13591,7219,
12413590,7761,13595,6473,13601,13602,13596,4626,13597,13606,13605,13604,13600,
12513599,13603,10583,13610,13607,13609,11345,13608,13598,7762,13611,6422,13612,
12613613,13616,13615,13614,9287,13593,13622,13618,13617,13619,13620,13623,11589,
12713624,13621,13625,4927,13626,13628,13627,13629,13630,8013,7170,
1287235,8258,6152,6423,6153,5199,13631,6424,5929,13632,11013,9762,13633,6154,
1294875,8710,5425,6707,10298,10016,13634,4948,13637,8960,13636,13635,13638,9034,
1307746,6708,7977,8498,5121,8961,13639,13640,7502,10776,13643,13642,13641,10332,
13113650,10809,13644,13646,10826,13645,13647,9991,13648,10525,13649,4882,10526,
1329742,13651,13652,6155,4883,13653,5911,11299,11272,4949,13655,8962,6156,7440,
13310046,7441,7255,9035,10584,9240,6157,10299,13656,9272,6433,5930,9036,3874,
1347245,6158,11302,13657,13658,9776,13659,11606,11788,13661,13660,4646,13824,
13513827,13828,13826,10271,7442,13830,13829,13825,13831,13832,13833,13836,13834,
13613835,13837,4163,9037,13838,5721,4437,9749,13839,9562,10554,13840,11789,13841,
13710527,13844,12032,12048,6927,9556,13845,5180,8963,3929,13846,10501,6159,8751,
1389038,11086,5912,5931,13847,13848,13854,6980,8964,5390,13849,10250,8741,13850,
13913851,5391,13852,13853,13855,9301,13856,13857,13858,13843,13842,13859,5664,
14010246,6443,10262,8965,10282,13860,7443,4133,13861,13862,11089,10047,13865,
1414188,7947,13864,13863,5665,8499,13869,13867,13866,11526,5956,7256,13868,9259,
1427197,9503,13872,13871,13870,13873,5957,13874,10331,7226,13875,10072,9504,8966,
1439231,13876,5130,7699,10251,4950,9733,13877,6709,10777,10778,4189,13882,8776,
14413879,4438,14092,13881,9743,13880,13878,6233,13884,13890,13896,13888,9275,
14513893,10300,13887,13892,11590,6710,8500,13885,5181,13895,7948,4164,13889,4439,
14613894,5392,13891,13897,13899,13909,13907,13904,13903,11607,
14713905,5393,6160,7257,13912,13898,13902,13886,4441,13906,13908,8752,6407,4375,
14813900,13911,13910,5394,8456,4677,5666,13901,13913,13916,14080,6940,14086,9039,
14913914,14084,4440,14082,14083,13917,14081,5958,11273,4884,4152,14085,9753,3852,
15010048,13883,14091,14095,11076,14088,9288,14093,7503,14094,9526,11814,14090,
15114096,6234,7978,3891,14089,14087,8249,13915,6675,8485,14108,8250,14103,14100,
15214101,6981,14104,14107,14102,7172,14105,14099,11099,11098,14109,14110,3892,
15314098,5457,3845,4885,14106,14114,14113,14118,14119,14117,14120,14112,14116,
15414121,14122,14111,6747,14115,8501,6161,14097,7700,14135,10568,14125,14126,
15514127,14134,14133,10844,4886,14131,5668,4627,14128,11543,14130,3893,14132,
15614123,14129,14136,5667,14124,11324,11274,14139,14143,8285,11608,14144,14141,
15714138,14137,14142,10511,9491,5669,14145,14140,14146,5722,4368,14154,4887,
15814152,14153,6408,14151,14149,14148,14155,14147,14157,4442,14159,14158,8967,
15914162,14160,14150,5723,14161,14165,14164,14166,14163,14167,14168,14169,10569,
16014171,14170,7198,7949,4421,4443,14172,3870,7979,14173,19234,14336,5696,14337,
1618014,14338,14339,5145,14340,14341,14342,8502,5932,11072,10779,7241,14343,8015,
16219740,10049,6985,6444,14344,8486,10502,8528,14347,14345,14348,14346,14349,
16310512,3862,10301,10050,14350,14353,7444,5146,14351,14358,7445,14352,9763,
16411325,14354,14355,14359,9289,14356,6162,7997,14373,10003,8529,10051,14604,
16510585,9040,10836,14362,4352,8777,14371,8723,14365,14372,14367,14374,14370,
16614369,9806,14363,
1674444,14361,5200,8530,14357,14360,6163,7994,7446,14368,9777,5201,4647,4678,
1687680,14376,14381,14377,5724,14382,6657,6216,7173,14364,6748,14379,6711,14380,
1693875,14375,8968,5202,5395,14378,3846,6434,7701,9041,10035,14384,8253,8457,
1706666,14385,14387,14383,10560,8988,8251,10586,6957,14399,14398,7767,5725,14392,
1717448,9543,9744,14390,8252,6999,14395,7447,14389,14394,9778,14388,5632,4668,
17214396,11530,6445,8724,14393,7995,6164,7747,4165,8219,14391,5156,5670,9006,
17314397,8254,14400,14402,8470,14408,14403,14405,10272,9042,14406,11275,11303,
1744888,3853,14404,14401,4951,4166,14407,11304,14411,8474,14418,14412,14409,
17514416,14386,14413,14417,10017,9290,14410,14414,5671,6480,7996,14422,9221,
17614419,10815,14420,14421,11053,7937,5697,14428,6676,14425,14424,9745,9492,9232,
17714426,14427,10318,9764,6658,8016,10799,4648,14596,14429,11305,14598,14594,
17814595,8255,14593,14366,14597,14592,14602,14603,9222,14605,6659,14600,5147,
17914606,14599,14610,14609,14608,14611,14613,7504,14612,14616,14614,14615,14415,
18014618,14617,14423,14619,14607,6712,14620,14621,14623,14622,14624,4445,6165,
18110587,7950,5933,14626,14629,10289,5182,14628,14627,9779,14630,5396,14632,
18214631,4889,6677,9527,5672,7763,14633,7951,9223,10302,14634,14635,14636,10519,
18313372,7973,10283,6455,10052,10018,9260,11552,14638,6959,14639,3861,5427,7980,
18410303,14640,6689,8742,6714,7702,14641,10588,4182,6715,14644,14642,14645,11544,
18514643,8026,14646,8465,14647,4953,14649,14648,14650,14651,4954,9563,
1868725,5195,6716,8256,7227,3855,14652,4353,14656,6166,14655,6410,7449,14654,
1877450,11039,6409,3894,7981,14661,7952,4134,7220,10821,6481,7451,7942,14660,
18814658,14659,8778,14853,14665,6749,6167,14663,14664,7703,14662,6670,14667,
18914666,14671,14672,14668,4609,14669,14670,10036,10304,5673,14673,7953,7452,
1908753,5414,14674,14678,4394,14675,14677,14676,7242,8743,3876,14679,14680,8969,
19111600,6690,10570,10780,14849,14682,14685,14684,14681,14848,9533,14683,14850,
1927243,14851,11306,9815,14852,14854,14855,14856,5417,4135,6168,14857,14858,7248,
1938257,12599,8221,8220,8503,6438,12113,5709,11276,10589,10333,14859,6482,8990,
19414860,11790,10781,8970,14861,4955,14862,14863,11065,11011,10837,10811,6660,
19514865,6986,10800,14867,14870,14869,4952,5183,14866,14868,14871,7768,11354,
1963880,6463,8475,6972,7506,14874,9261,14872,8458,14873,7505,11068,14875,14876,
19711335,14881,6169,9780,14878,9291,14653,14657,5166,9766,14880,7453,10019,14886,
19810073,14877,14883,14882,7982,10828,11570,10822,4395,6717,11815,14885,7764,
19914884,14879,5934,14891,14889,4396,14887,14893,14899,8487,10528,14901,10241,
20014900,9807,10782,4890,8022,7199,9010,11277,14896,14895,14897,14894,14902,
20114892,14890,14898,14888,8779,11095,6949,6483,6425,10830,4640,9005,9513,4136,
2028017,7955,5641,14904,6170,4699,14906,4691,14912,14909,8018,4650,6411,4649,
2036446,14907,5700,5674,9292,14905,3877,14908,14910,5420,5643,4891,5162,14913,
2046488,10832,6678,14914,10255,14926,4370,14915,14932,14916,11553,14923,
2059790,14931,14918,3859,14920,6171,14922,14921,14917,14928,7454,13132,5959,
20611355,14919,9043,4610,6412,14911,14927,4672,14925,14929,9293,4957,15121,11048,
20714934,4956,14941,10783,15104,15106,15110,14936,8713,9294,15114,14939,15111,
20815105,7704,15115,7954,15113,4892,11823,14933,15109,3895,14935,11033,14940,
2097681,8998,14930,15108,7769,15118,4688,5888,15120,14937,15119,15112,14938,
21015116,15117,15134,9517,15107,15130,15132,9015,11307,10325,15127,8489,15133,
2118222,15124,15137,15136,9550,15135,9545,15139,15126,5415,15129,7228,9791,15131,
2125418,15123,15125,15122,11791,4665,15128,15138,4628,6470,4156,15155,11792,
21315158,7705,15157,15156,15153,15141,15170,15140,15159,15151,15146,15143,15144,
21415152,21249,15149,6172,8999,8259,15147,15142,15145,11308,10825,15150,15160,
21515168,15161,15174,15172,15167,15166,9007,8260,15164,15162,15169,15175,10068,
21615181,15176,15179,15173,8787,10263,15163,15171,7455,11054,15191,15178,5889,
2174354,4670,15154,7456,15183,15190,7000,4689,8717,15180,15185,15189,5397,5163,
21815187,5120,9514,15186,15188,15182,15184,4671,8744,15195,15193,5960,15192,
21915360,14903,15194,15196,15197,15371,15367,14924,15366,15365,15362,15177,15364,
22015363,15369,11781,15372,5466,15368,15370,9990,15373,15377,15374,11346,15375,
22115165,15378,15379,4116,15381,5702,6912,5428,4355,11326,15383,15382,15385,5148,
2225429,4893,15388,15387,15389,4397,8726,15390,4894,15392,15391,15393,15394,
22315395,6718,7956,6400,10319,10561,11811,6740,6447,11601,15396,15397,6719,15398,
22415399,15401,15400,10807,
2257229,6987,6691,15402,15404,7682,15403,15405,15406,15407,15408,15409,15411,
22615410,15412,4356,8745,15413,6661,4651,15414,9249,13099,5122,15415,15416,10571,
22710823,9510,15417,10053,10074,11058,15418,15420,15419,15422,15421,15424,6720,
22811024,15425,15426,5123,15427,15429,15428,7748,10264,4137,10020,9044,7200,5184,
22910021,6925,15431,4895,4183,9553,15430,6173,8754,15432,15440,15433,8480,5185,
23015441,5703,5124,15439,15437,15434,11327,8991,9528,15435,15443,15442,5634,4364,
2316426,15436,15438,10806,8531,10838,15451,15452,4398,10503,11100,15616,6914,
2327457,15447,15453,4167,5398,15444,15449,8019,9808,10054,15446,10752,15448,
23315619,15617,15450,10753,9767,5186,9220,8780,15620,15618,8504,15445,4138,11309,
23415631,15630,8021,15627,11339,9493,15621,8996,4139,6174,15624,7174,15629,15628,
23515623,15626,4679,15625,9768,11533,7507,8020,15637,15635,10284,15632,15634,
2364121,6175,11793,4636,10305,11328,4611,7706,15636,15641,7458,11279,15638,15633,
23715639,11581,9298,9505,4629,4148,15645,15648,11554,11331,15655,15649,15646,
23811571,15652,7209,15654,15659,9296,15657,15651,8727,15658,15647,15653,15660,
2393931,15650,15661,7707,7230,10500,6413,15642,15656,9241,7957,4680,6448,7459,
24015644,7201,5675,15643,15665,7244,5913,15680,15674,5203,9262,15669,15678,3854,
2414113,4376,15671,8459,15662,15664,6176,15681,15676,15668,15675,11018,15673,
24215677,5935,7460,8728,15667,11278,15670,15663,9297,15666,15672,11824,6941,
24310845,15682,9997,15694,5914,7231,15684,11534,6177,15697,3917,15695,15683,
24415689,15691,11310,15686,9229,15688,15696,15690,11046,15685,6913,15709,4681,
24515687,15692,15693,8523,8505,15701,15707,15705,9224,15874,15702,15703,15679,
2465208,10265,6942,6230,11794,15699,15873,4168,8261,9816,4896,11609,11008,9009,
24715706,15708,8209,15872,15704,15698,4898,5704,15886,15881,8023,4674,7232,15890,
24815883,8971,15880,9016,15915,15877,15876,15885,15879,15878,15884,7936,15875,
24915887,15888,4897,15893,15892,15894,15897,9250,15891,15895,5698,8536,15889,
2509754,15896,15901,15899,15902,15905,15898,6217,9735,15640,11347,15900,15904,
2518532,15903,15882,20040,15908,15912,15910,15906,15907,15911,15909,10285,15917,
25215914,15913,15916,9523,15918,8788,8524,7940,15919,15921,15920,15700,15922,
2539542,15923,4399,9299,4612,5187,6973,6449,11782,7749,4169,15925,15924,15928,
2548729,15931,15926,15930,15929,9247,3896,11604,15933,4103,15935,15934,15932,
25515927,10754,15937,15936,4170,15939,10513,15938,11028,7462,8210,7461,11610,
25615945,8024,15941,15946,4171,15944,9792,15940,15943,7463,10032,15947,6960,8025,
25715950,15942,5638,15948,11311,15951,21253,7214,15952,15953,9741,15955,15956,
2589746,9300,15958,15960,11572,15957,15959,4172,15954,12858,15961,8262,6679,
25915963,15962,7683,12600,15964,16128,15949,15965,16129,9817,16130,16131,16132,
26016133,9021,16135,16134,16136,16137,6974,10306,11083,16138,16139,8245,6915,
26116140,16141,16142,10545,10022,16143,9782,8972,16144,4422,5196,11045,11029,
2624371,11795,10801,10505,7958,16145,9506,5890,16146,6451,16148,16147,16149,
26316150,16151,5149,16152,16153,
2645891,10023,16155,7508,16154,5399,16156,16158,16157,16159,5936,16160,5448,8223,
2656236,16162,16163,16161,6988,9511,5400,16165,8715,16164,11796,9793,16168,16170,
26616167,11059,16169,16171,11555,16175,16174,8789,9740,5892,16173,16172,11280,
26711281,16176,4173,6229,6721,16177,16178,16180,7202,16182,16181,16183,4652,
26816185,16184,16187,16186,5915,11527,5419,4357,5449,4928,11591,16189,16191,
26916192,4400,16188,6680,8992,16190,16195,6989,16193,5661,10024,16194,16221,
27016200,5916,5188,16197,11356,11535,8533,16199,16201,11573,5430,10075,9769,
27116202,16204,16207,16203,16206,5961,4140,16208,7759,16205,11579,16211,21251,
27216209,16212,16198,16210,6427,16213,16214,11357,16215,16216,16196,16217,4899,
2736916,16218,16219,16220,4122,16384,10266,16385,4867,16386,16387,16388,16390,
27416391,16389,10290,16393,16392,16395,16394,16396,16397,16399,16398,6232,16401,
27516400,4900,7730,9243,16402,7959,6681,4184,16403,11312,10562,16404,9251,11282,
2766178,7708,8746,12563,8973,4423,16405,16406,16411,16409,16408,14625,4613,16407,
2773897,9993,10025,11536,16412,16410,8763,7941,9994,10252,16414,11531,5676,16415,
27816413,10037,16416,16417,3898,7509,16422,16419,9548,16418,5125,16425,16420,
27916421,16424,16423,10244,8225,8224,5150,16426,16427,16428,16430,16429,4149,
28016438,10055,16432,16434,16436,7709,16437,16435,6943,16431,16433,10273,7464,
28116440,16439,16441,6917,6414,9302,16442,9002,16444,11520,16443,8264,16449,
28216451,16452,8755,16450,16447,16445,16446,16448,16455,16453,16454,16456,16458,
28316459,16460,16461,16457,
28416463,16462,16464,11556,16467,16465,16466,4929,11101,10537,16469,16468,16470,
28516471,16475,16472,16473,16474,16476,16477,16640,16641,16642,9998,9263,16643,
2869809,10259,16644,16645,9225,4614,6179,16646,16647,16648,6664,16650,16649,
28716651,16652,10056,16653,16654,21064,16655,16656,16657,6669,16658,9781,10814,
2884141,4150,16659,16661,16660,9295,7960,15384,16662,11040,16663,4901,10038,
28916664,16665,16666,11067,11060,8989,8265,16668,7233,7465,16671,16670,16669,
29010076,4902,5896,16677,16674,7710,11025,16673,16675,16676,16672,16678,16679,
2918974,4930,8772,16680,16681,16684,7750,9507,16685,10802,16682,16683,16688,
29216687,16686,16690,16689,16691,16693,16692,10540,7221,11557,16694,9494,16695,
29316696,16700,16698,16699,16697,16701,16702,16703,16704,11030,16705,11087,16706,
2948749,9801,5450,8730,16707,5401,7983,16708,6428,16709,16710,5893,6452,16712,
2959269,6453,5165,10755,9770,9270,6203,16714,7466,11537,6180,5894,9986,16716,
29616718,5962,16717,9045,16720,4630,16715,10057,4111,6475,11825,16719,16721,
29710538,7992,16723,16724,16722,4653,16730,16729,6918,16731,16726,16732,16727,
29810039,16725,16728,16897,16896,10816,16733,3914,16899,16898,7467,16900,8226,
29916902,16901,16903,16711,16713,16905,16904,6919,11592,6961,16906,5654,5151,
3005126,6722,11283,16912,16911,8227,16908,16910,7210,7711,16909,16907,9737,7468,
30110267,6454,9303,16913,16914,16936,5431,11804,8212,16915,4401,9046,10496,16916,
3025209,16917,16919,16920,9736,16921,16922,16923,5432,4402,9508,7175,6723,16924,
3037176,4393,10274,16925,
30410058,8228,16928,16929,9800,7712,16926,8768,16927,7469,3899,5128,16930,9047,
30516931,7974,11020,10242,16932,16933,8756,11558,16935,16934,6990,16937,3919,
30616940,16938,4403,5677,16939,6181,6225,10565,16941,10803,16943,7984,4142,4377,
3073851,16942,16944,16945,7510,16946,4654,16948,5705,5189,16949,5460,16950,8027,
3089516,7999,6484,16951,8769,8266,16953,16955,16952,16954,5633,16956,5637,5190,
30911313,16958,16959,4109,16962,4693,16961,16960,16964,16957,16965,11528,16966,
31016967,13139,16969,16968,16970,16971,11540,16972,20302,7470,16973,16974,7222,
3119495,16975,8711,16976,8731,16977,5380,12318,8764,6930,4903,16978,17153,16981,
3125191,16980,17155,16979,7471,16983,16984,9226,16985,4669,7737,10307,16987,8519,
31316982,16986,16988,6490,17157,10253,9989,9304,5433,17156,17154,10004,16989,
3148765,9306,9305,6485,17175,17159,17161,17164,17165,17162,17163,17160,17158,
31517152,10542,4404,17172,17169,17174,17173,9810,11014,6682,17167,17176,17171,
31617170,17166,17168,4904,8732,8028,9985,17181,9987,8000,17178,10030,17182,10546,
3178762,17177,17179,17180,17183,6947,9509,17188,17187,17184,11797,17193,17197,
31817194,17190,17191,17196,17185,12596,17192,17186,17195,17201,4905,17198,17199,
31917200,17203,17202,10069,17204,11611,10572,17209,17206,17205,7985,17208,17210,
32017207,17214,17211,17212,17189,17213,17215,17216,10533,17217,11073,5421,5640,
32117218,10515,7751,11023,17219,11538,9811,8229,9747,7212,3871,17224,17222,17220,
3224864,7472,17225,17223,17221,17229,17228,17227,17226,17230,17231,7961,17232,
32317234,
32417233,5937,8215,17236,9307,17235,17237,10516,8267,6182,17238,11559,17240,
32517241,17242,17243,6724,17244,5678,5193,5129,17408,11090,6183,17245,17411,
32611077,9755,10258,7234,17410,6962,6184,6725,5192,10517,17409,8230,10785,6486,
3276726,9020,17414,11582,6456,17415,7713,17417,7473,6415,17416,7177,5917,8231,
32817412,17418,17413,5679,17421,17425,5706,17420,17429,6185,11340,3867,17426,
3295194,17423,17424,9308,17422,17419,4615,8003,5895,17431,17428,17430,17427,5680,
3308466,17432,8269,17445,17441,17435,17439,7001,3900,17434,17442,17446,6186,
33111061,9013,17436,17444,17433,8733,17438,3868,11049,17437,5434,10059,8268,
33211567,7246,17485,17447,8029,17443,17448,17450,9048,17453,17449,10547,4906,
33311050,3901,17452,11612,17451,4174,9547,17454,17461,17455,17462,17458,9818,
3346953,17460,17457,17463,17456,7203,10756,7211,17459,17471,17467,17470,17468,
33517472,17466,17440,7986,10026,17469,17464,8192,5681,7178,7684,8213,17475,17477,
33617478,17474,17476,17465,17473,17481,17480,10841,5642,17479,17483,17482,17486,
33717488,6683,17484,17489,17490,17491,17497,9242,17493,17492,17494,17495,17496,
33817498,17499,4907,17500,17501,17664,17665,17666,17667,17668,17669,17671,17670,
33917672,17673,17674,17677,17675,17676,6464,5682,8757,10002,7247,9772,10060,
34017678,14156,17679,17681,11332,17680,17683,17682,11314,17684,10077,17685,17688,
34117687,17686,17689,5649,8193,5152,17693,17690,17691,17694,17695,17692,4104,
3424358,17697,17698,17699,11329,7179,17701,17700,7752,17702,17703,17704,4932,
3434908,17705,17706,10812,11330,
34411315,11798,6188,17709,6963,17708,17710,6920,8496,17711,6187,11062,17712,
34517713,17714,17715,17716,6921,11084,17718,8734,17717,17720,17719,17721,7962,
34617722,17723,10520,17724,8270,17725,17726,11613,17729,17728,17727,8975,17730,
3477685,17731,17732,11799,17733,17734,17736,17735,9988,9560,11805,9992,17738,
3487474,10249,17739,17737,4909,5939,6727,10061,5897,10786,17742,17740,6189,6190,
3493912,6471,9784,3902,17747,8735,9783,8506,17749,17745,17748,17743,17746,10757,
3505940,3932,17744,17751,17752,9496,5402,17925,9756,6728,5403,7975,11813,11021,
35117750,7987,5170,17753,17755,17754,17756,8709,9757,8976,17922,17921,17757,7732,
35210308,17924,17923,6191,11826,17940,17928,17929,6991,17927,6231,17926,17930,
3538977,10497,8194,8507,17934,17935,17931,17932,17933,6192,17941,17937,10309,
35410827,10247,17936,17939,17938,10787,17942,17943,8214,17944,17946,17950,17947,
35517945,9758,17948,17949,4369,17956,17951,17952,17953,8448,17955,17954,17957,
35617958,17959,7714,4424,17960,11574,6922,7180,6729,8758,17961,17962,4112,17963,
35717964,17965,17966,17967,5404,14601,17968,8004,17969,6954,17970,12047,17971,
35810557,4923,8195,7223,10320,7181,17972,6193,17973,10027,17987,17975,8488,9812,
3595918,17974,8196,17976,9049,17978,17977,17980,17979,17981,17983,17982,4910,
36017984,17985,17986,6416,11560,17988,7686,4175,17989,17990,17991,3921,17992,
36117993,10310,6950,17995,4616,3857,17994,17997,9773,7715,4405,10758,5692,5435,
36217996,4425,4866,4176,18001,11593,8508,10275,18013,4406,18011,18009,18000,
36317998,17999,
3646978,5451,8790,9520,4144,18003,18002,18008,18004,18007,11055,18006,4407,4700,
36518010,18012,5683,18178,18187,18188,3850,18195,3920,18186,18185,18180,18179,
36618177,18176,8770,8538,18182,18181,18184,8271,5684,4128,18183,6194,8272,18201,
36718202,4408,4365,18199,18189,18197,18204,18198,18196,18005,18194,18190,4911,
36818192,18203,18193,18205,18191,9819,11336,18200,18222,18214,7770,5157,5436,
36918209,4410,7475,18212,6457,9264,18217,10573,18208,4409,5941,10248,18218,18206,
37018215,18225,18210,18211,9497,18216,18213,10759,18219,3903,18207,18221,18220,
3719802,18227,18238,4701,18241,18223,18228,11341,18237,11316,11529,8791,4682,
37210321,18243,9472,3856,18236,18232,8273,18226,18234,18239,9739,3849,18231,
37318240,10327,18235,18230,7476,7182,6923,11063,10278,18246,18255,18233,4694,
3747511,18244,18249,8274,18245,18252,8766,18253,11317,18242,4631,18248,18251,
37511019,18254,18247,18250,10760,11776,18258,18265,18257,6946,18224,10541,11009,
37618264,18263,18259,18260,4117,18262,18256,9012,18261,3933,8449,10530,18266,
37718432,10040,18269,7477,6952,18434,5405,18435,10328,18268,18229,18267,11822,
3789473,10322,18442,18448,18449,18436,9813,18446,18438,18440,18450,18439,18443,
3794177,9540,18444,18447,18437,8197,18441,6662,7716,5647,11091,11096,7249,18454,
38018452,11821,18451,11348,18453,18455,18456,18459,18457,9474,18458,10028,18445,
3817250,18460,18465,8275,18464,18433,18466,8232,18461,18463,18462,15376,15361,
38218468,18467,11349,16667,18469,18470,18471,5942,5171,18473,12348,5204,11545,
3835458,18474,18475,8781,18476,
3849561,3865,4418,18481,18482,18477,6684,18478,9761,18479,18480,18490,18484,
38518487,18483,18485,18486,6967,18488,8736,5685,4641,18491,4638,18496,18492,
38618495,10009,18493,18494,10279,10041,18497,8540,18507,18503,4426,18501,10761,
38718502,18499,18500,18505,18508,18506,18504,18498,8759,18515,11017,18513,18514,
38818509,18511,18512,18510,8005,11800,18519,18520,18688,7689,18522,18525,18517,
38918516,18689,4411,18523,18690,18524,18521,8978,18518,9799,18694,11290,18693,
39018692,18701,18695,18703,11333,18706,18697,18698,18702,18705,18704,18696,18699,
39118716,18709,18707,18708,18713,18714,4617,5153,18712,18691,18711,18715,18710,
39218717,18719,18718,18721,18720,18489,18725,18722,18723,18724,18726,5707,18728,
39318727,7183,6195,15622,18729,7216,4632,18730,4145,7478,18731,6196,18732,3904,
39410268,18733,7753,18740,18737,8782,18738,18735,5437,18734,18741,5653,8509,
39518747,18743,8468,18742,18745,18736,18746,18748,10062,18744,18749,18751,5938,
39618739,3872,18750,6458,11605,18752,18753,8276,11521,18754,11284,18755,18756,
39710563,18757,6431,11522,18762,18763,7479,18761,11334,18758,18760,7964,7773,
39818759,18764,10498,18766,18765,4683,10762,18767,18779,18769,18770,18771,18772,
39918776,18777,18775,18773,18768,18774,18778,20246,4359,18781,5438,18780,18945,
40018944,18947,18946,18948,7184,18949,18950,18951,7965,11318,18952,10499,9765,
40118953,18954,5898,5131,18955,6730,9760,18956,4655,18957,18959,11350,18958,7717,
40218960,18961,18962,4912,18963,18964,18965,18966,4656,18967,18968,18969,4433,
4037687,18970,18971,18972,5919,9050,18973,
4045686,7733,18976,9475,18975,5648,18974,8534,5132,18977,18978,7480,5708,18979,
40510763,7998,5205,11092,8233,18980,7718,8783,7481,18981,18984,18985,6429,8481,
40618983,7482,10269,18982,6731,4146,18989,5687,6733,6732,11820,18988,18987,8198,
4075164,11810,4633,7483,18986,18991,18992,18990,5943,11295,6734,9734,18995,7967,
4088737,11285,18998,5963,7966,18994,18999,5964,18996,18997,18993,8001,9512,8718,
4094412,10063,5154,8979,19002,19000,8747,7968,4913,19001,7738,11561,11807,19003,
41019014,8980,19013,19010,19018,19011,19007,9051,19006,19004,11264,6735,19008,
41119005,19012,7251,5920,8537,10788,4153,3905,9476,19016,19015,9541,19020,19009,
41219019,19021,5899,19017,6197,6964,19022,11319,19025,19028,19026,10260,19023,
4135439,19027,19029,19033,19030,19032,19031,19034,6928,19036,19035,10311,19200,
4145688,19037,19201,19202,5155,17696,7512,19203,5965,19204,19205,6685,14637,
41519206,19207,7185,19208,19209,19210,19211,19212,8714,19213,19215,19214,9477,
41619216,10764,19217,19218,19219,19220,9529,7484,19221,6218,12045,19222,19223,
41710270,19224,19232,19225,19227,19226,19228,10789,19229,19230,19231,19233,4620,
4189030,10312,6465,6198,10286,4414,10029,19236,4914,7988,19235,19240,8792,11074,
41919238,19239,5133,19241,9794,8510,10064,9244,19237,10790,4427,19243,11783,8993,
42011812,6736,19242,8464,19259,8199,9559,10287,19246,6686,6737,7485,9796,5900,
42119245,19244,10313,6944,9265,19248,19249,6199,19247,19250,19251,19253,8450,
42219252,4933,19255,19254,19256,19258,19260,19261,7989,6958,19262,4657,
42319263,8277,19264,19265,10314,5134,19266,8981,4154,19267,6992,7765,8460,19270,
42419269,19268,19276,19274,19271,19273,19272,19275,5206,19279,7990,19280,5944,
42519277,19278,11784,8982,8200,19281,19284,19282,19283,11320,9478,19287,19285,
42619286,19288,19464,19291,19292,19290,19289,9052,19456,19460,19457,19293,19458,
42719459,19466,19461,7991,19463,19465,19462,19468,7186,19467,19469,19470,19473,
42819472,19471,19475,19474,11093,19477,19476,19478,19479,19481,19480,7719,19482,
4295452,19483,19485,19486,19487,19484,19488,6965,19489,5135,5650,5901,19490,9551,
4309245,19491,19494,6931,19493,19492,5689,19495,4658,19497,6459,19496,19505,
43119499,19501,10564,19498,19500,19504,19502,5136,19503,19506,9785,11575,7187,
43219507,11265,19509,19508,19512,11296,19511,4684,19510,19515,19514,19513,9233,
43319516,19517,19518,6219,5636,19519,19520,19521,7720,19522,6924,19523,19524,
43412544,12381,19525,17487,19526,8707,7690,9759,19527,10548,9011,6237,8712,4105,
43510839,7734,5693,5440,10549,19528,19530,19529,4415,9557,19531,9814,9234,19532,
4367217,19534,11041,19549,19536,19537,9000,8511,8278,9479,19535,5172,19544,19541,
43719716,9480,8767,19538,9053,9266,19539,19543,7743,9798,9003,7969,19542,8461,
4388451,19540,3848,11777,19545,8512,7188,7721,19547,19546,3918,19548,10254,19718,
4399530,7754,8760,5463,19717,11286,4126,10550,4416,19712,19713,19714,19715,9498,
4408706,3906,19719,19720,21250,8476,19721,4178,8235,5902,11321,19722,9227,8279,
4416966,19723,19726,7236,19724,8202,8201,3907,11562,19728,10065,19730,19729,
44219727,16963,4915,19533,19732,19731,19733,11287,9536,10765,19734,6968,19735,
44319736,19737,9216,3913,6200,11801,19741,5651,19738,19739,10323,4659,11288,5406,
4449267,19742,19743,19744,9217,19746,19745,9522,19747,7189,6975,9786,8784,6993,
4457755,19748,19749,7740,19750,19751,19752,11342,7190,19754,19753,6201,6226,6687,
44619757,7237,19756,19755,8520,5966,7970,9999,7192,19758,7486,19761,19759,19760,
44719763,19762,7513,19764,19765,19766,10031,6450,6976,19767,19768,11523,7204,
44811085,11563,19769,5441,19770,9218,19773,4695,7722,19771,19772,9023,10804,5467,
44919775,19776,19774,19778,9534,4642,19782,19779,19781,19777,20014,19780,11594,
4505945,19790,9235,19785,19788,19786,19791,19792,19784,19797,4179,19783,9996,
45119787,7487,6202,10791,5443,7205,9499,8204,19795,19789,19794,11042,8983,19796,
45219793,8203,19800,19799,19798,10766,7258,19801,10558,4147,10277,8785,5207,
45319803,6204,6667,19802,7756,7757,19968,19970,7514,19969,19971,5426,10276,6977,
45411778,19805,6487,11806,19973,19972,19974,19804,9544,9268,9014,19979,8738,
45519975,19976,5644,19978,5903,19977,7488,4696,19983,6430,8280,9001,4634,19981,
45619982,8994,19980,19984,19990,19993,19992,9228,19985,19986,19989,19991,5407,
45719994,19988,19987,19998,19999,20000,19997,19996,7489,9481,19995,20004,20002,
45820003,20001,8535,20005,20006,20008,4916,20007,11097,20019,20009,20012,20010,
45920011,20013,20015,20016,20017,20020,20018,20021,20023,20022,8984,11078,20024,
4608205,20025,10531,20026,4618,4123,4918,4917,20027,20028,20029,20030,20031,4919,
4614660,6205,10005,20033,20032,20034,4155,20037,20036,20035,20038,20041,3878,
46220039,20043,20042,20045,20044,20046,9485,20047,20048,20050,20049,10315,20051,
46320052,6468,20053,20054,10792,8234,3843,8490,20055,10316,20058,20056,6206,
46420057,5921,10532,20060,20224,20061,20225,4096,7735,7259,4920,20226,9797,20228,
4654097,20227,8995,11564,9482,20059,11525,5904,11322,5464,11539,5639,8513,17920,
46620229,4619,7758,4661,20231,20232,20230,5699,6460,7490,4098,11576,20234,19725,
46720233,20237,20235,20236,20238,20239,11595,20240,20241,7976,10010,7772,4934,
46811289,4428,7191,5946,20244,20243,6738,20245,20242,6663,20249,18700,12597,7766,
46920247,11524,9552,4106,8002,6933,10518,4127,11596,11338,20250,9252,7002,20251,
47020252,7723,20253,11597,20248,20255,20257,20256,20254,20258,20259,8281,4417,
47120260,11031,20261,20262,11785,14864,20263,20264,20265,20269,20266,20267,20268,
47220270,7971,11094,7972,20271,10066,20272,21042,11051,20273,20274,20275,4662,
47320277,7736,20278,5635,20279,20283,20281,20282,4690,20280,20284,20285,3879,
47420286,20287,7491,20288,5158,20291,20290,20289,19024,10555,20292,20293,20294,
47520295,20296,20297,4921,20298,20299,9730,20301,4378,20304,20303,4099,5408,
47610534,8985,6401,6207,7238,7739,20306,20305,11297,4935,10033,9531,7771,11565,
4775690,20309,20308,10794,9483,4143,20310,20307,10288,11337,20311,20312,20314,
4788521,4666,4667,20313,4936,5905,4937,9246,11583,5947,20315,20316,20317,20480,
47920482,20481,10326,20483,20484,20485,20486,20488,20487,20489,10067,17707,7688,
4805137,20490,
48120491,12555,15386,10034,3930,3866,6739,10767,7517,20492,11070,20493,11323,
4824129,6688,20494,4429,20495,20496,20498,20499,20501,20497,20500,4922,20502,
48320503,20504,20505,20506,20508,20507,20510,20513,20509,20511,20512,20514,5409,
4846994,20515,20516,6208,20517,4637,9774,20518,20519,8761,9546,20520,9820,8491,
4854151,5453,5454,8786,20525,5455,4430,20524,20522,20523,20521,20535,20526,20527,
48620528,20529,20531,20530,7224,20532,20534,5138,20533,8282,5906,20536,8492,
48720537,9484,20538,20543,20541,20540,20542,20539,20545,20544,20547,5410,20546,
48820548,20549,20551,20550,20552,20554,20553,6235,20555,20556,4635,20557,20558,
4897760,20559,20560,20561,20562,6209,20563,20564,20565,20566,20567,10000,20569,
49010245,20570,20568,20572,20571,20573,20736,20737,20738,20739,20740,20741,20742,
49120743,20744,20745,20746,20747,20748,20749,15380,20750,17239,5139,4608,6417,
49220752,20751,11012,20754,20755,20753,20756,10817,20757,5210,11780,20758,20760,
4933869,20761,10506,20759,20762,20763,20764,20765,20766,10829,6668,6489,8206,
49420767,20770,20768,20771,5968,20769,20772,20773,20774,20778,6665,8515,20779,
49520776,20775,20777,5694,20783,20782,20781,3858,20793,20789,20790,20786,20792,
49620788,4673,11819,20791,20787,20785,20784,20795,20798,20797,20796,10280,20794,
4973922,20799,20801,4686,20780,4118,20803,20802,20800,8716,10831,11577,20804,
49820805,20806,20807,20808,8986,20809,10006,20814,20810,20811,10768,11043,9519,
49920815,20816,9501,20813,20812,4361,20824,20823,4180,20821,20820,20818,4698,
50020817,6929,4360,6210,20827,20826,20825,
50120822,20828,20829,20996,20995,20997,4108,20992,20993,6227,11032,20994,10769,
50221002,20998,21003,21000,20999,5691,21004,21005,21006,21001,20819,21007,9024,
50321011,21012,21010,21009,21015,21008,21013,21014,21017,21016,21019,21020,21021,
50411816,21018,8522,6476,21022,21023,21024,21025,21026,5907,21027,21028,6926,
50521029,21030,21031,21032,21035,21033,11803,21034,11598,21036,11578,21037,9821,
50621038,21040,21041,21039,6220,11052,10818,13654,15423,10842,4362,21043,5167,
50721044,21045,21046,6228,21047,16179,11066,8514,21048,21050,21049,21051,21052,
50821053,21054,21055,21056,21057,21058,21059,21060,21061,21062,21063,9219,5948,
50921065,8236,21066,21067,10240,21068,21069,16918,19257,20300,21070,21071,21073,
51021074,21075,11599,21072,21076,21077,21079,21078,21081,21082,21080,11541,21083,
51121084,16947,21085,9,83,79,82,84,41,42,85,59,3,4,30,527,528,529,530,531,532,
512533,534,535,536,6,7,66,64,67,8,86,544,545,546,547,548,549,550,551,552,553,554,
513555,556,557,558,559,560,561,562,563,564,565,566,567,568,569,45,46,15,17,13,
514576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,
515595,596,597,598,599,600,601,47,34,48,16,78,
libc/musl/src/locale/setlocale.c created+79
......@@ -0,0 +1,79 @@
1#include <locale.h>
2#include <stdlib.h>
3#include <string.h>
4#include "locale_impl.h"
5#include "libc.h"
6#include "lock.h"
7
8static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
9
10char *setlocale(int cat, const char *name)
11{
12 static volatile int lock[1];
13 const struct __locale_map *lm;
14
15 if ((unsigned)cat > LC_ALL) return 0;
16
17 LOCK(lock);
18
19 /* For LC_ALL, setlocale is required to return a string which
20 * encodes the current setting for all categories. The format of
21 * this string is unspecified, and only the following code, which
22 * performs both the serialization and deserialization, depends
23 * on the format, so it can easily be changed if needed. */
24 if (cat == LC_ALL) {
25 int i;
26 if (name) {
27 struct __locale_struct tmp_locale;
28 char part[LOCALE_NAME_MAX+1] = "C.UTF-8";
29 const char *p = name;
30 for (i=0; i<LC_ALL; i++) {
31 const char *z = __strchrnul(p, ';');
32 if (z-p <= LOCALE_NAME_MAX) {
33 memcpy(part, p, z-p);
34 part[z-p] = 0;
35 if (*z) p = z+1;
36 }
37 lm = __get_locale(i, part);
38 if (lm == LOC_MAP_FAILED) {
39 UNLOCK(lock);
40 return 0;
41 }
42 tmp_locale.cat[i] = lm;
43 }
44 libc.global_locale = tmp_locale;
45 }
46 char *s = buf;
47 const char *part;
48 int same = 0;
49 for (i=0; i<LC_ALL; i++) {
50 const struct __locale_map *lm =
51 libc.global_locale.cat[i];
52 if (lm == libc.global_locale.cat[0]) same++;
53 part = lm ? lm->name : "C";
54 size_t l = strlen(part);
55 memcpy(s, part, l);
56 s[l] = ';';
57 s += l+1;
58 }
59 *--s = 0;
60 UNLOCK(lock);
61 return same==LC_ALL ? (char *)part : buf;
62 }
63
64 if (name) {
65 lm = __get_locale(cat, name);
66 if (lm == LOC_MAP_FAILED) {
67 UNLOCK(lock);
68 return 0;
69 }
70 libc.global_locale.cat[cat] = lm;
71 } else {
72 lm = libc.global_locale.cat[cat];
73 }
74 char *ret = lm ? (char *)lm->name : "C";
75
76 UNLOCK(lock);
77
78 return ret;
79}
libc/musl/src/locale/strcoll.c created+15
......@@ -0,0 +1,15 @@
1#include <string.h>
2#include <locale.h>
3#include "locale_impl.h"
4
5int __strcoll_l(const char *l, const char *r, locale_t loc)
6{
7 return strcmp(l, r);
8}
9
10int strcoll(const char *l, const char *r)
11{
12 return __strcoll_l(l, r, CURRENT_LOCALE);
13}
14
15weak_alias(__strcoll_l, strcoll_l);
libc/musl/src/locale/strfmon.c created+101
......@@ -0,0 +1,101 @@
1#include <stdio.h>
2#include <ctype.h>
3#include <stdarg.h>
4#include <monetary.h>
5#include <errno.h>
6#include "locale_impl.h"
7
8static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_list ap)
9{
10 size_t l;
11 double x;
12 int fill, nogrp, negpar, nosym, left, intl;
13 int lp, rp, w, fw;
14 char *s0=s;
15 for (; n && *fmt; ) {
16 if (*fmt != '%') {
17 literal:
18 *s++ = *fmt++;
19 n--;
20 continue;
21 }
22 fmt++;
23 if (*fmt == '%') goto literal;
24
25 fill = ' ';
26 nogrp = 0;
27 negpar = 0;
28 nosym = 0;
29 left = 0;
30 for (; ; fmt++) {
31 switch (*fmt) {
32 case '=':
33 fill = *++fmt;
34 continue;
35 case '^':
36 nogrp = 1;
37 continue;
38 case '(':
39 negpar = 1;
40 case '+':
41 continue;
42 case '!':
43 nosym = 1;
44 continue;
45 case '-':
46 left = 1;
47 continue;
48 }
49 break;
50 }
51
52 for (fw=0; isdigit(*fmt); fmt++)
53 fw = 10*fw + (*fmt-'0');
54 lp = 0;
55 rp = 2;
56 if (*fmt=='#') for (lp=0, fmt++; isdigit(*fmt); fmt++)
57 lp = 10*lp + (*fmt-'0');
58 if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++)
59 rp = 10*rp + (*fmt-'0');
60
61 intl = *fmt++ == 'i';
62
63 w = lp + 1 + rp;
64 if (!left && fw>w) w = fw;
65
66 x = va_arg(ap, double);
67 l = snprintf(s, n, "%*.*f", w, rp, x);
68 if (l >= n) {
69 errno = E2BIG;
70 return -1;
71 }
72 s += l;
73 n -= l;
74 }
75 return s-s0;
76}
77
78ssize_t strfmon_l(char *restrict s, size_t n, locale_t loc, const char *restrict fmt, ...)
79{
80 va_list ap;
81 ssize_t ret;
82
83 va_start(ap, fmt);
84 ret = vstrfmon_l(s, n, loc, fmt, ap);
85 va_end(ap);
86
87 return ret;
88}
89
90
91ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...)
92{
93 va_list ap;
94 ssize_t ret;
95
96 va_start(ap, fmt);
97 ret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap);
98 va_end(ap);
99
100 return ret;
101}
libc/musl/src/locale/strxfrm.c created+18
......@@ -0,0 +1,18 @@
1#include <string.h>
2#include <locale.h>
3#include "locale_impl.h"
4
5/* collate only by code points */
6size_t __strxfrm_l(char *restrict dest, const char *restrict src, size_t n, locale_t loc)
7{
8 size_t l = strlen(src);
9 if (n > l) strcpy(dest, src);
10 return l;
11}
12
13size_t strxfrm(char *restrict dest, const char *restrict src, size_t n)
14{
15 return __strxfrm_l(dest, src, n, CURRENT_LOCALE);
16}
17
18weak_alias(__strxfrm_l, strxfrm_l);
libc/musl/src/locale/textdomain.c created+42
......@@ -0,0 +1,42 @@
1#include <libintl.h>
2#include <string.h>
3#include <stdlib.h>
4#include <errno.h>
5#include <limits.h>
6
7static char *current_domain;
8
9char *__gettextdomain()
10{
11 return current_domain ? current_domain : "messages";
12}
13
14char *textdomain(const char *domainname)
15{
16 if (!domainname) return __gettextdomain();
17
18 size_t domlen = strlen(domainname);
19 if (domlen > NAME_MAX) {
20 errno = EINVAL;
21 return 0;
22 }
23
24 if (!current_domain) {
25 current_domain = malloc(NAME_MAX+1);
26 if (!current_domain) return 0;
27 }
28
29 memcpy(current_domain, domainname, domlen+1);
30
31 return current_domain;
32}
33
34char *gettext(const char *msgid)
35{
36 return dgettext(0, msgid);
37}
38
39char *ngettext(const char *msgid1, const char *msgid2, unsigned long int n)
40{
41 return dngettext(0, msgid1, msgid2, n);
42}
libc/musl/src/locale/uselocale.c created+16
......@@ -0,0 +1,16 @@
1#include "locale_impl.h"
2#include "pthread_impl.h"
3#include "libc.h"
4
5locale_t __uselocale(locale_t new)
6{
7 pthread_t self = __pthread_self();
8 locale_t old = self->locale;
9 locale_t global = &libc.global_locale;
10
11 if (new) self->locale = new == LC_GLOBAL_LOCALE ? global : new;
12
13 return old == global ? LC_GLOBAL_LOCALE : old;
14}
15
16weak_alias(__uselocale, uselocale);
libc/musl/src/locale/wcscoll.c created+16
......@@ -0,0 +1,16 @@
1#include <wchar.h>
2#include <locale.h>
3#include "locale_impl.h"
4
5/* FIXME: stub */
6int __wcscoll_l(const wchar_t *l, const wchar_t *r, locale_t locale)
7{
8 return wcscmp(l, r);
9}
10
11int wcscoll(const wchar_t *l, const wchar_t *r)
12{
13 return __wcscoll_l(l, r, CURRENT_LOCALE);
14}
15
16weak_alias(__wcscoll_l, wcscoll_l);
libc/musl/src/locale/wcsxfrm.c created+23
......@@ -0,0 +1,23 @@
1#include <wchar.h>
2#include <locale.h>
3#include "locale_impl.h"
4
5/* collate only by code points */
6size_t __wcsxfrm_l(wchar_t *restrict dest, const wchar_t *restrict src, size_t n, locale_t loc)
7{
8 size_t l = wcslen(src);
9 if (l < n) {
10 wmemcpy(dest, src, l+1);
11 } else if (n) {
12 wmemcpy(dest, src, n-1);
13 dest[n-1] = 0;
14 }
15 return l;
16}
17
18size_t wcsxfrm(wchar_t *restrict dest, const wchar_t *restrict src, size_t n)
19{
20 return __wcsxfrm_l(dest, src, n, CURRENT_LOCALE);
21}
22
23weak_alias(__wcsxfrm_l, wcsxfrm_l);
libc/musl/src/malloc/DESIGN created+22
......@@ -0,0 +1,22 @@
1
2
3In principle, this memory allocator is roughly equivalent to Doug
4Lea's dlmalloc with fine-grained locking.
5
6
7
8malloc:
9
10Uses a freelist binned by chunk size, with a bitmap to optimize
11searching for the smallest non-empty bin which can satisfy an
12allocation. If no free chunks are available, it creates a new chunk of
13the requested size and attempts to merge it with any existing free
14chunk immediately below the newly created chunk.
15
16Whether the chunk was obtained from a bin or newly created, it's
17likely to be larger than the requested allocation. malloc always
18finishes its work by passing the new chunk to realloc, which will
19split it into two chunks and free the tail portion.
20
21
22
libc/musl/src/malloc/aligned_alloc.c created+7
......@@ -0,0 +1,7 @@
1#include <stdlib.h>
2#include "malloc_impl.h"
3
4void *aligned_alloc(size_t align, size_t len)
5{
6 return __memalign(align, len);
7}
libc/musl/src/malloc/expand_heap.c created+71
......@@ -0,0 +1,71 @@
1#include <limits.h>
2#include <stdint.h>
3#include <errno.h>
4#include <sys/mman.h>
5#include "libc.h"
6#include "syscall.h"
7#include "malloc_impl.h"
8
9/* This function returns true if the interval [old,new]
10 * intersects the 'len'-sized interval below &libc.auxv
11 * (interpreted as the main-thread stack) or below &b
12 * (the current stack). It is used to defend against
13 * buggy brk implementations that can cross the stack. */
14
15static int traverses_stack_p(uintptr_t old, uintptr_t new)
16{
17 const uintptr_t len = 8<<20;
18 uintptr_t a, b;
19
20 b = (uintptr_t)libc.auxv;
21 a = b > len ? b-len : 0;
22 if (new>a && old<b) return 1;
23
24 b = (uintptr_t)&b;
25 a = b > len ? b-len : 0;
26 if (new>a && old<b) return 1;
27
28 return 0;
29}
30
31/* Expand the heap in-place if brk can be used, or otherwise via mmap,
32 * using an exponential lower bound on growth by mmap to make
33 * fragmentation asymptotically irrelevant. The size argument is both
34 * an input and an output, since the caller needs to know the size
35 * allocated, which will be larger than requested due to page alignment
36 * and mmap minimum size rules. The caller is responsible for locking
37 * to prevent concurrent calls. */
38
39void *__expand_heap(size_t *pn)
40{
41 static uintptr_t brk;
42 static unsigned mmap_step;
43 size_t n = *pn;
44
45 if (n > SIZE_MAX/2 - PAGE_SIZE) {
46 errno = ENOMEM;
47 return 0;
48 }
49 n += -n & PAGE_SIZE-1;
50
51 if (!brk) {
52 brk = __syscall(SYS_brk, 0);
53 brk += -brk & PAGE_SIZE-1;
54 }
55
56 if (n < SIZE_MAX-brk && !traverses_stack_p(brk, brk+n)
57 && __syscall(SYS_brk, brk+n)==brk+n) {
58 *pn = n;
59 brk += n;
60 return (void *)(brk-n);
61 }
62
63 size_t min = (size_t)PAGE_SIZE << mmap_step/2;
64 if (n < min) n = min;
65 void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
66 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
67 if (area == MAP_FAILED) return 0;
68 *pn = n;
69 mmap_step++;
70 return area;
71}
libc/musl/src/malloc/lite_malloc.c created+59
......@@ -0,0 +1,59 @@
1#include <stdlib.h>
2#include <stdint.h>
3#include <limits.h>
4#include <errno.h>
5#include "lock.h"
6#include "malloc_impl.h"
7
8#define ALIGN 16
9
10static void *__simple_malloc(size_t n)
11{
12 static char *cur, *end;
13 static volatile int lock[1];
14 size_t align=1, pad;
15 void *p;
16
17 if (!n) n++;
18 while (align<n && align<ALIGN)
19 align += align;
20
21 LOCK(lock);
22
23 pad = -(uintptr_t)cur & align-1;
24
25 if (n <= SIZE_MAX/2 + ALIGN) n += pad;
26
27 if (n > end-cur) {
28 size_t m = n;
29 char *new = __expand_heap(&m);
30 if (!new) {
31 UNLOCK(lock);
32 return 0;
33 }
34 if (new != end) {
35 cur = new;
36 n -= pad;
37 pad = 0;
38 }
39 end = new + m;
40 }
41
42 p = cur + pad;
43 cur += n;
44 UNLOCK(lock);
45 return p;
46}
47
48weak_alias(__simple_malloc, malloc);
49
50static void *__simple_calloc(size_t m, size_t n)
51{
52 if (n && m > (size_t)-1/n) {
53 errno = ENOMEM;
54 return 0;
55 }
56 return __simple_malloc(n * m);
57}
58
59weak_alias(__simple_calloc, calloc);
libc/musl/src/malloc/malloc.c created+548
......@@ -0,0 +1,548 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <string.h>
4#include <limits.h>
5#include <stdint.h>
6#include <errno.h>
7#include <sys/mman.h>
8#include "libc.h"
9#include "atomic.h"
10#include "pthread_impl.h"
11#include "malloc_impl.h"
12
13#if defined(__GNUC__) && defined(__PIC__)
14#define inline inline __attribute__((always_inline))
15#endif
16
17static struct {
18 volatile uint64_t binmap;
19 struct bin bins[64];
20 volatile int free_lock[2];
21} mal;
22
23int __malloc_replaced;
24
25/* Synchronization tools */
26
27static inline void lock(volatile int *lk)
28{
29 if (libc.threads_minus_1)
30 while(a_swap(lk, 1)) __wait(lk, lk+1, 1, 1);
31}
32
33static inline void unlock(volatile int *lk)
34{
35 if (lk[0]) {
36 a_store(lk, 0);
37 if (lk[1]) __wake(lk, 1, 1);
38 }
39}
40
41static inline void lock_bin(int i)
42{
43 lock(mal.bins[i].lock);
44 if (!mal.bins[i].head)
45 mal.bins[i].head = mal.bins[i].tail = BIN_TO_CHUNK(i);
46}
47
48static inline void unlock_bin(int i)
49{
50 unlock(mal.bins[i].lock);
51}
52
53static int first_set(uint64_t x)
54{
55#if 1
56 return a_ctz_64(x);
57#else
58 static const char debruijn64[64] = {
59 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
60 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
61 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
62 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
63 };
64 static const char debruijn32[32] = {
65 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
66 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
67 };
68 if (sizeof(long) < 8) {
69 uint32_t y = x;
70 if (!y) {
71 y = x>>32;
72 return 32 + debruijn32[(y&-y)*0x076be629 >> 27];
73 }
74 return debruijn32[(y&-y)*0x076be629 >> 27];
75 }
76 return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
77#endif
78}
79
80static const unsigned char bin_tab[60] = {
81 32,33,34,35,36,36,37,37,38,38,39,39,
82 40,40,40,40,41,41,41,41,42,42,42,42,43,43,43,43,
83 44,44,44,44,44,44,44,44,45,45,45,45,45,45,45,45,
84 46,46,46,46,46,46,46,46,47,47,47,47,47,47,47,47,
85};
86
87static int bin_index(size_t x)
88{
89 x = x / SIZE_ALIGN - 1;
90 if (x <= 32) return x;
91 if (x < 512) return bin_tab[x/8-4];
92 if (x > 0x1c00) return 63;
93 return bin_tab[x/128-4] + 16;
94}
95
96static int bin_index_up(size_t x)
97{
98 x = x / SIZE_ALIGN - 1;
99 if (x <= 32) return x;
100 x--;
101 if (x < 512) return bin_tab[x/8-4] + 1;
102 return bin_tab[x/128-4] + 17;
103}
104
105#if 0
106void __dump_heap(int x)
107{
108 struct chunk *c;
109 int i;
110 for (c = (void *)mal.heap; CHUNK_SIZE(c); c = NEXT_CHUNK(c))
111 fprintf(stderr, "base %p size %zu (%d) flags %d/%d\n",
112 c, CHUNK_SIZE(c), bin_index(CHUNK_SIZE(c)),
113 c->csize & 15,
114 NEXT_CHUNK(c)->psize & 15);
115 for (i=0; i<64; i++) {
116 if (mal.bins[i].head != BIN_TO_CHUNK(i) && mal.bins[i].head) {
117 fprintf(stderr, "bin %d: %p\n", i, mal.bins[i].head);
118 if (!(mal.binmap & 1ULL<<i))
119 fprintf(stderr, "missing from binmap!\n");
120 } else if (mal.binmap & 1ULL<<i)
121 fprintf(stderr, "binmap wrongly contains %d!\n", i);
122 }
123}
124#endif
125
126static struct chunk *expand_heap(size_t n)
127{
128 static int heap_lock[2];
129 static void *end;
130 void *p;
131 struct chunk *w;
132
133 /* The argument n already accounts for the caller's chunk
134 * overhead needs, but if the heap can't be extended in-place,
135 * we need room for an extra zero-sized sentinel chunk. */
136 n += SIZE_ALIGN;
137
138 lock(heap_lock);
139
140 p = __expand_heap(&n);
141 if (!p) {
142 unlock(heap_lock);
143 return 0;
144 }
145
146 /* If not just expanding existing space, we need to make a
147 * new sentinel chunk below the allocated space. */
148 if (p != end) {
149 /* Valid/safe because of the prologue increment. */
150 n -= SIZE_ALIGN;
151 p = (char *)p + SIZE_ALIGN;
152 w = MEM_TO_CHUNK(p);
153 w->psize = 0 | C_INUSE;
154 }
155
156 /* Record new heap end and fill in footer. */
157 end = (char *)p + n;
158 w = MEM_TO_CHUNK(end);
159 w->psize = n | C_INUSE;
160 w->csize = 0 | C_INUSE;
161
162 /* Fill in header, which may be new or may be replacing a
163 * zero-size sentinel header at the old end-of-heap. */
164 w = MEM_TO_CHUNK(p);
165 w->csize = n | C_INUSE;
166
167 unlock(heap_lock);
168
169 return w;
170}
171
172static int adjust_size(size_t *n)
173{
174 /* Result of pointer difference must fit in ptrdiff_t. */
175 if (*n-1 > PTRDIFF_MAX - SIZE_ALIGN - PAGE_SIZE) {
176 if (*n) {
177 errno = ENOMEM;
178 return -1;
179 } else {
180 *n = SIZE_ALIGN;
181 return 0;
182 }
183 }
184 *n = (*n + OVERHEAD + SIZE_ALIGN - 1) & SIZE_MASK;
185 return 0;
186}
187
188static void unbin(struct chunk *c, int i)
189{
190 if (c->prev == c->next)
191 a_and_64(&mal.binmap, ~(1ULL<<i));
192 c->prev->next = c->next;
193 c->next->prev = c->prev;
194 c->csize |= C_INUSE;
195 NEXT_CHUNK(c)->psize |= C_INUSE;
196}
197
198static int alloc_fwd(struct chunk *c)
199{
200 int i;
201 size_t k;
202 while (!((k=c->csize) & C_INUSE)) {
203 i = bin_index(k);
204 lock_bin(i);
205 if (c->csize == k) {
206 unbin(c, i);
207 unlock_bin(i);
208 return 1;
209 }
210 unlock_bin(i);
211 }
212 return 0;
213}
214
215static int alloc_rev(struct chunk *c)
216{
217 int i;
218 size_t k;
219 while (!((k=c->psize) & C_INUSE)) {
220 i = bin_index(k);
221 lock_bin(i);
222 if (c->psize == k) {
223 unbin(PREV_CHUNK(c), i);
224 unlock_bin(i);
225 return 1;
226 }
227 unlock_bin(i);
228 }
229 return 0;
230}
231
232
233/* pretrim - trims a chunk _prior_ to removing it from its bin.
234 * Must be called with i as the ideal bin for size n, j the bin
235 * for the _free_ chunk self, and bin j locked. */
236static int pretrim(struct chunk *self, size_t n, int i, int j)
237{
238 size_t n1;
239 struct chunk *next, *split;
240
241 /* We cannot pretrim if it would require re-binning. */
242 if (j < 40) return 0;
243 if (j < i+3) {
244 if (j != 63) return 0;
245 n1 = CHUNK_SIZE(self);
246 if (n1-n <= MMAP_THRESHOLD) return 0;
247 } else {
248 n1 = CHUNK_SIZE(self);
249 }
250 if (bin_index(n1-n) != j) return 0;
251
252 next = NEXT_CHUNK(self);
253 split = (void *)((char *)self + n);
254
255 split->prev = self->prev;
256 split->next = self->next;
257 split->prev->next = split;
258 split->next->prev = split;
259 split->psize = n | C_INUSE;
260 split->csize = n1-n;
261 next->psize = n1-n;
262 self->csize = n | C_INUSE;
263 return 1;
264}
265
266static void trim(struct chunk *self, size_t n)
267{
268 size_t n1 = CHUNK_SIZE(self);
269 struct chunk *next, *split;
270
271 if (n >= n1 - DONTCARE) return;
272
273 next = NEXT_CHUNK(self);
274 split = (void *)((char *)self + n);
275
276 split->psize = n | C_INUSE;
277 split->csize = n1-n | C_INUSE;
278 next->psize = n1-n | C_INUSE;
279 self->csize = n | C_INUSE;
280
281 __bin_chunk(split);
282}
283
284void *malloc(size_t n)
285{
286 struct chunk *c;
287 int i, j;
288
289 if (adjust_size(&n) < 0) return 0;
290
291 if (n > MMAP_THRESHOLD) {
292 size_t len = n + OVERHEAD + PAGE_SIZE - 1 & -PAGE_SIZE;
293 char *base = __mmap(0, len, PROT_READ|PROT_WRITE,
294 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
295 if (base == (void *)-1) return 0;
296 c = (void *)(base + SIZE_ALIGN - OVERHEAD);
297 c->csize = len - (SIZE_ALIGN - OVERHEAD);
298 c->psize = SIZE_ALIGN - OVERHEAD;
299 return CHUNK_TO_MEM(c);
300 }
301
302 i = bin_index_up(n);
303 for (;;) {
304 uint64_t mask = mal.binmap & -(1ULL<<i);
305 if (!mask) {
306 c = expand_heap(n);
307 if (!c) return 0;
308 if (alloc_rev(c)) {
309 struct chunk *x = c;
310 c = PREV_CHUNK(c);
311 NEXT_CHUNK(x)->psize = c->csize =
312 x->csize + CHUNK_SIZE(c);
313 }
314 break;
315 }
316 j = first_set(mask);
317 lock_bin(j);
318 c = mal.bins[j].head;
319 if (c != BIN_TO_CHUNK(j)) {
320 if (!pretrim(c, n, i, j)) unbin(c, j);
321 unlock_bin(j);
322 break;
323 }
324 unlock_bin(j);
325 }
326
327 /* Now patch up in case we over-allocated */
328 trim(c, n);
329
330 return CHUNK_TO_MEM(c);
331}
332
333static size_t mal0_clear(char *p, size_t pagesz, size_t n)
334{
335#ifdef __GNUC__
336 typedef uint64_t __attribute__((__may_alias__)) T;
337#else
338 typedef unsigned char T;
339#endif
340 char *pp = p + n;
341 size_t i = (uintptr_t)pp & (pagesz - 1);
342 for (;;) {
343 pp = memset(pp - i, 0, i);
344 if (pp - p < pagesz) return pp - p;
345 for (i = pagesz; i; i -= 2*sizeof(T), pp -= 2*sizeof(T))
346 if (((T *)pp)[-1] | ((T *)pp)[-2])
347 break;
348 }
349}
350
351void *calloc(size_t m, size_t n)
352{
353 if (n && m > (size_t)-1/n) {
354 errno = ENOMEM;
355 return 0;
356 }
357 n *= m;
358 void *p = malloc(n);
359 if (!p) return p;
360 if (!__malloc_replaced) {
361 if (IS_MMAPPED(MEM_TO_CHUNK(p)))
362 return p;
363 if (n >= PAGE_SIZE)
364 n = mal0_clear(p, PAGE_SIZE, n);
365 }
366 return memset(p, 0, n);
367}
368
369void *realloc(void *p, size_t n)
370{
371 struct chunk *self, *next;
372 size_t n0, n1;
373 void *new;
374
375 if (!p) return malloc(n);
376
377 if (adjust_size(&n) < 0) return 0;
378
379 self = MEM_TO_CHUNK(p);
380 n1 = n0 = CHUNK_SIZE(self);
381
382 if (IS_MMAPPED(self)) {
383 size_t extra = self->psize;
384 char *base = (char *)self - extra;
385 size_t oldlen = n0 + extra;
386 size_t newlen = n + extra;
387 /* Crash on realloc of freed chunk */
388 if (extra & 1) a_crash();
389 if (newlen < PAGE_SIZE && (new = malloc(n-OVERHEAD))) {
390 n0 = n;
391 goto copy_free_ret;
392 }
393 newlen = (newlen + PAGE_SIZE-1) & -PAGE_SIZE;
394 if (oldlen == newlen) return p;
395 base = __mremap(base, oldlen, newlen, MREMAP_MAYMOVE);
396 if (base == (void *)-1)
397 goto copy_realloc;
398 self = (void *)(base + extra);
399 self->csize = newlen - extra;
400 return CHUNK_TO_MEM(self);
401 }
402
403 next = NEXT_CHUNK(self);
404
405 /* Crash on corrupted footer (likely from buffer overflow) */
406 if (next->psize != self->csize) a_crash();
407
408 /* Merge adjacent chunks if we need more space. This is not
409 * a waste of time even if we fail to get enough space, because our
410 * subsequent call to free would otherwise have to do the merge. */
411 if (n > n1 && alloc_fwd(next)) {
412 n1 += CHUNK_SIZE(next);
413 next = NEXT_CHUNK(next);
414 }
415 /* FIXME: find what's wrong here and reenable it..? */
416 if (0 && n > n1 && alloc_rev(self)) {
417 self = PREV_CHUNK(self);
418 n1 += CHUNK_SIZE(self);
419 }
420 self->csize = n1 | C_INUSE;
421 next->psize = n1 | C_INUSE;
422
423 /* If we got enough space, split off the excess and return */
424 if (n <= n1) {
425 //memmove(CHUNK_TO_MEM(self), p, n0-OVERHEAD);
426 trim(self, n);
427 return CHUNK_TO_MEM(self);
428 }
429
430copy_realloc:
431 /* As a last resort, allocate a new chunk and copy to it. */
432 new = malloc(n-OVERHEAD);
433 if (!new) return 0;
434copy_free_ret:
435 memcpy(new, p, n0-OVERHEAD);
436 free(CHUNK_TO_MEM(self));
437 return new;
438}
439
440void __bin_chunk(struct chunk *self)
441{
442 struct chunk *next = NEXT_CHUNK(self);
443 size_t final_size, new_size, size;
444 int reclaim=0;
445 int i;
446
447 final_size = new_size = CHUNK_SIZE(self);
448
449 /* Crash on corrupted footer (likely from buffer overflow) */
450 if (next->psize != self->csize) a_crash();
451
452 for (;;) {
453 if (self->psize & next->csize & C_INUSE) {
454 self->csize = final_size | C_INUSE;
455 next->psize = final_size | C_INUSE;
456 i = bin_index(final_size);
457 lock_bin(i);
458 lock(mal.free_lock);
459 if (self->psize & next->csize & C_INUSE)
460 break;
461 unlock(mal.free_lock);
462 unlock_bin(i);
463 }
464
465 if (alloc_rev(self)) {
466 self = PREV_CHUNK(self);
467 size = CHUNK_SIZE(self);
468 final_size += size;
469 if (new_size+size > RECLAIM && (new_size+size^size) > size)
470 reclaim = 1;
471 }
472
473 if (alloc_fwd(next)) {
474 size = CHUNK_SIZE(next);
475 final_size += size;
476 if (new_size+size > RECLAIM && (new_size+size^size) > size)
477 reclaim = 1;
478 next = NEXT_CHUNK(next);
479 }
480 }
481
482 if (!(mal.binmap & 1ULL<<i))
483 a_or_64(&mal.binmap, 1ULL<<i);
484
485 self->csize = final_size;
486 next->psize = final_size;
487 unlock(mal.free_lock);
488
489 self->next = BIN_TO_CHUNK(i);
490 self->prev = mal.bins[i].tail;
491 self->next->prev = self;
492 self->prev->next = self;
493
494 /* Replace middle of large chunks with fresh zero pages */
495 if (reclaim) {
496 uintptr_t a = (uintptr_t)self + SIZE_ALIGN+PAGE_SIZE-1 & -PAGE_SIZE;
497 uintptr_t b = (uintptr_t)next - SIZE_ALIGN & -PAGE_SIZE;
498#if 1
499 __madvise((void *)a, b-a, MADV_DONTNEED);
500#else
501 __mmap((void *)a, b-a, PROT_READ|PROT_WRITE,
502 MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
503#endif
504 }
505
506 unlock_bin(i);
507}
508
509static void unmap_chunk(struct chunk *self)
510{
511 size_t extra = self->psize;
512 char *base = (char *)self - extra;
513 size_t len = CHUNK_SIZE(self) + extra;
514 /* Crash on double free */
515 if (extra & 1) a_crash();
516 __munmap(base, len);
517}
518
519void free(void *p)
520{
521 if (!p) return;
522
523 struct chunk *self = MEM_TO_CHUNK(p);
524
525 if (IS_MMAPPED(self))
526 unmap_chunk(self);
527 else
528 __bin_chunk(self);
529}
530
531void __malloc_donate(char *start, char *end)
532{
533 size_t align_start_up = (SIZE_ALIGN-1) & (-(uintptr_t)start - OVERHEAD);
534 size_t align_end_down = (SIZE_ALIGN-1) & (uintptr_t)end;
535
536 /* Getting past this condition ensures that the padding for alignment
537 * and header overhead will not overflow and will leave a nonzero
538 * multiple of SIZE_ALIGN bytes between start and end. */
539 if (end - start <= OVERHEAD + align_start_up + align_end_down)
540 return;
541 start += align_start_up + OVERHEAD;
542 end -= align_end_down;
543
544 struct chunk *c = MEM_TO_CHUNK(start), *n = MEM_TO_CHUNK(end);
545 c->psize = n->csize = C_INUSE;
546 c->csize = n->psize = C_INUSE | (end-start);
547 __bin_chunk(c);
548}
libc/musl/src/malloc/malloc_usable_size.c created+9
......@@ -0,0 +1,9 @@
1#include <malloc.h>
2#include "malloc_impl.h"
3
4hidden void *(*const __realloc_dep)(void *, size_t) = realloc;
5
6size_t malloc_usable_size(void *p)
7{
8 return p ? CHUNK_SIZE(MEM_TO_CHUNK(p)) - OVERHEAD : 0;
9}
libc/musl/src/malloc/memalign.c created+54
......@@ -0,0 +1,54 @@
1#include <stdlib.h>
2#include <stdint.h>
3#include <errno.h>
4#include "malloc_impl.h"
5
6void *__memalign(size_t align, size_t len)
7{
8 unsigned char *mem, *new;
9
10 if ((align & -align) != align) {
11 errno = EINVAL;
12 return 0;
13 }
14
15 if (len > SIZE_MAX - align || __malloc_replaced) {
16 errno = ENOMEM;
17 return 0;
18 }
19
20 if (align <= SIZE_ALIGN)
21 return malloc(len);
22
23 if (!(mem = malloc(len + align-1)))
24 return 0;
25
26 new = (void *)((uintptr_t)mem + align-1 & -align);
27 if (new == mem) return mem;
28
29 struct chunk *c = MEM_TO_CHUNK(mem);
30 struct chunk *n = MEM_TO_CHUNK(new);
31
32 if (IS_MMAPPED(c)) {
33 /* Apply difference between aligned and original
34 * address to the "extra" field of mmapped chunk. */
35 n->psize = c->psize + (new-mem);
36 n->csize = c->csize - (new-mem);
37 return new;
38 }
39
40 struct chunk *t = NEXT_CHUNK(c);
41
42 /* Split the allocated chunk into two chunks. The aligned part
43 * that will be used has the size in its footer reduced by the
44 * difference between the aligned and original addresses, and
45 * the resulting size copied to its header. A new header and
46 * footer are written for the split-off part to be freed. */
47 n->psize = c->csize = C_INUSE | (new-mem);
48 n->csize = t->psize -= new-mem;
49
50 __bin_chunk(c);
51 return new;
52}
53
54weak_alias(__memalign, memalign);
libc/musl/src/malloc/posix_memalign.c created+12
......@@ -0,0 +1,12 @@
1#include <stdlib.h>
2#include <errno.h>
3#include "malloc_impl.h"
4
5int posix_memalign(void **res, size_t align, size_t len)
6{
7 if (align < sizeof(void *)) return EINVAL;
8 void *mem = __memalign(align, len);
9 if (!mem) return errno;
10 *res = mem;
11 return 0;
12}
libc/musl/src/math/__cos.c created+71
......@@ -0,0 +1,71 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/k_cos.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * __cos( x, y )
14 * kernel cos function on [-pi/4, pi/4], pi/4 ~ 0.785398164
15 * Input x is assumed to be bounded by ~pi/4 in magnitude.
16 * Input y is the tail of x.
17 *
18 * Algorithm
19 * 1. Since cos(-x) = cos(x), we need only to consider positive x.
20 * 2. if x < 2^-27 (hx<0x3e400000 0), return 1 with inexact if x!=0.
21 * 3. cos(x) is approximated by a polynomial of degree 14 on
22 * [0,pi/4]
23 * 4 14
24 * cos(x) ~ 1 - x*x/2 + C1*x + ... + C6*x
25 * where the remez error is
26 *
27 * | 2 4 6 8 10 12 14 | -58
28 * |cos(x)-(1-.5*x +C1*x +C2*x +C3*x +C4*x +C5*x +C6*x )| <= 2
29 * | |
30 *
31 * 4 6 8 10 12 14
32 * 4. let r = C1*x +C2*x +C3*x +C4*x +C5*x +C6*x , then
33 * cos(x) ~ 1 - x*x/2 + r
34 * since cos(x+y) ~ cos(x) - sin(x)*y
35 * ~ cos(x) - x*y,
36 * a correction term is necessary in cos(x) and hence
37 * cos(x+y) = 1 - (x*x/2 - (r - x*y))
38 * For better accuracy, rearrange to
39 * cos(x+y) ~ w + (tmp + (r-x*y))
40 * where w = 1 - x*x/2 and tmp is a tiny correction term
41 * (1 - x*x/2 == w + tmp exactly in infinite precision).
42 * The exactness of w + tmp in infinite precision depends on w
43 * and tmp having the same precision as x. If they have extra
44 * precision due to compiler bugs, then the extra precision is
45 * only good provided it is retained in all terms of the final
46 * expression for cos(). Retention happens in all cases tested
47 * under FreeBSD, so don't pessimize things by forcibly clipping
48 * any extra precision in w.
49 */
50
51#include "libm.h"
52
53static const double
54C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */
55C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */
56C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */
57C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */
58C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */
59C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */
60
61double __cos(double x, double y)
62{
63 double_t hz,z,r,w;
64
65 z = x*x;
66 w = z*z;
67 r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6));
68 hz = 0.5*z;
69 w = 1.0-hz;
70 return w + (((1.0-w)-hz) + (z*r-x*y));
71}
libc/musl/src/math/__cosdf.c created+35
......@@ -0,0 +1,35 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 * Debugged and optimized by Bruce D. Evans.
5 */
6/*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 *
10 * Developed at SunPro, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
15 */
16
17#include "libm.h"
18
19/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
20static const double
21C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
22C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */
23C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
24C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */
25
26float __cosdf(double x)
27{
28 double_t r, w, z;
29
30 /* Try to optimize for parallel evaluation as in __tandf.c. */
31 z = x*x;
32 w = z*z;
33 r = C2+z*C3;
34 return ((1.0+z*C0) + w*C1) + (w*z)*r;
35}
libc/musl/src/math/__cosl.c created+96
......@@ -0,0 +1,96 @@
1/* origin: FreeBSD /usr/src/lib/msun/ld80/k_cosl.c */
2/* origin: FreeBSD /usr/src/lib/msun/ld128/k_cosl.c */
3/*
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
7 *
8 * Developed at SunSoft, a Sun Microsystems, Inc. business.
9 * Permission to use, copy, modify, and distribute this
10 * software is freely granted, provided that this notice
11 * is preserved.
12 * ====================================================
13 */
14
15
16#include "libm.h"
17
18#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
19#if LDBL_MANT_DIG == 64
20/*
21 * ld80 version of __cos.c. See __cos.c for most comments.
22 */
23/*
24 * Domain [-0.7854, 0.7854], range ~[-2.43e-23, 2.425e-23]:
25 * |cos(x) - c(x)| < 2**-75.1
26 *
27 * The coefficients of c(x) were generated by a pari-gp script using
28 * a Remez algorithm that searches for the best higher coefficients
29 * after rounding leading coefficients to a specified precision.
30 *
31 * Simpler methods like Chebyshev or basic Remez barely suffice for
32 * cos() in 64-bit precision, because we want the coefficient of x^2
33 * to be precisely -0.5 so that multiplying by it is exact, and plain
34 * rounding of the coefficients of a good polynomial approximation only
35 * gives this up to about 64-bit precision. Plain rounding also gives
36 * a mediocre approximation for the coefficient of x^4, but a rounding
37 * error of 0.5 ulps for this coefficient would only contribute ~0.01
38 * ulps to the final error, so this is unimportant. Rounding errors in
39 * higher coefficients are even less important.
40 *
41 * In fact, coefficients above the x^4 one only need to have 53-bit
42 * precision, and this is more efficient. We get this optimization
43 * almost for free from the complications needed to search for the best
44 * higher coefficients.
45 */
46static const long double
47C1 = 0.0416666666666666666136L; /* 0xaaaaaaaaaaaaaa9b.0p-68 */
48static const double
49C2 = -0.0013888888888888874, /* -0x16c16c16c16c10.0p-62 */
50C3 = 0.000024801587301571716, /* 0x1a01a01a018e22.0p-68 */
51C4 = -0.00000027557319215507120, /* -0x127e4fb7602f22.0p-74 */
52C5 = 0.0000000020876754400407278, /* 0x11eed8caaeccf1.0p-81 */
53C6 = -1.1470297442401303e-11, /* -0x19393412bd1529.0p-89 */
54C7 = 4.7383039476436467e-14; /* 0x1aac9d9af5c43e.0p-97 */
55#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*C7)))))))
56#elif LDBL_MANT_DIG == 113
57/*
58 * ld128 version of __cos.c. See __cos.c for most comments.
59 */
60/*
61 * Domain [-0.7854, 0.7854], range ~[-1.80e-37, 1.79e-37]:
62 * |cos(x) - c(x))| < 2**-122.0
63 *
64 * 113-bit precision requires more care than 64-bit precision, since
65 * simple methods give a minimax polynomial with coefficient for x^2
66 * that is 1 ulp below 0.5, but we want it to be precisely 0.5. See
67 * above for more details.
68 */
69static const long double
70C1 = 0.04166666666666666666666666666666658424671L,
71C2 = -0.001388888888888888888888888888863490893732L,
72C3 = 0.00002480158730158730158730158600795304914210L,
73C4 = -0.2755731922398589065255474947078934284324e-6L,
74C5 = 0.2087675698786809897659225313136400793948e-8L,
75C6 = -0.1147074559772972315817149986812031204775e-10L,
76C7 = 0.4779477332386808976875457937252120293400e-13L;
77static const double
78C8 = -0.1561920696721507929516718307820958119868e-15,
79C9 = 0.4110317413744594971475941557607804508039e-18,
80C10 = -0.8896592467191938803288521958313920156409e-21,
81C11 = 0.1601061435794535138244346256065192782581e-23;
82#define POLY(z) (z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*(C6+z*(C7+ \
83 z*(C8+z*(C9+z*(C10+z*C11)))))))))))
84#endif
85
86long double __cosl(long double x, long double y)
87{
88 long double hz,z,r,w;
89
90 z = x*x;
91 r = POLY(z);
92 hz = 0.5*z;
93 w = 1.0-hz;
94 return w + (((1.0-w)-hz) + (z*r-x*y));
95}
96#endif
libc/musl/src/math/__expo2.c created+16
......@@ -0,0 +1,16 @@
1#include "libm.h"
2
3/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */
4static const int k = 2043;
5static const double kln2 = 0x1.62066151add8bp+10;
6
7/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */
8double __expo2(double x)
9{
10 double scale;
11
12 /* note that k is odd and scale*scale overflows */
13 INSERT_WORDS(scale, (uint32_t)(0x3ff + k/2) << 20, 0);
14 /* exp(x - k ln2) * 2**(k-1) */
15 return exp(x - kln2) * scale * scale;
16}
libc/musl/src/math/__expo2f.c created+16
......@@ -0,0 +1,16 @@
1#include "libm.h"
2
3/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */
4static const int k = 235;
5static const float kln2 = 0x1.45c778p+7f;
6
7/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */
8float __expo2f(float x)
9{
10 float scale;
11
12 /* note that k is odd and scale*scale overflows */
13 SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23);
14 /* exp(x - k ln2) * 2**(k-1) */
15 return expf(x - kln2) * scale * scale;
16}
libc/musl/src/math/__fpclassify.c created+11
......@@ -0,0 +1,11 @@
1#include <math.h>
2#include <stdint.h>
3
4int __fpclassify(double x)
5{
6 union {double f; uint64_t i;} u = {x};
7 int e = u.i>>52 & 0x7ff;
8 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
9 if (e==0x7ff) return u.i<<12 ? FP_NAN : FP_INFINITE;
10 return FP_NORMAL;
11}
libc/musl/src/math/__fpclassifyf.c created+11
......@@ -0,0 +1,11 @@
1#include <math.h>
2#include <stdint.h>
3
4int __fpclassifyf(float x)
5{
6 union {float f; uint32_t i;} u = {x};
7 int e = u.i>>23 & 0xff;
8 if (!e) return u.i<<1 ? FP_SUBNORMAL : FP_ZERO;
9 if (e==0xff) return u.i<<9 ? FP_NAN : FP_INFINITE;
10 return FP_NORMAL;
11}
libc/musl/src/math/__fpclassifyl.c created+42
......@@ -0,0 +1,42 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4int __fpclassifyl(long double x)
5{
6 return __fpclassify(x);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9int __fpclassifyl(long double x)
10{
11 union ldshape u = {x};
12 int e = u.i.se & 0x7fff;
13 int msb = u.i.m>>63;
14 if (!e && !msb)
15 return u.i.m ? FP_SUBNORMAL : FP_ZERO;
16 if (e == 0x7fff) {
17 /* The x86 variant of 80-bit extended precision only admits
18 * one representation of each infinity, with the mantissa msb
19 * necessarily set. The version with it clear is invalid/nan.
20 * The m68k variant, however, allows either, and tooling uses
21 * the version with it clear. */
22 if (__BYTE_ORDER == __LITTLE_ENDIAN && !msb)
23 return FP_NAN;
24 return u.i.m << 1 ? FP_NAN : FP_INFINITE;
25 }
26 if (!msb)
27 return FP_NAN;
28 return FP_NORMAL;
29}
30#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
31int __fpclassifyl(long double x)
32{
33 union ldshape u = {x};
34 int e = u.i.se & 0x7fff;
35 u.i.se = 0;
36 if (!e)
37 return u.i2.lo | u.i2.hi ? FP_SUBNORMAL : FP_ZERO;
38 if (e == 0x7fff)
39 return u.i2.lo | u.i2.hi ? FP_NAN : FP_INFINITE;
40 return FP_NORMAL;
41}
42#endif
libc/musl/src/math/__invtrigl.c created+63
......@@ -0,0 +1,63 @@
1#include <float.h>
2#include "__invtrigl.h"
3
4#if LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
5static const long double
6pS0 = 1.66666666666666666631e-01L,
7pS1 = -4.16313987993683104320e-01L,
8pS2 = 3.69068046323246813704e-01L,
9pS3 = -1.36213932016738603108e-01L,
10pS4 = 1.78324189708471965733e-02L,
11pS5 = -2.19216428382605211588e-04L,
12pS6 = -7.10526623669075243183e-06L,
13qS1 = -2.94788392796209867269e+00L,
14qS2 = 3.27309890266528636716e+00L,
15qS3 = -1.68285799854822427013e+00L,
16qS4 = 3.90699412641738801874e-01L,
17qS5 = -3.14365703596053263322e-02L;
18
19const long double pio2_hi = 1.57079632679489661926L;
20const long double pio2_lo = -2.50827880633416601173e-20L;
21
22/* used in asinl() and acosl() */
23/* R(x^2) is a rational approximation of (asin(x)-x)/x^3 with Remez algorithm */
24long double __invtrigl_R(long double z)
25{
26 long double p, q;
27 p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*pS6))))));
28 q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*qS5))));
29 return p/q;
30}
31#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
32static const long double
33pS0 = 1.66666666666666666666666666666700314e-01L,
34pS1 = -7.32816946414566252574527475428622708e-01L,
35pS2 = 1.34215708714992334609030036562143589e+00L,
36pS3 = -1.32483151677116409805070261790752040e+00L,
37pS4 = 7.61206183613632558824485341162121989e-01L,
38pS5 = -2.56165783329023486777386833928147375e-01L,
39pS6 = 4.80718586374448793411019434585413855e-02L,
40pS7 = -4.42523267167024279410230886239774718e-03L,
41pS8 = 1.44551535183911458253205638280410064e-04L,
42pS9 = -2.10558957916600254061591040482706179e-07L,
43qS1 = -4.84690167848739751544716485245697428e+00L,
44qS2 = 9.96619113536172610135016921140206980e+00L,
45qS3 = -1.13177895428973036660836798461641458e+01L,
46qS4 = 7.74004374389488266169304117714658761e+00L,
47qS5 = -3.25871986053534084709023539900339905e+00L,
48qS6 = 8.27830318881232209752469022352928864e-01L,
49qS7 = -1.18768052702942805423330715206348004e-01L,
50qS8 = 8.32600764660522313269101537926539470e-03L,
51qS9 = -1.99407384882605586705979504567947007e-04L;
52
53const long double pio2_hi = 1.57079632679489661923132169163975140L;
54const long double pio2_lo = 4.33590506506189051239852201302167613e-35L;
55
56long double __invtrigl_R(long double z)
57{
58 long double p, q;
59 p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*(pS5+z*(pS6+z*(pS7+z*(pS8+z*pS9)))))))));
60 q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*(qS4+z*(qS5+z*(qS6+z*(qS7+z*(qS8+z*qS9))))))));
61 return p/q;
62}
63#endif
libc/musl/src/math/__invtrigl.h created+8
......@@ -0,0 +1,8 @@
1#include <features.h>
2
3/* shared by acosl, asinl and atan2l */
4#define pio2_hi __pio2_hi
5#define pio2_lo __pio2_lo
6hidden extern const long double pio2_hi, pio2_lo;
7
8hidden long double __invtrigl_R(long double z);
libc/musl/src/math/__polevll.c created+93
......@@ -0,0 +1,93 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/polevll.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Evaluate polynomial
19 *
20 *
21 * SYNOPSIS:
22 *
23 * int N;
24 * long double x, y, coef[N+1], polevl[];
25 *
26 * y = polevll( x, coef, N );
27 *
28 *
29 * DESCRIPTION:
30 *
31 * Evaluates polynomial of degree N:
32 *
33 * 2 N
34 * y = C + C x + C x +...+ C x
35 * 0 1 2 N
36 *
37 * Coefficients are stored in reverse order:
38 *
39 * coef[0] = C , ..., coef[N] = C .
40 * N 0
41 *
42 * The function p1evll() assumes that coef[N] = 1.0 and is
43 * omitted from the array. Its calling arguments are
44 * otherwise the same as polevll().
45 *
46 *
47 * SPEED:
48 *
49 * In the interest of speed, there are no checks for out
50 * of bounds arithmetic. This routine is used by most of
51 * the functions in the library. Depending on available
52 * equipment features, the user may wish to rewrite the
53 * program in microcode or assembly language.
54 *
55 */
56
57#include "libm.h"
58
59#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
60#else
61/*
62 * Polynomial evaluator:
63 * P[0] x^n + P[1] x^(n-1) + ... + P[n]
64 */
65long double __polevll(long double x, const long double *P, int n)
66{
67 long double y;
68
69 y = *P++;
70 do {
71 y = y * x + *P++;
72 } while (--n);
73
74 return y;
75}
76
77/*
78 * Polynomial evaluator:
79 * x^n + P[0] x^(n-1) + P[1] x^(n-2) + ... + P[n]
80 */
81long double __p1evll(long double x, const long double *P, int n)
82{
83 long double y;
84
85 n -= 1;
86 y = x + *P++;
87 do {
88 y = y * x + *P++;
89 } while (--n);
90
91 return y;
92}
93#endif
libc/musl/src/math/__rem_pio2.c created+177
......@@ -0,0 +1,177 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 *
12 * Optimized by Bruce D. Evans.
13 */
14/* __rem_pio2(x,y)
15 *
16 * return the remainder of x rem pi/2 in y[0]+y[1]
17 * use __rem_pio2_large() for large x
18 */
19
20#include "libm.h"
21
22#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
23#define EPS DBL_EPSILON
24#elif FLT_EVAL_METHOD==2
25#define EPS LDBL_EPSILON
26#endif
27
28/*
29 * invpio2: 53 bits of 2/pi
30 * pio2_1: first 33 bit of pi/2
31 * pio2_1t: pi/2 - pio2_1
32 * pio2_2: second 33 bit of pi/2
33 * pio2_2t: pi/2 - (pio2_1+pio2_2)
34 * pio2_3: third 33 bit of pi/2
35 * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
36 */
37static const double
38toint = 1.5/EPS,
39invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
40pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */
41pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */
42pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */
43pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */
44pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */
45pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */
46
47/* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */
48int __rem_pio2(double x, double *y)
49{
50 union {double f; uint64_t i;} u = {x};
51 double_t z,w,t,r,fn;
52 double tx[3],ty[2];
53 uint32_t ix;
54 int sign, n, ex, ey, i;
55
56 sign = u.i>>63;
57 ix = u.i>>32 & 0x7fffffff;
58 if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */
59 if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */
60 goto medium; /* cancellation -- use medium case */
61 if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */
62 if (!sign) {
63 z = x - pio2_1; /* one round good to 85 bits */
64 y[0] = z - pio2_1t;
65 y[1] = (z-y[0]) - pio2_1t;
66 return 1;
67 } else {
68 z = x + pio2_1;
69 y[0] = z + pio2_1t;
70 y[1] = (z-y[0]) + pio2_1t;
71 return -1;
72 }
73 } else {
74 if (!sign) {
75 z = x - 2*pio2_1;
76 y[0] = z - 2*pio2_1t;
77 y[1] = (z-y[0]) - 2*pio2_1t;
78 return 2;
79 } else {
80 z = x + 2*pio2_1;
81 y[0] = z + 2*pio2_1t;
82 y[1] = (z-y[0]) + 2*pio2_1t;
83 return -2;
84 }
85 }
86 }
87 if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */
88 if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */
89 if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */
90 goto medium;
91 if (!sign) {
92 z = x - 3*pio2_1;
93 y[0] = z - 3*pio2_1t;
94 y[1] = (z-y[0]) - 3*pio2_1t;
95 return 3;
96 } else {
97 z = x + 3*pio2_1;
98 y[0] = z + 3*pio2_1t;
99 y[1] = (z-y[0]) + 3*pio2_1t;
100 return -3;
101 }
102 } else {
103 if (ix == 0x401921fb) /* |x| ~= 4pi/2 */
104 goto medium;
105 if (!sign) {
106 z = x - 4*pio2_1;
107 y[0] = z - 4*pio2_1t;
108 y[1] = (z-y[0]) - 4*pio2_1t;
109 return 4;
110 } else {
111 z = x + 4*pio2_1;
112 y[0] = z + 4*pio2_1t;
113 y[1] = (z-y[0]) + 4*pio2_1t;
114 return -4;
115 }
116 }
117 }
118 if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */
119medium:
120 /* rint(x/(pi/2)), Assume round-to-nearest. */
121 fn = (double_t)x*invpio2 + toint - toint;
122 n = (int32_t)fn;
123 r = x - fn*pio2_1;
124 w = fn*pio2_1t; /* 1st round, good to 85 bits */
125 y[0] = r - w;
126 u.f = y[0];
127 ey = u.i>>52 & 0x7ff;
128 ex = ix>>20;
129 if (ex - ey > 16) { /* 2nd round, good to 118 bits */
130 t = r;
131 w = fn*pio2_2;
132 r = t - w;
133 w = fn*pio2_2t - ((t-r)-w);
134 y[0] = r - w;
135 u.f = y[0];
136 ey = u.i>>52 & 0x7ff;
137 if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */
138 t = r;
139 w = fn*pio2_3;
140 r = t - w;
141 w = fn*pio2_3t - ((t-r)-w);
142 y[0] = r - w;
143 }
144 }
145 y[1] = (r - y[0]) - w;
146 return n;
147 }
148 /*
149 * all other (large) arguments
150 */
151 if (ix >= 0x7ff00000) { /* x is inf or NaN */
152 y[0] = y[1] = x - x;
153 return 0;
154 }
155 /* set z = scalbn(|x|,-ilogb(x)+23) */
156 u.f = x;
157 u.i &= (uint64_t)-1>>12;
158 u.i |= (uint64_t)(0x3ff + 23)<<52;
159 z = u.f;
160 for (i=0; i < 2; i++) {
161 tx[i] = (double)(int32_t)z;
162 z = (z-tx[i])*0x1p24;
163 }
164 tx[i] = z;
165 /* skip zero terms, first term is non-zero */
166 while (tx[i] == 0.0)
167 i--;
168 n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1);
169 if (sign) {
170 y[0] = -ty[0];
171 y[1] = -ty[1];
172 return -n;
173 }
174 y[0] = ty[0];
175 y[1] = ty[1];
176 return n;
177}
libc/musl/src/math/__rem_pio2_large.c created+442
......@@ -0,0 +1,442 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/k_rem_pio2.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * __rem_pio2_large(x,y,e0,nx,prec)
14 * double x[],y[]; int e0,nx,prec;
15 *
16 * __rem_pio2_large return the last three digits of N with
17 * y = x - N*pi/2
18 * so that |y| < pi/2.
19 *
20 * The method is to compute the integer (mod 8) and fraction parts of
21 * (2/pi)*x without doing the full multiplication. In general we
22 * skip the part of the product that are known to be a huge integer (
23 * more accurately, = 0 mod 8 ). Thus the number of operations are
24 * independent of the exponent of the input.
25 *
26 * (2/pi) is represented by an array of 24-bit integers in ipio2[].
27 *
28 * Input parameters:
29 * x[] The input value (must be positive) is broken into nx
30 * pieces of 24-bit integers in double precision format.
31 * x[i] will be the i-th 24 bit of x. The scaled exponent
32 * of x[0] is given in input parameter e0 (i.e., x[0]*2^e0
33 * match x's up to 24 bits.
34 *
35 * Example of breaking a double positive z into x[0]+x[1]+x[2]:
36 * e0 = ilogb(z)-23
37 * z = scalbn(z,-e0)
38 * for i = 0,1,2
39 * x[i] = floor(z)
40 * z = (z-x[i])*2**24
41 *
42 *
43 * y[] ouput result in an array of double precision numbers.
44 * The dimension of y[] is:
45 * 24-bit precision 1
46 * 53-bit precision 2
47 * 64-bit precision 2
48 * 113-bit precision 3
49 * The actual value is the sum of them. Thus for 113-bit
50 * precison, one may have to do something like:
51 *
52 * long double t,w,r_head, r_tail;
53 * t = (long double)y[2] + (long double)y[1];
54 * w = (long double)y[0];
55 * r_head = t+w;
56 * r_tail = w - (r_head - t);
57 *
58 * e0 The exponent of x[0]. Must be <= 16360 or you need to
59 * expand the ipio2 table.
60 *
61 * nx dimension of x[]
62 *
63 * prec an integer indicating the precision:
64 * 0 24 bits (single)
65 * 1 53 bits (double)
66 * 2 64 bits (extended)
67 * 3 113 bits (quad)
68 *
69 * External function:
70 * double scalbn(), floor();
71 *
72 *
73 * Here is the description of some local variables:
74 *
75 * jk jk+1 is the initial number of terms of ipio2[] needed
76 * in the computation. The minimum and recommended value
77 * for jk is 3,4,4,6 for single, double, extended, and quad.
78 * jk+1 must be 2 larger than you might expect so that our
79 * recomputation test works. (Up to 24 bits in the integer
80 * part (the 24 bits of it that we compute) and 23 bits in
81 * the fraction part may be lost to cancelation before we
82 * recompute.)
83 *
84 * jz local integer variable indicating the number of
85 * terms of ipio2[] used.
86 *
87 * jx nx - 1
88 *
89 * jv index for pointing to the suitable ipio2[] for the
90 * computation. In general, we want
91 * ( 2^e0*x[0] * ipio2[jv-1]*2^(-24jv) )/8
92 * is an integer. Thus
93 * e0-3-24*jv >= 0 or (e0-3)/24 >= jv
94 * Hence jv = max(0,(e0-3)/24).
95 *
96 * jp jp+1 is the number of terms in PIo2[] needed, jp = jk.
97 *
98 * q[] double array with integral value, representing the
99 * 24-bits chunk of the product of x and 2/pi.
100 *
101 * q0 the corresponding exponent of q[0]. Note that the
102 * exponent for q[i] would be q0-24*i.
103 *
104 * PIo2[] double precision array, obtained by cutting pi/2
105 * into 24 bits chunks.
106 *
107 * f[] ipio2[] in floating point
108 *
109 * iq[] integer array by breaking up q[] in 24-bits chunk.
110 *
111 * fq[] final product of x*(2/pi) in fq[0],..,fq[jk]
112 *
113 * ih integer. If >0 it indicates q[] is >= 0.5, hence
114 * it also indicates the *sign* of the result.
115 *
116 */
117/*
118 * Constants:
119 * The hexadecimal values are the intended ones for the following
120 * constants. The decimal values may be used, provided that the
121 * compiler will convert from decimal to binary accurately enough
122 * to produce the hexadecimal values shown.
123 */
124
125#include "libm.h"
126
127static const int init_jk[] = {3,4,4,6}; /* initial value for jk */
128
129/*
130 * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi
131 *
132 * integer array, contains the (24*i)-th to (24*i+23)-th
133 * bit of 2/pi after binary point. The corresponding
134 * floating value is
135 *
136 * ipio2[i] * 2^(-24(i+1)).
137 *
138 * NB: This table must have at least (e0-3)/24 + jk terms.
139 * For quad precision (e0 <= 16360, jk = 6), this is 686.
140 */
141static const int32_t ipio2[] = {
1420xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62,
1430x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A,
1440x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129,
1450xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41,
1460x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8,
1470x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF,
1480x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5,
1490xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08,
1500x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3,
1510x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880,
1520x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B,
153
154#if LDBL_MAX_EXP > 1024
1550x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6,
1560xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2,
1570xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35,
1580xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30,
1590x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C,
1600x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4,
1610xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770,
1620xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7,
1630xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19,
1640xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522,
1650x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16,
1660xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6,
1670x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E,
1680x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48,
1690xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3,
1700xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF,
1710xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55,
1720x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612,
1730xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929,
1740x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC,
1750xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B,
1760x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C,
1770x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4,
1780x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB,
1790xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC,
1800x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C,
1810x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F,
1820xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5,
1830x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437,
1840x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B,
1850x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA,
1860x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD,
1870x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3,
1880x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3,
1890xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717,
1900x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F,
1910xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61,
1920xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB,
1930xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51,
1940xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0,
1950x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C,
1960x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6,
1970x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC,
1980xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED,
1990x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328,
2000x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D,
2010x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0,
2020xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B,
2030x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4,
2040xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3,
2050xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F,
2060x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD,
2070x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B,
2080x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4,
2090xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761,
2100x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31,
2110x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30,
2120xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262,
2130x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E,
2140xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1,
2150xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C,
2160x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4,
2170xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08,
2180x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196,
2190xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9,
2200x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4,
2210x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC,
2220x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C,
2230xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0,
2240x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C,
2250xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0,
2260x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC,
2270xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22,
2280x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893,
2290x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7,
2300xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5,
2310x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F,
2320xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4,
2330x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF,
2340x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B,
2350x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2,
2360x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138,
2370xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E,
2380xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569,
2390x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34,
2400xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9,
2410x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D,
2420xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F,
2430xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855,
2440x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569,
2450xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B,
2460x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE,
2470x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41,
2480x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49,
2490xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F,
2500xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110,
2510x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8,
2520x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365,
2530xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A,
2540x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270,
2550x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5,
2560x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616,
2570x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B,
2580x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0,
259#endif
260};
261
262static const double PIo2[] = {
263 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */
264 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */
265 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */
266 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */
267 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */
268 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */
269 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */
270 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */
271};
272
273int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec)
274{
275 int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih;
276 double z,fw,f[20],fq[20],q[20];
277
278 /* initialize jk*/
279 jk = init_jk[prec];
280 jp = jk;
281
282 /* determine jx,jv,q0, note that 3>q0 */
283 jx = nx-1;
284 jv = (e0-3)/24; if(jv<0) jv=0;
285 q0 = e0-24*(jv+1);
286
287 /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */
288 j = jv-jx; m = jx+jk;
289 for (i=0; i<=m; i++,j++)
290 f[i] = j<0 ? 0.0 : (double)ipio2[j];
291
292 /* compute q[0],q[1],...q[jk] */
293 for (i=0; i<=jk; i++) {
294 for (j=0,fw=0.0; j<=jx; j++)
295 fw += x[j]*f[jx+i-j];
296 q[i] = fw;
297 }
298
299 jz = jk;
300recompute:
301 /* distill q[] into iq[] reversingly */
302 for (i=0,j=jz,z=q[jz]; j>0; i++,j--) {
303 fw = (double)(int32_t)(0x1p-24*z);
304 iq[i] = (int32_t)(z - 0x1p24*fw);
305 z = q[j-1]+fw;
306 }
307
308 /* compute n */
309 z = scalbn(z,q0); /* actual value of z */
310 z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */
311 n = (int32_t)z;
312 z -= (double)n;
313 ih = 0;
314 if (q0 > 0) { /* need iq[jz-1] to determine n */
315 i = iq[jz-1]>>(24-q0); n += i;
316 iq[jz-1] -= i<<(24-q0);
317 ih = iq[jz-1]>>(23-q0);
318 }
319 else if (q0 == 0) ih = iq[jz-1]>>23;
320 else if (z >= 0.5) ih = 2;
321
322 if (ih > 0) { /* q > 0.5 */
323 n += 1; carry = 0;
324 for (i=0; i<jz; i++) { /* compute 1-q */
325 j = iq[i];
326 if (carry == 0) {
327 if (j != 0) {
328 carry = 1;
329 iq[i] = 0x1000000 - j;
330 }
331 } else
332 iq[i] = 0xffffff - j;
333 }
334 if (q0 > 0) { /* rare case: chance is 1 in 12 */
335 switch(q0) {
336 case 1:
337 iq[jz-1] &= 0x7fffff; break;
338 case 2:
339 iq[jz-1] &= 0x3fffff; break;
340 }
341 }
342 if (ih == 2) {
343 z = 1.0 - z;
344 if (carry != 0)
345 z -= scalbn(1.0,q0);
346 }
347 }
348
349 /* check if recomputation is needed */
350 if (z == 0.0) {
351 j = 0;
352 for (i=jz-1; i>=jk; i--) j |= iq[i];
353 if (j == 0) { /* need recomputation */
354 for (k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */
355
356 for (i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */
357 f[jx+i] = (double)ipio2[jv+i];
358 for (j=0,fw=0.0; j<=jx; j++)
359 fw += x[j]*f[jx+i-j];
360 q[i] = fw;
361 }
362 jz += k;
363 goto recompute;
364 }
365 }
366
367 /* chop off zero terms */
368 if (z == 0.0) {
369 jz -= 1;
370 q0 -= 24;
371 while (iq[jz] == 0) {
372 jz--;
373 q0 -= 24;
374 }
375 } else { /* break z into 24-bit if necessary */
376 z = scalbn(z,-q0);
377 if (z >= 0x1p24) {
378 fw = (double)(int32_t)(0x1p-24*z);
379 iq[jz] = (int32_t)(z - 0x1p24*fw);
380 jz += 1;
381 q0 += 24;
382 iq[jz] = (int32_t)fw;
383 } else
384 iq[jz] = (int32_t)z;
385 }
386
387 /* convert integer "bit" chunk to floating-point value */
388 fw = scalbn(1.0,q0);
389 for (i=jz; i>=0; i--) {
390 q[i] = fw*(double)iq[i];
391 fw *= 0x1p-24;
392 }
393
394 /* compute PIo2[0,...,jp]*q[jz,...,0] */
395 for(i=jz; i>=0; i--) {
396 for (fw=0.0,k=0; k<=jp && k<=jz-i; k++)
397 fw += PIo2[k]*q[i+k];
398 fq[jz-i] = fw;
399 }
400
401 /* compress fq[] into y[] */
402 switch(prec) {
403 case 0:
404 fw = 0.0;
405 for (i=jz; i>=0; i--)
406 fw += fq[i];
407 y[0] = ih==0 ? fw : -fw;
408 break;
409 case 1:
410 case 2:
411 fw = 0.0;
412 for (i=jz; i>=0; i--)
413 fw += fq[i];
414 // TODO: drop excess precision here once double_t is used
415 fw = (double)fw;
416 y[0] = ih==0 ? fw : -fw;
417 fw = fq[0]-fw;
418 for (i=1; i<=jz; i++)
419 fw += fq[i];
420 y[1] = ih==0 ? fw : -fw;
421 break;
422 case 3: /* painful */
423 for (i=jz; i>0; i--) {
424 fw = fq[i-1]+fq[i];
425 fq[i] += fq[i-1]-fw;
426 fq[i-1] = fw;
427 }
428 for (i=jz; i>1; i--) {
429 fw = fq[i-1]+fq[i];
430 fq[i] += fq[i-1]-fw;
431 fq[i-1] = fw;
432 }
433 for (fw=0.0,i=jz; i>=2; i--)
434 fw += fq[i];
435 if (ih==0) {
436 y[0] = fq[0]; y[1] = fq[1]; y[2] = fw;
437 } else {
438 y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw;
439 }
440 }
441 return n&7;
442}
libc/musl/src/math/__rem_pio2f.c created+75
......@@ -0,0 +1,75 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_rem_pio2f.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 * Debugged and optimized by Bruce D. Evans.
5 */
6/*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 *
10 * Developed at SunPro, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
15 */
16/* __rem_pio2f(x,y)
17 *
18 * return the remainder of x rem pi/2 in *y
19 * use double precision for everything except passing x
20 * use __rem_pio2_large() for large x
21 */
22
23#include "libm.h"
24
25#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
26#define EPS DBL_EPSILON
27#elif FLT_EVAL_METHOD==2
28#define EPS LDBL_EPSILON
29#endif
30
31/*
32 * invpio2: 53 bits of 2/pi
33 * pio2_1: first 25 bits of pi/2
34 * pio2_1t: pi/2 - pio2_1
35 */
36static const double
37toint = 1.5/EPS,
38invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */
39pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */
40pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */
41
42int __rem_pio2f(float x, double *y)
43{
44 union {float f; uint32_t i;} u = {x};
45 double tx[1],ty[1];
46 double_t fn;
47 uint32_t ix;
48 int n, sign, e0;
49
50 ix = u.i & 0x7fffffff;
51 /* 25+53 bit pi is good enough for medium size */
52 if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */
53 /* Use a specialized rint() to get fn. Assume round-to-nearest. */
54 fn = (double_t)x*invpio2 + toint - toint;
55 n = (int32_t)fn;
56 *y = x - fn*pio2_1 - fn*pio2_1t;
57 return n;
58 }
59 if(ix>=0x7f800000) { /* x is inf or NaN */
60 *y = x-x;
61 return 0;
62 }
63 /* scale x into [2^23, 2^24-1] */
64 sign = u.i>>31;
65 e0 = (ix>>23) - (0x7f+23); /* e0 = ilogb(|x|)-23, positive */
66 u.i = ix - (e0<<23);
67 tx[0] = u.f;
68 n = __rem_pio2_large(tx,ty,e0,1,0);
69 if (sign) {
70 *y = -ty[0];
71 return -n;
72 }
73 *y = ty[0];
74 return n;
75}
libc/musl/src/math/__rem_pio2l.c created+141
......@@ -0,0 +1,141 @@
1/* origin: FreeBSD /usr/src/lib/msun/ld80/e_rem_pio2.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
6 *
7 * Developed at SunSoft, a Sun Microsystems, Inc. business.
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
12 *
13 * Optimized by Bruce D. Evans.
14 */
15#include "libm.h"
16#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
17/* ld80 and ld128 version of __rem_pio2(x,y)
18 *
19 * return the remainder of x rem pi/2 in y[0]+y[1]
20 * use __rem_pio2_large() for large x
21 */
22
23static const long double toint = 1.5/LDBL_EPSILON;
24
25#if LDBL_MANT_DIG == 64
26/* u ~< 0x1p25*pi/2 */
27#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.m>>48) < ((0x3fff + 25)<<16 | 0x921f>>1 | 0x8000))
28#define QUOBITS(x) ((uint32_t)(int32_t)x & 0x7fffffff)
29#define ROUND1 22
30#define ROUND2 61
31#define NX 3
32#define NY 2
33/*
34 * invpio2: 64 bits of 2/pi
35 * pio2_1: first 39 bits of pi/2
36 * pio2_1t: pi/2 - pio2_1
37 * pio2_2: second 39 bits of pi/2
38 * pio2_2t: pi/2 - (pio2_1+pio2_2)
39 * pio2_3: third 39 bits of pi/2
40 * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
41 */
42static const double
43pio2_1 = 1.57079632679597125389e+00, /* 0x3FF921FB, 0x54444000 */
44pio2_2 = -1.07463465549783099519e-12, /* -0x12e7b967674000.0p-92 */
45pio2_3 = 6.36831716351370313614e-25; /* 0x18a2e037074000.0p-133 */
46static const long double
47invpio2 = 6.36619772367581343076e-01L, /* 0xa2f9836e4e44152a.0p-64 */
48pio2_1t = -1.07463465549719416346e-12L, /* -0x973dcb3b399d747f.0p-103 */
49pio2_2t = 6.36831716351095013979e-25L, /* 0xc51701b839a25205.0p-144 */
50pio2_3t = -2.75299651904407171810e-37L; /* -0xbb5bf6c7ddd660ce.0p-185 */
51#elif LDBL_MANT_DIG == 113
52/* u ~< 0x1p45*pi/2 */
53#define SMALL(u) (((u.i.se & 0x7fffU)<<16 | u.i.top) < ((0x3fff + 45)<<16 | 0x921f))
54#define QUOBITS(x) ((uint32_t)(int64_t)x & 0x7fffffff)
55#define ROUND1 51
56#define ROUND2 119
57#define NX 5
58#define NY 3
59static const long double
60invpio2 = 6.3661977236758134307553505349005747e-01L, /* 0x145f306dc9c882a53f84eafa3ea6a.0p-113 */
61pio2_1 = 1.5707963267948966192292994253909555e+00L, /* 0x1921fb54442d18469800000000000.0p-112 */
62pio2_1t = 2.0222662487959507323996846200947577e-21L, /* 0x13198a2e03707344a4093822299f3.0p-181 */
63pio2_2 = 2.0222662487959507323994779168837751e-21L, /* 0x13198a2e03707344a400000000000.0p-181 */
64pio2_2t = 2.0670321098263988236496903051604844e-43L, /* 0x127044533e63a0105df531d89cd91.0p-254 */
65pio2_3 = 2.0670321098263988236499468110329591e-43L, /* 0x127044533e63a0105e00000000000.0p-254 */
66pio2_3t = -2.5650587247459238361625433492959285e-65L; /* -0x159c4ec64ddaeb5f78671cbfb2210.0p-327 */
67#endif
68
69int __rem_pio2l(long double x, long double *y)
70{
71 union ldshape u,uz;
72 long double z,w,t,r,fn;
73 double tx[NX],ty[NY];
74 int ex,ey,n,i;
75
76 u.f = x;
77 ex = u.i.se & 0x7fff;
78 if (SMALL(u)) {
79 /* rint(x/(pi/2)), Assume round-to-nearest. */
80 fn = x*invpio2 + toint - toint;
81 n = QUOBITS(fn);
82 r = x-fn*pio2_1;
83 w = fn*pio2_1t; /* 1st round good to 102/180 bits (ld80/ld128) */
84 y[0] = r-w;
85 u.f = y[0];
86 ey = u.i.se & 0x7fff;
87 if (ex - ey > ROUND1) { /* 2nd iteration needed, good to 141/248 (ld80/ld128) */
88 t = r;
89 w = fn*pio2_2;
90 r = t-w;
91 w = fn*pio2_2t-((t-r)-w);
92 y[0] = r-w;
93 u.f = y[0];
94 ey = u.i.se & 0x7fff;
95 if (ex - ey > ROUND2) { /* 3rd iteration, good to 180/316 bits */
96 t = r; /* will cover all possible cases (not verified for ld128) */
97 w = fn*pio2_3;
98 r = t-w;
99 w = fn*pio2_3t-((t-r)-w);
100 y[0] = r-w;
101 }
102 }
103 y[1] = (r - y[0]) - w;
104 return n;
105 }
106 /*
107 * all other (large) arguments
108 */
109 if (ex == 0x7fff) { /* x is inf or NaN */
110 y[0] = y[1] = x - x;
111 return 0;
112 }
113 /* set z = scalbn(|x|,-ilogb(x)+23) */
114 uz.f = x;
115 uz.i.se = 0x3fff + 23;
116 z = uz.f;
117 for (i=0; i < NX - 1; i++) {
118 tx[i] = (double)(int32_t)z;
119 z = (z-tx[i])*0x1p24;
120 }
121 tx[i] = z;
122 while (tx[i] == 0)
123 i--;
124 n = __rem_pio2_large(tx, ty, ex-0x3fff-23, i+1, NY);
125 w = ty[1];
126 if (NY == 3)
127 w += ty[2];
128 r = ty[0] + w;
129 /* TODO: for ld128 this does not follow the recommendation of the
130 comments of __rem_pio2_large which seem wrong if |ty[0]| > |ty[1]+ty[2]| */
131 w -= r - ty[0];
132 if (u.i.se >> 15) {
133 y[0] = -r;
134 y[1] = -w;
135 return -n;
136 }
137 y[0] = r;
138 y[1] = w;
139 return n;
140}
141#endif
libc/musl/src/math/__signbit.c created+13
......@@ -0,0 +1,13 @@
1#include "libm.h"
2
3// FIXME: macro in math.h
4int __signbit(double x)
5{
6 union {
7 double d;
8 uint64_t i;
9 } y = { x };
10 return y.i>>63;
11}
12
13
libc/musl/src/math/__signbitf.c created+11
......@@ -0,0 +1,11 @@
1#include "libm.h"
2
3// FIXME: macro in math.h
4int __signbitf(float x)
5{
6 union {
7 float f;
8 uint32_t i;
9 } y = { x };
10 return y.i>>31;
11}
libc/musl/src/math/__signbitl.c created+14
......@@ -0,0 +1,14 @@
1#include "libm.h"
2
3#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
4int __signbitl(long double x)
5{
6 union ldshape u = {x};
7 return u.i.se >> 15;
8}
9#elif LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
10int __signbitl(long double x)
11{
12 return __signbit(x);
13}
14#endif
libc/musl/src/math/__sin.c created+64
......@@ -0,0 +1,64 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/k_sin.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* __sin( x, y, iy)
13 * kernel sin function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
14 * Input x is assumed to be bounded by ~pi/4 in magnitude.
15 * Input y is the tail of x.
16 * Input iy indicates whether y is 0. (if iy=0, y assume to be 0).
17 *
18 * Algorithm
19 * 1. Since sin(-x) = -sin(x), we need only to consider positive x.
20 * 2. Callers must return sin(-0) = -0 without calling here since our
21 * odd polynomial is not evaluated in a way that preserves -0.
22 * Callers may do the optimization sin(x) ~ x for tiny x.
23 * 3. sin(x) is approximated by a polynomial of degree 13 on
24 * [0,pi/4]
25 * 3 13
26 * sin(x) ~ x + S1*x + ... + S6*x
27 * where
28 *
29 * |sin(x) 2 4 6 8 10 12 | -58
30 * |----- - (1+S1*x +S2*x +S3*x +S4*x +S5*x +S6*x )| <= 2
31 * | x |
32 *
33 * 4. sin(x+y) = sin(x) + sin'(x')*y
34 * ~ sin(x) + (1-x*x/2)*y
35 * For better accuracy, let
36 * 3 2 2 2 2
37 * r = x *(S2+x *(S3+x *(S4+x *(S5+x *S6))))
38 * then 3 2
39 * sin(x) = x + (S1*x + (x *(r-y/2)+y))
40 */
41
42#include "libm.h"
43
44static const double
45S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */
46S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */
47S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */
48S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */
49S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */
50S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */
51
52double __sin(double x, double y, int iy)
53{
54 double_t z,r,v,w;
55
56 z = x*x;
57 w = z*z;
58 r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6);
59 v = z*x;
60 if (iy == 0)
61 return x + v*(S1 + z*r);
62 else
63 return x - ((z*(0.5*y - v*r) - y) - v*S1);
64}
libc/musl/src/math/__sindf.c created+36
......@@ -0,0 +1,36 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 * Optimized by Bruce D. Evans.
5 */
6/*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 *
10 * Developed at SunPro, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
15 */
16
17#include "libm.h"
18
19/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
20static const double
21S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
22S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */
23S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
24S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */
25
26float __sindf(double x)
27{
28 double_t r, s, w, z;
29
30 /* Try to optimize for parallel evaluation as in __tandf.c. */
31 z = x*x;
32 w = z*z;
33 r = S3 + z*S4;
34 s = z*x;
35 return (x + s*(S1 + z*S2)) + s*w*r;
36}
libc/musl/src/math/__sinl.c created+78
......@@ -0,0 +1,78 @@
1/* origin: FreeBSD /usr/src/lib/msun/ld80/k_sinl.c */
2/* origin: FreeBSD /usr/src/lib/msun/ld128/k_sinl.c */
3/*
4 * ====================================================
5 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
6 * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
7 *
8 * Developed at SunSoft, a Sun Microsystems, Inc. business.
9 * Permission to use, copy, modify, and distribute this
10 * software is freely granted, provided that this notice
11 * is preserved.
12 * ====================================================
13 */
14
15#include "libm.h"
16
17#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
18#if LDBL_MANT_DIG == 64
19/*
20 * ld80 version of __sin.c. See __sin.c for most comments.
21 */
22/*
23 * Domain [-0.7854, 0.7854], range ~[-1.89e-22, 1.915e-22]
24 * |sin(x)/x - s(x)| < 2**-72.1
25 *
26 * See __cosl.c for more details about the polynomial.
27 */
28static const long double
29S1 = -0.166666666666666666671L; /* -0xaaaaaaaaaaaaaaab.0p-66 */
30static const double
31S2 = 0.0083333333333333332, /* 0x11111111111111.0p-59 */
32S3 = -0.00019841269841269427, /* -0x1a01a01a019f81.0p-65 */
33S4 = 0.0000027557319223597490, /* 0x171de3a55560f7.0p-71 */
34S5 = -0.000000025052108218074604, /* -0x1ae64564f16cad.0p-78 */
35S6 = 1.6059006598854211e-10, /* 0x161242b90243b5.0p-85 */
36S7 = -7.6429779983024564e-13, /* -0x1ae42ebd1b2e00.0p-93 */
37S8 = 2.6174587166648325e-15; /* 0x179372ea0b3f64.0p-101 */
38#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*S8))))))
39#elif LDBL_MANT_DIG == 113
40/*
41 * ld128 version of __sin.c. See __sin.c for most comments.
42 */
43/*
44 * Domain [-0.7854, 0.7854], range ~[-1.53e-37, 1.659e-37]
45 * |sin(x)/x - s(x)| < 2**-122.1
46 *
47 * See __cosl.c for more details about the polynomial.
48 */
49static const long double
50S1 = -0.16666666666666666666666666666666666606732416116558L,
51S2 = 0.0083333333333333333333333333333331135404851288270047L,
52S3 = -0.00019841269841269841269841269839935785325638310428717L,
53S4 = 0.27557319223985890652557316053039946268333231205686e-5L,
54S5 = -0.25052108385441718775048214826384312253862930064745e-7L,
55S6 = 0.16059043836821614596571832194524392581082444805729e-9L,
56S7 = -0.76471637318198151807063387954939213287488216303768e-12L,
57S8 = 0.28114572543451292625024967174638477283187397621303e-14L;
58static const double
59S9 = -0.82206352458348947812512122163446202498005154296863e-17,
60S10 = 0.19572940011906109418080609928334380560135358385256e-19,
61S11 = -0.38680813379701966970673724299207480965452616911420e-22,
62S12 = 0.64038150078671872796678569586315881020659912139412e-25;
63#define POLY(z) (S2+z*(S3+z*(S4+z*(S5+z*(S6+z*(S7+z*(S8+ \
64 z*(S9+z*(S10+z*(S11+z*S12))))))))))
65#endif
66
67long double __sinl(long double x, long double y, int iy)
68{
69 long double z,r,v;
70
71 z = x*x;
72 v = z*x;
73 r = POLY(z);
74 if (iy == 0)
75 return x+v*(S1+z*r);
76 return x-((z*(0.5*y-v*r)-y)-v*S1);
77}
78#endif
libc/musl/src/math/__tan.c created+110
......@@ -0,0 +1,110 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/k_tan.c */
2/*
3 * ====================================================
4 * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
5 *
6 * Permission to use, copy, modify, and distribute this
7 * software is freely granted, provided that this notice
8 * is preserved.
9 * ====================================================
10 */
11/* __tan( x, y, k )
12 * kernel tan function on ~[-pi/4, pi/4] (except on -0), pi/4 ~ 0.7854
13 * Input x is assumed to be bounded by ~pi/4 in magnitude.
14 * Input y is the tail of x.
15 * Input odd indicates whether tan (if odd = 0) or -1/tan (if odd = 1) is returned.
16 *
17 * Algorithm
18 * 1. Since tan(-x) = -tan(x), we need only to consider positive x.
19 * 2. Callers must return tan(-0) = -0 without calling here since our
20 * odd polynomial is not evaluated in a way that preserves -0.
21 * Callers may do the optimization tan(x) ~ x for tiny x.
22 * 3. tan(x) is approximated by a odd polynomial of degree 27 on
23 * [0,0.67434]
24 * 3 27
25 * tan(x) ~ x + T1*x + ... + T13*x
26 * where
27 *
28 * |tan(x) 2 4 26 | -59.2
29 * |----- - (1+T1*x +T2*x +.... +T13*x )| <= 2
30 * | x |
31 *
32 * Note: tan(x+y) = tan(x) + tan'(x)*y
33 * ~ tan(x) + (1+x*x)*y
34 * Therefore, for better accuracy in computing tan(x+y), let
35 * 3 2 2 2 2
36 * r = x *(T2+x *(T3+x *(...+x *(T12+x *T13))))
37 * then
38 * 3 2
39 * tan(x+y) = x + (T1*x + (x *(r+y)+y))
40 *
41 * 4. For x in [0.67434,pi/4], let y = pi/4 - x, then
42 * tan(x) = tan(pi/4-y) = (1-tan(y))/(1+tan(y))
43 * = 1 - 2*(tan(y) - (tan(y)^2)/(1+tan(y)))
44 */
45
46#include "libm.h"
47
48static const double T[] = {
49 3.33333333333334091986e-01, /* 3FD55555, 55555563 */
50 1.33333333333201242699e-01, /* 3FC11111, 1110FE7A */
51 5.39682539762260521377e-02, /* 3FABA1BA, 1BB341FE */
52 2.18694882948595424599e-02, /* 3F9664F4, 8406D637 */
53 8.86323982359930005737e-03, /* 3F8226E3, E96E8493 */
54 3.59207910759131235356e-03, /* 3F6D6D22, C9560328 */
55 1.45620945432529025516e-03, /* 3F57DBC8, FEE08315 */
56 5.88041240820264096874e-04, /* 3F4344D8, F2F26501 */
57 2.46463134818469906812e-04, /* 3F3026F7, 1A8D1068 */
58 7.81794442939557092300e-05, /* 3F147E88, A03792A6 */
59 7.14072491382608190305e-05, /* 3F12B80F, 32F0A7E9 */
60 -1.85586374855275456654e-05, /* BEF375CB, DB605373 */
61 2.59073051863633712884e-05, /* 3EFB2A70, 74BF7AD4 */
62},
63pio4 = 7.85398163397448278999e-01, /* 3FE921FB, 54442D18 */
64pio4lo = 3.06161699786838301793e-17; /* 3C81A626, 33145C07 */
65
66double __tan(double x, double y, int odd)
67{
68 double_t z, r, v, w, s, a;
69 double w0, a0;
70 uint32_t hx;
71 int big, sign;
72
73 GET_HIGH_WORD(hx,x);
74 big = (hx&0x7fffffff) >= 0x3FE59428; /* |x| >= 0.6744 */
75 if (big) {
76 sign = hx>>31;
77 if (sign) {
78 x = -x;
79 y = -y;
80 }
81 x = (pio4 - x) + (pio4lo - y);
82 y = 0.0;
83 }
84 z = x * x;
85 w = z * z;
86 /*
87 * Break x^5*(T[1]+x^2*T[2]+...) into
88 * x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
89 * x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
90 */
91 r = T[1] + w*(T[3] + w*(T[5] + w*(T[7] + w*(T[9] + w*T[11]))));
92 v = z*(T[2] + w*(T[4] + w*(T[6] + w*(T[8] + w*(T[10] + w*T[12])))));
93 s = z * x;
94 r = y + z*(s*(r + v) + y) + s*T[0];
95 w = x + r;
96 if (big) {
97 s = 1 - 2*odd;
98 v = s - 2.0 * (x + (r - w*w/(w + s)));
99 return sign ? -v : v;
100 }
101 if (!odd)
102 return w;
103 /* -1.0/(x+r) has up to 2ulp error, so compute it accurately */
104 w0 = w;
105 SET_LOW_WORD(w0, 0);
106 v = r - (w0 - x); /* w0+v = r+x */
107 a0 = a = -1.0 / w;
108 SET_LOW_WORD(a0, 0);
109 return a0 + a*(1.0 + a0*w0 + a0*v);
110}
libc/musl/src/math/__tandf.c created+54
......@@ -0,0 +1,54 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 * Optimized by Bruce D. Evans.
5 */
6/*
7 * ====================================================
8 * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
9 *
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include "libm.h"
17
18/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */
19static const double T[] = {
20 0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */
21 0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */
22 0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */
23 0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */
24 0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */
25 0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */
26};
27
28float __tandf(double x, int odd)
29{
30 double_t z,r,w,s,t,u;
31
32 z = x*x;
33 /*
34 * Split up the polynomial into small independent terms to give
35 * opportunities for parallel evaluation. The chosen splitting is
36 * micro-optimized for Athlons (XP, X64). It costs 2 multiplications
37 * relative to Horner's method on sequential machines.
38 *
39 * We add the small terms from lowest degree up for efficiency on
40 * non-sequential machines (the lowest degree terms tend to be ready
41 * earlier). Apart from this, we don't care about order of
42 * operations, and don't need to to care since we have precision to
43 * spare. However, the chosen splitting is good for accuracy too,
44 * and would give results as accurate as Horner's method if the
45 * small terms were added from highest degree down.
46 */
47 r = T[4] + z*T[5];
48 t = T[2] + z*T[3];
49 w = z*z;
50 s = z*x;
51 u = T[0] + z*T[1];
52 r = (x + s*u) + (s*w)*(t + w*r);
53 return odd ? -1.0/r : r;
54}
libc/musl/src/math/__tanl.c created+143
......@@ -0,0 +1,143 @@
1/* origin: FreeBSD /usr/src/lib/msun/ld80/k_tanl.c */
2/* origin: FreeBSD /usr/src/lib/msun/ld128/k_tanl.c */
3/*
4 * ====================================================
5 * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
6 * Copyright (c) 2008 Steven G. Kargl, David Schultz, Bruce D. Evans.
7 *
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
12 */
13
14#include "libm.h"
15
16#if (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
17#if LDBL_MANT_DIG == 64
18/*
19 * ld80 version of __tan.c. See __tan.c for most comments.
20 */
21/*
22 * Domain [-0.67434, 0.67434], range ~[-2.25e-22, 1.921e-22]
23 * |tan(x)/x - t(x)| < 2**-71.9
24 *
25 * See __cosl.c for more details about the polynomial.
26 */
27static const long double
28T3 = 0.333333333333333333180L, /* 0xaaaaaaaaaaaaaaa5.0p-65 */
29T5 = 0.133333333333333372290L, /* 0x88888888888893c3.0p-66 */
30T7 = 0.0539682539682504975744L, /* 0xdd0dd0dd0dc13ba2.0p-68 */
31pio4 = 0.785398163397448309628L, /* 0xc90fdaa22168c235.0p-64 */
32pio4lo = -1.25413940316708300586e-20L; /* -0xece675d1fc8f8cbb.0p-130 */
33static const double
34T9 = 0.021869488536312216, /* 0x1664f4882cc1c2.0p-58 */
35T11 = 0.0088632355256619590, /* 0x1226e355c17612.0p-59 */
36T13 = 0.0035921281113786528, /* 0x1d6d3d185d7ff8.0p-61 */
37T15 = 0.0014558334756312418, /* 0x17da354aa3f96b.0p-62 */
38T17 = 0.00059003538700862256, /* 0x13559358685b83.0p-63 */
39T19 = 0.00023907843576635544, /* 0x1f56242026b5be.0p-65 */
40T21 = 0.000097154625656538905, /* 0x1977efc26806f4.0p-66 */
41T23 = 0.000038440165747303162, /* 0x14275a09b3ceac.0p-67 */
42T25 = 0.000018082171885432524, /* 0x12f5e563e5487e.0p-68 */
43T27 = 0.0000024196006108814377, /* 0x144c0d80cc6896.0p-71 */
44T29 = 0.0000078293456938132840, /* 0x106b59141a6cb3.0p-69 */
45T31 = -0.0000032609076735050182, /* -0x1b5abef3ba4b59.0p-71 */
46T33 = 0.0000023261313142559411; /* 0x13835436c0c87f.0p-71 */
47#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
48 w * (T25 + w * (T29 + w * T33)))))))
49#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
50 w * (T27 + w * T31))))))
51#elif LDBL_MANT_DIG == 113
52/*
53 * ld128 version of __tan.c. See __tan.c for most comments.
54 */
55/*
56 * Domain [-0.67434, 0.67434], range ~[-3.37e-36, 1.982e-37]
57 * |tan(x)/x - t(x)| < 2**-117.8 (XXX should be ~1e-37)
58 *
59 * See __cosl.c for more details about the polynomial.
60 */
61static const long double
62T3 = 0x1.5555555555555555555555555553p-2L,
63T5 = 0x1.1111111111111111111111111eb5p-3L,
64T7 = 0x1.ba1ba1ba1ba1ba1ba1ba1b694cd6p-5L,
65T9 = 0x1.664f4882c10f9f32d6bbe09d8bcdp-6L,
66T11 = 0x1.226e355e6c23c8f5b4f5762322eep-7L,
67T13 = 0x1.d6d3d0e157ddfb5fed8e84e27b37p-9L,
68T15 = 0x1.7da36452b75e2b5fce9ee7c2c92ep-10L,
69T17 = 0x1.355824803674477dfcf726649efep-11L,
70T19 = 0x1.f57d7734d1656e0aceb716f614c2p-13L,
71T21 = 0x1.967e18afcb180ed942dfdc518d6cp-14L,
72T23 = 0x1.497d8eea21e95bc7e2aa79b9f2cdp-15L,
73T25 = 0x1.0b132d39f055c81be49eff7afd50p-16L,
74T27 = 0x1.b0f72d33eff7bfa2fbc1059d90b6p-18L,
75T29 = 0x1.5ef2daf21d1113df38d0fbc00267p-19L,
76T31 = 0x1.1c77d6eac0234988cdaa04c96626p-20L,
77T33 = 0x1.cd2a5a292b180e0bdd701057dfe3p-22L,
78T35 = 0x1.75c7357d0298c01a31d0a6f7d518p-23L,
79T37 = 0x1.2f3190f4718a9a520f98f50081fcp-24L,
80pio4 = 0x1.921fb54442d18469898cc51701b8p-1L,
81pio4lo = 0x1.cd129024e088a67cc74020bbea60p-116L;
82static const double
83T39 = 0.000000028443389121318352, /* 0x1e8a7592977938.0p-78 */
84T41 = 0.000000011981013102001973, /* 0x19baa1b1223219.0p-79 */
85T43 = 0.0000000038303578044958070, /* 0x107385dfb24529.0p-80 */
86T45 = 0.0000000034664378216909893, /* 0x1dc6c702a05262.0p-81 */
87T47 = -0.0000000015090641701997785, /* -0x19ecef3569ebb6.0p-82 */
88T49 = 0.0000000029449552300483952, /* 0x194c0668da786a.0p-81 */
89T51 = -0.0000000022006995706097711, /* -0x12e763b8845268.0p-81 */
90T53 = 0.0000000015468200913196612, /* 0x1a92fc98c29554.0p-82 */
91T55 = -0.00000000061311613386849674, /* -0x151106cbc779a9.0p-83 */
92T57 = 1.4912469681508012e-10; /* 0x147edbdba6f43a.0p-85 */
93#define RPOLY(w) (T5 + w * (T9 + w * (T13 + w * (T17 + w * (T21 + \
94 w * (T25 + w * (T29 + w * (T33 + w * (T37 + w * (T41 + \
95 w * (T45 + w * (T49 + w * (T53 + w * T57)))))))))))))
96#define VPOLY(w) (T7 + w * (T11 + w * (T15 + w * (T19 + w * (T23 + \
97 w * (T27 + w * (T31 + w * (T35 + w * (T39 + w * (T43 + \
98 w * (T47 + w * (T51 + w * T55))))))))))))
99#endif
100
101long double __tanl(long double x, long double y, int odd) {
102 long double z, r, v, w, s, a, t;
103 int big, sign;
104
105 big = fabsl(x) >= 0.67434;
106 if (big) {
107 sign = 0;
108 if (x < 0) {
109 sign = 1;
110 x = -x;
111 y = -y;
112 }
113 x = (pio4 - x) + (pio4lo - y);
114 y = 0.0;
115 }
116 z = x * x;
117 w = z * z;
118 r = RPOLY(w);
119 v = z * VPOLY(w);
120 s = z * x;
121 r = y + z * (s * (r + v) + y) + T3 * s;
122 w = x + r;
123 if (big) {
124 s = 1 - 2*odd;
125 v = s - 2.0 * (x + (r - w * w / (w + s)));
126 return sign ? -v : v;
127 }
128 if (!odd)
129 return w;
130 /*
131 * if allow error up to 2 ulp, simply return
132 * -1.0 / (x+r) here
133 */
134 /* compute -1.0 / (x+r) accurately */
135 z = w;
136 z = z + 0x1p32 - 0x1p32;
137 v = r - (z - x); /* z+v = r+x */
138 t = a = -1.0 / w; /* a = -1.0/w */
139 t = t + 0x1p32 - 0x1p32;
140 s = 1.0 + t * z;
141 return t + a * (s + t * v);
142}
143#endif
libc/musl/src/math/aarch64/ceil.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double ceil(double x)
4{
5 __asm__ ("frintp %d0, %d1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/ceilf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float ceilf(float x)
4{
5 __asm__ ("frintp %s0, %s1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/fabs.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double fabs(double x)
4{
5 __asm__ ("fabs %d0, %d1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/fabsf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float fabsf(float x)
4{
5 __asm__ ("fabs %s0, %s1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/floor.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double floor(double x)
4{
5 __asm__ ("frintm %d0, %d1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/floorf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float floorf(float x)
4{
5 __asm__ ("frintm %s0, %s1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/fma.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double fma(double x, double y, double z)
4{
5 __asm__ ("fmadd %d0, %d1, %d2, %d3" : "=w"(x) : "w"(x), "w"(y), "w"(z));
6 return x;
7}
libc/musl/src/math/aarch64/fmaf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float fmaf(float x, float y, float z)
4{
5 __asm__ ("fmadd %s0, %s1, %s2, %s3" : "=w"(x) : "w"(x), "w"(y), "w"(z));
6 return x;
7}
libc/musl/src/math/aarch64/fmax.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double fmax(double x, double y)
4{
5 __asm__ ("fmaxnm %d0, %d1, %d2" : "=w"(x) : "w"(x), "w"(y));
6 return x;
7}
libc/musl/src/math/aarch64/fmaxf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float fmaxf(float x, float y)
4{
5 __asm__ ("fmaxnm %s0, %s1, %s2" : "=w"(x) : "w"(x), "w"(y));
6 return x;
7}
libc/musl/src/math/aarch64/fmin.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double fmin(double x, double y)
4{
5 __asm__ ("fminnm %d0, %d1, %d2" : "=w"(x) : "w"(x), "w"(y));
6 return x;
7}
libc/musl/src/math/aarch64/fminf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float fminf(float x, float y)
4{
5 __asm__ ("fminnm %s0, %s1, %s2" : "=w"(x) : "w"(x), "w"(y));
6 return x;
7}
libc/musl/src/math/aarch64/llrint.c created+10
......@@ -0,0 +1,10 @@
1#include <math.h>
2
3long long llrint(double x)
4{
5 long long n;
6 __asm__ (
7 "frintx %d1, %d1\n"
8 "fcvtzs %x0, %d1\n" : "=r"(n), "+w"(x));
9 return n;
10}
libc/musl/src/math/aarch64/llrintf.c created+10
......@@ -0,0 +1,10 @@
1#include <math.h>
2
3long long llrintf(float x)
4{
5 long long n;
6 __asm__ (
7 "frintx %s1, %s1\n"
8 "fcvtzs %x0, %s1\n" : "=r"(n), "+w"(x));
9 return n;
10}
libc/musl/src/math/aarch64/llround.c created+8
......@@ -0,0 +1,8 @@
1#include <math.h>
2
3long long llround(double x)
4{
5 long long n;
6 __asm__ ("fcvtas %x0, %d1" : "=r"(n) : "w"(x));
7 return n;
8}
libc/musl/src/math/aarch64/llroundf.c created+8
......@@ -0,0 +1,8 @@
1#include <math.h>
2
3long long llroundf(float x)
4{
5 long long n;
6 __asm__ ("fcvtas %x0, %s1" : "=r"(n) : "w"(x));
7 return n;
8}
libc/musl/src/math/aarch64/lrint.c created+10
......@@ -0,0 +1,10 @@
1#include <math.h>
2
3long lrint(double x)
4{
5 long n;
6 __asm__ (
7 "frintx %d1, %d1\n"
8 "fcvtzs %x0, %d1\n" : "=r"(n), "+w"(x));
9 return n;
10}
libc/musl/src/math/aarch64/lrintf.c created+10
......@@ -0,0 +1,10 @@
1#include <math.h>
2
3long lrintf(float x)
4{
5 long n;
6 __asm__ (
7 "frintx %s1, %s1\n"
8 "fcvtzs %x0, %s1\n" : "=r"(n), "+w"(x));
9 return n;
10}
libc/musl/src/math/aarch64/lround.c created+8
......@@ -0,0 +1,8 @@
1#include <math.h>
2
3long lround(double x)
4{
5 long n;
6 __asm__ ("fcvtas %x0, %d1" : "=r"(n) : "w"(x));
7 return n;
8}
libc/musl/src/math/aarch64/lroundf.c created+8
......@@ -0,0 +1,8 @@
1#include <math.h>
2
3long lroundf(float x)
4{
5 long n;
6 __asm__ ("fcvtas %x0, %s1" : "=r"(n) : "w"(x));
7 return n;
8}
libc/musl/src/math/aarch64/nearbyint.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double nearbyint(double x)
4{
5 __asm__ ("frinti %d0, %d1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/nearbyintf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float nearbyintf(float x)
4{
5 __asm__ ("frinti %s0, %s1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/rint.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double rint(double x)
4{
5 __asm__ ("frintx %d0, %d1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/rintf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float rintf(float x)
4{
5 __asm__ ("frintx %s0, %s1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/round.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double round(double x)
4{
5 __asm__ ("frinta %d0, %d1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/roundf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float roundf(float x)
4{
5 __asm__ ("frinta %s0, %s1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/sqrt.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double sqrt(double x)
4{
5 __asm__ ("fsqrt %d0, %d1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/sqrtf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float sqrtf(float x)
4{
5 __asm__ ("fsqrt %s0, %s1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/trunc.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double trunc(double x)
4{
5 __asm__ ("frintz %d0, %d1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/aarch64/truncf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float truncf(float x)
4{
5 __asm__ ("frintz %s0, %s1" : "=w"(x) : "w"(x));
6 return x;
7}
libc/musl/src/math/acos.c created+101
......@@ -0,0 +1,101 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_acos.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* acos(x)
13 * Method :
14 * acos(x) = pi/2 - asin(x)
15 * acos(-x) = pi/2 + asin(x)
16 * For |x|<=0.5
17 * acos(x) = pi/2 - (x + x*x^2*R(x^2)) (see asin.c)
18 * For x>0.5
19 * acos(x) = pi/2 - (pi/2 - 2asin(sqrt((1-x)/2)))
20 * = 2asin(sqrt((1-x)/2))
21 * = 2s + 2s*z*R(z) ...z=(1-x)/2, s=sqrt(z)
22 * = 2f + (2c + 2s*z*R(z))
23 * where f=hi part of s, and c = (z-f*f)/(s+f) is the correction term
24 * for f so that f+c ~ sqrt(z).
25 * For x<-0.5
26 * acos(x) = pi - 2asin(sqrt((1-|x|)/2))
27 * = pi - 0.5*(s+s*z*R(z)), where z=(1-|x|)/2,s=sqrt(z)
28 *
29 * Special cases:
30 * if x is NaN, return x itself;
31 * if |x|>1, return NaN with invalid signal.
32 *
33 * Function needed: sqrt
34 */
35
36#include "libm.h"
37
38static const double
39pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
40pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
41pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
42pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
43pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
44pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
45pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
46pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
47qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
48qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
49qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
50qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
51
52static double R(double z)
53{
54 double_t p, q;
55 p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
56 q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
57 return p/q;
58}
59
60double acos(double x)
61{
62 double z,w,s,c,df;
63 uint32_t hx,ix;
64
65 GET_HIGH_WORD(hx, x);
66 ix = hx & 0x7fffffff;
67 /* |x| >= 1 or nan */
68 if (ix >= 0x3ff00000) {
69 uint32_t lx;
70
71 GET_LOW_WORD(lx,x);
72 if ((ix-0x3ff00000 | lx) == 0) {
73 /* acos(1)=0, acos(-1)=pi */
74 if (hx >> 31)
75 return 2*pio2_hi + 0x1p-120f;
76 return 0;
77 }
78 return 0/(x-x);
79 }
80 /* |x| < 0.5 */
81 if (ix < 0x3fe00000) {
82 if (ix <= 0x3c600000) /* |x| < 2**-57 */
83 return pio2_hi + 0x1p-120f;
84 return pio2_hi - (x - (pio2_lo-x*R(x*x)));
85 }
86 /* x < -0.5 */
87 if (hx >> 31) {
88 z = (1.0+x)*0.5;
89 s = sqrt(z);
90 w = R(z)*s-pio2_lo;
91 return 2*(pio2_hi - (s+w));
92 }
93 /* x > 0.5 */
94 z = (1.0-x)*0.5;
95 s = sqrt(z);
96 df = s;
97 SET_LOW_WORD(df,0);
98 c = (z-df*df)/(s+df);
99 w = R(z)*s+c;
100 return 2*(df+w);
101}
libc/musl/src/math/acosf.c created+71
......@@ -0,0 +1,71 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_acosf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include "libm.h"
17
18static const float
19pio2_hi = 1.5707962513e+00, /* 0x3fc90fda */
20pio2_lo = 7.5497894159e-08, /* 0x33a22168 */
21pS0 = 1.6666586697e-01,
22pS1 = -4.2743422091e-02,
23pS2 = -8.6563630030e-03,
24qS1 = -7.0662963390e-01;
25
26static float R(float z)
27{
28 float_t p, q;
29 p = z*(pS0+z*(pS1+z*pS2));
30 q = 1.0f+z*qS1;
31 return p/q;
32}
33
34float acosf(float x)
35{
36 float z,w,s,c,df;
37 uint32_t hx,ix;
38
39 GET_FLOAT_WORD(hx, x);
40 ix = hx & 0x7fffffff;
41 /* |x| >= 1 or nan */
42 if (ix >= 0x3f800000) {
43 if (ix == 0x3f800000) {
44 if (hx >> 31)
45 return 2*pio2_hi + 0x1p-120f;
46 return 0;
47 }
48 return 0/(x-x);
49 }
50 /* |x| < 0.5 */
51 if (ix < 0x3f000000) {
52 if (ix <= 0x32800000) /* |x| < 2**-26 */
53 return pio2_hi + 0x1p-120f;
54 return pio2_hi - (x - (pio2_lo-x*R(x*x)));
55 }
56 /* x < -0.5 */
57 if (hx >> 31) {
58 z = (1+x)*0.5f;
59 s = sqrtf(z);
60 w = R(z)*s-pio2_lo;
61 return 2*(pio2_hi - (s+w));
62 }
63 /* x > 0.5 */
64 z = (1-x)*0.5f;
65 s = sqrtf(z);
66 GET_FLOAT_WORD(hx,s);
67 SET_FLOAT_WORD(df,hx&0xfffff000);
68 c = (z-df*df)/(s+df);
69 w = R(z)*s+c;
70 return 2*(df+w);
71}
libc/musl/src/math/acosh.c created+24
......@@ -0,0 +1,24 @@
1#include "libm.h"
2
3#if FLT_EVAL_METHOD==2
4#undef sqrt
5#define sqrt sqrtl
6#endif
7
8/* acosh(x) = log(x + sqrt(x*x-1)) */
9double acosh(double x)
10{
11 union {double f; uint64_t i;} u = {.f = x};
12 unsigned e = u.i >> 52 & 0x7ff;
13
14 /* x < 1 domain error is handled in the called functions */
15
16 if (e < 0x3ff + 1)
17 /* |x| < 2, up to 2ulp error in [1,1.125] */
18 return log1p(x-1 + sqrt((x-1)*(x-1)+2*(x-1)));
19 if (e < 0x3ff + 26)
20 /* |x| < 0x1p26 */
21 return log(2*x - 1/(x+sqrt(x*x-1)));
22 /* |x| >= 0x1p26 or nan */
23 return log(x) + 0.693147180559945309417232121458176568;
24}
libc/musl/src/math/acoshf.c created+26
......@@ -0,0 +1,26 @@
1#include "libm.h"
2
3#if FLT_EVAL_METHOD==2
4#undef sqrtf
5#define sqrtf sqrtl
6#elif FLT_EVAL_METHOD==1
7#undef sqrtf
8#define sqrtf sqrt
9#endif
10
11/* acosh(x) = log(x + sqrt(x*x-1)) */
12float acoshf(float x)
13{
14 union {float f; uint32_t i;} u = {x};
15 uint32_t a = u.i & 0x7fffffff;
16
17 if (a < 0x3f800000+(1<<23))
18 /* |x| < 2, invalid if x < 1 or nan */
19 /* up to 2ulp error in [1,1.125] */
20 return log1pf(x-1 + sqrtf((x-1)*(x-1)+2*(x-1)));
21 if (a < 0x3f800000+(12<<23))
22 /* |x| < 0x1p12 */
23 return logf(2*x - 1/(x+sqrtf(x*x-1)));
24 /* x >= 0x1p12 */
25 return logf(x) + 0.693147180559945309417232121458176568f;
26}
libc/musl/src/math/acoshl.c created+29
......@@ -0,0 +1,29 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double acoshl(long double x)
5{
6 return acosh(x);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9/* acosh(x) = log(x + sqrt(x*x-1)) */
10long double acoshl(long double x)
11{
12 union ldshape u = {x};
13 int e = u.i.se & 0x7fff;
14
15 if (e < 0x3fff + 1)
16 /* |x| < 2, invalid if x < 1 or nan */
17 return log1pl(x-1 + sqrtl((x-1)*(x-1)+2*(x-1)));
18 if (e < 0x3fff + 32)
19 /* |x| < 0x1p32 */
20 return logl(2*x - 1/(x+sqrtl(x*x-1)));
21 return logl(x) + 0.693147180559945309417232121458176568L;
22}
23#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
24// TODO: broken implementation to make things compile
25long double acoshl(long double x)
26{
27 return acosh(x);
28}
29#endif
libc/musl/src/math/acosl.c created+67
......@@ -0,0 +1,67 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_acosl.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * See comments in acos.c.
14 * Converted to long double by David Schultz <das@FreeBSD.ORG>.
15 */
16
17#include "libm.h"
18
19#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
20long double acosl(long double x)
21{
22 return acos(x);
23}
24#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
25#include "__invtrigl.h"
26#if LDBL_MANT_DIG == 64
27#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
28#elif LDBL_MANT_DIG == 113
29#define CLEARBOTTOM(u) (u.i.lo = 0)
30#endif
31
32long double acosl(long double x)
33{
34 union ldshape u = {x};
35 long double z, s, c, f;
36 uint16_t e = u.i.se & 0x7fff;
37
38 /* |x| >= 1 or nan */
39 if (e >= 0x3fff) {
40 if (x == 1)
41 return 0;
42 if (x == -1)
43 return 2*pio2_hi + 0x1p-120f;
44 return 0/(x-x);
45 }
46 /* |x| < 0.5 */
47 if (e < 0x3fff - 1) {
48 if (e < 0x3fff - LDBL_MANT_DIG - 1)
49 return pio2_hi + 0x1p-120f;
50 return pio2_hi - (__invtrigl_R(x*x)*x - pio2_lo + x);
51 }
52 /* x < -0.5 */
53 if (u.i.se >> 15) {
54 z = (1 + x)*0.5;
55 s = sqrtl(z);
56 return 2*(pio2_hi - (__invtrigl_R(z)*s - pio2_lo + s));
57 }
58 /* x > 0.5 */
59 z = (1 - x)*0.5;
60 s = sqrtl(z);
61 u.f = s;
62 CLEARBOTTOM(u);
63 f = u.f;
64 c = (z - f*f)/(s + f);
65 return 2*(__invtrigl_R(z)*s + c + f);
66}
67#endif
libc/musl/src/math/arm/fabs.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if __ARM_PCS_VFP
4
5double fabs(double x)
6{
7 __asm__ ("vabs.f64 %P0, %P1" : "=w"(x) : "w"(x));
8 return x;
9}
10
11#else
12
13#include "../fabs.c"
14
15#endif
libc/musl/src/math/arm/fabsf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if __ARM_PCS_VFP && !BROKEN_VFP_ASM
4
5float fabsf(float x)
6{
7 __asm__ ("vabs.f32 %0, %1" : "=t"(x) : "t"(x));
8 return x;
9}
10
11#else
12
13#include "../fabsf.c"
14
15#endif
libc/musl/src/math/arm/fma.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if __ARM_FEATURE_FMA && __ARM_FP&8 && !__SOFTFP__
4
5double fma(double x, double y, double z)
6{
7 __asm__ ("vfma.f64 %P0, %P1, %P2" : "+w"(z) : "w"(x), "w"(y));
8 return z;
9}
10
11#else
12
13#include "../fma.c"
14
15#endif
libc/musl/src/math/arm/fmaf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if __ARM_FEATURE_FMA && __ARM_FP&4 && !__SOFTFP__ && !BROKEN_VFP_ASM
4
5float fmaf(float x, float y, float z)
6{
7 __asm__ ("vfma.f32 %0, %1, %2" : "+t"(z) : "t"(x), "t"(y));
8 return z;
9}
10
11#else
12
13#include "../fmaf.c"
14
15#endif
libc/musl/src/math/arm/sqrt.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if __ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)
4
5double sqrt(double x)
6{
7 __asm__ ("vsqrt.f64 %P0, %P1" : "=w"(x) : "w"(x));
8 return x;
9}
10
11#else
12
13#include "../sqrt.c"
14
15#endif
libc/musl/src/math/arm/sqrtf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if (__ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)) && !BROKEN_VFP_ASM
4
5float sqrtf(float x)
6{
7 __asm__ ("vsqrt.f32 %0, %1" : "=t"(x) : "t"(x));
8 return x;
9}
10
11#else
12
13#include "../sqrtf.c"
14
15#endif
libc/musl/src/math/asin.c created+107
......@@ -0,0 +1,107 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_asin.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* asin(x)
13 * Method :
14 * Since asin(x) = x + x^3/6 + x^5*3/40 + x^7*15/336 + ...
15 * we approximate asin(x) on [0,0.5] by
16 * asin(x) = x + x*x^2*R(x^2)
17 * where
18 * R(x^2) is a rational approximation of (asin(x)-x)/x^3
19 * and its remez error is bounded by
20 * |(asin(x)-x)/x^3 - R(x^2)| < 2^(-58.75)
21 *
22 * For x in [0.5,1]
23 * asin(x) = pi/2-2*asin(sqrt((1-x)/2))
24 * Let y = (1-x), z = y/2, s := sqrt(z), and pio2_hi+pio2_lo=pi/2;
25 * then for x>0.98
26 * asin(x) = pi/2 - 2*(s+s*z*R(z))
27 * = pio2_hi - (2*(s+s*z*R(z)) - pio2_lo)
28 * For x<=0.98, let pio4_hi = pio2_hi/2, then
29 * f = hi part of s;
30 * c = sqrt(z) - f = (z-f*f)/(s+f) ...f+c=sqrt(z)
31 * and
32 * asin(x) = pi/2 - 2*(s+s*z*R(z))
33 * = pio4_hi+(pio4-2s)-(2s*z*R(z)-pio2_lo)
34 * = pio4_hi+(pio4-2f)-(2s*z*R(z)-(pio2_lo+2c))
35 *
36 * Special cases:
37 * if x is NaN, return x itself;
38 * if |x|>1, return NaN with invalid signal.
39 *
40 */
41
42#include "libm.h"
43
44static const double
45pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */
46pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */
47/* coefficients for R(x^2) */
48pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */
49pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */
50pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */
51pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */
52pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */
53pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */
54qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */
55qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */
56qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */
57qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */
58
59static double R(double z)
60{
61 double_t p, q;
62 p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
63 q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
64 return p/q;
65}
66
67double asin(double x)
68{
69 double z,r,s;
70 uint32_t hx,ix;
71
72 GET_HIGH_WORD(hx, x);
73 ix = hx & 0x7fffffff;
74 /* |x| >= 1 or nan */
75 if (ix >= 0x3ff00000) {
76 uint32_t lx;
77 GET_LOW_WORD(lx, x);
78 if ((ix-0x3ff00000 | lx) == 0)
79 /* asin(1) = +-pi/2 with inexact */
80 return x*pio2_hi + 0x1p-120f;
81 return 0/(x-x);
82 }
83 /* |x| < 0.5 */
84 if (ix < 0x3fe00000) {
85 /* if 0x1p-1022 <= |x| < 0x1p-26, avoid raising underflow */
86 if (ix < 0x3e500000 && ix >= 0x00100000)
87 return x;
88 return x + x*R(x*x);
89 }
90 /* 1 > |x| >= 0.5 */
91 z = (1 - fabs(x))*0.5;
92 s = sqrt(z);
93 r = R(z);
94 if (ix >= 0x3fef3333) { /* if |x| > 0.975 */
95 x = pio2_hi-(2*(s+s*r)-pio2_lo);
96 } else {
97 double f,c;
98 /* f+c = sqrt(z) */
99 f = s;
100 SET_LOW_WORD(f,0);
101 c = (z-f*f)/(s+f);
102 x = 0.5*pio2_hi - (2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
103 }
104 if (hx >> 31)
105 return -x;
106 return x;
107}
libc/musl/src/math/asinf.c created+61
......@@ -0,0 +1,61 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_asinf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15#include "libm.h"
16
17static const double
18pio2 = 1.570796326794896558e+00;
19
20static const float
21/* coefficients for R(x^2) */
22pS0 = 1.6666586697e-01,
23pS1 = -4.2743422091e-02,
24pS2 = -8.6563630030e-03,
25qS1 = -7.0662963390e-01;
26
27static float R(float z)
28{
29 float_t p, q;
30 p = z*(pS0+z*(pS1+z*pS2));
31 q = 1.0f+z*qS1;
32 return p/q;
33}
34
35float asinf(float x)
36{
37 double s;
38 float z;
39 uint32_t hx,ix;
40
41 GET_FLOAT_WORD(hx, x);
42 ix = hx & 0x7fffffff;
43 if (ix >= 0x3f800000) { /* |x| >= 1 */
44 if (ix == 0x3f800000) /* |x| == 1 */
45 return x*pio2 + 0x1p-120f; /* asin(+-1) = +-pi/2 with inexact */
46 return 0/(x-x); /* asin(|x|>1) is NaN */
47 }
48 if (ix < 0x3f000000) { /* |x| < 0.5 */
49 /* if 0x1p-126 <= |x| < 0x1p-12, avoid raising underflow */
50 if (ix < 0x39800000 && ix >= 0x00800000)
51 return x;
52 return x + x*R(x*x);
53 }
54 /* 1 > |x| >= 0.5 */
55 z = (1 - fabsf(x))*0.5f;
56 s = sqrt(z);
57 x = pio2 - 2*(s+s*R(z));
58 if (hx >> 31)
59 return -x;
60 return x;
61}
libc/musl/src/math/asinh.c created+28
......@@ -0,0 +1,28 @@
1#include "libm.h"
2
3/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
4double asinh(double x)
5{
6 union {double f; uint64_t i;} u = {.f = x};
7 unsigned e = u.i >> 52 & 0x7ff;
8 unsigned s = u.i >> 63;
9
10 /* |x| */
11 u.i &= (uint64_t)-1/2;
12 x = u.f;
13
14 if (e >= 0x3ff + 26) {
15 /* |x| >= 0x1p26 or inf or nan */
16 x = log(x) + 0.693147180559945309417232121458176568;
17 } else if (e >= 0x3ff + 1) {
18 /* |x| >= 2 */
19 x = log(2*x + 1/(sqrt(x*x+1)+x));
20 } else if (e >= 0x3ff - 26) {
21 /* |x| >= 0x1p-26, up to 1.6ulp error in [0.125,0.5] */
22 x = log1p(x + x*x/(sqrt(x*x+1)+1));
23 } else {
24 /* |x| < 0x1p-26, raise inexact if x != 0 */
25 FORCE_EVAL(x + 0x1p120f);
26 }
27 return s ? -x : x;
28}
libc/musl/src/math/asinhf.c created+28
......@@ -0,0 +1,28 @@
1#include "libm.h"
2
3/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
4float asinhf(float x)
5{
6 union {float f; uint32_t i;} u = {.f = x};
7 uint32_t i = u.i & 0x7fffffff;
8 unsigned s = u.i >> 31;
9
10 /* |x| */
11 u.i = i;
12 x = u.f;
13
14 if (i >= 0x3f800000 + (12<<23)) {
15 /* |x| >= 0x1p12 or inf or nan */
16 x = logf(x) + 0.693147180559945309417232121458176568f;
17 } else if (i >= 0x3f800000 + (1<<23)) {
18 /* |x| >= 2 */
19 x = logf(2*x + 1/(sqrtf(x*x+1)+x));
20 } else if (i >= 0x3f800000 - (12<<23)) {
21 /* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */
22 x = log1pf(x + x*x/(sqrtf(x*x+1)+1));
23 } else {
24 /* |x| < 0x1p-12, raise inexact if x!=0 */
25 FORCE_EVAL(x + 0x1p120f);
26 }
27 return s ? -x : x;
28}
libc/musl/src/math/asinhl.c created+41
......@@ -0,0 +1,41 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double asinhl(long double x)
5{
6 return asinh(x);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
10long double asinhl(long double x)
11{
12 union ldshape u = {x};
13 unsigned e = u.i.se & 0x7fff;
14 unsigned s = u.i.se >> 15;
15
16 /* |x| */
17 u.i.se = e;
18 x = u.f;
19
20 if (e >= 0x3fff + 32) {
21 /* |x| >= 0x1p32 or inf or nan */
22 x = logl(x) + 0.693147180559945309417232121458176568L;
23 } else if (e >= 0x3fff + 1) {
24 /* |x| >= 2 */
25 x = logl(2*x + 1/(sqrtl(x*x+1)+x));
26 } else if (e >= 0x3fff - 32) {
27 /* |x| >= 0x1p-32 */
28 x = log1pl(x + x*x/(sqrtl(x*x+1)+1));
29 } else {
30 /* |x| < 0x1p-32, raise inexact if x!=0 */
31 FORCE_EVAL(x + 0x1p120f);
32 }
33 return s ? -x : x;
34}
35#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
36// TODO: broken implementation to make things compile
37long double asinhl(long double x)
38{
39 return asinh(x);
40}
41#endif
libc/musl/src/math/asinl.c created+71
......@@ -0,0 +1,71 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_asinl.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * See comments in asin.c.
14 * Converted to long double by David Schultz <das@FreeBSD.ORG>.
15 */
16
17#include "libm.h"
18
19#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
20long double asinl(long double x)
21{
22 return asin(x);
23}
24#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
25#include "__invtrigl.h"
26#if LDBL_MANT_DIG == 64
27#define CLOSETO1(u) (u.i.m>>56 >= 0xf7)
28#define CLEARBOTTOM(u) (u.i.m &= -1ULL << 32)
29#elif LDBL_MANT_DIG == 113
30#define CLOSETO1(u) (u.i.top >= 0xee00)
31#define CLEARBOTTOM(u) (u.i.lo = 0)
32#endif
33
34long double asinl(long double x)
35{
36 union ldshape u = {x};
37 long double z, r, s;
38 uint16_t e = u.i.se & 0x7fff;
39 int sign = u.i.se >> 15;
40
41 if (e >= 0x3fff) { /* |x| >= 1 or nan */
42 /* asin(+-1)=+-pi/2 with inexact */
43 if (x == 1 || x == -1)
44 return x*pio2_hi + 0x1p-120f;
45 return 0/(x-x);
46 }
47 if (e < 0x3fff - 1) { /* |x| < 0.5 */
48 if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {
49 /* return x with inexact if x!=0 */
50 FORCE_EVAL(x + 0x1p120f);
51 return x;
52 }
53 return x + x*__invtrigl_R(x*x);
54 }
55 /* 1 > |x| >= 0.5 */
56 z = (1.0 - fabsl(x))*0.5;
57 s = sqrtl(z);
58 r = __invtrigl_R(z);
59 if (CLOSETO1(u)) {
60 x = pio2_hi - (2*(s+s*r)-pio2_lo);
61 } else {
62 long double f, c;
63 u.f = s;
64 CLEARBOTTOM(u);
65 f = u.f;
66 c = (z - f*f)/(s + f);
67 x = 0.5*pio2_hi-(2*s*r - (pio2_lo-2*c) - (0.5*pio2_hi-2*f));
68 }
69 return sign ? -x : x;
70}
71#endif
libc/musl/src/math/atan.c created+116
......@@ -0,0 +1,116 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_atan.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* atan(x)
13 * Method
14 * 1. Reduce x to positive by atan(x) = -atan(-x).
15 * 2. According to the integer k=4t+0.25 chopped, t=x, the argument
16 * is further reduced to one of the following intervals and the
17 * arctangent of t is evaluated by the corresponding formula:
18 *
19 * [0,7/16] atan(x) = t-t^3*(a1+t^2*(a2+...(a10+t^2*a11)...)
20 * [7/16,11/16] atan(x) = atan(1/2) + atan( (t-0.5)/(1+t/2) )
21 * [11/16.19/16] atan(x) = atan( 1 ) + atan( (t-1)/(1+t) )
22 * [19/16,39/16] atan(x) = atan(3/2) + atan( (t-1.5)/(1+1.5t) )
23 * [39/16,INF] atan(x) = atan(INF) + atan( -1/t )
24 *
25 * Constants:
26 * The hexadecimal values are the intended ones for the following
27 * constants. The decimal values may be used, provided that the
28 * compiler will convert from decimal to binary accurately enough
29 * to produce the hexadecimal values shown.
30 */
31
32
33#include "libm.h"
34
35static const double atanhi[] = {
36 4.63647609000806093515e-01, /* atan(0.5)hi 0x3FDDAC67, 0x0561BB4F */
37 7.85398163397448278999e-01, /* atan(1.0)hi 0x3FE921FB, 0x54442D18 */
38 9.82793723247329054082e-01, /* atan(1.5)hi 0x3FEF730B, 0xD281F69B */
39 1.57079632679489655800e+00, /* atan(inf)hi 0x3FF921FB, 0x54442D18 */
40};
41
42static const double atanlo[] = {
43 2.26987774529616870924e-17, /* atan(0.5)lo 0x3C7A2B7F, 0x222F65E2 */
44 3.06161699786838301793e-17, /* atan(1.0)lo 0x3C81A626, 0x33145C07 */
45 1.39033110312309984516e-17, /* atan(1.5)lo 0x3C700788, 0x7AF0CBBD */
46 6.12323399573676603587e-17, /* atan(inf)lo 0x3C91A626, 0x33145C07 */
47};
48
49static const double aT[] = {
50 3.33333333333329318027e-01, /* 0x3FD55555, 0x5555550D */
51 -1.99999999998764832476e-01, /* 0xBFC99999, 0x9998EBC4 */
52 1.42857142725034663711e-01, /* 0x3FC24924, 0x920083FF */
53 -1.11111104054623557880e-01, /* 0xBFBC71C6, 0xFE231671 */
54 9.09088713343650656196e-02, /* 0x3FB745CD, 0xC54C206E */
55 -7.69187620504482999495e-02, /* 0xBFB3B0F2, 0xAF749A6D */
56 6.66107313738753120669e-02, /* 0x3FB10D66, 0xA0D03D51 */
57 -5.83357013379057348645e-02, /* 0xBFADDE2D, 0x52DEFD9A */
58 4.97687799461593236017e-02, /* 0x3FA97B4B, 0x24760DEB */
59 -3.65315727442169155270e-02, /* 0xBFA2B444, 0x2C6A6C2F */
60 1.62858201153657823623e-02, /* 0x3F90AD3A, 0xE322DA11 */
61};
62
63double atan(double x)
64{
65 double_t w,s1,s2,z;
66 uint32_t ix,sign;
67 int id;
68
69 GET_HIGH_WORD(ix, x);
70 sign = ix >> 31;
71 ix &= 0x7fffffff;
72 if (ix >= 0x44100000) { /* if |x| >= 2^66 */
73 if (isnan(x))
74 return x;
75 z = atanhi[3] + 0x1p-120f;
76 return sign ? -z : z;
77 }
78 if (ix < 0x3fdc0000) { /* |x| < 0.4375 */
79 if (ix < 0x3e400000) { /* |x| < 2^-27 */
80 if (ix < 0x00100000)
81 /* raise underflow for subnormal x */
82 FORCE_EVAL((float)x);
83 return x;
84 }
85 id = -1;
86 } else {
87 x = fabs(x);
88 if (ix < 0x3ff30000) { /* |x| < 1.1875 */
89 if (ix < 0x3fe60000) { /* 7/16 <= |x| < 11/16 */
90 id = 0;
91 x = (2.0*x-1.0)/(2.0+x);
92 } else { /* 11/16 <= |x| < 19/16 */
93 id = 1;
94 x = (x-1.0)/(x+1.0);
95 }
96 } else {
97 if (ix < 0x40038000) { /* |x| < 2.4375 */
98 id = 2;
99 x = (x-1.5)/(1.0+1.5*x);
100 } else { /* 2.4375 <= |x| < 2^66 */
101 id = 3;
102 x = -1.0/x;
103 }
104 }
105 }
106 /* end of argument reduction */
107 z = x*x;
108 w = z*z;
109 /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
110 s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
111 s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
112 if (id < 0)
113 return x - x*(s1+s2);
114 z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x);
115 return sign ? -z : z;
116}
libc/musl/src/math/atan2.c created+107
......@@ -0,0 +1,107 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 *
12 */
13/* atan2(y,x)
14 * Method :
15 * 1. Reduce y to positive by atan2(y,x)=-atan2(-y,x).
16 * 2. Reduce x to positive by (if x and y are unexceptional):
17 * ARG (x+iy) = arctan(y/x) ... if x > 0,
18 * ARG (x+iy) = pi - arctan[y/(-x)] ... if x < 0,
19 *
20 * Special cases:
21 *
22 * ATAN2((anything), NaN ) is NaN;
23 * ATAN2(NAN , (anything) ) is NaN;
24 * ATAN2(+-0, +(anything but NaN)) is +-0 ;
25 * ATAN2(+-0, -(anything but NaN)) is +-pi ;
26 * ATAN2(+-(anything but 0 and NaN), 0) is +-pi/2;
27 * ATAN2(+-(anything but INF and NaN), +INF) is +-0 ;
28 * ATAN2(+-(anything but INF and NaN), -INF) is +-pi;
29 * ATAN2(+-INF,+INF ) is +-pi/4 ;
30 * ATAN2(+-INF,-INF ) is +-3pi/4;
31 * ATAN2(+-INF, (anything but,0,NaN, and INF)) is +-pi/2;
32 *
33 * Constants:
34 * The hexadecimal values are the intended ones for the following
35 * constants. The decimal values may be used, provided that the
36 * compiler will convert from decimal to binary accurately enough
37 * to produce the hexadecimal values shown.
38 */
39
40#include "libm.h"
41
42static const double
43pi = 3.1415926535897931160E+00, /* 0x400921FB, 0x54442D18 */
44pi_lo = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
45
46double atan2(double y, double x)
47{
48 double z;
49 uint32_t m,lx,ly,ix,iy;
50
51 if (isnan(x) || isnan(y))
52 return x+y;
53 EXTRACT_WORDS(ix, lx, x);
54 EXTRACT_WORDS(iy, ly, y);
55 if ((ix-0x3ff00000 | lx) == 0) /* x = 1.0 */
56 return atan(y);
57 m = ((iy>>31)&1) | ((ix>>30)&2); /* 2*sign(x)+sign(y) */
58 ix = ix & 0x7fffffff;
59 iy = iy & 0x7fffffff;
60
61 /* when y = 0 */
62 if ((iy|ly) == 0) {
63 switch(m) {
64 case 0:
65 case 1: return y; /* atan(+-0,+anything)=+-0 */
66 case 2: return pi; /* atan(+0,-anything) = pi */
67 case 3: return -pi; /* atan(-0,-anything) =-pi */
68 }
69 }
70 /* when x = 0 */
71 if ((ix|lx) == 0)
72 return m&1 ? -pi/2 : pi/2;
73 /* when x is INF */
74 if (ix == 0x7ff00000) {
75 if (iy == 0x7ff00000) {
76 switch(m) {
77 case 0: return pi/4; /* atan(+INF,+INF) */
78 case 1: return -pi/4; /* atan(-INF,+INF) */
79 case 2: return 3*pi/4; /* atan(+INF,-INF) */
80 case 3: return -3*pi/4; /* atan(-INF,-INF) */
81 }
82 } else {
83 switch(m) {
84 case 0: return 0.0; /* atan(+...,+INF) */
85 case 1: return -0.0; /* atan(-...,+INF) */
86 case 2: return pi; /* atan(+...,-INF) */
87 case 3: return -pi; /* atan(-...,-INF) */
88 }
89 }
90 }
91 /* |y/x| > 0x1p64 */
92 if (ix+(64<<20) < iy || iy == 0x7ff00000)
93 return m&1 ? -pi/2 : pi/2;
94
95 /* z = atan(|y/x|) without spurious underflow */
96 if ((m&2) && iy+(64<<20) < ix) /* |y/x| < 0x1p-64, x<0 */
97 z = 0;
98 else
99 z = atan(fabs(y/x));
100 switch (m) {
101 case 0: return z; /* atan(+,+) */
102 case 1: return -z; /* atan(-,+) */
103 case 2: return pi - (z-pi_lo); /* atan(+,-) */
104 default: /* case 3 */
105 return (z-pi_lo) - pi; /* atan(-,-) */
106 }
107}
libc/musl/src/math/atan2f.c created+83
......@@ -0,0 +1,83 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2f.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include "libm.h"
17
18static const float
19pi = 3.1415927410e+00, /* 0x40490fdb */
20pi_lo = -8.7422776573e-08; /* 0xb3bbbd2e */
21
22float atan2f(float y, float x)
23{
24 float z;
25 uint32_t m,ix,iy;
26
27 if (isnan(x) || isnan(y))
28 return x+y;
29 GET_FLOAT_WORD(ix, x);
30 GET_FLOAT_WORD(iy, y);
31 if (ix == 0x3f800000) /* x=1.0 */
32 return atanf(y);
33 m = ((iy>>31)&1) | ((ix>>30)&2); /* 2*sign(x)+sign(y) */
34 ix &= 0x7fffffff;
35 iy &= 0x7fffffff;
36
37 /* when y = 0 */
38 if (iy == 0) {
39 switch (m) {
40 case 0:
41 case 1: return y; /* atan(+-0,+anything)=+-0 */
42 case 2: return pi; /* atan(+0,-anything) = pi */
43 case 3: return -pi; /* atan(-0,-anything) =-pi */
44 }
45 }
46 /* when x = 0 */
47 if (ix == 0)
48 return m&1 ? -pi/2 : pi/2;
49 /* when x is INF */
50 if (ix == 0x7f800000) {
51 if (iy == 0x7f800000) {
52 switch (m) {
53 case 0: return pi/4; /* atan(+INF,+INF) */
54 case 1: return -pi/4; /* atan(-INF,+INF) */
55 case 2: return 3*pi/4; /*atan(+INF,-INF)*/
56 case 3: return -3*pi/4; /*atan(-INF,-INF)*/
57 }
58 } else {
59 switch (m) {
60 case 0: return 0.0f; /* atan(+...,+INF) */
61 case 1: return -0.0f; /* atan(-...,+INF) */
62 case 2: return pi; /* atan(+...,-INF) */
63 case 3: return -pi; /* atan(-...,-INF) */
64 }
65 }
66 }
67 /* |y/x| > 0x1p26 */
68 if (ix+(26<<23) < iy || iy == 0x7f800000)
69 return m&1 ? -pi/2 : pi/2;
70
71 /* z = atan(|y/x|) with correct underflow */
72 if ((m&2) && iy+(26<<23) < ix) /*|y/x| < 0x1p-26, x < 0 */
73 z = 0.0;
74 else
75 z = atanf(fabsf(y/x));
76 switch (m) {
77 case 0: return z; /* atan(+,+) */
78 case 1: return -z; /* atan(-,+) */
79 case 2: return pi - (z-pi_lo); /* atan(+,-) */
80 default: /* case 3 */
81 return (z-pi_lo) - pi; /* atan(-,-) */
82 }
83}
libc/musl/src/math/atan2l.c created+85
......@@ -0,0 +1,85 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_atan2l.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 *
12 */
13/*
14 * See comments in atan2.c.
15 * Converted to long double by David Schultz <das@FreeBSD.ORG>.
16 */
17
18#include "libm.h"
19
20#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
21long double atan2l(long double y, long double x)
22{
23 return atan2(y, x);
24}
25#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
26#include "__invtrigl.h"
27
28long double atan2l(long double y, long double x)
29{
30 union ldshape ux, uy;
31 long double z;
32 int m, ex, ey;
33
34 if (isnan(x) || isnan(y))
35 return x+y;
36 if (x == 1)
37 return atanl(y);
38 ux.f = x;
39 uy.f = y;
40 ex = ux.i.se & 0x7fff;
41 ey = uy.i.se & 0x7fff;
42 m = 2*(ux.i.se>>15) | uy.i.se>>15;
43 if (y == 0) {
44 switch(m) {
45 case 0:
46 case 1: return y; /* atan(+-0,+anything)=+-0 */
47 case 2: return 2*pio2_hi; /* atan(+0,-anything) = pi */
48 case 3: return -2*pio2_hi; /* atan(-0,-anything) =-pi */
49 }
50 }
51 if (x == 0)
52 return m&1 ? -pio2_hi : pio2_hi;
53 if (ex == 0x7fff) {
54 if (ey == 0x7fff) {
55 switch(m) {
56 case 0: return pio2_hi/2; /* atan(+INF,+INF) */
57 case 1: return -pio2_hi/2; /* atan(-INF,+INF) */
58 case 2: return 1.5*pio2_hi; /* atan(+INF,-INF) */
59 case 3: return -1.5*pio2_hi; /* atan(-INF,-INF) */
60 }
61 } else {
62 switch(m) {
63 case 0: return 0.0; /* atan(+...,+INF) */
64 case 1: return -0.0; /* atan(-...,+INF) */
65 case 2: return 2*pio2_hi; /* atan(+...,-INF) */
66 case 3: return -2*pio2_hi; /* atan(-...,-INF) */
67 }
68 }
69 }
70 if (ex+120 < ey || ey == 0x7fff)
71 return m&1 ? -pio2_hi : pio2_hi;
72 /* z = atan(|y/x|) without spurious underflow */
73 if ((m&2) && ey+120 < ex) /* |y/x| < 0x1p-120, x<0 */
74 z = 0.0;
75 else
76 z = atanl(fabsl(y/x));
77 switch (m) {
78 case 0: return z; /* atan(+,+) */
79 case 1: return -z; /* atan(-,+) */
80 case 2: return 2*pio2_hi-(z-2*pio2_lo); /* atan(+,-) */
81 default: /* case 3 */
82 return (z-2*pio2_lo)-2*pio2_hi; /* atan(-,-) */
83 }
84}
85#endif
libc/musl/src/math/atanf.c created+94
......@@ -0,0 +1,94 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_atanf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16
17#include "libm.h"
18
19static const float atanhi[] = {
20 4.6364760399e-01, /* atan(0.5)hi 0x3eed6338 */
21 7.8539812565e-01, /* atan(1.0)hi 0x3f490fda */
22 9.8279368877e-01, /* atan(1.5)hi 0x3f7b985e */
23 1.5707962513e+00, /* atan(inf)hi 0x3fc90fda */
24};
25
26static const float atanlo[] = {
27 5.0121582440e-09, /* atan(0.5)lo 0x31ac3769 */
28 3.7748947079e-08, /* atan(1.0)lo 0x33222168 */
29 3.4473217170e-08, /* atan(1.5)lo 0x33140fb4 */
30 7.5497894159e-08, /* atan(inf)lo 0x33a22168 */
31};
32
33static const float aT[] = {
34 3.3333328366e-01,
35 -1.9999158382e-01,
36 1.4253635705e-01,
37 -1.0648017377e-01,
38 6.1687607318e-02,
39};
40
41float atanf(float x)
42{
43 float_t w,s1,s2,z;
44 uint32_t ix,sign;
45 int id;
46
47 GET_FLOAT_WORD(ix, x);
48 sign = ix>>31;
49 ix &= 0x7fffffff;
50 if (ix >= 0x4c800000) { /* if |x| >= 2**26 */
51 if (isnan(x))
52 return x;
53 z = atanhi[3] + 0x1p-120f;
54 return sign ? -z : z;
55 }
56 if (ix < 0x3ee00000) { /* |x| < 0.4375 */
57 if (ix < 0x39800000) { /* |x| < 2**-12 */
58 if (ix < 0x00800000)
59 /* raise underflow for subnormal x */
60 FORCE_EVAL(x*x);
61 return x;
62 }
63 id = -1;
64 } else {
65 x = fabsf(x);
66 if (ix < 0x3f980000) { /* |x| < 1.1875 */
67 if (ix < 0x3f300000) { /* 7/16 <= |x| < 11/16 */
68 id = 0;
69 x = (2.0f*x - 1.0f)/(2.0f + x);
70 } else { /* 11/16 <= |x| < 19/16 */
71 id = 1;
72 x = (x - 1.0f)/(x + 1.0f);
73 }
74 } else {
75 if (ix < 0x401c0000) { /* |x| < 2.4375 */
76 id = 2;
77 x = (x - 1.5f)/(1.0f + 1.5f*x);
78 } else { /* 2.4375 <= |x| < 2**26 */
79 id = 3;
80 x = -1.0f/x;
81 }
82 }
83 }
84 /* end of argument reduction */
85 z = x*x;
86 w = z*z;
87 /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
88 s1 = z*(aT[0]+w*(aT[2]+w*aT[4]));
89 s2 = w*(aT[1]+w*aT[3]);
90 if (id < 0)
91 return x - x*(s1+s2);
92 z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
93 return sign ? -z : z;
94}
libc/musl/src/math/atanh.c created+29
......@@ -0,0 +1,29 @@
1#include "libm.h"
2
3/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
4double atanh(double x)
5{
6 union {double f; uint64_t i;} u = {.f = x};
7 unsigned e = u.i >> 52 & 0x7ff;
8 unsigned s = u.i >> 63;
9 double_t y;
10
11 /* |x| */
12 u.i &= (uint64_t)-1/2;
13 y = u.f;
14
15 if (e < 0x3ff - 1) {
16 if (e < 0x3ff - 32) {
17 /* handle underflow */
18 if (e == 0)
19 FORCE_EVAL((float)y);
20 } else {
21 /* |x| < 0.5, up to 1.7ulp error */
22 y = 0.5*log1p(2*y + 2*y*y/(1-y));
23 }
24 } else {
25 /* avoid overflow */
26 y = 0.5*log1p(2*(y/(1-y)));
27 }
28 return s ? -y : y;
29}
libc/musl/src/math/atanhf.c created+28
......@@ -0,0 +1,28 @@
1#include "libm.h"
2
3/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
4float atanhf(float x)
5{
6 union {float f; uint32_t i;} u = {.f = x};
7 unsigned s = u.i >> 31;
8 float_t y;
9
10 /* |x| */
11 u.i &= 0x7fffffff;
12 y = u.f;
13
14 if (u.i < 0x3f800000 - (1<<23)) {
15 if (u.i < 0x3f800000 - (32<<23)) {
16 /* handle underflow */
17 if (u.i < (1<<23))
18 FORCE_EVAL((float)(y*y));
19 } else {
20 /* |x| < 0.5, up to 1.7ulp error */
21 y = 0.5f*log1pf(2*y + 2*y*y/(1-y));
22 }
23 } else {
24 /* avoid overflow */
25 y = 0.5f*log1pf(2*(y/(1-y)));
26 }
27 return s ? -y : y;
28}
libc/musl/src/math/atanhl.c created+35
......@@ -0,0 +1,35 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double atanhl(long double x)
5{
6 return atanh(x);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
10long double atanhl(long double x)
11{
12 union ldshape u = {x};
13 unsigned e = u.i.se & 0x7fff;
14 unsigned s = u.i.se >> 15;
15
16 /* |x| */
17 u.i.se = e;
18 x = u.f;
19
20 if (e < 0x3ff - 1) {
21 if (e < 0x3ff - LDBL_MANT_DIG/2) {
22 /* handle underflow */
23 if (e == 0)
24 FORCE_EVAL((float)x);
25 } else {
26 /* |x| < 0.5, up to 1.7ulp error */
27 x = 0.5*log1pl(2*x + 2*x*x/(1-x));
28 }
29 } else {
30 /* avoid overflow */
31 x = 0.5*log1pl(2*(x/(1-x)));
32 }
33 return s ? -x : x;
34}
35#endif
libc/musl/src/math/atanl.c created+184
......@@ -0,0 +1,184 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_atanl.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * See comments in atan.c.
14 * Converted to long double by David Schultz <das@FreeBSD.ORG>.
15 */
16
17#include "libm.h"
18
19#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
20long double atanl(long double x)
21{
22 return atan(x);
23}
24#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
25
26#if LDBL_MANT_DIG == 64
27#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | (u.i.m>>55 & 0xff))
28
29static const long double atanhi[] = {
30 4.63647609000806116202e-01L,
31 7.85398163397448309628e-01L,
32 9.82793723247329067960e-01L,
33 1.57079632679489661926e+00L,
34};
35
36static const long double atanlo[] = {
37 1.18469937025062860669e-20L,
38 -1.25413940316708300586e-20L,
39 2.55232234165405176172e-20L,
40 -2.50827880633416601173e-20L,
41};
42
43static const long double aT[] = {
44 3.33333333333333333017e-01L,
45 -1.99999999999999632011e-01L,
46 1.42857142857046531280e-01L,
47 -1.11111111100562372733e-01L,
48 9.09090902935647302252e-02L,
49 -7.69230552476207730353e-02L,
50 6.66661718042406260546e-02L,
51 -5.88158892835030888692e-02L,
52 5.25499891539726639379e-02L,
53 -4.70119845393155721494e-02L,
54 4.03539201366454414072e-02L,
55 -2.91303858419364158725e-02L,
56 1.24822046299269234080e-02L,
57};
58
59static long double T_even(long double x)
60{
61 return aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] +
62 x * (aT[8] + x * (aT[10] + x * aT[12])))));
63}
64
65static long double T_odd(long double x)
66{
67 return aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] +
68 x * (aT[9] + x * aT[11]))));
69}
70#elif LDBL_MANT_DIG == 113
71#define EXPMAN(u) ((u.i.se & 0x7fff)<<8 | u.i.top>>8)
72
73const long double atanhi[] = {
74 4.63647609000806116214256231461214397e-01L,
75 7.85398163397448309615660845819875699e-01L,
76 9.82793723247329067985710611014666038e-01L,
77 1.57079632679489661923132169163975140e+00L,
78};
79
80const long double atanlo[] = {
81 4.89509642257333492668618435220297706e-36L,
82 2.16795253253094525619926100651083806e-35L,
83 -2.31288434538183565909319952098066272e-35L,
84 4.33590506506189051239852201302167613e-35L,
85};
86
87const long double aT[] = {
88 3.33333333333333333333333333333333125e-01L,
89 -1.99999999999999999999999999999180430e-01L,
90 1.42857142857142857142857142125269827e-01L,
91 -1.11111111111111111111110834490810169e-01L,
92 9.09090909090909090908522355708623681e-02L,
93 -7.69230769230769230696553844935357021e-02L,
94 6.66666666666666660390096773046256096e-02L,
95 -5.88235294117646671706582985209643694e-02L,
96 5.26315789473666478515847092020327506e-02L,
97 -4.76190476189855517021024424991436144e-02L,
98 4.34782608678695085948531993458097026e-02L,
99 -3.99999999632663469330634215991142368e-02L,
100 3.70370363987423702891250829918659723e-02L,
101 -3.44827496515048090726669907612335954e-02L,
102 3.22579620681420149871973710852268528e-02L,
103 -3.03020767654269261041647570626778067e-02L,
104 2.85641979882534783223403715930946138e-02L,
105 -2.69824879726738568189929461383741323e-02L,
106 2.54194698498808542954187110873675769e-02L,
107 -2.35083879708189059926183138130183215e-02L,
108 2.04832358998165364349957325067131428e-02L,
109 -1.54489555488544397858507248612362957e-02L,
110 8.64492360989278761493037861575248038e-03L,
111 -2.58521121597609872727919154569765469e-03L,
112};
113
114static long double T_even(long double x)
115{
116 return (aT[0] + x * (aT[2] + x * (aT[4] + x * (aT[6] + x * (aT[8] +
117 x * (aT[10] + x * (aT[12] + x * (aT[14] + x * (aT[16] +
118 x * (aT[18] + x * (aT[20] + x * aT[22])))))))))));
119}
120
121static long double T_odd(long double x)
122{
123 return (aT[1] + x * (aT[3] + x * (aT[5] + x * (aT[7] + x * (aT[9] +
124 x * (aT[11] + x * (aT[13] + x * (aT[15] + x * (aT[17] +
125 x * (aT[19] + x * (aT[21] + x * aT[23])))))))))));
126}
127#endif
128
129long double atanl(long double x)
130{
131 union ldshape u = {x};
132 long double w, s1, s2, z;
133 int id;
134 unsigned e = u.i.se & 0x7fff;
135 unsigned sign = u.i.se >> 15;
136 unsigned expman;
137
138 if (e >= 0x3fff + LDBL_MANT_DIG + 1) { /* if |x| is large, atan(x)~=pi/2 */
139 if (isnan(x))
140 return x;
141 return sign ? -atanhi[3] : atanhi[3];
142 }
143 /* Extract the exponent and the first few bits of the mantissa. */
144 expman = EXPMAN(u);
145 if (expman < ((0x3fff - 2) << 8) + 0xc0) { /* |x| < 0.4375 */
146 if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) { /* if |x| is small, atanl(x)~=x */
147 /* raise underflow if subnormal */
148 if (e == 0)
149 FORCE_EVAL((float)x);
150 return x;
151 }
152 id = -1;
153 } else {
154 x = fabsl(x);
155 if (expman < (0x3fff << 8) + 0x30) { /* |x| < 1.1875 */
156 if (expman < ((0x3fff - 1) << 8) + 0x60) { /* 7/16 <= |x| < 11/16 */
157 id = 0;
158 x = (2.0*x-1.0)/(2.0+x);
159 } else { /* 11/16 <= |x| < 19/16 */
160 id = 1;
161 x = (x-1.0)/(x+1.0);
162 }
163 } else {
164 if (expman < ((0x3fff + 1) << 8) + 0x38) { /* |x| < 2.4375 */
165 id = 2;
166 x = (x-1.5)/(1.0+1.5*x);
167 } else { /* 2.4375 <= |x| */
168 id = 3;
169 x = -1.0/x;
170 }
171 }
172 }
173 /* end of argument reduction */
174 z = x*x;
175 w = z*z;
176 /* break sum aT[i]z**(i+1) into odd and even poly */
177 s1 = z*T_even(w);
178 s2 = w*T_odd(w);
179 if (id < 0)
180 return x - x*(s1+s2);
181 z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
182 return sign ? -z : z;
183}
184#endif
libc/musl/src/math/cbrt.c created+103
......@@ -0,0 +1,103 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrt.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 *
12 * Optimized by Bruce D. Evans.
13 */
14/* cbrt(x)
15 * Return cube root of x
16 */
17
18#include <math.h>
19#include <stdint.h>
20
21static const uint32_t
22B1 = 715094163, /* B1 = (1023-1023/3-0.03306235651)*2**20 */
23B2 = 696219795; /* B2 = (1023-1023/3-54/3-0.03306235651)*2**20 */
24
25/* |1/cbrt(x) - p(x)| < 2**-23.5 (~[-7.93e-8, 7.929e-8]). */
26static const double
27P0 = 1.87595182427177009643, /* 0x3ffe03e6, 0x0f61e692 */
28P1 = -1.88497979543377169875, /* 0xbffe28e0, 0x92f02420 */
29P2 = 1.621429720105354466140, /* 0x3ff9f160, 0x4a49d6c2 */
30P3 = -0.758397934778766047437, /* 0xbfe844cb, 0xbee751d9 */
31P4 = 0.145996192886612446982; /* 0x3fc2b000, 0xd4e4edd7 */
32
33double cbrt(double x)
34{
35 union {double f; uint64_t i;} u = {x};
36 double_t r,s,t,w;
37 uint32_t hx = u.i>>32 & 0x7fffffff;
38
39 if (hx >= 0x7ff00000) /* cbrt(NaN,INF) is itself */
40 return x+x;
41
42 /*
43 * Rough cbrt to 5 bits:
44 * cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3)
45 * where e is integral and >= 0, m is real and in [0, 1), and "/" and
46 * "%" are integer division and modulus with rounding towards minus
47 * infinity. The RHS is always >= the LHS and has a maximum relative
48 * error of about 1 in 16. Adding a bias of -0.03306235651 to the
49 * (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE
50 * floating point representation, for finite positive normal values,
51 * ordinary integer divison of the value in bits magically gives
52 * almost exactly the RHS of the above provided we first subtract the
53 * exponent bias (1023 for doubles) and later add it back. We do the
54 * subtraction virtually to keep e >= 0 so that ordinary integer
55 * division rounds towards minus infinity; this is also efficient.
56 */
57 if (hx < 0x00100000) { /* zero or subnormal? */
58 u.f = x*0x1p54;
59 hx = u.i>>32 & 0x7fffffff;
60 if (hx == 0)
61 return x; /* cbrt(0) is itself */
62 hx = hx/3 + B2;
63 } else
64 hx = hx/3 + B1;
65 u.i &= 1ULL<<63;
66 u.i |= (uint64_t)hx << 32;
67 t = u.f;
68
69 /*
70 * New cbrt to 23 bits:
71 * cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x)
72 * where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r)
73 * to within 2**-23.5 when |r - 1| < 1/10. The rough approximation
74 * has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this
75 * gives us bounds for r = t**3/x.
76 *
77 * Try to optimize for parallel evaluation as in __tanf.c.
78 */
79 r = (t*t)*(t/x);
80 t = t*((P0+r*(P1+r*P2))+((r*r)*r)*(P3+r*P4));
81
82 /*
83 * Round t away from zero to 23 bits (sloppily except for ensuring that
84 * the result is larger in magnitude than cbrt(x) but not much more than
85 * 2 23-bit ulps larger). With rounding towards zero, the error bound
86 * would be ~5/6 instead of ~4/6. With a maximum error of 2 23-bit ulps
87 * in the rounded t, the infinite-precision error in the Newton
88 * approximation barely affects third digit in the final error
89 * 0.667; the error in the rounded t can be up to about 3 23-bit ulps
90 * before the final error is larger than 0.667 ulps.
91 */
92 u.f = t;
93 u.i = (u.i + 0x80000000) & 0xffffffffc0000000ULL;
94 t = u.f;
95
96 /* one step Newton iteration to 53 bits with error < 0.667 ulps */
97 s = t*t; /* t*t is exact */
98 r = x/s; /* error <= 0.5 ulps; |r| < |t| */
99 w = t+t; /* t+t is exact */
100 r = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */
101 t = t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */
102 return t;
103}
libc/musl/src/math/cbrtf.c created+66
......@@ -0,0 +1,66 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 * Debugged and optimized by Bruce D. Evans.
5 */
6/*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 *
10 * Developed at SunPro, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
15 */
16/* cbrtf(x)
17 * Return cube root of x
18 */
19
20#include <math.h>
21#include <stdint.h>
22
23static const unsigned
24B1 = 709958130, /* B1 = (127-127.0/3-0.03306235651)*2**23 */
25B2 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */
26
27float cbrtf(float x)
28{
29 double_t r,T;
30 union {float f; uint32_t i;} u = {x};
31 uint32_t hx = u.i & 0x7fffffff;
32
33 if (hx >= 0x7f800000) /* cbrt(NaN,INF) is itself */
34 return x + x;
35
36 /* rough cbrt to 5 bits */
37 if (hx < 0x00800000) { /* zero or subnormal? */
38 if (hx == 0)
39 return x; /* cbrt(+-0) is itself */
40 u.f = x*0x1p24f;
41 hx = u.i & 0x7fffffff;
42 hx = hx/3 + B2;
43 } else
44 hx = hx/3 + B1;
45 u.i &= 0x80000000;
46 u.i |= hx;
47
48 /*
49 * First step Newton iteration (solving t*t-x/t == 0) to 16 bits. In
50 * double precision so that its terms can be arranged for efficiency
51 * without causing overflow or underflow.
52 */
53 T = u.f;
54 r = T*T*T;
55 T = T*((double_t)x+x+r)/(x+r+r);
56
57 /*
58 * Second step Newton iteration to 47 bits. In double precision for
59 * efficiency and accuracy.
60 */
61 r = T*T*T;
62 T = T*((double_t)x+x+r)/(x+r+r);
63
64 /* rounding to 24 bits is perfect in round-to-nearest mode */
65 return T;
66}
libc/musl/src/math/cbrtl.c created+124
......@@ -0,0 +1,124 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_cbrtl.c */
2/*-
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 * Copyright (c) 2009-2011, Bruce D. Evans, Steven G. Kargl, David Schultz.
6 *
7 * Developed at SunPro, a Sun Microsystems, Inc. business.
8 * Permission to use, copy, modify, and distribute this
9 * software is freely granted, provided that this notice
10 * is preserved.
11 * ====================================================
12 *
13 * The argument reduction and testing for exceptional cases was
14 * written by Steven G. Kargl with input from Bruce D. Evans
15 * and David A. Schultz.
16 */
17
18#include "libm.h"
19
20#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
21long double cbrtl(long double x)
22{
23 return cbrt(x);
24}
25#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
26static const unsigned B1 = 709958130; /* B1 = (127-127.0/3-0.03306235651)*2**23 */
27
28long double cbrtl(long double x)
29{
30 union ldshape u = {x}, v;
31 union {float f; uint32_t i;} uft;
32 long double r, s, t, w;
33 double_t dr, dt, dx;
34 float_t ft;
35 int e = u.i.se & 0x7fff;
36 int sign = u.i.se & 0x8000;
37
38 /*
39 * If x = +-Inf, then cbrt(x) = +-Inf.
40 * If x = NaN, then cbrt(x) = NaN.
41 */
42 if (e == 0x7fff)
43 return x + x;
44 if (e == 0) {
45 /* Adjust subnormal numbers. */
46 u.f *= 0x1p120;
47 e = u.i.se & 0x7fff;
48 /* If x = +-0, then cbrt(x) = +-0. */
49 if (e == 0)
50 return x;
51 e -= 120;
52 }
53 e -= 0x3fff;
54 u.i.se = 0x3fff;
55 x = u.f;
56 switch (e % 3) {
57 case 1:
58 case -2:
59 x *= 2;
60 e--;
61 break;
62 case 2:
63 case -1:
64 x *= 4;
65 e -= 2;
66 break;
67 }
68 v.f = 1.0;
69 v.i.se = sign | (0x3fff + e/3);
70
71 /*
72 * The following is the guts of s_cbrtf, with the handling of
73 * special values removed and extra care for accuracy not taken,
74 * but with most of the extra accuracy not discarded.
75 */
76
77 /* ~5-bit estimate: */
78 uft.f = x;
79 uft.i = (uft.i & 0x7fffffff)/3 + B1;
80 ft = uft.f;
81
82 /* ~16-bit estimate: */
83 dx = x;
84 dt = ft;
85 dr = dt * dt * dt;
86 dt = dt * (dx + dx + dr) / (dx + dr + dr);
87
88 /* ~47-bit estimate: */
89 dr = dt * dt * dt;
90 dt = dt * (dx + dx + dr) / (dx + dr + dr);
91
92#if LDBL_MANT_DIG == 64
93 /*
94 * dt is cbrtl(x) to ~47 bits (after x has been reduced to 1 <= x < 8).
95 * Round it away from zero to 32 bits (32 so that t*t is exact, and
96 * away from zero for technical reasons).
97 */
98 t = dt + (0x1.0p32L + 0x1.0p-31L) - 0x1.0p32;
99#elif LDBL_MANT_DIG == 113
100 /*
101 * Round dt away from zero to 47 bits. Since we don't trust the 47,
102 * add 2 47-bit ulps instead of 1 to round up. Rounding is slow and
103 * might be avoidable in this case, since on most machines dt will
104 * have been evaluated in 53-bit precision and the technical reasons
105 * for rounding up might not apply to either case in cbrtl() since
106 * dt is much more accurate than needed.
107 */
108 t = dt + 0x2.0p-46 + 0x1.0p60L - 0x1.0p60;
109#endif
110
111 /*
112 * Final step Newton iteration to 64 or 113 bits with
113 * error < 0.667 ulps
114 */
115 s = t*t; /* t*t is exact */
116 r = x/s; /* error <= 0.5 ulps; |r| < |t| */
117 w = t+t; /* t+t is exact */
118 r = (r-t)/(w+r); /* r-t is exact; w+r ~= 3*t */
119 t = t+t*r; /* error <= 0.5 + 0.5/3 + epsilon */
120
121 t *= v.f;
122 return t;
123}
124#endif
libc/musl/src/math/ceil.c created+31
......@@ -0,0 +1,31 @@
1#include "libm.h"
2
3#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
4#define EPS DBL_EPSILON
5#elif FLT_EVAL_METHOD==2
6#define EPS LDBL_EPSILON
7#endif
8static const double_t toint = 1/EPS;
9
10double ceil(double x)
11{
12 union {double f; uint64_t i;} u = {x};
13 int e = u.i >> 52 & 0x7ff;
14 double_t y;
15
16 if (e >= 0x3ff+52 || x == 0)
17 return x;
18 /* y = int(x) - x, where int(x) is an integer neighbor of x */
19 if (u.i >> 63)
20 y = x - toint + toint - x;
21 else
22 y = x + toint - toint - x;
23 /* special case because of non-nearest rounding modes */
24 if (e <= 0x3ff-1) {
25 FORCE_EVAL(y);
26 return u.i >> 63 ? -0.0 : 1;
27 }
28 if (y < 0)
29 return x + y + 1;
30 return x + y;
31}
libc/musl/src/math/ceilf.c created+27
......@@ -0,0 +1,27 @@
1#include "libm.h"
2
3float ceilf(float x)
4{
5 union {float f; uint32_t i;} u = {x};
6 int e = (int)(u.i >> 23 & 0xff) - 0x7f;
7 uint32_t m;
8
9 if (e >= 23)
10 return x;
11 if (e >= 0) {
12 m = 0x007fffff >> e;
13 if ((u.i & m) == 0)
14 return x;
15 FORCE_EVAL(x + 0x1p120f);
16 if (u.i >> 31 == 0)
17 u.i += m;
18 u.i &= ~m;
19 } else {
20 FORCE_EVAL(x + 0x1p120f);
21 if (u.i >> 31)
22 u.f = -0.0;
23 else if (u.i << 1)
24 u.f = 1.0;
25 }
26 return u.f;
27}
libc/musl/src/math/ceill.c created+34
......@@ -0,0 +1,34 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double ceill(long double x)
5{
6 return ceil(x);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9
10static const long double toint = 1/LDBL_EPSILON;
11
12long double ceill(long double x)
13{
14 union ldshape u = {x};
15 int e = u.i.se & 0x7fff;
16 long double y;
17
18 if (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0)
19 return x;
20 /* y = int(x) - x, where int(x) is an integer neighbor of x */
21 if (u.i.se >> 15)
22 y = x - toint + toint - x;
23 else
24 y = x + toint - toint - x;
25 /* special case because of non-nearest rounding modes */
26 if (e <= 0x3fff-1) {
27 FORCE_EVAL(y);
28 return u.i.se >> 15 ? -0.0 : 1;
29 }
30 if (y < 0)
31 return x + y + 1;
32 return x + y;
33}
34#endif
libc/musl/src/math/copysign.c created+8
......@@ -0,0 +1,8 @@
1#include "libm.h"
2
3double copysign(double x, double y) {
4 union {double f; uint64_t i;} ux={x}, uy={y};
5 ux.i &= -1ULL/2;
6 ux.i |= uy.i & 1ULL<<63;
7 return ux.f;
8}
libc/musl/src/math/copysignf.c created+10
......@@ -0,0 +1,10 @@
1#include <math.h>
2#include <stdint.h>
3
4float copysignf(float x, float y)
5{
6 union {float f; uint32_t i;} ux={x}, uy={y};
7 ux.i &= 0x7fffffff;
8 ux.i |= uy.i & 0x80000000;
9 return ux.f;
10}
libc/musl/src/math/copysignl.c created+16
......@@ -0,0 +1,16 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double copysignl(long double x, long double y)
5{
6 return copysign(x, y);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9long double copysignl(long double x, long double y)
10{
11 union ldshape ux = {x}, uy = {y};
12 ux.i.se &= 0x7fff;
13 ux.i.se |= uy.i.se & 0x8000;
14 return ux.f;
15}
16#endif
libc/musl/src/math/cos.c created+77
......@@ -0,0 +1,77 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_cos.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* cos(x)
13 * Return cosine function of x.
14 *
15 * kernel function:
16 * __sin ... sine function on [-pi/4,pi/4]
17 * __cos ... cosine function on [-pi/4,pi/4]
18 * __rem_pio2 ... argument reduction routine
19 *
20 * Method.
21 * Let S,C and T denote the sin, cos and tan respectively on
22 * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
23 * in [-pi/4 , +pi/4], and let n = k mod 4.
24 * We have
25 *
26 * n sin(x) cos(x) tan(x)
27 * ----------------------------------------------------------
28 * 0 S C T
29 * 1 C -S -1/T
30 * 2 -S -C T
31 * 3 -C S -1/T
32 * ----------------------------------------------------------
33 *
34 * Special cases:
35 * Let trig be any of sin, cos, or tan.
36 * trig(+-INF) is NaN, with signals;
37 * trig(NaN) is that NaN;
38 *
39 * Accuracy:
40 * TRIG(x) returns trig(x) nearly rounded
41 */
42
43#include "libm.h"
44
45double cos(double x)
46{
47 double y[2];
48 uint32_t ix;
49 unsigned n;
50
51 GET_HIGH_WORD(ix, x);
52 ix &= 0x7fffffff;
53
54 /* |x| ~< pi/4 */
55 if (ix <= 0x3fe921fb) {
56 if (ix < 0x3e46a09e) { /* |x| < 2**-27 * sqrt(2) */
57 /* raise inexact if x!=0 */
58 FORCE_EVAL(x + 0x1p120f);
59 return 1.0;
60 }
61 return __cos(x, 0);
62 }
63
64 /* cos(Inf or NaN) is NaN */
65 if (ix >= 0x7ff00000)
66 return x-x;
67
68 /* argument reduction */
69 n = __rem_pio2(x, y);
70 switch (n&3) {
71 case 0: return __cos(y[0], y[1]);
72 case 1: return -__sin(y[0], y[1], 1);
73 case 2: return -__cos(y[0], y[1]);
74 default:
75 return __sin(y[0], y[1], 1);
76 }
77}
libc/musl/src/math/cosf.c created+78
......@@ -0,0 +1,78 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_cosf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 * Optimized by Bruce D. Evans.
5 */
6/*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 *
10 * Developed at SunPro, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
15 */
16
17#include "libm.h"
18
19/* Small multiples of pi/2 rounded to double precision. */
20static const double
21c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
22c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
23c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
24c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
25
26float cosf(float x)
27{
28 double y;
29 uint32_t ix;
30 unsigned n, sign;
31
32 GET_FLOAT_WORD(ix, x);
33 sign = ix >> 31;
34 ix &= 0x7fffffff;
35
36 if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
37 if (ix < 0x39800000) { /* |x| < 2**-12 */
38 /* raise inexact if x != 0 */
39 FORCE_EVAL(x + 0x1p120f);
40 return 1.0f;
41 }
42 return __cosdf(x);
43 }
44 if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
45 if (ix > 0x4016cbe3) /* |x| ~> 3*pi/4 */
46 return -__cosdf(sign ? x+c2pio2 : x-c2pio2);
47 else {
48 if (sign)
49 return __sindf(x + c1pio2);
50 else
51 return __sindf(c1pio2 - x);
52 }
53 }
54 if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
55 if (ix > 0x40afeddf) /* |x| ~> 7*pi/4 */
56 return __cosdf(sign ? x+c4pio2 : x-c4pio2);
57 else {
58 if (sign)
59 return __sindf(-x - c3pio2);
60 else
61 return __sindf(x - c3pio2);
62 }
63 }
64
65 /* cos(Inf or NaN) is NaN */
66 if (ix >= 0x7f800000)
67 return x-x;
68
69 /* general argument reduction needed */
70 n = __rem_pio2f(x,&y);
71 switch (n&3) {
72 case 0: return __cosdf(y);
73 case 1: return __sindf(-y);
74 case 2: return -__cosdf(y);
75 default:
76 return __sindf(y);
77 }
78}
libc/musl/src/math/cosh.c created+40
......@@ -0,0 +1,40 @@
1#include "libm.h"
2
3/* cosh(x) = (exp(x) + 1/exp(x))/2
4 * = 1 + 0.5*(exp(x)-1)*(exp(x)-1)/exp(x)
5 * = 1 + x*x/2 + o(x^4)
6 */
7double cosh(double x)
8{
9 union {double f; uint64_t i;} u = {.f = x};
10 uint32_t w;
11 double t;
12
13 /* |x| */
14 u.i &= (uint64_t)-1/2;
15 x = u.f;
16 w = u.i >> 32;
17
18 /* |x| < log(2) */
19 if (w < 0x3fe62e42) {
20 if (w < 0x3ff00000 - (26<<20)) {
21 /* raise inexact if x!=0 */
22 FORCE_EVAL(x + 0x1p120f);
23 return 1;
24 }
25 t = expm1(x);
26 return 1 + t*t/(2*(1+t));
27 }
28
29 /* |x| < log(DBL_MAX) */
30 if (w < 0x40862e42) {
31 t = exp(x);
32 /* note: if x>log(0x1p26) then the 1/t is not needed */
33 return 0.5*(t + 1/t);
34 }
35
36 /* |x| > log(DBL_MAX) or nan */
37 /* note: the result is stored to handle overflow */
38 t = __expo2(x);
39 return t;
40}
libc/musl/src/math/coshf.c created+33
......@@ -0,0 +1,33 @@
1#include "libm.h"
2
3float coshf(float x)
4{
5 union {float f; uint32_t i;} u = {.f = x};
6 uint32_t w;
7 float t;
8
9 /* |x| */
10 u.i &= 0x7fffffff;
11 x = u.f;
12 w = u.i;
13
14 /* |x| < log(2) */
15 if (w < 0x3f317217) {
16 if (w < 0x3f800000 - (12<<23)) {
17 FORCE_EVAL(x + 0x1p120f);
18 return 1;
19 }
20 t = expm1f(x);
21 return 1 + t*t/(2*(1+t));
22 }
23
24 /* |x| < log(FLT_MAX) */
25 if (w < 0x42b17217) {
26 t = expf(x);
27 return 0.5f*(t + 1/t);
28 }
29
30 /* |x| > log(FLT_MAX) or nan */
31 t = __expo2f(x);
32 return t;
33}
libc/musl/src/math/coshl.c created+47
......@@ -0,0 +1,47 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double coshl(long double x)
5{
6 return cosh(x);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9long double coshl(long double x)
10{
11 union ldshape u = {x};
12 unsigned ex = u.i.se & 0x7fff;
13 uint32_t w;
14 long double t;
15
16 /* |x| */
17 u.i.se = ex;
18 x = u.f;
19 w = u.i.m >> 32;
20
21 /* |x| < log(2) */
22 if (ex < 0x3fff-1 || (ex == 0x3fff-1 && w < 0xb17217f7)) {
23 if (ex < 0x3fff-32) {
24 FORCE_EVAL(x + 0x1p120f);
25 return 1;
26 }
27 t = expm1l(x);
28 return 1 + t*t/(2*(1+t));
29 }
30
31 /* |x| < log(LDBL_MAX) */
32 if (ex < 0x3fff+13 || (ex == 0x3fff+13 && w < 0xb17217f7)) {
33 t = expl(x);
34 return 0.5*(t + 1/t);
35 }
36
37 /* |x| > log(LDBL_MAX) or nan */
38 t = expl(0.5*x);
39 return 0.5*t*t;
40}
41#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
42// TODO: broken implementation to make things compile
43long double coshl(long double x)
44{
45 return cosh(x);
46}
47#endif
libc/musl/src/math/cosl.c created+39
......@@ -0,0 +1,39 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double cosl(long double x) {
5 return cos(x);
6}
7#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
8long double cosl(long double x)
9{
10 union ldshape u = {x};
11 unsigned n;
12 long double y[2], hi, lo;
13
14 u.i.se &= 0x7fff;
15 if (u.i.se == 0x7fff)
16 return x - x;
17 x = u.f;
18 if (x < M_PI_4) {
19 if (u.i.se < 0x3fff - LDBL_MANT_DIG)
20 /* raise inexact if x!=0 */
21 return 1.0 + x;
22 return __cosl(x, 0);
23 }
24 n = __rem_pio2l(x, y);
25 hi = y[0];
26 lo = y[1];
27 switch (n & 3) {
28 case 0:
29 return __cosl(hi, lo);
30 case 1:
31 return -__sinl(hi, lo, 1);
32 case 2:
33 return -__cosl(hi, lo);
34 case 3:
35 default:
36 return __sinl(hi, lo, 1);
37 }
38}
39#endif
libc/musl/src/math/erf.c created+273
......@@ -0,0 +1,273 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_erf.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* double erf(double x)
13 * double erfc(double x)
14 * x
15 * 2 |\
16 * erf(x) = --------- | exp(-t*t)dt
17 * sqrt(pi) \|
18 * 0
19 *
20 * erfc(x) = 1-erf(x)
21 * Note that
22 * erf(-x) = -erf(x)
23 * erfc(-x) = 2 - erfc(x)
24 *
25 * Method:
26 * 1. For |x| in [0, 0.84375]
27 * erf(x) = x + x*R(x^2)
28 * erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
29 * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
30 * where R = P/Q where P is an odd poly of degree 8 and
31 * Q is an odd poly of degree 10.
32 * -57.90
33 * | R - (erf(x)-x)/x | <= 2
34 *
35 *
36 * Remark. The formula is derived by noting
37 * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
38 * and that
39 * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
40 * is close to one. The interval is chosen because the fix
41 * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
42 * near 0.6174), and by some experiment, 0.84375 is chosen to
43 * guarantee the error is less than one ulp for erf.
44 *
45 * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
46 * c = 0.84506291151 rounded to single (24 bits)
47 * erf(x) = sign(x) * (c + P1(s)/Q1(s))
48 * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
49 * 1+(c+P1(s)/Q1(s)) if x < 0
50 * |P1/Q1 - (erf(|x|)-c)| <= 2**-59.06
51 * Remark: here we use the taylor series expansion at x=1.
52 * erf(1+s) = erf(1) + s*Poly(s)
53 * = 0.845.. + P1(s)/Q1(s)
54 * That is, we use rational approximation to approximate
55 * erf(1+s) - (c = (single)0.84506291151)
56 * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
57 * where
58 * P1(s) = degree 6 poly in s
59 * Q1(s) = degree 6 poly in s
60 *
61 * 3. For x in [1.25,1/0.35(~2.857143)],
62 * erfc(x) = (1/x)*exp(-x*x-0.5625+R1/S1)
63 * erf(x) = 1 - erfc(x)
64 * where
65 * R1(z) = degree 7 poly in z, (z=1/x^2)
66 * S1(z) = degree 8 poly in z
67 *
68 * 4. For x in [1/0.35,28]
69 * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
70 * = 2.0 - (1/x)*exp(-x*x-0.5625+R2/S2) if -6<x<0
71 * = 2.0 - tiny (if x <= -6)
72 * erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6, else
73 * erf(x) = sign(x)*(1.0 - tiny)
74 * where
75 * R2(z) = degree 6 poly in z, (z=1/x^2)
76 * S2(z) = degree 7 poly in z
77 *
78 * Note1:
79 * To compute exp(-x*x-0.5625+R/S), let s be a single
80 * precision number and s := x; then
81 * -x*x = -s*s + (s-x)*(s+x)
82 * exp(-x*x-0.5626+R/S) =
83 * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
84 * Note2:
85 * Here 4 and 5 make use of the asymptotic series
86 * exp(-x*x)
87 * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
88 * x*sqrt(pi)
89 * We use rational approximation to approximate
90 * g(s)=f(1/x^2) = log(erfc(x)*x) - x*x + 0.5625
91 * Here is the error bound for R1/S1 and R2/S2
92 * |R1/S1 - f(x)| < 2**(-62.57)
93 * |R2/S2 - f(x)| < 2**(-61.52)
94 *
95 * 5. For inf > x >= 28
96 * erf(x) = sign(x) *(1 - tiny) (raise inexact)
97 * erfc(x) = tiny*tiny (raise underflow) if x > 0
98 * = 2 - tiny if x<0
99 *
100 * 7. Special case:
101 * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
102 * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
103 * erfc/erf(NaN) is NaN
104 */
105
106#include "libm.h"
107
108static const double
109erx = 8.45062911510467529297e-01, /* 0x3FEB0AC1, 0x60000000 */
110/*
111 * Coefficients for approximation to erf on [0,0.84375]
112 */
113efx8 = 1.02703333676410069053e+00, /* 0x3FF06EBA, 0x8214DB69 */
114pp0 = 1.28379167095512558561e-01, /* 0x3FC06EBA, 0x8214DB68 */
115pp1 = -3.25042107247001499370e-01, /* 0xBFD4CD7D, 0x691CB913 */
116pp2 = -2.84817495755985104766e-02, /* 0xBF9D2A51, 0xDBD7194F */
117pp3 = -5.77027029648944159157e-03, /* 0xBF77A291, 0x236668E4 */
118pp4 = -2.37630166566501626084e-05, /* 0xBEF8EAD6, 0x120016AC */
119qq1 = 3.97917223959155352819e-01, /* 0x3FD97779, 0xCDDADC09 */
120qq2 = 6.50222499887672944485e-02, /* 0x3FB0A54C, 0x5536CEBA */
121qq3 = 5.08130628187576562776e-03, /* 0x3F74D022, 0xC4D36B0F */
122qq4 = 1.32494738004321644526e-04, /* 0x3F215DC9, 0x221C1A10 */
123qq5 = -3.96022827877536812320e-06, /* 0xBED09C43, 0x42A26120 */
124/*
125 * Coefficients for approximation to erf in [0.84375,1.25]
126 */
127pa0 = -2.36211856075265944077e-03, /* 0xBF6359B8, 0xBEF77538 */
128pa1 = 4.14856118683748331666e-01, /* 0x3FDA8D00, 0xAD92B34D */
129pa2 = -3.72207876035701323847e-01, /* 0xBFD7D240, 0xFBB8C3F1 */
130pa3 = 3.18346619901161753674e-01, /* 0x3FD45FCA, 0x805120E4 */
131pa4 = -1.10894694282396677476e-01, /* 0xBFBC6398, 0x3D3E28EC */
132pa5 = 3.54783043256182359371e-02, /* 0x3FA22A36, 0x599795EB */
133pa6 = -2.16637559486879084300e-03, /* 0xBF61BF38, 0x0A96073F */
134qa1 = 1.06420880400844228286e-01, /* 0x3FBB3E66, 0x18EEE323 */
135qa2 = 5.40397917702171048937e-01, /* 0x3FE14AF0, 0x92EB6F33 */
136qa3 = 7.18286544141962662868e-02, /* 0x3FB2635C, 0xD99FE9A7 */
137qa4 = 1.26171219808761642112e-01, /* 0x3FC02660, 0xE763351F */
138qa5 = 1.36370839120290507362e-02, /* 0x3F8BEDC2, 0x6B51DD1C */
139qa6 = 1.19844998467991074170e-02, /* 0x3F888B54, 0x5735151D */
140/*
141 * Coefficients for approximation to erfc in [1.25,1/0.35]
142 */
143ra0 = -9.86494403484714822705e-03, /* 0xBF843412, 0x600D6435 */
144ra1 = -6.93858572707181764372e-01, /* 0xBFE63416, 0xE4BA7360 */
145ra2 = -1.05586262253232909814e+01, /* 0xC0251E04, 0x41B0E726 */
146ra3 = -6.23753324503260060396e+01, /* 0xC04F300A, 0xE4CBA38D */
147ra4 = -1.62396669462573470355e+02, /* 0xC0644CB1, 0x84282266 */
148ra5 = -1.84605092906711035994e+02, /* 0xC067135C, 0xEBCCABB2 */
149ra6 = -8.12874355063065934246e+01, /* 0xC0545265, 0x57E4D2F2 */
150ra7 = -9.81432934416914548592e+00, /* 0xC023A0EF, 0xC69AC25C */
151sa1 = 1.96512716674392571292e+01, /* 0x4033A6B9, 0xBD707687 */
152sa2 = 1.37657754143519042600e+02, /* 0x4061350C, 0x526AE721 */
153sa3 = 4.34565877475229228821e+02, /* 0x407B290D, 0xD58A1A71 */
154sa4 = 6.45387271733267880336e+02, /* 0x40842B19, 0x21EC2868 */
155sa5 = 4.29008140027567833386e+02, /* 0x407AD021, 0x57700314 */
156sa6 = 1.08635005541779435134e+02, /* 0x405B28A3, 0xEE48AE2C */
157sa7 = 6.57024977031928170135e+00, /* 0x401A47EF, 0x8E484A93 */
158sa8 = -6.04244152148580987438e-02, /* 0xBFAEEFF2, 0xEE749A62 */
159/*
160 * Coefficients for approximation to erfc in [1/.35,28]
161 */
162rb0 = -9.86494292470009928597e-03, /* 0xBF843412, 0x39E86F4A */
163rb1 = -7.99283237680523006574e-01, /* 0xBFE993BA, 0x70C285DE */
164rb2 = -1.77579549177547519889e+01, /* 0xC031C209, 0x555F995A */
165rb3 = -1.60636384855821916062e+02, /* 0xC064145D, 0x43C5ED98 */
166rb4 = -6.37566443368389627722e+02, /* 0xC083EC88, 0x1375F228 */
167rb5 = -1.02509513161107724954e+03, /* 0xC0900461, 0x6A2E5992 */
168rb6 = -4.83519191608651397019e+02, /* 0xC07E384E, 0x9BDC383F */
169sb1 = 3.03380607434824582924e+01, /* 0x403E568B, 0x261D5190 */
170sb2 = 3.25792512996573918826e+02, /* 0x40745CAE, 0x221B9F0A */
171sb3 = 1.53672958608443695994e+03, /* 0x409802EB, 0x189D5118 */
172sb4 = 3.19985821950859553908e+03, /* 0x40A8FFB7, 0x688C246A */
173sb5 = 2.55305040643316442583e+03, /* 0x40A3F219, 0xCEDF3BE6 */
174sb6 = 4.74528541206955367215e+02, /* 0x407DA874, 0xE79FE763 */
175sb7 = -2.24409524465858183362e+01; /* 0xC03670E2, 0x42712D62 */
176
177static double erfc1(double x)
178{
179 double_t s,P,Q;
180
181 s = fabs(x) - 1;
182 P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
183 Q = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
184 return 1 - erx - P/Q;
185}
186
187static double erfc2(uint32_t ix, double x)
188{
189 double_t s,R,S;
190 double z;
191
192 if (ix < 0x3ff40000) /* |x| < 1.25 */
193 return erfc1(x);
194
195 x = fabs(x);
196 s = 1/(x*x);
197 if (ix < 0x4006db6d) { /* |x| < 1/.35 ~ 2.85714 */
198 R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
199 ra5+s*(ra6+s*ra7))))));
200 S = 1.0+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
201 sa5+s*(sa6+s*(sa7+s*sa8)))))));
202 } else { /* |x| > 1/.35 */
203 R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
204 rb5+s*rb6)))));
205 S = 1.0+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
206 sb5+s*(sb6+s*sb7))))));
207 }
208 z = x;
209 SET_LOW_WORD(z,0);
210 return exp(-z*z-0.5625)*exp((z-x)*(z+x)+R/S)/x;
211}
212
213double erf(double x)
214{
215 double r,s,z,y;
216 uint32_t ix;
217 int sign;
218
219 GET_HIGH_WORD(ix, x);
220 sign = ix>>31;
221 ix &= 0x7fffffff;
222 if (ix >= 0x7ff00000) {
223 /* erf(nan)=nan, erf(+-inf)=+-1 */
224 return 1-2*sign + 1/x;
225 }
226 if (ix < 0x3feb0000) { /* |x| < 0.84375 */
227 if (ix < 0x3e300000) { /* |x| < 2**-28 */
228 /* avoid underflow */
229 return 0.125*(8*x + efx8*x);
230 }
231 z = x*x;
232 r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
233 s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
234 y = r/s;
235 return x + x*y;
236 }
237 if (ix < 0x40180000) /* 0.84375 <= |x| < 6 */
238 y = 1 - erfc2(ix,x);
239 else
240 y = 1 - 0x1p-1022;
241 return sign ? -y : y;
242}
243
244double erfc(double x)
245{
246 double r,s,z,y;
247 uint32_t ix;
248 int sign;
249
250 GET_HIGH_WORD(ix, x);
251 sign = ix>>31;
252 ix &= 0x7fffffff;
253 if (ix >= 0x7ff00000) {
254 /* erfc(nan)=nan, erfc(+-inf)=0,2 */
255 return 2*sign + 1/x;
256 }
257 if (ix < 0x3feb0000) { /* |x| < 0.84375 */
258 if (ix < 0x3c700000) /* |x| < 2**-56 */
259 return 1.0 - x;
260 z = x*x;
261 r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
262 s = 1.0+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
263 y = r/s;
264 if (sign || ix < 0x3fd00000) { /* x < 1/4 */
265 return 1.0 - (x+x*y);
266 }
267 return 0.5 - (x - 0.5 + x*y);
268 }
269 if (ix < 0x403c0000) { /* 0.84375 <= |x| < 28 */
270 return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
271 }
272 return sign ? 2 - 0x1p-1022 : 0x1p-1022*0x1p-1022;
273}
libc/musl/src/math/erff.c created+183
......@@ -0,0 +1,183 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_erff.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include "libm.h"
17
18static const float
19erx = 8.4506291151e-01, /* 0x3f58560b */
20/*
21 * Coefficients for approximation to erf on [0,0.84375]
22 */
23efx8 = 1.0270333290e+00, /* 0x3f8375d4 */
24pp0 = 1.2837916613e-01, /* 0x3e0375d4 */
25pp1 = -3.2504209876e-01, /* 0xbea66beb */
26pp2 = -2.8481749818e-02, /* 0xbce9528f */
27pp3 = -5.7702702470e-03, /* 0xbbbd1489 */
28pp4 = -2.3763017452e-05, /* 0xb7c756b1 */
29qq1 = 3.9791721106e-01, /* 0x3ecbbbce */
30qq2 = 6.5022252500e-02, /* 0x3d852a63 */
31qq3 = 5.0813062117e-03, /* 0x3ba68116 */
32qq4 = 1.3249473704e-04, /* 0x390aee49 */
33qq5 = -3.9602282413e-06, /* 0xb684e21a */
34/*
35 * Coefficients for approximation to erf in [0.84375,1.25]
36 */
37pa0 = -2.3621185683e-03, /* 0xbb1acdc6 */
38pa1 = 4.1485610604e-01, /* 0x3ed46805 */
39pa2 = -3.7220788002e-01, /* 0xbebe9208 */
40pa3 = 3.1834661961e-01, /* 0x3ea2fe54 */
41pa4 = -1.1089469492e-01, /* 0xbde31cc2 */
42pa5 = 3.5478305072e-02, /* 0x3d1151b3 */
43pa6 = -2.1663755178e-03, /* 0xbb0df9c0 */
44qa1 = 1.0642088205e-01, /* 0x3dd9f331 */
45qa2 = 5.4039794207e-01, /* 0x3f0a5785 */
46qa3 = 7.1828655899e-02, /* 0x3d931ae7 */
47qa4 = 1.2617121637e-01, /* 0x3e013307 */
48qa5 = 1.3637083583e-02, /* 0x3c5f6e13 */
49qa6 = 1.1984500103e-02, /* 0x3c445aa3 */
50/*
51 * Coefficients for approximation to erfc in [1.25,1/0.35]
52 */
53ra0 = -9.8649440333e-03, /* 0xbc21a093 */
54ra1 = -6.9385856390e-01, /* 0xbf31a0b7 */
55ra2 = -1.0558626175e+01, /* 0xc128f022 */
56ra3 = -6.2375331879e+01, /* 0xc2798057 */
57ra4 = -1.6239666748e+02, /* 0xc322658c */
58ra5 = -1.8460508728e+02, /* 0xc3389ae7 */
59ra6 = -8.1287437439e+01, /* 0xc2a2932b */
60ra7 = -9.8143291473e+00, /* 0xc11d077e */
61sa1 = 1.9651271820e+01, /* 0x419d35ce */
62sa2 = 1.3765776062e+02, /* 0x4309a863 */
63sa3 = 4.3456588745e+02, /* 0x43d9486f */
64sa4 = 6.4538726807e+02, /* 0x442158c9 */
65sa5 = 4.2900814819e+02, /* 0x43d6810b */
66sa6 = 1.0863500214e+02, /* 0x42d9451f */
67sa7 = 6.5702495575e+00, /* 0x40d23f7c */
68sa8 = -6.0424413532e-02, /* 0xbd777f97 */
69/*
70 * Coefficients for approximation to erfc in [1/.35,28]
71 */
72rb0 = -9.8649431020e-03, /* 0xbc21a092 */
73rb1 = -7.9928326607e-01, /* 0xbf4c9dd4 */
74rb2 = -1.7757955551e+01, /* 0xc18e104b */
75rb3 = -1.6063638306e+02, /* 0xc320a2ea */
76rb4 = -6.3756646729e+02, /* 0xc41f6441 */
77rb5 = -1.0250950928e+03, /* 0xc480230b */
78rb6 = -4.8351919556e+02, /* 0xc3f1c275 */
79sb1 = 3.0338060379e+01, /* 0x41f2b459 */
80sb2 = 3.2579251099e+02, /* 0x43a2e571 */
81sb3 = 1.5367296143e+03, /* 0x44c01759 */
82sb4 = 3.1998581543e+03, /* 0x4547fdbb */
83sb5 = 2.5530502930e+03, /* 0x451f90ce */
84sb6 = 4.7452853394e+02, /* 0x43ed43a7 */
85sb7 = -2.2440952301e+01; /* 0xc1b38712 */
86
87static float erfc1(float x)
88{
89 float_t s,P,Q;
90
91 s = fabsf(x) - 1;
92 P = pa0+s*(pa1+s*(pa2+s*(pa3+s*(pa4+s*(pa5+s*pa6)))));
93 Q = 1+s*(qa1+s*(qa2+s*(qa3+s*(qa4+s*(qa5+s*qa6)))));
94 return 1 - erx - P/Q;
95}
96
97static float erfc2(uint32_t ix, float x)
98{
99 float_t s,R,S;
100 float z;
101
102 if (ix < 0x3fa00000) /* |x| < 1.25 */
103 return erfc1(x);
104
105 x = fabsf(x);
106 s = 1/(x*x);
107 if (ix < 0x4036db6d) { /* |x| < 1/0.35 */
108 R = ra0+s*(ra1+s*(ra2+s*(ra3+s*(ra4+s*(
109 ra5+s*(ra6+s*ra7))))));
110 S = 1.0f+s*(sa1+s*(sa2+s*(sa3+s*(sa4+s*(
111 sa5+s*(sa6+s*(sa7+s*sa8)))))));
112 } else { /* |x| >= 1/0.35 */
113 R = rb0+s*(rb1+s*(rb2+s*(rb3+s*(rb4+s*(
114 rb5+s*rb6)))));
115 S = 1.0f+s*(sb1+s*(sb2+s*(sb3+s*(sb4+s*(
116 sb5+s*(sb6+s*sb7))))));
117 }
118 GET_FLOAT_WORD(ix, x);
119 SET_FLOAT_WORD(z, ix&0xffffe000);
120 return expf(-z*z - 0.5625f) * expf((z-x)*(z+x) + R/S)/x;
121}
122
123float erff(float x)
124{
125 float r,s,z,y;
126 uint32_t ix;
127 int sign;
128
129 GET_FLOAT_WORD(ix, x);
130 sign = ix>>31;
131 ix &= 0x7fffffff;
132 if (ix >= 0x7f800000) {
133 /* erf(nan)=nan, erf(+-inf)=+-1 */
134 return 1-2*sign + 1/x;
135 }
136 if (ix < 0x3f580000) { /* |x| < 0.84375 */
137 if (ix < 0x31800000) { /* |x| < 2**-28 */
138 /*avoid underflow */
139 return 0.125f*(8*x + efx8*x);
140 }
141 z = x*x;
142 r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
143 s = 1+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
144 y = r/s;
145 return x + x*y;
146 }
147 if (ix < 0x40c00000) /* |x| < 6 */
148 y = 1 - erfc2(ix,x);
149 else
150 y = 1 - 0x1p-120f;
151 return sign ? -y : y;
152}
153
154float erfcf(float x)
155{
156 float r,s,z,y;
157 uint32_t ix;
158 int sign;
159
160 GET_FLOAT_WORD(ix, x);
161 sign = ix>>31;
162 ix &= 0x7fffffff;
163 if (ix >= 0x7f800000) {
164 /* erfc(nan)=nan, erfc(+-inf)=0,2 */
165 return 2*sign + 1/x;
166 }
167
168 if (ix < 0x3f580000) { /* |x| < 0.84375 */
169 if (ix < 0x23800000) /* |x| < 2**-56 */
170 return 1.0f - x;
171 z = x*x;
172 r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
173 s = 1.0f+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
174 y = r/s;
175 if (sign || ix < 0x3e800000) /* x < 1/4 */
176 return 1.0f - (x+x*y);
177 return 0.5f - (x - 0.5f + x*y);
178 }
179 if (ix < 0x41e00000) { /* |x| < 28 */
180 return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
181 }
182 return sign ? 2 - 0x1p-120f : 0x1p-120f*0x1p-120f;
183}
libc/musl/src/math/erfl.c created+353
......@@ -0,0 +1,353 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_erfl.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
14 *
15 * Permission to use, copy, modify, and distribute this software for any
16 * purpose with or without fee is hereby granted, provided that the above
17 * copyright notice and this permission notice appear in all copies.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
20 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
22 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
24 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
25 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 */
27/* double erf(double x)
28 * double erfc(double x)
29 * x
30 * 2 |\
31 * erf(x) = --------- | exp(-t*t)dt
32 * sqrt(pi) \|
33 * 0
34 *
35 * erfc(x) = 1-erf(x)
36 * Note that
37 * erf(-x) = -erf(x)
38 * erfc(-x) = 2 - erfc(x)
39 *
40 * Method:
41 * 1. For |x| in [0, 0.84375]
42 * erf(x) = x + x*R(x^2)
43 * erfc(x) = 1 - erf(x) if x in [-.84375,0.25]
44 * = 0.5 + ((0.5-x)-x*R) if x in [0.25,0.84375]
45 * Remark. The formula is derived by noting
46 * erf(x) = (2/sqrt(pi))*(x - x^3/3 + x^5/10 - x^7/42 + ....)
47 * and that
48 * 2/sqrt(pi) = 1.128379167095512573896158903121545171688
49 * is close to one. The interval is chosen because the fix
50 * point of erf(x) is near 0.6174 (i.e., erf(x)=x when x is
51 * near 0.6174), and by some experiment, 0.84375 is chosen to
52 * guarantee the error is less than one ulp for erf.
53 *
54 * 2. For |x| in [0.84375,1.25], let s = |x| - 1, and
55 * c = 0.84506291151 rounded to single (24 bits)
56 * erf(x) = sign(x) * (c + P1(s)/Q1(s))
57 * erfc(x) = (1-c) - P1(s)/Q1(s) if x > 0
58 * 1+(c+P1(s)/Q1(s)) if x < 0
59 * Remark: here we use the taylor series expansion at x=1.
60 * erf(1+s) = erf(1) + s*Poly(s)
61 * = 0.845.. + P1(s)/Q1(s)
62 * Note that |P1/Q1|< 0.078 for x in [0.84375,1.25]
63 *
64 * 3. For x in [1.25,1/0.35(~2.857143)],
65 * erfc(x) = (1/x)*exp(-x*x-0.5625+R1(z)/S1(z))
66 * z=1/x^2
67 * erf(x) = 1 - erfc(x)
68 *
69 * 4. For x in [1/0.35,107]
70 * erfc(x) = (1/x)*exp(-x*x-0.5625+R2/S2) if x > 0
71 * = 2.0 - (1/x)*exp(-x*x-0.5625+R2(z)/S2(z))
72 * if -6.666<x<0
73 * = 2.0 - tiny (if x <= -6.666)
74 * z=1/x^2
75 * erf(x) = sign(x)*(1.0 - erfc(x)) if x < 6.666, else
76 * erf(x) = sign(x)*(1.0 - tiny)
77 * Note1:
78 * To compute exp(-x*x-0.5625+R/S), let s be a single
79 * precision number and s := x; then
80 * -x*x = -s*s + (s-x)*(s+x)
81 * exp(-x*x-0.5626+R/S) =
82 * exp(-s*s-0.5625)*exp((s-x)*(s+x)+R/S);
83 * Note2:
84 * Here 4 and 5 make use of the asymptotic series
85 * exp(-x*x)
86 * erfc(x) ~ ---------- * ( 1 + Poly(1/x^2) )
87 * x*sqrt(pi)
88 *
89 * 5. For inf > x >= 107
90 * erf(x) = sign(x) *(1 - tiny) (raise inexact)
91 * erfc(x) = tiny*tiny (raise underflow) if x > 0
92 * = 2 - tiny if x<0
93 *
94 * 7. Special case:
95 * erf(0) = 0, erf(inf) = 1, erf(-inf) = -1,
96 * erfc(0) = 1, erfc(inf) = 0, erfc(-inf) = 2,
97 * erfc/erf(NaN) is NaN
98 */
99
100
101#include "libm.h"
102
103#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
104long double erfl(long double x)
105{
106 return erf(x);
107}
108long double erfcl(long double x)
109{
110 return erfc(x);
111}
112#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
113static const long double
114erx = 0.845062911510467529296875L,
115
116/*
117 * Coefficients for approximation to erf on [0,0.84375]
118 */
119/* 8 * (2/sqrt(pi) - 1) */
120efx8 = 1.0270333367641005911692712249723613735048E0L,
121pp[6] = {
122 1.122751350964552113068262337278335028553E6L,
123 -2.808533301997696164408397079650699163276E6L,
124 -3.314325479115357458197119660818768924100E5L,
125 -6.848684465326256109712135497895525446398E4L,
126 -2.657817695110739185591505062971929859314E3L,
127 -1.655310302737837556654146291646499062882E2L,
128},
129qq[6] = {
130 8.745588372054466262548908189000448124232E6L,
131 3.746038264792471129367533128637019611485E6L,
132 7.066358783162407559861156173539693900031E5L,
133 7.448928604824620999413120955705448117056E4L,
134 4.511583986730994111992253980546131408924E3L,
135 1.368902937933296323345610240009071254014E2L,
136 /* 1.000000000000000000000000000000000000000E0 */
137},
138
139/*
140 * Coefficients for approximation to erf in [0.84375,1.25]
141 */
142/* erf(x+1) = 0.845062911510467529296875 + pa(x)/qa(x)
143 -0.15625 <= x <= +.25
144 Peak relative error 8.5e-22 */
145pa[8] = {
146 -1.076952146179812072156734957705102256059E0L,
147 1.884814957770385593365179835059971587220E2L,
148 -5.339153975012804282890066622962070115606E1L,
149 4.435910679869176625928504532109635632618E1L,
150 1.683219516032328828278557309642929135179E1L,
151 -2.360236618396952560064259585299045804293E0L,
152 1.852230047861891953244413872297940938041E0L,
153 9.394994446747752308256773044667843200719E-2L,
154},
155qa[7] = {
156 4.559263722294508998149925774781887811255E2L,
157 3.289248982200800575749795055149780689738E2L,
158 2.846070965875643009598627918383314457912E2L,
159 1.398715859064535039433275722017479994465E2L,
160 6.060190733759793706299079050985358190726E1L,
161 2.078695677795422351040502569964299664233E1L,
162 4.641271134150895940966798357442234498546E0L,
163 /* 1.000000000000000000000000000000000000000E0 */
164},
165
166/*
167 * Coefficients for approximation to erfc in [1.25,1/0.35]
168 */
169/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + ra(x^2)/sa(x^2))
170 1/2.85711669921875 < 1/x < 1/1.25
171 Peak relative error 3.1e-21 */
172ra[] = {
173 1.363566591833846324191000679620738857234E-1L,
174 1.018203167219873573808450274314658434507E1L,
175 1.862359362334248675526472871224778045594E2L,
176 1.411622588180721285284945138667933330348E3L,
177 5.088538459741511988784440103218342840478E3L,
178 8.928251553922176506858267311750789273656E3L,
179 7.264436000148052545243018622742770549982E3L,
180 2.387492459664548651671894725748959751119E3L,
181 2.220916652813908085449221282808458466556E2L,
182},
183sa[] = {
184 -1.382234625202480685182526402169222331847E1L,
185 -3.315638835627950255832519203687435946482E2L,
186 -2.949124863912936259747237164260785326692E3L,
187 -1.246622099070875940506391433635999693661E4L,
188 -2.673079795851665428695842853070996219632E4L,
189 -2.880269786660559337358397106518918220991E4L,
190 -1.450600228493968044773354186390390823713E4L,
191 -2.874539731125893533960680525192064277816E3L,
192 -1.402241261419067750237395034116942296027E2L,
193 /* 1.000000000000000000000000000000000000000E0 */
194},
195
196/*
197 * Coefficients for approximation to erfc in [1/.35,107]
198 */
199/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rb(x^2)/sb(x^2))
200 1/6.6666259765625 < 1/x < 1/2.85711669921875
201 Peak relative error 4.2e-22 */
202rb[] = {
203 -4.869587348270494309550558460786501252369E-5L,
204 -4.030199390527997378549161722412466959403E-3L,
205 -9.434425866377037610206443566288917589122E-2L,
206 -9.319032754357658601200655161585539404155E-1L,
207 -4.273788174307459947350256581445442062291E0L,
208 -8.842289940696150508373541814064198259278E0L,
209 -7.069215249419887403187988144752613025255E0L,
210 -1.401228723639514787920274427443330704764E0L,
211},
212sb[] = {
213 4.936254964107175160157544545879293019085E-3L,
214 1.583457624037795744377163924895349412015E-1L,
215 1.850647991850328356622940552450636420484E0L,
216 9.927611557279019463768050710008450625415E0L,
217 2.531667257649436709617165336779212114570E1L,
218 2.869752886406743386458304052862814690045E1L,
219 1.182059497870819562441683560749192539345E1L,
220 /* 1.000000000000000000000000000000000000000E0 */
221},
222/* erfc(1/x) = x exp (-1/x^2 - 0.5625 + rc(x^2)/sc(x^2))
223 1/107 <= 1/x <= 1/6.6666259765625
224 Peak relative error 1.1e-21 */
225rc[] = {
226 -8.299617545269701963973537248996670806850E-5L,
227 -6.243845685115818513578933902532056244108E-3L,
228 -1.141667210620380223113693474478394397230E-1L,
229 -7.521343797212024245375240432734425789409E-1L,
230 -1.765321928311155824664963633786967602934E0L,
231 -1.029403473103215800456761180695263439188E0L,
232},
233sc[] = {
234 8.413244363014929493035952542677768808601E-3L,
235 2.065114333816877479753334599639158060979E-1L,
236 1.639064941530797583766364412782135680148E0L,
237 4.936788463787115555582319302981666347450E0L,
238 5.005177727208955487404729933261347679090E0L,
239 /* 1.000000000000000000000000000000000000000E0 */
240};
241
242static long double erfc1(long double x)
243{
244 long double s,P,Q;
245
246 s = fabsl(x) - 1;
247 P = pa[0] + s * (pa[1] + s * (pa[2] +
248 s * (pa[3] + s * (pa[4] + s * (pa[5] + s * (pa[6] + s * pa[7]))))));
249 Q = qa[0] + s * (qa[1] + s * (qa[2] +
250 s * (qa[3] + s * (qa[4] + s * (qa[5] + s * (qa[6] + s))))));
251 return 1 - erx - P / Q;
252}
253
254static long double erfc2(uint32_t ix, long double x)
255{
256 union ldshape u;
257 long double s,z,R,S;
258
259 if (ix < 0x3fffa000) /* 0.84375 <= |x| < 1.25 */
260 return erfc1(x);
261
262 x = fabsl(x);
263 s = 1 / (x * x);
264 if (ix < 0x4000b6db) { /* 1.25 <= |x| < 2.857 ~ 1/.35 */
265 R = ra[0] + s * (ra[1] + s * (ra[2] + s * (ra[3] + s * (ra[4] +
266 s * (ra[5] + s * (ra[6] + s * (ra[7] + s * ra[8])))))));
267 S = sa[0] + s * (sa[1] + s * (sa[2] + s * (sa[3] + s * (sa[4] +
268 s * (sa[5] + s * (sa[6] + s * (sa[7] + s * (sa[8] + s))))))));
269 } else if (ix < 0x4001d555) { /* 2.857 <= |x| < 6.6666259765625 */
270 R = rb[0] + s * (rb[1] + s * (rb[2] + s * (rb[3] + s * (rb[4] +
271 s * (rb[5] + s * (rb[6] + s * rb[7]))))));
272 S = sb[0] + s * (sb[1] + s * (sb[2] + s * (sb[3] + s * (sb[4] +
273 s * (sb[5] + s * (sb[6] + s))))));
274 } else { /* 6.666 <= |x| < 107 (erfc only) */
275 R = rc[0] + s * (rc[1] + s * (rc[2] + s * (rc[3] +
276 s * (rc[4] + s * rc[5]))));
277 S = sc[0] + s * (sc[1] + s * (sc[2] + s * (sc[3] +
278 s * (sc[4] + s))));
279 }
280 u.f = x;
281 u.i.m &= -1ULL << 40;
282 z = u.f;
283 return expl(-z*z - 0.5625) * expl((z - x) * (z + x) + R / S) / x;
284}
285
286long double erfl(long double x)
287{
288 long double r, s, z, y;
289 union ldshape u = {x};
290 uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
291 int sign = u.i.se >> 15;
292
293 if (ix >= 0x7fff0000)
294 /* erf(nan)=nan, erf(+-inf)=+-1 */
295 return 1 - 2*sign + 1/x;
296 if (ix < 0x3ffed800) { /* |x| < 0.84375 */
297 if (ix < 0x3fde8000) { /* |x| < 2**-33 */
298 return 0.125 * (8 * x + efx8 * x); /* avoid underflow */
299 }
300 z = x * x;
301 r = pp[0] + z * (pp[1] +
302 z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));
303 s = qq[0] + z * (qq[1] +
304 z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));
305 y = r / s;
306 return x + x * y;
307 }
308 if (ix < 0x4001d555) /* |x| < 6.6666259765625 */
309 y = 1 - erfc2(ix,x);
310 else
311 y = 1 - 0x1p-16382L;
312 return sign ? -y : y;
313}
314
315long double erfcl(long double x)
316{
317 long double r, s, z, y;
318 union ldshape u = {x};
319 uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
320 int sign = u.i.se >> 15;
321
322 if (ix >= 0x7fff0000)
323 /* erfc(nan) = nan, erfc(+-inf) = 0,2 */
324 return 2*sign + 1/x;
325 if (ix < 0x3ffed800) { /* |x| < 0.84375 */
326 if (ix < 0x3fbe0000) /* |x| < 2**-65 */
327 return 1.0 - x;
328 z = x * x;
329 r = pp[0] + z * (pp[1] +
330 z * (pp[2] + z * (pp[3] + z * (pp[4] + z * pp[5]))));
331 s = qq[0] + z * (qq[1] +
332 z * (qq[2] + z * (qq[3] + z * (qq[4] + z * (qq[5] + z)))));
333 y = r / s;
334 if (ix < 0x3ffd8000) /* x < 1/4 */
335 return 1.0 - (x + x * y);
336 return 0.5 - (x - 0.5 + x * y);
337 }
338 if (ix < 0x4005d600) /* |x| < 107 */
339 return sign ? 2 - erfc2(ix,x) : erfc2(ix,x);
340 y = 0x1p-16382L;
341 return sign ? 2 - y : y*y;
342}
343#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
344// TODO: broken implementation to make things compile
345long double erfl(long double x)
346{
347 return erf(x);
348}
349long double erfcl(long double x)
350{
351 return erfc(x);
352}
353#endif
libc/musl/src/math/exp.c created+134
......@@ -0,0 +1,134 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_exp.c */
2/*
3 * ====================================================
4 * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Permission to use, copy, modify, and distribute this
7 * software is freely granted, provided that this notice
8 * is preserved.
9 * ====================================================
10 */
11/* exp(x)
12 * Returns the exponential of x.
13 *
14 * Method
15 * 1. Argument reduction:
16 * Reduce x to an r so that |r| <= 0.5*ln2 ~ 0.34658.
17 * Given x, find r and integer k such that
18 *
19 * x = k*ln2 + r, |r| <= 0.5*ln2.
20 *
21 * Here r will be represented as r = hi-lo for better
22 * accuracy.
23 *
24 * 2. Approximation of exp(r) by a special rational function on
25 * the interval [0,0.34658]:
26 * Write
27 * R(r**2) = r*(exp(r)+1)/(exp(r)-1) = 2 + r*r/6 - r**4/360 + ...
28 * We use a special Remez algorithm on [0,0.34658] to generate
29 * a polynomial of degree 5 to approximate R. The maximum error
30 * of this polynomial approximation is bounded by 2**-59. In
31 * other words,
32 * R(z) ~ 2.0 + P1*z + P2*z**2 + P3*z**3 + P4*z**4 + P5*z**5
33 * (where z=r*r, and the values of P1 to P5 are listed below)
34 * and
35 * | 5 | -59
36 * | 2.0+P1*z+...+P5*z - R(z) | <= 2
37 * | |
38 * The computation of exp(r) thus becomes
39 * 2*r
40 * exp(r) = 1 + ----------
41 * R(r) - r
42 * r*c(r)
43 * = 1 + r + ----------- (for better accuracy)
44 * 2 - c(r)
45 * where
46 * 2 4 10
47 * c(r) = r - (P1*r + P2*r + ... + P5*r ).
48 *
49 * 3. Scale back to obtain exp(x):
50 * From step 1, we have
51 * exp(x) = 2^k * exp(r)
52 *
53 * Special cases:
54 * exp(INF) is INF, exp(NaN) is NaN;
55 * exp(-INF) is 0, and
56 * for finite argument, only exp(0)=1 is exact.
57 *
58 * Accuracy:
59 * according to an error analysis, the error is always less than
60 * 1 ulp (unit in the last place).
61 *
62 * Misc. info.
63 * For IEEE double
64 * if x > 709.782712893383973096 then exp(x) overflows
65 * if x < -745.133219101941108420 then exp(x) underflows
66 */
67
68#include "libm.h"
69
70static const double
71half[2] = {0.5,-0.5},
72ln2hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
73ln2lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
74invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
75P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
76P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
77P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
78P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
79P5 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
80
81double exp(double x)
82{
83 double_t hi, lo, c, xx, y;
84 int k, sign;
85 uint32_t hx;
86
87 GET_HIGH_WORD(hx, x);
88 sign = hx>>31;
89 hx &= 0x7fffffff; /* high word of |x| */
90
91 /* special cases */
92 if (hx >= 0x4086232b) { /* if |x| >= 708.39... */
93 if (isnan(x))
94 return x;
95 if (x > 709.782712893383973096) {
96 /* overflow if x!=inf */
97 x *= 0x1p1023;
98 return x;
99 }
100 if (x < -708.39641853226410622) {
101 /* underflow if x!=-inf */
102 FORCE_EVAL((float)(-0x1p-149/x));
103 if (x < -745.13321910194110842)
104 return 0;
105 }
106 }
107
108 /* argument reduction */
109 if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
110 if (hx >= 0x3ff0a2b2) /* if |x| >= 1.5 ln2 */
111 k = (int)(invln2*x + half[sign]);
112 else
113 k = 1 - sign - sign;
114 hi = x - k*ln2hi; /* k*ln2hi is exact here */
115 lo = k*ln2lo;
116 x = hi - lo;
117 } else if (hx > 0x3e300000) { /* if |x| > 2**-28 */
118 k = 0;
119 hi = x;
120 lo = 0;
121 } else {
122 /* inexact if x!=0 */
123 FORCE_EVAL(0x1p1023 + x);
124 return 1 + x;
125 }
126
127 /* x is now in primary range */
128 xx = x*x;
129 c = x - xx*(P1+xx*(P2+xx*(P3+xx*(P4+xx*P5))));
130 y = 1 + (x*c/(2-c) - lo + hi);
131 if (k == 0)
132 return y;
133 return scalbn(y, k);
134}
libc/musl/src/math/exp10.c created+24
......@@ -0,0 +1,24 @@
1#define _GNU_SOURCE
2#include <math.h>
3#include <stdint.h>
4
5double exp10(double x)
6{
7 static const double p10[] = {
8 1e-15, 1e-14, 1e-13, 1e-12, 1e-11, 1e-10,
9 1e-9, 1e-8, 1e-7, 1e-6, 1e-5, 1e-4, 1e-3, 1e-2, 1e-1,
10 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
11 1e10, 1e11, 1e12, 1e13, 1e14, 1e15
12 };
13 double n, y = modf(x, &n);
14 union {double f; uint64_t i;} u = {n};
15 /* fabs(n) < 16 without raising invalid on nan */
16 if ((u.i>>52 & 0x7ff) < 0x3ff+4) {
17 if (!y) return p10[(int)n+15];
18 y = exp2(3.32192809488736234787031942948939 * y);
19 return y * p10[(int)n+15];
20 }
21 return pow(10.0, x);
22}
23
24weak_alias(exp10, pow10);
libc/musl/src/math/exp10f.c created+22
......@@ -0,0 +1,22 @@
1#define _GNU_SOURCE
2#include <math.h>
3#include <stdint.h>
4
5float exp10f(float x)
6{
7 static const float p10[] = {
8 1e-7f, 1e-6f, 1e-5f, 1e-4f, 1e-3f, 1e-2f, 1e-1f,
9 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7
10 };
11 float n, y = modff(x, &n);
12 union {float f; uint32_t i;} u = {n};
13 /* fabsf(n) < 8 without raising invalid on nan */
14 if ((u.i>>23 & 0xff) < 0x7f+3) {
15 if (!y) return p10[(int)n+7];
16 y = exp2f(3.32192809488736234787031942948939f * y);
17 return y * p10[(int)n+7];
18 }
19 return exp2(3.32192809488736234787031942948939 * x);
20}
21
22weak_alias(exp10f, pow10f);
libc/musl/src/math/exp10l.c created+32
......@@ -0,0 +1,32 @@
1#define _GNU_SOURCE
2#include <float.h>
3#include <math.h>
4#include "libm.h"
5
6#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
7long double exp10l(long double x)
8{
9 return exp10(x);
10}
11#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
12long double exp10l(long double x)
13{
14 static const long double p10[] = {
15 1e-15L, 1e-14L, 1e-13L, 1e-12L, 1e-11L, 1e-10L,
16 1e-9L, 1e-8L, 1e-7L, 1e-6L, 1e-5L, 1e-4L, 1e-3L, 1e-2L, 1e-1L,
17 1, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9,
18 1e10, 1e11, 1e12, 1e13, 1e14, 1e15
19 };
20 long double n, y = modfl(x, &n);
21 union ldshape u = {n};
22 /* fabsl(n) < 16 without raising invalid on nan */
23 if ((u.i.se & 0x7fff) < 0x3fff+4) {
24 if (!y) return p10[(int)n+15];
25 y = exp2l(3.32192809488736234787031942948939L * y);
26 return y * p10[(int)n+15];
27 }
28 return powl(10.0, x);
29}
30#endif
31
32weak_alias(exp10l, pow10l);
libc/musl/src/math/exp2.c created+375
......@@ -0,0 +1,375 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_exp2.c */
2/*-
3 * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "libm.h"
29
30#define TBLSIZE 256
31
32static const double
33redux = 0x1.8p52 / TBLSIZE,
34P1 = 0x1.62e42fefa39efp-1,
35P2 = 0x1.ebfbdff82c575p-3,
36P3 = 0x1.c6b08d704a0a6p-5,
37P4 = 0x1.3b2ab88f70400p-7,
38P5 = 0x1.5d88003875c74p-10;
39
40static const double tbl[TBLSIZE * 2] = {
41/* exp2(z + eps) eps */
42 0x1.6a09e667f3d5dp-1, 0x1.9880p-44,
43 0x1.6b052fa751744p-1, 0x1.8000p-50,
44 0x1.6c012750bd9fep-1, -0x1.8780p-45,
45 0x1.6cfdcddd476bfp-1, 0x1.ec00p-46,
46 0x1.6dfb23c651a29p-1, -0x1.8000p-50,
47 0x1.6ef9298593ae3p-1, -0x1.c000p-52,
48 0x1.6ff7df9519386p-1, -0x1.fd80p-45,
49 0x1.70f7466f42da3p-1, -0x1.c880p-45,
50 0x1.71f75e8ec5fc3p-1, 0x1.3c00p-46,
51 0x1.72f8286eacf05p-1, -0x1.8300p-44,
52 0x1.73f9a48a58152p-1, -0x1.0c00p-47,
53 0x1.74fbd35d7ccfcp-1, 0x1.f880p-45,
54 0x1.75feb564267f1p-1, 0x1.3e00p-47,
55 0x1.77024b1ab6d48p-1, -0x1.7d00p-45,
56 0x1.780694fde5d38p-1, -0x1.d000p-50,
57 0x1.790b938ac1d00p-1, 0x1.3000p-49,
58 0x1.7a11473eb0178p-1, -0x1.d000p-49,
59 0x1.7b17b0976d060p-1, 0x1.0400p-45,
60 0x1.7c1ed0130c133p-1, 0x1.0000p-53,
61 0x1.7d26a62ff8636p-1, -0x1.6900p-45,
62 0x1.7e2f336cf4e3bp-1, -0x1.2e00p-47,
63 0x1.7f3878491c3e8p-1, -0x1.4580p-45,
64 0x1.80427543e1b4ep-1, 0x1.3000p-44,
65 0x1.814d2add1071ap-1, 0x1.f000p-47,
66 0x1.82589994ccd7ep-1, -0x1.1c00p-45,
67 0x1.8364c1eb942d0p-1, 0x1.9d00p-45,
68 0x1.8471a4623cab5p-1, 0x1.7100p-43,
69 0x1.857f4179f5bbcp-1, 0x1.2600p-45,
70 0x1.868d99b4491afp-1, -0x1.2c40p-44,
71 0x1.879cad931a395p-1, -0x1.3000p-45,
72 0x1.88ac7d98a65b8p-1, -0x1.a800p-45,
73 0x1.89bd0a4785800p-1, -0x1.d000p-49,
74 0x1.8ace5422aa223p-1, 0x1.3280p-44,
75 0x1.8be05bad619fap-1, 0x1.2b40p-43,
76 0x1.8cf3216b54383p-1, -0x1.ed00p-45,
77 0x1.8e06a5e08664cp-1, -0x1.0500p-45,
78 0x1.8f1ae99157807p-1, 0x1.8280p-45,
79 0x1.902fed0282c0ep-1, -0x1.cb00p-46,
80 0x1.9145b0b91ff96p-1, -0x1.5e00p-47,
81 0x1.925c353aa2ff9p-1, 0x1.5400p-48,
82 0x1.93737b0cdc64ap-1, 0x1.7200p-46,
83 0x1.948b82b5f98aep-1, -0x1.9000p-47,
84 0x1.95a44cbc852cbp-1, 0x1.5680p-45,
85 0x1.96bdd9a766f21p-1, -0x1.6d00p-44,
86 0x1.97d829fde4e2ap-1, -0x1.1000p-47,
87 0x1.98f33e47a23a3p-1, 0x1.d000p-45,
88 0x1.9a0f170ca0604p-1, -0x1.8a40p-44,
89 0x1.9b2bb4d53ff89p-1, 0x1.55c0p-44,
90 0x1.9c49182a3f15bp-1, 0x1.6b80p-45,
91 0x1.9d674194bb8c5p-1, -0x1.c000p-49,
92 0x1.9e86319e3238ep-1, 0x1.7d00p-46,
93 0x1.9fa5e8d07f302p-1, 0x1.6400p-46,
94 0x1.a0c667b5de54dp-1, -0x1.5000p-48,
95 0x1.a1e7aed8eb8f6p-1, 0x1.9e00p-47,
96 0x1.a309bec4a2e27p-1, 0x1.ad80p-45,
97 0x1.a42c980460a5dp-1, -0x1.af00p-46,
98 0x1.a5503b23e259bp-1, 0x1.b600p-47,
99 0x1.a674a8af46213p-1, 0x1.8880p-44,
100 0x1.a799e1330b3a7p-1, 0x1.1200p-46,
101 0x1.a8bfe53c12e8dp-1, 0x1.6c00p-47,
102 0x1.a9e6b5579fcd2p-1, -0x1.9b80p-45,
103 0x1.ab0e521356fb8p-1, 0x1.b700p-45,
104 0x1.ac36bbfd3f381p-1, 0x1.9000p-50,
105 0x1.ad5ff3a3c2780p-1, 0x1.4000p-49,
106 0x1.ae89f995ad2a3p-1, -0x1.c900p-45,
107 0x1.afb4ce622f367p-1, 0x1.6500p-46,
108 0x1.b0e07298db790p-1, 0x1.fd40p-45,
109 0x1.b20ce6c9a89a9p-1, 0x1.2700p-46,
110 0x1.b33a2b84f1a4bp-1, 0x1.d470p-43,
111 0x1.b468415b747e7p-1, -0x1.8380p-44,
112 0x1.b59728de5593ap-1, 0x1.8000p-54,
113 0x1.b6c6e29f1c56ap-1, 0x1.ad00p-47,
114 0x1.b7f76f2fb5e50p-1, 0x1.e800p-50,
115 0x1.b928cf22749b2p-1, -0x1.4c00p-47,
116 0x1.ba5b030a10603p-1, -0x1.d700p-47,
117 0x1.bb8e0b79a6f66p-1, 0x1.d900p-47,
118 0x1.bcc1e904bc1ffp-1, 0x1.2a00p-47,
119 0x1.bdf69c3f3a16fp-1, -0x1.f780p-46,
120 0x1.bf2c25bd71db8p-1, -0x1.0a00p-46,
121 0x1.c06286141b2e9p-1, -0x1.1400p-46,
122 0x1.c199bdd8552e0p-1, 0x1.be00p-47,
123 0x1.c2d1cd9fa64eep-1, -0x1.9400p-47,
124 0x1.c40ab5fffd02fp-1, -0x1.ed00p-47,
125 0x1.c544778fafd15p-1, 0x1.9660p-44,
126 0x1.c67f12e57d0cbp-1, -0x1.a100p-46,
127 0x1.c7ba88988c1b6p-1, -0x1.8458p-42,
128 0x1.c8f6d9406e733p-1, -0x1.a480p-46,
129 0x1.ca3405751c4dfp-1, 0x1.b000p-51,
130 0x1.cb720dcef9094p-1, 0x1.1400p-47,
131 0x1.ccb0f2e6d1689p-1, 0x1.0200p-48,
132 0x1.cdf0b555dc412p-1, 0x1.3600p-48,
133 0x1.cf3155b5bab3bp-1, -0x1.6900p-47,
134 0x1.d072d4a0789bcp-1, 0x1.9a00p-47,
135 0x1.d1b532b08c8fap-1, -0x1.5e00p-46,
136 0x1.d2f87080d8a85p-1, 0x1.d280p-46,
137 0x1.d43c8eacaa203p-1, 0x1.1a00p-47,
138 0x1.d5818dcfba491p-1, 0x1.f000p-50,
139 0x1.d6c76e862e6a1p-1, -0x1.3a00p-47,
140 0x1.d80e316c9834ep-1, -0x1.cd80p-47,
141 0x1.d955d71ff6090p-1, 0x1.4c00p-48,
142 0x1.da9e603db32aep-1, 0x1.f900p-48,
143 0x1.dbe7cd63a8325p-1, 0x1.9800p-49,
144 0x1.dd321f301b445p-1, -0x1.5200p-48,
145 0x1.de7d5641c05bfp-1, -0x1.d700p-46,
146 0x1.dfc97337b9aecp-1, -0x1.6140p-46,
147 0x1.e11676b197d5ep-1, 0x1.b480p-47,
148 0x1.e264614f5a3e7p-1, 0x1.0ce0p-43,
149 0x1.e3b333b16ee5cp-1, 0x1.c680p-47,
150 0x1.e502ee78b3fb4p-1, -0x1.9300p-47,
151 0x1.e653924676d68p-1, -0x1.5000p-49,
152 0x1.e7a51fbc74c44p-1, -0x1.7f80p-47,
153 0x1.e8f7977cdb726p-1, -0x1.3700p-48,
154 0x1.ea4afa2a490e8p-1, 0x1.5d00p-49,
155 0x1.eb9f4867ccae4p-1, 0x1.61a0p-46,
156 0x1.ecf482d8e680dp-1, 0x1.5500p-48,
157 0x1.ee4aaa2188514p-1, 0x1.6400p-51,
158 0x1.efa1bee615a13p-1, -0x1.e800p-49,
159 0x1.f0f9c1cb64106p-1, -0x1.a880p-48,
160 0x1.f252b376bb963p-1, -0x1.c900p-45,
161 0x1.f3ac948dd7275p-1, 0x1.a000p-53,
162 0x1.f50765b6e4524p-1, -0x1.4f00p-48,
163 0x1.f6632798844fdp-1, 0x1.a800p-51,
164 0x1.f7bfdad9cbe38p-1, 0x1.abc0p-48,
165 0x1.f91d802243c82p-1, -0x1.4600p-50,
166 0x1.fa7c1819e908ep-1, -0x1.b0c0p-47,
167 0x1.fbdba3692d511p-1, -0x1.0e00p-51,
168 0x1.fd3c22b8f7194p-1, -0x1.0de8p-46,
169 0x1.fe9d96b2a23eep-1, 0x1.e430p-49,
170 0x1.0000000000000p+0, 0x0.0000p+0,
171 0x1.00b1afa5abcbep+0, -0x1.3400p-52,
172 0x1.0163da9fb3303p+0, -0x1.2170p-46,
173 0x1.02168143b0282p+0, 0x1.a400p-52,
174 0x1.02c9a3e77806cp+0, 0x1.f980p-49,
175 0x1.037d42e11bbcap+0, -0x1.7400p-51,
176 0x1.04315e86e7f89p+0, 0x1.8300p-50,
177 0x1.04e5f72f65467p+0, -0x1.a3f0p-46,
178 0x1.059b0d315855ap+0, -0x1.2840p-47,
179 0x1.0650a0e3c1f95p+0, 0x1.1600p-48,
180 0x1.0706b29ddf71ap+0, 0x1.5240p-46,
181 0x1.07bd42b72a82dp+0, -0x1.9a00p-49,
182 0x1.0874518759bd0p+0, 0x1.6400p-49,
183 0x1.092bdf66607c8p+0, -0x1.0780p-47,
184 0x1.09e3ecac6f383p+0, -0x1.8000p-54,
185 0x1.0a9c79b1f3930p+0, 0x1.fa00p-48,
186 0x1.0b5586cf988fcp+0, -0x1.ac80p-48,
187 0x1.0c0f145e46c8ap+0, 0x1.9c00p-50,
188 0x1.0cc922b724816p+0, 0x1.5200p-47,
189 0x1.0d83b23395dd8p+0, -0x1.ad00p-48,
190 0x1.0e3ec32d3d1f3p+0, 0x1.bac0p-46,
191 0x1.0efa55fdfa9a6p+0, -0x1.4e80p-47,
192 0x1.0fb66affed2f0p+0, -0x1.d300p-47,
193 0x1.1073028d7234bp+0, 0x1.1500p-48,
194 0x1.11301d0125b5bp+0, 0x1.c000p-49,
195 0x1.11edbab5e2af9p+0, 0x1.6bc0p-46,
196 0x1.12abdc06c31d5p+0, 0x1.8400p-49,
197 0x1.136a814f2047dp+0, -0x1.ed00p-47,
198 0x1.1429aaea92de9p+0, 0x1.8e00p-49,
199 0x1.14e95934f3138p+0, 0x1.b400p-49,
200 0x1.15a98c8a58e71p+0, 0x1.5300p-47,
201 0x1.166a45471c3dfp+0, 0x1.3380p-47,
202 0x1.172b83c7d5211p+0, 0x1.8d40p-45,
203 0x1.17ed48695bb9fp+0, -0x1.5d00p-47,
204 0x1.18af9388c8d93p+0, -0x1.c880p-46,
205 0x1.1972658375d66p+0, 0x1.1f00p-46,
206 0x1.1a35beb6fcba7p+0, 0x1.0480p-46,
207 0x1.1af99f81387e3p+0, -0x1.7390p-43,
208 0x1.1bbe084045d54p+0, 0x1.4e40p-45,
209 0x1.1c82f95281c43p+0, -0x1.a200p-47,
210 0x1.1d4873168b9b2p+0, 0x1.3800p-49,
211 0x1.1e0e75eb44031p+0, 0x1.ac00p-49,
212 0x1.1ed5022fcd938p+0, 0x1.1900p-47,
213 0x1.1f9c18438cdf7p+0, -0x1.b780p-46,
214 0x1.2063b88628d8fp+0, 0x1.d940p-45,
215 0x1.212be3578a81ep+0, 0x1.8000p-50,
216 0x1.21f49917ddd41p+0, 0x1.b340p-45,
217 0x1.22bdda2791323p+0, 0x1.9f80p-46,
218 0x1.2387a6e7561e7p+0, -0x1.9c80p-46,
219 0x1.2451ffb821427p+0, 0x1.2300p-47,
220 0x1.251ce4fb2a602p+0, -0x1.3480p-46,
221 0x1.25e85711eceb0p+0, 0x1.2700p-46,
222 0x1.26b4565e27d16p+0, 0x1.1d00p-46,
223 0x1.2780e341de00fp+0, 0x1.1ee0p-44,
224 0x1.284dfe1f5633ep+0, -0x1.4c00p-46,
225 0x1.291ba7591bb30p+0, -0x1.3d80p-46,
226 0x1.29e9df51fdf09p+0, 0x1.8b00p-47,
227 0x1.2ab8a66d10e9bp+0, -0x1.27c0p-45,
228 0x1.2b87fd0dada3ap+0, 0x1.a340p-45,
229 0x1.2c57e39771af9p+0, -0x1.0800p-46,
230 0x1.2d285a6e402d9p+0, -0x1.ed00p-47,
231 0x1.2df961f641579p+0, -0x1.4200p-48,
232 0x1.2ecafa93e2ecfp+0, -0x1.4980p-45,
233 0x1.2f9d24abd8822p+0, -0x1.6300p-46,
234 0x1.306fe0a31b625p+0, -0x1.2360p-44,
235 0x1.31432edeea50bp+0, -0x1.0df8p-40,
236 0x1.32170fc4cd7b8p+0, -0x1.2480p-45,
237 0x1.32eb83ba8e9a2p+0, -0x1.5980p-45,
238 0x1.33c08b2641766p+0, 0x1.ed00p-46,
239 0x1.3496266e3fa27p+0, -0x1.c000p-50,
240 0x1.356c55f929f0fp+0, -0x1.0d80p-44,
241 0x1.36431a2de88b9p+0, 0x1.2c80p-45,
242 0x1.371a7373aaa39p+0, 0x1.0600p-45,
243 0x1.37f26231e74fep+0, -0x1.6600p-46,
244 0x1.38cae6d05d838p+0, -0x1.ae00p-47,
245 0x1.39a401b713ec3p+0, -0x1.4720p-43,
246 0x1.3a7db34e5a020p+0, 0x1.8200p-47,
247 0x1.3b57fbfec6e95p+0, 0x1.e800p-44,
248 0x1.3c32dc313a8f2p+0, 0x1.f800p-49,
249 0x1.3d0e544ede122p+0, -0x1.7a00p-46,
250 0x1.3dea64c1234bbp+0, 0x1.6300p-45,
251 0x1.3ec70df1c4eccp+0, -0x1.8a60p-43,
252 0x1.3fa4504ac7e8cp+0, -0x1.cdc0p-44,
253 0x1.40822c367a0bbp+0, 0x1.5b80p-45,
254 0x1.4160a21f72e95p+0, 0x1.ec00p-46,
255 0x1.423fb27094646p+0, -0x1.3600p-46,
256 0x1.431f5d950a920p+0, 0x1.3980p-45,
257 0x1.43ffa3f84b9ebp+0, 0x1.a000p-48,
258 0x1.44e0860618919p+0, -0x1.6c00p-48,
259 0x1.45c2042a7d201p+0, -0x1.bc00p-47,
260 0x1.46a41ed1d0016p+0, -0x1.2800p-46,
261 0x1.4786d668b3326p+0, 0x1.0e00p-44,
262 0x1.486a2b5c13c00p+0, -0x1.d400p-45,
263 0x1.494e1e192af04p+0, 0x1.c200p-47,
264 0x1.4a32af0d7d372p+0, -0x1.e500p-46,
265 0x1.4b17dea6db801p+0, 0x1.7800p-47,
266 0x1.4bfdad53629e1p+0, -0x1.3800p-46,
267 0x1.4ce41b817c132p+0, 0x1.0800p-47,
268 0x1.4dcb299fddddbp+0, 0x1.c700p-45,
269 0x1.4eb2d81d8ab96p+0, -0x1.ce00p-46,
270 0x1.4f9b2769d2d02p+0, 0x1.9200p-46,
271 0x1.508417f4531c1p+0, -0x1.8c00p-47,
272 0x1.516daa2cf662ap+0, -0x1.a000p-48,
273 0x1.5257de83f51eap+0, 0x1.a080p-43,
274 0x1.5342b569d4edap+0, -0x1.6d80p-45,
275 0x1.542e2f4f6ac1ap+0, -0x1.2440p-44,
276 0x1.551a4ca5d94dbp+0, 0x1.83c0p-43,
277 0x1.56070dde9116bp+0, 0x1.4b00p-45,
278 0x1.56f4736b529dep+0, 0x1.15a0p-43,
279 0x1.57e27dbe2c40ep+0, -0x1.9e00p-45,
280 0x1.58d12d497c76fp+0, -0x1.3080p-45,
281 0x1.59c0827ff0b4cp+0, 0x1.dec0p-43,
282 0x1.5ab07dd485427p+0, -0x1.4000p-51,
283 0x1.5ba11fba87af4p+0, 0x1.0080p-44,
284 0x1.5c9268a59460bp+0, -0x1.6c80p-45,
285 0x1.5d84590998e3fp+0, 0x1.69a0p-43,
286 0x1.5e76f15ad20e1p+0, -0x1.b400p-46,
287 0x1.5f6a320dcebcap+0, 0x1.7700p-46,
288 0x1.605e1b976dcb8p+0, 0x1.6f80p-45,
289 0x1.6152ae6cdf715p+0, 0x1.1000p-47,
290 0x1.6247eb03a5531p+0, -0x1.5d00p-46,
291 0x1.633dd1d1929b5p+0, -0x1.2d00p-46,
292 0x1.6434634ccc313p+0, -0x1.a800p-49,
293 0x1.652b9febc8efap+0, -0x1.8600p-45,
294 0x1.6623882553397p+0, 0x1.1fe0p-40,
295 0x1.671c1c708328ep+0, -0x1.7200p-44,
296 0x1.68155d44ca97ep+0, 0x1.6800p-49,
297 0x1.690f4b19e9471p+0, -0x1.9780p-45,
298};
299
300/*
301 * exp2(x): compute the base 2 exponential of x
302 *
303 * Accuracy: Peak error < 0.503 ulp for normalized results.
304 *
305 * Method: (accurate tables)
306 *
307 * Reduce x:
308 * x = k + y, for integer k and |y| <= 1/2.
309 * Thus we have exp2(x) = 2**k * exp2(y).
310 *
311 * Reduce y:
312 * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE.
313 * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]),
314 * with |z - eps[i]| <= 2**-9 + 2**-39 for the table used.
315 *
316 * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via
317 * a degree-5 minimax polynomial with maximum error under 1.3 * 2**-61.
318 * The values in exp2t[] and eps[] are chosen such that
319 * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such
320 * that exp2t[i] is accurate to 2**-64.
321 *
322 * Note that the range of i is +-TBLSIZE/2, so we actually index the tables
323 * by i0 = i + TBLSIZE/2. For cache efficiency, exp2t[] and eps[] are
324 * virtual tables, interleaved in the real table tbl[].
325 *
326 * This method is due to Gal, with many details due to Gal and Bachelis:
327 *
328 * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library
329 * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991).
330 */
331double exp2(double x)
332{
333 double_t r, t, z;
334 uint32_t ix, i0;
335 union {double f; uint64_t i;} u = {x};
336 union {uint32_t u; int32_t i;} k;
337
338 /* Filter out exceptional cases. */
339 ix = u.i>>32 & 0x7fffffff;
340 if (ix >= 0x408ff000) { /* |x| >= 1022 or nan */
341 if (ix >= 0x40900000 && u.i>>63 == 0) { /* x >= 1024 or nan */
342 /* overflow */
343 x *= 0x1p1023;
344 return x;
345 }
346 if (ix >= 0x7ff00000) /* -inf or -nan */
347 return -1/x;
348 if (u.i>>63) { /* x <= -1022 */
349 /* underflow */
350 if (x <= -1075 || x - 0x1p52 + 0x1p52 != x)
351 FORCE_EVAL((float)(-0x1p-149/x));
352 if (x <= -1075)
353 return 0;
354 }
355 } else if (ix < 0x3c900000) { /* |x| < 0x1p-54 */
356 return 1.0 + x;
357 }
358
359 /* Reduce x, computing z, i0, and k. */
360 u.f = x + redux;
361 i0 = u.i;
362 i0 += TBLSIZE / 2;
363 k.u = i0 / TBLSIZE * TBLSIZE;
364 k.i /= TBLSIZE;
365 i0 %= TBLSIZE;
366 u.f -= redux;
367 z = x - u.f;
368
369 /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
370 t = tbl[2*i0]; /* exp2t[i0] */
371 z -= tbl[2*i0 + 1]; /* eps[i0] */
372 r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * P5))));
373
374 return scalbn(r, k.i);
375}
libc/musl/src/math/exp2f.c created+126
......@@ -0,0 +1,126 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_exp2f.c */
2/*-
3 * Copyright (c) 2005 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "libm.h"
29
30#define TBLSIZE 16
31
32static const float
33redux = 0x1.8p23f / TBLSIZE,
34P1 = 0x1.62e430p-1f,
35P2 = 0x1.ebfbe0p-3f,
36P3 = 0x1.c6b348p-5f,
37P4 = 0x1.3b2c9cp-7f;
38
39static const double exp2ft[TBLSIZE] = {
40 0x1.6a09e667f3bcdp-1,
41 0x1.7a11473eb0187p-1,
42 0x1.8ace5422aa0dbp-1,
43 0x1.9c49182a3f090p-1,
44 0x1.ae89f995ad3adp-1,
45 0x1.c199bdd85529cp-1,
46 0x1.d5818dcfba487p-1,
47 0x1.ea4afa2a490dap-1,
48 0x1.0000000000000p+0,
49 0x1.0b5586cf9890fp+0,
50 0x1.172b83c7d517bp+0,
51 0x1.2387a6e756238p+0,
52 0x1.306fe0a31b715p+0,
53 0x1.3dea64c123422p+0,
54 0x1.4bfdad5362a27p+0,
55 0x1.5ab07dd485429p+0,
56};
57
58/*
59 * exp2f(x): compute the base 2 exponential of x
60 *
61 * Accuracy: Peak error < 0.501 ulp; location of peak: -0.030110927.
62 *
63 * Method: (equally-spaced tables)
64 *
65 * Reduce x:
66 * x = k + y, for integer k and |y| <= 1/2.
67 * Thus we have exp2f(x) = 2**k * exp2(y).
68 *
69 * Reduce y:
70 * y = i/TBLSIZE + z for integer i near y * TBLSIZE.
71 * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z),
72 * with |z| <= 2**-(TBLSIZE+1).
73 *
74 * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
75 * degree-4 minimax polynomial with maximum error under 1.4 * 2**-33.
76 * Using double precision for everything except the reduction makes
77 * roundoff error insignificant and simplifies the scaling step.
78 *
79 * This method is due to Tang, but I do not use his suggested parameters:
80 *
81 * Tang, P. Table-driven Implementation of the Exponential Function
82 * in IEEE Floating-Point Arithmetic. TOMS 15(2), 144-157 (1989).
83 */
84float exp2f(float x)
85{
86 double_t t, r, z;
87 union {float f; uint32_t i;} u = {x};
88 union {double f; uint64_t i;} uk;
89 uint32_t ix, i0, k;
90
91 /* Filter out exceptional cases. */
92 ix = u.i & 0x7fffffff;
93 if (ix > 0x42fc0000) { /* |x| > 126 */
94 if (ix > 0x7f800000) /* NaN */
95 return x;
96 if (u.i >= 0x43000000 && u.i < 0x80000000) { /* x >= 128 */
97 x *= 0x1p127f;
98 return x;
99 }
100 if (u.i >= 0x80000000) { /* x < -126 */
101 if (u.i >= 0xc3160000 || (u.i & 0x0000ffff))
102 FORCE_EVAL(-0x1p-149f/x);
103 if (u.i >= 0xc3160000) /* x <= -150 */
104 return 0;
105 }
106 } else if (ix <= 0x33000000) { /* |x| <= 0x1p-25 */
107 return 1.0f + x;
108 }
109
110 /* Reduce x, computing z, i0, and k. */
111 u.f = x + redux;
112 i0 = u.i;
113 i0 += TBLSIZE / 2;
114 k = i0 / TBLSIZE;
115 uk.i = (uint64_t)(0x3ff + k)<<52;
116 i0 &= TBLSIZE - 1;
117 u.f -= redux;
118 z = x - u.f;
119 /* Compute r = exp2(y) = exp2ft[i0] * p(z). */
120 r = exp2ft[i0];
121 t = r * z;
122 r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);
123
124 /* Scale by 2**k */
125 return r * uk.f;
126}
libc/musl/src/math/exp2l.c created+619
......@@ -0,0 +1,619 @@
1/* origin: FreeBSD /usr/src/lib/msun/ld80/s_exp2l.c and /usr/src/lib/msun/ld128/s_exp2l.c */
2/*-
3 * Copyright (c) 2005-2008 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "libm.h"
29
30#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
31long double exp2l(long double x)
32{
33 return exp2(x);
34}
35#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
36#define TBLBITS 7
37#define TBLSIZE (1 << TBLBITS)
38
39static const double
40redux = 0x1.8p63 / TBLSIZE,
41P1 = 0x1.62e42fefa39efp-1,
42P2 = 0x1.ebfbdff82c58fp-3,
43P3 = 0x1.c6b08d7049fap-5,
44P4 = 0x1.3b2ab6fba4da5p-7,
45P5 = 0x1.5d8804780a736p-10,
46P6 = 0x1.430918835e33dp-13;
47
48static const double tbl[TBLSIZE * 2] = {
49 0x1.6a09e667f3bcdp-1, -0x1.bdd3413b2648p-55,
50 0x1.6c012750bdabfp-1, -0x1.2895667ff0cp-57,
51 0x1.6dfb23c651a2fp-1, -0x1.bbe3a683c88p-58,
52 0x1.6ff7df9519484p-1, -0x1.83c0f25860fp-56,
53 0x1.71f75e8ec5f74p-1, -0x1.16e4786887bp-56,
54 0x1.73f9a48a58174p-1, -0x1.0a8d96c65d5p-55,
55 0x1.75feb564267c9p-1, -0x1.0245957316ep-55,
56 0x1.780694fde5d3fp-1, 0x1.866b80a0216p-55,
57 0x1.7a11473eb0187p-1, -0x1.41577ee0499p-56,
58 0x1.7c1ed0130c132p-1, 0x1.f124cd1164ep-55,
59 0x1.7e2f336cf4e62p-1, 0x1.05d02ba157ap-57,
60 0x1.80427543e1a12p-1, -0x1.27c86626d97p-55,
61 0x1.82589994cce13p-1, -0x1.d4c1dd41533p-55,
62 0x1.8471a4623c7adp-1, -0x1.8d684a341cep-56,
63 0x1.868d99b4492edp-1, -0x1.fc6f89bd4f68p-55,
64 0x1.88ac7d98a6699p-1, 0x1.994c2f37cb5p-55,
65 0x1.8ace5422aa0dbp-1, 0x1.6e9f156864bp-55,
66 0x1.8cf3216b5448cp-1, -0x1.0d55e32e9e4p-57,
67 0x1.8f1ae99157736p-1, 0x1.5cc13a2e397p-56,
68 0x1.9145b0b91ffc6p-1, -0x1.dd6792e5825p-55,
69 0x1.93737b0cdc5e5p-1, -0x1.75fc781b58p-58,
70 0x1.95a44cbc8520fp-1, -0x1.64b7c96a5fp-57,
71 0x1.97d829fde4e5p-1, -0x1.d185b7c1b86p-55,
72 0x1.9a0f170ca07bap-1, -0x1.173bd91cee6p-55,
73 0x1.9c49182a3f09p-1, 0x1.c7c46b071f2p-57,
74 0x1.9e86319e32323p-1, 0x1.824ca78e64cp-57,
75 0x1.a0c667b5de565p-1, -0x1.359495d1cd5p-55,
76 0x1.a309bec4a2d33p-1, 0x1.6305c7ddc368p-55,
77 0x1.a5503b23e255dp-1, -0x1.d2f6edb8d42p-55,
78 0x1.a799e1330b358p-1, 0x1.bcb7ecac564p-55,
79 0x1.a9e6b5579fdbfp-1, 0x1.0fac90ef7fdp-55,
80 0x1.ac36bbfd3f37ap-1, -0x1.f9234cae76dp-56,
81 0x1.ae89f995ad3adp-1, 0x1.7a1cd345dcc8p-55,
82 0x1.b0e07298db666p-1, -0x1.bdef54c80e4p-55,
83 0x1.b33a2b84f15fbp-1, -0x1.2805e3084d8p-58,
84 0x1.b59728de5593ap-1, -0x1.c71dfbbba6ep-55,
85 0x1.b7f76f2fb5e47p-1, -0x1.5584f7e54acp-57,
86 0x1.ba5b030a1064ap-1, -0x1.efcd30e5429p-55,
87 0x1.bcc1e904bc1d2p-1, 0x1.23dd07a2d9fp-56,
88 0x1.bf2c25bd71e09p-1, -0x1.efdca3f6b9c8p-55,
89 0x1.c199bdd85529cp-1, 0x1.11065895049p-56,
90 0x1.c40ab5fffd07ap-1, 0x1.b4537e083c6p-55,
91 0x1.c67f12e57d14bp-1, 0x1.2884dff483c8p-55,
92 0x1.c8f6d9406e7b5p-1, 0x1.1acbc48805cp-57,
93 0x1.cb720dcef9069p-1, 0x1.503cbd1e94ap-57,
94 0x1.cdf0b555dc3fap-1, -0x1.dd83b53829dp-56,
95 0x1.d072d4a07897cp-1, -0x1.cbc3743797a8p-55,
96 0x1.d2f87080d89f2p-1, -0x1.d487b719d858p-55,
97 0x1.d5818dcfba487p-1, 0x1.2ed02d75b37p-56,
98 0x1.d80e316c98398p-1, -0x1.11ec18bedep-55,
99 0x1.da9e603db3285p-1, 0x1.c2300696db5p-55,
100 0x1.dd321f301b46p-1, 0x1.2da5778f019p-55,
101 0x1.dfc97337b9b5fp-1, -0x1.1a5cd4f184b8p-55,
102 0x1.e264614f5a129p-1, -0x1.7b627817a148p-55,
103 0x1.e502ee78b3ff6p-1, 0x1.39e8980a9cdp-56,
104 0x1.e7a51fbc74c83p-1, 0x1.2d522ca0c8ep-55,
105 0x1.ea4afa2a490dap-1, -0x1.e9c23179c288p-55,
106 0x1.ecf482d8e67f1p-1, -0x1.c93f3b411ad8p-55,
107 0x1.efa1bee615a27p-1, 0x1.dc7f486a4b68p-55,
108 0x1.f252b376bba97p-1, 0x1.3a1a5bf0d8e8p-55,
109 0x1.f50765b6e454p-1, 0x1.9d3e12dd8a18p-55,
110 0x1.f7bfdad9cbe14p-1, -0x1.dbb12d00635p-55,
111 0x1.fa7c1819e90d8p-1, 0x1.74853f3a593p-56,
112 0x1.fd3c22b8f71f1p-1, 0x1.2eb74966578p-58,
113 0x1p+0, 0x0p+0,
114 0x1.0163da9fb3335p+0, 0x1.b61299ab8cd8p-54,
115 0x1.02c9a3e778061p+0, -0x1.19083535b08p-56,
116 0x1.04315e86e7f85p+0, -0x1.0a31c1977c98p-54,
117 0x1.059b0d3158574p+0, 0x1.d73e2a475b4p-55,
118 0x1.0706b29ddf6dep+0, -0x1.c91dfe2b13cp-55,
119 0x1.0874518759bc8p+0, 0x1.186be4bb284p-57,
120 0x1.09e3ecac6f383p+0, 0x1.14878183161p-54,
121 0x1.0b5586cf9890fp+0, 0x1.8a62e4adc61p-54,
122 0x1.0cc922b7247f7p+0, 0x1.01edc16e24f8p-54,
123 0x1.0e3ec32d3d1a2p+0, 0x1.03a1727c58p-59,
124 0x1.0fb66affed31bp+0, -0x1.b9bedc44ebcp-57,
125 0x1.11301d0125b51p+0, -0x1.6c51039449bp-54,
126 0x1.12abdc06c31ccp+0, -0x1.1b514b36ca8p-58,
127 0x1.1429aaea92dep+0, -0x1.32fbf9af1368p-54,
128 0x1.15a98c8a58e51p+0, 0x1.2406ab9eeabp-55,
129 0x1.172b83c7d517bp+0, -0x1.19041b9d78ap-55,
130 0x1.18af9388c8deap+0, -0x1.11023d1970f8p-54,
131 0x1.1a35beb6fcb75p+0, 0x1.e5b4c7b4969p-55,
132 0x1.1bbe084045cd4p+0, -0x1.95386352ef6p-54,
133 0x1.1d4873168b9aap+0, 0x1.e016e00a264p-54,
134 0x1.1ed5022fcd91dp+0, -0x1.1df98027bb78p-54,
135 0x1.2063b88628cd6p+0, 0x1.dc775814a85p-55,
136 0x1.21f49917ddc96p+0, 0x1.2a97e9494a6p-55,
137 0x1.2387a6e756238p+0, 0x1.9b07eb6c7058p-54,
138 0x1.251ce4fb2a63fp+0, 0x1.ac155bef4f5p-55,
139 0x1.26b4565e27cddp+0, 0x1.2bd339940eap-55,
140 0x1.284dfe1f56381p+0, -0x1.a4c3a8c3f0d8p-54,
141 0x1.29e9df51fdee1p+0, 0x1.612e8afad12p-55,
142 0x1.2b87fd0dad99p+0, -0x1.10adcd6382p-59,
143 0x1.2d285a6e4030bp+0, 0x1.0024754db42p-54,
144 0x1.2ecafa93e2f56p+0, 0x1.1ca0f45d524p-56,
145 0x1.306fe0a31b715p+0, 0x1.6f46ad23183p-55,
146 0x1.32170fc4cd831p+0, 0x1.a9ce78e1804p-55,
147 0x1.33c08b26416ffp+0, 0x1.327218436598p-54,
148 0x1.356c55f929ff1p+0, -0x1.b5cee5c4e46p-55,
149 0x1.371a7373aa9cbp+0, -0x1.63aeabf42ebp-54,
150 0x1.38cae6d05d866p+0, -0x1.e958d3c99048p-54,
151 0x1.3a7db34e59ff7p+0, -0x1.5e436d661f6p-56,
152 0x1.3c32dc313a8e5p+0, -0x1.efff8375d2ap-54,
153 0x1.3dea64c123422p+0, 0x1.ada0911f09fp-55,
154 0x1.3fa4504ac801cp+0, -0x1.7d023f956fap-54,
155 0x1.4160a21f72e2ap+0, -0x1.ef3691c309p-58,
156 0x1.431f5d950a897p+0, -0x1.1c7dde35f7ap-55,
157 0x1.44e086061892dp+0, 0x1.89b7a04ef8p-59,
158 0x1.46a41ed1d0057p+0, 0x1.c944bd1648a8p-54,
159 0x1.486a2b5c13cdp+0, 0x1.3c1a3b69062p-56,
160 0x1.4a32af0d7d3dep+0, 0x1.9cb62f3d1be8p-54,
161 0x1.4bfdad5362a27p+0, 0x1.d4397afec42p-56,
162 0x1.4dcb299fddd0dp+0, 0x1.8ecdbbc6a78p-54,
163 0x1.4f9b2769d2ca7p+0, -0x1.4b309d25958p-54,
164 0x1.516daa2cf6642p+0, -0x1.f768569bd94p-55,
165 0x1.5342b569d4f82p+0, -0x1.07abe1db13dp-55,
166 0x1.551a4ca5d920fp+0, -0x1.d689cefede6p-55,
167 0x1.56f4736b527dap+0, 0x1.9bb2c011d938p-54,
168 0x1.58d12d497c7fdp+0, 0x1.295e15b9a1ep-55,
169 0x1.5ab07dd485429p+0, 0x1.6324c0546478p-54,
170 0x1.5c9268a5946b7p+0, 0x1.c4b1b81698p-60,
171 0x1.5e76f15ad2148p+0, 0x1.ba6f93080e68p-54,
172 0x1.605e1b976dc09p+0, -0x1.3e2429b56de8p-54,
173 0x1.6247eb03a5585p+0, -0x1.383c17e40b48p-54,
174 0x1.6434634ccc32p+0, -0x1.c483c759d89p-55,
175 0x1.6623882552225p+0, -0x1.bb60987591cp-54,
176 0x1.68155d44ca973p+0, 0x1.038ae44f74p-57,
177};
178
179/*
180 * exp2l(x): compute the base 2 exponential of x
181 *
182 * Accuracy: Peak error < 0.511 ulp.
183 *
184 * Method: (equally-spaced tables)
185 *
186 * Reduce x:
187 * x = 2**k + y, for integer k and |y| <= 1/2.
188 * Thus we have exp2l(x) = 2**k * exp2(y).
189 *
190 * Reduce y:
191 * y = i/TBLSIZE + z for integer i near y * TBLSIZE.
192 * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z),
193 * with |z| <= 2**-(TBLBITS+1).
194 *
195 * We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
196 * degree-6 minimax polynomial with maximum error under 2**-69.
197 * The table entries each have 104 bits of accuracy, encoded as
198 * a pair of double precision values.
199 */
200long double exp2l(long double x)
201{
202 union ldshape u = {x};
203 int e = u.i.se & 0x7fff;
204 long double r, z;
205 uint32_t i0;
206 union {uint32_t u; int32_t i;} k;
207
208 /* Filter out exceptional cases. */
209 if (e >= 0x3fff + 13) { /* |x| >= 8192 or x is NaN */
210 if (u.i.se >= 0x3fff + 14 && u.i.se >> 15 == 0)
211 /* overflow */
212 return x * 0x1p16383L;
213 if (e == 0x7fff) /* -inf or -nan */
214 return -1/x;
215 if (x < -16382) {
216 if (x <= -16446 || x - 0x1p63 + 0x1p63 != x)
217 /* underflow */
218 FORCE_EVAL((float)(-0x1p-149/x));
219 if (x <= -16446)
220 return 0;
221 }
222 } else if (e < 0x3fff - 64) {
223 return 1 + x;
224 }
225
226 /*
227 * Reduce x, computing z, i0, and k. The low bits of x + redux
228 * contain the 16-bit integer part of the exponent (k) followed by
229 * TBLBITS fractional bits (i0). We use bit tricks to extract these
230 * as integers, then set z to the remainder.
231 *
232 * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8.
233 * Then the low-order word of x + redux is 0x000abc12,
234 * We split this into k = 0xabc and i0 = 0x12 (adjusted to
235 * index into the table), then we compute z = 0x0.003456p0.
236 */
237 u.f = x + redux;
238 i0 = u.i.m + TBLSIZE / 2;
239 k.u = i0 / TBLSIZE * TBLSIZE;
240 k.i /= TBLSIZE;
241 i0 %= TBLSIZE;
242 u.f -= redux;
243 z = x - u.f;
244
245 /* Compute r = exp2l(y) = exp2lt[i0] * p(z). */
246 long double t_hi = tbl[2*i0];
247 long double t_lo = tbl[2*i0 + 1];
248 /* XXX This gives > 1 ulp errors outside of FE_TONEAREST mode */
249 r = t_lo + (t_hi + t_lo) * z * (P1 + z * (P2 + z * (P3 + z * (P4
250 + z * (P5 + z * P6))))) + t_hi;
251
252 return scalbnl(r, k.i);
253}
254#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
255#define TBLBITS 7
256#define TBLSIZE (1 << TBLBITS)
257
258static const long double
259 P1 = 0x1.62e42fefa39ef35793c7673007e6p-1L,
260 P2 = 0x1.ebfbdff82c58ea86f16b06ec9736p-3L,
261 P3 = 0x1.c6b08d704a0bf8b33a762bad3459p-5L,
262 P4 = 0x1.3b2ab6fba4e7729ccbbe0b4f3fc2p-7L,
263 P5 = 0x1.5d87fe78a67311071dee13fd11d9p-10L,
264 P6 = 0x1.430912f86c7876f4b663b23c5fe5p-13L;
265
266static const double
267 P7 = 0x1.ffcbfc588b041p-17,
268 P8 = 0x1.62c0223a5c7c7p-20,
269 P9 = 0x1.b52541ff59713p-24,
270 P10 = 0x1.e4cf56a391e22p-28,
271 redux = 0x1.8p112 / TBLSIZE;
272
273static const long double tbl[TBLSIZE] = {
274 0x1.6a09e667f3bcc908b2fb1366dfeap-1L,
275 0x1.6c012750bdabeed76a99800f4edep-1L,
276 0x1.6dfb23c651a2ef220e2cbe1bc0d4p-1L,
277 0x1.6ff7df9519483cf87e1b4f3e1e98p-1L,
278 0x1.71f75e8ec5f73dd2370f2ef0b148p-1L,
279 0x1.73f9a48a58173bd5c9a4e68ab074p-1L,
280 0x1.75feb564267c8bf6e9aa33a489a8p-1L,
281 0x1.780694fde5d3f619ae02808592a4p-1L,
282 0x1.7a11473eb0186d7d51023f6ccb1ap-1L,
283 0x1.7c1ed0130c1327c49334459378dep-1L,
284 0x1.7e2f336cf4e62105d02ba1579756p-1L,
285 0x1.80427543e1a11b60de67649a3842p-1L,
286 0x1.82589994cce128acf88afab34928p-1L,
287 0x1.8471a4623c7acce52f6b97c6444cp-1L,
288 0x1.868d99b4492ec80e41d90ac2556ap-1L,
289 0x1.88ac7d98a669966530bcdf2d4cc0p-1L,
290 0x1.8ace5422aa0db5ba7c55a192c648p-1L,
291 0x1.8cf3216b5448bef2aa1cd161c57ap-1L,
292 0x1.8f1ae991577362b982745c72eddap-1L,
293 0x1.9145b0b91ffc588a61b469f6b6a0p-1L,
294 0x1.93737b0cdc5e4f4501c3f2540ae8p-1L,
295 0x1.95a44cbc8520ee9b483695a0e7fep-1L,
296 0x1.97d829fde4e4f8b9e920f91e8eb6p-1L,
297 0x1.9a0f170ca07b9ba3109b8c467844p-1L,
298 0x1.9c49182a3f0901c7c46b071f28dep-1L,
299 0x1.9e86319e323231824ca78e64c462p-1L,
300 0x1.a0c667b5de564b29ada8b8cabbacp-1L,
301 0x1.a309bec4a2d3358c171f770db1f4p-1L,
302 0x1.a5503b23e255c8b424491caf88ccp-1L,
303 0x1.a799e1330b3586f2dfb2b158f31ep-1L,
304 0x1.a9e6b5579fdbf43eb243bdff53a2p-1L,
305 0x1.ac36bbfd3f379c0db966a3126988p-1L,
306 0x1.ae89f995ad3ad5e8734d17731c80p-1L,
307 0x1.b0e07298db66590842acdfc6fb4ep-1L,
308 0x1.b33a2b84f15faf6bfd0e7bd941b0p-1L,
309 0x1.b59728de559398e3881111648738p-1L,
310 0x1.b7f76f2fb5e46eaa7b081ab53ff6p-1L,
311 0x1.ba5b030a10649840cb3c6af5b74cp-1L,
312 0x1.bcc1e904bc1d2247ba0f45b3d06cp-1L,
313 0x1.bf2c25bd71e088408d7025190cd0p-1L,
314 0x1.c199bdd85529c2220cb12a0916bap-1L,
315 0x1.c40ab5fffd07a6d14df820f17deap-1L,
316 0x1.c67f12e57d14b4a2137fd20f2a26p-1L,
317 0x1.c8f6d9406e7b511acbc48805c3f6p-1L,
318 0x1.cb720dcef90691503cbd1e949d0ap-1L,
319 0x1.cdf0b555dc3f9c44f8958fac4f12p-1L,
320 0x1.d072d4a07897b8d0f22f21a13792p-1L,
321 0x1.d2f87080d89f18ade123989ea50ep-1L,
322 0x1.d5818dcfba48725da05aeb66dff8p-1L,
323 0x1.d80e316c98397bb84f9d048807a0p-1L,
324 0x1.da9e603db3285708c01a5b6d480cp-1L,
325 0x1.dd321f301b4604b695de3c0630c0p-1L,
326 0x1.dfc97337b9b5eb968cac39ed284cp-1L,
327 0x1.e264614f5a128a12761fa17adc74p-1L,
328 0x1.e502ee78b3ff6273d130153992d0p-1L,
329 0x1.e7a51fbc74c834b548b2832378a4p-1L,
330 0x1.ea4afa2a490d9858f73a18f5dab4p-1L,
331 0x1.ecf482d8e67f08db0312fb949d50p-1L,
332 0x1.efa1bee615a27771fd21a92dabb6p-1L,
333 0x1.f252b376bba974e8696fc3638f24p-1L,
334 0x1.f50765b6e4540674f84b762861a6p-1L,
335 0x1.f7bfdad9cbe138913b4bfe72bd78p-1L,
336 0x1.fa7c1819e90d82e90a7e74b26360p-1L,
337 0x1.fd3c22b8f71f10975ba4b32bd006p-1L,
338 0x1.0000000000000000000000000000p+0L,
339 0x1.0163da9fb33356d84a66ae336e98p+0L,
340 0x1.02c9a3e778060ee6f7caca4f7a18p+0L,
341 0x1.04315e86e7f84bd738f9a20da442p+0L,
342 0x1.059b0d31585743ae7c548eb68c6ap+0L,
343 0x1.0706b29ddf6ddc6dc403a9d87b1ep+0L,
344 0x1.0874518759bc808c35f25d942856p+0L,
345 0x1.09e3ecac6f3834521e060c584d5cp+0L,
346 0x1.0b5586cf9890f6298b92b7184200p+0L,
347 0x1.0cc922b7247f7407b705b893dbdep+0L,
348 0x1.0e3ec32d3d1a2020742e4f8af794p+0L,
349 0x1.0fb66affed31af232091dd8a169ep+0L,
350 0x1.11301d0125b50a4ebbf1aed9321cp+0L,
351 0x1.12abdc06c31cbfb92bad324d6f84p+0L,
352 0x1.1429aaea92ddfb34101943b2588ep+0L,
353 0x1.15a98c8a58e512480d573dd562aep+0L,
354 0x1.172b83c7d517adcdf7c8c50eb162p+0L,
355 0x1.18af9388c8de9bbbf70b9a3c269cp+0L,
356 0x1.1a35beb6fcb753cb698f692d2038p+0L,
357 0x1.1bbe084045cd39ab1e72b442810ep+0L,
358 0x1.1d4873168b9aa7805b8028990be8p+0L,
359 0x1.1ed5022fcd91cb8819ff61121fbep+0L,
360 0x1.2063b88628cd63b8eeb0295093f6p+0L,
361 0x1.21f49917ddc962552fd29294bc20p+0L,
362 0x1.2387a6e75623866c1fadb1c159c0p+0L,
363 0x1.251ce4fb2a63f3582ab7de9e9562p+0L,
364 0x1.26b4565e27cdd257a673281d3068p+0L,
365 0x1.284dfe1f5638096cf15cf03c9fa0p+0L,
366 0x1.29e9df51fdee12c25d15f5a25022p+0L,
367 0x1.2b87fd0dad98ffddea46538fca24p+0L,
368 0x1.2d285a6e4030b40091d536d0733ep+0L,
369 0x1.2ecafa93e2f5611ca0f45d5239a4p+0L,
370 0x1.306fe0a31b7152de8d5a463063bep+0L,
371 0x1.32170fc4cd8313539cf1c3009330p+0L,
372 0x1.33c08b26416ff4c9c8610d96680ep+0L,
373 0x1.356c55f929ff0c94623476373be4p+0L,
374 0x1.371a7373aa9caa7145502f45452ap+0L,
375 0x1.38cae6d05d86585a9cb0d9bed530p+0L,
376 0x1.3a7db34e59ff6ea1bc9299e0a1fep+0L,
377 0x1.3c32dc313a8e484001f228b58cf0p+0L,
378 0x1.3dea64c12342235b41223e13d7eep+0L,
379 0x1.3fa4504ac801ba0bf701aa417b9cp+0L,
380 0x1.4160a21f72e29f84325b8f3dbacap+0L,
381 0x1.431f5d950a896dc704439410b628p+0L,
382 0x1.44e086061892d03136f409df0724p+0L,
383 0x1.46a41ed1d005772512f459229f0ap+0L,
384 0x1.486a2b5c13cd013c1a3b69062f26p+0L,
385 0x1.4a32af0d7d3de672d8bcf46f99b4p+0L,
386 0x1.4bfdad5362a271d4397afec42e36p+0L,
387 0x1.4dcb299fddd0d63b36ef1a9e19dep+0L,
388 0x1.4f9b2769d2ca6ad33d8b69aa0b8cp+0L,
389 0x1.516daa2cf6641c112f52c84d6066p+0L,
390 0x1.5342b569d4f81df0a83c49d86bf4p+0L,
391 0x1.551a4ca5d920ec52ec620243540cp+0L,
392 0x1.56f4736b527da66ecb004764e61ep+0L,
393 0x1.58d12d497c7fd252bc2b7343d554p+0L,
394 0x1.5ab07dd48542958c93015191e9a8p+0L,
395 0x1.5c9268a5946b701c4b1b81697ed4p+0L,
396 0x1.5e76f15ad21486e9be4c20399d12p+0L,
397 0x1.605e1b976dc08b076f592a487066p+0L,
398 0x1.6247eb03a5584b1f0fa06fd2d9eap+0L,
399 0x1.6434634ccc31fc76f8714c4ee122p+0L,
400 0x1.66238825522249127d9e29b92ea2p+0L,
401 0x1.68155d44ca973081c57227b9f69ep+0L,
402};
403
404static const float eps[TBLSIZE] = {
405 -0x1.5c50p-101,
406 -0x1.5d00p-106,
407 0x1.8e90p-102,
408 -0x1.5340p-103,
409 0x1.1bd0p-102,
410 -0x1.4600p-105,
411 -0x1.7a40p-104,
412 0x1.d590p-102,
413 -0x1.d590p-101,
414 0x1.b100p-103,
415 -0x1.0d80p-105,
416 0x1.6b00p-103,
417 -0x1.9f00p-105,
418 0x1.c400p-103,
419 0x1.e120p-103,
420 -0x1.c100p-104,
421 -0x1.9d20p-103,
422 0x1.a800p-108,
423 0x1.4c00p-106,
424 -0x1.9500p-106,
425 0x1.6900p-105,
426 -0x1.29d0p-100,
427 0x1.4c60p-103,
428 0x1.13a0p-102,
429 -0x1.5b60p-103,
430 -0x1.1c40p-103,
431 0x1.db80p-102,
432 0x1.91a0p-102,
433 0x1.dc00p-105,
434 0x1.44c0p-104,
435 0x1.9710p-102,
436 0x1.8760p-103,
437 -0x1.a720p-103,
438 0x1.ed20p-103,
439 -0x1.49c0p-102,
440 -0x1.e000p-111,
441 0x1.86a0p-103,
442 0x1.2b40p-103,
443 -0x1.b400p-108,
444 0x1.1280p-99,
445 -0x1.02d8p-102,
446 -0x1.e3d0p-103,
447 -0x1.b080p-105,
448 -0x1.f100p-107,
449 -0x1.16c0p-105,
450 -0x1.1190p-103,
451 -0x1.a7d2p-100,
452 0x1.3450p-103,
453 -0x1.67c0p-105,
454 0x1.4b80p-104,
455 -0x1.c4e0p-103,
456 0x1.6000p-108,
457 -0x1.3f60p-105,
458 0x1.93f0p-104,
459 0x1.5fe0p-105,
460 0x1.6f80p-107,
461 -0x1.7600p-106,
462 0x1.21e0p-106,
463 -0x1.3a40p-106,
464 -0x1.40c0p-104,
465 -0x1.9860p-105,
466 -0x1.5d40p-108,
467 -0x1.1d70p-106,
468 0x1.2760p-105,
469 0x0.0000p+0,
470 0x1.21e2p-104,
471 -0x1.9520p-108,
472 -0x1.5720p-106,
473 -0x1.4810p-106,
474 -0x1.be00p-109,
475 0x1.0080p-105,
476 -0x1.5780p-108,
477 -0x1.d460p-105,
478 -0x1.6140p-105,
479 0x1.4630p-104,
480 0x1.ad50p-103,
481 0x1.82e0p-105,
482 0x1.1d3cp-101,
483 0x1.6100p-107,
484 0x1.ec30p-104,
485 0x1.f200p-108,
486 0x1.0b40p-103,
487 0x1.3660p-102,
488 0x1.d9d0p-103,
489 -0x1.02d0p-102,
490 0x1.b070p-103,
491 0x1.b9c0p-104,
492 -0x1.01c0p-103,
493 -0x1.dfe0p-103,
494 0x1.1b60p-104,
495 -0x1.ae94p-101,
496 -0x1.3340p-104,
497 0x1.b3d8p-102,
498 -0x1.6e40p-105,
499 -0x1.3670p-103,
500 0x1.c140p-104,
501 0x1.1840p-101,
502 0x1.1ab0p-102,
503 -0x1.a400p-104,
504 0x1.1f00p-104,
505 -0x1.7180p-103,
506 0x1.4ce0p-102,
507 0x1.9200p-107,
508 -0x1.54c0p-103,
509 0x1.1b80p-105,
510 -0x1.1828p-101,
511 0x1.5720p-102,
512 -0x1.a060p-100,
513 0x1.9160p-102,
514 0x1.a280p-104,
515 0x1.3400p-107,
516 0x1.2b20p-102,
517 0x1.7800p-108,
518 0x1.cfd0p-101,
519 0x1.2ef0p-102,
520 -0x1.2760p-99,
521 0x1.b380p-104,
522 0x1.0048p-101,
523 -0x1.60b0p-102,
524 0x1.a1ccp-100,
525 -0x1.a640p-104,
526 -0x1.08a0p-101,
527 0x1.7e60p-102,
528 0x1.22c0p-103,
529 -0x1.7200p-106,
530 0x1.f0f0p-102,
531 0x1.eb4ep-99,
532 0x1.c6e0p-103,
533};
534
535/*
536 * exp2l(x): compute the base 2 exponential of x
537 *
538 * Accuracy: Peak error < 0.502 ulp.
539 *
540 * Method: (accurate tables)
541 *
542 * Reduce x:
543 * x = 2**k + y, for integer k and |y| <= 1/2.
544 * Thus we have exp2(x) = 2**k * exp2(y).
545 *
546 * Reduce y:
547 * y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE.
548 * Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]),
549 * with |z - eps[i]| <= 2**-8 + 2**-98 for the table used.
550 *
551 * We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via
552 * a degree-10 minimax polynomial with maximum error under 2**-120.
553 * The values in exp2t[] and eps[] are chosen such that
554 * exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such
555 * that exp2t[i] is accurate to 2**-122.
556 *
557 * Note that the range of i is +-TBLSIZE/2, so we actually index the tables
558 * by i0 = i + TBLSIZE/2.
559 *
560 * This method is due to Gal, with many details due to Gal and Bachelis:
561 *
562 * Gal, S. and Bachelis, B. An Accurate Elementary Mathematical Library
563 * for the IEEE Floating Point Standard. TOMS 17(1), 26-46 (1991).
564 */
565long double
566exp2l(long double x)
567{
568 union ldshape u = {x};
569 int e = u.i.se & 0x7fff;
570 long double r, z, t;
571 uint32_t i0;
572 union {uint32_t u; int32_t i;} k;
573
574 /* Filter out exceptional cases. */
575 if (e >= 0x3fff + 14) { /* |x| >= 16384 or x is NaN */
576 if (u.i.se >= 0x3fff + 15 && u.i.se >> 15 == 0)
577 /* overflow */
578 return x * 0x1p16383L;
579 if (e == 0x7fff) /* -inf or -nan */
580 return -1/x;
581 if (x < -16382) {
582 if (x <= -16495 || x - 0x1p112 + 0x1p112 != x)
583 /* underflow */
584 FORCE_EVAL((float)(-0x1p-149/x));
585 if (x <= -16446)
586 return 0;
587 }
588 } else if (e < 0x3fff - 114) {
589 return 1 + x;
590 }
591
592 /*
593 * Reduce x, computing z, i0, and k. The low bits of x + redux
594 * contain the 16-bit integer part of the exponent (k) followed by
595 * TBLBITS fractional bits (i0). We use bit tricks to extract these
596 * as integers, then set z to the remainder.
597 *
598 * Example: Suppose x is 0xabc.123456p0 and TBLBITS is 8.
599 * Then the low-order word of x + redux is 0x000abc12,
600 * We split this into k = 0xabc and i0 = 0x12 (adjusted to
601 * index into the table), then we compute z = 0x0.003456p0.
602 */
603 u.f = x + redux;
604 i0 = u.i2.lo + TBLSIZE / 2;
605 k.u = i0 / TBLSIZE * TBLSIZE;
606 k.i /= TBLSIZE;
607 i0 %= TBLSIZE;
608 u.f -= redux;
609 z = x - u.f;
610
611 /* Compute r = exp2(y) = exp2t[i0] * p(z - eps[i]). */
612 t = tbl[i0];
613 z -= eps[i0];
614 r = t + t * z * (P1 + z * (P2 + z * (P3 + z * (P4 + z * (P5 + z * (P6
615 + z * (P7 + z * (P8 + z * (P9 + z * P10)))))))));
616
617 return scalbnl(r, k.i);
618}
619#endif
libc/musl/src/math/expf.c created+83
......@@ -0,0 +1,83 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_expf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include "libm.h"
17
18static const float
19half[2] = {0.5,-0.5},
20ln2hi = 6.9314575195e-1f, /* 0x3f317200 */
21ln2lo = 1.4286067653e-6f, /* 0x35bfbe8e */
22invln2 = 1.4426950216e+0f, /* 0x3fb8aa3b */
23/*
24 * Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]:
25 * |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74
26 */
27P1 = 1.6666625440e-1f, /* 0xaaaa8f.0p-26 */
28P2 = -2.7667332906e-3f; /* -0xb55215.0p-32 */
29
30float expf(float x)
31{
32 float_t hi, lo, c, xx, y;
33 int k, sign;
34 uint32_t hx;
35
36 GET_FLOAT_WORD(hx, x);
37 sign = hx >> 31; /* sign bit of x */
38 hx &= 0x7fffffff; /* high word of |x| */
39
40 /* special cases */
41 if (hx >= 0x42aeac50) { /* if |x| >= -87.33655f or NaN */
42 if (hx > 0x7f800000) /* NaN */
43 return x;
44 if (hx >= 0x42b17218 && !sign) { /* x >= 88.722839f */
45 /* overflow */
46 x *= 0x1p127f;
47 return x;
48 }
49 if (sign) {
50 /* underflow */
51 FORCE_EVAL(-0x1p-149f/x);
52 if (hx >= 0x42cff1b5) /* x <= -103.972084f */
53 return 0;
54 }
55 }
56
57 /* argument reduction */
58 if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
59 if (hx > 0x3f851592) /* if |x| > 1.5 ln2 */
60 k = invln2*x + half[sign];
61 else
62 k = 1 - sign - sign;
63 hi = x - k*ln2hi; /* k*ln2hi is exact here */
64 lo = k*ln2lo;
65 x = hi - lo;
66 } else if (hx > 0x39000000) { /* |x| > 2**-14 */
67 k = 0;
68 hi = x;
69 lo = 0;
70 } else {
71 /* raise inexact */
72 FORCE_EVAL(0x1p127f + x);
73 return 1 + x;
74 }
75
76 /* x is now in primary range */
77 xx = x*x;
78 c = x - xx*(P1+xx*P2);
79 y = 1 + (x*c/(2-c) - lo + hi);
80 if (k == 0)
81 return y;
82 return scalbnf(y, k);
83}
libc/musl/src/math/expl.c created+128
......@@ -0,0 +1,128 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expl.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Exponential function, long double precision
19 *
20 *
21 * SYNOPSIS:
22 *
23 * long double x, y, expl();
24 *
25 * y = expl( x );
26 *
27 *
28 * DESCRIPTION:
29 *
30 * Returns e (2.71828...) raised to the x power.
31 *
32 * Range reduction is accomplished by separating the argument
33 * into an integer k and fraction f such that
34 *
35 * x k f
36 * e = 2 e.
37 *
38 * A Pade' form of degree 5/6 is used to approximate exp(f) - 1
39 * in the basic range [-0.5 ln 2, 0.5 ln 2].
40 *
41 *
42 * ACCURACY:
43 *
44 * Relative error:
45 * arithmetic domain # trials peak rms
46 * IEEE +-10000 50000 1.12e-19 2.81e-20
47 *
48 *
49 * Error amplification in the exponential function can be
50 * a serious matter. The error propagation involves
51 * exp( X(1+delta) ) = exp(X) ( 1 + X*delta + ... ),
52 * which shows that a 1 lsb error in representing X produces
53 * a relative error of X times 1 lsb in the function.
54 * While the routine gives an accurate result for arguments
55 * that are exactly represented by a long double precision
56 * computer number, the result contains amplified roundoff
57 * error for large arguments not exactly represented.
58 *
59 *
60 * ERROR MESSAGES:
61 *
62 * message condition value returned
63 * exp underflow x < MINLOG 0.0
64 * exp overflow x > MAXLOG MAXNUM
65 *
66 */
67
68#include "libm.h"
69
70#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
71long double expl(long double x)
72{
73 return exp(x);
74}
75#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
76
77static const long double P[3] = {
78 1.2617719307481059087798E-4L,
79 3.0299440770744196129956E-2L,
80 9.9999999999999999991025E-1L,
81};
82static const long double Q[4] = {
83 3.0019850513866445504159E-6L,
84 2.5244834034968410419224E-3L,
85 2.2726554820815502876593E-1L,
86 2.0000000000000000000897E0L,
87};
88static const long double
89LN2HI = 6.9314575195312500000000E-1L,
90LN2LO = 1.4286068203094172321215E-6L,
91LOG2E = 1.4426950408889634073599E0L;
92
93long double expl(long double x)
94{
95 long double px, xx;
96 int k;
97
98 if (isnan(x))
99 return x;
100 if (x > 11356.5234062941439488L) /* x > ln(2^16384 - 0.5) */
101 return x * 0x1p16383L;
102 if (x < -11399.4985314888605581L) /* x < ln(2^-16446) */
103 return -0x1p-16445L/x;
104
105 /* Express e**x = e**f 2**k
106 * = e**(f + k ln(2))
107 */
108 px = floorl(LOG2E * x + 0.5);
109 k = px;
110 x -= px * LN2HI;
111 x -= px * LN2LO;
112
113 /* rational approximation of the fractional part:
114 * e**x = 1 + 2x P(x**2)/(Q(x**2) - x P(x**2))
115 */
116 xx = x * x;
117 px = x * __polevll(xx, P, 2);
118 x = px/(__polevll(xx, Q, 3) - px);
119 x = 1.0 + 2.0 * x;
120 return scalbnl(x, k);
121}
122#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
123// TODO: broken implementation to make things compile
124long double expl(long double x)
125{
126 return exp(x);
127}
128#endif
libc/musl/src/math/expm1.c created+201
......@@ -0,0 +1,201 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* expm1(x)
13 * Returns exp(x)-1, the exponential of x minus 1.
14 *
15 * Method
16 * 1. Argument reduction:
17 * Given x, find r and integer k such that
18 *
19 * x = k*ln2 + r, |r| <= 0.5*ln2 ~ 0.34658
20 *
21 * Here a correction term c will be computed to compensate
22 * the error in r when rounded to a floating-point number.
23 *
24 * 2. Approximating expm1(r) by a special rational function on
25 * the interval [0,0.34658]:
26 * Since
27 * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 - r^4/360 + ...
28 * we define R1(r*r) by
29 * r*(exp(r)+1)/(exp(r)-1) = 2+ r^2/6 * R1(r*r)
30 * That is,
31 * R1(r**2) = 6/r *((exp(r)+1)/(exp(r)-1) - 2/r)
32 * = 6/r * ( 1 + 2.0*(1/(exp(r)-1) - 1/r))
33 * = 1 - r^2/60 + r^4/2520 - r^6/100800 + ...
34 * We use a special Remez algorithm on [0,0.347] to generate
35 * a polynomial of degree 5 in r*r to approximate R1. The
36 * maximum error of this polynomial approximation is bounded
37 * by 2**-61. In other words,
38 * R1(z) ~ 1.0 + Q1*z + Q2*z**2 + Q3*z**3 + Q4*z**4 + Q5*z**5
39 * where Q1 = -1.6666666666666567384E-2,
40 * Q2 = 3.9682539681370365873E-4,
41 * Q3 = -9.9206344733435987357E-6,
42 * Q4 = 2.5051361420808517002E-7,
43 * Q5 = -6.2843505682382617102E-9;
44 * z = r*r,
45 * with error bounded by
46 * | 5 | -61
47 * | 1.0+Q1*z+...+Q5*z - R1(z) | <= 2
48 * | |
49 *
50 * expm1(r) = exp(r)-1 is then computed by the following
51 * specific way which minimize the accumulation rounding error:
52 * 2 3
53 * r r [ 3 - (R1 + R1*r/2) ]
54 * expm1(r) = r + --- + --- * [--------------------]
55 * 2 2 [ 6 - r*(3 - R1*r/2) ]
56 *
57 * To compensate the error in the argument reduction, we use
58 * expm1(r+c) = expm1(r) + c + expm1(r)*c
59 * ~ expm1(r) + c + r*c
60 * Thus c+r*c will be added in as the correction terms for
61 * expm1(r+c). Now rearrange the term to avoid optimization
62 * screw up:
63 * ( 2 2 )
64 * ({ ( r [ R1 - (3 - R1*r/2) ] ) } r )
65 * expm1(r+c)~r - ({r*(--- * [--------------------]-c)-c} - --- )
66 * ({ ( 2 [ 6 - r*(3 - R1*r/2) ] ) } 2 )
67 * ( )
68 *
69 * = r - E
70 * 3. Scale back to obtain expm1(x):
71 * From step 1, we have
72 * expm1(x) = either 2^k*[expm1(r)+1] - 1
73 * = or 2^k*[expm1(r) + (1-2^-k)]
74 * 4. Implementation notes:
75 * (A). To save one multiplication, we scale the coefficient Qi
76 * to Qi*2^i, and replace z by (x^2)/2.
77 * (B). To achieve maximum accuracy, we compute expm1(x) by
78 * (i) if x < -56*ln2, return -1.0, (raise inexact if x!=inf)
79 * (ii) if k=0, return r-E
80 * (iii) if k=-1, return 0.5*(r-E)-0.5
81 * (iv) if k=1 if r < -0.25, return 2*((r+0.5)- E)
82 * else return 1.0+2.0*(r-E);
83 * (v) if (k<-2||k>56) return 2^k(1-(E-r)) - 1 (or exp(x)-1)
84 * (vi) if k <= 20, return 2^k((1-2^-k)-(E-r)), else
85 * (vii) return 2^k(1-((E+2^-k)-r))
86 *
87 * Special cases:
88 * expm1(INF) is INF, expm1(NaN) is NaN;
89 * expm1(-INF) is -1, and
90 * for finite argument, only expm1(0)=0 is exact.
91 *
92 * Accuracy:
93 * according to an error analysis, the error is always less than
94 * 1 ulp (unit in the last place).
95 *
96 * Misc. info.
97 * For IEEE double
98 * if x > 7.09782712893383973096e+02 then expm1(x) overflow
99 *
100 * Constants:
101 * The hexadecimal values are the intended ones for the following
102 * constants. The decimal values may be used, provided that the
103 * compiler will convert from decimal to binary accurately enough
104 * to produce the hexadecimal values shown.
105 */
106
107#include "libm.h"
108
109static const double
110o_threshold = 7.09782712893383973096e+02, /* 0x40862E42, 0xFEFA39EF */
111ln2_hi = 6.93147180369123816490e-01, /* 0x3fe62e42, 0xfee00000 */
112ln2_lo = 1.90821492927058770002e-10, /* 0x3dea39ef, 0x35793c76 */
113invln2 = 1.44269504088896338700e+00, /* 0x3ff71547, 0x652b82fe */
114/* Scaled Q's: Qn_here = 2**n * Qn_above, for R(2*z) where z = hxs = x*x/2: */
115Q1 = -3.33333333333331316428e-02, /* BFA11111 111110F4 */
116Q2 = 1.58730158725481460165e-03, /* 3F5A01A0 19FE5585 */
117Q3 = -7.93650757867487942473e-05, /* BF14CE19 9EAADBB7 */
118Q4 = 4.00821782732936239552e-06, /* 3ED0CFCA 86E65239 */
119Q5 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
120
121double expm1(double x)
122{
123 double_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
124 union {double f; uint64_t i;} u = {x};
125 uint32_t hx = u.i>>32 & 0x7fffffff;
126 int k, sign = u.i>>63;
127
128 /* filter out huge and non-finite argument */
129 if (hx >= 0x4043687A) { /* if |x|>=56*ln2 */
130 if (isnan(x))
131 return x;
132 if (sign)
133 return -1;
134 if (x > o_threshold) {
135 x *= 0x1p1023;
136 return x;
137 }
138 }
139
140 /* argument reduction */
141 if (hx > 0x3fd62e42) { /* if |x| > 0.5 ln2 */
142 if (hx < 0x3FF0A2B2) { /* and |x| < 1.5 ln2 */
143 if (!sign) {
144 hi = x - ln2_hi;
145 lo = ln2_lo;
146 k = 1;
147 } else {
148 hi = x + ln2_hi;
149 lo = -ln2_lo;
150 k = -1;
151 }
152 } else {
153 k = invln2*x + (sign ? -0.5 : 0.5);
154 t = k;
155 hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
156 lo = t*ln2_lo;
157 }
158 x = hi-lo;
159 c = (hi-x)-lo;
160 } else if (hx < 0x3c900000) { /* |x| < 2**-54, return x */
161 if (hx < 0x00100000)
162 FORCE_EVAL((float)x);
163 return x;
164 } else
165 k = 0;
166
167 /* x is now in primary range */
168 hfx = 0.5*x;
169 hxs = x*hfx;
170 r1 = 1.0+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
171 t = 3.0-r1*hfx;
172 e = hxs*((r1-t)/(6.0 - x*t));
173 if (k == 0) /* c is 0 */
174 return x - (x*e-hxs);
175 e = x*(e-c) - c;
176 e -= hxs;
177 /* exp(x) ~ 2^k (x_reduced - e + 1) */
178 if (k == -1)
179 return 0.5*(x-e) - 0.5;
180 if (k == 1) {
181 if (x < -0.25)
182 return -2.0*(e-(x+0.5));
183 return 1.0+2.0*(x-e);
184 }
185 u.i = (uint64_t)(0x3ff + k)<<52; /* 2^k */
186 twopk = u.f;
187 if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */
188 y = x - e + 1.0;
189 if (k == 1024)
190 y = y*2.0*0x1p1023;
191 else
192 y = y*twopk;
193 return y - 1.0;
194 }
195 u.i = (uint64_t)(0x3ff - k)<<52; /* 2^-k */
196 if (k < 20)
197 y = (x-e+(1-u.f))*twopk;
198 else
199 y = (x-(e+u.f)+1)*twopk;
200 return y;
201}
libc/musl/src/math/expm1f.c created+111
......@@ -0,0 +1,111 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1f.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include "libm.h"
17
18static const float
19o_threshold = 8.8721679688e+01, /* 0x42b17180 */
20ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
21ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
22invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */
23/*
24 * Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]:
25 * |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04
26 * Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c):
27 */
28Q1 = -3.3333212137e-2, /* -0x888868.0p-28 */
29Q2 = 1.5807170421e-3; /* 0xcf3010.0p-33 */
30
31float expm1f(float x)
32{
33 float_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
34 union {float f; uint32_t i;} u = {x};
35 uint32_t hx = u.i & 0x7fffffff;
36 int k, sign = u.i >> 31;
37
38 /* filter out huge and non-finite argument */
39 if (hx >= 0x4195b844) { /* if |x|>=27*ln2 */
40 if (hx > 0x7f800000) /* NaN */
41 return x;
42 if (sign)
43 return -1;
44 if (x > o_threshold) {
45 x *= 0x1p127f;
46 return x;
47 }
48 }
49
50 /* argument reduction */
51 if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
52 if (hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
53 if (!sign) {
54 hi = x - ln2_hi;
55 lo = ln2_lo;
56 k = 1;
57 } else {
58 hi = x + ln2_hi;
59 lo = -ln2_lo;
60 k = -1;
61 }
62 } else {
63 k = invln2*x + (sign ? -0.5f : 0.5f);
64 t = k;
65 hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
66 lo = t*ln2_lo;
67 }
68 x = hi-lo;
69 c = (hi-x)-lo;
70 } else if (hx < 0x33000000) { /* when |x|<2**-25, return x */
71 if (hx < 0x00800000)
72 FORCE_EVAL(x*x);
73 return x;
74 } else
75 k = 0;
76
77 /* x is now in primary range */
78 hfx = 0.5f*x;
79 hxs = x*hfx;
80 r1 = 1.0f+hxs*(Q1+hxs*Q2);
81 t = 3.0f - r1*hfx;
82 e = hxs*((r1-t)/(6.0f - x*t));
83 if (k == 0) /* c is 0 */
84 return x - (x*e-hxs);
85 e = x*(e-c) - c;
86 e -= hxs;
87 /* exp(x) ~ 2^k (x_reduced - e + 1) */
88 if (k == -1)
89 return 0.5f*(x-e) - 0.5f;
90 if (k == 1) {
91 if (x < -0.25f)
92 return -2.0f*(e-(x+0.5f));
93 return 1.0f + 2.0f*(x-e);
94 }
95 u.i = (0x7f+k)<<23; /* 2^k */
96 twopk = u.f;
97 if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */
98 y = x - e + 1.0f;
99 if (k == 128)
100 y = y*2.0f*0x1p127f;
101 else
102 y = y*twopk;
103 return y - 1.0f;
104 }
105 u.i = (0x7f-k)<<23; /* 2^-k */
106 if (k < 23)
107 y = (x-e+(1-u.f))*twopk;
108 else
109 y = (x-(e+u.f)+1)*twopk;
110 return y;
111}
libc/musl/src/math/expm1l.c created+123
......@@ -0,0 +1,123 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_expm1l.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Exponential function, minus 1
19 * Long double precision
20 *
21 *
22 * SYNOPSIS:
23 *
24 * long double x, y, expm1l();
25 *
26 * y = expm1l( x );
27 *
28 *
29 * DESCRIPTION:
30 *
31 * Returns e (2.71828...) raised to the x power, minus 1.
32 *
33 * Range reduction is accomplished by separating the argument
34 * into an integer k and fraction f such that
35 *
36 * x k f
37 * e = 2 e.
38 *
39 * An expansion x + .5 x^2 + x^3 R(x) approximates exp(f) - 1
40 * in the basic range [-0.5 ln 2, 0.5 ln 2].
41 *
42 *
43 * ACCURACY:
44 *
45 * Relative error:
46 * arithmetic domain # trials peak rms
47 * IEEE -45,+maxarg 200,000 1.2e-19 2.5e-20
48 */
49
50#include "libm.h"
51
52#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
53long double expm1l(long double x)
54{
55 return expm1(x);
56}
57#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
58
59/* exp(x) - 1 = x + 0.5 x^2 + x^3 P(x)/Q(x)
60 -.5 ln 2 < x < .5 ln 2
61 Theoretical peak relative error = 3.4e-22 */
62static const long double
63P0 = -1.586135578666346600772998894928250240826E4L,
64P1 = 2.642771505685952966904660652518429479531E3L,
65P2 = -3.423199068835684263987132888286791620673E2L,
66P3 = 1.800826371455042224581246202420972737840E1L,
67P4 = -5.238523121205561042771939008061958820811E-1L,
68Q0 = -9.516813471998079611319047060563358064497E4L,
69Q1 = 3.964866271411091674556850458227710004570E4L,
70Q2 = -7.207678383830091850230366618190187434796E3L,
71Q3 = 7.206038318724600171970199625081491823079E2L,
72Q4 = -4.002027679107076077238836622982900945173E1L,
73/* Q5 = 1.000000000000000000000000000000000000000E0 */
74/* C1 + C2 = ln 2 */
75C1 = 6.93145751953125E-1L,
76C2 = 1.428606820309417232121458176568075500134E-6L,
77/* ln 2^-65 */
78minarg = -4.5054566736396445112120088E1L,
79/* ln 2^16384 */
80maxarg = 1.1356523406294143949492E4L;
81
82long double expm1l(long double x)
83{
84 long double px, qx, xx;
85 int k;
86
87 if (isnan(x))
88 return x;
89 if (x > maxarg)
90 return x*0x1p16383L; /* overflow, unless x==inf */
91 if (x == 0.0)
92 return x;
93 if (x < minarg)
94 return -1.0;
95
96 xx = C1 + C2;
97 /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
98 px = floorl(0.5 + x / xx);
99 k = px;
100 /* remainder times ln 2 */
101 x -= px * C1;
102 x -= px * C2;
103
104 /* Approximate exp(remainder ln 2).*/
105 px = (((( P4 * x + P3) * x + P2) * x + P1) * x + P0) * x;
106 qx = (((( x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0;
107 xx = x * x;
108 qx = x + (0.5 * xx + xx * px / qx);
109
110 /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2).
111 We have qx = exp(remainder ln 2) - 1, so
112 exp(x) - 1 = 2^k (qx + 1) - 1 = 2^k qx + 2^k - 1. */
113 px = scalbnl(1.0, k);
114 x = px * qx + (px - 1.0);
115 return x;
116}
117#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
118// TODO: broken implementation to make things compile
119long double expm1l(long double x)
120{
121 return expm1(x);
122}
123#endif
libc/musl/src/math/fabs.c created+9
......@@ -0,0 +1,9 @@
1#include <math.h>
2#include <stdint.h>
3
4double fabs(double x)
5{
6 union {double f; uint64_t i;} u = {x};
7 u.i &= -1ULL/2;
8 return u.f;
9}
libc/musl/src/math/fabsf.c created+9
......@@ -0,0 +1,9 @@
1#include <math.h>
2#include <stdint.h>
3
4float fabsf(float x)
5{
6 union {float f; uint32_t i;} u = {x};
7 u.i &= 0x7fffffff;
8 return u.f;
9}
libc/musl/src/math/fabsl.c created+15
......@@ -0,0 +1,15 @@
1#include "libm.h"
2#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
3long double fabsl(long double x)
4{
5 return fabs(x);
6}
7#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
8long double fabsl(long double x)
9{
10 union ldshape u = {x};
11
12 u.i.se &= 0x7fff;
13 return u.f;
14}
15#endif
libc/musl/src/math/fdim.c created+10
......@@ -0,0 +1,10 @@
1#include <math.h>
2
3double fdim(double x, double y)
4{
5 if (isnan(x))
6 return x;
7 if (isnan(y))
8 return y;
9 return x > y ? x - y : 0;
10}
libc/musl/src/math/fdimf.c created+10
......@@ -0,0 +1,10 @@
1#include <math.h>
2
3float fdimf(float x, float y)
4{
5 if (isnan(x))
6 return x;
7 if (isnan(y))
8 return y;
9 return x > y ? x - y : 0;
10}
libc/musl/src/math/fdiml.c created+18
......@@ -0,0 +1,18 @@
1#include <math.h>
2#include <float.h>
3
4#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5long double fdiml(long double x, long double y)
6{
7 return fdim(x, y);
8}
9#else
10long double fdiml(long double x, long double y)
11{
12 if (isnan(x))
13 return x;
14 if (isnan(y))
15 return y;
16 return x > y ? x - y : 0;
17}
18#endif
libc/musl/src/math/finite.c created+7
......@@ -0,0 +1,7 @@
1#define _GNU_SOURCE
2#include <math.h>
3
4int finite(double x)
5{
6 return isfinite(x);
7}
libc/musl/src/math/finitef.c created+7
......@@ -0,0 +1,7 @@
1#define _GNU_SOURCE
2#include <math.h>
3
4int finitef(float x)
5{
6 return isfinite(x);
7}
libc/musl/src/math/floor.c created+31
......@@ -0,0 +1,31 @@
1#include "libm.h"
2
3#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
4#define EPS DBL_EPSILON
5#elif FLT_EVAL_METHOD==2
6#define EPS LDBL_EPSILON
7#endif
8static const double_t toint = 1/EPS;
9
10double floor(double x)
11{
12 union {double f; uint64_t i;} u = {x};
13 int e = u.i >> 52 & 0x7ff;
14 double_t y;
15
16 if (e >= 0x3ff+52 || x == 0)
17 return x;
18 /* y = int(x) - x, where int(x) is an integer neighbor of x */
19 if (u.i >> 63)
20 y = x - toint + toint - x;
21 else
22 y = x + toint - toint - x;
23 /* special case because of non-nearest rounding modes */
24 if (e <= 0x3ff-1) {
25 FORCE_EVAL(y);
26 return u.i >> 63 ? -1 : 0;
27 }
28 if (y > 0)
29 return x + y - 1;
30 return x + y;
31}
libc/musl/src/math/floorf.c created+27
......@@ -0,0 +1,27 @@
1#include "libm.h"
2
3float floorf(float x)
4{
5 union {float f; uint32_t i;} u = {x};
6 int e = (int)(u.i >> 23 & 0xff) - 0x7f;
7 uint32_t m;
8
9 if (e >= 23)
10 return x;
11 if (e >= 0) {
12 m = 0x007fffff >> e;
13 if ((u.i & m) == 0)
14 return x;
15 FORCE_EVAL(x + 0x1p120f);
16 if (u.i >> 31)
17 u.i += m;
18 u.i &= ~m;
19 } else {
20 FORCE_EVAL(x + 0x1p120f);
21 if (u.i >> 31 == 0)
22 u.i = 0;
23 else if (u.i << 1)
24 u.f = -1.0;
25 }
26 return u.f;
27}
libc/musl/src/math/floorl.c created+34
......@@ -0,0 +1,34 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double floorl(long double x)
5{
6 return floor(x);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9
10static const long double toint = 1/LDBL_EPSILON;
11
12long double floorl(long double x)
13{
14 union ldshape u = {x};
15 int e = u.i.se & 0x7fff;
16 long double y;
17
18 if (e >= 0x3fff+LDBL_MANT_DIG-1 || x == 0)
19 return x;
20 /* y = int(x) - x, where int(x) is an integer neighbor of x */
21 if (u.i.se >> 15)
22 y = x - toint + toint - x;
23 else
24 y = x + toint - toint - x;
25 /* special case because of non-nearest rounding modes */
26 if (e <= 0x3fff-1) {
27 FORCE_EVAL(y);
28 return u.i.se >> 15 ? -1 : 0;
29 }
30 if (y > 0)
31 return x + y - 1;
32 return x + y;
33}
34#endif
libc/musl/src/math/fma.c created+183
......@@ -0,0 +1,183 @@
1#include <stdint.h>
2#include <float.h>
3#include <math.h>
4#include "atomic.h"
5
6#define ASUINT64(x) ((union {double f; uint64_t i;}){x}).i
7#define ZEROINFNAN (0x7ff-0x3ff-52-1)
8
9struct num { uint64_t m; int e; int sign; };
10
11static struct num normalize(double x)
12{
13 uint64_t ix = ASUINT64(x);
14 int e = ix>>52;
15 int sign = e & 0x800;
16 e &= 0x7ff;
17 if (!e) {
18 ix = ASUINT64(x*0x1p63);
19 e = ix>>52 & 0x7ff;
20 e = e ? e-63 : 0x800;
21 }
22 ix &= (1ull<<52)-1;
23 ix |= 1ull<<52;
24 ix <<= 1;
25 e -= 0x3ff + 52 + 1;
26 return (struct num){ix,e,sign};
27}
28
29static void mul(uint64_t *hi, uint64_t *lo, uint64_t x, uint64_t y)
30{
31 uint64_t t1,t2,t3;
32 uint64_t xlo = (uint32_t)x, xhi = x>>32;
33 uint64_t ylo = (uint32_t)y, yhi = y>>32;
34
35 t1 = xlo*ylo;
36 t2 = xlo*yhi + xhi*ylo;
37 t3 = xhi*yhi;
38 *lo = t1 + (t2<<32);
39 *hi = t3 + (t2>>32) + (t1 > *lo);
40}
41
42double fma(double x, double y, double z)
43{
44 #pragma STDC FENV_ACCESS ON
45
46 /* normalize so top 10bits and last bit are 0 */
47 struct num nx, ny, nz;
48 nx = normalize(x);
49 ny = normalize(y);
50 nz = normalize(z);
51
52 if (nx.e >= ZEROINFNAN || ny.e >= ZEROINFNAN)
53 return x*y + z;
54 if (nz.e >= ZEROINFNAN) {
55 if (nz.e > ZEROINFNAN) /* z==0 */
56 return x*y + z;
57 return z;
58 }
59
60 /* mul: r = x*y */
61 uint64_t rhi, rlo, zhi, zlo;
62 mul(&rhi, &rlo, nx.m, ny.m);
63 /* either top 20 or 21 bits of rhi and last 2 bits of rlo are 0 */
64
65 /* align exponents */
66 int e = nx.e + ny.e;
67 int d = nz.e - e;
68 /* shift bits z<<=kz, r>>=kr, so kz+kr == d, set e = e+kr (== ez-kz) */
69 if (d > 0) {
70 if (d < 64) {
71 zlo = nz.m<<d;
72 zhi = nz.m>>64-d;
73 } else {
74 zlo = 0;
75 zhi = nz.m;
76 e = nz.e - 64;
77 d -= 64;
78 if (d == 0) {
79 } else if (d < 64) {
80 rlo = rhi<<64-d | rlo>>d | !!(rlo<<64-d);
81 rhi = rhi>>d;
82 } else {
83 rlo = 1;
84 rhi = 0;
85 }
86 }
87 } else {
88 zhi = 0;
89 d = -d;
90 if (d == 0) {
91 zlo = nz.m;
92 } else if (d < 64) {
93 zlo = nz.m>>d | !!(nz.m<<64-d);
94 } else {
95 zlo = 1;
96 }
97 }
98
99 /* add */
100 int sign = nx.sign^ny.sign;
101 int samesign = !(sign^nz.sign);
102 int nonzero = 1;
103 if (samesign) {
104 /* r += z */
105 rlo += zlo;
106 rhi += zhi + (rlo < zlo);
107 } else {
108 /* r -= z */
109 uint64_t t = rlo;
110 rlo -= zlo;
111 rhi = rhi - zhi - (t < rlo);
112 if (rhi>>63) {
113 rlo = -rlo;
114 rhi = -rhi-!!rlo;
115 sign = !sign;
116 }
117 nonzero = !!rhi;
118 }
119
120 /* set rhi to top 63bit of the result (last bit is sticky) */
121 if (nonzero) {
122 e += 64;
123 d = a_clz_64(rhi)-1;
124 /* note: d > 0 */
125 rhi = rhi<<d | rlo>>64-d | !!(rlo<<d);
126 } else if (rlo) {
127 d = a_clz_64(rlo)-1;
128 if (d < 0)
129 rhi = rlo>>1 | (rlo&1);
130 else
131 rhi = rlo<<d;
132 } else {
133 /* exact +-0 */
134 return x*y + z;
135 }
136 e -= d;
137
138 /* convert to double */
139 int64_t i = rhi; /* i is in [1<<62,(1<<63)-1] */
140 if (sign)
141 i = -i;
142 double r = i; /* |r| is in [0x1p62,0x1p63] */
143
144 if (e < -1022-62) {
145 /* result is subnormal before rounding */
146 if (e == -1022-63) {
147 double c = 0x1p63;
148 if (sign)
149 c = -c;
150 if (r == c) {
151 /* min normal after rounding, underflow depends
152 on arch behaviour which can be imitated by
153 a double to float conversion */
154 float fltmin = 0x0.ffffff8p-63*FLT_MIN * r;
155 return DBL_MIN/FLT_MIN * fltmin;
156 }
157 /* one bit is lost when scaled, add another top bit to
158 only round once at conversion if it is inexact */
159 if (rhi << 53) {
160 i = rhi>>1 | (rhi&1) | 1ull<<62;
161 if (sign)
162 i = -i;
163 r = i;
164 r = 2*r - c; /* remove top bit */
165
166 /* raise underflow portably, such that it
167 cannot be optimized away */
168 {
169 double_t tiny = DBL_MIN/FLT_MIN * r;
170 r += (double)(tiny*tiny) * (r-r);
171 }
172 }
173 } else {
174 /* only round once when scaled */
175 d = 10;
176 i = ( rhi>>d | !!(rhi<<64-d) ) << d;
177 if (sign)
178 i = -i;
179 r = i;
180 }
181 }
182 return scalbn(r, e);
183}
libc/musl/src/math/fmaf.c created+93
......@@ -0,0 +1,93 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_fmaf.c */
2/*-
3 * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <fenv.h>
29#include <math.h>
30#include <stdint.h>
31
32/*
33 * Fused multiply-add: Compute x * y + z with a single rounding error.
34 *
35 * A double has more than twice as much precision than a float, so
36 * direct double-precision arithmetic suffices, except where double
37 * rounding occurs.
38 */
39float fmaf(float x, float y, float z)
40{
41 #pragma STDC FENV_ACCESS ON
42 double xy, result;
43 union {double f; uint64_t i;} u;
44 int e;
45
46 xy = (double)x * y;
47 result = xy + z;
48 u.f = result;
49 e = u.i>>52 & 0x7ff;
50 /* Common case: The double precision result is fine. */
51 if ((u.i & 0x1fffffff) != 0x10000000 || /* not a halfway case */
52 e == 0x7ff || /* NaN */
53 (result - xy == z && result - z == xy) || /* exact */
54 fegetround() != FE_TONEAREST) /* not round-to-nearest */
55 {
56 /*
57 underflow may not be raised correctly, example:
58 fmaf(0x1p-120f, 0x1p-120f, 0x1p-149f)
59 */
60#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)
61 if (e < 0x3ff-126 && e >= 0x3ff-149 && fetestexcept(FE_INEXACT)) {
62 feclearexcept(FE_INEXACT);
63 /* TODO: gcc and clang bug workaround */
64 volatile float vz = z;
65 result = xy + vz;
66 if (fetestexcept(FE_INEXACT))
67 feraiseexcept(FE_UNDERFLOW);
68 else
69 feraiseexcept(FE_INEXACT);
70 }
71#endif
72 z = result;
73 return z;
74 }
75
76 /*
77 * If result is inexact, and exactly halfway between two float values,
78 * we need to adjust the low-order bit in the direction of the error.
79 */
80#ifdef FE_TOWARDZERO
81 fesetround(FE_TOWARDZERO);
82#endif
83 volatile double vxy = xy; /* XXX work around gcc CSE bug */
84 double adjusted_result = vxy + z;
85 fesetround(FE_TONEAREST);
86 if (result == adjusted_result) {
87 u.f = adjusted_result;
88 u.i++;
89 adjusted_result = u.f;
90 }
91 z = adjusted_result;
92 return z;
93}
libc/musl/src/math/fmal.c created+293
......@@ -0,0 +1,293 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_fmal.c */
2/*-
3 * Copyright (c) 2005-2011 David Schultz <das@FreeBSD.ORG>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28
29#include "libm.h"
30#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
31long double fmal(long double x, long double y, long double z)
32{
33 return fma(x, y, z);
34}
35#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
36#include <fenv.h>
37#if LDBL_MANT_DIG == 64
38#define LASTBIT(u) (u.i.m & 1)
39#define SPLIT (0x1p32L + 1)
40#elif LDBL_MANT_DIG == 113
41#define LASTBIT(u) (u.i.lo & 1)
42#define SPLIT (0x1p57L + 1)
43#endif
44
45/*
46 * A struct dd represents a floating-point number with twice the precision
47 * of a long double. We maintain the invariant that "hi" stores the high-order
48 * bits of the result.
49 */
50struct dd {
51 long double hi;
52 long double lo;
53};
54
55/*
56 * Compute a+b exactly, returning the exact result in a struct dd. We assume
57 * that both a and b are finite, but make no assumptions about their relative
58 * magnitudes.
59 */
60static inline struct dd dd_add(long double a, long double b)
61{
62 struct dd ret;
63 long double s;
64
65 ret.hi = a + b;
66 s = ret.hi - a;
67 ret.lo = (a - (ret.hi - s)) + (b - s);
68 return (ret);
69}
70
71/*
72 * Compute a+b, with a small tweak: The least significant bit of the
73 * result is adjusted into a sticky bit summarizing all the bits that
74 * were lost to rounding. This adjustment negates the effects of double
75 * rounding when the result is added to another number with a higher
76 * exponent. For an explanation of round and sticky bits, see any reference
77 * on FPU design, e.g.,
78 *
79 * J. Coonen. An Implementation Guide to a Proposed Standard for
80 * Floating-Point Arithmetic. Computer, vol. 13, no. 1, Jan 1980.
81 */
82static inline long double add_adjusted(long double a, long double b)
83{
84 struct dd sum;
85 union ldshape u;
86
87 sum = dd_add(a, b);
88 if (sum.lo != 0) {
89 u.f = sum.hi;
90 if (!LASTBIT(u))
91 sum.hi = nextafterl(sum.hi, INFINITY * sum.lo);
92 }
93 return (sum.hi);
94}
95
96/*
97 * Compute ldexp(a+b, scale) with a single rounding error. It is assumed
98 * that the result will be subnormal, and care is taken to ensure that
99 * double rounding does not occur.
100 */
101static inline long double add_and_denormalize(long double a, long double b, int scale)
102{
103 struct dd sum;
104 int bits_lost;
105 union ldshape u;
106
107 sum = dd_add(a, b);
108
109 /*
110 * If we are losing at least two bits of accuracy to denormalization,
111 * then the first lost bit becomes a round bit, and we adjust the
112 * lowest bit of sum.hi to make it a sticky bit summarizing all the
113 * bits in sum.lo. With the sticky bit adjusted, the hardware will
114 * break any ties in the correct direction.
115 *
116 * If we are losing only one bit to denormalization, however, we must
117 * break the ties manually.
118 */
119 if (sum.lo != 0) {
120 u.f = sum.hi;
121 bits_lost = -u.i.se - scale + 1;
122 if ((bits_lost != 1) ^ LASTBIT(u))
123 sum.hi = nextafterl(sum.hi, INFINITY * sum.lo);
124 }
125 return scalbnl(sum.hi, scale);
126}
127
128/*
129 * Compute a*b exactly, returning the exact result in a struct dd. We assume
130 * that both a and b are normalized, so no underflow or overflow will occur.
131 * The current rounding mode must be round-to-nearest.
132 */
133static inline struct dd dd_mul(long double a, long double b)
134{
135 struct dd ret;
136 long double ha, hb, la, lb, p, q;
137
138 p = a * SPLIT;
139 ha = a - p;
140 ha += p;
141 la = a - ha;
142
143 p = b * SPLIT;
144 hb = b - p;
145 hb += p;
146 lb = b - hb;
147
148 p = ha * hb;
149 q = ha * lb + la * hb;
150
151 ret.hi = p + q;
152 ret.lo = p - ret.hi + q + la * lb;
153 return (ret);
154}
155
156/*
157 * Fused multiply-add: Compute x * y + z with a single rounding error.
158 *
159 * We use scaling to avoid overflow/underflow, along with the
160 * canonical precision-doubling technique adapted from:
161 *
162 * Dekker, T. A Floating-Point Technique for Extending the
163 * Available Precision. Numer. Math. 18, 224-242 (1971).
164 */
165long double fmal(long double x, long double y, long double z)
166{
167 #pragma STDC FENV_ACCESS ON
168 long double xs, ys, zs, adj;
169 struct dd xy, r;
170 int oround;
171 int ex, ey, ez;
172 int spread;
173
174 /*
175 * Handle special cases. The order of operations and the particular
176 * return values here are crucial in handling special cases involving
177 * infinities, NaNs, overflows, and signed zeroes correctly.
178 */
179 if (!isfinite(x) || !isfinite(y))
180 return (x * y + z);
181 if (!isfinite(z))
182 return (z);
183 if (x == 0.0 || y == 0.0)
184 return (x * y + z);
185 if (z == 0.0)
186 return (x * y);
187
188 xs = frexpl(x, &ex);
189 ys = frexpl(y, &ey);
190 zs = frexpl(z, &ez);
191 oround = fegetround();
192 spread = ex + ey - ez;
193
194 /*
195 * If x * y and z are many orders of magnitude apart, the scaling
196 * will overflow, so we handle these cases specially. Rounding
197 * modes other than FE_TONEAREST are painful.
198 */
199 if (spread < -LDBL_MANT_DIG) {
200#ifdef FE_INEXACT
201 feraiseexcept(FE_INEXACT);
202#endif
203#ifdef FE_UNDERFLOW
204 if (!isnormal(z))
205 feraiseexcept(FE_UNDERFLOW);
206#endif
207 switch (oround) {
208 default: /* FE_TONEAREST */
209 return (z);
210#ifdef FE_TOWARDZERO
211 case FE_TOWARDZERO:
212 if (x > 0.0 ^ y < 0.0 ^ z < 0.0)
213 return (z);
214 else
215 return (nextafterl(z, 0));
216#endif
217#ifdef FE_DOWNWARD
218 case FE_DOWNWARD:
219 if (x > 0.0 ^ y < 0.0)
220 return (z);
221 else
222 return (nextafterl(z, -INFINITY));
223#endif
224#ifdef FE_UPWARD
225 case FE_UPWARD:
226 if (x > 0.0 ^ y < 0.0)
227 return (nextafterl(z, INFINITY));
228 else
229 return (z);
230#endif
231 }
232 }
233 if (spread <= LDBL_MANT_DIG * 2)
234 zs = scalbnl(zs, -spread);
235 else
236 zs = copysignl(LDBL_MIN, zs);
237
238 fesetround(FE_TONEAREST);
239
240 /*
241 * Basic approach for round-to-nearest:
242 *
243 * (xy.hi, xy.lo) = x * y (exact)
244 * (r.hi, r.lo) = xy.hi + z (exact)
245 * adj = xy.lo + r.lo (inexact; low bit is sticky)
246 * result = r.hi + adj (correctly rounded)
247 */
248 xy = dd_mul(xs, ys);
249 r = dd_add(xy.hi, zs);
250
251 spread = ex + ey;
252
253 if (r.hi == 0.0) {
254 /*
255 * When the addends cancel to 0, ensure that the result has
256 * the correct sign.
257 */
258 fesetround(oround);
259 volatile long double vzs = zs; /* XXX gcc CSE bug workaround */
260 return xy.hi + vzs + scalbnl(xy.lo, spread);
261 }
262
263 if (oround != FE_TONEAREST) {
264 /*
265 * There is no need to worry about double rounding in directed
266 * rounding modes.
267 * But underflow may not be raised correctly, example in downward rounding:
268 * fmal(0x1.0000000001p-16000L, 0x1.0000000001p-400L, -0x1p-16440L)
269 */
270 long double ret;
271#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)
272 int e = fetestexcept(FE_INEXACT);
273 feclearexcept(FE_INEXACT);
274#endif
275 fesetround(oround);
276 adj = r.lo + xy.lo;
277 ret = scalbnl(r.hi + adj, spread);
278#if defined(FE_INEXACT) && defined(FE_UNDERFLOW)
279 if (ilogbl(ret) < -16382 && fetestexcept(FE_INEXACT))
280 feraiseexcept(FE_UNDERFLOW);
281 else if (e)
282 feraiseexcept(FE_INEXACT);
283#endif
284 return ret;
285 }
286
287 adj = add_adjusted(r.lo, xy.lo);
288 if (spread + ilogbl(r.hi) > -16383)
289 return scalbnl(r.hi + adj, spread);
290 else
291 return add_and_denormalize(r.hi, adj, spread);
292}
293#endif
libc/musl/src/math/fmax.c created+13
......@@ -0,0 +1,13 @@
1#include <math.h>
2
3double fmax(double x, double y)
4{
5 if (isnan(x))
6 return y;
7 if (isnan(y))
8 return x;
9 /* handle signed zeros, see C99 Annex F.9.9.2 */
10 if (signbit(x) != signbit(y))
11 return signbit(x) ? y : x;
12 return x < y ? y : x;
13}
libc/musl/src/math/fmaxf.c created+13
......@@ -0,0 +1,13 @@
1#include <math.h>
2
3float fmaxf(float x, float y)
4{
5 if (isnan(x))
6 return y;
7 if (isnan(y))
8 return x;
9 /* handle signed zeroes, see C99 Annex F.9.9.2 */
10 if (signbit(x) != signbit(y))
11 return signbit(x) ? y : x;
12 return x < y ? y : x;
13}
libc/musl/src/math/fmaxl.c created+21
......@@ -0,0 +1,21 @@
1#include <math.h>
2#include <float.h>
3
4#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5long double fmaxl(long double x, long double y)
6{
7 return fmax(x, y);
8}
9#else
10long double fmaxl(long double x, long double y)
11{
12 if (isnan(x))
13 return y;
14 if (isnan(y))
15 return x;
16 /* handle signed zeros, see C99 Annex F.9.9.2 */
17 if (signbit(x) != signbit(y))
18 return signbit(x) ? y : x;
19 return x < y ? y : x;
20}
21#endif
libc/musl/src/math/fmin.c created+13
......@@ -0,0 +1,13 @@
1#include <math.h>
2
3double fmin(double x, double y)
4{
5 if (isnan(x))
6 return y;
7 if (isnan(y))
8 return x;
9 /* handle signed zeros, see C99 Annex F.9.9.2 */
10 if (signbit(x) != signbit(y))
11 return signbit(x) ? x : y;
12 return x < y ? x : y;
13}
libc/musl/src/math/fminf.c created+13
......@@ -0,0 +1,13 @@
1#include <math.h>
2
3float fminf(float x, float y)
4{
5 if (isnan(x))
6 return y;
7 if (isnan(y))
8 return x;
9 /* handle signed zeros, see C99 Annex F.9.9.2 */
10 if (signbit(x) != signbit(y))
11 return signbit(x) ? x : y;
12 return x < y ? x : y;
13}
libc/musl/src/math/fminl.c created+21
......@@ -0,0 +1,21 @@
1#include <math.h>
2#include <float.h>
3
4#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5long double fminl(long double x, long double y)
6{
7 return fmin(x, y);
8}
9#else
10long double fminl(long double x, long double y)
11{
12 if (isnan(x))
13 return y;
14 if (isnan(y))
15 return x;
16 /* handle signed zeros, see C99 Annex F.9.9.2 */
17 if (signbit(x) != signbit(y))
18 return signbit(x) ? x : y;
19 return x < y ? x : y;
20}
21#endif
libc/musl/src/math/fmod.c created+68
......@@ -0,0 +1,68 @@
1#include <math.h>
2#include <stdint.h>
3
4double fmod(double x, double y)
5{
6 union {double f; uint64_t i;} ux = {x}, uy = {y};
7 int ex = ux.i>>52 & 0x7ff;
8 int ey = uy.i>>52 & 0x7ff;
9 int sx = ux.i>>63;
10 uint64_t i;
11
12 /* in the followings uxi should be ux.i, but then gcc wrongly adds */
13 /* float load/store to inner loops ruining performance and code size */
14 uint64_t uxi = ux.i;
15
16 if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
17 return (x*y)/(x*y);
18 if (uxi<<1 <= uy.i<<1) {
19 if (uxi<<1 == uy.i<<1)
20 return 0*x;
21 return x;
22 }
23
24 /* normalize x and y */
25 if (!ex) {
26 for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);
27 uxi <<= -ex + 1;
28 } else {
29 uxi &= -1ULL >> 12;
30 uxi |= 1ULL << 52;
31 }
32 if (!ey) {
33 for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);
34 uy.i <<= -ey + 1;
35 } else {
36 uy.i &= -1ULL >> 12;
37 uy.i |= 1ULL << 52;
38 }
39
40 /* x mod y */
41 for (; ex > ey; ex--) {
42 i = uxi - uy.i;
43 if (i >> 63 == 0) {
44 if (i == 0)
45 return 0*x;
46 uxi = i;
47 }
48 uxi <<= 1;
49 }
50 i = uxi - uy.i;
51 if (i >> 63 == 0) {
52 if (i == 0)
53 return 0*x;
54 uxi = i;
55 }
56 for (; uxi>>52 == 0; uxi <<= 1, ex--);
57
58 /* scale result */
59 if (ex > 0) {
60 uxi -= 1ULL << 52;
61 uxi |= (uint64_t)ex << 52;
62 } else {
63 uxi >>= -ex + 1;
64 }
65 uxi |= (uint64_t)sx << 63;
66 ux.i = uxi;
67 return ux.f;
68}
libc/musl/src/math/fmodf.c created+65
......@@ -0,0 +1,65 @@
1#include <math.h>
2#include <stdint.h>
3
4float fmodf(float x, float y)
5{
6 union {float f; uint32_t i;} ux = {x}, uy = {y};
7 int ex = ux.i>>23 & 0xff;
8 int ey = uy.i>>23 & 0xff;
9 uint32_t sx = ux.i & 0x80000000;
10 uint32_t i;
11 uint32_t uxi = ux.i;
12
13 if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
14 return (x*y)/(x*y);
15 if (uxi<<1 <= uy.i<<1) {
16 if (uxi<<1 == uy.i<<1)
17 return 0*x;
18 return x;
19 }
20
21 /* normalize x and y */
22 if (!ex) {
23 for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);
24 uxi <<= -ex + 1;
25 } else {
26 uxi &= -1U >> 9;
27 uxi |= 1U << 23;
28 }
29 if (!ey) {
30 for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);
31 uy.i <<= -ey + 1;
32 } else {
33 uy.i &= -1U >> 9;
34 uy.i |= 1U << 23;
35 }
36
37 /* x mod y */
38 for (; ex > ey; ex--) {
39 i = uxi - uy.i;
40 if (i >> 31 == 0) {
41 if (i == 0)
42 return 0*x;
43 uxi = i;
44 }
45 uxi <<= 1;
46 }
47 i = uxi - uy.i;
48 if (i >> 31 == 0) {
49 if (i == 0)
50 return 0*x;
51 uxi = i;
52 }
53 for (; uxi>>23 == 0; uxi <<= 1, ex--);
54
55 /* scale result up */
56 if (ex > 0) {
57 uxi -= 1U << 23;
58 uxi |= (uint32_t)ex << 23;
59 } else {
60 uxi >>= -ex + 1;
61 }
62 uxi |= sx;
63 ux.i = uxi;
64 return ux.f;
65}
libc/musl/src/math/fmodl.c created+105
......@@ -0,0 +1,105 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double fmodl(long double x, long double y)
5{
6 return fmod(x, y);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9long double fmodl(long double x, long double y)
10{
11 union ldshape ux = {x}, uy = {y};
12 int ex = ux.i.se & 0x7fff;
13 int ey = uy.i.se & 0x7fff;
14 int sx = ux.i.se & 0x8000;
15
16 if (y == 0 || isnan(y) || ex == 0x7fff)
17 return (x*y)/(x*y);
18 ux.i.se = ex;
19 uy.i.se = ey;
20 if (ux.f <= uy.f) {
21 if (ux.f == uy.f)
22 return 0*x;
23 return x;
24 }
25
26 /* normalize x and y */
27 if (!ex) {
28 ux.f *= 0x1p120f;
29 ex = ux.i.se - 120;
30 }
31 if (!ey) {
32 uy.f *= 0x1p120f;
33 ey = uy.i.se - 120;
34 }
35
36 /* x mod y */
37#if LDBL_MANT_DIG == 64
38 uint64_t i, mx, my;
39 mx = ux.i.m;
40 my = uy.i.m;
41 for (; ex > ey; ex--) {
42 i = mx - my;
43 if (mx >= my) {
44 if (i == 0)
45 return 0*x;
46 mx = 2*i;
47 } else if (2*mx < mx) {
48 mx = 2*mx - my;
49 } else {
50 mx = 2*mx;
51 }
52 }
53 i = mx - my;
54 if (mx >= my) {
55 if (i == 0)
56 return 0*x;
57 mx = i;
58 }
59 for (; mx >> 63 == 0; mx *= 2, ex--);
60 ux.i.m = mx;
61#elif LDBL_MANT_DIG == 113
62 uint64_t hi, lo, xhi, xlo, yhi, ylo;
63 xhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48;
64 yhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48;
65 xlo = ux.i2.lo;
66 ylo = uy.i2.lo;
67 for (; ex > ey; ex--) {
68 hi = xhi - yhi;
69 lo = xlo - ylo;
70 if (xlo < ylo)
71 hi -= 1;
72 if (hi >> 63 == 0) {
73 if ((hi|lo) == 0)
74 return 0*x;
75 xhi = 2*hi + (lo>>63);
76 xlo = 2*lo;
77 } else {
78 xhi = 2*xhi + (xlo>>63);
79 xlo = 2*xlo;
80 }
81 }
82 hi = xhi - yhi;
83 lo = xlo - ylo;
84 if (xlo < ylo)
85 hi -= 1;
86 if (hi >> 63 == 0) {
87 if ((hi|lo) == 0)
88 return 0*x;
89 xhi = hi;
90 xlo = lo;
91 }
92 for (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--);
93 ux.i2.hi = xhi;
94 ux.i2.lo = xlo;
95#endif
96
97 /* scale result */
98 if (ex <= 0) {
99 ux.i.se = (ex+120)|sx;
100 ux.f *= 0x1p-120f;
101 } else
102 ux.i.se = ex|sx;
103 return ux.f;
104}
105#endif
libc/musl/src/math/frexp.c created+23
......@@ -0,0 +1,23 @@
1#include <math.h>
2#include <stdint.h>
3
4double frexp(double x, int *e)
5{
6 union { double d; uint64_t i; } y = { x };
7 int ee = y.i>>52 & 0x7ff;
8
9 if (!ee) {
10 if (x) {
11 x = frexp(x*0x1p64, e);
12 *e -= 64;
13 } else *e = 0;
14 return x;
15 } else if (ee == 0x7ff) {
16 return x;
17 }
18
19 *e = ee - 0x3fe;
20 y.i &= 0x800fffffffffffffull;
21 y.i |= 0x3fe0000000000000ull;
22 return y.d;
23}
libc/musl/src/math/frexpf.c created+23
......@@ -0,0 +1,23 @@
1#include <math.h>
2#include <stdint.h>
3
4float frexpf(float x, int *e)
5{
6 union { float f; uint32_t i; } y = { x };
7 int ee = y.i>>23 & 0xff;
8
9 if (!ee) {
10 if (x) {
11 x = frexpf(x*0x1p64, e);
12 *e -= 64;
13 } else *e = 0;
14 return x;
15 } else if (ee == 0xff) {
16 return x;
17 }
18
19 *e = ee - 0x7e;
20 y.i &= 0x807ffffful;
21 y.i |= 0x3f000000ul;
22 return y.f;
23}
libc/musl/src/math/frexpl.c created+29
......@@ -0,0 +1,29 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double frexpl(long double x, int *e)
5{
6 return frexp(x, e);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9long double frexpl(long double x, int *e)
10{
11 union ldshape u = {x};
12 int ee = u.i.se & 0x7fff;
13
14 if (!ee) {
15 if (x) {
16 x = frexpl(x*0x1p120, e);
17 *e -= 120;
18 } else *e = 0;
19 return x;
20 } else if (ee == 0x7fff) {
21 return x;
22 }
23
24 *e = ee - 0x3ffe;
25 u.i.se &= 0x8000;
26 u.i.se |= 0x3ffe;
27 return u.f;
28}
29#endif
libc/musl/src/math/hypot.c created+67
......@@ -0,0 +1,67 @@
1#include <math.h>
2#include <stdint.h>
3#include <float.h>
4
5#if FLT_EVAL_METHOD > 1U && LDBL_MANT_DIG == 64
6#define SPLIT (0x1p32 + 1)
7#else
8#define SPLIT (0x1p27 + 1)
9#endif
10
11static void sq(double_t *hi, double_t *lo, double x)
12{
13 double_t xh, xl, xc;
14
15 xc = (double_t)x*SPLIT;
16 xh = x - xc + xc;
17 xl = x - xh;
18 *hi = (double_t)x*x;
19 *lo = xh*xh - *hi + 2*xh*xl + xl*xl;
20}
21
22double hypot(double x, double y)
23{
24 union {double f; uint64_t i;} ux = {x}, uy = {y}, ut;
25 int ex, ey;
26 double_t hx, lx, hy, ly, z;
27
28 /* arrange |x| >= |y| */
29 ux.i &= -1ULL>>1;
30 uy.i &= -1ULL>>1;
31 if (ux.i < uy.i) {
32 ut = ux;
33 ux = uy;
34 uy = ut;
35 }
36
37 /* special cases */
38 ex = ux.i>>52;
39 ey = uy.i>>52;
40 x = ux.f;
41 y = uy.f;
42 /* note: hypot(inf,nan) == inf */
43 if (ey == 0x7ff)
44 return y;
45 if (ex == 0x7ff || uy.i == 0)
46 return x;
47 /* note: hypot(x,y) ~= x + y*y/x/2 with inexact for small y/x */
48 /* 64 difference is enough for ld80 double_t */
49 if (ex - ey > 64)
50 return x + y;
51
52 /* precise sqrt argument in nearest rounding mode without overflow */
53 /* xh*xh must not overflow and xl*xl must not underflow in sq */
54 z = 1;
55 if (ex > 0x3ff+510) {
56 z = 0x1p700;
57 x *= 0x1p-700;
58 y *= 0x1p-700;
59 } else if (ey < 0x3ff-450) {
60 z = 0x1p-700;
61 x *= 0x1p700;
62 y *= 0x1p700;
63 }
64 sq(&hx, &lx, x);
65 sq(&hy, &ly, y);
66 return z*sqrt(ly+lx+hy+hx);
67}
libc/musl/src/math/hypotf.c created+35
......@@ -0,0 +1,35 @@
1#include <math.h>
2#include <stdint.h>
3
4float hypotf(float x, float y)
5{
6 union {float f; uint32_t i;} ux = {x}, uy = {y}, ut;
7 float_t z;
8
9 ux.i &= -1U>>1;
10 uy.i &= -1U>>1;
11 if (ux.i < uy.i) {
12 ut = ux;
13 ux = uy;
14 uy = ut;
15 }
16
17 x = ux.f;
18 y = uy.f;
19 if (uy.i == 0xff<<23)
20 return y;
21 if (ux.i >= 0xff<<23 || uy.i == 0 || ux.i - uy.i >= 25<<23)
22 return x + y;
23
24 z = 1;
25 if (ux.i >= (0x7f+60)<<23) {
26 z = 0x1p90f;
27 x *= 0x1p-90f;
28 y *= 0x1p-90f;
29 } else if (uy.i < (0x7f-60)<<23) {
30 z = 0x1p-90f;
31 x *= 0x1p90f;
32 y *= 0x1p90f;
33 }
34 return z*sqrtf((double)x*x + (double)y*y);
35}
libc/musl/src/math/hypotl.c created+66
......@@ -0,0 +1,66 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double hypotl(long double x, long double y)
5{
6 return hypot(x, y);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9#if LDBL_MANT_DIG == 64
10#define SPLIT (0x1p32L+1)
11#elif LDBL_MANT_DIG == 113
12#define SPLIT (0x1p57L+1)
13#endif
14
15static void sq(long double *hi, long double *lo, long double x)
16{
17 long double xh, xl, xc;
18 xc = x*SPLIT;
19 xh = x - xc + xc;
20 xl = x - xh;
21 *hi = x*x;
22 *lo = xh*xh - *hi + 2*xh*xl + xl*xl;
23}
24
25long double hypotl(long double x, long double y)
26{
27 union ldshape ux = {x}, uy = {y};
28 int ex, ey;
29 long double hx, lx, hy, ly, z;
30
31 ux.i.se &= 0x7fff;
32 uy.i.se &= 0x7fff;
33 if (ux.i.se < uy.i.se) {
34 ex = uy.i.se;
35 ey = ux.i.se;
36 x = uy.f;
37 y = ux.f;
38 } else {
39 ex = ux.i.se;
40 ey = uy.i.se;
41 x = ux.f;
42 y = uy.f;
43 }
44
45 if (ex == 0x7fff && isinf(y))
46 return y;
47 if (ex == 0x7fff || y == 0)
48 return x;
49 if (ex - ey > LDBL_MANT_DIG)
50 return x + y;
51
52 z = 1;
53 if (ex > 0x3fff+8000) {
54 z = 0x1p10000L;
55 x *= 0x1p-10000L;
56 y *= 0x1p-10000L;
57 } else if (ey < 0x3fff-8000) {
58 z = 0x1p-10000L;
59 x *= 0x1p10000L;
60 y *= 0x1p10000L;
61 }
62 sq(&hx, &lx, x);
63 sq(&hy, &ly, y);
64 return z*sqrtl(ly+lx+hy+hx);
65}
66#endif
libc/musl/src/math/i386/__invtrigl.s created
libc/musl/src/math/i386/acos.s created+28
......@@ -0,0 +1,28 @@
1# use acos(x) = atan2(fabs(sqrt((1-x)*(1+x))), x)
2
3.global acosf
4.type acosf,@function
5acosf:
6 flds 4(%esp)
7 jmp 1f
8
9.global acosl
10.type acosl,@function
11acosl:
12 fldt 4(%esp)
13 jmp 1f
14
15.global acos
16.type acos,@function
17acos:
18 fldl 4(%esp)
191: fld %st(0)
20 fld1
21 fsub %st(0),%st(1)
22 fadd %st(2)
23 fmulp
24 fsqrt
25 fabs # fix sign of zero (matters in downward rounding mode)
26 fxch %st(1)
27 fpatan
28 ret
libc/musl/src/math/i386/acosf.s created+1
......@@ -0,0 +1 @@
1# see acos.s
libc/musl/src/math/i386/acosl.s created+1
......@@ -0,0 +1 @@
1# see acos.s
libc/musl/src/math/i386/asin.s created+45
......@@ -0,0 +1,45 @@
1.global asinf
2.type asinf,@function
3asinf:
4 flds 4(%esp)
5 mov 4(%esp),%eax
6 add %eax,%eax
7 cmp $0x01000000,%eax
8 jae 1f
9 # subnormal x, return x with underflow
10 fnstsw %ax
11 and $16,%ax
12 jnz 2f
13 fld %st(0)
14 fmul %st(1)
15 fstps 4(%esp)
162: ret
17
18.global asinl
19.type asinl,@function
20asinl:
21 fldt 4(%esp)
22 jmp 1f
23
24.global asin
25.type asin,@function
26asin:
27 fldl 4(%esp)
28 mov 8(%esp),%eax
29 add %eax,%eax
30 cmp $0x00200000,%eax
31 jae 1f
32 # subnormal x, return x with underflow
33 fnstsw %ax
34 and $16,%ax
35 jnz 2f
36 fsts 4(%esp)
372: ret
381: fld %st(0)
39 fld1
40 fsub %st(0),%st(1)
41 fadd %st(2)
42 fmulp
43 fsqrt
44 fpatan
45 ret
libc/musl/src/math/i386/asinf.s created+1
......@@ -0,0 +1 @@
1# see asin.s
libc/musl/src/math/i386/asinl.s created+1
......@@ -0,0 +1 @@
1# see asin.s
libc/musl/src/math/i386/atan.s created+17
......@@ -0,0 +1,17 @@
1.global atan
2.type atan,@function
3atan:
4 fldl 4(%esp)
5 mov 8(%esp),%eax
6 add %eax,%eax
7 cmp $0x00200000,%eax
8 jb 1f
9 fld1
10 fpatan
11 ret
12 # subnormal x, return x with underflow
131: fnstsw %ax
14 and $16,%ax
15 jnz 2f
16 fsts 4(%esp)
172: ret
libc/musl/src/math/i386/atan2.s created+17
......@@ -0,0 +1,17 @@
1.global atan2
2.type atan2,@function
3atan2:
4 fldl 4(%esp)
5 fldl 12(%esp)
6 fpatan
7 fstl 4(%esp)
8 mov 8(%esp),%eax
9 add %eax,%eax
10 cmp $0x00200000,%eax
11 jae 1f
12 # subnormal x, return x with underflow
13 fnstsw %ax
14 and $16,%ax
15 jnz 1f
16 fsts 4(%esp)
171: ret
libc/musl/src/math/i386/atan2f.s created+19
......@@ -0,0 +1,19 @@
1.global atan2f
2.type atan2f,@function
3atan2f:
4 flds 4(%esp)
5 flds 8(%esp)
6 fpatan
7 fsts 4(%esp)
8 mov 4(%esp),%eax
9 add %eax,%eax
10 cmp $0x01000000,%eax
11 jae 1f
12 # subnormal x, return x with underflow
13 fnstsw %ax
14 and $16,%ax
15 jnz 1f
16 fld %st(0)
17 fmul %st(1)
18 fstps 4(%esp)
191: ret
libc/musl/src/math/i386/atan2l.s created+7
......@@ -0,0 +1,7 @@
1.global atan2l
2.type atan2l,@function
3atan2l:
4 fldt 4(%esp)
5 fldt 16(%esp)
6 fpatan
7 ret
libc/musl/src/math/i386/atanf.s created+19
......@@ -0,0 +1,19 @@
1.global atanf
2.type atanf,@function
3atanf:
4 flds 4(%esp)
5 mov 4(%esp),%eax
6 add %eax,%eax
7 cmp $0x01000000,%eax
8 jb 1f
9 fld1
10 fpatan
11 ret
12 # subnormal x, return x with underflow
131: fnstsw %ax
14 and $16,%ax
15 jnz 2f
16 fld %st(0)
17 fmul %st(1)
18 fstps 4(%esp)
192: ret
libc/musl/src/math/i386/atanl.s created+7
......@@ -0,0 +1,7 @@
1.global atanl
2.type atanl,@function
3atanl:
4 fldt 4(%esp)
5 fld1
6 fpatan
7 ret
libc/musl/src/math/i386/ceil.s created+1
......@@ -0,0 +1 @@
1# see floor.s
libc/musl/src/math/i386/ceilf.s created+1
......@@ -0,0 +1 @@
1# see floor.s
libc/musl/src/math/i386/ceill.s created+1
......@@ -0,0 +1 @@
1# see floor.s
libc/musl/src/math/i386/exp.s created+152
......@@ -0,0 +1,152 @@
1.global expm1f
2.type expm1f,@function
3expm1f:
4 flds 4(%esp)
5 mov 4(%esp),%eax
6 add %eax,%eax
7 cmp $0x01000000,%eax
8 jae 1f
9 # subnormal x, return x with underflow
10 fnstsw %ax
11 and $16,%ax
12 jnz 2f
13 fld %st(0)
14 fmul %st(1)
15 fstps 4(%esp)
162: ret
17
18.global expm1l
19.type expm1l,@function
20expm1l:
21 fldt 4(%esp)
22 jmp 1f
23
24.global expm1
25.type expm1,@function
26expm1:
27 fldl 4(%esp)
28 mov 8(%esp),%eax
29 add %eax,%eax
30 cmp $0x00200000,%eax
31 jae 1f
32 # subnormal x, return x with underflow
33 fnstsw %ax
34 and $16,%ax
35 jnz 2f
36 fsts 4(%esp)
372: ret
381: fldl2e
39 fmulp
40 mov $0xc2820000,%eax
41 push %eax
42 flds (%esp)
43 pop %eax
44 fucomp %st(1)
45 fnstsw %ax
46 sahf
47 fld1
48 jb 1f
49 # x*log2e < -65, return -1 without underflow
50 fstp %st(1)
51 fchs
52 ret
531: fld %st(1)
54 fabs
55 fucom %st(1)
56 fnstsw %ax
57 fstp %st(0)
58 fstp %st(0)
59 sahf
60 ja 1f
61 f2xm1
62 ret
631: call 1f
64 fld1
65 fsubrp
66 ret
67
68.global exp2f
69.type exp2f,@function
70exp2f:
71 flds 4(%esp)
72 jmp 1f
73
74.global exp2l
75.global __exp2l
76.hidden __exp2l
77.type exp2l,@function
78exp2l:
79__exp2l:
80 fldt 4(%esp)
81 jmp 1f
82
83.global expf
84.type expf,@function
85expf:
86 flds 4(%esp)
87 jmp 2f
88
89.global exp
90.type exp,@function
91exp:
92 fldl 4(%esp)
932: fldl2e
94 fmulp
95 jmp 1f
96
97.global exp2
98.type exp2,@function
99exp2:
100 fldl 4(%esp)
1011: sub $12,%esp
102 fld %st(0)
103 fstpt (%esp)
104 mov 8(%esp),%ax
105 and $0x7fff,%ax
106 cmp $0x3fff+13,%ax
107 jb 4f # |x| < 8192
108 cmp $0x3fff+15,%ax
109 jae 3f # |x| >= 32768
110 fsts (%esp)
111 cmpl $0xc67ff800,(%esp)
112 jb 2f # x > -16382
113 movl $0x5f000000,(%esp)
114 flds (%esp) # 0x1p63
115 fld %st(1)
116 fsub %st(1)
117 faddp
118 fucomp %st(1)
119 fnstsw
120 sahf
121 je 2f # x - 0x1p63 + 0x1p63 == x
122 movl $1,(%esp)
123 flds (%esp) # 0x1p-149
124 fdiv %st(1)
125 fstps (%esp) # raise underflow
1262: fld1
127 fld %st(1)
128 frndint
129 fxch %st(2)
130 fsub %st(2) # st(0)=x-rint(x), st(1)=1, st(2)=rint(x)
131 f2xm1
132 faddp # 2^(x-rint(x))
1331: fscale
134 fstp %st(1)
135 add $12,%esp
136 ret
1373: xor %eax,%eax
1384: cmp $0x3fff-64,%ax
139 fld1
140 jb 1b # |x| < 0x1p-64
141 fstpt (%esp)
142 fistl 8(%esp)
143 fildl 8(%esp)
144 fsubrp %st(1)
145 addl $0x3fff,8(%esp)
146 f2xm1
147 fld1
148 faddp # 2^(x-rint(x))
149 fldt (%esp) # 2^rint(x)
150 fmulp
151 add $12,%esp
152 ret
libc/musl/src/math/i386/exp2.s created+1
......@@ -0,0 +1 @@
1# see exp.s
libc/musl/src/math/i386/exp2f.s created+1
......@@ -0,0 +1 @@
1# see exp.s
libc/musl/src/math/i386/exp2l.s created+1
......@@ -0,0 +1 @@
1# see exp.s
libc/musl/src/math/i386/expf.s created+1
......@@ -0,0 +1 @@
1# see exp.s
libc/musl/src/math/i386/expl.s created+101
......@@ -0,0 +1,101 @@
1# exp(x) = 2^hi + 2^hi (2^lo - 1)
2# where hi+lo = log2e*x with 128bit precision
3# exact log2e*x calculation depends on nearest rounding mode
4# using the exact multiplication method of Dekker and Veltkamp
5
6.global expl
7.type expl,@function
8expl:
9 fldt 4(%esp)
10
11 # interesting case: 0x1p-32 <= |x| < 16384
12 # check if (exponent|0x8000) is in [0xbfff-32, 0xbfff+13]
13 mov 12(%esp), %ax
14 or $0x8000, %ax
15 sub $0xbfdf, %ax
16 cmp $45, %ax
17 jbe 2f
18 test %ax, %ax
19 fld1
20 js 1f
21 # if |x|>=0x1p14 or nan return 2^trunc(x)
22 fscale
23 fstp %st(1)
24 ret
25 # if |x|<0x1p-32 return 1+x
261: faddp
27 ret
28
29 # should be 0x1.71547652b82fe178p0L == 0x3fff b8aa3b29 5c17f0bc
30 # it will be wrong on non-nearest rounding mode
312: fldl2e
32 subl $44, %esp
33 # hi = log2e_hi*x
34 # 2^hi = exp2l(hi)
35 fmul %st(1),%st
36 fld %st(0)
37 fstpt (%esp)
38 fstpt 16(%esp)
39 fstpt 32(%esp)
40.hidden __exp2l
41 call __exp2l
42 # if 2^hi == inf return 2^hi
43 fld %st(0)
44 fstpt (%esp)
45 cmpw $0x7fff, 8(%esp)
46 je 1f
47 fldt 32(%esp)
48 fldt 16(%esp)
49 # fpu stack: 2^hi x hi
50 # exact mult: x*log2e
51 fld %st(1)
52 # c = 0x1p32+1
53 pushl $0x41f00000
54 pushl $0x00100000
55 fldl (%esp)
56 # xh = x - c*x + c*x
57 # xl = x - xh
58 fmulp
59 fld %st(2)
60 fsub %st(1), %st
61 faddp
62 fld %st(2)
63 fsub %st(1), %st
64 # yh = log2e_hi - c*log2e_hi + c*log2e_hi
65 pushl $0x3ff71547
66 pushl $0x65200000
67 fldl (%esp)
68 # fpu stack: 2^hi x hi xh xl yh
69 # lo = hi - xh*yh + xl*yh
70 fld %st(2)
71 fmul %st(1), %st
72 fsubp %st, %st(4)
73 fmul %st(1), %st
74 faddp %st, %st(3)
75 # yl = log2e_hi - yh
76 pushl $0x3de705fc
77 pushl $0x2f000000
78 fldl (%esp)
79 # fpu stack: 2^hi x lo xh xl yl
80 # lo += xh*yl + xl*yl
81 fmul %st, %st(2)
82 fmulp %st, %st(1)
83 fxch %st(2)
84 faddp
85 faddp
86 # log2e_lo
87 pushl $0xbfbe
88 pushl $0x82f0025f
89 pushl $0x2dc582ee
90 fldt (%esp)
91 addl $36,%esp
92 # fpu stack: 2^hi x lo log2e_lo
93 # lo += log2e_lo*x
94 # return 2^hi + 2^hi (2^lo - 1)
95 fmulp %st, %st(2)
96 faddp
97 f2xm1
98 fmul %st(1), %st
99 faddp
1001: addl $44, %esp
101 ret
libc/musl/src/math/i386/expm1.s created+1
......@@ -0,0 +1 @@
1# see exp.s
libc/musl/src/math/i386/expm1f.s created+1
......@@ -0,0 +1 @@
1# see exp.s
libc/musl/src/math/i386/expm1l.s created+1
......@@ -0,0 +1 @@
1# see exp.s
libc/musl/src/math/i386/fabs.s created+6
......@@ -0,0 +1,6 @@
1.global fabs
2.type fabs,@function
3fabs:
4 fldl 4(%esp)
5 fabs
6 ret
libc/musl/src/math/i386/fabsf.s created+6
......@@ -0,0 +1,6 @@
1.global fabsf
2.type fabsf,@function
3fabsf:
4 flds 4(%esp)
5 fabs
6 ret
libc/musl/src/math/i386/fabsl.s created+6
......@@ -0,0 +1,6 @@
1.global fabsl
2.type fabsl,@function
3fabsl:
4 fldt 4(%esp)
5 fabs
6 ret
libc/musl/src/math/i386/floor.s created+67
......@@ -0,0 +1,67 @@
1.global floorf
2.type floorf,@function
3floorf:
4 flds 4(%esp)
5 jmp 1f
6
7.global floorl
8.type floorl,@function
9floorl:
10 fldt 4(%esp)
11 jmp 1f
12
13.global floor
14.type floor,@function
15floor:
16 fldl 4(%esp)
171: mov $0x7,%al
181: fstcw 4(%esp)
19 mov 5(%esp),%ah
20 mov %al,5(%esp)
21 fldcw 4(%esp)
22 frndint
23 mov %ah,5(%esp)
24 fldcw 4(%esp)
25 ret
26
27.global ceil
28.type ceil,@function
29ceil:
30 fldl 4(%esp)
31 mov $0xb,%al
32 jmp 1b
33
34.global ceilf
35.type ceilf,@function
36ceilf:
37 flds 4(%esp)
38 mov $0xb,%al
39 jmp 1b
40
41.global ceill
42.type ceill,@function
43ceill:
44 fldt 4(%esp)
45 mov $0xb,%al
46 jmp 1b
47
48.global trunc
49.type trunc,@function
50trunc:
51 fldl 4(%esp)
52 mov $0xf,%al
53 jmp 1b
54
55.global truncf
56.type truncf,@function
57truncf:
58 flds 4(%esp)
59 mov $0xf,%al
60 jmp 1b
61
62.global truncl
63.type truncl,@function
64truncl:
65 fldt 4(%esp)
66 mov $0xf,%al
67 jmp 1b
libc/musl/src/math/i386/floorf.s created+1
......@@ -0,0 +1 @@
1# see floor.s
libc/musl/src/math/i386/floorl.s created+1
......@@ -0,0 +1 @@
1# see floor.s
libc/musl/src/math/i386/fmod.s created+11
......@@ -0,0 +1,11 @@
1.global fmod
2.type fmod,@function
3fmod:
4 fldl 12(%esp)
5 fldl 4(%esp)
61: fprem
7 fnstsw %ax
8 sahf
9 jp 1b
10 fstp %st(1)
11 ret
libc/musl/src/math/i386/fmodf.s created+11
......@@ -0,0 +1,11 @@
1.global fmodf
2.type fmodf,@function
3fmodf:
4 flds 8(%esp)
5 flds 4(%esp)
61: fprem
7 fnstsw %ax
8 sahf
9 jp 1b
10 fstp %st(1)
11 ret
libc/musl/src/math/i386/fmodl.s created+11
......@@ -0,0 +1,11 @@
1.global fmodl
2.type fmodl,@function
3fmodl:
4 fldt 16(%esp)
5 fldt 4(%esp)
61: fprem
7 fnstsw %ax
8 sahf
9 jp 1b
10 fstp %st(1)
11 ret
libc/musl/src/math/i386/hypot.s created+45
......@@ -0,0 +1,45 @@
1.global hypot
2.type hypot,@function
3hypot:
4 mov 8(%esp),%eax
5 mov 16(%esp),%ecx
6 add %eax,%eax
7 add %ecx,%ecx
8 and %eax,%ecx
9 cmp $0xffe00000,%ecx
10 jae 2f
11 or 4(%esp),%eax
12 jnz 1f
13 fldl 12(%esp)
14 fabs
15 ret
161: mov 16(%esp),%eax
17 add %eax,%eax
18 or 12(%esp),%eax
19 jnz 1f
20 fldl 4(%esp)
21 fabs
22 ret
231: fldl 4(%esp)
24 fld %st(0)
25 fmulp
26 fldl 12(%esp)
27 fld %st(0)
28 fmulp
29 faddp
30 fsqrt
31 ret
322: sub $0xffe00000,%eax
33 or 4(%esp),%eax
34 jnz 1f
35 fldl 4(%esp)
36 fabs
37 ret
381: mov 16(%esp),%eax
39 add %eax,%eax
40 sub $0xffe00000,%eax
41 or 12(%esp),%eax
42 fldl 12(%esp)
43 jnz 1f
44 fabs
451: ret
libc/musl/src/math/i386/hypotf.s created+42
......@@ -0,0 +1,42 @@
1.global hypotf
2.type hypotf,@function
3hypotf:
4 mov 4(%esp),%eax
5 mov 8(%esp),%ecx
6 add %eax,%eax
7 add %ecx,%ecx
8 and %eax,%ecx
9 cmp $0xff000000,%ecx
10 jae 2f
11 test %eax,%eax
12 jnz 1f
13 flds 8(%esp)
14 fabs
15 ret
161: mov 8(%esp),%eax
17 add %eax,%eax
18 jnz 1f
19 flds 4(%esp)
20 fabs
21 ret
221: flds 4(%esp)
23 fld %st(0)
24 fmulp
25 flds 8(%esp)
26 fld %st(0)
27 fmulp
28 faddp
29 fsqrt
30 ret
312: cmp $0xff000000,%eax
32 jnz 1f
33 flds 4(%esp)
34 fabs
35 ret
361: mov 8(%esp),%eax
37 add %eax,%eax
38 cmp $0xff000000,%eax
39 flds 8(%esp)
40 jnz 1f
41 fabs
421: ret
libc/musl/src/math/i386/ldexp.s created+1
......@@ -0,0 +1 @@
1# see scalbn.s
libc/musl/src/math/i386/ldexpf.s created+1
......@@ -0,0 +1 @@
1# see scalbnf.s
libc/musl/src/math/i386/ldexpl.s created+1
......@@ -0,0 +1 @@
1# see scalbnl.s
libc/musl/src/math/i386/llrint.s created+8
......@@ -0,0 +1,8 @@
1.global llrint
2.type llrint,@function
3llrint:
4 fldl 4(%esp)
5 fistpll 4(%esp)
6 mov 4(%esp),%eax
7 mov 8(%esp),%edx
8 ret
libc/musl/src/math/i386/llrintf.s created+9
......@@ -0,0 +1,9 @@
1.global llrintf
2.type llrintf,@function
3llrintf:
4 sub $8,%esp
5 flds 12(%esp)
6 fistpll (%esp)
7 pop %eax
8 pop %edx
9 ret
libc/musl/src/math/i386/llrintl.s created+8
......@@ -0,0 +1,8 @@
1.global llrintl
2.type llrintl,@function
3llrintl:
4 fldt 4(%esp)
5 fistpll 4(%esp)
6 mov 4(%esp),%eax
7 mov 8(%esp),%edx
8 ret
libc/musl/src/math/i386/log.s created+7
......@@ -0,0 +1,7 @@
1.global log
2.type log,@function
3log:
4 fldln2
5 fldl 4(%esp)
6 fyl2x
7 ret
libc/musl/src/math/i386/log10.s created+7
......@@ -0,0 +1,7 @@
1.global log10
2.type log10,@function
3log10:
4 fldlg2
5 fldl 4(%esp)
6 fyl2x
7 ret
libc/musl/src/math/i386/log10f.s created+7
......@@ -0,0 +1,7 @@
1.global log10f
2.type log10f,@function
3log10f:
4 fldlg2
5 flds 4(%esp)
6 fyl2x
7 ret
libc/musl/src/math/i386/log10l.s created+7
......@@ -0,0 +1,7 @@
1.global log10l
2.type log10l,@function
3log10l:
4 fldlg2
5 fldt 4(%esp)
6 fyl2x
7 ret
libc/musl/src/math/i386/log1p.s created+24
......@@ -0,0 +1,24 @@
1.global log1p
2.type log1p,@function
3log1p:
4 mov 8(%esp),%eax
5 fldln2
6 and $0x7fffffff,%eax
7 fldl 4(%esp)
8 cmp $0x3fd28f00,%eax
9 ja 1f
10 cmp $0x00100000,%eax
11 jb 2f
12 fyl2xp1
13 ret
141: fld1
15 faddp
16 fyl2x
17 ret
18 # subnormal x, return x with underflow
192: fnstsw %ax
20 and $16,%ax
21 jnz 1f
22 fsts 4(%esp)
23 fstp %st(1)
241: ret
libc/musl/src/math/i386/log1pf.s created+25
......@@ -0,0 +1,25 @@
1.global log1pf
2.type log1pf,@function
3log1pf:
4 mov 4(%esp),%eax
5 fldln2
6 and $0x7fffffff,%eax
7 flds 4(%esp)
8 cmp $0x3e940000,%eax
9 ja 1f
10 cmp $0x00800000,%eax
11 jb 2f
12 fyl2xp1
13 ret
141: fld1
15 faddp
16 fyl2x
17 ret
18 # subnormal x, return x with underflow
192: fnstsw %ax
20 and $16,%ax
21 jnz 1f
22 fxch
23 fmul %st(1)
24 fstps 4(%esp)
251: ret
libc/musl/src/math/i386/log1pl.s created+15
......@@ -0,0 +1,15 @@
1.global log1pl
2.type log1pl,@function
3log1pl:
4 mov 10(%esp),%eax
5 fldln2
6 and $0x7fffffff,%eax
7 fldt 4(%esp)
8 cmp $0x3ffd9400,%eax
9 ja 1f
10 fyl2xp1
11 ret
121: fld1
13 faddp
14 fyl2x
15 ret
libc/musl/src/math/i386/log2.s created+7
......@@ -0,0 +1,7 @@
1.global log2
2.type log2,@function
3log2:
4 fld1
5 fldl 4(%esp)
6 fyl2x
7 ret
libc/musl/src/math/i386/log2f.s created+7
......@@ -0,0 +1,7 @@
1.global log2f
2.type log2f,@function
3log2f:
4 fld1
5 flds 4(%esp)
6 fyl2x
7 ret
libc/musl/src/math/i386/log2l.s created+7
......@@ -0,0 +1,7 @@
1.global log2l
2.type log2l,@function
3log2l:
4 fld1
5 fldt 4(%esp)
6 fyl2x
7 ret
libc/musl/src/math/i386/logf.s created+7
......@@ -0,0 +1,7 @@
1.global logf
2.type logf,@function
3logf:
4 fldln2
5 flds 4(%esp)
6 fyl2x
7 ret
libc/musl/src/math/i386/logl.s created+7
......@@ -0,0 +1,7 @@
1.global logl
2.type logl,@function
3logl:
4 fldln2
5 fldt 4(%esp)
6 fyl2x
7 ret
libc/musl/src/math/i386/lrint.s created+7
......@@ -0,0 +1,7 @@
1.global lrint
2.type lrint,@function
3lrint:
4 fldl 4(%esp)
5 fistpl 4(%esp)
6 mov 4(%esp),%eax
7 ret
libc/musl/src/math/i386/lrintf.s created+7
......@@ -0,0 +1,7 @@
1.global lrintf
2.type lrintf,@function
3lrintf:
4 flds 4(%esp)
5 fistpl 4(%esp)
6 mov 4(%esp),%eax
7 ret
libc/musl/src/math/i386/lrintl.s created+7
......@@ -0,0 +1,7 @@
1.global lrintl
2.type lrintl,@function
3lrintl:
4 fldt 4(%esp)
5 fistpl 4(%esp)
6 mov 4(%esp),%eax
7 ret
libc/musl/src/math/i386/remainder.s created+14
......@@ -0,0 +1,14 @@
1.global remainder
2.type remainder,@function
3remainder:
4.weak drem
5.type drem,@function
6drem:
7 fldl 12(%esp)
8 fldl 4(%esp)
91: fprem1
10 fnstsw %ax
11 sahf
12 jp 1b
13 fstp %st(1)
14 ret
libc/musl/src/math/i386/remainderf.s created+14
......@@ -0,0 +1,14 @@
1.global remainderf
2.type remainderf,@function
3remainderf:
4.weak dremf
5.type dremf,@function
6dremf:
7 flds 8(%esp)
8 flds 4(%esp)
91: fprem1
10 fnstsw %ax
11 sahf
12 jp 1b
13 fstp %st(1)
14 ret
libc/musl/src/math/i386/remainderl.s created+11
......@@ -0,0 +1,11 @@
1.global remainderl
2.type remainderl,@function
3remainderl:
4 fldt 16(%esp)
5 fldt 4(%esp)
61: fprem1
7 fnstsw %ax
8 sahf
9 jp 1b
10 fstp %st(1)
11 ret
libc/musl/src/math/i386/remquo.s created+50
......@@ -0,0 +1,50 @@
1.global remquof
2.type remquof,@function
3remquof:
4 mov 12(%esp),%ecx
5 flds 8(%esp)
6 flds 4(%esp)
7 mov 11(%esp),%dh
8 xor 7(%esp),%dh
9 jmp 1f
10
11.global remquol
12.type remquol,@function
13remquol:
14 mov 28(%esp),%ecx
15 fldt 16(%esp)
16 fldt 4(%esp)
17 mov 25(%esp),%dh
18 xor 13(%esp),%dh
19 jmp 1f
20
21.global remquo
22.type remquo,@function
23remquo:
24 mov 20(%esp),%ecx
25 fldl 12(%esp)
26 fldl 4(%esp)
27 mov 19(%esp),%dh
28 xor 11(%esp),%dh
291: fprem1
30 fnstsw %ax
31 sahf
32 jp 1b
33 fstp %st(1)
34 mov %ah,%dl
35 shr %dl
36 and $1,%dl
37 mov %ah,%al
38 shr $5,%al
39 and $2,%al
40 or %al,%dl
41 mov %ah,%al
42 shl $2,%al
43 and $4,%al
44 or %al,%dl
45 test %dh,%dh
46 jns 1f
47 neg %dl
481: movsbl %dl,%edx
49 mov %edx,(%ecx)
50 ret
libc/musl/src/math/i386/remquof.s created+1
......@@ -0,0 +1 @@
1# see remquo.s
libc/musl/src/math/i386/remquol.s created+1
......@@ -0,0 +1 @@
1# see remquo.s
libc/musl/src/math/i386/rint.s created+6
......@@ -0,0 +1,6 @@
1.global rint
2.type rint,@function
3rint:
4 fldl 4(%esp)
5 frndint
6 ret
libc/musl/src/math/i386/rintf.s created+6
......@@ -0,0 +1,6 @@
1.global rintf
2.type rintf,@function
3rintf:
4 flds 4(%esp)
5 frndint
6 ret
libc/musl/src/math/i386/rintl.s created+6
......@@ -0,0 +1,6 @@
1.global rintl
2.type rintl,@function
3rintl:
4 fldt 4(%esp)
5 frndint
6 ret
libc/musl/src/math/i386/scalbln.s created+1
......@@ -0,0 +1 @@
1# see scalbn.s
libc/musl/src/math/i386/scalblnf.s created+1
......@@ -0,0 +1 @@
1# see scalbnf.s
libc/musl/src/math/i386/scalblnl.s created+1
......@@ -0,0 +1 @@
1# see scalbnl.s
libc/musl/src/math/i386/scalbn.s created+33
......@@ -0,0 +1,33 @@
1.global ldexp
2.type ldexp,@function
3ldexp:
4 nop
5
6.global scalbln
7.type scalbln,@function
8scalbln:
9 nop
10
11.global scalbn
12.type scalbn,@function
13scalbn:
14 mov 12(%esp),%eax
15 add $0x3ffe,%eax
16 cmp $0x7ffd,%eax
17 jb 1f
18 sub $0x3ffe,%eax
19 sar $31,%eax
20 xor $0xfff,%eax
21 add $0x3ffe,%eax
221: inc %eax
23 fldl 4(%esp)
24 mov %eax,12(%esp)
25 mov $0x80000000,%eax
26 mov %eax,8(%esp)
27 xor %eax,%eax
28 mov %eax,4(%esp)
29 fldt 4(%esp)
30 fmulp
31 fstpl 4(%esp)
32 fldl 4(%esp)
33 ret
libc/musl/src/math/i386/scalbnf.s created+32
......@@ -0,0 +1,32 @@
1.global ldexpf
2.type ldexpf,@function
3ldexpf:
4 nop
5
6.global scalblnf
7.type scalblnf,@function
8scalblnf:
9 nop
10
11.global scalbnf
12.type scalbnf,@function
13scalbnf:
14 mov 8(%esp),%eax
15 add $0x3fe,%eax
16 cmp $0x7fd,%eax
17 jb 1f
18 sub $0x3fe,%eax
19 sar $31,%eax
20 xor $0x1ff,%eax
21 add $0x3fe,%eax
221: inc %eax
23 shl $20,%eax
24 flds 4(%esp)
25 mov %eax,8(%esp)
26 xor %eax,%eax
27 mov %eax,4(%esp)
28 fldl 4(%esp)
29 fmulp
30 fstps 4(%esp)
31 flds 4(%esp)
32 ret
libc/musl/src/math/i386/scalbnl.s created+32
......@@ -0,0 +1,32 @@
1.global ldexpl
2.type ldexpl,@function
3ldexpl:
4 nop
5
6.global scalblnl
7.type scalblnl,@function
8scalblnl:
9 nop
10
11.global scalbnl
12.type scalbnl,@function
13scalbnl:
14 mov 16(%esp),%eax
15 add $0x3ffe,%eax
16 cmp $0x7ffd,%eax
17 jae 1f
18 inc %eax
19 fldt 4(%esp)
20 mov %eax,12(%esp)
21 mov $0x80000000,%eax
22 mov %eax,8(%esp)
23 xor %eax,%eax
24 mov %eax,4(%esp)
25 fldt 4(%esp)
26 fmulp
27 ret
281: fildl 16(%esp)
29 fldt 4(%esp)
30 fscale
31 fstp %st(1)
32 ret
libc/musl/src/math/i386/sqrt.s created+21
......@@ -0,0 +1,21 @@
1.global sqrt
2.type sqrt,@function
3sqrt: fldl 4(%esp)
4 fsqrt
5 fnstsw %ax
6 sub $12,%esp
7 fld %st(0)
8 fstpt (%esp)
9 mov (%esp),%ecx
10 and $0x7ff,%ecx
11 cmp $0x400,%ecx
12 jnz 1f
13 and $0x200,%eax
14 sub $0x100,%eax
15 sub %eax,(%esp)
16 fstp %st(0)
17 fldt (%esp)
181: add $12,%esp
19 fstpl 4(%esp)
20 fldl 4(%esp)
21 ret
libc/musl/src/math/i386/sqrtf.s created+7
......@@ -0,0 +1,7 @@
1.global sqrtf
2.type sqrtf,@function
3sqrtf: flds 4(%esp)
4 fsqrt
5 fstps 4(%esp)
6 flds 4(%esp)
7 ret
libc/musl/src/math/i386/sqrtl.s created+5
......@@ -0,0 +1,5 @@
1.global sqrtl
2.type sqrtl,@function
3sqrtl: fldt 4(%esp)
4 fsqrt
5 ret
libc/musl/src/math/i386/trunc.s created+1
......@@ -0,0 +1 @@
1# see floor.s
libc/musl/src/math/i386/truncf.s created+1
......@@ -0,0 +1 @@
1# see floor.s
libc/musl/src/math/i386/truncl.s created+1
......@@ -0,0 +1 @@
1# see floor.s
libc/musl/src/math/ilogb.c created+26
......@@ -0,0 +1,26 @@
1#include <limits.h>
2#include "libm.h"
3
4int ilogb(double x)
5{
6 #pragma STDC FENV_ACCESS ON
7 union {double f; uint64_t i;} u = {x};
8 uint64_t i = u.i;
9 int e = i>>52 & 0x7ff;
10
11 if (!e) {
12 i <<= 12;
13 if (i == 0) {
14 FORCE_EVAL(0/0.0f);
15 return FP_ILOGB0;
16 }
17 /* subnormal x */
18 for (e = -0x3ff; i>>63 == 0; e--, i<<=1);
19 return e;
20 }
21 if (e == 0x7ff) {
22 FORCE_EVAL(0/0.0f);
23 return i<<12 ? FP_ILOGBNAN : INT_MAX;
24 }
25 return e - 0x3ff;
26}
libc/musl/src/math/ilogbf.c created+26
......@@ -0,0 +1,26 @@
1#include <limits.h>
2#include "libm.h"
3
4int ilogbf(float x)
5{
6 #pragma STDC FENV_ACCESS ON
7 union {float f; uint32_t i;} u = {x};
8 uint32_t i = u.i;
9 int e = i>>23 & 0xff;
10
11 if (!e) {
12 i <<= 9;
13 if (i == 0) {
14 FORCE_EVAL(0/0.0f);
15 return FP_ILOGB0;
16 }
17 /* subnormal x */
18 for (e = -0x7f; i>>31 == 0; e--, i<<=1);
19 return e;
20 }
21 if (e == 0xff) {
22 FORCE_EVAL(0/0.0f);
23 return i<<9 ? FP_ILOGBNAN : INT_MAX;
24 }
25 return e - 0x7f;
26}
libc/musl/src/math/ilogbl.c created+55
......@@ -0,0 +1,55 @@
1#include <limits.h>
2#include "libm.h"
3
4#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5int ilogbl(long double x)
6{
7 return ilogb(x);
8}
9#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
10int ilogbl(long double x)
11{
12 #pragma STDC FENV_ACCESS ON
13 union ldshape u = {x};
14 uint64_t m = u.i.m;
15 int e = u.i.se & 0x7fff;
16
17 if (!e) {
18 if (m == 0) {
19 FORCE_EVAL(0/0.0f);
20 return FP_ILOGB0;
21 }
22 /* subnormal x */
23 for (e = -0x3fff+1; m>>63 == 0; e--, m<<=1);
24 return e;
25 }
26 if (e == 0x7fff) {
27 FORCE_EVAL(0/0.0f);
28 return m<<1 ? FP_ILOGBNAN : INT_MAX;
29 }
30 return e - 0x3fff;
31}
32#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
33int ilogbl(long double x)
34{
35 #pragma STDC FENV_ACCESS ON
36 union ldshape u = {x};
37 int e = u.i.se & 0x7fff;
38
39 if (!e) {
40 if (x == 0) {
41 FORCE_EVAL(0/0.0f);
42 return FP_ILOGB0;
43 }
44 /* subnormal x */
45 x *= 0x1p120;
46 return ilogbl(x) - 120;
47 }
48 if (e == 0x7fff) {
49 FORCE_EVAL(0/0.0f);
50 u.i.se = 0;
51 return u.f ? FP_ILOGBNAN : INT_MAX;
52 }
53 return e - 0x3fff;
54}
55#endif
libc/musl/src/math/j0.c created+375
......@@ -0,0 +1,375 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_j0.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* j0(x), y0(x)
13 * Bessel function of the first and second kinds of order zero.
14 * Method -- j0(x):
15 * 1. For tiny x, we use j0(x) = 1 - x^2/4 + x^4/64 - ...
16 * 2. Reduce x to |x| since j0(x)=j0(-x), and
17 * for x in (0,2)
18 * j0(x) = 1-z/4+ z^2*R0/S0, where z = x*x;
19 * (precision: |j0-1+z/4-z^2R0/S0 |<2**-63.67 )
20 * for x in (2,inf)
21 * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)-q0(x)*sin(x0))
22 * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
23 * as follow:
24 * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
25 * = 1/sqrt(2) * (cos(x) + sin(x))
26 * sin(x0) = sin(x)cos(pi/4)-cos(x)sin(pi/4)
27 * = 1/sqrt(2) * (sin(x) - cos(x))
28 * (To avoid cancellation, use
29 * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
30 * to compute the worse one.)
31 *
32 * 3 Special cases
33 * j0(nan)= nan
34 * j0(0) = 1
35 * j0(inf) = 0
36 *
37 * Method -- y0(x):
38 * 1. For x<2.
39 * Since
40 * y0(x) = 2/pi*(j0(x)*(ln(x/2)+Euler) + x^2/4 - ...)
41 * therefore y0(x)-2/pi*j0(x)*ln(x) is an even function.
42 * We use the following function to approximate y0,
43 * y0(x) = U(z)/V(z) + (2/pi)*(j0(x)*ln(x)), z= x^2
44 * where
45 * U(z) = u00 + u01*z + ... + u06*z^6
46 * V(z) = 1 + v01*z + ... + v04*z^4
47 * with absolute approximation error bounded by 2**-72.
48 * Note: For tiny x, U/V = u0 and j0(x)~1, hence
49 * y0(tiny) = u0 + (2/pi)*ln(tiny), (choose tiny<2**-27)
50 * 2. For x>=2.
51 * y0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x0)+q0(x)*sin(x0))
52 * where x0 = x-pi/4. It is better to compute sin(x0),cos(x0)
53 * by the method mentioned above.
54 * 3. Special cases: y0(0)=-inf, y0(x<0)=NaN, y0(inf)=0.
55 */
56
57#include "libm.h"
58
59static double pzero(double), qzero(double);
60
61static const double
62invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
63tpi = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */
64
65/* common method when |x|>=2 */
66static double common(uint32_t ix, double x, int y0)
67{
68 double s,c,ss,cc,z;
69
70 /*
71 * j0(x) = sqrt(2/(pi*x))*(p0(x)*cos(x-pi/4)-q0(x)*sin(x-pi/4))
72 * y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x-pi/4)+q0(x)*cos(x-pi/4))
73 *
74 * sin(x-pi/4) = (sin(x) - cos(x))/sqrt(2)
75 * cos(x-pi/4) = (sin(x) + cos(x))/sqrt(2)
76 * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
77 */
78 s = sin(x);
79 c = cos(x);
80 if (y0)
81 c = -c;
82 cc = s+c;
83 /* avoid overflow in 2*x, big ulp error when x>=0x1p1023 */
84 if (ix < 0x7fe00000) {
85 ss = s-c;
86 z = -cos(2*x);
87 if (s*c < 0)
88 cc = z/ss;
89 else
90 ss = z/cc;
91 if (ix < 0x48000000) {
92 if (y0)
93 ss = -ss;
94 cc = pzero(x)*cc-qzero(x)*ss;
95 }
96 }
97 return invsqrtpi*cc/sqrt(x);
98}
99
100/* R0/S0 on [0, 2.00] */
101static const double
102R02 = 1.56249999999999947958e-02, /* 0x3F8FFFFF, 0xFFFFFFFD */
103R03 = -1.89979294238854721751e-04, /* 0xBF28E6A5, 0xB61AC6E9 */
104R04 = 1.82954049532700665670e-06, /* 0x3EBEB1D1, 0x0C503919 */
105R05 = -4.61832688532103189199e-09, /* 0xBE33D5E7, 0x73D63FCE */
106S01 = 1.56191029464890010492e-02, /* 0x3F8FFCE8, 0x82C8C2A4 */
107S02 = 1.16926784663337450260e-04, /* 0x3F1EA6D2, 0xDD57DBF4 */
108S03 = 5.13546550207318111446e-07, /* 0x3EA13B54, 0xCE84D5A9 */
109S04 = 1.16614003333790000205e-09; /* 0x3E1408BC, 0xF4745D8F */
110
111double j0(double x)
112{
113 double z,r,s;
114 uint32_t ix;
115
116 GET_HIGH_WORD(ix, x);
117 ix &= 0x7fffffff;
118
119 /* j0(+-inf)=0, j0(nan)=nan */
120 if (ix >= 0x7ff00000)
121 return 1/(x*x);
122 x = fabs(x);
123
124 if (ix >= 0x40000000) { /* |x| >= 2 */
125 /* large ulp error near zeros: 2.4, 5.52, 8.6537,.. */
126 return common(ix,x,0);
127 }
128
129 /* 1 - x*x/4 + x*x*R(x^2)/S(x^2) */
130 if (ix >= 0x3f200000) { /* |x| >= 2**-13 */
131 /* up to 4ulp error close to 2 */
132 z = x*x;
133 r = z*(R02+z*(R03+z*(R04+z*R05)));
134 s = 1+z*(S01+z*(S02+z*(S03+z*S04)));
135 return (1+x/2)*(1-x/2) + z*(r/s);
136 }
137
138 /* 1 - x*x/4 */
139 /* prevent underflow */
140 /* inexact should be raised when x!=0, this is not done correctly */
141 if (ix >= 0x38000000) /* |x| >= 2**-127 */
142 x = 0.25*x*x;
143 return 1 - x;
144}
145
146static const double
147u00 = -7.38042951086872317523e-02, /* 0xBFB2E4D6, 0x99CBD01F */
148u01 = 1.76666452509181115538e-01, /* 0x3FC69D01, 0x9DE9E3FC */
149u02 = -1.38185671945596898896e-02, /* 0xBF8C4CE8, 0xB16CFA97 */
150u03 = 3.47453432093683650238e-04, /* 0x3F36C54D, 0x20B29B6B */
151u04 = -3.81407053724364161125e-06, /* 0xBECFFEA7, 0x73D25CAD */
152u05 = 1.95590137035022920206e-08, /* 0x3E550057, 0x3B4EABD4 */
153u06 = -3.98205194132103398453e-11, /* 0xBDC5E43D, 0x693FB3C8 */
154v01 = 1.27304834834123699328e-02, /* 0x3F8A1270, 0x91C9C71A */
155v02 = 7.60068627350353253702e-05, /* 0x3F13ECBB, 0xF578C6C1 */
156v03 = 2.59150851840457805467e-07, /* 0x3E91642D, 0x7FF202FD */
157v04 = 4.41110311332675467403e-10; /* 0x3DFE5018, 0x3BD6D9EF */
158
159double y0(double x)
160{
161 double z,u,v;
162 uint32_t ix,lx;
163
164 EXTRACT_WORDS(ix, lx, x);
165
166 /* y0(nan)=nan, y0(<0)=nan, y0(0)=-inf, y0(inf)=0 */
167 if ((ix<<1 | lx) == 0)
168 return -1/0.0;
169 if (ix>>31)
170 return 0/0.0;
171 if (ix >= 0x7ff00000)
172 return 1/x;
173
174 if (ix >= 0x40000000) { /* x >= 2 */
175 /* large ulp errors near zeros: 3.958, 7.086,.. */
176 return common(ix,x,1);
177 }
178
179 /* U(x^2)/V(x^2) + (2/pi)*j0(x)*log(x) */
180 if (ix >= 0x3e400000) { /* x >= 2**-27 */
181 /* large ulp error near the first zero, x ~= 0.89 */
182 z = x*x;
183 u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
184 v = 1.0+z*(v01+z*(v02+z*(v03+z*v04)));
185 return u/v + tpi*(j0(x)*log(x));
186 }
187 return u00 + tpi*log(x);
188}
189
190/* The asymptotic expansions of pzero is
191 * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x.
192 * For x >= 2, We approximate pzero by
193 * pzero(x) = 1 + (R/S)
194 * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
195 * S = 1 + pS0*s^2 + ... + pS4*s^10
196 * and
197 * | pzero(x)-1-R/S | <= 2 ** ( -60.26)
198 */
199static const double pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
200 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
201 -7.03124999999900357484e-02, /* 0xBFB1FFFF, 0xFFFFFD32 */
202 -8.08167041275349795626e+00, /* 0xC02029D0, 0xB44FA779 */
203 -2.57063105679704847262e+02, /* 0xC0701102, 0x7B19E863 */
204 -2.48521641009428822144e+03, /* 0xC0A36A6E, 0xCD4DCAFC */
205 -5.25304380490729545272e+03, /* 0xC0B4850B, 0x36CC643D */
206};
207static const double pS8[5] = {
208 1.16534364619668181717e+02, /* 0x405D2233, 0x07A96751 */
209 3.83374475364121826715e+03, /* 0x40ADF37D, 0x50596938 */
210 4.05978572648472545552e+04, /* 0x40E3D2BB, 0x6EB6B05F */
211 1.16752972564375915681e+05, /* 0x40FC810F, 0x8F9FA9BD */
212 4.76277284146730962675e+04, /* 0x40E74177, 0x4F2C49DC */
213};
214
215static const double pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
216 -1.14125464691894502584e-11, /* 0xBDA918B1, 0x47E495CC */
217 -7.03124940873599280078e-02, /* 0xBFB1FFFF, 0xE69AFBC6 */
218 -4.15961064470587782438e+00, /* 0xC010A370, 0xF90C6BBF */
219 -6.76747652265167261021e+01, /* 0xC050EB2F, 0x5A7D1783 */
220 -3.31231299649172967747e+02, /* 0xC074B3B3, 0x6742CC63 */
221 -3.46433388365604912451e+02, /* 0xC075A6EF, 0x28A38BD7 */
222};
223static const double pS5[5] = {
224 6.07539382692300335975e+01, /* 0x404E6081, 0x0C98C5DE */
225 1.05125230595704579173e+03, /* 0x40906D02, 0x5C7E2864 */
226 5.97897094333855784498e+03, /* 0x40B75AF8, 0x8FBE1D60 */
227 9.62544514357774460223e+03, /* 0x40C2CCB8, 0xFA76FA38 */
228 2.40605815922939109441e+03, /* 0x40A2CC1D, 0xC70BE864 */
229};
230
231static const double pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
232 -2.54704601771951915620e-09, /* 0xBE25E103, 0x6FE1AA86 */
233 -7.03119616381481654654e-02, /* 0xBFB1FFF6, 0xF7C0E24B */
234 -2.40903221549529611423e+00, /* 0xC00345B2, 0xAEA48074 */
235 -2.19659774734883086467e+01, /* 0xC035F74A, 0x4CB94E14 */
236 -5.80791704701737572236e+01, /* 0xC04D0A22, 0x420A1A45 */
237 -3.14479470594888503854e+01, /* 0xC03F72AC, 0xA892D80F */
238};
239static const double pS3[5] = {
240 3.58560338055209726349e+01, /* 0x4041ED92, 0x84077DD3 */
241 3.61513983050303863820e+02, /* 0x40769839, 0x464A7C0E */
242 1.19360783792111533330e+03, /* 0x4092A66E, 0x6D1061D6 */
243 1.12799679856907414432e+03, /* 0x40919FFC, 0xB8C39B7E */
244 1.73580930813335754692e+02, /* 0x4065B296, 0xFC379081 */
245};
246
247static const double pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
248 -8.87534333032526411254e-08, /* 0xBE77D316, 0xE927026D */
249 -7.03030995483624743247e-02, /* 0xBFB1FF62, 0x495E1E42 */
250 -1.45073846780952986357e+00, /* 0xBFF73639, 0x8A24A843 */
251 -7.63569613823527770791e+00, /* 0xC01E8AF3, 0xEDAFA7F3 */
252 -1.11931668860356747786e+01, /* 0xC02662E6, 0xC5246303 */
253 -3.23364579351335335033e+00, /* 0xC009DE81, 0xAF8FE70F */
254};
255static const double pS2[5] = {
256 2.22202997532088808441e+01, /* 0x40363865, 0x908B5959 */
257 1.36206794218215208048e+02, /* 0x4061069E, 0x0EE8878F */
258 2.70470278658083486789e+02, /* 0x4070E786, 0x42EA079B */
259 1.53875394208320329881e+02, /* 0x40633C03, 0x3AB6FAFF */
260 1.46576176948256193810e+01, /* 0x402D50B3, 0x44391809 */
261};
262
263static double pzero(double x)
264{
265 const double *p,*q;
266 double_t z,r,s;
267 uint32_t ix;
268
269 GET_HIGH_WORD(ix, x);
270 ix &= 0x7fffffff;
271 if (ix >= 0x40200000){p = pR8; q = pS8;}
272 else if (ix >= 0x40122E8B){p = pR5; q = pS5;}
273 else if (ix >= 0x4006DB6D){p = pR3; q = pS3;}
274 else /*ix >= 0x40000000*/ {p = pR2; q = pS2;}
275 z = 1.0/(x*x);
276 r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
277 s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
278 return 1.0 + r/s;
279}
280
281
282/* For x >= 8, the asymptotic expansions of qzero is
283 * -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
284 * We approximate pzero by
285 * qzero(x) = s*(-1.25 + (R/S))
286 * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
287 * S = 1 + qS0*s^2 + ... + qS5*s^12
288 * and
289 * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22)
290 */
291static const double qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
292 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
293 7.32421874999935051953e-02, /* 0x3FB2BFFF, 0xFFFFFE2C */
294 1.17682064682252693899e+01, /* 0x40278952, 0x5BB334D6 */
295 5.57673380256401856059e+02, /* 0x40816D63, 0x15301825 */
296 8.85919720756468632317e+03, /* 0x40C14D99, 0x3E18F46D */
297 3.70146267776887834771e+04, /* 0x40E212D4, 0x0E901566 */
298};
299static const double qS8[6] = {
300 1.63776026895689824414e+02, /* 0x406478D5, 0x365B39BC */
301 8.09834494656449805916e+03, /* 0x40BFA258, 0x4E6B0563 */
302 1.42538291419120476348e+05, /* 0x41016652, 0x54D38C3F */
303 8.03309257119514397345e+05, /* 0x412883DA, 0x83A52B43 */
304 8.40501579819060512818e+05, /* 0x4129A66B, 0x28DE0B3D */
305 -3.43899293537866615225e+05, /* 0xC114FD6D, 0x2C9530C5 */
306};
307
308static const double qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
309 1.84085963594515531381e-11, /* 0x3DB43D8F, 0x29CC8CD9 */
310 7.32421766612684765896e-02, /* 0x3FB2BFFF, 0xD172B04C */
311 5.83563508962056953777e+00, /* 0x401757B0, 0xB9953DD3 */
312 1.35111577286449829671e+02, /* 0x4060E392, 0x0A8788E9 */
313 1.02724376596164097464e+03, /* 0x40900CF9, 0x9DC8C481 */
314 1.98997785864605384631e+03, /* 0x409F17E9, 0x53C6E3A6 */
315};
316static const double qS5[6] = {
317 8.27766102236537761883e+01, /* 0x4054B1B3, 0xFB5E1543 */
318 2.07781416421392987104e+03, /* 0x40A03BA0, 0xDA21C0CE */
319 1.88472887785718085070e+04, /* 0x40D267D2, 0x7B591E6D */
320 5.67511122894947329769e+04, /* 0x40EBB5E3, 0x97E02372 */
321 3.59767538425114471465e+04, /* 0x40E19118, 0x1F7A54A0 */
322 -5.35434275601944773371e+03, /* 0xC0B4EA57, 0xBEDBC609 */
323};
324
325static const double qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
326 4.37741014089738620906e-09, /* 0x3E32CD03, 0x6ADECB82 */
327 7.32411180042911447163e-02, /* 0x3FB2BFEE, 0x0E8D0842 */
328 3.34423137516170720929e+00, /* 0x400AC0FC, 0x61149CF5 */
329 4.26218440745412650017e+01, /* 0x40454F98, 0x962DAEDD */
330 1.70808091340565596283e+02, /* 0x406559DB, 0xE25EFD1F */
331 1.66733948696651168575e+02, /* 0x4064D77C, 0x81FA21E0 */
332};
333static const double qS3[6] = {
334 4.87588729724587182091e+01, /* 0x40486122, 0xBFE343A6 */
335 7.09689221056606015736e+02, /* 0x40862D83, 0x86544EB3 */
336 3.70414822620111362994e+03, /* 0x40ACF04B, 0xE44DFC63 */
337 6.46042516752568917582e+03, /* 0x40B93C6C, 0xD7C76A28 */
338 2.51633368920368957333e+03, /* 0x40A3A8AA, 0xD94FB1C0 */
339 -1.49247451836156386662e+02, /* 0xC062A7EB, 0x201CF40F */
340};
341
342static const double qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
343 1.50444444886983272379e-07, /* 0x3E84313B, 0x54F76BDB */
344 7.32234265963079278272e-02, /* 0x3FB2BEC5, 0x3E883E34 */
345 1.99819174093815998816e+00, /* 0x3FFFF897, 0xE727779C */
346 1.44956029347885735348e+01, /* 0x402CFDBF, 0xAAF96FE5 */
347 3.16662317504781540833e+01, /* 0x403FAA8E, 0x29FBDC4A */
348 1.62527075710929267416e+01, /* 0x403040B1, 0x71814BB4 */
349};
350static const double qS2[6] = {
351 3.03655848355219184498e+01, /* 0x403E5D96, 0xF7C07AED */
352 2.69348118608049844624e+02, /* 0x4070D591, 0xE4D14B40 */
353 8.44783757595320139444e+02, /* 0x408A6645, 0x22B3BF22 */
354 8.82935845112488550512e+02, /* 0x408B977C, 0x9C5CC214 */
355 2.12666388511798828631e+02, /* 0x406A9553, 0x0E001365 */
356 -5.31095493882666946917e+00, /* 0xC0153E6A, 0xF8B32931 */
357};
358
359static double qzero(double x)
360{
361 const double *p,*q;
362 double_t s,r,z;
363 uint32_t ix;
364
365 GET_HIGH_WORD(ix, x);
366 ix &= 0x7fffffff;
367 if (ix >= 0x40200000){p = qR8; q = qS8;}
368 else if (ix >= 0x40122E8B){p = qR5; q = qS5;}
369 else if (ix >= 0x4006DB6D){p = qR3; q = qS3;}
370 else /*ix >= 0x40000000*/ {p = qR2; q = qS2;}
371 z = 1.0/(x*x);
372 r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
373 s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
374 return (-.125 + r/s)/x;
375}
libc/musl/src/math/j0f.c created+314
......@@ -0,0 +1,314 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_j0f.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#define _GNU_SOURCE
17#include "libm.h"
18
19static float pzerof(float), qzerof(float);
20
21static const float
22invsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */
23tpi = 6.3661974669e-01; /* 0x3f22f983 */
24
25static float common(uint32_t ix, float x, int y0)
26{
27 float z,s,c,ss,cc;
28 /*
29 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
30 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
31 */
32 s = sinf(x);
33 c = cosf(x);
34 if (y0)
35 c = -c;
36 cc = s+c;
37 if (ix < 0x7f000000) {
38 ss = s-c;
39 z = -cosf(2*x);
40 if (s*c < 0)
41 cc = z/ss;
42 else
43 ss = z/cc;
44 if (ix < 0x58800000) {
45 if (y0)
46 ss = -ss;
47 cc = pzerof(x)*cc-qzerof(x)*ss;
48 }
49 }
50 return invsqrtpi*cc/sqrtf(x);
51}
52
53/* R0/S0 on [0, 2.00] */
54static const float
55R02 = 1.5625000000e-02, /* 0x3c800000 */
56R03 = -1.8997929874e-04, /* 0xb947352e */
57R04 = 1.8295404516e-06, /* 0x35f58e88 */
58R05 = -4.6183270541e-09, /* 0xb19eaf3c */
59S01 = 1.5619102865e-02, /* 0x3c7fe744 */
60S02 = 1.1692678527e-04, /* 0x38f53697 */
61S03 = 5.1354652442e-07, /* 0x3509daa6 */
62S04 = 1.1661400734e-09; /* 0x30a045e8 */
63
64float j0f(float x)
65{
66 float z,r,s;
67 uint32_t ix;
68
69 GET_FLOAT_WORD(ix, x);
70 ix &= 0x7fffffff;
71 if (ix >= 0x7f800000)
72 return 1/(x*x);
73 x = fabsf(x);
74
75 if (ix >= 0x40000000) { /* |x| >= 2 */
76 /* large ulp error near zeros */
77 return common(ix, x, 0);
78 }
79 if (ix >= 0x3a000000) { /* |x| >= 2**-11 */
80 /* up to 4ulp error near 2 */
81 z = x*x;
82 r = z*(R02+z*(R03+z*(R04+z*R05)));
83 s = 1+z*(S01+z*(S02+z*(S03+z*S04)));
84 return (1+x/2)*(1-x/2) + z*(r/s);
85 }
86 if (ix >= 0x21800000) /* |x| >= 2**-60 */
87 x = 0.25f*x*x;
88 return 1 - x;
89}
90
91static const float
92u00 = -7.3804296553e-02, /* 0xbd9726b5 */
93u01 = 1.7666645348e-01, /* 0x3e34e80d */
94u02 = -1.3818567619e-02, /* 0xbc626746 */
95u03 = 3.4745343146e-04, /* 0x39b62a69 */
96u04 = -3.8140706238e-06, /* 0xb67ff53c */
97u05 = 1.9559013964e-08, /* 0x32a802ba */
98u06 = -3.9820518410e-11, /* 0xae2f21eb */
99v01 = 1.2730483897e-02, /* 0x3c509385 */
100v02 = 7.6006865129e-05, /* 0x389f65e0 */
101v03 = 2.5915085189e-07, /* 0x348b216c */
102v04 = 4.4111031494e-10; /* 0x2ff280c2 */
103
104float y0f(float x)
105{
106 float z,u,v;
107 uint32_t ix;
108
109 GET_FLOAT_WORD(ix, x);
110 if ((ix & 0x7fffffff) == 0)
111 return -1/0.0f;
112 if (ix>>31)
113 return 0/0.0f;
114 if (ix >= 0x7f800000)
115 return 1/x;
116 if (ix >= 0x40000000) { /* |x| >= 2.0 */
117 /* large ulp error near zeros */
118 return common(ix,x,1);
119 }
120 if (ix >= 0x39000000) { /* x >= 2**-13 */
121 /* large ulp error at x ~= 0.89 */
122 z = x*x;
123 u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
124 v = 1+z*(v01+z*(v02+z*(v03+z*v04)));
125 return u/v + tpi*(j0f(x)*logf(x));
126 }
127 return u00 + tpi*logf(x);
128}
129
130/* The asymptotic expansions of pzero is
131 * 1 - 9/128 s^2 + 11025/98304 s^4 - ..., where s = 1/x.
132 * For x >= 2, We approximate pzero by
133 * pzero(x) = 1 + (R/S)
134 * where R = pR0 + pR1*s^2 + pR2*s^4 + ... + pR5*s^10
135 * S = 1 + pS0*s^2 + ... + pS4*s^10
136 * and
137 * | pzero(x)-1-R/S | <= 2 ** ( -60.26)
138 */
139static const float pR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
140 0.0000000000e+00, /* 0x00000000 */
141 -7.0312500000e-02, /* 0xbd900000 */
142 -8.0816707611e+00, /* 0xc1014e86 */
143 -2.5706311035e+02, /* 0xc3808814 */
144 -2.4852163086e+03, /* 0xc51b5376 */
145 -5.2530439453e+03, /* 0xc5a4285a */
146};
147static const float pS8[5] = {
148 1.1653436279e+02, /* 0x42e91198 */
149 3.8337448730e+03, /* 0x456f9beb */
150 4.0597855469e+04, /* 0x471e95db */
151 1.1675296875e+05, /* 0x47e4087c */
152 4.7627726562e+04, /* 0x473a0bba */
153};
154static const float pR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
155 -1.1412546255e-11, /* 0xad48c58a */
156 -7.0312492549e-02, /* 0xbd8fffff */
157 -4.1596107483e+00, /* 0xc0851b88 */
158 -6.7674766541e+01, /* 0xc287597b */
159 -3.3123129272e+02, /* 0xc3a59d9b */
160 -3.4643338013e+02, /* 0xc3ad3779 */
161};
162static const float pS5[5] = {
163 6.0753936768e+01, /* 0x42730408 */
164 1.0512523193e+03, /* 0x44836813 */
165 5.9789707031e+03, /* 0x45bad7c4 */
166 9.6254453125e+03, /* 0x461665c8 */
167 2.4060581055e+03, /* 0x451660ee */
168};
169
170static const float pR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
171 -2.5470459075e-09, /* 0xb12f081b */
172 -7.0311963558e-02, /* 0xbd8fffb8 */
173 -2.4090321064e+00, /* 0xc01a2d95 */
174 -2.1965976715e+01, /* 0xc1afba52 */
175 -5.8079170227e+01, /* 0xc2685112 */
176 -3.1447946548e+01, /* 0xc1fb9565 */
177};
178static const float pS3[5] = {
179 3.5856033325e+01, /* 0x420f6c94 */
180 3.6151397705e+02, /* 0x43b4c1ca */
181 1.1936077881e+03, /* 0x44953373 */
182 1.1279968262e+03, /* 0x448cffe6 */
183 1.7358093262e+02, /* 0x432d94b8 */
184};
185
186static const float pR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
187 -8.8753431271e-08, /* 0xb3be98b7 */
188 -7.0303097367e-02, /* 0xbd8ffb12 */
189 -1.4507384300e+00, /* 0xbfb9b1cc */
190 -7.6356959343e+00, /* 0xc0f4579f */
191 -1.1193166733e+01, /* 0xc1331736 */
192 -3.2336456776e+00, /* 0xc04ef40d */
193};
194static const float pS2[5] = {
195 2.2220300674e+01, /* 0x41b1c32d */
196 1.3620678711e+02, /* 0x430834f0 */
197 2.7047027588e+02, /* 0x43873c32 */
198 1.5387539673e+02, /* 0x4319e01a */
199 1.4657617569e+01, /* 0x416a859a */
200};
201
202static float pzerof(float x)
203{
204 const float *p,*q;
205 float_t z,r,s;
206 uint32_t ix;
207
208 GET_FLOAT_WORD(ix, x);
209 ix &= 0x7fffffff;
210 if (ix >= 0x41000000){p = pR8; q = pS8;}
211 else if (ix >= 0x409173eb){p = pR5; q = pS5;}
212 else if (ix >= 0x4036d917){p = pR3; q = pS3;}
213 else /*ix >= 0x40000000*/ {p = pR2; q = pS2;}
214 z = 1.0f/(x*x);
215 r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
216 s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
217 return 1.0f + r/s;
218}
219
220
221/* For x >= 8, the asymptotic expansions of qzero is
222 * -1/8 s + 75/1024 s^3 - ..., where s = 1/x.
223 * We approximate pzero by
224 * qzero(x) = s*(-1.25 + (R/S))
225 * where R = qR0 + qR1*s^2 + qR2*s^4 + ... + qR5*s^10
226 * S = 1 + qS0*s^2 + ... + qS5*s^12
227 * and
228 * | qzero(x)/s +1.25-R/S | <= 2 ** ( -61.22)
229 */
230static const float qR8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
231 0.0000000000e+00, /* 0x00000000 */
232 7.3242187500e-02, /* 0x3d960000 */
233 1.1768206596e+01, /* 0x413c4a93 */
234 5.5767340088e+02, /* 0x440b6b19 */
235 8.8591972656e+03, /* 0x460a6cca */
236 3.7014625000e+04, /* 0x471096a0 */
237};
238static const float qS8[6] = {
239 1.6377603149e+02, /* 0x4323c6aa */
240 8.0983447266e+03, /* 0x45fd12c2 */
241 1.4253829688e+05, /* 0x480b3293 */
242 8.0330925000e+05, /* 0x49441ed4 */
243 8.4050156250e+05, /* 0x494d3359 */
244 -3.4389928125e+05, /* 0xc8a7eb69 */
245};
246
247static const float qR5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
248 1.8408595828e-11, /* 0x2da1ec79 */
249 7.3242180049e-02, /* 0x3d95ffff */
250 5.8356351852e+00, /* 0x40babd86 */
251 1.3511157227e+02, /* 0x43071c90 */
252 1.0272437744e+03, /* 0x448067cd */
253 1.9899779053e+03, /* 0x44f8bf4b */
254};
255static const float qS5[6] = {
256 8.2776611328e+01, /* 0x42a58da0 */
257 2.0778142090e+03, /* 0x4501dd07 */
258 1.8847289062e+04, /* 0x46933e94 */
259 5.6751113281e+04, /* 0x475daf1d */
260 3.5976753906e+04, /* 0x470c88c1 */
261 -5.3543427734e+03, /* 0xc5a752be */
262};
263
264static const float qR3[6] = {/* for x in [4.547,2.8571]=1/[0.2199,0.35001] */
265 4.3774099900e-09, /* 0x3196681b */
266 7.3241114616e-02, /* 0x3d95ff70 */
267 3.3442313671e+00, /* 0x405607e3 */
268 4.2621845245e+01, /* 0x422a7cc5 */
269 1.7080809021e+02, /* 0x432acedf */
270 1.6673394775e+02, /* 0x4326bbe4 */
271};
272static const float qS3[6] = {
273 4.8758872986e+01, /* 0x42430916 */
274 7.0968920898e+02, /* 0x44316c1c */
275 3.7041481934e+03, /* 0x4567825f */
276 6.4604252930e+03, /* 0x45c9e367 */
277 2.5163337402e+03, /* 0x451d4557 */
278 -1.4924745178e+02, /* 0xc3153f59 */
279};
280
281static const float qR2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
282 1.5044444979e-07, /* 0x342189db */
283 7.3223426938e-02, /* 0x3d95f62a */
284 1.9981917143e+00, /* 0x3fffc4bf */
285 1.4495602608e+01, /* 0x4167edfd */
286 3.1666231155e+01, /* 0x41fd5471 */
287 1.6252708435e+01, /* 0x4182058c */
288};
289static const float qS2[6] = {
290 3.0365585327e+01, /* 0x41f2ecb8 */
291 2.6934811401e+02, /* 0x4386ac8f */
292 8.4478375244e+02, /* 0x44533229 */
293 8.8293585205e+02, /* 0x445cbbe5 */
294 2.1266638184e+02, /* 0x4354aa98 */
295 -5.3109550476e+00, /* 0xc0a9f358 */
296};
297
298static float qzerof(float x)
299{
300 const float *p,*q;
301 float_t s,r,z;
302 uint32_t ix;
303
304 GET_FLOAT_WORD(ix, x);
305 ix &= 0x7fffffff;
306 if (ix >= 0x41000000){p = qR8; q = qS8;}
307 else if (ix >= 0x409173eb){p = qR5; q = qS5;}
308 else if (ix >= 0x4036d917){p = qR3; q = qS3;}
309 else /*ix >= 0x40000000*/ {p = qR2; q = qS2;}
310 z = 1.0f/(x*x);
311 r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
312 s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
313 return (-.125f + r/s)/x;
314}
libc/musl/src/math/j1.c created+362
......@@ -0,0 +1,362 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_j1.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* j1(x), y1(x)
13 * Bessel function of the first and second kinds of order zero.
14 * Method -- j1(x):
15 * 1. For tiny x, we use j1(x) = x/2 - x^3/16 + x^5/384 - ...
16 * 2. Reduce x to |x| since j1(x)=-j1(-x), and
17 * for x in (0,2)
18 * j1(x) = x/2 + x*z*R0/S0, where z = x*x;
19 * (precision: |j1/x - 1/2 - R0/S0 |<2**-61.51 )
20 * for x in (2,inf)
21 * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x1)-q1(x)*sin(x1))
22 * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
23 * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
24 * as follow:
25 * cos(x1) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
26 * = 1/sqrt(2) * (sin(x) - cos(x))
27 * sin(x1) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
28 * = -1/sqrt(2) * (sin(x) + cos(x))
29 * (To avoid cancellation, use
30 * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
31 * to compute the worse one.)
32 *
33 * 3 Special cases
34 * j1(nan)= nan
35 * j1(0) = 0
36 * j1(inf) = 0
37 *
38 * Method -- y1(x):
39 * 1. screen out x<=0 cases: y1(0)=-inf, y1(x<0)=NaN
40 * 2. For x<2.
41 * Since
42 * y1(x) = 2/pi*(j1(x)*(ln(x/2)+Euler)-1/x-x/2+5/64*x^3-...)
43 * therefore y1(x)-2/pi*j1(x)*ln(x)-1/x is an odd function.
44 * We use the following function to approximate y1,
45 * y1(x) = x*U(z)/V(z) + (2/pi)*(j1(x)*ln(x)-1/x), z= x^2
46 * where for x in [0,2] (abs err less than 2**-65.89)
47 * U(z) = U0[0] + U0[1]*z + ... + U0[4]*z^4
48 * V(z) = 1 + v0[0]*z + ... + v0[4]*z^5
49 * Note: For tiny x, 1/x dominate y1 and hence
50 * y1(tiny) = -2/pi/tiny, (choose tiny<2**-54)
51 * 3. For x>=2.
52 * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x1)+q1(x)*cos(x1))
53 * where x1 = x-3*pi/4. It is better to compute sin(x1),cos(x1)
54 * by method mentioned above.
55 */
56
57#include "libm.h"
58
59static double pone(double), qone(double);
60
61static const double
62invsqrtpi = 5.64189583547756279280e-01, /* 0x3FE20DD7, 0x50429B6D */
63tpi = 6.36619772367581382433e-01; /* 0x3FE45F30, 0x6DC9C883 */
64
65static double common(uint32_t ix, double x, int y1, int sign)
66{
67 double z,s,c,ss,cc;
68
69 /*
70 * j1(x) = sqrt(2/(pi*x))*(p1(x)*cos(x-3pi/4)-q1(x)*sin(x-3pi/4))
71 * y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x-3pi/4)+q1(x)*cos(x-3pi/4))
72 *
73 * sin(x-3pi/4) = -(sin(x) + cos(x))/sqrt(2)
74 * cos(x-3pi/4) = (sin(x) - cos(x))/sqrt(2)
75 * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
76 */
77 s = sin(x);
78 if (y1)
79 s = -s;
80 c = cos(x);
81 cc = s-c;
82 if (ix < 0x7fe00000) {
83 /* avoid overflow in 2*x */
84 ss = -s-c;
85 z = cos(2*x);
86 if (s*c > 0)
87 cc = z/ss;
88 else
89 ss = z/cc;
90 if (ix < 0x48000000) {
91 if (y1)
92 ss = -ss;
93 cc = pone(x)*cc-qone(x)*ss;
94 }
95 }
96 if (sign)
97 cc = -cc;
98 return invsqrtpi*cc/sqrt(x);
99}
100
101/* R0/S0 on [0,2] */
102static const double
103r00 = -6.25000000000000000000e-02, /* 0xBFB00000, 0x00000000 */
104r01 = 1.40705666955189706048e-03, /* 0x3F570D9F, 0x98472C61 */
105r02 = -1.59955631084035597520e-05, /* 0xBEF0C5C6, 0xBA169668 */
106r03 = 4.96727999609584448412e-08, /* 0x3E6AAAFA, 0x46CA0BD9 */
107s01 = 1.91537599538363460805e-02, /* 0x3F939D0B, 0x12637E53 */
108s02 = 1.85946785588630915560e-04, /* 0x3F285F56, 0xB9CDF664 */
109s03 = 1.17718464042623683263e-06, /* 0x3EB3BFF8, 0x333F8498 */
110s04 = 5.04636257076217042715e-09, /* 0x3E35AC88, 0xC97DFF2C */
111s05 = 1.23542274426137913908e-11; /* 0x3DAB2ACF, 0xCFB97ED8 */
112
113double j1(double x)
114{
115 double z,r,s;
116 uint32_t ix;
117 int sign;
118
119 GET_HIGH_WORD(ix, x);
120 sign = ix>>31;
121 ix &= 0x7fffffff;
122 if (ix >= 0x7ff00000)
123 return 1/(x*x);
124 if (ix >= 0x40000000) /* |x| >= 2 */
125 return common(ix, fabs(x), 0, sign);
126 if (ix >= 0x38000000) { /* |x| >= 2**-127 */
127 z = x*x;
128 r = z*(r00+z*(r01+z*(r02+z*r03)));
129 s = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
130 z = r/s;
131 } else
132 /* avoid underflow, raise inexact if x!=0 */
133 z = x;
134 return (0.5 + z)*x;
135}
136
137static const double U0[5] = {
138 -1.96057090646238940668e-01, /* 0xBFC91866, 0x143CBC8A */
139 5.04438716639811282616e-02, /* 0x3FA9D3C7, 0x76292CD1 */
140 -1.91256895875763547298e-03, /* 0xBF5F55E5, 0x4844F50F */
141 2.35252600561610495928e-05, /* 0x3EF8AB03, 0x8FA6B88E */
142 -9.19099158039878874504e-08, /* 0xBE78AC00, 0x569105B8 */
143};
144static const double V0[5] = {
145 1.99167318236649903973e-02, /* 0x3F94650D, 0x3F4DA9F0 */
146 2.02552581025135171496e-04, /* 0x3F2A8C89, 0x6C257764 */
147 1.35608801097516229404e-06, /* 0x3EB6C05A, 0x894E8CA6 */
148 6.22741452364621501295e-09, /* 0x3E3ABF1D, 0x5BA69A86 */
149 1.66559246207992079114e-11, /* 0x3DB25039, 0xDACA772A */
150};
151
152double y1(double x)
153{
154 double z,u,v;
155 uint32_t ix,lx;
156
157 EXTRACT_WORDS(ix, lx, x);
158 /* y1(nan)=nan, y1(<0)=nan, y1(0)=-inf, y1(inf)=0 */
159 if ((ix<<1 | lx) == 0)
160 return -1/0.0;
161 if (ix>>31)
162 return 0/0.0;
163 if (ix >= 0x7ff00000)
164 return 1/x;
165
166 if (ix >= 0x40000000) /* x >= 2 */
167 return common(ix, x, 1, 0);
168 if (ix < 0x3c900000) /* x < 2**-54 */
169 return -tpi/x;
170 z = x*x;
171 u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
172 v = 1+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
173 return x*(u/v) + tpi*(j1(x)*log(x)-1/x);
174}
175
176/* For x >= 8, the asymptotic expansions of pone is
177 * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x.
178 * We approximate pone by
179 * pone(x) = 1 + (R/S)
180 * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
181 * S = 1 + ps0*s^2 + ... + ps4*s^10
182 * and
183 * | pone(x)-1-R/S | <= 2 ** ( -60.06)
184 */
185
186static const double pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
187 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
188 1.17187499999988647970e-01, /* 0x3FBDFFFF, 0xFFFFFCCE */
189 1.32394806593073575129e+01, /* 0x402A7A9D, 0x357F7FCE */
190 4.12051854307378562225e+02, /* 0x4079C0D4, 0x652EA590 */
191 3.87474538913960532227e+03, /* 0x40AE457D, 0xA3A532CC */
192 7.91447954031891731574e+03, /* 0x40BEEA7A, 0xC32782DD */
193};
194static const double ps8[5] = {
195 1.14207370375678408436e+02, /* 0x405C8D45, 0x8E656CAC */
196 3.65093083420853463394e+03, /* 0x40AC85DC, 0x964D274F */
197 3.69562060269033463555e+04, /* 0x40E20B86, 0x97C5BB7F */
198 9.76027935934950801311e+04, /* 0x40F7D42C, 0xB28F17BB */
199 3.08042720627888811578e+04, /* 0x40DE1511, 0x697A0B2D */
200};
201
202static const double pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
203 1.31990519556243522749e-11, /* 0x3DAD0667, 0xDAE1CA7D */
204 1.17187493190614097638e-01, /* 0x3FBDFFFF, 0xE2C10043 */
205 6.80275127868432871736e+00, /* 0x401B3604, 0x6E6315E3 */
206 1.08308182990189109773e+02, /* 0x405B13B9, 0x452602ED */
207 5.17636139533199752805e+02, /* 0x40802D16, 0xD052D649 */
208 5.28715201363337541807e+02, /* 0x408085B8, 0xBB7E0CB7 */
209};
210static const double ps5[5] = {
211 5.92805987221131331921e+01, /* 0x404DA3EA, 0xA8AF633D */
212 9.91401418733614377743e+02, /* 0x408EFB36, 0x1B066701 */
213 5.35326695291487976647e+03, /* 0x40B4E944, 0x5706B6FB */
214 7.84469031749551231769e+03, /* 0x40BEA4B0, 0xB8A5BB15 */
215 1.50404688810361062679e+03, /* 0x40978030, 0x036F5E51 */
216};
217
218static const double pr3[6] = {
219 3.02503916137373618024e-09, /* 0x3E29FC21, 0xA7AD9EDD */
220 1.17186865567253592491e-01, /* 0x3FBDFFF5, 0x5B21D17B */
221 3.93297750033315640650e+00, /* 0x400F76BC, 0xE85EAD8A */
222 3.51194035591636932736e+01, /* 0x40418F48, 0x9DA6D129 */
223 9.10550110750781271918e+01, /* 0x4056C385, 0x4D2C1837 */
224 4.85590685197364919645e+01, /* 0x4048478F, 0x8EA83EE5 */
225};
226static const double ps3[5] = {
227 3.47913095001251519989e+01, /* 0x40416549, 0xA134069C */
228 3.36762458747825746741e+02, /* 0x40750C33, 0x07F1A75F */
229 1.04687139975775130551e+03, /* 0x40905B7C, 0x5037D523 */
230 8.90811346398256432622e+02, /* 0x408BD67D, 0xA32E31E9 */
231 1.03787932439639277504e+02, /* 0x4059F26D, 0x7C2EED53 */
232};
233
234static const double pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
235 1.07710830106873743082e-07, /* 0x3E7CE9D4, 0xF65544F4 */
236 1.17176219462683348094e-01, /* 0x3FBDFF42, 0xBE760D83 */
237 2.36851496667608785174e+00, /* 0x4002F2B7, 0xF98FAEC0 */
238 1.22426109148261232917e+01, /* 0x40287C37, 0x7F71A964 */
239 1.76939711271687727390e+01, /* 0x4031B1A8, 0x177F8EE2 */
240 5.07352312588818499250e+00, /* 0x40144B49, 0xA574C1FE */
241};
242static const double ps2[5] = {
243 2.14364859363821409488e+01, /* 0x40356FBD, 0x8AD5ECDC */
244 1.25290227168402751090e+02, /* 0x405F5293, 0x14F92CD5 */
245 2.32276469057162813669e+02, /* 0x406D08D8, 0xD5A2DBD9 */
246 1.17679373287147100768e+02, /* 0x405D6B7A, 0xDA1884A9 */
247 8.36463893371618283368e+00, /* 0x4020BAB1, 0xF44E5192 */
248};
249
250static double pone(double x)
251{
252 const double *p,*q;
253 double_t z,r,s;
254 uint32_t ix;
255
256 GET_HIGH_WORD(ix, x);
257 ix &= 0x7fffffff;
258 if (ix >= 0x40200000){p = pr8; q = ps8;}
259 else if (ix >= 0x40122E8B){p = pr5; q = ps5;}
260 else if (ix >= 0x4006DB6D){p = pr3; q = ps3;}
261 else /*ix >= 0x40000000*/ {p = pr2; q = ps2;}
262 z = 1.0/(x*x);
263 r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
264 s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
265 return 1.0+ r/s;
266}
267
268/* For x >= 8, the asymptotic expansions of qone is
269 * 3/8 s - 105/1024 s^3 - ..., where s = 1/x.
270 * We approximate pone by
271 * qone(x) = s*(0.375 + (R/S))
272 * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
273 * S = 1 + qs1*s^2 + ... + qs6*s^12
274 * and
275 * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13)
276 */
277
278static const double qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
279 0.00000000000000000000e+00, /* 0x00000000, 0x00000000 */
280 -1.02539062499992714161e-01, /* 0xBFBA3FFF, 0xFFFFFDF3 */
281 -1.62717534544589987888e+01, /* 0xC0304591, 0xA26779F7 */
282 -7.59601722513950107896e+02, /* 0xC087BCD0, 0x53E4B576 */
283 -1.18498066702429587167e+04, /* 0xC0C724E7, 0x40F87415 */
284 -4.84385124285750353010e+04, /* 0xC0E7A6D0, 0x65D09C6A */
285};
286static const double qs8[6] = {
287 1.61395369700722909556e+02, /* 0x40642CA6, 0xDE5BCDE5 */
288 7.82538599923348465381e+03, /* 0x40BE9162, 0xD0D88419 */
289 1.33875336287249578163e+05, /* 0x4100579A, 0xB0B75E98 */
290 7.19657723683240939863e+05, /* 0x4125F653, 0x72869C19 */
291 6.66601232617776375264e+05, /* 0x412457D2, 0x7719AD5C */
292 -2.94490264303834643215e+05, /* 0xC111F969, 0x0EA5AA18 */
293};
294
295static const double qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
296 -2.08979931141764104297e-11, /* 0xBDB6FA43, 0x1AA1A098 */
297 -1.02539050241375426231e-01, /* 0xBFBA3FFF, 0xCB597FEF */
298 -8.05644828123936029840e+00, /* 0xC0201CE6, 0xCA03AD4B */
299 -1.83669607474888380239e+02, /* 0xC066F56D, 0x6CA7B9B0 */
300 -1.37319376065508163265e+03, /* 0xC09574C6, 0x6931734F */
301 -2.61244440453215656817e+03, /* 0xC0A468E3, 0x88FDA79D */
302};
303static const double qs5[6] = {
304 8.12765501384335777857e+01, /* 0x405451B2, 0xFF5A11B2 */
305 1.99179873460485964642e+03, /* 0x409F1F31, 0xE77BF839 */
306 1.74684851924908907677e+04, /* 0x40D10F1F, 0x0D64CE29 */
307 4.98514270910352279316e+04, /* 0x40E8576D, 0xAABAD197 */
308 2.79480751638918118260e+04, /* 0x40DB4B04, 0xCF7C364B */
309 -4.71918354795128470869e+03, /* 0xC0B26F2E, 0xFCFFA004 */
310};
311
312static const double qr3[6] = {
313 -5.07831226461766561369e-09, /* 0xBE35CFA9, 0xD38FC84F */
314 -1.02537829820837089745e-01, /* 0xBFBA3FEB, 0x51AEED54 */
315 -4.61011581139473403113e+00, /* 0xC01270C2, 0x3302D9FF */
316 -5.78472216562783643212e+01, /* 0xC04CEC71, 0xC25D16DA */
317 -2.28244540737631695038e+02, /* 0xC06C87D3, 0x4718D55F */
318 -2.19210128478909325622e+02, /* 0xC06B66B9, 0x5F5C1BF6 */
319};
320static const double qs3[6] = {
321 4.76651550323729509273e+01, /* 0x4047D523, 0xCCD367E4 */
322 6.73865112676699709482e+02, /* 0x40850EEB, 0xC031EE3E */
323 3.38015286679526343505e+03, /* 0x40AA684E, 0x448E7C9A */
324 5.54772909720722782367e+03, /* 0x40B5ABBA, 0xA61D54A6 */
325 1.90311919338810798763e+03, /* 0x409DBC7A, 0x0DD4DF4B */
326 -1.35201191444307340817e+02, /* 0xC060E670, 0x290A311F */
327};
328
329static const double qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
330 -1.78381727510958865572e-07, /* 0xBE87F126, 0x44C626D2 */
331 -1.02517042607985553460e-01, /* 0xBFBA3E8E, 0x9148B010 */
332 -2.75220568278187460720e+00, /* 0xC0060484, 0x69BB4EDA */
333 -1.96636162643703720221e+01, /* 0xC033A9E2, 0xC168907F */
334 -4.23253133372830490089e+01, /* 0xC04529A3, 0xDE104AAA */
335 -2.13719211703704061733e+01, /* 0xC0355F36, 0x39CF6E52 */
336};
337static const double qs2[6] = {
338 2.95333629060523854548e+01, /* 0x403D888A, 0x78AE64FF */
339 2.52981549982190529136e+02, /* 0x406F9F68, 0xDB821CBA */
340 7.57502834868645436472e+02, /* 0x4087AC05, 0xCE49A0F7 */
341 7.39393205320467245656e+02, /* 0x40871B25, 0x48D4C029 */
342 1.55949003336666123687e+02, /* 0x40637E5E, 0x3C3ED8D4 */
343 -4.95949898822628210127e+00, /* 0xC013D686, 0xE71BE86B */
344};
345
346static double qone(double x)
347{
348 const double *p,*q;
349 double_t s,r,z;
350 uint32_t ix;
351
352 GET_HIGH_WORD(ix, x);
353 ix &= 0x7fffffff;
354 if (ix >= 0x40200000){p = qr8; q = qs8;}
355 else if (ix >= 0x40122E8B){p = qr5; q = qs5;}
356 else if (ix >= 0x4006DB6D){p = qr3; q = qs3;}
357 else /*ix >= 0x40000000*/ {p = qr2; q = qs2;}
358 z = 1.0/(x*x);
359 r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
360 s = 1.0+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
361 return (.375 + r/s)/x;
362}
libc/musl/src/math/j1f.c created+310
......@@ -0,0 +1,310 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_j1f.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#define _GNU_SOURCE
17#include "libm.h"
18
19static float ponef(float), qonef(float);
20
21static const float
22invsqrtpi = 5.6418961287e-01, /* 0x3f106ebb */
23tpi = 6.3661974669e-01; /* 0x3f22f983 */
24
25static float common(uint32_t ix, float x, int y1, int sign)
26{
27 double z,s,c,ss,cc;
28
29 s = sinf(x);
30 if (y1)
31 s = -s;
32 c = cosf(x);
33 cc = s-c;
34 if (ix < 0x7f000000) {
35 ss = -s-c;
36 z = cosf(2*x);
37 if (s*c > 0)
38 cc = z/ss;
39 else
40 ss = z/cc;
41 if (ix < 0x58800000) {
42 if (y1)
43 ss = -ss;
44 cc = ponef(x)*cc-qonef(x)*ss;
45 }
46 }
47 if (sign)
48 cc = -cc;
49 return invsqrtpi*cc/sqrtf(x);
50}
51
52/* R0/S0 on [0,2] */
53static const float
54r00 = -6.2500000000e-02, /* 0xbd800000 */
55r01 = 1.4070566976e-03, /* 0x3ab86cfd */
56r02 = -1.5995563444e-05, /* 0xb7862e36 */
57r03 = 4.9672799207e-08, /* 0x335557d2 */
58s01 = 1.9153760746e-02, /* 0x3c9ce859 */
59s02 = 1.8594678841e-04, /* 0x3942fab6 */
60s03 = 1.1771846857e-06, /* 0x359dffc2 */
61s04 = 5.0463624390e-09, /* 0x31ad6446 */
62s05 = 1.2354227016e-11; /* 0x2d59567e */
63
64float j1f(float x)
65{
66 float z,r,s;
67 uint32_t ix;
68 int sign;
69
70 GET_FLOAT_WORD(ix, x);
71 sign = ix>>31;
72 ix &= 0x7fffffff;
73 if (ix >= 0x7f800000)
74 return 1/(x*x);
75 if (ix >= 0x40000000) /* |x| >= 2 */
76 return common(ix, fabsf(x), 0, sign);
77 if (ix >= 0x39000000) { /* |x| >= 2**-13 */
78 z = x*x;
79 r = z*(r00+z*(r01+z*(r02+z*r03)));
80 s = 1+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
81 z = 0.5f + r/s;
82 } else
83 z = 0.5f;
84 return z*x;
85}
86
87static const float U0[5] = {
88 -1.9605709612e-01, /* 0xbe48c331 */
89 5.0443872809e-02, /* 0x3d4e9e3c */
90 -1.9125689287e-03, /* 0xbafaaf2a */
91 2.3525259166e-05, /* 0x37c5581c */
92 -9.1909917899e-08, /* 0xb3c56003 */
93};
94static const float V0[5] = {
95 1.9916731864e-02, /* 0x3ca3286a */
96 2.0255257550e-04, /* 0x3954644b */
97 1.3560879779e-06, /* 0x35b602d4 */
98 6.2274145840e-09, /* 0x31d5f8eb */
99 1.6655924903e-11, /* 0x2d9281cf */
100};
101
102float y1f(float x)
103{
104 float z,u,v;
105 uint32_t ix;
106
107 GET_FLOAT_WORD(ix, x);
108 if ((ix & 0x7fffffff) == 0)
109 return -1/0.0f;
110 if (ix>>31)
111 return 0/0.0f;
112 if (ix >= 0x7f800000)
113 return 1/x;
114 if (ix >= 0x40000000) /* |x| >= 2.0 */
115 return common(ix,x,1,0);
116 if (ix < 0x33000000) /* x < 2**-25 */
117 return -tpi/x;
118 z = x*x;
119 u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
120 v = 1.0f+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
121 return x*(u/v) + tpi*(j1f(x)*logf(x)-1.0f/x);
122}
123
124/* For x >= 8, the asymptotic expansions of pone is
125 * 1 + 15/128 s^2 - 4725/2^15 s^4 - ..., where s = 1/x.
126 * We approximate pone by
127 * pone(x) = 1 + (R/S)
128 * where R = pr0 + pr1*s^2 + pr2*s^4 + ... + pr5*s^10
129 * S = 1 + ps0*s^2 + ... + ps4*s^10
130 * and
131 * | pone(x)-1-R/S | <= 2 ** ( -60.06)
132 */
133
134static const float pr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
135 0.0000000000e+00, /* 0x00000000 */
136 1.1718750000e-01, /* 0x3df00000 */
137 1.3239480972e+01, /* 0x4153d4ea */
138 4.1205184937e+02, /* 0x43ce06a3 */
139 3.8747453613e+03, /* 0x45722bed */
140 7.9144794922e+03, /* 0x45f753d6 */
141};
142static const float ps8[5] = {
143 1.1420736694e+02, /* 0x42e46a2c */
144 3.6509309082e+03, /* 0x45642ee5 */
145 3.6956207031e+04, /* 0x47105c35 */
146 9.7602796875e+04, /* 0x47bea166 */
147 3.0804271484e+04, /* 0x46f0a88b */
148};
149
150static const float pr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
151 1.3199052094e-11, /* 0x2d68333f */
152 1.1718749255e-01, /* 0x3defffff */
153 6.8027510643e+00, /* 0x40d9b023 */
154 1.0830818176e+02, /* 0x42d89dca */
155 5.1763616943e+02, /* 0x440168b7 */
156 5.2871520996e+02, /* 0x44042dc6 */
157};
158static const float ps5[5] = {
159 5.9280597687e+01, /* 0x426d1f55 */
160 9.9140142822e+02, /* 0x4477d9b1 */
161 5.3532670898e+03, /* 0x45a74a23 */
162 7.8446904297e+03, /* 0x45f52586 */
163 1.5040468750e+03, /* 0x44bc0180 */
164};
165
166static const float pr3[6] = {
167 3.0250391081e-09, /* 0x314fe10d */
168 1.1718686670e-01, /* 0x3defffab */
169 3.9329774380e+00, /* 0x407bb5e7 */
170 3.5119403839e+01, /* 0x420c7a45 */
171 9.1055007935e+01, /* 0x42b61c2a */
172 4.8559066772e+01, /* 0x42423c7c */
173};
174static const float ps3[5] = {
175 3.4791309357e+01, /* 0x420b2a4d */
176 3.3676245117e+02, /* 0x43a86198 */
177 1.0468714600e+03, /* 0x4482dbe3 */
178 8.9081134033e+02, /* 0x445eb3ed */
179 1.0378793335e+02, /* 0x42cf936c */
180};
181
182static const float pr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
183 1.0771083225e-07, /* 0x33e74ea8 */
184 1.1717621982e-01, /* 0x3deffa16 */
185 2.3685150146e+00, /* 0x401795c0 */
186 1.2242610931e+01, /* 0x4143e1bc */
187 1.7693971634e+01, /* 0x418d8d41 */
188 5.0735230446e+00, /* 0x40a25a4d */
189};
190static const float ps2[5] = {
191 2.1436485291e+01, /* 0x41ab7dec */
192 1.2529022980e+02, /* 0x42fa9499 */
193 2.3227647400e+02, /* 0x436846c7 */
194 1.1767937469e+02, /* 0x42eb5bd7 */
195 8.3646392822e+00, /* 0x4105d590 */
196};
197
198static float ponef(float x)
199{
200 const float *p,*q;
201 float_t z,r,s;
202 uint32_t ix;
203
204 GET_FLOAT_WORD(ix, x);
205 ix &= 0x7fffffff;
206 if (ix >= 0x41000000){p = pr8; q = ps8;}
207 else if (ix >= 0x409173eb){p = pr5; q = ps5;}
208 else if (ix >= 0x4036d917){p = pr3; q = ps3;}
209 else /*ix >= 0x40000000*/ {p = pr2; q = ps2;}
210 z = 1.0f/(x*x);
211 r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
212 s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*q[4]))));
213 return 1.0f + r/s;
214}
215
216/* For x >= 8, the asymptotic expansions of qone is
217 * 3/8 s - 105/1024 s^3 - ..., where s = 1/x.
218 * We approximate pone by
219 * qone(x) = s*(0.375 + (R/S))
220 * where R = qr1*s^2 + qr2*s^4 + ... + qr5*s^10
221 * S = 1 + qs1*s^2 + ... + qs6*s^12
222 * and
223 * | qone(x)/s -0.375-R/S | <= 2 ** ( -61.13)
224 */
225
226static const float qr8[6] = { /* for x in [inf, 8]=1/[0,0.125] */
227 0.0000000000e+00, /* 0x00000000 */
228 -1.0253906250e-01, /* 0xbdd20000 */
229 -1.6271753311e+01, /* 0xc1822c8d */
230 -7.5960174561e+02, /* 0xc43de683 */
231 -1.1849806641e+04, /* 0xc639273a */
232 -4.8438511719e+04, /* 0xc73d3683 */
233};
234static const float qs8[6] = {
235 1.6139537048e+02, /* 0x43216537 */
236 7.8253862305e+03, /* 0x45f48b17 */
237 1.3387534375e+05, /* 0x4802bcd6 */
238 7.1965775000e+05, /* 0x492fb29c */
239 6.6660125000e+05, /* 0x4922be94 */
240 -2.9449025000e+05, /* 0xc88fcb48 */
241};
242
243static const float qr5[6] = { /* for x in [8,4.5454]=1/[0.125,0.22001] */
244 -2.0897993405e-11, /* 0xadb7d219 */
245 -1.0253904760e-01, /* 0xbdd1fffe */
246 -8.0564479828e+00, /* 0xc100e736 */
247 -1.8366960144e+02, /* 0xc337ab6b */
248 -1.3731937256e+03, /* 0xc4aba633 */
249 -2.6124443359e+03, /* 0xc523471c */
250};
251static const float qs5[6] = {
252 8.1276550293e+01, /* 0x42a28d98 */
253 1.9917987061e+03, /* 0x44f8f98f */
254 1.7468484375e+04, /* 0x468878f8 */
255 4.9851425781e+04, /* 0x4742bb6d */
256 2.7948074219e+04, /* 0x46da5826 */
257 -4.7191835938e+03, /* 0xc5937978 */
258};
259
260static const float qr3[6] = {
261 -5.0783124372e-09, /* 0xb1ae7d4f */
262 -1.0253783315e-01, /* 0xbdd1ff5b */
263 -4.6101160049e+00, /* 0xc0938612 */
264 -5.7847221375e+01, /* 0xc267638e */
265 -2.2824453735e+02, /* 0xc3643e9a */
266 -2.1921012878e+02, /* 0xc35b35cb */
267};
268static const float qs3[6] = {
269 4.7665153503e+01, /* 0x423ea91e */
270 6.7386511230e+02, /* 0x4428775e */
271 3.3801528320e+03, /* 0x45534272 */
272 5.5477290039e+03, /* 0x45ad5dd5 */
273 1.9031191406e+03, /* 0x44ede3d0 */
274 -1.3520118713e+02, /* 0xc3073381 */
275};
276
277static const float qr2[6] = {/* for x in [2.8570,2]=1/[0.3499,0.5] */
278 -1.7838172539e-07, /* 0xb43f8932 */
279 -1.0251704603e-01, /* 0xbdd1f475 */
280 -2.7522056103e+00, /* 0xc0302423 */
281 -1.9663616180e+01, /* 0xc19d4f16 */
282 -4.2325313568e+01, /* 0xc2294d1f */
283 -2.1371921539e+01, /* 0xc1aaf9b2 */
284};
285static const float qs2[6] = {
286 2.9533363342e+01, /* 0x41ec4454 */
287 2.5298155212e+02, /* 0x437cfb47 */
288 7.5750280762e+02, /* 0x443d602e */
289 7.3939318848e+02, /* 0x4438d92a */
290 1.5594900513e+02, /* 0x431bf2f2 */
291 -4.9594988823e+00, /* 0xc09eb437 */
292};
293
294static float qonef(float x)
295{
296 const float *p,*q;
297 float_t s,r,z;
298 uint32_t ix;
299
300 GET_FLOAT_WORD(ix, x);
301 ix &= 0x7fffffff;
302 if (ix >= 0x41000000){p = qr8; q = qs8;}
303 else if (ix >= 0x409173eb){p = qr5; q = qs5;}
304 else if (ix >= 0x4036d917){p = qr3; q = qs3;}
305 else /*ix >= 0x40000000*/ {p = qr2; q = qs2;}
306 z = 1.0f/(x*x);
307 r = p[0]+z*(p[1]+z*(p[2]+z*(p[3]+z*(p[4]+z*p[5]))));
308 s = 1.0f+z*(q[0]+z*(q[1]+z*(q[2]+z*(q[3]+z*(q[4]+z*q[5])))));
309 return (.375f + r/s)/x;
310}
libc/musl/src/math/jn.c created+280
......@@ -0,0 +1,280 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_jn.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * jn(n, x), yn(n, x)
14 * floating point Bessel's function of the 1st and 2nd kind
15 * of order n
16 *
17 * Special cases:
18 * y0(0)=y1(0)=yn(n,0) = -inf with division by zero signal;
19 * y0(-ve)=y1(-ve)=yn(n,-ve) are NaN with invalid signal.
20 * Note 2. About jn(n,x), yn(n,x)
21 * For n=0, j0(x) is called,
22 * for n=1, j1(x) is called,
23 * for n<=x, forward recursion is used starting
24 * from values of j0(x) and j1(x).
25 * for n>x, a continued fraction approximation to
26 * j(n,x)/j(n-1,x) is evaluated and then backward
27 * recursion is used starting from a supposed value
28 * for j(n,x). The resulting value of j(0,x) is
29 * compared with the actual value to correct the
30 * supposed value of j(n,x).
31 *
32 * yn(n,x) is similar in all respects, except
33 * that forward recursion is used for all
34 * values of n>1.
35 */
36
37#include "libm.h"
38
39static const double invsqrtpi = 5.64189583547756279280e-01; /* 0x3FE20DD7, 0x50429B6D */
40
41double jn(int n, double x)
42{
43 uint32_t ix, lx;
44 int nm1, i, sign;
45 double a, b, temp;
46
47 EXTRACT_WORDS(ix, lx, x);
48 sign = ix>>31;
49 ix &= 0x7fffffff;
50
51 if ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */
52 return x;
53
54 /* J(-n,x) = (-1)^n * J(n, x), J(n, -x) = (-1)^n * J(n, x)
55 * Thus, J(-n,x) = J(n,-x)
56 */
57 /* nm1 = |n|-1 is used instead of |n| to handle n==INT_MIN */
58 if (n == 0)
59 return j0(x);
60 if (n < 0) {
61 nm1 = -(n+1);
62 x = -x;
63 sign ^= 1;
64 } else
65 nm1 = n-1;
66 if (nm1 == 0)
67 return j1(x);
68
69 sign &= n; /* even n: 0, odd n: signbit(x) */
70 x = fabs(x);
71 if ((ix|lx) == 0 || ix == 0x7ff00000) /* if x is 0 or inf */
72 b = 0.0;
73 else if (nm1 < x) {
74 /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
75 if (ix >= 0x52d00000) { /* x > 2**302 */
76 /* (x >> n**2)
77 * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
78 * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
79 * Let s=sin(x), c=cos(x),
80 * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
81 *
82 * n sin(xn)*sqt2 cos(xn)*sqt2
83 * ----------------------------------
84 * 0 s-c c+s
85 * 1 -s-c -c+s
86 * 2 -s+c -c-s
87 * 3 s+c c-s
88 */
89 switch(nm1&3) {
90 case 0: temp = -cos(x)+sin(x); break;
91 case 1: temp = -cos(x)-sin(x); break;
92 case 2: temp = cos(x)-sin(x); break;
93 default:
94 case 3: temp = cos(x)+sin(x); break;
95 }
96 b = invsqrtpi*temp/sqrt(x);
97 } else {
98 a = j0(x);
99 b = j1(x);
100 for (i=0; i<nm1; ) {
101 i++;
102 temp = b;
103 b = b*(2.0*i/x) - a; /* avoid underflow */
104 a = temp;
105 }
106 }
107 } else {
108 if (ix < 0x3e100000) { /* x < 2**-29 */
109 /* x is tiny, return the first Taylor expansion of J(n,x)
110 * J(n,x) = 1/n!*(x/2)^n - ...
111 */
112 if (nm1 > 32) /* underflow */
113 b = 0.0;
114 else {
115 temp = x*0.5;
116 b = temp;
117 a = 1.0;
118 for (i=2; i<=nm1+1; i++) {
119 a *= (double)i; /* a = n! */
120 b *= temp; /* b = (x/2)^n */
121 }
122 b = b/a;
123 }
124 } else {
125 /* use backward recurrence */
126 /* x x^2 x^2
127 * J(n,x)/J(n-1,x) = ---- ------ ------ .....
128 * 2n - 2(n+1) - 2(n+2)
129 *
130 * 1 1 1
131 * (for large x) = ---- ------ ------ .....
132 * 2n 2(n+1) 2(n+2)
133 * -- - ------ - ------ -
134 * x x x
135 *
136 * Let w = 2n/x and h=2/x, then the above quotient
137 * is equal to the continued fraction:
138 * 1
139 * = -----------------------
140 * 1
141 * w - -----------------
142 * 1
143 * w+h - ---------
144 * w+2h - ...
145 *
146 * To determine how many terms needed, let
147 * Q(0) = w, Q(1) = w(w+h) - 1,
148 * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
149 * When Q(k) > 1e4 good for single
150 * When Q(k) > 1e9 good for double
151 * When Q(k) > 1e17 good for quadruple
152 */
153 /* determine k */
154 double t,q0,q1,w,h,z,tmp,nf;
155 int k;
156
157 nf = nm1 + 1.0;
158 w = 2*nf/x;
159 h = 2/x;
160 z = w+h;
161 q0 = w;
162 q1 = w*z - 1.0;
163 k = 1;
164 while (q1 < 1.0e9) {
165 k += 1;
166 z += h;
167 tmp = z*q1 - q0;
168 q0 = q1;
169 q1 = tmp;
170 }
171 for (t=0.0, i=k; i>=0; i--)
172 t = 1/(2*(i+nf)/x - t);
173 a = t;
174 b = 1.0;
175 /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
176 * Hence, if n*(log(2n/x)) > ...
177 * single 8.8722839355e+01
178 * double 7.09782712893383973096e+02
179 * long double 1.1356523406294143949491931077970765006170e+04
180 * then recurrent value may overflow and the result is
181 * likely underflow to zero
182 */
183 tmp = nf*log(fabs(w));
184 if (tmp < 7.09782712893383973096e+02) {
185 for (i=nm1; i>0; i--) {
186 temp = b;
187 b = b*(2.0*i)/x - a;
188 a = temp;
189 }
190 } else {
191 for (i=nm1; i>0; i--) {
192 temp = b;
193 b = b*(2.0*i)/x - a;
194 a = temp;
195 /* scale b to avoid spurious overflow */
196 if (b > 0x1p500) {
197 a /= b;
198 t /= b;
199 b = 1.0;
200 }
201 }
202 }
203 z = j0(x);
204 w = j1(x);
205 if (fabs(z) >= fabs(w))
206 b = t*z/b;
207 else
208 b = t*w/a;
209 }
210 }
211 return sign ? -b : b;
212}
213
214
215double yn(int n, double x)
216{
217 uint32_t ix, lx, ib;
218 int nm1, sign, i;
219 double a, b, temp;
220
221 EXTRACT_WORDS(ix, lx, x);
222 sign = ix>>31;
223 ix &= 0x7fffffff;
224
225 if ((ix | (lx|-lx)>>31) > 0x7ff00000) /* nan */
226 return x;
227 if (sign && (ix|lx)!=0) /* x < 0 */
228 return 0/0.0;
229 if (ix == 0x7ff00000)
230 return 0.0;
231
232 if (n == 0)
233 return y0(x);
234 if (n < 0) {
235 nm1 = -(n+1);
236 sign = n&1;
237 } else {
238 nm1 = n-1;
239 sign = 0;
240 }
241 if (nm1 == 0)
242 return sign ? -y1(x) : y1(x);
243
244 if (ix >= 0x52d00000) { /* x > 2**302 */
245 /* (x >> n**2)
246 * Jn(x) = cos(x-(2n+1)*pi/4)*sqrt(2/x*pi)
247 * Yn(x) = sin(x-(2n+1)*pi/4)*sqrt(2/x*pi)
248 * Let s=sin(x), c=cos(x),
249 * xn=x-(2n+1)*pi/4, sqt2 = sqrt(2),then
250 *
251 * n sin(xn)*sqt2 cos(xn)*sqt2
252 * ----------------------------------
253 * 0 s-c c+s
254 * 1 -s-c -c+s
255 * 2 -s+c -c-s
256 * 3 s+c c-s
257 */
258 switch(nm1&3) {
259 case 0: temp = -sin(x)-cos(x); break;
260 case 1: temp = -sin(x)+cos(x); break;
261 case 2: temp = sin(x)+cos(x); break;
262 default:
263 case 3: temp = sin(x)-cos(x); break;
264 }
265 b = invsqrtpi*temp/sqrt(x);
266 } else {
267 a = y0(x);
268 b = y1(x);
269 /* quit if b is -inf */
270 GET_HIGH_WORD(ib, b);
271 for (i=0; i<nm1 && ib!=0xfff00000; ){
272 i++;
273 temp = b;
274 b = (2.0*i/x)*b - a;
275 GET_HIGH_WORD(ib, b);
276 a = temp;
277 }
278 }
279 return sign ? -b : b;
280}
libc/musl/src/math/jnf.c created+202
......@@ -0,0 +1,202 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_jnf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#define _GNU_SOURCE
17#include "libm.h"
18
19float jnf(int n, float x)
20{
21 uint32_t ix;
22 int nm1, sign, i;
23 float a, b, temp;
24
25 GET_FLOAT_WORD(ix, x);
26 sign = ix>>31;
27 ix &= 0x7fffffff;
28 if (ix > 0x7f800000) /* nan */
29 return x;
30
31 /* J(-n,x) = J(n,-x), use |n|-1 to avoid overflow in -n */
32 if (n == 0)
33 return j0f(x);
34 if (n < 0) {
35 nm1 = -(n+1);
36 x = -x;
37 sign ^= 1;
38 } else
39 nm1 = n-1;
40 if (nm1 == 0)
41 return j1f(x);
42
43 sign &= n; /* even n: 0, odd n: signbit(x) */
44 x = fabsf(x);
45 if (ix == 0 || ix == 0x7f800000) /* if x is 0 or inf */
46 b = 0.0f;
47 else if (nm1 < x) {
48 /* Safe to use J(n+1,x)=2n/x *J(n,x)-J(n-1,x) */
49 a = j0f(x);
50 b = j1f(x);
51 for (i=0; i<nm1; ){
52 i++;
53 temp = b;
54 b = b*(2.0f*i/x) - a;
55 a = temp;
56 }
57 } else {
58 if (ix < 0x35800000) { /* x < 2**-20 */
59 /* x is tiny, return the first Taylor expansion of J(n,x)
60 * J(n,x) = 1/n!*(x/2)^n - ...
61 */
62 if (nm1 > 8) /* underflow */
63 nm1 = 8;
64 temp = 0.5f * x;
65 b = temp;
66 a = 1.0f;
67 for (i=2; i<=nm1+1; i++) {
68 a *= (float)i; /* a = n! */
69 b *= temp; /* b = (x/2)^n */
70 }
71 b = b/a;
72 } else {
73 /* use backward recurrence */
74 /* x x^2 x^2
75 * J(n,x)/J(n-1,x) = ---- ------ ------ .....
76 * 2n - 2(n+1) - 2(n+2)
77 *
78 * 1 1 1
79 * (for large x) = ---- ------ ------ .....
80 * 2n 2(n+1) 2(n+2)
81 * -- - ------ - ------ -
82 * x x x
83 *
84 * Let w = 2n/x and h=2/x, then the above quotient
85 * is equal to the continued fraction:
86 * 1
87 * = -----------------------
88 * 1
89 * w - -----------------
90 * 1
91 * w+h - ---------
92 * w+2h - ...
93 *
94 * To determine how many terms needed, let
95 * Q(0) = w, Q(1) = w(w+h) - 1,
96 * Q(k) = (w+k*h)*Q(k-1) - Q(k-2),
97 * When Q(k) > 1e4 good for single
98 * When Q(k) > 1e9 good for double
99 * When Q(k) > 1e17 good for quadruple
100 */
101 /* determine k */
102 float t,q0,q1,w,h,z,tmp,nf;
103 int k;
104
105 nf = nm1+1.0f;
106 w = 2*nf/x;
107 h = 2/x;
108 z = w+h;
109 q0 = w;
110 q1 = w*z - 1.0f;
111 k = 1;
112 while (q1 < 1.0e4f) {
113 k += 1;
114 z += h;
115 tmp = z*q1 - q0;
116 q0 = q1;
117 q1 = tmp;
118 }
119 for (t=0.0f, i=k; i>=0; i--)
120 t = 1.0f/(2*(i+nf)/x-t);
121 a = t;
122 b = 1.0f;
123 /* estimate log((2/x)^n*n!) = n*log(2/x)+n*ln(n)
124 * Hence, if n*(log(2n/x)) > ...
125 * single 8.8722839355e+01
126 * double 7.09782712893383973096e+02
127 * long double 1.1356523406294143949491931077970765006170e+04
128 * then recurrent value may overflow and the result is
129 * likely underflow to zero
130 */
131 tmp = nf*logf(fabsf(w));
132 if (tmp < 88.721679688f) {
133 for (i=nm1; i>0; i--) {
134 temp = b;
135 b = 2.0f*i*b/x - a;
136 a = temp;
137 }
138 } else {
139 for (i=nm1; i>0; i--){
140 temp = b;
141 b = 2.0f*i*b/x - a;
142 a = temp;
143 /* scale b to avoid spurious overflow */
144 if (b > 0x1p60f) {
145 a /= b;
146 t /= b;
147 b = 1.0f;
148 }
149 }
150 }
151 z = j0f(x);
152 w = j1f(x);
153 if (fabsf(z) >= fabsf(w))
154 b = t*z/b;
155 else
156 b = t*w/a;
157 }
158 }
159 return sign ? -b : b;
160}
161
162float ynf(int n, float x)
163{
164 uint32_t ix, ib;
165 int nm1, sign, i;
166 float a, b, temp;
167
168 GET_FLOAT_WORD(ix, x);
169 sign = ix>>31;
170 ix &= 0x7fffffff;
171 if (ix > 0x7f800000) /* nan */
172 return x;
173 if (sign && ix != 0) /* x < 0 */
174 return 0/0.0f;
175 if (ix == 0x7f800000)
176 return 0.0f;
177
178 if (n == 0)
179 return y0f(x);
180 if (n < 0) {
181 nm1 = -(n+1);
182 sign = n&1;
183 } else {
184 nm1 = n-1;
185 sign = 0;
186 }
187 if (nm1 == 0)
188 return sign ? -y1f(x) : y1f(x);
189
190 a = y0f(x);
191 b = y1f(x);
192 /* quit if b is -inf */
193 GET_FLOAT_WORD(ib,b);
194 for (i = 0; i < nm1 && ib != 0xff800000; ) {
195 i++;
196 temp = b;
197 b = (2.0f*i/x)*b - a;
198 GET_FLOAT_WORD(ib, b);
199 a = temp;
200 }
201 return sign ? -b : b;
202}
libc/musl/src/math/ldexp.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3double ldexp(double x, int n)
4{
5 return scalbn(x, n);
6}
libc/musl/src/math/ldexpf.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3float ldexpf(float x, int n)
4{
5 return scalbnf(x, n);
6}
libc/musl/src/math/ldexpl.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3long double ldexpl(long double x, int n)
4{
5 return scalbnl(x, n);
6}
libc/musl/src/math/lgamma.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2#include "libm.h"
3
4double lgamma(double x)
5{
6 return __lgamma_r(x, &__signgam);
7}
libc/musl/src/math/lgamma_r.c created+283
......@@ -0,0 +1,283 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_lgamma_r.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 *
12 */
13/* lgamma_r(x, signgamp)
14 * Reentrant version of the logarithm of the Gamma function
15 * with user provide pointer for the sign of Gamma(x).
16 *
17 * Method:
18 * 1. Argument Reduction for 0 < x <= 8
19 * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
20 * reduce x to a number in [1.5,2.5] by
21 * lgamma(1+s) = log(s) + lgamma(s)
22 * for example,
23 * lgamma(7.3) = log(6.3) + lgamma(6.3)
24 * = log(6.3*5.3) + lgamma(5.3)
25 * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
26 * 2. Polynomial approximation of lgamma around its
27 * minimun ymin=1.461632144968362245 to maintain monotonicity.
28 * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
29 * Let z = x-ymin;
30 * lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
31 * where
32 * poly(z) is a 14 degree polynomial.
33 * 2. Rational approximation in the primary interval [2,3]
34 * We use the following approximation:
35 * s = x-2.0;
36 * lgamma(x) = 0.5*s + s*P(s)/Q(s)
37 * with accuracy
38 * |P/Q - (lgamma(x)-0.5s)| < 2**-61.71
39 * Our algorithms are based on the following observation
40 *
41 * zeta(2)-1 2 zeta(3)-1 3
42 * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ...
43 * 2 3
44 *
45 * where Euler = 0.5771... is the Euler constant, which is very
46 * close to 0.5.
47 *
48 * 3. For x>=8, we have
49 * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
50 * (better formula:
51 * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
52 * Let z = 1/x, then we approximation
53 * f(z) = lgamma(x) - (x-0.5)(log(x)-1)
54 * by
55 * 3 5 11
56 * w = w0 + w1*z + w2*z + w3*z + ... + w6*z
57 * where
58 * |w - f(z)| < 2**-58.74
59 *
60 * 4. For negative x, since (G is gamma function)
61 * -x*G(-x)*G(x) = pi/sin(pi*x),
62 * we have
63 * G(x) = pi/(sin(pi*x)*(-x)*G(-x))
64 * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
65 * Hence, for x<0, signgam = sign(sin(pi*x)) and
66 * lgamma(x) = log(|Gamma(x)|)
67 * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
68 * Note: one should avoid compute pi*(-x) directly in the
69 * computation of sin(pi*(-x)).
70 *
71 * 5. Special Cases
72 * lgamma(2+s) ~ s*(1-Euler) for tiny s
73 * lgamma(1) = lgamma(2) = 0
74 * lgamma(x) ~ -log(|x|) for tiny x
75 * lgamma(0) = lgamma(neg.integer) = inf and raise divide-by-zero
76 * lgamma(inf) = inf
77 * lgamma(-inf) = inf (bug for bug compatible with C99!?)
78 *
79 */
80
81#include "libm.h"
82
83static const double
84pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
85a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */
86a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */
87a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */
88a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */
89a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */
90a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */
91a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */
92a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */
93a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */
94a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */
95a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */
96a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */
97tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */
98tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */
99/* tt = -(tail of tf) */
100tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */
101t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */
102t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */
103t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */
104t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */
105t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */
106t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */
107t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */
108t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */
109t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */
110t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */
111t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */
112t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */
113t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */
114t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */
115t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */
116u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
117u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */
118u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */
119u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */
120u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */
121u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */
122v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */
123v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */
124v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */
125v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */
126v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */
127s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
128s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */
129s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */
130s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */
131s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */
132s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */
133s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */
134r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */
135r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */
136r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */
137r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */
138r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */
139r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */
140w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */
141w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */
142w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */
143w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */
144w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
145w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
146w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
147
148/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */
149static double sin_pi(double x)
150{
151 int n;
152
153 /* spurious inexact if odd int */
154 x = 2.0*(x*0.5 - floor(x*0.5)); /* x mod 2.0 */
155
156 n = (int)(x*4.0);
157 n = (n+1)/2;
158 x -= n*0.5f;
159 x *= pi;
160
161 switch (n) {
162 default: /* case 4: */
163 case 0: return __sin(x, 0.0, 0);
164 case 1: return __cos(x, 0.0);
165 case 2: return __sin(-x, 0.0, 0);
166 case 3: return -__cos(x, 0.0);
167 }
168}
169
170double __lgamma_r(double x, int *signgamp)
171{
172 union {double f; uint64_t i;} u = {x};
173 double_t t,y,z,nadj,p,p1,p2,p3,q,r,w;
174 uint32_t ix;
175 int sign,i;
176
177 /* purge off +-inf, NaN, +-0, tiny and negative arguments */
178 *signgamp = 1;
179 sign = u.i>>63;
180 ix = u.i>>32 & 0x7fffffff;
181 if (ix >= 0x7ff00000)
182 return x*x;
183 if (ix < (0x3ff-70)<<20) { /* |x|<2**-70, return -log(|x|) */
184 if(sign) {
185 x = -x;
186 *signgamp = -1;
187 }
188 return -log(x);
189 }
190 if (sign) {
191 x = -x;
192 t = sin_pi(x);
193 if (t == 0.0) /* -integer */
194 return 1.0/(x-x);
195 if (t > 0.0)
196 *signgamp = -1;
197 else
198 t = -t;
199 nadj = log(pi/(t*x));
200 }
201
202 /* purge off 1 and 2 */
203 if ((ix == 0x3ff00000 || ix == 0x40000000) && (uint32_t)u.i == 0)
204 r = 0;
205 /* for x < 2.0 */
206 else if (ix < 0x40000000) {
207 if (ix <= 0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */
208 r = -log(x);
209 if (ix >= 0x3FE76944) {
210 y = 1.0 - x;
211 i = 0;
212 } else if (ix >= 0x3FCDA661) {
213 y = x - (tc-1.0);
214 i = 1;
215 } else {
216 y = x;
217 i = 2;
218 }
219 } else {
220 r = 0.0;
221 if (ix >= 0x3FFBB4C3) { /* [1.7316,2] */
222 y = 2.0 - x;
223 i = 0;
224 } else if(ix >= 0x3FF3B4C4) { /* [1.23,1.73] */
225 y = x - tc;
226 i = 1;
227 } else {
228 y = x - 1.0;
229 i = 2;
230 }
231 }
232 switch (i) {
233 case 0:
234 z = y*y;
235 p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
236 p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
237 p = y*p1+p2;
238 r += (p-0.5*y);
239 break;
240 case 1:
241 z = y*y;
242 w = z*y;
243 p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */
244 p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
245 p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
246 p = z*p1-(tt-w*(p2+y*p3));
247 r += tf + p;
248 break;
249 case 2:
250 p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
251 p2 = 1.0+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
252 r += -0.5*y + p1/p2;
253 }
254 } else if (ix < 0x40200000) { /* x < 8.0 */
255 i = (int)x;
256 y = x - (double)i;
257 p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
258 q = 1.0+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
259 r = 0.5*y+p/q;
260 z = 1.0; /* lgamma(1+s) = log(s) + lgamma(s) */
261 switch (i) {
262 case 7: z *= y + 6.0; /* FALLTHRU */
263 case 6: z *= y + 5.0; /* FALLTHRU */
264 case 5: z *= y + 4.0; /* FALLTHRU */
265 case 4: z *= y + 3.0; /* FALLTHRU */
266 case 3: z *= y + 2.0; /* FALLTHRU */
267 r += log(z);
268 break;
269 }
270 } else if (ix < 0x43900000) { /* 8.0 <= x < 2**58 */
271 t = log(x);
272 z = 1.0/x;
273 y = z*z;
274 w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
275 r = (x-0.5)*(t-1.0)+w;
276 } else /* 2**58 <= x <= inf */
277 r = x*(log(x)-1.0);
278 if (sign)
279 r = nadj - r;
280 return r;
281}
282
283weak_alias(__lgamma_r, lgamma_r);
libc/musl/src/math/lgammaf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2#include "libm.h"
3
4float lgammaf(float x)
5{
6 return __lgammaf_r(x, &__signgam);
7}
libc/musl/src/math/lgammaf_r.c created+218
......@@ -0,0 +1,218 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_lgammaf_r.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include "libm.h"
17
18static const float
19pi = 3.1415927410e+00, /* 0x40490fdb */
20a0 = 7.7215664089e-02, /* 0x3d9e233f */
21a1 = 3.2246702909e-01, /* 0x3ea51a66 */
22a2 = 6.7352302372e-02, /* 0x3d89f001 */
23a3 = 2.0580807701e-02, /* 0x3ca89915 */
24a4 = 7.3855509982e-03, /* 0x3bf2027e */
25a5 = 2.8905137442e-03, /* 0x3b3d6ec6 */
26a6 = 1.1927076848e-03, /* 0x3a9c54a1 */
27a7 = 5.1006977446e-04, /* 0x3a05b634 */
28a8 = 2.2086278477e-04, /* 0x39679767 */
29a9 = 1.0801156895e-04, /* 0x38e28445 */
30a10 = 2.5214456400e-05, /* 0x37d383a2 */
31a11 = 4.4864096708e-05, /* 0x383c2c75 */
32tc = 1.4616321325e+00, /* 0x3fbb16c3 */
33tf = -1.2148628384e-01, /* 0xbdf8cdcd */
34/* tt = -(tail of tf) */
35tt = 6.6971006518e-09, /* 0x31e61c52 */
36t0 = 4.8383611441e-01, /* 0x3ef7b95e */
37t1 = -1.4758771658e-01, /* 0xbe17213c */
38t2 = 6.4624942839e-02, /* 0x3d845a15 */
39t3 = -3.2788541168e-02, /* 0xbd064d47 */
40t4 = 1.7970675603e-02, /* 0x3c93373d */
41t5 = -1.0314224288e-02, /* 0xbc28fcfe */
42t6 = 6.1005386524e-03, /* 0x3bc7e707 */
43t7 = -3.6845202558e-03, /* 0xbb7177fe */
44t8 = 2.2596477065e-03, /* 0x3b141699 */
45t9 = -1.4034647029e-03, /* 0xbab7f476 */
46t10 = 8.8108185446e-04, /* 0x3a66f867 */
47t11 = -5.3859531181e-04, /* 0xba0d3085 */
48t12 = 3.1563205994e-04, /* 0x39a57b6b */
49t13 = -3.1275415677e-04, /* 0xb9a3f927 */
50t14 = 3.3552918467e-04, /* 0x39afe9f7 */
51u0 = -7.7215664089e-02, /* 0xbd9e233f */
52u1 = 6.3282704353e-01, /* 0x3f2200f4 */
53u2 = 1.4549225569e+00, /* 0x3fba3ae7 */
54u3 = 9.7771751881e-01, /* 0x3f7a4bb2 */
55u4 = 2.2896373272e-01, /* 0x3e6a7578 */
56u5 = 1.3381091878e-02, /* 0x3c5b3c5e */
57v1 = 2.4559779167e+00, /* 0x401d2ebe */
58v2 = 2.1284897327e+00, /* 0x4008392d */
59v3 = 7.6928514242e-01, /* 0x3f44efdf */
60v4 = 1.0422264785e-01, /* 0x3dd572af */
61v5 = 3.2170924824e-03, /* 0x3b52d5db */
62s0 = -7.7215664089e-02, /* 0xbd9e233f */
63s1 = 2.1498242021e-01, /* 0x3e5c245a */
64s2 = 3.2577878237e-01, /* 0x3ea6cc7a */
65s3 = 1.4635047317e-01, /* 0x3e15dce6 */
66s4 = 2.6642270386e-02, /* 0x3cda40e4 */
67s5 = 1.8402845599e-03, /* 0x3af135b4 */
68s6 = 3.1947532989e-05, /* 0x3805ff67 */
69r1 = 1.3920053244e+00, /* 0x3fb22d3b */
70r2 = 7.2193557024e-01, /* 0x3f38d0c5 */
71r3 = 1.7193385959e-01, /* 0x3e300f6e */
72r4 = 1.8645919859e-02, /* 0x3c98bf54 */
73r5 = 7.7794247773e-04, /* 0x3a4beed6 */
74r6 = 7.3266842264e-06, /* 0x36f5d7bd */
75w0 = 4.1893854737e-01, /* 0x3ed67f1d */
76w1 = 8.3333335817e-02, /* 0x3daaaaab */
77w2 = -2.7777778450e-03, /* 0xbb360b61 */
78w3 = 7.9365057172e-04, /* 0x3a500cfd */
79w4 = -5.9518753551e-04, /* 0xba1c065c */
80w5 = 8.3633989561e-04, /* 0x3a5b3dd2 */
81w6 = -1.6309292987e-03; /* 0xbad5c4e8 */
82
83/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */
84static float sin_pi(float x)
85{
86 double_t y;
87 int n;
88
89 /* spurious inexact if odd int */
90 x = 2*(x*0.5f - floorf(x*0.5f)); /* x mod 2.0 */
91
92 n = (int)(x*4);
93 n = (n+1)/2;
94 y = x - n*0.5f;
95 y *= 3.14159265358979323846;
96 switch (n) {
97 default: /* case 4: */
98 case 0: return __sindf(y);
99 case 1: return __cosdf(y);
100 case 2: return __sindf(-y);
101 case 3: return -__cosdf(y);
102 }
103}
104
105float __lgammaf_r(float x, int *signgamp)
106{
107 union {float f; uint32_t i;} u = {x};
108 float t,y,z,nadj,p,p1,p2,p3,q,r,w;
109 uint32_t ix;
110 int i,sign;
111
112 /* purge off +-inf, NaN, +-0, tiny and negative arguments */
113 *signgamp = 1;
114 sign = u.i>>31;
115 ix = u.i & 0x7fffffff;
116 if (ix >= 0x7f800000)
117 return x*x;
118 if (ix < 0x35000000) { /* |x| < 2**-21, return -log(|x|) */
119 if (sign) {
120 *signgamp = -1;
121 x = -x;
122 }
123 return -logf(x);
124 }
125 if (sign) {
126 x = -x;
127 t = sin_pi(x);
128 if (t == 0.0f) /* -integer */
129 return 1.0f/(x-x);
130 if (t > 0.0f)
131 *signgamp = -1;
132 else
133 t = -t;
134 nadj = logf(pi/(t*x));
135 }
136
137 /* purge off 1 and 2 */
138 if (ix == 0x3f800000 || ix == 0x40000000)
139 r = 0;
140 /* for x < 2.0 */
141 else if (ix < 0x40000000) {
142 if (ix <= 0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */
143 r = -logf(x);
144 if (ix >= 0x3f3b4a20) {
145 y = 1.0f - x;
146 i = 0;
147 } else if (ix >= 0x3e6d3308) {
148 y = x - (tc-1.0f);
149 i = 1;
150 } else {
151 y = x;
152 i = 2;
153 }
154 } else {
155 r = 0.0f;
156 if (ix >= 0x3fdda618) { /* [1.7316,2] */
157 y = 2.0f - x;
158 i = 0;
159 } else if (ix >= 0x3F9da620) { /* [1.23,1.73] */
160 y = x - tc;
161 i = 1;
162 } else {
163 y = x - 1.0f;
164 i = 2;
165 }
166 }
167 switch(i) {
168 case 0:
169 z = y*y;
170 p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
171 p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
172 p = y*p1+p2;
173 r += p - 0.5f*y;
174 break;
175 case 1:
176 z = y*y;
177 w = z*y;
178 p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */
179 p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
180 p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
181 p = z*p1-(tt-w*(p2+y*p3));
182 r += (tf + p);
183 break;
184 case 2:
185 p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
186 p2 = 1.0f+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
187 r += -0.5f*y + p1/p2;
188 }
189 } else if (ix < 0x41000000) { /* x < 8.0 */
190 i = (int)x;
191 y = x - (float)i;
192 p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
193 q = 1.0f+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
194 r = 0.5f*y+p/q;
195 z = 1.0f; /* lgamma(1+s) = log(s) + lgamma(s) */
196 switch (i) {
197 case 7: z *= y + 6.0f; /* FALLTHRU */
198 case 6: z *= y + 5.0f; /* FALLTHRU */
199 case 5: z *= y + 4.0f; /* FALLTHRU */
200 case 4: z *= y + 3.0f; /* FALLTHRU */
201 case 3: z *= y + 2.0f; /* FALLTHRU */
202 r += logf(z);
203 break;
204 }
205 } else if (ix < 0x5c800000) { /* 8.0 <= x < 2**58 */
206 t = logf(x);
207 z = 1.0f/x;
208 y = z*z;
209 w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
210 r = (x-0.5f)*(t-1.0f)+w;
211 } else /* 2**58 <= x <= inf */
212 r = x*(logf(x)-1.0f);
213 if (sign)
214 r = nadj - r;
215 return r;
216}
217
218weak_alias(__lgammaf_r, lgammaf_r);
libc/musl/src/math/lgammal.c created+353
......@@ -0,0 +1,353 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_lgammal.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
14 *
15 * Permission to use, copy, modify, and distribute this software for any
16 * purpose with or without fee is hereby granted, provided that the above
17 * copyright notice and this permission notice appear in all copies.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
20 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
21 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
22 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
23 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
24 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
25 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 */
27/* lgammal(x)
28 * Reentrant version of the logarithm of the Gamma function
29 * with user provide pointer for the sign of Gamma(x).
30 *
31 * Method:
32 * 1. Argument Reduction for 0 < x <= 8
33 * Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
34 * reduce x to a number in [1.5,2.5] by
35 * lgamma(1+s) = log(s) + lgamma(s)
36 * for example,
37 * lgamma(7.3) = log(6.3) + lgamma(6.3)
38 * = log(6.3*5.3) + lgamma(5.3)
39 * = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
40 * 2. Polynomial approximation of lgamma around its
41 * minimun ymin=1.461632144968362245 to maintain monotonicity.
42 * On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
43 * Let z = x-ymin;
44 * lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
45 * 2. Rational approximation in the primary interval [2,3]
46 * We use the following approximation:
47 * s = x-2.0;
48 * lgamma(x) = 0.5*s + s*P(s)/Q(s)
49 * Our algorithms are based on the following observation
50 *
51 * zeta(2)-1 2 zeta(3)-1 3
52 * lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ...
53 * 2 3
54 *
55 * where Euler = 0.5771... is the Euler constant, which is very
56 * close to 0.5.
57 *
58 * 3. For x>=8, we have
59 * lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
60 * (better formula:
61 * lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
62 * Let z = 1/x, then we approximation
63 * f(z) = lgamma(x) - (x-0.5)(log(x)-1)
64 * by
65 * 3 5 11
66 * w = w0 + w1*z + w2*z + w3*z + ... + w6*z
67 *
68 * 4. For negative x, since (G is gamma function)
69 * -x*G(-x)*G(x) = pi/sin(pi*x),
70 * we have
71 * G(x) = pi/(sin(pi*x)*(-x)*G(-x))
72 * since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
73 * Hence, for x<0, signgam = sign(sin(pi*x)) and
74 * lgamma(x) = log(|Gamma(x)|)
75 * = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
76 * Note: one should avoid compute pi*(-x) directly in the
77 * computation of sin(pi*(-x)).
78 *
79 * 5. Special Cases
80 * lgamma(2+s) ~ s*(1-Euler) for tiny s
81 * lgamma(1)=lgamma(2)=0
82 * lgamma(x) ~ -log(x) for tiny x
83 * lgamma(0) = lgamma(inf) = inf
84 * lgamma(-integer) = +-inf
85 *
86 */
87
88#define _GNU_SOURCE
89#include "libm.h"
90
91#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
92long double __lgammal_r(long double x, int *sg)
93{
94 return __lgamma_r(x, sg);
95}
96#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
97static const long double
98pi = 3.14159265358979323846264L,
99
100/* lgam(1+x) = 0.5 x + x a(x)/b(x)
101 -0.268402099609375 <= x <= 0
102 peak relative error 6.6e-22 */
103a0 = -6.343246574721079391729402781192128239938E2L,
104a1 = 1.856560238672465796768677717168371401378E3L,
105a2 = 2.404733102163746263689288466865843408429E3L,
106a3 = 8.804188795790383497379532868917517596322E2L,
107a4 = 1.135361354097447729740103745999661157426E2L,
108a5 = 3.766956539107615557608581581190400021285E0L,
109
110b0 = 8.214973713960928795704317259806842490498E3L,
111b1 = 1.026343508841367384879065363925870888012E4L,
112b2 = 4.553337477045763320522762343132210919277E3L,
113b3 = 8.506975785032585797446253359230031874803E2L,
114b4 = 6.042447899703295436820744186992189445813E1L,
115/* b5 = 1.000000000000000000000000000000000000000E0 */
116
117
118tc = 1.4616321449683623412626595423257213284682E0L,
119tf = -1.2148629053584961146050602565082954242826E-1, /* double precision */
120/* tt = (tail of tf), i.e. tf + tt has extended precision. */
121tt = 3.3649914684731379602768989080467587736363E-18L,
122/* lgam ( 1.4616321449683623412626595423257213284682E0 ) =
123-1.2148629053584960809551455717769158215135617312999903886372437313313530E-1 */
124
125/* lgam (x + tc) = tf + tt + x g(x)/h(x)
126 -0.230003726999612341262659542325721328468 <= x
127 <= 0.2699962730003876587373404576742786715318
128 peak relative error 2.1e-21 */
129g0 = 3.645529916721223331888305293534095553827E-18L,
130g1 = 5.126654642791082497002594216163574795690E3L,
131g2 = 8.828603575854624811911631336122070070327E3L,
132g3 = 5.464186426932117031234820886525701595203E3L,
133g4 = 1.455427403530884193180776558102868592293E3L,
134g5 = 1.541735456969245924860307497029155838446E2L,
135g6 = 4.335498275274822298341872707453445815118E0L,
136
137h0 = 1.059584930106085509696730443974495979641E4L,
138h1 = 2.147921653490043010629481226937850618860E4L,
139h2 = 1.643014770044524804175197151958100656728E4L,
140h3 = 5.869021995186925517228323497501767586078E3L,
141h4 = 9.764244777714344488787381271643502742293E2L,
142h5 = 6.442485441570592541741092969581997002349E1L,
143/* h6 = 1.000000000000000000000000000000000000000E0 */
144
145
146/* lgam (x+1) = -0.5 x + x u(x)/v(x)
147 -0.100006103515625 <= x <= 0.231639862060546875
148 peak relative error 1.3e-21 */
149u0 = -8.886217500092090678492242071879342025627E1L,
150u1 = 6.840109978129177639438792958320783599310E2L,
151u2 = 2.042626104514127267855588786511809932433E3L,
152u3 = 1.911723903442667422201651063009856064275E3L,
153u4 = 7.447065275665887457628865263491667767695E2L,
154u5 = 1.132256494121790736268471016493103952637E2L,
155u6 = 4.484398885516614191003094714505960972894E0L,
156
157v0 = 1.150830924194461522996462401210374632929E3L,
158v1 = 3.399692260848747447377972081399737098610E3L,
159v2 = 3.786631705644460255229513563657226008015E3L,
160v3 = 1.966450123004478374557778781564114347876E3L,
161v4 = 4.741359068914069299837355438370682773122E2L,
162v5 = 4.508989649747184050907206782117647852364E1L,
163/* v6 = 1.000000000000000000000000000000000000000E0 */
164
165
166/* lgam (x+2) = .5 x + x s(x)/r(x)
167 0 <= x <= 1
168 peak relative error 7.2e-22 */
169s0 = 1.454726263410661942989109455292824853344E6L,
170s1 = -3.901428390086348447890408306153378922752E6L,
171s2 = -6.573568698209374121847873064292963089438E6L,
172s3 = -3.319055881485044417245964508099095984643E6L,
173s4 = -7.094891568758439227560184618114707107977E5L,
174s5 = -6.263426646464505837422314539808112478303E4L,
175s6 = -1.684926520999477529949915657519454051529E3L,
176
177r0 = -1.883978160734303518163008696712983134698E7L,
178r1 = -2.815206082812062064902202753264922306830E7L,
179r2 = -1.600245495251915899081846093343626358398E7L,
180r3 = -4.310526301881305003489257052083370058799E6L,
181r4 = -5.563807682263923279438235987186184968542E5L,
182r5 = -3.027734654434169996032905158145259713083E4L,
183r6 = -4.501995652861105629217250715790764371267E2L,
184/* r6 = 1.000000000000000000000000000000000000000E0 */
185
186
187/* lgam(x) = ( x - 0.5 ) * log(x) - x + LS2PI + 1/x w(1/x^2)
188 x >= 8
189 Peak relative error 1.51e-21
190w0 = LS2PI - 0.5 */
191w0 = 4.189385332046727417803e-1L,
192w1 = 8.333333333333331447505E-2L,
193w2 = -2.777777777750349603440E-3L,
194w3 = 7.936507795855070755671E-4L,
195w4 = -5.952345851765688514613E-4L,
196w5 = 8.412723297322498080632E-4L,
197w6 = -1.880801938119376907179E-3L,
198w7 = 4.885026142432270781165E-3L;
199
200/* sin(pi*x) assuming x > 2^-1000, if sin(pi*x)==0 the sign is arbitrary */
201static long double sin_pi(long double x)
202{
203 int n;
204
205 /* spurious inexact if odd int */
206 x *= 0.5;
207 x = 2.0*(x - floorl(x)); /* x mod 2.0 */
208
209 n = (int)(x*4.0);
210 n = (n+1)/2;
211 x -= n*0.5f;
212 x *= pi;
213
214 switch (n) {
215 default: /* case 4: */
216 case 0: return __sinl(x, 0.0, 0);
217 case 1: return __cosl(x, 0.0);
218 case 2: return __sinl(-x, 0.0, 0);
219 case 3: return -__cosl(x, 0.0);
220 }
221}
222
223long double __lgammal_r(long double x, int *sg) {
224 long double t, y, z, nadj, p, p1, p2, q, r, w;
225 union ldshape u = {x};
226 uint32_t ix = (u.i.se & 0x7fffU)<<16 | u.i.m>>48;
227 int sign = u.i.se >> 15;
228 int i;
229
230 *sg = 1;
231
232 /* purge off +-inf, NaN, +-0, tiny and negative arguments */
233 if (ix >= 0x7fff0000)
234 return x * x;
235 if (ix < 0x3fc08000) { /* |x|<2**-63, return -log(|x|) */
236 if (sign) {
237 *sg = -1;
238 x = -x;
239 }
240 return -logl(x);
241 }
242 if (sign) {
243 x = -x;
244 t = sin_pi(x);
245 if (t == 0.0)
246 return 1.0 / (x-x); /* -integer */
247 if (t > 0.0)
248 *sg = -1;
249 else
250 t = -t;
251 nadj = logl(pi / (t * x));
252 }
253
254 /* purge off 1 and 2 (so the sign is ok with downward rounding) */
255 if ((ix == 0x3fff8000 || ix == 0x40008000) && u.i.m == 0) {
256 r = 0;
257 } else if (ix < 0x40008000) { /* x < 2.0 */
258 if (ix <= 0x3ffee666) { /* 8.99993896484375e-1 */
259 /* lgamma(x) = lgamma(x+1) - log(x) */
260 r = -logl(x);
261 if (ix >= 0x3ffebb4a) { /* 7.31597900390625e-1 */
262 y = x - 1.0;
263 i = 0;
264 } else if (ix >= 0x3ffced33) { /* 2.31639862060546875e-1 */
265 y = x - (tc - 1.0);
266 i = 1;
267 } else { /* x < 0.23 */
268 y = x;
269 i = 2;
270 }
271 } else {
272 r = 0.0;
273 if (ix >= 0x3fffdda6) { /* 1.73162841796875 */
274 /* [1.7316,2] */
275 y = x - 2.0;
276 i = 0;
277 } else if (ix >= 0x3fff9da6) { /* 1.23162841796875 */
278 /* [1.23,1.73] */
279 y = x - tc;
280 i = 1;
281 } else {
282 /* [0.9, 1.23] */
283 y = x - 1.0;
284 i = 2;
285 }
286 }
287 switch (i) {
288 case 0:
289 p1 = a0 + y * (a1 + y * (a2 + y * (a3 + y * (a4 + y * a5))));
290 p2 = b0 + y * (b1 + y * (b2 + y * (b3 + y * (b4 + y))));
291 r += 0.5 * y + y * p1/p2;
292 break;
293 case 1:
294 p1 = g0 + y * (g1 + y * (g2 + y * (g3 + y * (g4 + y * (g5 + y * g6)))));
295 p2 = h0 + y * (h1 + y * (h2 + y * (h3 + y * (h4 + y * (h5 + y)))));
296 p = tt + y * p1/p2;
297 r += (tf + p);
298 break;
299 case 2:
300 p1 = y * (u0 + y * (u1 + y * (u2 + y * (u3 + y * (u4 + y * (u5 + y * u6))))));
301 p2 = v0 + y * (v1 + y * (v2 + y * (v3 + y * (v4 + y * (v5 + y)))));
302 r += (-0.5 * y + p1 / p2);
303 }
304 } else if (ix < 0x40028000) { /* 8.0 */
305 /* x < 8.0 */
306 i = (int)x;
307 y = x - (double)i;
308 p = y * (s0 + y * (s1 + y * (s2 + y * (s3 + y * (s4 + y * (s5 + y * s6))))));
309 q = r0 + y * (r1 + y * (r2 + y * (r3 + y * (r4 + y * (r5 + y * (r6 + y))))));
310 r = 0.5 * y + p / q;
311 z = 1.0;
312 /* lgamma(1+s) = log(s) + lgamma(s) */
313 switch (i) {
314 case 7:
315 z *= (y + 6.0); /* FALLTHRU */
316 case 6:
317 z *= (y + 5.0); /* FALLTHRU */
318 case 5:
319 z *= (y + 4.0); /* FALLTHRU */
320 case 4:
321 z *= (y + 3.0); /* FALLTHRU */
322 case 3:
323 z *= (y + 2.0); /* FALLTHRU */
324 r += logl(z);
325 break;
326 }
327 } else if (ix < 0x40418000) { /* 2^66 */
328 /* 8.0 <= x < 2**66 */
329 t = logl(x);
330 z = 1.0 / x;
331 y = z * z;
332 w = w0 + z * (w1 + y * (w2 + y * (w3 + y * (w4 + y * (w5 + y * (w6 + y * w7))))));
333 r = (x - 0.5) * (t - 1.0) + w;
334 } else /* 2**66 <= x <= inf */
335 r = x * (logl(x) - 1.0);
336 if (sign)
337 r = nadj - r;
338 return r;
339}
340#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
341// TODO: broken implementation to make things compile
342long double __lgammal_r(long double x, int *sg)
343{
344 return __lgamma_r(x, sg);
345}
346#endif
347
348long double lgammal(long double x)
349{
350 return __lgammal_r(x, &__signgam);
351}
352
353weak_alias(__lgammal_r, lgammal_r);
libc/musl/src/math/llrint.c created+8
......@@ -0,0 +1,8 @@
1#include <math.h>
2
3/* uses LLONG_MAX > 2^53, see comments in lrint.c */
4
5long long llrint(double x)
6{
7 return rint(x);
8}
libc/musl/src/math/llrintf.c created+8
......@@ -0,0 +1,8 @@
1#include <math.h>
2
3/* uses LLONG_MAX > 2^24, see comments in lrint.c */
4
5long long llrintf(float x)
6{
7 return rintf(x);
8}
libc/musl/src/math/llrintl.c created+36
......@@ -0,0 +1,36 @@
1#include <limits.h>
2#include <fenv.h>
3#include "libm.h"
4
5
6#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
7long long llrintl(long double x)
8{
9 return llrint(x);
10}
11#elif defined(FE_INEXACT)
12/*
13see comments in lrint.c
14
15Note that if LLONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64
16then x == 2**63 - 0.5 is the only input that overflows and
17raises inexact (with tonearest or upward rounding mode)
18*/
19long long llrintl(long double x)
20{
21 #pragma STDC FENV_ACCESS ON
22 int e;
23
24 e = fetestexcept(FE_INEXACT);
25 x = rintl(x);
26 if (!e && (x > LLONG_MAX || x < LLONG_MIN))
27 feclearexcept(FE_INEXACT);
28 /* conversion */
29 return x;
30}
31#else
32long long llrintl(long double x)
33{
34 return rintl(x);
35}
36#endif
libc/musl/src/math/llround.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3long long llround(double x)
4{
5 return round(x);
6}
libc/musl/src/math/llroundf.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3long long llroundf(float x)
4{
5 return roundf(x);
6}
libc/musl/src/math/llroundl.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3long long llroundl(long double x)
4{
5 return roundl(x);
6}
libc/musl/src/math/log.c created+118
......@@ -0,0 +1,118 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_log.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* log(x)
13 * Return the logarithm of x
14 *
15 * Method :
16 * 1. Argument Reduction: find k and f such that
17 * x = 2^k * (1+f),
18 * where sqrt(2)/2 < 1+f < sqrt(2) .
19 *
20 * 2. Approximation of log(1+f).
21 * Let s = f/(2+f) ; based on log(1+f) = log(1+s) - log(1-s)
22 * = 2s + 2/3 s**3 + 2/5 s**5 + .....,
23 * = 2s + s*R
24 * We use a special Remez algorithm on [0,0.1716] to generate
25 * a polynomial of degree 14 to approximate R The maximum error
26 * of this polynomial approximation is bounded by 2**-58.45. In
27 * other words,
28 * 2 4 6 8 10 12 14
29 * R(z) ~ Lg1*s +Lg2*s +Lg3*s +Lg4*s +Lg5*s +Lg6*s +Lg7*s
30 * (the values of Lg1 to Lg7 are listed in the program)
31 * and
32 * | 2 14 | -58.45
33 * | Lg1*s +...+Lg7*s - R(z) | <= 2
34 * | |
35 * Note that 2s = f - s*f = f - hfsq + s*hfsq, where hfsq = f*f/2.
36 * In order to guarantee error in log below 1ulp, we compute log
37 * by
38 * log(1+f) = f - s*(f - R) (if f is not too large)
39 * log(1+f) = f - (hfsq - s*(hfsq+R)). (better accuracy)
40 *
41 * 3. Finally, log(x) = k*ln2 + log(1+f).
42 * = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
43 * Here ln2 is split into two floating point number:
44 * ln2_hi + ln2_lo,
45 * where n*ln2_hi is always exact for |n| < 2000.
46 *
47 * Special cases:
48 * log(x) is NaN with signal if x < 0 (including -INF) ;
49 * log(+INF) is +INF; log(0) is -INF with signal;
50 * log(NaN) is that NaN with no signal.
51 *
52 * Accuracy:
53 * according to an error analysis, the error is always less than
54 * 1 ulp (unit in the last place).
55 *
56 * Constants:
57 * The hexadecimal values are the intended ones for the following
58 * constants. The decimal values may be used, provided that the
59 * compiler will convert from decimal to binary accurately enough
60 * to produce the hexadecimal values shown.
61 */
62
63#include <math.h>
64#include <stdint.h>
65
66static const double
67ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
68ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
69Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
70Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
71Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
72Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
73Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
74Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
75Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
76
77double log(double x)
78{
79 union {double f; uint64_t i;} u = {x};
80 double_t hfsq,f,s,z,R,w,t1,t2,dk;
81 uint32_t hx;
82 int k;
83
84 hx = u.i>>32;
85 k = 0;
86 if (hx < 0x00100000 || hx>>31) {
87 if (u.i<<1 == 0)
88 return -1/(x*x); /* log(+-0)=-inf */
89 if (hx>>31)
90 return (x-x)/0.0; /* log(-#) = NaN */
91 /* subnormal number, scale x up */
92 k -= 54;
93 x *= 0x1p54;
94 u.f = x;
95 hx = u.i>>32;
96 } else if (hx >= 0x7ff00000) {
97 return x;
98 } else if (hx == 0x3ff00000 && u.i<<32 == 0)
99 return 0;
100
101 /* reduce x into [sqrt(2)/2, sqrt(2)] */
102 hx += 0x3ff00000 - 0x3fe6a09e;
103 k += (int)(hx>>20) - 0x3ff;
104 hx = (hx&0x000fffff) + 0x3fe6a09e;
105 u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
106 x = u.f;
107
108 f = x - 1.0;
109 hfsq = 0.5*f*f;
110 s = f/(2.0+f);
111 z = s*s;
112 w = z*z;
113 t1 = w*(Lg2+w*(Lg4+w*Lg6));
114 t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
115 R = t2 + t1;
116 dk = k;
117 return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi;
118}
libc/musl/src/math/log10.c created+101
......@@ -0,0 +1,101 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_log10.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * Return the base 10 logarithm of x. See log.c for most comments.
14 *
15 * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2
16 * as in log.c, then combine and scale in extra precision:
17 * log10(x) = (f - f*f/2 + r)/log(10) + k*log10(2)
18 */
19
20#include <math.h>
21#include <stdint.h>
22
23static const double
24ivln10hi = 4.34294481878168880939e-01, /* 0x3fdbcb7b, 0x15200000 */
25ivln10lo = 2.50829467116452752298e-11, /* 0x3dbb9438, 0xca9aadd5 */
26log10_2hi = 3.01029995663611771306e-01, /* 0x3FD34413, 0x509F6000 */
27log10_2lo = 3.69423907715893078616e-13, /* 0x3D59FEF3, 0x11F12B36 */
28Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
29Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
30Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
31Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
32Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
33Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
34Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
35
36double log10(double x)
37{
38 union {double f; uint64_t i;} u = {x};
39 double_t hfsq,f,s,z,R,w,t1,t2,dk,y,hi,lo,val_hi,val_lo;
40 uint32_t hx;
41 int k;
42
43 hx = u.i>>32;
44 k = 0;
45 if (hx < 0x00100000 || hx>>31) {
46 if (u.i<<1 == 0)
47 return -1/(x*x); /* log(+-0)=-inf */
48 if (hx>>31)
49 return (x-x)/0.0; /* log(-#) = NaN */
50 /* subnormal number, scale x up */
51 k -= 54;
52 x *= 0x1p54;
53 u.f = x;
54 hx = u.i>>32;
55 } else if (hx >= 0x7ff00000) {
56 return x;
57 } else if (hx == 0x3ff00000 && u.i<<32 == 0)
58 return 0;
59
60 /* reduce x into [sqrt(2)/2, sqrt(2)] */
61 hx += 0x3ff00000 - 0x3fe6a09e;
62 k += (int)(hx>>20) - 0x3ff;
63 hx = (hx&0x000fffff) + 0x3fe6a09e;
64 u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
65 x = u.f;
66
67 f = x - 1.0;
68 hfsq = 0.5*f*f;
69 s = f/(2.0+f);
70 z = s*s;
71 w = z*z;
72 t1 = w*(Lg2+w*(Lg4+w*Lg6));
73 t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
74 R = t2 + t1;
75
76 /* See log2.c for details. */
77 /* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */
78 hi = f - hfsq;
79 u.f = hi;
80 u.i &= (uint64_t)-1<<32;
81 hi = u.f;
82 lo = f - hi - hfsq + s*(hfsq+R);
83
84 /* val_hi+val_lo ~ log10(1+f) + k*log10(2) */
85 val_hi = hi*ivln10hi;
86 dk = k;
87 y = dk*log10_2hi;
88 val_lo = dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi;
89
90 /*
91 * Extra precision in for adding y is not strictly needed
92 * since there is no very large cancellation near x = sqrt(2) or
93 * x = 1/sqrt(2), but we do it anyway since it costs little on CPUs
94 * with some parallelism and it reduces the error for many args.
95 */
96 w = y + val_hi;
97 val_lo += (y - w) + val_hi;
98 val_hi = w;
99
100 return val_lo + val_hi;
101}
libc/musl/src/math/log10f.c created+77
......@@ -0,0 +1,77 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_log10f.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * See comments in log10.c.
14 */
15
16#include <math.h>
17#include <stdint.h>
18
19static const float
20ivln10hi = 4.3432617188e-01, /* 0x3ede6000 */
21ivln10lo = -3.1689971365e-05, /* 0xb804ead9 */
22log10_2hi = 3.0102920532e-01, /* 0x3e9a2080 */
23log10_2lo = 7.9034151668e-07, /* 0x355427db */
24/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
25Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
26Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
27Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
28Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
29
30float log10f(float x)
31{
32 union {float f; uint32_t i;} u = {x};
33 float_t hfsq,f,s,z,R,w,t1,t2,dk,hi,lo;
34 uint32_t ix;
35 int k;
36
37 ix = u.i;
38 k = 0;
39 if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */
40 if (ix<<1 == 0)
41 return -1/(x*x); /* log(+-0)=-inf */
42 if (ix>>31)
43 return (x-x)/0.0f; /* log(-#) = NaN */
44 /* subnormal number, scale up x */
45 k -= 25;
46 x *= 0x1p25f;
47 u.f = x;
48 ix = u.i;
49 } else if (ix >= 0x7f800000) {
50 return x;
51 } else if (ix == 0x3f800000)
52 return 0;
53
54 /* reduce x into [sqrt(2)/2, sqrt(2)] */
55 ix += 0x3f800000 - 0x3f3504f3;
56 k += (int)(ix>>23) - 0x7f;
57 ix = (ix&0x007fffff) + 0x3f3504f3;
58 u.i = ix;
59 x = u.f;
60
61 f = x - 1.0f;
62 s = f/(2.0f + f);
63 z = s*s;
64 w = z*z;
65 t1= w*(Lg2+w*Lg4);
66 t2= z*(Lg1+w*Lg3);
67 R = t2 + t1;
68 hfsq = 0.5f*f*f;
69
70 hi = f - hfsq;
71 u.f = hi;
72 u.i &= 0xfffff000;
73 hi = u.f;
74 lo = f - hi - hfsq + s*(hfsq+R);
75 dk = k;
76 return dk*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + hi*ivln10hi + dk*log10_2hi;
77}
libc/musl/src/math/log10l.c created+191
......@@ -0,0 +1,191 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log10l.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Common logarithm, long double precision
19 *
20 *
21 * SYNOPSIS:
22 *
23 * long double x, y, log10l();
24 *
25 * y = log10l( x );
26 *
27 *
28 * DESCRIPTION:
29 *
30 * Returns the base 10 logarithm of x.
31 *
32 * The argument is separated into its exponent and fractional
33 * parts. If the exponent is between -1 and +1, the logarithm
34 * of the fraction is approximated by
35 *
36 * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
37 *
38 * Otherwise, setting z = 2(x-1)/x+1),
39 *
40 * log(x) = z + z**3 P(z)/Q(z).
41 *
42 *
43 * ACCURACY:
44 *
45 * Relative error:
46 * arithmetic domain # trials peak rms
47 * IEEE 0.5, 2.0 30000 9.0e-20 2.6e-20
48 * IEEE exp(+-10000) 30000 6.0e-20 2.3e-20
49 *
50 * In the tests over the interval exp(+-10000), the logarithms
51 * of the random arguments were uniformly distributed over
52 * [-10000, +10000].
53 *
54 * ERROR MESSAGES:
55 *
56 * log singularity: x = 0; returns MINLOG
57 * log domain: x < 0; returns MINLOG
58 */
59
60#include "libm.h"
61
62#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
63long double log10l(long double x)
64{
65 return log10(x);
66}
67#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
68/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
69 * 1/sqrt(2) <= x < sqrt(2)
70 * Theoretical peak relative error = 6.2e-22
71 */
72static const long double P[] = {
73 4.9962495940332550844739E-1L,
74 1.0767376367209449010438E1L,
75 7.7671073698359539859595E1L,
76 2.5620629828144409632571E2L,
77 4.2401812743503691187826E2L,
78 3.4258224542413922935104E2L,
79 1.0747524399916215149070E2L,
80};
81static const long double Q[] = {
82/* 1.0000000000000000000000E0,*/
83 2.3479774160285863271658E1L,
84 1.9444210022760132894510E2L,
85 7.7952888181207260646090E2L,
86 1.6911722418503949084863E3L,
87 2.0307734695595183428202E3L,
88 1.2695660352705325274404E3L,
89 3.2242573199748645407652E2L,
90};
91
92/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
93 * where z = 2(x-1)/(x+1)
94 * 1/sqrt(2) <= x < sqrt(2)
95 * Theoretical peak relative error = 6.16e-22
96 */
97static const long double R[4] = {
98 1.9757429581415468984296E-3L,
99-7.1990767473014147232598E-1L,
100 1.0777257190312272158094E1L,
101-3.5717684488096787370998E1L,
102};
103static const long double S[4] = {
104/* 1.00000000000000000000E0L,*/
105-2.6201045551331104417768E1L,
106 1.9361891836232102174846E2L,
107-4.2861221385716144629696E2L,
108};
109/* log10(2) */
110#define L102A 0.3125L
111#define L102B -1.1470004336018804786261e-2L
112/* log10(e) */
113#define L10EA 0.5L
114#define L10EB -6.5705518096748172348871e-2L
115
116#define SQRTH 0.70710678118654752440L
117
118long double log10l(long double x)
119{
120 long double y, z;
121 int e;
122
123 if (isnan(x))
124 return x;
125 if(x <= 0.0) {
126 if(x == 0.0)
127 return -1.0 / (x*x);
128 return (x - x) / 0.0;
129 }
130 if (x == INFINITY)
131 return INFINITY;
132 /* separate mantissa from exponent */
133 /* Note, frexp is used so that denormal numbers
134 * will be handled properly.
135 */
136 x = frexpl(x, &e);
137
138 /* logarithm using log(x) = z + z**3 P(z)/Q(z),
139 * where z = 2(x-1)/x+1)
140 */
141 if (e > 2 || e < -2) {
142 if (x < SQRTH) { /* 2(2x-1)/(2x+1) */
143 e -= 1;
144 z = x - 0.5;
145 y = 0.5 * z + 0.5;
146 } else { /* 2 (x-1)/(x+1) */
147 z = x - 0.5;
148 z -= 0.5;
149 y = 0.5 * x + 0.5;
150 }
151 x = z / y;
152 z = x*x;
153 y = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
154 goto done;
155 }
156
157 /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
158 if (x < SQRTH) {
159 e -= 1;
160 x = 2.0*x - 1.0;
161 } else {
162 x = x - 1.0;
163 }
164 z = x*x;
165 y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7));
166 y = y - 0.5*z;
167
168done:
169 /* Multiply log of fraction by log10(e)
170 * and base 2 exponent by log10(2).
171 *
172 * ***CAUTION***
173 *
174 * This sequence of operations is critical and it may
175 * be horribly defeated by some compiler optimizers.
176 */
177 z = y * (L10EB);
178 z += x * (L10EB);
179 z += e * (L102B);
180 z += y * (L10EA);
181 z += x * (L10EA);
182 z += e * (L102A);
183 return z;
184}
185#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
186// TODO: broken implementation to make things compile
187long double log10l(long double x)
188{
189 return log10(x);
190}
191#endif
libc/musl/src/math/log1p.c created+122
......@@ -0,0 +1,122 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_log1p.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* double log1p(double x)
13 * Return the natural logarithm of 1+x.
14 *
15 * Method :
16 * 1. Argument Reduction: find k and f such that
17 * 1+x = 2^k * (1+f),
18 * where sqrt(2)/2 < 1+f < sqrt(2) .
19 *
20 * Note. If k=0, then f=x is exact. However, if k!=0, then f
21 * may not be representable exactly. In that case, a correction
22 * term is need. Let u=1+x rounded. Let c = (1+x)-u, then
23 * log(1+x) - log(u) ~ c/u. Thus, we proceed to compute log(u),
24 * and add back the correction term c/u.
25 * (Note: when x > 2**53, one can simply return log(x))
26 *
27 * 2. Approximation of log(1+f): See log.c
28 *
29 * 3. Finally, log1p(x) = k*ln2 + log(1+f) + c/u. See log.c
30 *
31 * Special cases:
32 * log1p(x) is NaN with signal if x < -1 (including -INF) ;
33 * log1p(+INF) is +INF; log1p(-1) is -INF with signal;
34 * log1p(NaN) is that NaN with no signal.
35 *
36 * Accuracy:
37 * according to an error analysis, the error is always less than
38 * 1 ulp (unit in the last place).
39 *
40 * Constants:
41 * The hexadecimal values are the intended ones for the following
42 * constants. The decimal values may be used, provided that the
43 * compiler will convert from decimal to binary accurately enough
44 * to produce the hexadecimal values shown.
45 *
46 * Note: Assuming log() return accurate answer, the following
47 * algorithm can be used to compute log1p(x) to within a few ULP:
48 *
49 * u = 1+x;
50 * if(u==1.0) return x ; else
51 * return log(u)*(x/(u-1.0));
52 *
53 * See HP-15C Advanced Functions Handbook, p.193.
54 */
55
56#include "libm.h"
57
58static const double
59ln2_hi = 6.93147180369123816490e-01, /* 3fe62e42 fee00000 */
60ln2_lo = 1.90821492927058770002e-10, /* 3dea39ef 35793c76 */
61Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
62Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
63Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
64Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
65Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
66Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
67Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
68
69double log1p(double x)
70{
71 union {double f; uint64_t i;} u = {x};
72 double_t hfsq,f,c,s,z,R,w,t1,t2,dk;
73 uint32_t hx,hu;
74 int k;
75
76 hx = u.i>>32;
77 k = 1;
78 if (hx < 0x3fda827a || hx>>31) { /* 1+x < sqrt(2)+ */
79 if (hx >= 0xbff00000) { /* x <= -1.0 */
80 if (x == -1)
81 return x/0.0; /* log1p(-1) = -inf */
82 return (x-x)/0.0; /* log1p(x<-1) = NaN */
83 }
84 if (hx<<1 < 0x3ca00000<<1) { /* |x| < 2**-53 */
85 /* underflow if subnormal */
86 if ((hx&0x7ff00000) == 0)
87 FORCE_EVAL((float)x);
88 return x;
89 }
90 if (hx <= 0xbfd2bec4) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */
91 k = 0;
92 c = 0;
93 f = x;
94 }
95 } else if (hx >= 0x7ff00000)
96 return x;
97 if (k) {
98 u.f = 1 + x;
99 hu = u.i>>32;
100 hu += 0x3ff00000 - 0x3fe6a09e;
101 k = (int)(hu>>20) - 0x3ff;
102 /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */
103 if (k < 54) {
104 c = k >= 2 ? 1-(u.f-x) : x-(u.f-1);
105 c /= u.f;
106 } else
107 c = 0;
108 /* reduce u into [sqrt(2)/2, sqrt(2)] */
109 hu = (hu&0x000fffff) + 0x3fe6a09e;
110 u.i = (uint64_t)hu<<32 | (u.i&0xffffffff);
111 f = u.f - 1;
112 }
113 hfsq = 0.5*f*f;
114 s = f/(2.0+f);
115 z = s*s;
116 w = z*z;
117 t1 = w*(Lg2+w*(Lg4+w*Lg6));
118 t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
119 R = t2 + t1;
120 dk = k;
121 return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;
122}
libc/musl/src/math/log1pf.c created+77
......@@ -0,0 +1,77 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_log1pf.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12
13#include "libm.h"
14
15static const float
16ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
17ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
18/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
19Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
20Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
21Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
22Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
23
24float log1pf(float x)
25{
26 union {float f; uint32_t i;} u = {x};
27 float_t hfsq,f,c,s,z,R,w,t1,t2,dk;
28 uint32_t ix,iu;
29 int k;
30
31 ix = u.i;
32 k = 1;
33 if (ix < 0x3ed413d0 || ix>>31) { /* 1+x < sqrt(2)+ */
34 if (ix >= 0xbf800000) { /* x <= -1.0 */
35 if (x == -1)
36 return x/0.0f; /* log1p(-1)=+inf */
37 return (x-x)/0.0f; /* log1p(x<-1)=NaN */
38 }
39 if (ix<<1 < 0x33800000<<1) { /* |x| < 2**-24 */
40 /* underflow if subnormal */
41 if ((ix&0x7f800000) == 0)
42 FORCE_EVAL(x*x);
43 return x;
44 }
45 if (ix <= 0xbe95f619) { /* sqrt(2)/2- <= 1+x < sqrt(2)+ */
46 k = 0;
47 c = 0;
48 f = x;
49 }
50 } else if (ix >= 0x7f800000)
51 return x;
52 if (k) {
53 u.f = 1 + x;
54 iu = u.i;
55 iu += 0x3f800000 - 0x3f3504f3;
56 k = (int)(iu>>23) - 0x7f;
57 /* correction term ~ log(1+x)-log(u), avoid underflow in c/u */
58 if (k < 25) {
59 c = k >= 2 ? 1-(u.f-x) : x-(u.f-1);
60 c /= u.f;
61 } else
62 c = 0;
63 /* reduce u into [sqrt(2)/2, sqrt(2)] */
64 iu = (iu&0x007fffff) + 0x3f3504f3;
65 u.i = iu;
66 f = u.f - 1;
67 }
68 s = f/(2.0f + f);
69 z = s*s;
70 w = z*z;
71 t1= w*(Lg2+w*Lg4);
72 t2= z*(Lg1+w*Lg3);
73 R = t2 + t1;
74 hfsq = 0.5f*f*f;
75 dk = k;
76 return s*(hfsq+R) + (dk*ln2_lo+c) - hfsq + f + dk*ln2_hi;
77}
libc/musl/src/math/log1pl.c created+177
......@@ -0,0 +1,177 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/s_log1pl.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Relative error logarithm
19 * Natural logarithm of 1+x, long double precision
20 *
21 *
22 * SYNOPSIS:
23 *
24 * long double x, y, log1pl();
25 *
26 * y = log1pl( x );
27 *
28 *
29 * DESCRIPTION:
30 *
31 * Returns the base e (2.718...) logarithm of 1+x.
32 *
33 * The argument 1+x is separated into its exponent and fractional
34 * parts. If the exponent is between -1 and +1, the logarithm
35 * of the fraction is approximated by
36 *
37 * log(1+x) = x - 0.5 x^2 + x^3 P(x)/Q(x).
38 *
39 * Otherwise, setting z = 2(x-1)/x+1),
40 *
41 * log(x) = z + z^3 P(z)/Q(z).
42 *
43 *
44 * ACCURACY:
45 *
46 * Relative error:
47 * arithmetic domain # trials peak rms
48 * IEEE -1.0, 9.0 100000 8.2e-20 2.5e-20
49 */
50
51#include "libm.h"
52
53#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
54long double log1pl(long double x)
55{
56 return log1p(x);
57}
58#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
59/* Coefficients for log(1+x) = x - x^2 / 2 + x^3 P(x)/Q(x)
60 * 1/sqrt(2) <= x < sqrt(2)
61 * Theoretical peak relative error = 2.32e-20
62 */
63static const long double P[] = {
64 4.5270000862445199635215E-5L,
65 4.9854102823193375972212E-1L,
66 6.5787325942061044846969E0L,
67 2.9911919328553073277375E1L,
68 6.0949667980987787057556E1L,
69 5.7112963590585538103336E1L,
70 2.0039553499201281259648E1L,
71};
72static const long double Q[] = {
73/* 1.0000000000000000000000E0,*/
74 1.5062909083469192043167E1L,
75 8.3047565967967209469434E1L,
76 2.2176239823732856465394E2L,
77 3.0909872225312059774938E2L,
78 2.1642788614495947685003E2L,
79 6.0118660497603843919306E1L,
80};
81
82/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
83 * where z = 2(x-1)/(x+1)
84 * 1/sqrt(2) <= x < sqrt(2)
85 * Theoretical peak relative error = 6.16e-22
86 */
87static const long double R[4] = {
88 1.9757429581415468984296E-3L,
89-7.1990767473014147232598E-1L,
90 1.0777257190312272158094E1L,
91-3.5717684488096787370998E1L,
92};
93static const long double S[4] = {
94/* 1.00000000000000000000E0L,*/
95-2.6201045551331104417768E1L,
96 1.9361891836232102174846E2L,
97-4.2861221385716144629696E2L,
98};
99static const long double C1 = 6.9314575195312500000000E-1L;
100static const long double C2 = 1.4286068203094172321215E-6L;
101
102#define SQRTH 0.70710678118654752440L
103
104long double log1pl(long double xm1)
105{
106 long double x, y, z;
107 int e;
108
109 if (isnan(xm1))
110 return xm1;
111 if (xm1 == INFINITY)
112 return xm1;
113 if (xm1 == 0.0)
114 return xm1;
115
116 x = xm1 + 1.0;
117
118 /* Test for domain errors. */
119 if (x <= 0.0) {
120 if (x == 0.0)
121 return -1/(x*x); /* -inf with divbyzero */
122 return 0/0.0f; /* nan with invalid */
123 }
124
125 /* Separate mantissa from exponent.
126 Use frexp so that denormal numbers will be handled properly. */
127 x = frexpl(x, &e);
128
129 /* logarithm using log(x) = z + z^3 P(z)/Q(z),
130 where z = 2(x-1)/x+1) */
131 if (e > 2 || e < -2) {
132 if (x < SQRTH) { /* 2(2x-1)/(2x+1) */
133 e -= 1;
134 z = x - 0.5;
135 y = 0.5 * z + 0.5;
136 } else { /* 2 (x-1)/(x+1) */
137 z = x - 0.5;
138 z -= 0.5;
139 y = 0.5 * x + 0.5;
140 }
141 x = z / y;
142 z = x*x;
143 z = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
144 z = z + e * C2;
145 z = z + x;
146 z = z + e * C1;
147 return z;
148 }
149
150 /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
151 if (x < SQRTH) {
152 e -= 1;
153 if (e != 0)
154 x = 2.0 * x - 1.0;
155 else
156 x = xm1;
157 } else {
158 if (e != 0)
159 x = x - 1.0;
160 else
161 x = xm1;
162 }
163 z = x*x;
164 y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6));
165 y = y + e * C2;
166 z = y - 0.5 * z;
167 z = z + x;
168 z = z + e * C1;
169 return z;
170}
171#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
172// TODO: broken implementation to make things compile
173long double log1pl(long double x)
174{
175 return log1p(x);
176}
177#endif
libc/musl/src/math/log2.c created+122
......@@ -0,0 +1,122 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_log2.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * Return the base 2 logarithm of x. See log.c for most comments.
14 *
15 * Reduce x to 2^k (1+f) and calculate r = log(1+f) - f + f*f/2
16 * as in log.c, then combine and scale in extra precision:
17 * log2(x) = (f - f*f/2 + r)/log(2) + k
18 */
19
20#include <math.h>
21#include <stdint.h>
22
23static const double
24ivln2hi = 1.44269504072144627571e+00, /* 0x3ff71547, 0x65200000 */
25ivln2lo = 1.67517131648865118353e-10, /* 0x3de705fc, 0x2eefa200 */
26Lg1 = 6.666666666666735130e-01, /* 3FE55555 55555593 */
27Lg2 = 3.999999999940941908e-01, /* 3FD99999 9997FA04 */
28Lg3 = 2.857142874366239149e-01, /* 3FD24924 94229359 */
29Lg4 = 2.222219843214978396e-01, /* 3FCC71C5 1D8E78AF */
30Lg5 = 1.818357216161805012e-01, /* 3FC74664 96CB03DE */
31Lg6 = 1.531383769920937332e-01, /* 3FC39A09 D078C69F */
32Lg7 = 1.479819860511658591e-01; /* 3FC2F112 DF3E5244 */
33
34double log2(double x)
35{
36 union {double f; uint64_t i;} u = {x};
37 double_t hfsq,f,s,z,R,w,t1,t2,y,hi,lo,val_hi,val_lo;
38 uint32_t hx;
39 int k;
40
41 hx = u.i>>32;
42 k = 0;
43 if (hx < 0x00100000 || hx>>31) {
44 if (u.i<<1 == 0)
45 return -1/(x*x); /* log(+-0)=-inf */
46 if (hx>>31)
47 return (x-x)/0.0; /* log(-#) = NaN */
48 /* subnormal number, scale x up */
49 k -= 54;
50 x *= 0x1p54;
51 u.f = x;
52 hx = u.i>>32;
53 } else if (hx >= 0x7ff00000) {
54 return x;
55 } else if (hx == 0x3ff00000 && u.i<<32 == 0)
56 return 0;
57
58 /* reduce x into [sqrt(2)/2, sqrt(2)] */
59 hx += 0x3ff00000 - 0x3fe6a09e;
60 k += (int)(hx>>20) - 0x3ff;
61 hx = (hx&0x000fffff) + 0x3fe6a09e;
62 u.i = (uint64_t)hx<<32 | (u.i&0xffffffff);
63 x = u.f;
64
65 f = x - 1.0;
66 hfsq = 0.5*f*f;
67 s = f/(2.0+f);
68 z = s*s;
69 w = z*z;
70 t1 = w*(Lg2+w*(Lg4+w*Lg6));
71 t2 = z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7)));
72 R = t2 + t1;
73
74 /*
75 * f-hfsq must (for args near 1) be evaluated in extra precision
76 * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2).
77 * This is fairly efficient since f-hfsq only depends on f, so can
78 * be evaluated in parallel with R. Not combining hfsq with R also
79 * keeps R small (though not as small as a true `lo' term would be),
80 * so that extra precision is not needed for terms involving R.
81 *
82 * Compiler bugs involving extra precision used to break Dekker's
83 * theorem for spitting f-hfsq as hi+lo, unless double_t was used
84 * or the multi-precision calculations were avoided when double_t
85 * has extra precision. These problems are now automatically
86 * avoided as a side effect of the optimization of combining the
87 * Dekker splitting step with the clear-low-bits step.
88 *
89 * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra
90 * precision to avoid a very large cancellation when x is very near
91 * these values. Unlike the above cancellations, this problem is
92 * specific to base 2. It is strange that adding +-1 is so much
93 * harder than adding +-ln2 or +-log10_2.
94 *
95 * This uses Dekker's theorem to normalize y+val_hi, so the
96 * compiler bugs are back in some configurations, sigh. And I
97 * don't want to used double_t to avoid them, since that gives a
98 * pessimization and the support for avoiding the pessimization
99 * is not yet available.
100 *
101 * The multi-precision calculations for the multiplications are
102 * routine.
103 */
104
105 /* hi+lo = f - hfsq + s*(hfsq+R) ~ log(1+f) */
106 hi = f - hfsq;
107 u.f = hi;
108 u.i &= (uint64_t)-1<<32;
109 hi = u.f;
110 lo = f - hi - hfsq + s*(hfsq+R);
111
112 val_hi = hi*ivln2hi;
113 val_lo = (lo+hi)*ivln2lo + lo*ivln2hi;
114
115 /* spadd(val_hi, val_lo, y), except for not using double_t: */
116 y = k;
117 w = y + val_hi;
118 val_lo += (y - w) + val_hi;
119 val_hi = w;
120
121 return val_lo + val_hi;
122}
libc/musl/src/math/log2f.c created+74
......@@ -0,0 +1,74 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_log2f.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * See comments in log2.c.
14 */
15
16#include <math.h>
17#include <stdint.h>
18
19static const float
20ivln2hi = 1.4428710938e+00, /* 0x3fb8b000 */
21ivln2lo = -1.7605285393e-04, /* 0xb9389ad4 */
22/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
23Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
24Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
25Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
26Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
27
28float log2f(float x)
29{
30 union {float f; uint32_t i;} u = {x};
31 float_t hfsq,f,s,z,R,w,t1,t2,hi,lo;
32 uint32_t ix;
33 int k;
34
35 ix = u.i;
36 k = 0;
37 if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */
38 if (ix<<1 == 0)
39 return -1/(x*x); /* log(+-0)=-inf */
40 if (ix>>31)
41 return (x-x)/0.0f; /* log(-#) = NaN */
42 /* subnormal number, scale up x */
43 k -= 25;
44 x *= 0x1p25f;
45 u.f = x;
46 ix = u.i;
47 } else if (ix >= 0x7f800000) {
48 return x;
49 } else if (ix == 0x3f800000)
50 return 0;
51
52 /* reduce x into [sqrt(2)/2, sqrt(2)] */
53 ix += 0x3f800000 - 0x3f3504f3;
54 k += (int)(ix>>23) - 0x7f;
55 ix = (ix&0x007fffff) + 0x3f3504f3;
56 u.i = ix;
57 x = u.f;
58
59 f = x - 1.0f;
60 s = f/(2.0f + f);
61 z = s*s;
62 w = z*z;
63 t1= w*(Lg2+w*Lg4);
64 t2= z*(Lg1+w*Lg3);
65 R = t2 + t1;
66 hfsq = 0.5f*f*f;
67
68 hi = f - hfsq;
69 u.f = hi;
70 u.i &= 0xfffff000;
71 hi = u.f;
72 lo = f - hi - hfsq + s*(hfsq+R);
73 return (lo+hi)*ivln2lo + lo*ivln2hi + hi*ivln2hi + k;
74}
libc/musl/src/math/log2l.c created+182
......@@ -0,0 +1,182 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_log2l.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Base 2 logarithm, long double precision
19 *
20 *
21 * SYNOPSIS:
22 *
23 * long double x, y, log2l();
24 *
25 * y = log2l( x );
26 *
27 *
28 * DESCRIPTION:
29 *
30 * Returns the base 2 logarithm of x.
31 *
32 * The argument is separated into its exponent and fractional
33 * parts. If the exponent is between -1 and +1, the (natural)
34 * logarithm of the fraction is approximated by
35 *
36 * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
37 *
38 * Otherwise, setting z = 2(x-1)/x+1),
39 *
40 * log(x) = z + z**3 P(z)/Q(z).
41 *
42 *
43 * ACCURACY:
44 *
45 * Relative error:
46 * arithmetic domain # trials peak rms
47 * IEEE 0.5, 2.0 30000 9.8e-20 2.7e-20
48 * IEEE exp(+-10000) 70000 5.4e-20 2.3e-20
49 *
50 * In the tests over the interval exp(+-10000), the logarithms
51 * of the random arguments were uniformly distributed over
52 * [-10000, +10000].
53 */
54
55#include "libm.h"
56
57#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
58long double log2l(long double x)
59{
60 return log2(x);
61}
62#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
63/* Coefficients for ln(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
64 * 1/sqrt(2) <= x < sqrt(2)
65 * Theoretical peak relative error = 6.2e-22
66 */
67static const long double P[] = {
68 4.9962495940332550844739E-1L,
69 1.0767376367209449010438E1L,
70 7.7671073698359539859595E1L,
71 2.5620629828144409632571E2L,
72 4.2401812743503691187826E2L,
73 3.4258224542413922935104E2L,
74 1.0747524399916215149070E2L,
75};
76static const long double Q[] = {
77/* 1.0000000000000000000000E0,*/
78 2.3479774160285863271658E1L,
79 1.9444210022760132894510E2L,
80 7.7952888181207260646090E2L,
81 1.6911722418503949084863E3L,
82 2.0307734695595183428202E3L,
83 1.2695660352705325274404E3L,
84 3.2242573199748645407652E2L,
85};
86
87/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
88 * where z = 2(x-1)/(x+1)
89 * 1/sqrt(2) <= x < sqrt(2)
90 * Theoretical peak relative error = 6.16e-22
91 */
92static const long double R[4] = {
93 1.9757429581415468984296E-3L,
94-7.1990767473014147232598E-1L,
95 1.0777257190312272158094E1L,
96-3.5717684488096787370998E1L,
97};
98static const long double S[4] = {
99/* 1.00000000000000000000E0L,*/
100-2.6201045551331104417768E1L,
101 1.9361891836232102174846E2L,
102-4.2861221385716144629696E2L,
103};
104/* log2(e) - 1 */
105#define LOG2EA 4.4269504088896340735992e-1L
106
107#define SQRTH 0.70710678118654752440L
108
109long double log2l(long double x)
110{
111 long double y, z;
112 int e;
113
114 if (isnan(x))
115 return x;
116 if (x == INFINITY)
117 return x;
118 if (x <= 0.0) {
119 if (x == 0.0)
120 return -1/(x*x); /* -inf with divbyzero */
121 return 0/0.0f; /* nan with invalid */
122 }
123
124 /* separate mantissa from exponent */
125 /* Note, frexp is used so that denormal numbers
126 * will be handled properly.
127 */
128 x = frexpl(x, &e);
129
130 /* logarithm using log(x) = z + z**3 P(z)/Q(z),
131 * where z = 2(x-1)/x+1)
132 */
133 if (e > 2 || e < -2) {
134 if (x < SQRTH) { /* 2(2x-1)/(2x+1) */
135 e -= 1;
136 z = x - 0.5;
137 y = 0.5 * z + 0.5;
138 } else { /* 2 (x-1)/(x+1) */
139 z = x - 0.5;
140 z -= 0.5;
141 y = 0.5 * x + 0.5;
142 }
143 x = z / y;
144 z = x*x;
145 y = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
146 goto done;
147 }
148
149 /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
150 if (x < SQRTH) {
151 e -= 1;
152 x = 2.0*x - 1.0;
153 } else {
154 x = x - 1.0;
155 }
156 z = x*x;
157 y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 7));
158 y = y - 0.5*z;
159
160done:
161 /* Multiply log of fraction by log2(e)
162 * and base 2 exponent by 1
163 *
164 * ***CAUTION***
165 *
166 * This sequence of operations is critical and it may
167 * be horribly defeated by some compiler optimizers.
168 */
169 z = y * LOG2EA;
170 z += x * LOG2EA;
171 z += y;
172 z += x;
173 z += e;
174 return z;
175}
176#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
177// TODO: broken implementation to make things compile
178long double log2l(long double x)
179{
180 return log2(x);
181}
182#endif
libc/musl/src/math/logb.c created+17
......@@ -0,0 +1,17 @@
1#include <math.h>
2
3/*
4special cases:
5 logb(+-0) = -inf, and raise divbyzero
6 logb(+-inf) = +inf
7 logb(nan) = nan
8*/
9
10double logb(double x)
11{
12 if (!isfinite(x))
13 return x * x;
14 if (x == 0)
15 return -1/(x*x);
16 return ilogb(x);
17}
libc/musl/src/math/logbf.c created+10
......@@ -0,0 +1,10 @@
1#include <math.h>
2
3float logbf(float x)
4{
5 if (!isfinite(x))
6 return x * x;
7 if (x == 0)
8 return -1/(x*x);
9 return ilogbf(x);
10}
libc/musl/src/math/logbl.c created+16
......@@ -0,0 +1,16 @@
1#include <math.h>
2#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
3long double logbl(long double x)
4{
5 return logb(x);
6}
7#else
8long double logbl(long double x)
9{
10 if (!isfinite(x))
11 return x * x;
12 if (x == 0)
13 return -1/(x*x);
14 return ilogbl(x);
15}
16#endif
libc/musl/src/math/logf.c created+69
......@@ -0,0 +1,69 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_logf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include <math.h>
17#include <stdint.h>
18
19static const float
20ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
21ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
22/* |(log(1+s)-log(1-s))/s - Lg(s)| < 2**-34.24 (~[-4.95e-11, 4.97e-11]). */
23Lg1 = 0xaaaaaa.0p-24, /* 0.66666662693 */
24Lg2 = 0xccce13.0p-25, /* 0.40000972152 */
25Lg3 = 0x91e9ee.0p-25, /* 0.28498786688 */
26Lg4 = 0xf89e26.0p-26; /* 0.24279078841 */
27
28float logf(float x)
29{
30 union {float f; uint32_t i;} u = {x};
31 float_t hfsq,f,s,z,R,w,t1,t2,dk;
32 uint32_t ix;
33 int k;
34
35 ix = u.i;
36 k = 0;
37 if (ix < 0x00800000 || ix>>31) { /* x < 2**-126 */
38 if (ix<<1 == 0)
39 return -1/(x*x); /* log(+-0)=-inf */
40 if (ix>>31)
41 return (x-x)/0.0f; /* log(-#) = NaN */
42 /* subnormal number, scale up x */
43 k -= 25;
44 x *= 0x1p25f;
45 u.f = x;
46 ix = u.i;
47 } else if (ix >= 0x7f800000) {
48 return x;
49 } else if (ix == 0x3f800000)
50 return 0;
51
52 /* reduce x into [sqrt(2)/2, sqrt(2)] */
53 ix += 0x3f800000 - 0x3f3504f3;
54 k += (int)(ix>>23) - 0x7f;
55 ix = (ix&0x007fffff) + 0x3f3504f3;
56 u.i = ix;
57 x = u.f;
58
59 f = x - 1.0f;
60 s = f/(2.0f + f);
61 z = s*s;
62 w = z*z;
63 t1= w*(Lg2+w*Lg4);
64 t2= z*(Lg1+w*Lg3);
65 R = t2 + t1;
66 hfsq = 0.5f*f*f;
67 dk = k;
68 return s*(hfsq+R) + dk*ln2_lo - hfsq + f + dk*ln2_hi;
69}
libc/musl/src/math/logl.c created+175
......@@ -0,0 +1,175 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_logl.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Natural logarithm, long double precision
19 *
20 *
21 * SYNOPSIS:
22 *
23 * long double x, y, logl();
24 *
25 * y = logl( x );
26 *
27 *
28 * DESCRIPTION:
29 *
30 * Returns the base e (2.718...) logarithm of x.
31 *
32 * The argument is separated into its exponent and fractional
33 * parts. If the exponent is between -1 and +1, the logarithm
34 * of the fraction is approximated by
35 *
36 * log(1+x) = x - 0.5 x**2 + x**3 P(x)/Q(x).
37 *
38 * Otherwise, setting z = 2(x-1)/(x+1),
39 *
40 * log(x) = log(1+z/2) - log(1-z/2) = z + z**3 P(z)/Q(z).
41 *
42 *
43 * ACCURACY:
44 *
45 * Relative error:
46 * arithmetic domain # trials peak rms
47 * IEEE 0.5, 2.0 150000 8.71e-20 2.75e-20
48 * IEEE exp(+-10000) 100000 5.39e-20 2.34e-20
49 *
50 * In the tests over the interval exp(+-10000), the logarithms
51 * of the random arguments were uniformly distributed over
52 * [-10000, +10000].
53 */
54
55#include "libm.h"
56
57#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
58long double logl(long double x)
59{
60 return log(x);
61}
62#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
63/* Coefficients for log(1+x) = x - x**2/2 + x**3 P(x)/Q(x)
64 * 1/sqrt(2) <= x < sqrt(2)
65 * Theoretical peak relative error = 2.32e-20
66 */
67static const long double P[] = {
68 4.5270000862445199635215E-5L,
69 4.9854102823193375972212E-1L,
70 6.5787325942061044846969E0L,
71 2.9911919328553073277375E1L,
72 6.0949667980987787057556E1L,
73 5.7112963590585538103336E1L,
74 2.0039553499201281259648E1L,
75};
76static const long double Q[] = {
77/* 1.0000000000000000000000E0,*/
78 1.5062909083469192043167E1L,
79 8.3047565967967209469434E1L,
80 2.2176239823732856465394E2L,
81 3.0909872225312059774938E2L,
82 2.1642788614495947685003E2L,
83 6.0118660497603843919306E1L,
84};
85
86/* Coefficients for log(x) = z + z^3 P(z^2)/Q(z^2),
87 * where z = 2(x-1)/(x+1)
88 * 1/sqrt(2) <= x < sqrt(2)
89 * Theoretical peak relative error = 6.16e-22
90 */
91static const long double R[4] = {
92 1.9757429581415468984296E-3L,
93-7.1990767473014147232598E-1L,
94 1.0777257190312272158094E1L,
95-3.5717684488096787370998E1L,
96};
97static const long double S[4] = {
98/* 1.00000000000000000000E0L,*/
99-2.6201045551331104417768E1L,
100 1.9361891836232102174846E2L,
101-4.2861221385716144629696E2L,
102};
103static const long double C1 = 6.9314575195312500000000E-1L;
104static const long double C2 = 1.4286068203094172321215E-6L;
105
106#define SQRTH 0.70710678118654752440L
107
108long double logl(long double x)
109{
110 long double y, z;
111 int e;
112
113 if (isnan(x))
114 return x;
115 if (x == INFINITY)
116 return x;
117 if (x <= 0.0) {
118 if (x == 0.0)
119 return -1/(x*x); /* -inf with divbyzero */
120 return 0/0.0f; /* nan with invalid */
121 }
122
123 /* separate mantissa from exponent */
124 /* Note, frexp is used so that denormal numbers
125 * will be handled properly.
126 */
127 x = frexpl(x, &e);
128
129 /* logarithm using log(x) = z + z**3 P(z)/Q(z),
130 * where z = 2(x-1)/(x+1)
131 */
132 if (e > 2 || e < -2) {
133 if (x < SQRTH) { /* 2(2x-1)/(2x+1) */
134 e -= 1;
135 z = x - 0.5;
136 y = 0.5 * z + 0.5;
137 } else { /* 2 (x-1)/(x+1) */
138 z = x - 0.5;
139 z -= 0.5;
140 y = 0.5 * x + 0.5;
141 }
142 x = z / y;
143 z = x*x;
144 z = x * (z * __polevll(z, R, 3) / __p1evll(z, S, 3));
145 z = z + e * C2;
146 z = z + x;
147 z = z + e * C1;
148 return z;
149 }
150
151 /* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */
152 if (x < SQRTH) {
153 e -= 1;
154 x = 2.0*x - 1.0;
155 } else {
156 x = x - 1.0;
157 }
158 z = x*x;
159 y = x * (z * __polevll(x, P, 6) / __p1evll(x, Q, 6));
160 y = y + e * C2;
161 z = y - 0.5*z;
162 /* Note, the sum of above terms does not exceed x/4,
163 * so it contributes at most about 1/4 lsb to the error.
164 */
165 z = z + x;
166 z = z + e * C1; /* This sum has an error of 1/2 lsb. */
167 return z;
168}
169#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
170// TODO: broken implementation to make things compile
171long double logl(long double x)
172{
173 return log(x);
174}
175#endif
libc/musl/src/math/lrint.c created+46
......@@ -0,0 +1,46 @@
1#include <limits.h>
2#include <fenv.h>
3#include "libm.h"
4
5/*
6If the result cannot be represented (overflow, nan), then
7lrint raises the invalid exception.
8
9Otherwise if the input was not an integer then the inexact
10exception is raised.
11
12C99 is a bit vague about whether inexact exception is
13allowed to be raised when invalid is raised.
14(F.9 explicitly allows spurious inexact exceptions, F.9.6.5
15does not make it clear if that rule applies to lrint, but
16IEEE 754r 7.8 seems to forbid spurious inexact exception in
17the ineger conversion functions)
18
19So we try to make sure that no spurious inexact exception is
20raised in case of an overflow.
21
22If the bit size of long > precision of double, then there
23cannot be inexact rounding in case the result overflows,
24otherwise LONG_MAX and LONG_MIN can be represented exactly
25as a double.
26*/
27
28#if LONG_MAX < 1U<<53 && defined(FE_INEXACT)
29long lrint(double x)
30{
31 #pragma STDC FENV_ACCESS ON
32 int e;
33
34 e = fetestexcept(FE_INEXACT);
35 x = rint(x);
36 if (!e && (x > LONG_MAX || x < LONG_MIN))
37 feclearexcept(FE_INEXACT);
38 /* conversion */
39 return x;
40}
41#else
42long lrint(double x)
43{
44 return rint(x);
45}
46#endif
libc/musl/src/math/lrintf.c created+8
......@@ -0,0 +1,8 @@
1#include <math.h>
2
3/* uses LONG_MAX > 2^24, see comments in lrint.c */
4
5long lrintf(float x)
6{
7 return rintf(x);
8}
libc/musl/src/math/lrintl.c created+36
......@@ -0,0 +1,36 @@
1#include <limits.h>
2#include <fenv.h>
3#include "libm.h"
4
5
6#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
7long lrintl(long double x)
8{
9 return lrint(x);
10}
11#elif defined(FE_INEXACT)
12/*
13see comments in lrint.c
14
15Note that if LONG_MAX == 0x7fffffffffffffff && LDBL_MANT_DIG == 64
16then x == 2**63 - 0.5 is the only input that overflows and
17raises inexact (with tonearest or upward rounding mode)
18*/
19long lrintl(long double x)
20{
21 #pragma STDC FENV_ACCESS ON
22 int e;
23
24 e = fetestexcept(FE_INEXACT);
25 x = rintl(x);
26 if (!e && (x > LONG_MAX || x < LONG_MIN))
27 feclearexcept(FE_INEXACT);
28 /* conversion */
29 return x;
30}
31#else
32long lrintl(long double x)
33{
34 return rintl(x);
35}
36#endif
libc/musl/src/math/lround.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3long lround(double x)
4{
5 return round(x);
6}
libc/musl/src/math/lroundf.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3long lroundf(float x)
4{
5 return roundf(x);
6}
libc/musl/src/math/lroundl.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3long lroundl(long double x)
4{
5 return roundl(x);
6}
libc/musl/src/math/modf.c created+34
......@@ -0,0 +1,34 @@
1#include "libm.h"
2
3double modf(double x, double *iptr)
4{
5 union {double f; uint64_t i;} u = {x};
6 uint64_t mask;
7 int e = (int)(u.i>>52 & 0x7ff) - 0x3ff;
8
9 /* no fractional part */
10 if (e >= 52) {
11 *iptr = x;
12 if (e == 0x400 && u.i<<12 != 0) /* nan */
13 return x;
14 u.i &= 1ULL<<63;
15 return u.f;
16 }
17
18 /* no integral part*/
19 if (e < 0) {
20 u.i &= 1ULL<<63;
21 *iptr = u.f;
22 return x;
23 }
24
25 mask = -1ULL>>12>>e;
26 if ((u.i & mask) == 0) {
27 *iptr = x;
28 u.i &= 1ULL<<63;
29 return u.f;
30 }
31 u.i &= ~mask;
32 *iptr = u.f;
33 return x - u.f;
34}
libc/musl/src/math/modff.c created+34
......@@ -0,0 +1,34 @@
1#include "libm.h"
2
3float modff(float x, float *iptr)
4{
5 union {float f; uint32_t i;} u = {x};
6 uint32_t mask;
7 int e = (int)(u.i>>23 & 0xff) - 0x7f;
8
9 /* no fractional part */
10 if (e >= 23) {
11 *iptr = x;
12 if (e == 0x80 && u.i<<9 != 0) { /* nan */
13 return x;
14 }
15 u.i &= 0x80000000;
16 return u.f;
17 }
18 /* no integral part */
19 if (e < 0) {
20 u.i &= 0x80000000;
21 *iptr = u.f;
22 return x;
23 }
24
25 mask = 0x007fffff>>e;
26 if ((u.i & mask) == 0) {
27 *iptr = x;
28 u.i &= 0x80000000;
29 return u.f;
30 }
31 u.i &= ~mask;
32 *iptr = u.f;
33 return x - u.f;
34}
libc/musl/src/math/modfl.c created+53
......@@ -0,0 +1,53 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double modfl(long double x, long double *iptr)
5{
6 double d;
7 long double r;
8
9 r = modf(x, &d);
10 *iptr = d;
11 return r;
12}
13#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
14
15static const long double toint = 1/LDBL_EPSILON;
16
17long double modfl(long double x, long double *iptr)
18{
19 union ldshape u = {x};
20 int e = (u.i.se & 0x7fff) - 0x3fff;
21 int s = u.i.se >> 15;
22 long double absx;
23 long double y;
24
25 /* no fractional part */
26 if (e >= LDBL_MANT_DIG-1) {
27 *iptr = x;
28 if (isnan(x))
29 return x;
30 return s ? -0.0 : 0.0;
31 }
32
33 /* no integral part*/
34 if (e < 0) {
35 *iptr = s ? -0.0 : 0.0;
36 return x;
37 }
38
39 /* raises spurious inexact */
40 absx = s ? -x : x;
41 y = absx + toint - toint - absx;
42 if (y == 0) {
43 *iptr = x;
44 return s ? -0.0 : 0.0;
45 }
46 if (y > 0)
47 y -= 1;
48 if (s)
49 y = -y;
50 *iptr = x + y;
51 return -y;
52}
53#endif
libc/musl/src/math/nan.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3double nan(const char *s)
4{
5 return NAN;
6}
libc/musl/src/math/nanf.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3float nanf(const char *s)
4{
5 return NAN;
6}
libc/musl/src/math/nanl.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3long double nanl(const char *s)
4{
5 return NAN;
6}
libc/musl/src/math/nearbyint.c created+20
......@@ -0,0 +1,20 @@
1#include <fenv.h>
2#include <math.h>
3
4/* nearbyint is the same as rint, but it must not raise the inexact exception */
5
6double nearbyint(double x)
7{
8#ifdef FE_INEXACT
9 #pragma STDC FENV_ACCESS ON
10 int e;
11
12 e = fetestexcept(FE_INEXACT);
13#endif
14 x = rint(x);
15#ifdef FE_INEXACT
16 if (!e)
17 feclearexcept(FE_INEXACT);
18#endif
19 return x;
20}
libc/musl/src/math/nearbyintf.c created+18
......@@ -0,0 +1,18 @@
1#include <fenv.h>
2#include <math.h>
3
4float nearbyintf(float x)
5{
6#ifdef FE_INEXACT
7 #pragma STDC FENV_ACCESS ON
8 int e;
9
10 e = fetestexcept(FE_INEXACT);
11#endif
12 x = rintf(x);
13#ifdef FE_INEXACT
14 if (!e)
15 feclearexcept(FE_INEXACT);
16#endif
17 return x;
18}
libc/musl/src/math/nearbyintl.c created+26
......@@ -0,0 +1,26 @@
1#include <math.h>
2#include <float.h>
3
4#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5long double nearbyintl(long double x)
6{
7 return nearbyint(x);
8}
9#else
10#include <fenv.h>
11long double nearbyintl(long double x)
12{
13#ifdef FE_INEXACT
14 #pragma STDC FENV_ACCESS ON
15 int e;
16
17 e = fetestexcept(FE_INEXACT);
18#endif
19 x = rintl(x);
20#ifdef FE_INEXACT
21 if (!e)
22 feclearexcept(FE_INEXACT);
23#endif
24 return x;
25}
26#endif
libc/musl/src/math/nextafter.c created+31
......@@ -0,0 +1,31 @@
1#include "libm.h"
2
3double nextafter(double x, double y)
4{
5 union {double f; uint64_t i;} ux={x}, uy={y};
6 uint64_t ax, ay;
7 int e;
8
9 if (isnan(x) || isnan(y))
10 return x + y;
11 if (ux.i == uy.i)
12 return y;
13 ax = ux.i & -1ULL/2;
14 ay = uy.i & -1ULL/2;
15 if (ax == 0) {
16 if (ay == 0)
17 return y;
18 ux.i = (uy.i & 1ULL<<63) | 1;
19 } else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63))
20 ux.i--;
21 else
22 ux.i++;
23 e = ux.i >> 52 & 0x7ff;
24 /* raise overflow if ux.f is infinite and x is finite */
25 if (e == 0x7ff)
26 FORCE_EVAL(x+x);
27 /* raise underflow if ux.f is subnormal or zero */
28 if (e == 0)
29 FORCE_EVAL(x*x + ux.f*ux.f);
30 return ux.f;
31}
libc/musl/src/math/nextafterf.c created+30
......@@ -0,0 +1,30 @@
1#include "libm.h"
2
3float nextafterf(float x, float y)
4{
5 union {float f; uint32_t i;} ux={x}, uy={y};
6 uint32_t ax, ay, e;
7
8 if (isnan(x) || isnan(y))
9 return x + y;
10 if (ux.i == uy.i)
11 return y;
12 ax = ux.i & 0x7fffffff;
13 ay = uy.i & 0x7fffffff;
14 if (ax == 0) {
15 if (ay == 0)
16 return y;
17 ux.i = (uy.i & 0x80000000) | 1;
18 } else if (ax > ay || ((ux.i ^ uy.i) & 0x80000000))
19 ux.i--;
20 else
21 ux.i++;
22 e = ux.i & 0x7f800000;
23 /* raise overflow if ux.f is infinite and x is finite */
24 if (e == 0x7f800000)
25 FORCE_EVAL(x+x);
26 /* raise underflow if ux.f is subnormal or zero */
27 if (e == 0)
28 FORCE_EVAL(x*x + ux.f*ux.f);
29 return ux.f;
30}
libc/musl/src/math/nextafterl.c created+75
......@@ -0,0 +1,75 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double nextafterl(long double x, long double y)
5{
6 return nextafter(x, y);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9long double nextafterl(long double x, long double y)
10{
11 union ldshape ux, uy;
12
13 if (isnan(x) || isnan(y))
14 return x + y;
15 if (x == y)
16 return y;
17 ux.f = x;
18 if (x == 0) {
19 uy.f = y;
20 ux.i.m = 1;
21 ux.i.se = uy.i.se & 0x8000;
22 } else if ((x < y) == !(ux.i.se & 0x8000)) {
23 ux.i.m++;
24 if (ux.i.m << 1 == 0) {
25 ux.i.m = 1ULL << 63;
26 ux.i.se++;
27 }
28 } else {
29 if (ux.i.m << 1 == 0) {
30 ux.i.se--;
31 if (ux.i.se)
32 ux.i.m = 0;
33 }
34 ux.i.m--;
35 }
36 /* raise overflow if ux is infinite and x is finite */
37 if ((ux.i.se & 0x7fff) == 0x7fff)
38 return x + x;
39 /* raise underflow if ux is subnormal or zero */
40 if ((ux.i.se & 0x7fff) == 0)
41 FORCE_EVAL(x*x + ux.f*ux.f);
42 return ux.f;
43}
44#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
45long double nextafterl(long double x, long double y)
46{
47 union ldshape ux, uy;
48
49 if (isnan(x) || isnan(y))
50 return x + y;
51 if (x == y)
52 return y;
53 ux.f = x;
54 if (x == 0) {
55 uy.f = y;
56 ux.i.lo = 1;
57 ux.i.se = uy.i.se & 0x8000;
58 } else if ((x < y) == !(ux.i.se & 0x8000)) {
59 ux.i2.lo++;
60 if (ux.i2.lo == 0)
61 ux.i2.hi++;
62 } else {
63 if (ux.i2.lo == 0)
64 ux.i2.hi--;
65 ux.i2.lo--;
66 }
67 /* raise overflow if ux is infinite and x is finite */
68 if ((ux.i.se & 0x7fff) == 0x7fff)
69 return x + x;
70 /* raise underflow if ux is subnormal or zero */
71 if ((ux.i.se & 0x7fff) == 0)
72 FORCE_EVAL(x*x + ux.f*ux.f);
73 return ux.f;
74}
75#endif
libc/musl/src/math/nexttoward.c created+42
......@@ -0,0 +1,42 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4double nexttoward(double x, long double y)
5{
6 return nextafter(x, y);
7}
8#else
9double nexttoward(double x, long double y)
10{
11 union {double f; uint64_t i;} ux = {x};
12 int e;
13
14 if (isnan(x) || isnan(y))
15 return x + y;
16 if (x == y)
17 return y;
18 if (x == 0) {
19 ux.i = 1;
20 if (signbit(y))
21 ux.i |= 1ULL<<63;
22 } else if (x < y) {
23 if (signbit(x))
24 ux.i--;
25 else
26 ux.i++;
27 } else {
28 if (signbit(x))
29 ux.i++;
30 else
31 ux.i--;
32 }
33 e = ux.i>>52 & 0x7ff;
34 /* raise overflow if ux.f is infinite and x is finite */
35 if (e == 0x7ff)
36 FORCE_EVAL(x+x);
37 /* raise underflow if ux.f is subnormal or zero */
38 if (e == 0)
39 FORCE_EVAL(x*x + ux.f*ux.f);
40 return ux.f;
41}
42#endif
libc/musl/src/math/nexttowardf.c created+35
......@@ -0,0 +1,35 @@
1#include "libm.h"
2
3float nexttowardf(float x, long double y)
4{
5 union {float f; uint32_t i;} ux = {x};
6 uint32_t e;
7
8 if (isnan(x) || isnan(y))
9 return x + y;
10 if (x == y)
11 return y;
12 if (x == 0) {
13 ux.i = 1;
14 if (signbit(y))
15 ux.i |= 0x80000000;
16 } else if (x < y) {
17 if (signbit(x))
18 ux.i--;
19 else
20 ux.i++;
21 } else {
22 if (signbit(x))
23 ux.i++;
24 else
25 ux.i--;
26 }
27 e = ux.i & 0x7f800000;
28 /* raise overflow if ux.f is infinite and x is finite */
29 if (e == 0x7f800000)
30 FORCE_EVAL(x+x);
31 /* raise underflow if ux.f is subnormal or zero */
32 if (e == 0)
33 FORCE_EVAL(x*x + ux.f*ux.f);
34 return ux.f;
35}
libc/musl/src/math/nexttowardl.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3long double nexttowardl(long double x, long double y)
4{
5 return nextafterl(x, y);
6}
libc/musl/src/math/pow.c created+328
......@@ -0,0 +1,328 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_pow.c */
2/*
3 * ====================================================
4 * Copyright (C) 2004 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Permission to use, copy, modify, and distribute this
7 * software is freely granted, provided that this notice
8 * is preserved.
9 * ====================================================
10 */
11/* pow(x,y) return x**y
12 *
13 * n
14 * Method: Let x = 2 * (1+f)
15 * 1. Compute and return log2(x) in two pieces:
16 * log2(x) = w1 + w2,
17 * where w1 has 53-24 = 29 bit trailing zeros.
18 * 2. Perform y*log2(x) = n+y' by simulating muti-precision
19 * arithmetic, where |y'|<=0.5.
20 * 3. Return x**y = 2**n*exp(y'*log2)
21 *
22 * Special cases:
23 * 1. (anything) ** 0 is 1
24 * 2. 1 ** (anything) is 1
25 * 3. (anything except 1) ** NAN is NAN
26 * 4. NAN ** (anything except 0) is NAN
27 * 5. +-(|x| > 1) ** +INF is +INF
28 * 6. +-(|x| > 1) ** -INF is +0
29 * 7. +-(|x| < 1) ** +INF is +0
30 * 8. +-(|x| < 1) ** -INF is +INF
31 * 9. -1 ** +-INF is 1
32 * 10. +0 ** (+anything except 0, NAN) is +0
33 * 11. -0 ** (+anything except 0, NAN, odd integer) is +0
34 * 12. +0 ** (-anything except 0, NAN) is +INF, raise divbyzero
35 * 13. -0 ** (-anything except 0, NAN, odd integer) is +INF, raise divbyzero
36 * 14. -0 ** (+odd integer) is -0
37 * 15. -0 ** (-odd integer) is -INF, raise divbyzero
38 * 16. +INF ** (+anything except 0,NAN) is +INF
39 * 17. +INF ** (-anything except 0,NAN) is +0
40 * 18. -INF ** (+odd integer) is -INF
41 * 19. -INF ** (anything) = -0 ** (-anything), (anything except odd integer)
42 * 20. (anything) ** 1 is (anything)
43 * 21. (anything) ** -1 is 1/(anything)
44 * 22. (-anything) ** (integer) is (-1)**(integer)*(+anything**integer)
45 * 23. (-anything except 0 and inf) ** (non-integer) is NAN
46 *
47 * Accuracy:
48 * pow(x,y) returns x**y nearly rounded. In particular
49 * pow(integer,integer)
50 * always returns the correct integer provided it is
51 * representable.
52 *
53 * Constants :
54 * The hexadecimal values are the intended ones for the following
55 * constants. The decimal values may be used, provided that the
56 * compiler will convert from decimal to binary accurately enough
57 * to produce the hexadecimal values shown.
58 */
59
60#include "libm.h"
61
62static const double
63bp[] = {1.0, 1.5,},
64dp_h[] = { 0.0, 5.84962487220764160156e-01,}, /* 0x3FE2B803, 0x40000000 */
65dp_l[] = { 0.0, 1.35003920212974897128e-08,}, /* 0x3E4CFDEB, 0x43CFD006 */
66two53 = 9007199254740992.0, /* 0x43400000, 0x00000000 */
67huge = 1.0e300,
68tiny = 1.0e-300,
69/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
70L1 = 5.99999999999994648725e-01, /* 0x3FE33333, 0x33333303 */
71L2 = 4.28571428578550184252e-01, /* 0x3FDB6DB6, 0xDB6FABFF */
72L3 = 3.33333329818377432918e-01, /* 0x3FD55555, 0x518F264D */
73L4 = 2.72728123808534006489e-01, /* 0x3FD17460, 0xA91D4101 */
74L5 = 2.30660745775561754067e-01, /* 0x3FCD864A, 0x93C9DB65 */
75L6 = 2.06975017800338417784e-01, /* 0x3FCA7E28, 0x4A454EEF */
76P1 = 1.66666666666666019037e-01, /* 0x3FC55555, 0x5555553E */
77P2 = -2.77777777770155933842e-03, /* 0xBF66C16C, 0x16BEBD93 */
78P3 = 6.61375632143793436117e-05, /* 0x3F11566A, 0xAF25DE2C */
79P4 = -1.65339022054652515390e-06, /* 0xBEBBBD41, 0xC5D26BF1 */
80P5 = 4.13813679705723846039e-08, /* 0x3E663769, 0x72BEA4D0 */
81lg2 = 6.93147180559945286227e-01, /* 0x3FE62E42, 0xFEFA39EF */
82lg2_h = 6.93147182464599609375e-01, /* 0x3FE62E43, 0x00000000 */
83lg2_l = -1.90465429995776804525e-09, /* 0xBE205C61, 0x0CA86C39 */
84ovt = 8.0085662595372944372e-017, /* -(1024-log2(ovfl+.5ulp)) */
85cp = 9.61796693925975554329e-01, /* 0x3FEEC709, 0xDC3A03FD =2/(3ln2) */
86cp_h = 9.61796700954437255859e-01, /* 0x3FEEC709, 0xE0000000 =(float)cp */
87cp_l = -7.02846165095275826516e-09, /* 0xBE3E2FE0, 0x145B01F5 =tail of cp_h*/
88ivln2 = 1.44269504088896338700e+00, /* 0x3FF71547, 0x652B82FE =1/ln2 */
89ivln2_h = 1.44269502162933349609e+00, /* 0x3FF71547, 0x60000000 =24b 1/ln2*/
90ivln2_l = 1.92596299112661746887e-08; /* 0x3E54AE0B, 0xF85DDF44 =1/ln2 tail*/
91
92double pow(double x, double y)
93{
94 double z,ax,z_h,z_l,p_h,p_l;
95 double y1,t1,t2,r,s,t,u,v,w;
96 int32_t i,j,k,yisint,n;
97 int32_t hx,hy,ix,iy;
98 uint32_t lx,ly;
99
100 EXTRACT_WORDS(hx, lx, x);
101 EXTRACT_WORDS(hy, ly, y);
102 ix = hx & 0x7fffffff;
103 iy = hy & 0x7fffffff;
104
105 /* x**0 = 1, even if x is NaN */
106 if ((iy|ly) == 0)
107 return 1.0;
108 /* 1**y = 1, even if y is NaN */
109 if (hx == 0x3ff00000 && lx == 0)
110 return 1.0;
111 /* NaN if either arg is NaN */
112 if (ix > 0x7ff00000 || (ix == 0x7ff00000 && lx != 0) ||
113 iy > 0x7ff00000 || (iy == 0x7ff00000 && ly != 0))
114 return x + y;
115
116 /* determine if y is an odd int when x < 0
117 * yisint = 0 ... y is not an integer
118 * yisint = 1 ... y is an odd int
119 * yisint = 2 ... y is an even int
120 */
121 yisint = 0;
122 if (hx < 0) {
123 if (iy >= 0x43400000)
124 yisint = 2; /* even integer y */
125 else if (iy >= 0x3ff00000) {
126 k = (iy>>20) - 0x3ff; /* exponent */
127 if (k > 20) {
128 uint32_t j = ly>>(52-k);
129 if ((j<<(52-k)) == ly)
130 yisint = 2 - (j&1);
131 } else if (ly == 0) {
132 uint32_t j = iy>>(20-k);
133 if ((j<<(20-k)) == iy)
134 yisint = 2 - (j&1);
135 }
136 }
137 }
138
139 /* special value of y */
140 if (ly == 0) {
141 if (iy == 0x7ff00000) { /* y is +-inf */
142 if (((ix-0x3ff00000)|lx) == 0) /* (-1)**+-inf is 1 */
143 return 1.0;
144 else if (ix >= 0x3ff00000) /* (|x|>1)**+-inf = inf,0 */
145 return hy >= 0 ? y : 0.0;
146 else /* (|x|<1)**+-inf = 0,inf */
147 return hy >= 0 ? 0.0 : -y;
148 }
149 if (iy == 0x3ff00000) { /* y is +-1 */
150 if (hy >= 0)
151 return x;
152 y = 1/x;
153#if FLT_EVAL_METHOD!=0
154 {
155 union {double f; uint64_t i;} u = {y};
156 uint64_t i = u.i & -1ULL/2;
157 if (i>>52 == 0 && (i&(i-1)))
158 FORCE_EVAL((float)y);
159 }
160#endif
161 return y;
162 }
163 if (hy == 0x40000000) /* y is 2 */
164 return x*x;
165 if (hy == 0x3fe00000) { /* y is 0.5 */
166 if (hx >= 0) /* x >= +0 */
167 return sqrt(x);
168 }
169 }
170
171 ax = fabs(x);
172 /* special value of x */
173 if (lx == 0) {
174 if (ix == 0x7ff00000 || ix == 0 || ix == 0x3ff00000) { /* x is +-0,+-inf,+-1 */
175 z = ax;
176 if (hy < 0) /* z = (1/|x|) */
177 z = 1.0/z;
178 if (hx < 0) {
179 if (((ix-0x3ff00000)|yisint) == 0) {
180 z = (z-z)/(z-z); /* (-1)**non-int is NaN */
181 } else if (yisint == 1)
182 z = -z; /* (x<0)**odd = -(|x|**odd) */
183 }
184 return z;
185 }
186 }
187
188 s = 1.0; /* sign of result */
189 if (hx < 0) {
190 if (yisint == 0) /* (x<0)**(non-int) is NaN */
191 return (x-x)/(x-x);
192 if (yisint == 1) /* (x<0)**(odd int) */
193 s = -1.0;
194 }
195
196 /* |y| is huge */
197 if (iy > 0x41e00000) { /* if |y| > 2**31 */
198 if (iy > 0x43f00000) { /* if |y| > 2**64, must o/uflow */
199 if (ix <= 0x3fefffff)
200 return hy < 0 ? huge*huge : tiny*tiny;
201 if (ix >= 0x3ff00000)
202 return hy > 0 ? huge*huge : tiny*tiny;
203 }
204 /* over/underflow if x is not close to one */
205 if (ix < 0x3fefffff)
206 return hy < 0 ? s*huge*huge : s*tiny*tiny;
207 if (ix > 0x3ff00000)
208 return hy > 0 ? s*huge*huge : s*tiny*tiny;
209 /* now |1-x| is tiny <= 2**-20, suffice to compute
210 log(x) by x-x^2/2+x^3/3-x^4/4 */
211 t = ax - 1.0; /* t has 20 trailing zeros */
212 w = (t*t)*(0.5 - t*(0.3333333333333333333333-t*0.25));
213 u = ivln2_h*t; /* ivln2_h has 21 sig. bits */
214 v = t*ivln2_l - w*ivln2;
215 t1 = u + v;
216 SET_LOW_WORD(t1, 0);
217 t2 = v - (t1-u);
218 } else {
219 double ss,s2,s_h,s_l,t_h,t_l;
220 n = 0;
221 /* take care subnormal number */
222 if (ix < 0x00100000) {
223 ax *= two53;
224 n -= 53;
225 GET_HIGH_WORD(ix,ax);
226 }
227 n += ((ix)>>20) - 0x3ff;
228 j = ix & 0x000fffff;
229 /* determine interval */
230 ix = j | 0x3ff00000; /* normalize ix */
231 if (j <= 0x3988E) /* |x|<sqrt(3/2) */
232 k = 0;
233 else if (j < 0xBB67A) /* |x|<sqrt(3) */
234 k = 1;
235 else {
236 k = 0;
237 n += 1;
238 ix -= 0x00100000;
239 }
240 SET_HIGH_WORD(ax, ix);
241
242 /* compute ss = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
243 u = ax - bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
244 v = 1.0/(ax+bp[k]);
245 ss = u*v;
246 s_h = ss;
247 SET_LOW_WORD(s_h, 0);
248 /* t_h=ax+bp[k] High */
249 t_h = 0.0;
250 SET_HIGH_WORD(t_h, ((ix>>1)|0x20000000) + 0x00080000 + (k<<18));
251 t_l = ax - (t_h-bp[k]);
252 s_l = v*((u-s_h*t_h)-s_h*t_l);
253 /* compute log(ax) */
254 s2 = ss*ss;
255 r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
256 r += s_l*(s_h+ss);
257 s2 = s_h*s_h;
258 t_h = 3.0 + s2 + r;
259 SET_LOW_WORD(t_h, 0);
260 t_l = r - ((t_h-3.0)-s2);
261 /* u+v = ss*(1+...) */
262 u = s_h*t_h;
263 v = s_l*t_h + t_l*ss;
264 /* 2/(3log2)*(ss+...) */
265 p_h = u + v;
266 SET_LOW_WORD(p_h, 0);
267 p_l = v - (p_h-u);
268 z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
269 z_l = cp_l*p_h+p_l*cp + dp_l[k];
270 /* log2(ax) = (ss+..)*2/(3*log2) = n + dp_h + z_h + z_l */
271 t = (double)n;
272 t1 = ((z_h + z_l) + dp_h[k]) + t;
273 SET_LOW_WORD(t1, 0);
274 t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
275 }
276
277 /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
278 y1 = y;
279 SET_LOW_WORD(y1, 0);
280 p_l = (y-y1)*t1 + y*t2;
281 p_h = y1*t1;
282 z = p_l + p_h;
283 EXTRACT_WORDS(j, i, z);
284 if (j >= 0x40900000) { /* z >= 1024 */
285 if (((j-0x40900000)|i) != 0) /* if z > 1024 */
286 return s*huge*huge; /* overflow */
287 if (p_l + ovt > z - p_h)
288 return s*huge*huge; /* overflow */
289 } else if ((j&0x7fffffff) >= 0x4090cc00) { /* z <= -1075 */ // FIXME: instead of abs(j) use unsigned j
290 if (((j-0xc090cc00)|i) != 0) /* z < -1075 */
291 return s*tiny*tiny; /* underflow */
292 if (p_l <= z - p_h)
293 return s*tiny*tiny; /* underflow */
294 }
295 /*
296 * compute 2**(p_h+p_l)
297 */
298 i = j & 0x7fffffff;
299 k = (i>>20) - 0x3ff;
300 n = 0;
301 if (i > 0x3fe00000) { /* if |z| > 0.5, set n = [z+0.5] */
302 n = j + (0x00100000>>(k+1));
303 k = ((n&0x7fffffff)>>20) - 0x3ff; /* new k for n */
304 t = 0.0;
305 SET_HIGH_WORD(t, n & ~(0x000fffff>>k));
306 n = ((n&0x000fffff)|0x00100000)>>(20-k);
307 if (j < 0)
308 n = -n;
309 p_h -= t;
310 }
311 t = p_l + p_h;
312 SET_LOW_WORD(t, 0);
313 u = t*lg2_h;
314 v = (p_l-(t-p_h))*lg2 + t*lg2_l;
315 z = u + v;
316 w = v - (z-u);
317 t = z*z;
318 t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
319 r = (z*t1)/(t1-2.0) - (w + z*w);
320 z = 1.0 - (r-z);
321 GET_HIGH_WORD(j, z);
322 j += n<<20;
323 if ((j>>20) <= 0) /* subnormal output */
324 z = scalbn(z,n);
325 else
326 SET_HIGH_WORD(z, j);
327 return s*z;
328}
libc/musl/src/math/powerpc/fabs.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _SOFT_FLOAT
4
5#include "../fabs.c"
6
7#else
8
9double fabs(double x)
10{
11 __asm__ ("fabs %0, %1" : "=d"(x) : "d"(x));
12 return x;
13}
14
15#endif
libc/musl/src/math/powerpc/fabsf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _SOFT_FLOAT
4
5#include "../fabsf.c"
6
7#else
8
9float fabsf(float x)
10{
11 __asm__ ("fabs %0, %1" : "=f"(x) : "f"(x));
12 return x;
13}
14
15#endif
libc/musl/src/math/powerpc/fma.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _SOFT_FLOAT
4
5#include "../fma.c"
6
7#else
8
9double fma(double x, double y, double z)
10{
11 __asm__("fmadd %0, %1, %2, %3" : "=d"(x) : "d"(x), "d"(y), "d"(z));
12 return x;
13}
14
15#endif
libc/musl/src/math/powerpc/fmaf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _SOFT_FLOAT
4
5#include "../fmaf.c"
6
7#else
8
9float fmaf(float x, float y, float z)
10{
11 __asm__("fmadds %0, %1, %2, %3" : "=f"(x) : "f"(x), "f"(y), "f"(z));
12 return x;
13}
14
15#endif
libc/musl/src/math/powerpc/sqrt.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if !defined _SOFT_FLOAT && defined _ARCH_PPCSQ
4
5double sqrt(double x)
6{
7 __asm__ ("fsqrt %0, %1\n" : "=d" (x) : "d" (x));
8 return x;
9}
10
11#else
12
13#include "../sqrt.c"
14
15#endif
libc/musl/src/math/powerpc/sqrtf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if !defined _SOFT_FLOAT && defined _ARCH_PPCSQ
4
5float sqrtf(float x)
6{
7 __asm__ ("fsqrts %0, %1\n" : "=f" (x) : "f" (x));
8 return x;
9}
10
11#else
12
13#include "../sqrtf.c"
14
15#endif
libc/musl/src/math/powerpc64/ceil.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5double ceil(double x)
6{
7 __asm__ ("frip %0, %1" : "=d"(x) : "d"(x));
8 return x;
9}
10
11#else
12
13#include "../ceil.c"
14
15#endif
libc/musl/src/math/powerpc64/ceilf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5float ceilf(float x)
6{
7 __asm__ ("frip %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../ceilf.c"
14
15#endif
libc/musl/src/math/powerpc64/fabs.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double fabs(double x)
4{
5 __asm__ ("fabs %0, %1" : "=d"(x) : "d"(x));
6 return x;
7}
libc/musl/src/math/powerpc64/fabsf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float fabsf(float x)
4{
5 __asm__ ("fabs %0, %1" : "=f"(x) : "f"(x));
6 return x;
7}
libc/musl/src/math/powerpc64/floor.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5double floor(double x)
6{
7 __asm__ ("frim %0, %1" : "=d"(x) : "d"(x));
8 return x;
9}
10
11#else
12
13#include "../floor.c"
14
15#endif
libc/musl/src/math/powerpc64/floorf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5float floorf(float x)
6{
7 __asm__ ("frim %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../floorf.c"
14
15#endif
libc/musl/src/math/powerpc64/fma.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double fma(double x, double y, double z)
4{
5 __asm__ ("fmadd %0, %1, %2, %3" : "=d"(x) : "d"(x), "d"(y), "d"(z));
6 return x;
7}
libc/musl/src/math/powerpc64/fmaf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float fmaf(float x, float y, float z)
4{
5 __asm__ ("fmadds %0, %1, %2, %3" : "=f"(x) : "f"(x), "f"(y), "f"(z));
6 return x;
7}
libc/musl/src/math/powerpc64/fmax.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef __VSX__
4
5double fmax(double x, double y)
6{
7 __asm__ ("xsmaxdp %x0, %x1, %x2" : "=ws"(x) : "ws"(x), "ws"(y));
8 return x;
9}
10
11#else
12
13#include "../fmax.c"
14
15#endif
libc/musl/src/math/powerpc64/fmaxf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef __VSX__
4
5float fmaxf(float x, float y)
6{
7 __asm__ ("xsmaxdp %x0, %x1, %x2" : "=ww"(x) : "ww"(x), "ww"(y));
8 return x;
9}
10
11#else
12
13#include "../fmaxf.c"
14
15#endif
libc/musl/src/math/powerpc64/fmin.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef __VSX__
4
5double fmin(double x, double y)
6{
7 __asm__ ("xsmindp %x0, %x1, %x2" : "=ws"(x) : "ws"(x), "ws"(y));
8 return x;
9}
10
11#else
12
13#include "../fmin.c"
14
15#endif
libc/musl/src/math/powerpc64/fminf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef __VSX__
4
5float fminf(float x, float y)
6{
7 __asm__ ("xsmindp %x0, %x1, %x2" : "=ww"(x) : "ww"(x), "ww"(y));
8 return x;
9}
10
11#else
12
13#include "../fminf.c"
14
15#endif
libc/musl/src/math/powerpc64/lrint.c created+16
......@@ -0,0 +1,16 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5long lrint(double x)
6{
7 long n;
8 __asm__ ("fctid %0, %1" : "=d"(n) : "d"(x));
9 return n;
10}
11
12#else
13
14#include "../lrint.c"
15
16#endif
libc/musl/src/math/powerpc64/lrintf.c created+16
......@@ -0,0 +1,16 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5long lrintf(float x)
6{
7 long n;
8 __asm__ ("fctid %0, %1" : "=d"(n) : "f"(x));
9 return n;
10}
11
12#else
13
14#include "../lrintf.c"
15
16#endif
libc/musl/src/math/powerpc64/lround.c created+18
......@@ -0,0 +1,18 @@
1#include <math.h>
2
3#ifdef __VSX__
4
5long lround(double x)
6{
7 long n;
8 __asm__ (
9 "xsrdpi %1, %1\n"
10 "fctid %0, %1\n" : "=d"(n), "+d"(x));
11 return n;
12}
13
14#else
15
16#include "../lround.c"
17
18#endif
libc/musl/src/math/powerpc64/lroundf.c created+18
......@@ -0,0 +1,18 @@
1#include <math.h>
2
3#ifdef __VSX__
4
5long lroundf(float x)
6{
7 long n;
8 __asm__ (
9 "xsrdpi %1, %1\n"
10 "fctid %0, %1\n" : "=d"(n), "+f"(x));
11 return n;
12}
13
14#else
15
16#include "../lroundf.c"
17
18#endif
libc/musl/src/math/powerpc64/round.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5double round(double x)
6{
7 __asm__ ("frin %0, %1" : "=d"(x) : "d"(x));
8 return x;
9}
10
11#else
12
13#include "../round.c"
14
15#endif
libc/musl/src/math/powerpc64/roundf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5float roundf(float x)
6{
7 __asm__ ("frin %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../roundf.c"
14
15#endif
libc/musl/src/math/powerpc64/sqrt.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double sqrt(double x)
4{
5 __asm__ ("fsqrt %0, %1" : "=d"(x) : "d"(x));
6 return x;
7}
libc/musl/src/math/powerpc64/sqrtf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float sqrtf(float x)
4{
5 __asm__ ("fsqrts %0, %1" : "=f"(x) : "f"(x));
6 return x;
7}
libc/musl/src/math/powerpc64/trunc.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5double trunc(double x)
6{
7 __asm__ ("friz %0, %1" : "=d"(x) : "d"(x));
8 return x;
9}
10
11#else
12
13#include "../trunc.c"
14
15#endif
libc/musl/src/math/powerpc64/truncf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#ifdef _ARCH_PWR5X
4
5float truncf(float x)
6{
7 __asm__ ("friz %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../truncf.c"
14
15#endif
libc/musl/src/math/powf.c created+259
......@@ -0,0 +1,259 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_powf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include "libm.h"
17
18static const float
19bp[] = {1.0, 1.5,},
20dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */
21dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */
22two24 = 16777216.0, /* 0x4b800000 */
23huge = 1.0e30,
24tiny = 1.0e-30,
25/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
26L1 = 6.0000002384e-01, /* 0x3f19999a */
27L2 = 4.2857143283e-01, /* 0x3edb6db7 */
28L3 = 3.3333334327e-01, /* 0x3eaaaaab */
29L4 = 2.7272811532e-01, /* 0x3e8ba305 */
30L5 = 2.3066075146e-01, /* 0x3e6c3255 */
31L6 = 2.0697501302e-01, /* 0x3e53f142 */
32P1 = 1.6666667163e-01, /* 0x3e2aaaab */
33P2 = -2.7777778450e-03, /* 0xbb360b61 */
34P3 = 6.6137559770e-05, /* 0x388ab355 */
35P4 = -1.6533901999e-06, /* 0xb5ddea0e */
36P5 = 4.1381369442e-08, /* 0x3331bb4c */
37lg2 = 6.9314718246e-01, /* 0x3f317218 */
38lg2_h = 6.93145752e-01, /* 0x3f317200 */
39lg2_l = 1.42860654e-06, /* 0x35bfbe8c */
40ovt = 4.2995665694e-08, /* -(128-log2(ovfl+.5ulp)) */
41cp = 9.6179670095e-01, /* 0x3f76384f =2/(3ln2) */
42cp_h = 9.6191406250e-01, /* 0x3f764000 =12b cp */
43cp_l = -1.1736857402e-04, /* 0xb8f623c6 =tail of cp_h */
44ivln2 = 1.4426950216e+00, /* 0x3fb8aa3b =1/ln2 */
45ivln2_h = 1.4426879883e+00, /* 0x3fb8aa00 =16b 1/ln2*/
46ivln2_l = 7.0526075433e-06; /* 0x36eca570 =1/ln2 tail*/
47
48float powf(float x, float y)
49{
50 float z,ax,z_h,z_l,p_h,p_l;
51 float y1,t1,t2,r,s,sn,t,u,v,w;
52 int32_t i,j,k,yisint,n;
53 int32_t hx,hy,ix,iy,is;
54
55 GET_FLOAT_WORD(hx, x);
56 GET_FLOAT_WORD(hy, y);
57 ix = hx & 0x7fffffff;
58 iy = hy & 0x7fffffff;
59
60 /* x**0 = 1, even if x is NaN */
61 if (iy == 0)
62 return 1.0f;
63 /* 1**y = 1, even if y is NaN */
64 if (hx == 0x3f800000)
65 return 1.0f;
66 /* NaN if either arg is NaN */
67 if (ix > 0x7f800000 || iy > 0x7f800000)
68 return x + y;
69
70 /* determine if y is an odd int when x < 0
71 * yisint = 0 ... y is not an integer
72 * yisint = 1 ... y is an odd int
73 * yisint = 2 ... y is an even int
74 */
75 yisint = 0;
76 if (hx < 0) {
77 if (iy >= 0x4b800000)
78 yisint = 2; /* even integer y */
79 else if (iy >= 0x3f800000) {
80 k = (iy>>23) - 0x7f; /* exponent */
81 j = iy>>(23-k);
82 if ((j<<(23-k)) == iy)
83 yisint = 2 - (j & 1);
84 }
85 }
86
87 /* special value of y */
88 if (iy == 0x7f800000) { /* y is +-inf */
89 if (ix == 0x3f800000) /* (-1)**+-inf is 1 */
90 return 1.0f;
91 else if (ix > 0x3f800000) /* (|x|>1)**+-inf = inf,0 */
92 return hy >= 0 ? y : 0.0f;
93 else /* (|x|<1)**+-inf = 0,inf */
94 return hy >= 0 ? 0.0f: -y;
95 }
96 if (iy == 0x3f800000) /* y is +-1 */
97 return hy >= 0 ? x : 1.0f/x;
98 if (hy == 0x40000000) /* y is 2 */
99 return x*x;
100 if (hy == 0x3f000000) { /* y is 0.5 */
101 if (hx >= 0) /* x >= +0 */
102 return sqrtf(x);
103 }
104
105 ax = fabsf(x);
106 /* special value of x */
107 if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) { /* x is +-0,+-inf,+-1 */
108 z = ax;
109 if (hy < 0) /* z = (1/|x|) */
110 z = 1.0f/z;
111 if (hx < 0) {
112 if (((ix-0x3f800000)|yisint) == 0) {
113 z = (z-z)/(z-z); /* (-1)**non-int is NaN */
114 } else if (yisint == 1)
115 z = -z; /* (x<0)**odd = -(|x|**odd) */
116 }
117 return z;
118 }
119
120 sn = 1.0f; /* sign of result */
121 if (hx < 0) {
122 if (yisint == 0) /* (x<0)**(non-int) is NaN */
123 return (x-x)/(x-x);
124 if (yisint == 1) /* (x<0)**(odd int) */
125 sn = -1.0f;
126 }
127
128 /* |y| is huge */
129 if (iy > 0x4d000000) { /* if |y| > 2**27 */
130 /* over/underflow if x is not close to one */
131 if (ix < 0x3f7ffff8)
132 return hy < 0 ? sn*huge*huge : sn*tiny*tiny;
133 if (ix > 0x3f800007)
134 return hy > 0 ? sn*huge*huge : sn*tiny*tiny;
135 /* now |1-x| is tiny <= 2**-20, suffice to compute
136 log(x) by x-x^2/2+x^3/3-x^4/4 */
137 t = ax - 1; /* t has 20 trailing zeros */
138 w = (t*t)*(0.5f - t*(0.333333333333f - t*0.25f));
139 u = ivln2_h*t; /* ivln2_h has 16 sig. bits */
140 v = t*ivln2_l - w*ivln2;
141 t1 = u + v;
142 GET_FLOAT_WORD(is, t1);
143 SET_FLOAT_WORD(t1, is & 0xfffff000);
144 t2 = v - (t1-u);
145 } else {
146 float s2,s_h,s_l,t_h,t_l;
147 n = 0;
148 /* take care subnormal number */
149 if (ix < 0x00800000) {
150 ax *= two24;
151 n -= 24;
152 GET_FLOAT_WORD(ix, ax);
153 }
154 n += ((ix)>>23) - 0x7f;
155 j = ix & 0x007fffff;
156 /* determine interval */
157 ix = j | 0x3f800000; /* normalize ix */
158 if (j <= 0x1cc471) /* |x|<sqrt(3/2) */
159 k = 0;
160 else if (j < 0x5db3d7) /* |x|<sqrt(3) */
161 k = 1;
162 else {
163 k = 0;
164 n += 1;
165 ix -= 0x00800000;
166 }
167 SET_FLOAT_WORD(ax, ix);
168
169 /* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
170 u = ax - bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
171 v = 1.0f/(ax+bp[k]);
172 s = u*v;
173 s_h = s;
174 GET_FLOAT_WORD(is, s_h);
175 SET_FLOAT_WORD(s_h, is & 0xfffff000);
176 /* t_h=ax+bp[k] High */
177 is = ((ix>>1) & 0xfffff000) | 0x20000000;
178 SET_FLOAT_WORD(t_h, is + 0x00400000 + (k<<21));
179 t_l = ax - (t_h - bp[k]);
180 s_l = v*((u - s_h*t_h) - s_h*t_l);
181 /* compute log(ax) */
182 s2 = s*s;
183 r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6)))));
184 r += s_l*(s_h+s);
185 s2 = s_h*s_h;
186 t_h = 3.0f + s2 + r;
187 GET_FLOAT_WORD(is, t_h);
188 SET_FLOAT_WORD(t_h, is & 0xfffff000);
189 t_l = r - ((t_h - 3.0f) - s2);
190 /* u+v = s*(1+...) */
191 u = s_h*t_h;
192 v = s_l*t_h + t_l*s;
193 /* 2/(3log2)*(s+...) */
194 p_h = u + v;
195 GET_FLOAT_WORD(is, p_h);
196 SET_FLOAT_WORD(p_h, is & 0xfffff000);
197 p_l = v - (p_h - u);
198 z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */
199 z_l = cp_l*p_h + p_l*cp+dp_l[k];
200 /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
201 t = (float)n;
202 t1 = (((z_h + z_l) + dp_h[k]) + t);
203 GET_FLOAT_WORD(is, t1);
204 SET_FLOAT_WORD(t1, is & 0xfffff000);
205 t2 = z_l - (((t1 - t) - dp_h[k]) - z_h);
206 }
207
208 /* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
209 GET_FLOAT_WORD(is, y);
210 SET_FLOAT_WORD(y1, is & 0xfffff000);
211 p_l = (y-y1)*t1 + y*t2;
212 p_h = y1*t1;
213 z = p_l + p_h;
214 GET_FLOAT_WORD(j, z);
215 if (j > 0x43000000) /* if z > 128 */
216 return sn*huge*huge; /* overflow */
217 else if (j == 0x43000000) { /* if z == 128 */
218 if (p_l + ovt > z - p_h)
219 return sn*huge*huge; /* overflow */
220 } else if ((j&0x7fffffff) > 0x43160000) /* z < -150 */ // FIXME: check should be (uint32_t)j > 0xc3160000
221 return sn*tiny*tiny; /* underflow */
222 else if (j == 0xc3160000) { /* z == -150 */
223 if (p_l <= z-p_h)
224 return sn*tiny*tiny; /* underflow */
225 }
226 /*
227 * compute 2**(p_h+p_l)
228 */
229 i = j & 0x7fffffff;
230 k = (i>>23) - 0x7f;
231 n = 0;
232 if (i > 0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */
233 n = j + (0x00800000>>(k+1));
234 k = ((n&0x7fffffff)>>23) - 0x7f; /* new k for n */
235 SET_FLOAT_WORD(t, n & ~(0x007fffff>>k));
236 n = ((n&0x007fffff)|0x00800000)>>(23-k);
237 if (j < 0)
238 n = -n;
239 p_h -= t;
240 }
241 t = p_l + p_h;
242 GET_FLOAT_WORD(is, t);
243 SET_FLOAT_WORD(t, is & 0xffff8000);
244 u = t*lg2_h;
245 v = (p_l-(t-p_h))*lg2 + t*lg2_l;
246 z = u + v;
247 w = v - (z - u);
248 t = z*z;
249 t1 = z - t*(P1+t*(P2+t*(P3+t*(P4+t*P5))));
250 r = (z*t1)/(t1-2.0f) - (w+z*w);
251 z = 1.0f - (r - z);
252 GET_FLOAT_WORD(j, z);
253 j += n<<23;
254 if ((j>>23) <= 0) /* subnormal output */
255 z = scalbnf(z, n);
256 else
257 SET_FLOAT_WORD(z, j);
258 return sn*z;
259}
libc/musl/src/math/powl.c created+522
......@@ -0,0 +1,522 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_powl.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/* powl.c
18 *
19 * Power function, long double precision
20 *
21 *
22 * SYNOPSIS:
23 *
24 * long double x, y, z, powl();
25 *
26 * z = powl( x, y );
27 *
28 *
29 * DESCRIPTION:
30 *
31 * Computes x raised to the yth power. Analytically,
32 *
33 * x**y = exp( y log(x) ).
34 *
35 * Following Cody and Waite, this program uses a lookup table
36 * of 2**-i/32 and pseudo extended precision arithmetic to
37 * obtain several extra bits of accuracy in both the logarithm
38 * and the exponential.
39 *
40 *
41 * ACCURACY:
42 *
43 * The relative error of pow(x,y) can be estimated
44 * by y dl ln(2), where dl is the absolute error of
45 * the internally computed base 2 logarithm. At the ends
46 * of the approximation interval the logarithm equal 1/32
47 * and its relative error is about 1 lsb = 1.1e-19. Hence
48 * the predicted relative error in the result is 2.3e-21 y .
49 *
50 * Relative error:
51 * arithmetic domain # trials peak rms
52 *
53 * IEEE +-1000 40000 2.8e-18 3.7e-19
54 * .001 < x < 1000, with log(x) uniformly distributed.
55 * -1000 < y < 1000, y uniformly distributed.
56 *
57 * IEEE 0,8700 60000 6.5e-18 1.0e-18
58 * 0.99 < x < 1.01, 0 < y < 8700, uniformly distributed.
59 *
60 *
61 * ERROR MESSAGES:
62 *
63 * message condition value returned
64 * pow overflow x**y > MAXNUM INFINITY
65 * pow underflow x**y < 1/MAXNUM 0.0
66 * pow domain x<0 and y noninteger 0.0
67 *
68 */
69
70#include "libm.h"
71
72#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
73long double powl(long double x, long double y)
74{
75 return pow(x, y);
76}
77#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
78
79/* Table size */
80#define NXT 32
81
82/* log(1+x) = x - .5x^2 + x^3 * P(z)/Q(z)
83 * on the domain 2^(-1/32) - 1 <= x <= 2^(1/32) - 1
84 */
85static const long double P[] = {
86 8.3319510773868690346226E-4L,
87 4.9000050881978028599627E-1L,
88 1.7500123722550302671919E0L,
89 1.4000100839971580279335E0L,
90};
91static const long double Q[] = {
92/* 1.0000000000000000000000E0L,*/
93 5.2500282295834889175431E0L,
94 8.4000598057587009834666E0L,
95 4.2000302519914740834728E0L,
96};
97/* A[i] = 2^(-i/32), rounded to IEEE long double precision.
98 * If i is even, A[i] + B[i/2] gives additional accuracy.
99 */
100static const long double A[33] = {
101 1.0000000000000000000000E0L,
102 9.7857206208770013448287E-1L,
103 9.5760328069857364691013E-1L,
104 9.3708381705514995065011E-1L,
105 9.1700404320467123175367E-1L,
106 8.9735453750155359320742E-1L,
107 8.7812608018664974155474E-1L,
108 8.5930964906123895780165E-1L,
109 8.4089641525371454301892E-1L,
110 8.2287773907698242225554E-1L,
111 8.0524516597462715409607E-1L,
112 7.8799042255394324325455E-1L,
113 7.7110541270397041179298E-1L,
114 7.5458221379671136985669E-1L,
115 7.3841307296974965571198E-1L,
116 7.2259040348852331001267E-1L,
117 7.0710678118654752438189E-1L,
118 6.9195494098191597746178E-1L,
119 6.7712777346844636413344E-1L,
120 6.6261832157987064729696E-1L,
121 6.4841977732550483296079E-1L,
122 6.3452547859586661129850E-1L,
123 6.2092890603674202431705E-1L,
124 6.0762367999023443907803E-1L,
125 5.9460355750136053334378E-1L,
126 5.8186242938878875689693E-1L,
127 5.6939431737834582684856E-1L,
128 5.5719337129794626814472E-1L,
129 5.4525386633262882960438E-1L,
130 5.3357020033841180906486E-1L,
131 5.2213689121370692017331E-1L,
132 5.1094857432705833910408E-1L,
133 5.0000000000000000000000E-1L,
134};
135static const long double B[17] = {
136 0.0000000000000000000000E0L,
137 2.6176170809902549338711E-20L,
138-1.0126791927256478897086E-20L,
139 1.3438228172316276937655E-21L,
140 1.2207982955417546912101E-20L,
141-6.3084814358060867200133E-21L,
142 1.3164426894366316434230E-20L,
143-1.8527916071632873716786E-20L,
144 1.8950325588932570796551E-20L,
145 1.5564775779538780478155E-20L,
146 6.0859793637556860974380E-21L,
147-2.0208749253662532228949E-20L,
148 1.4966292219224761844552E-20L,
149 3.3540909728056476875639E-21L,
150-8.6987564101742849540743E-22L,
151-1.2327176863327626135542E-20L,
152 0.0000000000000000000000E0L,
153};
154
155/* 2^x = 1 + x P(x),
156 * on the interval -1/32 <= x <= 0
157 */
158static const long double R[] = {
159 1.5089970579127659901157E-5L,
160 1.5402715328927013076125E-4L,
161 1.3333556028915671091390E-3L,
162 9.6181291046036762031786E-3L,
163 5.5504108664798463044015E-2L,
164 2.4022650695910062854352E-1L,
165 6.9314718055994530931447E-1L,
166};
167
168#define MEXP (NXT*16384.0L)
169/* The following if denormal numbers are supported, else -MEXP: */
170#define MNEXP (-NXT*(16384.0L+64.0L))
171/* log2(e) - 1 */
172#define LOG2EA 0.44269504088896340735992L
173
174#define F W
175#define Fa Wa
176#define Fb Wb
177#define G W
178#define Ga Wa
179#define Gb u
180#define H W
181#define Ha Wb
182#define Hb Wb
183
184static const long double MAXLOGL = 1.1356523406294143949492E4L;
185static const long double MINLOGL = -1.13994985314888605586758E4L;
186static const long double LOGE2L = 6.9314718055994530941723E-1L;
187static const long double huge = 0x1p10000L;
188/* XXX Prevent gcc from erroneously constant folding this. */
189static const volatile long double twom10000 = 0x1p-10000L;
190
191static long double reducl(long double);
192static long double powil(long double, int);
193
194long double powl(long double x, long double y)
195{
196 /* double F, Fa, Fb, G, Ga, Gb, H, Ha, Hb */
197 int i, nflg, iyflg, yoddint;
198 long e;
199 volatile long double z=0;
200 long double w=0, W=0, Wa=0, Wb=0, ya=0, yb=0, u=0;
201
202 /* make sure no invalid exception is raised by nan comparision */
203 if (isnan(x)) {
204 if (!isnan(y) && y == 0.0)
205 return 1.0;
206 return x;
207 }
208 if (isnan(y)) {
209 if (x == 1.0)
210 return 1.0;
211 return y;
212 }
213 if (x == 1.0)
214 return 1.0; /* 1**y = 1, even if y is nan */
215 if (x == -1.0 && !isfinite(y))
216 return 1.0; /* -1**inf = 1 */
217 if (y == 0.0)
218 return 1.0; /* x**0 = 1, even if x is nan */
219 if (y == 1.0)
220 return x;
221 if (y >= LDBL_MAX) {
222 if (x > 1.0 || x < -1.0)
223 return INFINITY;
224 if (x != 0.0)
225 return 0.0;
226 }
227 if (y <= -LDBL_MAX) {
228 if (x > 1.0 || x < -1.0)
229 return 0.0;
230 if (x != 0.0 || y == -INFINITY)
231 return INFINITY;
232 }
233 if (x >= LDBL_MAX) {
234 if (y > 0.0)
235 return INFINITY;
236 return 0.0;
237 }
238
239 w = floorl(y);
240
241 /* Set iyflg to 1 if y is an integer. */
242 iyflg = 0;
243 if (w == y)
244 iyflg = 1;
245
246 /* Test for odd integer y. */
247 yoddint = 0;
248 if (iyflg) {
249 ya = fabsl(y);
250 ya = floorl(0.5 * ya);
251 yb = 0.5 * fabsl(w);
252 if( ya != yb )
253 yoddint = 1;
254 }
255
256 if (x <= -LDBL_MAX) {
257 if (y > 0.0) {
258 if (yoddint)
259 return -INFINITY;
260 return INFINITY;
261 }
262 if (y < 0.0) {
263 if (yoddint)
264 return -0.0;
265 return 0.0;
266 }
267 }
268 nflg = 0; /* (x<0)**(odd int) */
269 if (x <= 0.0) {
270 if (x == 0.0) {
271 if (y < 0.0) {
272 if (signbit(x) && yoddint)
273 /* (-0.0)**(-odd int) = -inf, divbyzero */
274 return -1.0/0.0;
275 /* (+-0.0)**(negative) = inf, divbyzero */
276 return 1.0/0.0;
277 }
278 if (signbit(x) && yoddint)
279 return -0.0;
280 return 0.0;
281 }
282 if (iyflg == 0)
283 return (x - x) / (x - x); /* (x<0)**(non-int) is NaN */
284 /* (x<0)**(integer) */
285 if (yoddint)
286 nflg = 1; /* negate result */
287 x = -x;
288 }
289 /* (+integer)**(integer) */
290 if (iyflg && floorl(x) == x && fabsl(y) < 32768.0) {
291 w = powil(x, (int)y);
292 return nflg ? -w : w;
293 }
294
295 /* separate significand from exponent */
296 x = frexpl(x, &i);
297 e = i;
298
299 /* find significand in antilog table A[] */
300 i = 1;
301 if (x <= A[17])
302 i = 17;
303 if (x <= A[i+8])
304 i += 8;
305 if (x <= A[i+4])
306 i += 4;
307 if (x <= A[i+2])
308 i += 2;
309 if (x >= A[1])
310 i = -1;
311 i += 1;
312
313 /* Find (x - A[i])/A[i]
314 * in order to compute log(x/A[i]):
315 *
316 * log(x) = log( a x/a ) = log(a) + log(x/a)
317 *
318 * log(x/a) = log(1+v), v = x/a - 1 = (x-a)/a
319 */
320 x -= A[i];
321 x -= B[i/2];
322 x /= A[i];
323
324 /* rational approximation for log(1+v):
325 *
326 * log(1+v) = v - v**2/2 + v**3 P(v) / Q(v)
327 */
328 z = x*x;
329 w = x * (z * __polevll(x, P, 3) / __p1evll(x, Q, 3));
330 w = w - 0.5*z;
331
332 /* Convert to base 2 logarithm:
333 * multiply by log2(e) = 1 + LOG2EA
334 */
335 z = LOG2EA * w;
336 z += w;
337 z += LOG2EA * x;
338 z += x;
339
340 /* Compute exponent term of the base 2 logarithm. */
341 w = -i;
342 w /= NXT;
343 w += e;
344 /* Now base 2 log of x is w + z. */
345
346 /* Multiply base 2 log by y, in extended precision. */
347
348 /* separate y into large part ya
349 * and small part yb less than 1/NXT
350 */
351 ya = reducl(y);
352 yb = y - ya;
353
354 /* (w+z)(ya+yb)
355 * = w*ya + w*yb + z*y
356 */
357 F = z * y + w * yb;
358 Fa = reducl(F);
359 Fb = F - Fa;
360
361 G = Fa + w * ya;
362 Ga = reducl(G);
363 Gb = G - Ga;
364
365 H = Fb + Gb;
366 Ha = reducl(H);
367 w = (Ga + Ha) * NXT;
368
369 /* Test the power of 2 for overflow */
370 if (w > MEXP)
371 return huge * huge; /* overflow */
372 if (w < MNEXP)
373 return twom10000 * twom10000; /* underflow */
374
375 e = w;
376 Hb = H - Ha;
377
378 if (Hb > 0.0) {
379 e += 1;
380 Hb -= 1.0/NXT; /*0.0625L;*/
381 }
382
383 /* Now the product y * log2(x) = Hb + e/NXT.
384 *
385 * Compute base 2 exponential of Hb,
386 * where -0.0625 <= Hb <= 0.
387 */
388 z = Hb * __polevll(Hb, R, 6); /* z = 2**Hb - 1 */
389
390 /* Express e/NXT as an integer plus a negative number of (1/NXT)ths.
391 * Find lookup table entry for the fractional power of 2.
392 */
393 if (e < 0)
394 i = 0;
395 else
396 i = 1;
397 i = e/NXT + i;
398 e = NXT*i - e;
399 w = A[e];
400 z = w * z; /* 2**-e * ( 1 + (2**Hb-1) ) */
401 z = z + w;
402 z = scalbnl(z, i); /* multiply by integer power of 2 */
403
404 if (nflg)
405 z = -z;
406 return z;
407}
408
409
410/* Find a multiple of 1/NXT that is within 1/NXT of x. */
411static long double reducl(long double x)
412{
413 long double t;
414
415 t = x * NXT;
416 t = floorl(t);
417 t = t / NXT;
418 return t;
419}
420
421/*
422 * Positive real raised to integer power, long double precision
423 *
424 *
425 * SYNOPSIS:
426 *
427 * long double x, y, powil();
428 * int n;
429 *
430 * y = powil( x, n );
431 *
432 *
433 * DESCRIPTION:
434 *
435 * Returns argument x>0 raised to the nth power.
436 * The routine efficiently decomposes n as a sum of powers of
437 * two. The desired power is a product of two-to-the-kth
438 * powers of x. Thus to compute the 32767 power of x requires
439 * 28 multiplications instead of 32767 multiplications.
440 *
441 *
442 * ACCURACY:
443 *
444 * Relative error:
445 * arithmetic x domain n domain # trials peak rms
446 * IEEE .001,1000 -1022,1023 50000 4.3e-17 7.8e-18
447 * IEEE 1,2 -1022,1023 20000 3.9e-17 7.6e-18
448 * IEEE .99,1.01 0,8700 10000 3.6e-16 7.2e-17
449 *
450 * Returns MAXNUM on overflow, zero on underflow.
451 */
452
453static long double powil(long double x, int nn)
454{
455 long double ww, y;
456 long double s;
457 int n, e, sign, lx;
458
459 if (nn == 0)
460 return 1.0;
461
462 if (nn < 0) {
463 sign = -1;
464 n = -nn;
465 } else {
466 sign = 1;
467 n = nn;
468 }
469
470 /* Overflow detection */
471
472 /* Calculate approximate logarithm of answer */
473 s = x;
474 s = frexpl( s, &lx);
475 e = (lx - 1)*n;
476 if ((e == 0) || (e > 64) || (e < -64)) {
477 s = (s - 7.0710678118654752e-1L) / (s + 7.0710678118654752e-1L);
478 s = (2.9142135623730950L * s - 0.5 + lx) * nn * LOGE2L;
479 } else {
480 s = LOGE2L * e;
481 }
482
483 if (s > MAXLOGL)
484 return huge * huge; /* overflow */
485
486 if (s < MINLOGL)
487 return twom10000 * twom10000; /* underflow */
488 /* Handle tiny denormal answer, but with less accuracy
489 * since roundoff error in 1.0/x will be amplified.
490 * The precise demarcation should be the gradual underflow threshold.
491 */
492 if (s < -MAXLOGL+2.0) {
493 x = 1.0/x;
494 sign = -sign;
495 }
496
497 /* First bit of the power */
498 if (n & 1)
499 y = x;
500 else
501 y = 1.0;
502
503 ww = x;
504 n >>= 1;
505 while (n) {
506 ww = ww * ww; /* arg to the 2-to-the-kth power */
507 if (n & 1) /* if that bit is set, then include in product */
508 y *= ww;
509 n >>= 1;
510 }
511
512 if (sign < 0)
513 y = 1.0/y;
514 return y;
515}
516#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
517// TODO: broken implementation to make things compile
518long double powl(long double x, long double y)
519{
520 return pow(x, y);
521}
522#endif
libc/musl/src/math/remainder.c created+9
......@@ -0,0 +1,9 @@
1#include <math.h>
2
3double remainder(double x, double y)
4{
5 int q;
6 return remquo(x, y, &q);
7}
8
9weak_alias(remainder, drem);
libc/musl/src/math/remainderf.c created+9
......@@ -0,0 +1,9 @@
1#include <math.h>
2
3float remainderf(float x, float y)
4{
5 int q;
6 return remquof(x, y, &q);
7}
8
9weak_alias(remainderf, dremf);
libc/musl/src/math/remainderl.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2#include <float.h>
3
4#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5long double remainderl(long double x, long double y)
6{
7 return remainder(x, y);
8}
9#else
10long double remainderl(long double x, long double y)
11{
12 int q;
13 return remquol(x, y, &q);
14}
15#endif
libc/musl/src/math/remquo.c created+82
......@@ -0,0 +1,82 @@
1#include <math.h>
2#include <stdint.h>
3
4double remquo(double x, double y, int *quo)
5{
6 union {double f; uint64_t i;} ux = {x}, uy = {y};
7 int ex = ux.i>>52 & 0x7ff;
8 int ey = uy.i>>52 & 0x7ff;
9 int sx = ux.i>>63;
10 int sy = uy.i>>63;
11 uint32_t q;
12 uint64_t i;
13 uint64_t uxi = ux.i;
14
15 *quo = 0;
16 if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff)
17 return (x*y)/(x*y);
18 if (ux.i<<1 == 0)
19 return x;
20
21 /* normalize x and y */
22 if (!ex) {
23 for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1);
24 uxi <<= -ex + 1;
25 } else {
26 uxi &= -1ULL >> 12;
27 uxi |= 1ULL << 52;
28 }
29 if (!ey) {
30 for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1);
31 uy.i <<= -ey + 1;
32 } else {
33 uy.i &= -1ULL >> 12;
34 uy.i |= 1ULL << 52;
35 }
36
37 q = 0;
38 if (ex < ey) {
39 if (ex+1 == ey)
40 goto end;
41 return x;
42 }
43
44 /* x mod y */
45 for (; ex > ey; ex--) {
46 i = uxi - uy.i;
47 if (i >> 63 == 0) {
48 uxi = i;
49 q++;
50 }
51 uxi <<= 1;
52 q <<= 1;
53 }
54 i = uxi - uy.i;
55 if (i >> 63 == 0) {
56 uxi = i;
57 q++;
58 }
59 if (uxi == 0)
60 ex = -60;
61 else
62 for (; uxi>>52 == 0; uxi <<= 1, ex--);
63end:
64 /* scale result and decide between |x| and |x|-|y| */
65 if (ex > 0) {
66 uxi -= 1ULL << 52;
67 uxi |= (uint64_t)ex << 52;
68 } else {
69 uxi >>= -ex + 1;
70 }
71 ux.i = uxi;
72 x = ux.f;
73 if (sy)
74 y = -y;
75 if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {
76 x -= y;
77 q++;
78 }
79 q &= 0x7fffffff;
80 *quo = sx^sy ? -(int)q : (int)q;
81 return sx ? -x : x;
82}
libc/musl/src/math/remquof.c created+82
......@@ -0,0 +1,82 @@
1#include <math.h>
2#include <stdint.h>
3
4float remquof(float x, float y, int *quo)
5{
6 union {float f; uint32_t i;} ux = {x}, uy = {y};
7 int ex = ux.i>>23 & 0xff;
8 int ey = uy.i>>23 & 0xff;
9 int sx = ux.i>>31;
10 int sy = uy.i>>31;
11 uint32_t q;
12 uint32_t i;
13 uint32_t uxi = ux.i;
14
15 *quo = 0;
16 if (uy.i<<1 == 0 || isnan(y) || ex == 0xff)
17 return (x*y)/(x*y);
18 if (ux.i<<1 == 0)
19 return x;
20
21 /* normalize x and y */
22 if (!ex) {
23 for (i = uxi<<9; i>>31 == 0; ex--, i <<= 1);
24 uxi <<= -ex + 1;
25 } else {
26 uxi &= -1U >> 9;
27 uxi |= 1U << 23;
28 }
29 if (!ey) {
30 for (i = uy.i<<9; i>>31 == 0; ey--, i <<= 1);
31 uy.i <<= -ey + 1;
32 } else {
33 uy.i &= -1U >> 9;
34 uy.i |= 1U << 23;
35 }
36
37 q = 0;
38 if (ex < ey) {
39 if (ex+1 == ey)
40 goto end;
41 return x;
42 }
43
44 /* x mod y */
45 for (; ex > ey; ex--) {
46 i = uxi - uy.i;
47 if (i >> 31 == 0) {
48 uxi = i;
49 q++;
50 }
51 uxi <<= 1;
52 q <<= 1;
53 }
54 i = uxi - uy.i;
55 if (i >> 31 == 0) {
56 uxi = i;
57 q++;
58 }
59 if (uxi == 0)
60 ex = -30;
61 else
62 for (; uxi>>23 == 0; uxi <<= 1, ex--);
63end:
64 /* scale result and decide between |x| and |x|-|y| */
65 if (ex > 0) {
66 uxi -= 1U << 23;
67 uxi |= (uint32_t)ex << 23;
68 } else {
69 uxi >>= -ex + 1;
70 }
71 ux.i = uxi;
72 x = ux.f;
73 if (sy)
74 y = -y;
75 if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {
76 x -= y;
77 q++;
78 }
79 q &= 0x7fffffff;
80 *quo = sx^sy ? -(int)q : (int)q;
81 return sx ? -x : x;
82}
libc/musl/src/math/remquol.c created+124
......@@ -0,0 +1,124 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double remquol(long double x, long double y, int *quo)
5{
6 return remquo(x, y, quo);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9long double remquol(long double x, long double y, int *quo)
10{
11 union ldshape ux = {x}, uy = {y};
12 int ex = ux.i.se & 0x7fff;
13 int ey = uy.i.se & 0x7fff;
14 int sx = ux.i.se >> 15;
15 int sy = uy.i.se >> 15;
16 uint32_t q;
17
18 *quo = 0;
19 if (y == 0 || isnan(y) || ex == 0x7fff)
20 return (x*y)/(x*y);
21 if (x == 0)
22 return x;
23
24 /* normalize x and y */
25 if (!ex) {
26 ux.i.se = ex;
27 ux.f *= 0x1p120f;
28 ex = ux.i.se - 120;
29 }
30 if (!ey) {
31 uy.i.se = ey;
32 uy.f *= 0x1p120f;
33 ey = uy.i.se - 120;
34 }
35
36 q = 0;
37 if (ex >= ey) {
38 /* x mod y */
39#if LDBL_MANT_DIG == 64
40 uint64_t i, mx, my;
41 mx = ux.i.m;
42 my = uy.i.m;
43 for (; ex > ey; ex--) {
44 i = mx - my;
45 if (mx >= my) {
46 mx = 2*i;
47 q++;
48 q <<= 1;
49 } else if (2*mx < mx) {
50 mx = 2*mx - my;
51 q <<= 1;
52 q++;
53 } else {
54 mx = 2*mx;
55 q <<= 1;
56 }
57 }
58 i = mx - my;
59 if (mx >= my) {
60 mx = i;
61 q++;
62 }
63 if (mx == 0)
64 ex = -120;
65 else
66 for (; mx >> 63 == 0; mx *= 2, ex--);
67 ux.i.m = mx;
68#elif LDBL_MANT_DIG == 113
69 uint64_t hi, lo, xhi, xlo, yhi, ylo;
70 xhi = (ux.i2.hi & -1ULL>>16) | 1ULL<<48;
71 yhi = (uy.i2.hi & -1ULL>>16) | 1ULL<<48;
72 xlo = ux.i2.lo;
73 ylo = ux.i2.lo;
74 for (; ex > ey; ex--) {
75 hi = xhi - yhi;
76 lo = xlo - ylo;
77 if (xlo < ylo)
78 hi -= 1;
79 if (hi >> 63 == 0) {
80 xhi = 2*hi + (lo>>63);
81 xlo = 2*lo;
82 q++;
83 } else {
84 xhi = 2*xhi + (xlo>>63);
85 xlo = 2*xlo;
86 }
87 q <<= 1;
88 }
89 hi = xhi - yhi;
90 lo = xlo - ylo;
91 if (xlo < ylo)
92 hi -= 1;
93 if (hi >> 63 == 0) {
94 xhi = hi;
95 xlo = lo;
96 q++;
97 }
98 if ((xhi|xlo) == 0)
99 ex = -120;
100 else
101 for (; xhi >> 48 == 0; xhi = 2*xhi + (xlo>>63), xlo = 2*xlo, ex--);
102 ux.i2.hi = xhi;
103 ux.i2.lo = xlo;
104#endif
105 }
106
107 /* scale result and decide between |x| and |x|-|y| */
108 if (ex <= 0) {
109 ux.i.se = ex + 120;
110 ux.f *= 0x1p-120f;
111 } else
112 ux.i.se = ex;
113 x = ux.f;
114 if (sy)
115 y = -y;
116 if (ex == ey || (ex+1 == ey && (2*x > y || (2*x == y && q%2)))) {
117 x -= y;
118 q++;
119 }
120 q &= 0x7fffffff;
121 *quo = sx^sy ? -(int)q : (int)q;
122 return sx ? -x : x;
123}
124#endif
libc/musl/src/math/rint.c created+28
......@@ -0,0 +1,28 @@
1#include <float.h>
2#include <math.h>
3#include <stdint.h>
4
5#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
6#define EPS DBL_EPSILON
7#elif FLT_EVAL_METHOD==2
8#define EPS LDBL_EPSILON
9#endif
10static const double_t toint = 1/EPS;
11
12double rint(double x)
13{
14 union {double f; uint64_t i;} u = {x};
15 int e = u.i>>52 & 0x7ff;
16 int s = u.i>>63;
17 double_t y;
18
19 if (e >= 0x3ff+52)
20 return x;
21 if (s)
22 y = x - toint + toint;
23 else
24 y = x + toint - toint;
25 if (y == 0)
26 return s ? -0.0 : 0;
27 return y;
28}
libc/musl/src/math/rintf.c created+30
......@@ -0,0 +1,30 @@
1#include <float.h>
2#include <math.h>
3#include <stdint.h>
4
5#if FLT_EVAL_METHOD==0
6#define EPS FLT_EPSILON
7#elif FLT_EVAL_METHOD==1
8#define EPS DBL_EPSILON
9#elif FLT_EVAL_METHOD==2
10#define EPS LDBL_EPSILON
11#endif
12static const float_t toint = 1/EPS;
13
14float rintf(float x)
15{
16 union {float f; uint32_t i;} u = {x};
17 int e = u.i>>23 & 0xff;
18 int s = u.i>>31;
19 float_t y;
20
21 if (e >= 0x7f+23)
22 return x;
23 if (s)
24 y = x - toint + toint;
25 else
26 y = x + toint - toint;
27 if (y == 0)
28 return s ? -0.0f : 0.0f;
29 return y;
30}
libc/musl/src/math/rintl.c created+29
......@@ -0,0 +1,29 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double rintl(long double x)
5{
6 return rint(x);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9
10static const long double toint = 1/LDBL_EPSILON;
11
12long double rintl(long double x)
13{
14 union ldshape u = {x};
15 int e = u.i.se & 0x7fff;
16 int s = u.i.se >> 15;
17 long double y;
18
19 if (e >= 0x3fff+LDBL_MANT_DIG-1)
20 return x;
21 if (s)
22 y = x - toint + toint;
23 else
24 y = x + toint - toint;
25 if (y == 0)
26 return 0*x;
27 return y;
28}
29#endif
libc/musl/src/math/round.c created+35
......@@ -0,0 +1,35 @@
1#include "libm.h"
2
3#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
4#define EPS DBL_EPSILON
5#elif FLT_EVAL_METHOD==2
6#define EPS LDBL_EPSILON
7#endif
8static const double_t toint = 1/EPS;
9
10double round(double x)
11{
12 union {double f; uint64_t i;} u = {x};
13 int e = u.i >> 52 & 0x7ff;
14 double_t y;
15
16 if (e >= 0x3ff+52)
17 return x;
18 if (u.i >> 63)
19 x = -x;
20 if (e < 0x3ff-1) {
21 /* raise inexact if x!=0 */
22 FORCE_EVAL(x + toint);
23 return 0*u.f;
24 }
25 y = x + toint - toint - x;
26 if (y > 0.5)
27 y = y + x - 1;
28 else if (y <= -0.5)
29 y = y + x + 1;
30 else
31 y = y + x;
32 if (u.i >> 63)
33 y = -y;
34 return y;
35}
libc/musl/src/math/roundf.c created+36
......@@ -0,0 +1,36 @@
1#include "libm.h"
2
3#if FLT_EVAL_METHOD==0
4#define EPS FLT_EPSILON
5#elif FLT_EVAL_METHOD==1
6#define EPS DBL_EPSILON
7#elif FLT_EVAL_METHOD==2
8#define EPS LDBL_EPSILON
9#endif
10static const float_t toint = 1/EPS;
11
12float roundf(float x)
13{
14 union {float f; uint32_t i;} u = {x};
15 int e = u.i >> 23 & 0xff;
16 float_t y;
17
18 if (e >= 0x7f+23)
19 return x;
20 if (u.i >> 31)
21 x = -x;
22 if (e < 0x7f-1) {
23 FORCE_EVAL(x + toint);
24 return 0*u.f;
25 }
26 y = x + toint - toint - x;
27 if (y > 0.5f)
28 y = y + x - 1;
29 else if (y <= -0.5f)
30 y = y + x + 1;
31 else
32 y = y + x;
33 if (u.i >> 31)
34 y = -y;
35 return y;
36}
libc/musl/src/math/roundl.c created+37
......@@ -0,0 +1,37 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double roundl(long double x)
5{
6 return round(x);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9
10static const long double toint = 1/LDBL_EPSILON;
11
12long double roundl(long double x)
13{
14 union ldshape u = {x};
15 int e = u.i.se & 0x7fff;
16 long double y;
17
18 if (e >= 0x3fff+LDBL_MANT_DIG-1)
19 return x;
20 if (u.i.se >> 15)
21 x = -x;
22 if (e < 0x3fff-1) {
23 FORCE_EVAL(x + toint);
24 return 0*u.f;
25 }
26 y = x + toint - toint - x;
27 if (y > 0.5)
28 y = y + x - 1;
29 else if (y <= -0.5)
30 y = y + x + 1;
31 else
32 y = y + x;
33 if (u.i.se >> 15)
34 y = -y;
35 return y;
36}
37#endif
libc/musl/src/math/s390x/ceil.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5double ceil(double x)
6{
7 __asm__ ("fidbra %0, 6, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../ceil.c"
14
15#endif
libc/musl/src/math/s390x/ceilf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5float ceilf(float x)
6{
7 __asm__ ("fiebra %0, 6, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../ceilf.c"
14
15#endif
libc/musl/src/math/s390x/ceill.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5long double ceill(long double x)
6{
7 __asm__ ("fixbra %0, 6, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../ceill.c"
14
15#endif
libc/musl/src/math/s390x/fabs.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5double fabs(double x)
6{
7 __asm__ ("lpdbr %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../fabs.c"
14
15#endif
libc/musl/src/math/s390x/fabsf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5float fabsf(float x)
6{
7 __asm__ ("lpebr %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../fabsf.c"
14
15#endif
libc/musl/src/math/s390x/fabsl.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5long double fabsl(long double x)
6{
7 __asm__ ("lpxbr %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../fabsl.c"
14
15#endif
libc/musl/src/math/s390x/floor.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5double floor(double x)
6{
7 __asm__ ("fidbra %0, 7, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../floor.c"
14
15#endif
libc/musl/src/math/s390x/floorf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5float floorf(float x)
6{
7 __asm__ ("fiebra %0, 7, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../floorf.c"
14
15#endif
libc/musl/src/math/s390x/floorl.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5long double floorl(long double x)
6{
7 __asm__ ("fixbra %0, 7, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../floorl.c"
14
15#endif
libc/musl/src/math/s390x/fma.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3double fma(double x, double y, double z)
4{
5 __asm__ ("madbr %0, %1, %2" : "+f"(z) : "f"(x), "f"(y));
6 return z;
7}
libc/musl/src/math/s390x/fmaf.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3float fmaf(float x, float y, float z)
4{
5 __asm__ ("maebr %0, %1, %2" : "+f"(z) : "f"(x), "f"(y));
6 return z;
7}
libc/musl/src/math/s390x/nearbyint.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5double nearbyint(double x)
6{
7 __asm__ ("fidbra %0, 0, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../nearbyint.c"
14
15#endif
libc/musl/src/math/s390x/nearbyintf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5float nearbyintf(float x)
6{
7 __asm__ ("fiebra %0, 0, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../nearbyintf.c"
14
15#endif
libc/musl/src/math/s390x/nearbyintl.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5long double nearbyintl(long double x)
6{
7 __asm__ ("fixbra %0, 0, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../nearbyintl.c"
14
15#endif
libc/musl/src/math/s390x/rint.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5double rint(double x)
6{
7 __asm__ ("fidbr %0, 0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../rint.c"
14
15#endif
libc/musl/src/math/s390x/rintf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5float rintf(float x)
6{
7 __asm__ ("fiebr %0, 0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../rintf.c"
14
15#endif
libc/musl/src/math/s390x/rintl.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5long double rintl(long double x)
6{
7 __asm__ ("fixbr %0, 0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../rintl.c"
14
15#endif
libc/musl/src/math/s390x/round.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5double round(double x)
6{
7 __asm__ ("fidbra %0, 1, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../round.c"
14
15#endif
libc/musl/src/math/s390x/roundf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5float roundf(float x)
6{
7 __asm__ ("fiebra %0, 1, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../roundf.c"
14
15#endif
libc/musl/src/math/s390x/roundl.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5long double roundl(long double x)
6{
7 __asm__ ("fixbra %0, 1, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../roundl.c"
14
15#endif
libc/musl/src/math/s390x/sqrt.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5double sqrt(double x)
6{
7 __asm__ ("sqdbr %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../sqrt.c"
14
15#endif
libc/musl/src/math/s390x/sqrtf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5float sqrtf(float x)
6{
7 __asm__ ("sqebr %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../sqrtf.c"
14
15#endif
libc/musl/src/math/s390x/sqrtl.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5long double sqrtl(long double x)
6{
7 __asm__ ("sqxbr %0, %1" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../sqrtl.c"
14
15#endif
libc/musl/src/math/s390x/trunc.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5double trunc(double x)
6{
7 __asm__ ("fidbra %0, 5, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../trunc.c"
14
15#endif
libc/musl/src/math/s390x/truncf.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5float truncf(float x)
6{
7 __asm__ ("fiebra %0, 5, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../truncf.c"
14
15#endif
libc/musl/src/math/s390x/truncl.c created+15
......@@ -0,0 +1,15 @@
1#include <math.h>
2
3#if defined(__HTM__) || __ARCH__ >= 9
4
5long double truncl(long double x)
6{
7 __asm__ ("fixbra %0, 5, %1, 4" : "=f"(x) : "f"(x));
8 return x;
9}
10
11#else
12
13#include "../truncl.c"
14
15#endif
libc/musl/src/math/scalb.c created+35
......@@ -0,0 +1,35 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_scalb.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/*
13 * scalb(x, fn) is provide for
14 * passing various standard test suite. One
15 * should use scalbn() instead.
16 */
17
18#define _GNU_SOURCE
19#include <math.h>
20
21double scalb(double x, double fn)
22{
23 if (isnan(x) || isnan(fn))
24 return x*fn;
25 if (!isfinite(fn)) {
26 if (fn > 0.0)
27 return x*fn;
28 else
29 return x/(-fn);
30 }
31 if (rint(fn) != fn) return (fn-fn)/(fn-fn);
32 if ( fn > 65000.0) return scalbn(x, 65000);
33 if (-fn > 65000.0) return scalbn(x,-65000);
34 return scalbn(x,(int)fn);
35}
libc/musl/src/math/scalbf.c created+32
......@@ -0,0 +1,32 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_scalbf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#define _GNU_SOURCE
17#include <math.h>
18
19float scalbf(float x, float fn)
20{
21 if (isnan(x) || isnan(fn)) return x*fn;
22 if (!isfinite(fn)) {
23 if (fn > 0.0f)
24 return x*fn;
25 else
26 return x/(-fn);
27 }
28 if (rintf(fn) != fn) return (fn-fn)/(fn-fn);
29 if ( fn > 65000.0f) return scalbnf(x, 65000);
30 if (-fn > 65000.0f) return scalbnf(x,-65000);
31 return scalbnf(x,(int)fn);
32}
libc/musl/src/math/scalbln.c created+11
......@@ -0,0 +1,11 @@
1#include <limits.h>
2#include <math.h>
3
4double scalbln(double x, long n)
5{
6 if (n > INT_MAX)
7 n = INT_MAX;
8 else if (n < INT_MIN)
9 n = INT_MIN;
10 return scalbn(x, n);
11}
libc/musl/src/math/scalblnf.c created+11
......@@ -0,0 +1,11 @@
1#include <limits.h>
2#include <math.h>
3
4float scalblnf(float x, long n)
5{
6 if (n > INT_MAX)
7 n = INT_MAX;
8 else if (n < INT_MIN)
9 n = INT_MIN;
10 return scalbnf(x, n);
11}
libc/musl/src/math/scalblnl.c created+19
......@@ -0,0 +1,19 @@
1#include <limits.h>
2#include <math.h>
3#include <float.h>
4
5#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
6long double scalblnl(long double x, long n)
7{
8 return scalbln(x, n);
9}
10#else
11long double scalblnl(long double x, long n)
12{
13 if (n > INT_MAX)
14 n = INT_MAX;
15 else if (n < INT_MIN)
16 n = INT_MIN;
17 return scalbnl(x, n);
18}
19#endif
libc/musl/src/math/scalbn.c created+33
......@@ -0,0 +1,33 @@
1#include <math.h>
2#include <stdint.h>
3
4double scalbn(double x, int n)
5{
6 union {double f; uint64_t i;} u;
7 double_t y = x;
8
9 if (n > 1023) {
10 y *= 0x1p1023;
11 n -= 1023;
12 if (n > 1023) {
13 y *= 0x1p1023;
14 n -= 1023;
15 if (n > 1023)
16 n = 1023;
17 }
18 } else if (n < -1022) {
19 /* make sure final n < -53 to avoid double
20 rounding in the subnormal range */
21 y *= 0x1p-1022 * 0x1p53;
22 n += 1022 - 53;
23 if (n < -1022) {
24 y *= 0x1p-1022 * 0x1p53;
25 n += 1022 - 53;
26 if (n < -1022)
27 n = -1022;
28 }
29 }
30 u.i = (uint64_t)(0x3ff+n)<<52;
31 x = y * u.f;
32 return x;
33}
libc/musl/src/math/scalbnf.c created+31
......@@ -0,0 +1,31 @@
1#include <math.h>
2#include <stdint.h>
3
4float scalbnf(float x, int n)
5{
6 union {float f; uint32_t i;} u;
7 float_t y = x;
8
9 if (n > 127) {
10 y *= 0x1p127f;
11 n -= 127;
12 if (n > 127) {
13 y *= 0x1p127f;
14 n -= 127;
15 if (n > 127)
16 n = 127;
17 }
18 } else if (n < -126) {
19 y *= 0x1p-126f * 0x1p24f;
20 n += 126 - 24;
21 if (n < -126) {
22 y *= 0x1p-126f * 0x1p24f;
23 n += 126 - 24;
24 if (n < -126)
25 n = -126;
26 }
27 }
28 u.i = (uint32_t)(0x7f+n)<<23;
29 x = y * u.f;
30 return x;
31}
libc/musl/src/math/scalbnl.c created+36
......@@ -0,0 +1,36 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double scalbnl(long double x, int n)
5{
6 return scalbn(x, n);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9long double scalbnl(long double x, int n)
10{
11 union ldshape u;
12
13 if (n > 16383) {
14 x *= 0x1p16383L;
15 n -= 16383;
16 if (n > 16383) {
17 x *= 0x1p16383L;
18 n -= 16383;
19 if (n > 16383)
20 n = 16383;
21 }
22 } else if (n < -16382) {
23 x *= 0x1p-16382L * 0x1p113L;
24 n += 16382 - 113;
25 if (n < -16382) {
26 x *= 0x1p-16382L * 0x1p113L;
27 n += 16382 - 113;
28 if (n < -16382)
29 n = -16382;
30 }
31 }
32 u.f = 1.0;
33 u.i.se = 0x3fff + n;
34 return x * u.f;
35}
36#endif
libc/musl/src/math/signgam.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2#include "libm.h"
3
4int __signgam = 0;
5
6weak_alias(__signgam, signgam);
libc/musl/src/math/significand.c created+7
......@@ -0,0 +1,7 @@
1#define _GNU_SOURCE
2#include <math.h>
3
4double significand(double x)
5{
6 return scalbn(x, -ilogb(x));
7}
libc/musl/src/math/significandf.c created+7
......@@ -0,0 +1,7 @@
1#define _GNU_SOURCE
2#include <math.h>
3
4float significandf(float x)
5{
6 return scalbnf(x, -ilogbf(x));
7}
libc/musl/src/math/sin.c created+78
......@@ -0,0 +1,78 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* sin(x)
13 * Return sine function of x.
14 *
15 * kernel function:
16 * __sin ... sine function on [-pi/4,pi/4]
17 * __cos ... cose function on [-pi/4,pi/4]
18 * __rem_pio2 ... argument reduction routine
19 *
20 * Method.
21 * Let S,C and T denote the sin, cos and tan respectively on
22 * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
23 * in [-pi/4 , +pi/4], and let n = k mod 4.
24 * We have
25 *
26 * n sin(x) cos(x) tan(x)
27 * ----------------------------------------------------------
28 * 0 S C T
29 * 1 C -S -1/T
30 * 2 -S -C T
31 * 3 -C S -1/T
32 * ----------------------------------------------------------
33 *
34 * Special cases:
35 * Let trig be any of sin, cos, or tan.
36 * trig(+-INF) is NaN, with signals;
37 * trig(NaN) is that NaN;
38 *
39 * Accuracy:
40 * TRIG(x) returns trig(x) nearly rounded
41 */
42
43#include "libm.h"
44
45double sin(double x)
46{
47 double y[2];
48 uint32_t ix;
49 unsigned n;
50
51 /* High word of x. */
52 GET_HIGH_WORD(ix, x);
53 ix &= 0x7fffffff;
54
55 /* |x| ~< pi/4 */
56 if (ix <= 0x3fe921fb) {
57 if (ix < 0x3e500000) { /* |x| < 2**-26 */
58 /* raise inexact if x != 0 and underflow if subnormal*/
59 FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
60 return x;
61 }
62 return __sin(x, 0.0, 0);
63 }
64
65 /* sin(Inf or NaN) is NaN */
66 if (ix >= 0x7ff00000)
67 return x - x;
68
69 /* argument reduction needed */
70 n = __rem_pio2(x, y);
71 switch (n&3) {
72 case 0: return __sin(y[0], y[1], 1);
73 case 1: return __cos(y[0], y[1]);
74 case 2: return -__sin(y[0], y[1], 1);
75 default:
76 return -__cos(y[0], y[1]);
77 }
78}
libc/musl/src/math/sincos.c created+69
......@@ -0,0 +1,69 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_sin.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12
13#define _GNU_SOURCE
14#include "libm.h"
15
16void sincos(double x, double *sin, double *cos)
17{
18 double y[2], s, c;
19 uint32_t ix;
20 unsigned n;
21
22 GET_HIGH_WORD(ix, x);
23 ix &= 0x7fffffff;
24
25 /* |x| ~< pi/4 */
26 if (ix <= 0x3fe921fb) {
27 /* if |x| < 2**-27 * sqrt(2) */
28 if (ix < 0x3e46a09e) {
29 /* raise inexact if x!=0 and underflow if subnormal */
30 FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
31 *sin = x;
32 *cos = 1.0;
33 return;
34 }
35 *sin = __sin(x, 0.0, 0);
36 *cos = __cos(x, 0.0);
37 return;
38 }
39
40 /* sincos(Inf or NaN) is NaN */
41 if (ix >= 0x7ff00000) {
42 *sin = *cos = x - x;
43 return;
44 }
45
46 /* argument reduction needed */
47 n = __rem_pio2(x, y);
48 s = __sin(y[0], y[1], 1);
49 c = __cos(y[0], y[1]);
50 switch (n&3) {
51 case 0:
52 *sin = s;
53 *cos = c;
54 break;
55 case 1:
56 *sin = c;
57 *cos = -s;
58 break;
59 case 2:
60 *sin = -s;
61 *cos = -c;
62 break;
63 case 3:
64 default:
65 *sin = -c;
66 *cos = s;
67 break;
68 }
69}
libc/musl/src/math/sincosf.c created+117
......@@ -0,0 +1,117 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 * Optimized by Bruce D. Evans.
5 */
6/*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 *
10 * Developed at SunPro, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
15 */
16
17#define _GNU_SOURCE
18#include "libm.h"
19
20/* Small multiples of pi/2 rounded to double precision. */
21static const double
22s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
23s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
24s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
25s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
26
27void sincosf(float x, float *sin, float *cos)
28{
29 double y;
30 float_t s, c;
31 uint32_t ix;
32 unsigned n, sign;
33
34 GET_FLOAT_WORD(ix, x);
35 sign = ix >> 31;
36 ix &= 0x7fffffff;
37
38 /* |x| ~<= pi/4 */
39 if (ix <= 0x3f490fda) {
40 /* |x| < 2**-12 */
41 if (ix < 0x39800000) {
42 /* raise inexact if x!=0 and underflow if subnormal */
43 FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
44 *sin = x;
45 *cos = 1.0f;
46 return;
47 }
48 *sin = __sindf(x);
49 *cos = __cosdf(x);
50 return;
51 }
52
53 /* |x| ~<= 5*pi/4 */
54 if (ix <= 0x407b53d1) {
55 if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
56 if (sign) {
57 *sin = -__cosdf(x + s1pio2);
58 *cos = __sindf(x + s1pio2);
59 } else {
60 *sin = __cosdf(s1pio2 - x);
61 *cos = __sindf(s1pio2 - x);
62 }
63 return;
64 }
65 /* -sin(x+c) is not correct if x+c could be 0: -0 vs +0 */
66 *sin = -__sindf(sign ? x + s2pio2 : x - s2pio2);
67 *cos = -__cosdf(sign ? x + s2pio2 : x - s2pio2);
68 return;
69 }
70
71 /* |x| ~<= 9*pi/4 */
72 if (ix <= 0x40e231d5) {
73 if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
74 if (sign) {
75 *sin = __cosdf(x + s3pio2);
76 *cos = -__sindf(x + s3pio2);
77 } else {
78 *sin = -__cosdf(x - s3pio2);
79 *cos = __sindf(x - s3pio2);
80 }
81 return;
82 }
83 *sin = __sindf(sign ? x + s4pio2 : x - s4pio2);
84 *cos = __cosdf(sign ? x + s4pio2 : x - s4pio2);
85 return;
86 }
87
88 /* sin(Inf or NaN) is NaN */
89 if (ix >= 0x7f800000) {
90 *sin = *cos = x - x;
91 return;
92 }
93
94 /* general argument reduction needed */
95 n = __rem_pio2f(x, &y);
96 s = __sindf(y);
97 c = __cosdf(y);
98 switch (n&3) {
99 case 0:
100 *sin = s;
101 *cos = c;
102 break;
103 case 1:
104 *sin = c;
105 *cos = -s;
106 break;
107 case 2:
108 *sin = -s;
109 *cos = -c;
110 break;
111 case 3:
112 default:
113 *sin = -c;
114 *cos = s;
115 break;
116 }
117}
libc/musl/src/math/sincosl.c created+60
......@@ -0,0 +1,60 @@
1#define _GNU_SOURCE
2#include "libm.h"
3
4#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
5void sincosl(long double x, long double *sin, long double *cos)
6{
7 double sind, cosd;
8 sincos(x, &sind, &cosd);
9 *sin = sind;
10 *cos = cosd;
11}
12#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
13void sincosl(long double x, long double *sin, long double *cos)
14{
15 union ldshape u = {x};
16 unsigned n;
17 long double y[2], s, c;
18
19 u.i.se &= 0x7fff;
20 if (u.i.se == 0x7fff) {
21 *sin = *cos = x - x;
22 return;
23 }
24 if (u.f < M_PI_4) {
25 if (u.i.se < 0x3fff - LDBL_MANT_DIG) {
26 /* raise underflow if subnormal */
27 if (u.i.se == 0) FORCE_EVAL(x*0x1p-120f);
28 *sin = x;
29 /* raise inexact if x!=0 */
30 *cos = 1.0 + x;
31 return;
32 }
33 *sin = __sinl(x, 0, 0);
34 *cos = __cosl(x, 0);
35 return;
36 }
37 n = __rem_pio2l(x, y);
38 s = __sinl(y[0], y[1], 1);
39 c = __cosl(y[0], y[1]);
40 switch (n & 3) {
41 case 0:
42 *sin = s;
43 *cos = c;
44 break;
45 case 1:
46 *sin = c;
47 *cos = -s;
48 break;
49 case 2:
50 *sin = -s;
51 *cos = -c;
52 break;
53 case 3:
54 default:
55 *sin = -c;
56 *cos = s;
57 break;
58 }
59}
60#endif
libc/musl/src/math/sinf.c created+76
......@@ -0,0 +1,76 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_sinf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 * Optimized by Bruce D. Evans.
5 */
6/*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 *
10 * Developed at SunPro, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
15 */
16
17#include "libm.h"
18
19/* Small multiples of pi/2 rounded to double precision. */
20static const double
21s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
22s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
23s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
24s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
25
26float sinf(float x)
27{
28 double y;
29 uint32_t ix;
30 int n, sign;
31
32 GET_FLOAT_WORD(ix, x);
33 sign = ix >> 31;
34 ix &= 0x7fffffff;
35
36 if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
37 if (ix < 0x39800000) { /* |x| < 2**-12 */
38 /* raise inexact if x!=0 and underflow if subnormal */
39 FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);
40 return x;
41 }
42 return __sindf(x);
43 }
44 if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
45 if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */
46 if (sign)
47 return -__cosdf(x + s1pio2);
48 else
49 return __cosdf(x - s1pio2);
50 }
51 return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2));
52 }
53 if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
54 if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */
55 if (sign)
56 return __cosdf(x + s3pio2);
57 else
58 return -__cosdf(x - s3pio2);
59 }
60 return __sindf(sign ? x + s4pio2 : x - s4pio2);
61 }
62
63 /* sin(Inf or NaN) is NaN */
64 if (ix >= 0x7f800000)
65 return x - x;
66
67 /* general argument reduction needed */
68 n = __rem_pio2f(x, &y);
69 switch (n&3) {
70 case 0: return __sindf(y);
71 case 1: return __cosdf(y);
72 case 2: return __sindf(-y);
73 default:
74 return -__cosdf(y);
75 }
76}
libc/musl/src/math/sinh.c created+39
......@@ -0,0 +1,39 @@
1#include "libm.h"
2
3/* sinh(x) = (exp(x) - 1/exp(x))/2
4 * = (exp(x)-1 + (exp(x)-1)/exp(x))/2
5 * = x + x^3/6 + o(x^5)
6 */
7double sinh(double x)
8{
9 union {double f; uint64_t i;} u = {.f = x};
10 uint32_t w;
11 double t, h, absx;
12
13 h = 0.5;
14 if (u.i >> 63)
15 h = -h;
16 /* |x| */
17 u.i &= (uint64_t)-1/2;
18 absx = u.f;
19 w = u.i >> 32;
20
21 /* |x| < log(DBL_MAX) */
22 if (w < 0x40862e42) {
23 t = expm1(absx);
24 if (w < 0x3ff00000) {
25 if (w < 0x3ff00000 - (26<<20))
26 /* note: inexact and underflow are raised by expm1 */
27 /* note: this branch avoids spurious underflow */
28 return x;
29 return h*(2*t - t*t/(t+1));
30 }
31 /* note: |x|>log(0x1p26)+eps could be just h*exp(x) */
32 return h*(t + t/(t+1));
33 }
34
35 /* |x| > log(DBL_MAX) or nan */
36 /* note: the result is stored to handle overflow */
37 t = 2*h*__expo2(absx);
38 return t;
39}
libc/musl/src/math/sinhf.c created+31
......@@ -0,0 +1,31 @@
1#include "libm.h"
2
3float sinhf(float x)
4{
5 union {float f; uint32_t i;} u = {.f = x};
6 uint32_t w;
7 float t, h, absx;
8
9 h = 0.5;
10 if (u.i >> 31)
11 h = -h;
12 /* |x| */
13 u.i &= 0x7fffffff;
14 absx = u.f;
15 w = u.i;
16
17 /* |x| < log(FLT_MAX) */
18 if (w < 0x42b17217) {
19 t = expm1f(absx);
20 if (w < 0x3f800000) {
21 if (w < 0x3f800000 - (12<<23))
22 return x;
23 return h*(2*t - t*t/(t+1));
24 }
25 return h*(t + t/(t+1));
26 }
27
28 /* |x| > logf(FLT_MAX) or nan */
29 t = 2*h*__expo2f(absx);
30 return t;
31}
libc/musl/src/math/sinhl.c created+43
......@@ -0,0 +1,43 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double sinhl(long double x)
5{
6 return sinh(x);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9long double sinhl(long double x)
10{
11 union ldshape u = {x};
12 unsigned ex = u.i.se & 0x7fff;
13 long double h, t, absx;
14
15 h = 0.5;
16 if (u.i.se & 0x8000)
17 h = -h;
18 /* |x| */
19 u.i.se = ex;
20 absx = u.f;
21
22 /* |x| < log(LDBL_MAX) */
23 if (ex < 0x3fff+13 || (ex == 0x3fff+13 && u.i.m>>32 < 0xb17217f7)) {
24 t = expm1l(absx);
25 if (ex < 0x3fff) {
26 if (ex < 0x3fff-32)
27 return x;
28 return h*(2*t - t*t/(1+t));
29 }
30 return h*(t + t/(t+1));
31 }
32
33 /* |x| > log(LDBL_MAX) or nan */
34 t = expl(0.5*absx);
35 return h*t*t;
36}
37#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
38// TODO: broken implementation to make things compile
39long double sinhl(long double x)
40{
41 return sinh(x);
42}
43#endif
libc/musl/src/math/sinl.c created+41
......@@ -0,0 +1,41 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double sinl(long double x)
5{
6 return sin(x);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9long double sinl(long double x)
10{
11 union ldshape u = {x};
12 unsigned n;
13 long double y[2], hi, lo;
14
15 u.i.se &= 0x7fff;
16 if (u.i.se == 0x7fff)
17 return x - x;
18 if (u.f < M_PI_4) {
19 if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {
20 /* raise inexact if x!=0 and underflow if subnormal */
21 FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);
22 return x;
23 }
24 return __sinl(x, 0.0, 0);
25 }
26 n = __rem_pio2l(x, y);
27 hi = y[0];
28 lo = y[1];
29 switch (n & 3) {
30 case 0:
31 return __sinl(hi, lo, 1);
32 case 1:
33 return __cosl(hi, lo);
34 case 2:
35 return -__sinl(hi, lo, 1);
36 case 3:
37 default:
38 return -__cosl(hi, lo);
39 }
40}
41#endif
libc/musl/src/math/sqrt.c created+185
......@@ -0,0 +1,185 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrt.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunSoft, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* sqrt(x)
13 * Return correctly rounded sqrt.
14 * ------------------------------------------
15 * | Use the hardware sqrt if you have one |
16 * ------------------------------------------
17 * Method:
18 * Bit by bit method using integer arithmetic. (Slow, but portable)
19 * 1. Normalization
20 * Scale x to y in [1,4) with even powers of 2:
21 * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
22 * sqrt(x) = 2^k * sqrt(y)
23 * 2. Bit by bit computation
24 * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
25 * i 0
26 * i+1 2
27 * s = 2*q , and y = 2 * ( y - q ). (1)
28 * i i i i
29 *
30 * To compute q from q , one checks whether
31 * i+1 i
32 *
33 * -(i+1) 2
34 * (q + 2 ) <= y. (2)
35 * i
36 * -(i+1)
37 * If (2) is false, then q = q ; otherwise q = q + 2 .
38 * i+1 i i+1 i
39 *
40 * With some algebric manipulation, it is not difficult to see
41 * that (2) is equivalent to
42 * -(i+1)
43 * s + 2 <= y (3)
44 * i i
45 *
46 * The advantage of (3) is that s and y can be computed by
47 * i i
48 * the following recurrence formula:
49 * if (3) is false
50 *
51 * s = s , y = y ; (4)
52 * i+1 i i+1 i
53 *
54 * otherwise,
55 * -i -(i+1)
56 * s = s + 2 , y = y - s - 2 (5)
57 * i+1 i i+1 i i
58 *
59 * One may easily use induction to prove (4) and (5).
60 * Note. Since the left hand side of (3) contain only i+2 bits,
61 * it does not necessary to do a full (53-bit) comparison
62 * in (3).
63 * 3. Final rounding
64 * After generating the 53 bits result, we compute one more bit.
65 * Together with the remainder, we can decide whether the
66 * result is exact, bigger than 1/2ulp, or less than 1/2ulp
67 * (it will never equal to 1/2ulp).
68 * The rounding mode can be detected by checking whether
69 * huge + tiny is equal to huge, and whether huge - tiny is
70 * equal to huge for some floating point number "huge" and "tiny".
71 *
72 * Special cases:
73 * sqrt(+-0) = +-0 ... exact
74 * sqrt(inf) = inf
75 * sqrt(-ve) = NaN ... with invalid signal
76 * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
77 */
78
79#include "libm.h"
80
81static const double tiny = 1.0e-300;
82
83double sqrt(double x)
84{
85 double z;
86 int32_t sign = (int)0x80000000;
87 int32_t ix0,s0,q,m,t,i;
88 uint32_t r,t1,s1,ix1,q1;
89
90 EXTRACT_WORDS(ix0, ix1, x);
91
92 /* take care of Inf and NaN */
93 if ((ix0&0x7ff00000) == 0x7ff00000) {
94 return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
95 }
96 /* take care of zero */
97 if (ix0 <= 0) {
98 if (((ix0&~sign)|ix1) == 0)
99 return x; /* sqrt(+-0) = +-0 */
100 if (ix0 < 0)
101 return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
102 }
103 /* normalize x */
104 m = ix0>>20;
105 if (m == 0) { /* subnormal x */
106 while (ix0 == 0) {
107 m -= 21;
108 ix0 |= (ix1>>11);
109 ix1 <<= 21;
110 }
111 for (i=0; (ix0&0x00100000) == 0; i++)
112 ix0<<=1;
113 m -= i - 1;
114 ix0 |= ix1>>(32-i);
115 ix1 <<= i;
116 }
117 m -= 1023; /* unbias exponent */
118 ix0 = (ix0&0x000fffff)|0x00100000;
119 if (m & 1) { /* odd m, double x to make it even */
120 ix0 += ix0 + ((ix1&sign)>>31);
121 ix1 += ix1;
122 }
123 m >>= 1; /* m = [m/2] */
124
125 /* generate sqrt(x) bit by bit */
126 ix0 += ix0 + ((ix1&sign)>>31);
127 ix1 += ix1;
128 q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
129 r = 0x00200000; /* r = moving bit from right to left */
130
131 while (r != 0) {
132 t = s0 + r;
133 if (t <= ix0) {
134 s0 = t + r;
135 ix0 -= t;
136 q += r;
137 }
138 ix0 += ix0 + ((ix1&sign)>>31);
139 ix1 += ix1;
140 r >>= 1;
141 }
142
143 r = sign;
144 while (r != 0) {
145 t1 = s1 + r;
146 t = s0;
147 if (t < ix0 || (t == ix0 && t1 <= ix1)) {
148 s1 = t1 + r;
149 if ((t1&sign) == sign && (s1&sign) == 0)
150 s0++;
151 ix0 -= t;
152 if (ix1 < t1)
153 ix0--;
154 ix1 -= t1;
155 q1 += r;
156 }
157 ix0 += ix0 + ((ix1&sign)>>31);
158 ix1 += ix1;
159 r >>= 1;
160 }
161
162 /* use floating add to find out rounding direction */
163 if ((ix0|ix1) != 0) {
164 z = 1.0 - tiny; /* raise inexact flag */
165 if (z >= 1.0) {
166 z = 1.0 + tiny;
167 if (q1 == (uint32_t)0xffffffff) {
168 q1 = 0;
169 q++;
170 } else if (z > 1.0) {
171 if (q1 == (uint32_t)0xfffffffe)
172 q++;
173 q1 += 2;
174 } else
175 q1 += q1 & 1;
176 }
177 }
178 ix0 = (q>>1) + 0x3fe00000;
179 ix1 = q1>>1;
180 if (q&1)
181 ix1 |= sign;
182 ix0 += m << 20;
183 INSERT_WORDS(z, ix0, ix1);
184 return z;
185}
libc/musl/src/math/sqrtf.c created+84
......@@ -0,0 +1,84 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrtf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 */
5/*
6 * ====================================================
7 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
8 *
9 * Developed at SunPro, a Sun Microsystems, Inc. business.
10 * Permission to use, copy, modify, and distribute this
11 * software is freely granted, provided that this notice
12 * is preserved.
13 * ====================================================
14 */
15
16#include "libm.h"
17
18static const float tiny = 1.0e-30;
19
20float sqrtf(float x)
21{
22 float z;
23 int32_t sign = (int)0x80000000;
24 int32_t ix,s,q,m,t,i;
25 uint32_t r;
26
27 GET_FLOAT_WORD(ix, x);
28
29 /* take care of Inf and NaN */
30 if ((ix&0x7f800000) == 0x7f800000)
31 return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
32
33 /* take care of zero */
34 if (ix <= 0) {
35 if ((ix&~sign) == 0)
36 return x; /* sqrt(+-0) = +-0 */
37 if (ix < 0)
38 return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
39 }
40 /* normalize x */
41 m = ix>>23;
42 if (m == 0) { /* subnormal x */
43 for (i = 0; (ix&0x00800000) == 0; i++)
44 ix<<=1;
45 m -= i - 1;
46 }
47 m -= 127; /* unbias exponent */
48 ix = (ix&0x007fffff)|0x00800000;
49 if (m&1) /* odd m, double x to make it even */
50 ix += ix;
51 m >>= 1; /* m = [m/2] */
52
53 /* generate sqrt(x) bit by bit */
54 ix += ix;
55 q = s = 0; /* q = sqrt(x) */
56 r = 0x01000000; /* r = moving bit from right to left */
57
58 while (r != 0) {
59 t = s + r;
60 if (t <= ix) {
61 s = t+r;
62 ix -= t;
63 q += r;
64 }
65 ix += ix;
66 r >>= 1;
67 }
68
69 /* use floating add to find out rounding direction */
70 if (ix != 0) {
71 z = 1.0f - tiny; /* raise inexact flag */
72 if (z >= 1.0f) {
73 z = 1.0f + tiny;
74 if (z > 1.0f)
75 q += 2;
76 else
77 q += q & 1;
78 }
79 }
80 ix = (q>>1) + 0x3f000000;
81 ix += m << 23;
82 SET_FLOAT_WORD(z, ix);
83 return z;
84}
libc/musl/src/math/sqrtl.c created+7
......@@ -0,0 +1,7 @@
1#include <math.h>
2
3long double sqrtl(long double x)
4{
5 /* FIXME: implement in C, this is for LDBL_MANT_DIG == 64 only */
6 return sqrt(x);
7}
libc/musl/src/math/tan.c created+70
......@@ -0,0 +1,70 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_tan.c */
2/*
3 * ====================================================
4 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
5 *
6 * Developed at SunPro, a Sun Microsystems, Inc. business.
7 * Permission to use, copy, modify, and distribute this
8 * software is freely granted, provided that this notice
9 * is preserved.
10 * ====================================================
11 */
12/* tan(x)
13 * Return tangent function of x.
14 *
15 * kernel function:
16 * __tan ... tangent function on [-pi/4,pi/4]
17 * __rem_pio2 ... argument reduction routine
18 *
19 * Method.
20 * Let S,C and T denote the sin, cos and tan respectively on
21 * [-PI/4, +PI/4]. Reduce the argument x to y1+y2 = x-k*pi/2
22 * in [-pi/4 , +pi/4], and let n = k mod 4.
23 * We have
24 *
25 * n sin(x) cos(x) tan(x)
26 * ----------------------------------------------------------
27 * 0 S C T
28 * 1 C -S -1/T
29 * 2 -S -C T
30 * 3 -C S -1/T
31 * ----------------------------------------------------------
32 *
33 * Special cases:
34 * Let trig be any of sin, cos, or tan.
35 * trig(+-INF) is NaN, with signals;
36 * trig(NaN) is that NaN;
37 *
38 * Accuracy:
39 * TRIG(x) returns trig(x) nearly rounded
40 */
41
42#include "libm.h"
43
44double tan(double x)
45{
46 double y[2];
47 uint32_t ix;
48 unsigned n;
49
50 GET_HIGH_WORD(ix, x);
51 ix &= 0x7fffffff;
52
53 /* |x| ~< pi/4 */
54 if (ix <= 0x3fe921fb) {
55 if (ix < 0x3e400000) { /* |x| < 2**-27 */
56 /* raise inexact if x!=0 and underflow if subnormal */
57 FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
58 return x;
59 }
60 return __tan(x, 0.0, 0);
61 }
62
63 /* tan(Inf or NaN) is NaN */
64 if (ix >= 0x7ff00000)
65 return x - x;
66
67 /* argument reduction */
68 n = __rem_pio2(x, y);
69 return __tan(y[0], y[1], n&1);
70}
libc/musl/src/math/tanf.c created+64
......@@ -0,0 +1,64 @@
1/* origin: FreeBSD /usr/src/lib/msun/src/s_tanf.c */
2/*
3 * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
4 * Optimized by Bruce D. Evans.
5 */
6/*
7 * ====================================================
8 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
9 *
10 * Developed at SunPro, a Sun Microsystems, Inc. business.
11 * Permission to use, copy, modify, and distribute this
12 * software is freely granted, provided that this notice
13 * is preserved.
14 * ====================================================
15 */
16
17#include "libm.h"
18
19/* Small multiples of pi/2 rounded to double precision. */
20static const double
21t1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */
22t2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */
23t3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */
24t4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */
25
26float tanf(float x)
27{
28 double y;
29 uint32_t ix;
30 unsigned n, sign;
31
32 GET_FLOAT_WORD(ix, x);
33 sign = ix >> 31;
34 ix &= 0x7fffffff;
35
36 if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */
37 if (ix < 0x39800000) { /* |x| < 2**-12 */
38 /* raise inexact if x!=0 and underflow if subnormal */
39 FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);
40 return x;
41 }
42 return __tandf(x, 0);
43 }
44 if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
45 if (ix <= 0x4016cbe3) /* |x| ~<= 3pi/4 */
46 return __tandf((sign ? x+t1pio2 : x-t1pio2), 1);
47 else
48 return __tandf((sign ? x+t2pio2 : x-t2pio2), 0);
49 }
50 if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
51 if (ix <= 0x40afeddf) /* |x| ~<= 7*pi/4 */
52 return __tandf((sign ? x+t3pio2 : x-t3pio2), 1);
53 else
54 return __tandf((sign ? x+t4pio2 : x-t4pio2), 0);
55 }
56
57 /* tan(Inf or NaN) is NaN */
58 if (ix >= 0x7f800000)
59 return x - x;
60
61 /* argument reduction */
62 n = __rem_pio2f(x, &y);
63 return __tandf(y, n&1);
64}
libc/musl/src/math/tanh.c created+45
......@@ -0,0 +1,45 @@
1#include "libm.h"
2
3/* tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x))
4 * = (exp(2*x) - 1)/(exp(2*x) - 1 + 2)
5 * = (1 - exp(-2*x))/(exp(-2*x) - 1 + 2)
6 */
7double tanh(double x)
8{
9 union {double f; uint64_t i;} u = {.f = x};
10 uint32_t w;
11 int sign;
12 double_t t;
13
14 /* x = |x| */
15 sign = u.i >> 63;
16 u.i &= (uint64_t)-1/2;
17 x = u.f;
18 w = u.i >> 32;
19
20 if (w > 0x3fe193ea) {
21 /* |x| > log(3)/2 ~= 0.5493 or nan */
22 if (w > 0x40340000) {
23 /* |x| > 20 or nan */
24 /* note: this branch avoids raising overflow */
25 t = 1 - 0/x;
26 } else {
27 t = expm1(2*x);
28 t = 1 - 2/(t+2);
29 }
30 } else if (w > 0x3fd058ae) {
31 /* |x| > log(5/3)/2 ~= 0.2554 */
32 t = expm1(2*x);
33 t = t/(t+2);
34 } else if (w >= 0x00100000) {
35 /* |x| >= 0x1p-1022, up to 2ulp error in [0.1,0.2554] */
36 t = expm1(-2*x);
37 t = -t/(t+2);
38 } else {
39 /* |x| is subnormal */
40 /* note: the branch above would not raise underflow in [0x1p-1023,0x1p-1022) */
41 FORCE_EVAL((float)x);
42 t = x;
43 }
44 return sign ? -t : t;
45}
libc/musl/src/math/tanhf.c created+39
......@@ -0,0 +1,39 @@
1#include "libm.h"
2
3float tanhf(float x)
4{
5 union {float f; uint32_t i;} u = {.f = x};
6 uint32_t w;
7 int sign;
8 float t;
9
10 /* x = |x| */
11 sign = u.i >> 31;
12 u.i &= 0x7fffffff;
13 x = u.f;
14 w = u.i;
15
16 if (w > 0x3f0c9f54) {
17 /* |x| > log(3)/2 ~= 0.5493 or nan */
18 if (w > 0x41200000) {
19 /* |x| > 10 */
20 t = 1 + 0/x;
21 } else {
22 t = expm1f(2*x);
23 t = 1 - 2/(t+2);
24 }
25 } else if (w > 0x3e82c578) {
26 /* |x| > log(5/3)/2 ~= 0.2554 */
27 t = expm1f(2*x);
28 t = t/(t+2);
29 } else if (w >= 0x00800000) {
30 /* |x| >= 0x1p-126 */
31 t = expm1f(-2*x);
32 t = -t/(t+2);
33 } else {
34 /* |x| is subnormal */
35 FORCE_EVAL(x*x);
36 t = x;
37 }
38 return sign ? -t : t;
39}
libc/musl/src/math/tanhl.c created+48
......@@ -0,0 +1,48 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double tanhl(long double x)
5{
6 return tanh(x);
7}
8#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
9long double tanhl(long double x)
10{
11 union ldshape u = {x};
12 unsigned ex = u.i.se & 0x7fff;
13 unsigned sign = u.i.se & 0x8000;
14 uint32_t w;
15 long double t;
16
17 /* x = |x| */
18 u.i.se = ex;
19 x = u.f;
20 w = u.i.m >> 32;
21
22 if (ex > 0x3ffe || (ex == 0x3ffe && w > 0x8c9f53d5)) {
23 /* |x| > log(3)/2 ~= 0.5493 or nan */
24 if (ex >= 0x3fff+5) {
25 /* |x| >= 32 */
26 t = 1 + 0/(x + 0x1p-120f);
27 } else {
28 t = expm1l(2*x);
29 t = 1 - 2/(t+2);
30 }
31 } else if (ex > 0x3ffd || (ex == 0x3ffd && w > 0x82c577d4)) {
32 /* |x| > log(5/3)/2 ~= 0.2554 */
33 t = expm1l(2*x);
34 t = t/(t+2);
35 } else {
36 /* |x| is small */
37 t = expm1l(-2*x);
38 t = -t/(t+2);
39 }
40 return sign ? -t : t;
41}
42#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
43// TODO: broken implementation to make things compile
44long double tanhl(long double x)
45{
46 return tanh(x);
47}
48#endif
libc/musl/src/math/tanl.c created+29
......@@ -0,0 +1,29 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double tanl(long double x)
5{
6 return tan(x);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9long double tanl(long double x)
10{
11 union ldshape u = {x};
12 long double y[2];
13 unsigned n;
14
15 u.i.se &= 0x7fff;
16 if (u.i.se == 0x7fff)
17 return x - x;
18 if (u.f < M_PI_4) {
19 if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {
20 /* raise inexact if x!=0 and underflow if subnormal */
21 FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);
22 return x;
23 }
24 return __tanl(x, 0, 0);
25 }
26 n = __rem_pio2l(x, y);
27 return __tanl(y[0], y[1], n&1);
28}
29#endif
libc/musl/src/math/tgamma.c created+222
......@@ -0,0 +1,222 @@
1/*
2"A Precision Approximation of the Gamma Function" - Cornelius Lanczos (1964)
3"Lanczos Implementation of the Gamma Function" - Paul Godfrey (2001)
4"An Analysis of the Lanczos Gamma Approximation" - Glendon Ralph Pugh (2004)
5
6approximation method:
7
8 (x - 0.5) S(x)
9Gamma(x) = (x + g - 0.5) * ----------------
10 exp(x + g - 0.5)
11
12with
13 a1 a2 a3 aN
14S(x) ~= [ a0 + ----- + ----- + ----- + ... + ----- ]
15 x + 1 x + 2 x + 3 x + N
16
17with a0, a1, a2, a3,.. aN constants which depend on g.
18
19for x < 0 the following reflection formula is used:
20
21Gamma(x)*Gamma(-x) = -pi/(x sin(pi x))
22
23most ideas and constants are from boost and python
24*/
25#include "libm.h"
26
27static const double pi = 3.141592653589793238462643383279502884;
28
29/* sin(pi x) with x > 0x1p-100, if sin(pi*x)==0 the sign is arbitrary */
30static double sinpi(double x)
31{
32 int n;
33
34 /* argument reduction: x = |x| mod 2 */
35 /* spurious inexact when x is odd int */
36 x = x * 0.5;
37 x = 2 * (x - floor(x));
38
39 /* reduce x into [-.25,.25] */
40 n = 4 * x;
41 n = (n+1)/2;
42 x -= n * 0.5;
43
44 x *= pi;
45 switch (n) {
46 default: /* case 4 */
47 case 0:
48 return __sin(x, 0, 0);
49 case 1:
50 return __cos(x, 0);
51 case 2:
52 return __sin(-x, 0, 0);
53 case 3:
54 return -__cos(x, 0);
55 }
56}
57
58#define N 12
59//static const double g = 6.024680040776729583740234375;
60static const double gmhalf = 5.524680040776729583740234375;
61static const double Snum[N+1] = {
62 23531376880.410759688572007674451636754734846804940,
63 42919803642.649098768957899047001988850926355848959,
64 35711959237.355668049440185451547166705960488635843,
65 17921034426.037209699919755754458931112671403265390,
66 6039542586.3520280050642916443072979210699388420708,
67 1439720407.3117216736632230727949123939715485786772,
68 248874557.86205415651146038641322942321632125127801,
69 31426415.585400194380614231628318205362874684987640,
70 2876370.6289353724412254090516208496135991145378768,
71 186056.26539522349504029498971604569928220784236328,
72 8071.6720023658162106380029022722506138218516325024,
73 210.82427775157934587250973392071336271166969580291,
74 2.5066282746310002701649081771338373386264310793408,
75};
76static const double Sden[N+1] = {
77 0, 39916800, 120543840, 150917976, 105258076, 45995730, 13339535,
78 2637558, 357423, 32670, 1925, 66, 1,
79};
80/* n! for small integer n */
81static const double fact[] = {
82 1, 1, 2, 6, 24, 120, 720, 5040.0, 40320.0, 362880.0, 3628800.0, 39916800.0,
83 479001600.0, 6227020800.0, 87178291200.0, 1307674368000.0, 20922789888000.0,
84 355687428096000.0, 6402373705728000.0, 121645100408832000.0,
85 2432902008176640000.0, 51090942171709440000.0, 1124000727777607680000.0,
86};
87
88/* S(x) rational function for positive x */
89static double S(double x)
90{
91 double_t num = 0, den = 0;
92 int i;
93
94 /* to avoid overflow handle large x differently */
95 if (x < 8)
96 for (i = N; i >= 0; i--) {
97 num = num * x + Snum[i];
98 den = den * x + Sden[i];
99 }
100 else
101 for (i = 0; i <= N; i++) {
102 num = num / x + Snum[i];
103 den = den / x + Sden[i];
104 }
105 return num/den;
106}
107
108double tgamma(double x)
109{
110 union {double f; uint64_t i;} u = {x};
111 double absx, y;
112 double_t dy, z, r;
113 uint32_t ix = u.i>>32 & 0x7fffffff;
114 int sign = u.i>>63;
115
116 /* special cases */
117 if (ix >= 0x7ff00000)
118 /* tgamma(nan)=nan, tgamma(inf)=inf, tgamma(-inf)=nan with invalid */
119 return x + INFINITY;
120 if (ix < (0x3ff-54)<<20)
121 /* |x| < 2^-54: tgamma(x) ~ 1/x, +-0 raises div-by-zero */
122 return 1/x;
123
124 /* integer arguments */
125 /* raise inexact when non-integer */
126 if (x == floor(x)) {
127 if (sign)
128 return 0/0.0;
129 if (x <= sizeof fact/sizeof *fact)
130 return fact[(int)x - 1];
131 }
132
133 /* x >= 172: tgamma(x)=inf with overflow */
134 /* x =< -184: tgamma(x)=+-0 with underflow */
135 if (ix >= 0x40670000) { /* |x| >= 184 */
136 if (sign) {
137 FORCE_EVAL((float)(0x1p-126/x));
138 if (floor(x) * 0.5 == floor(x * 0.5))
139 return 0;
140 return -0.0;
141 }
142 x *= 0x1p1023;
143 return x;
144 }
145
146 absx = sign ? -x : x;
147
148 /* handle the error of x + g - 0.5 */
149 y = absx + gmhalf;
150 if (absx > gmhalf) {
151 dy = y - absx;
152 dy -= gmhalf;
153 } else {
154 dy = y - gmhalf;
155 dy -= absx;
156 }
157
158 z = absx - 0.5;
159 r = S(absx) * exp(-y);
160 if (x < 0) {
161 /* reflection formula for negative x */
162 /* sinpi(absx) is not 0, integers are already handled */
163 r = -pi / (sinpi(absx) * absx * r);
164 dy = -dy;
165 z = -z;
166 }
167 r += dy * (gmhalf+0.5) * r / y;
168 z = pow(y, 0.5*z);
169 y = r * z * z;
170 return y;
171}
172
173#if 0
174double __lgamma_r(double x, int *sign)
175{
176 double r, absx;
177
178 *sign = 1;
179
180 /* special cases */
181 if (!isfinite(x))
182 /* lgamma(nan)=nan, lgamma(+-inf)=inf */
183 return x*x;
184
185 /* integer arguments */
186 if (x == floor(x) && x <= 2) {
187 /* n <= 0: lgamma(n)=inf with divbyzero */
188 /* n == 1,2: lgamma(n)=0 */
189 if (x <= 0)
190 return 1/0.0;
191 return 0;
192 }
193
194 absx = fabs(x);
195
196 /* lgamma(x) ~ -log(|x|) for tiny |x| */
197 if (absx < 0x1p-54) {
198 *sign = 1 - 2*!!signbit(x);
199 return -log(absx);
200 }
201
202 /* use tgamma for smaller |x| */
203 if (absx < 128) {
204 x = tgamma(x);
205 *sign = 1 - 2*!!signbit(x);
206 return log(fabs(x));
207 }
208
209 /* second term (log(S)-g) could be more precise here.. */
210 /* or with stirling: (|x|-0.5)*(log(|x|)-1) + poly(1/|x|) */
211 r = (absx-0.5)*(log(absx+gmhalf)-1) + (log(S(absx)) - (gmhalf+0.5));
212 if (x < 0) {
213 /* reflection formula for negative x */
214 x = sinpi(absx);
215 *sign = 2*!!signbit(x) - 1;
216 r = log(pi/(fabs(x)*absx)) - r;
217 }
218 return r;
219}
220
221weak_alias(__lgamma_r, lgamma_r);
222#endif
libc/musl/src/math/tgammaf.c created+6
......@@ -0,0 +1,6 @@
1#include <math.h>
2
3float tgammaf(float x)
4{
5 return tgamma(x);
6}
libc/musl/src/math/tgammal.c created+281
......@@ -0,0 +1,281 @@
1/* origin: OpenBSD /usr/src/lib/libm/src/ld80/e_tgammal.c */
2/*
3 * Copyright (c) 2008 Stephen L. Moshier <steve@moshier.net>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17/*
18 * Gamma function
19 *
20 *
21 * SYNOPSIS:
22 *
23 * long double x, y, tgammal();
24 *
25 * y = tgammal( x );
26 *
27 *
28 * DESCRIPTION:
29 *
30 * Returns gamma function of the argument. The result is
31 * correctly signed.
32 *
33 * Arguments |x| <= 13 are reduced by recurrence and the function
34 * approximated by a rational function of degree 7/8 in the
35 * interval (2,3). Large arguments are handled by Stirling's
36 * formula. Large negative arguments are made positive using
37 * a reflection formula.
38 *
39 *
40 * ACCURACY:
41 *
42 * Relative error:
43 * arithmetic domain # trials peak rms
44 * IEEE -40,+40 10000 3.6e-19 7.9e-20
45 * IEEE -1755,+1755 10000 4.8e-18 6.5e-19
46 *
47 * Accuracy for large arguments is dominated by error in powl().
48 *
49 */
50
51#include "libm.h"
52
53#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
54long double tgammal(long double x)
55{
56 return tgamma(x);
57}
58#elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384
59/*
60tgamma(x+2) = tgamma(x+2) P(x)/Q(x)
610 <= x <= 1
62Relative error
63n=7, d=8
64Peak error = 1.83e-20
65Relative error spread = 8.4e-23
66*/
67static const long double P[8] = {
68 4.212760487471622013093E-5L,
69 4.542931960608009155600E-4L,
70 4.092666828394035500949E-3L,
71 2.385363243461108252554E-2L,
72 1.113062816019361559013E-1L,
73 3.629515436640239168939E-1L,
74 8.378004301573126728826E-1L,
75 1.000000000000000000009E0L,
76};
77static const long double Q[9] = {
78-1.397148517476170440917E-5L,
79 2.346584059160635244282E-4L,
80-1.237799246653152231188E-3L,
81-7.955933682494738320586E-4L,
82 2.773706565840072979165E-2L,
83-4.633887671244534213831E-2L,
84-2.243510905670329164562E-1L,
85 4.150160950588455434583E-1L,
86 9.999999999999999999908E-1L,
87};
88
89/*
90static const long double P[] = {
91-3.01525602666895735709e0L,
92-3.25157411956062339893e1L,
93-2.92929976820724030353e2L,
94-1.70730828800510297666e3L,
95-7.96667499622741999770e3L,
96-2.59780216007146401957e4L,
97-5.99650230220855581642e4L,
98-7.15743521530849602425e4L
99};
100static const long double Q[] = {
101 1.00000000000000000000e0L,
102-1.67955233807178858919e1L,
103 8.85946791747759881659e1L,
104 5.69440799097468430177e1L,
105-1.98526250512761318471e3L,
106 3.31667508019495079814e3L,
107 1.60577839621734713377e4L,
108-2.97045081369399940529e4L,
109-7.15743521530849602412e4L
110};
111*/
112#define MAXGAML 1755.455L
113/*static const long double LOGPI = 1.14472988584940017414L;*/
114
115/* Stirling's formula for the gamma function
116tgamma(x) = sqrt(2 pi) x^(x-.5) exp(-x) (1 + 1/x P(1/x))
117z(x) = x
11813 <= x <= 1024
119Relative error
120n=8, d=0
121Peak error = 9.44e-21
122Relative error spread = 8.8e-4
123*/
124static const long double STIR[9] = {
125 7.147391378143610789273E-4L,
126-2.363848809501759061727E-5L,
127-5.950237554056330156018E-4L,
128 6.989332260623193171870E-5L,
129 7.840334842744753003862E-4L,
130-2.294719747873185405699E-4L,
131-2.681327161876304418288E-3L,
132 3.472222222230075327854E-3L,
133 8.333333333333331800504E-2L,
134};
135
136#define MAXSTIR 1024.0L
137static const long double SQTPI = 2.50662827463100050242E0L;
138
139/* 1/tgamma(x) = z P(z)
140 * z(x) = 1/x
141 * 0 < x < 0.03125
142 * Peak relative error 4.2e-23
143 */
144static const long double S[9] = {
145-1.193945051381510095614E-3L,
146 7.220599478036909672331E-3L,
147-9.622023360406271645744E-3L,
148-4.219773360705915470089E-2L,
149 1.665386113720805206758E-1L,
150-4.200263503403344054473E-2L,
151-6.558780715202540684668E-1L,
152 5.772156649015328608253E-1L,
153 1.000000000000000000000E0L,
154};
155
156/* 1/tgamma(-x) = z P(z)
157 * z(x) = 1/x
158 * 0 < x < 0.03125
159 * Peak relative error 5.16e-23
160 * Relative error spread = 2.5e-24
161 */
162static const long double SN[9] = {
163 1.133374167243894382010E-3L,
164 7.220837261893170325704E-3L,
165 9.621911155035976733706E-3L,
166-4.219773343731191721664E-2L,
167-1.665386113944413519335E-1L,
168-4.200263503402112910504E-2L,
169 6.558780715202536547116E-1L,
170 5.772156649015328608727E-1L,
171-1.000000000000000000000E0L,
172};
173
174static const long double PIL = 3.1415926535897932384626L;
175
176/* Gamma function computed by Stirling's formula.
177 */
178static long double stirf(long double x)
179{
180 long double y, w, v;
181
182 w = 1.0/x;
183 /* For large x, use rational coefficients from the analytical expansion. */
184 if (x > 1024.0)
185 w = (((((6.97281375836585777429E-5L * w
186 + 7.84039221720066627474E-4L) * w
187 - 2.29472093621399176955E-4L) * w
188 - 2.68132716049382716049E-3L) * w
189 + 3.47222222222222222222E-3L) * w
190 + 8.33333333333333333333E-2L) * w
191 + 1.0;
192 else
193 w = 1.0 + w * __polevll(w, STIR, 8);
194 y = expl(x);
195 if (x > MAXSTIR) { /* Avoid overflow in pow() */
196 v = powl(x, 0.5L * x - 0.25L);
197 y = v * (v / y);
198 } else {
199 y = powl(x, x - 0.5L) / y;
200 }
201 y = SQTPI * y * w;
202 return y;
203}
204
205long double tgammal(long double x)
206{
207 long double p, q, z;
208
209 if (!isfinite(x))
210 return x + INFINITY;
211
212 q = fabsl(x);
213 if (q > 13.0) {
214 if (x < 0.0) {
215 p = floorl(q);
216 z = q - p;
217 if (z == 0)
218 return 0 / z;
219 if (q > MAXGAML) {
220 z = 0;
221 } else {
222 if (z > 0.5) {
223 p += 1.0;
224 z = q - p;
225 }
226 z = q * sinl(PIL * z);
227 z = fabsl(z) * stirf(q);
228 z = PIL/z;
229 }
230 if (0.5 * p == floorl(q * 0.5))
231 z = -z;
232 } else if (x > MAXGAML) {
233 z = x * 0x1p16383L;
234 } else {
235 z = stirf(x);
236 }
237 return z;
238 }
239
240 z = 1.0;
241 while (x >= 3.0) {
242 x -= 1.0;
243 z *= x;
244 }
245 while (x < -0.03125L) {
246 z /= x;
247 x += 1.0;
248 }
249 if (x <= 0.03125L)
250 goto small;
251 while (x < 2.0) {
252 z /= x;
253 x += 1.0;
254 }
255 if (x == 2.0)
256 return z;
257
258 x -= 2.0;
259 p = __polevll(x, P, 7);
260 q = __polevll(x, Q, 8);
261 z = z * p / q;
262 return z;
263
264small:
265 /* z==1 if x was originally +-0 */
266 if (x == 0 && z != 1)
267 return x / x;
268 if (x < 0.0) {
269 x = -x;
270 q = z / (x * __polevll(x, SN, 8));
271 } else
272 q = z / (x * __polevll(x, S, 8));
273 return q;
274}
275#elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
276// TODO: broken implementation to make things compile
277long double tgammal(long double x)
278{
279 return tgamma(x);
280}
281#endif
libc/musl/src/math/trunc.c created+19
......@@ -0,0 +1,19 @@
1#include "libm.h"
2
3double trunc(double x)
4{
5 union {double f; uint64_t i;} u = {x};
6 int e = (int)(u.i >> 52 & 0x7ff) - 0x3ff + 12;
7 uint64_t m;
8
9 if (e >= 52 + 12)
10 return x;
11 if (e < 12)
12 e = 1;
13 m = -1ULL >> e;
14 if ((u.i & m) == 0)
15 return x;
16 FORCE_EVAL(x + 0x1p120f);
17 u.i &= ~m;
18 return u.f;
19}
libc/musl/src/math/truncf.c created+19
......@@ -0,0 +1,19 @@
1#include "libm.h"
2
3float truncf(float x)
4{
5 union {float f; uint32_t i;} u = {x};
6 int e = (int)(u.i >> 23 & 0xff) - 0x7f + 9;
7 uint32_t m;
8
9 if (e >= 23 + 9)
10 return x;
11 if (e < 9)
12 e = 1;
13 m = -1U >> e;
14 if ((u.i & m) == 0)
15 return x;
16 FORCE_EVAL(x + 0x1p120f);
17 u.i &= ~m;
18 return u.f;
19}
libc/musl/src/math/truncl.c created+34
......@@ -0,0 +1,34 @@
1#include "libm.h"
2
3#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
4long double truncl(long double x)
5{
6 return trunc(x);
7}
8#elif (LDBL_MANT_DIG == 64 || LDBL_MANT_DIG == 113) && LDBL_MAX_EXP == 16384
9
10static const long double toint = 1/LDBL_EPSILON;
11
12long double truncl(long double x)
13{
14 union ldshape u = {x};
15 int e = u.i.se & 0x7fff;
16 int s = u.i.se >> 15;
17 long double y;
18
19 if (e >= 0x3fff+LDBL_MANT_DIG-1)
20 return x;
21 if (e <= 0x3fff-1) {
22 FORCE_EVAL(x + 0x1p120f);
23 return x*0;
24 }
25 /* y = int(|x|) - |x|, where int(|x|) is an integer neighbor of |x| */
26 if (s)
27 x = -x;
28 y = x + toint - toint - x;
29 if (y > 0)
30 y -= 1;
31 x += y;
32 return s ? -x : x;
33}
34#endif
libc/musl/src/math/x32/__invtrigl.s created
libc/musl/src/math/x32/acosl.s created+16
......@@ -0,0 +1,16 @@
1# see ../i386/acos.s
2
3.global acosl
4.type acosl,@function
5acosl:
6 fldt 8(%esp)
71: fld %st(0)
8 fld1
9 fsub %st(0),%st(1)
10 fadd %st(2)
11 fmulp
12 fsqrt
13 fabs
14 fxch %st(1)
15 fpatan
16 ret
libc/musl/src/math/x32/asinl.s created+12
......@@ -0,0 +1,12 @@
1.global asinl
2.type asinl,@function
3asinl:
4 fldt 8(%esp)
51: fld %st(0)
6 fld1
7 fsub %st(0),%st(1)
8 fadd %st(2)
9 fmulp
10 fsqrt
11 fpatan
12 ret
libc/musl/src/math/x32/atan2l.s created+7
......@@ -0,0 +1,7 @@
1.global atan2l
2.type atan2l,@function
3atan2l:
4 fldt 8(%esp)
5 fldt 24(%esp)
6 fpatan
7 ret
libc/musl/src/math/x32/atanl.s created+7
......@@ -0,0 +1,7 @@
1.global atanl
2.type atanl,@function
3atanl:
4 fldt 8(%esp)
5 fld1
6 fpatan
7 ret
libc/musl/src/math/x32/ceill.s created+1
......@@ -0,0 +1 @@
1# see floorl.s
libc/musl/src/math/x32/exp2l.s created+83
......@@ -0,0 +1,83 @@
1.global expm1l
2.type expm1l,@function
3expm1l:
4 fldt 8(%esp)
5 fldl2e
6 fmulp
7 movl $0xc2820000,-4(%esp)
8 flds -4(%esp)
9 fucomip %st(1),%st
10 fld1
11 jb 1f
12 # x*log2e <= -65, return -1 without underflow
13 fstp %st(1)
14 fchs
15 ret
161: fld %st(1)
17 fabs
18 fucomip %st(1),%st
19 fstp %st(0)
20 ja 1f
21 f2xm1
22 ret
231: push %rax
24 call 1f
25 pop %rax
26 fld1
27 fsubrp
28 ret
29
30.global exp2l
31.type exp2l,@function
32exp2l:
33 fldt 8(%esp)
341: fld %st(0)
35 sub $16,%esp
36 fstpt (%esp)
37 mov 8(%esp),%ax
38 and $0x7fff,%ax
39 cmp $0x3fff+13,%ax
40 jb 4f # |x| < 8192
41 cmp $0x3fff+15,%ax
42 jae 3f # |x| >= 32768
43 fsts (%esp)
44 cmpl $0xc67ff800,(%esp)
45 jb 2f # x > -16382
46 movl $0x5f000000,(%esp)
47 flds (%esp) # 0x1p63
48 fld %st(1)
49 fsub %st(1)
50 faddp
51 fucomip %st(1),%st
52 je 2f # x - 0x1p63 + 0x1p63 == x
53 movl $1,(%esp)
54 flds (%esp) # 0x1p-149
55 fdiv %st(1)
56 fstps (%esp) # raise underflow
572: fld1
58 fld %st(1)
59 frndint
60 fxch %st(2)
61 fsub %st(2) # st(0)=x-rint(x), st(1)=1, st(2)=rint(x)
62 f2xm1
63 faddp # 2^(x-rint(x))
641: fscale
65 fstp %st(1)
66 add $16,%esp
67 ret
683: xor %eax,%eax
694: cmp $0x3fff-64,%ax
70 fld1
71 jb 1b # |x| < 0x1p-64
72 fstpt (%esp)
73 fistl 8(%esp)
74 fildl 8(%esp)
75 fsubrp %st(1)
76 addl $0x3fff,8(%esp)
77 f2xm1
78 fld1
79 faddp # 2^(x-rint(x))
80 fldt (%esp) # 2^rint(x)
81 fmulp
82 add $16,%esp
83 ret
libc/musl/src/math/x32/expl.s created+101
......@@ -0,0 +1,101 @@
1# exp(x) = 2^hi + 2^hi (2^lo - 1)
2# where hi+lo = log2e*x with 128bit precision
3# exact log2e*x calculation depends on nearest rounding mode
4# using the exact multiplication method of Dekker and Veltkamp
5
6.global expl
7.type expl,@function
8expl:
9 fldt 8(%esp)
10
11 # interesting case: 0x1p-32 <= |x| < 16384
12 # check if (exponent|0x8000) is in [0xbfff-32, 0xbfff+13]
13 mov 16(%esp), %ax
14 or $0x8000, %ax
15 sub $0xbfdf, %ax
16 cmp $45, %ax
17 jbe 2f
18 test %ax, %ax
19 fld1
20 js 1f
21 # if |x|>=0x1p14 or nan return 2^trunc(x)
22 fscale
23 fstp %st(1)
24 ret
25 # if |x|<0x1p-32 return 1+x
261: faddp
27 ret
28
29 # should be 0x1.71547652b82fe178p0L == 0x3fff b8aa3b29 5c17f0bc
30 # it will be wrong on non-nearest rounding mode
312: fldl2e
32 sub $48, %esp
33 # hi = log2e_hi*x
34 # 2^hi = exp2l(hi)
35 fmul %st(1),%st
36 fld %st(0)
37 fstpt (%esp)
38 fstpt 16(%esp)
39 fstpt 32(%esp)
40 call exp2l@PLT
41 # if 2^hi == inf return 2^hi
42 fld %st(0)
43 fstpt (%esp)
44 cmpw $0x7fff, 8(%esp)
45 je 1f
46 fldt 32(%esp)
47 fldt 16(%esp)
48 # fpu stack: 2^hi x hi
49 # exact mult: x*log2e
50 fld %st(1)
51 # c = 0x1p32+1
52 movq $0x41f0000000100000,%rax
53 pushq %rax
54 fldl (%esp)
55 # xh = x - c*x + c*x
56 # xl = x - xh
57 fmulp
58 fld %st(2)
59 fsub %st(1), %st
60 faddp
61 fld %st(2)
62 fsub %st(1), %st
63 # yh = log2e_hi - c*log2e_hi + c*log2e_hi
64 movq $0x3ff7154765200000,%rax
65 pushq %rax
66 fldl (%esp)
67 # fpu stack: 2^hi x hi xh xl yh
68 # lo = hi - xh*yh + xl*yh
69 fld %st(2)
70 fmul %st(1), %st
71 fsubp %st, %st(4)
72 fmul %st(1), %st
73 faddp %st, %st(3)
74 # yl = log2e_hi - yh
75 movq $0x3de705fc2f000000,%rax
76 pushq %rax
77 fldl (%esp)
78 # fpu stack: 2^hi x lo xh xl yl
79 # lo += xh*yl + xl*yl
80 fmul %st, %st(2)
81 fmulp %st, %st(1)
82 fxch %st(2)
83 faddp
84 faddp
85 # log2e_lo
86 movq $0xbfbe,%rax
87 pushq %rax
88 movq $0x82f0025f2dc582ee,%rax
89 pushq %rax
90 fldt (%esp)
91 add $40,%esp
92 # fpu stack: 2^hi x lo log2e_lo
93 # lo += log2e_lo*x
94 # return 2^hi + 2^hi (2^lo - 1)
95 fmulp %st, %st(2)
96 faddp
97 f2xm1
98 fmul %st(1), %st
99 faddp
1001: add $48, %esp
101 ret
libc/musl/src/math/x32/expm1l.s created+1
......@@ -0,0 +1 @@
1# see exp2l.s
libc/musl/src/math/x32/fabs.s created+9
......@@ -0,0 +1,9 @@
1.global fabs
2.type fabs,@function
3fabs:
4 xor %eax,%eax
5 dec %rax
6 shr %rax
7 movq %rax,%xmm1
8 andpd %xmm1,%xmm0
9 ret
libc/musl/src/math/x32/fabsf.s created+7
......@@ -0,0 +1,7 @@
1.global fabsf
2.type fabsf,@function
3fabsf:
4 mov $0x7fffffff,%eax
5 movq %rax,%xmm1
6 andps %xmm1,%xmm0
7 ret
libc/musl/src/math/x32/fabsl.s created+6
......@@ -0,0 +1,6 @@
1.global fabsl
2.type fabsl,@function
3fabsl:
4 fldt 8(%esp)
5 fabs
6 ret
libc/musl/src/math/x32/floorl.s created+27
......@@ -0,0 +1,27 @@
1.global floorl
2.type floorl,@function
3floorl:
4 fldt 8(%esp)
51: mov $0x7,%al
61: fstcw 8(%esp)
7 mov 9(%esp),%ah
8 mov %al,9(%esp)
9 fldcw 8(%esp)
10 frndint
11 mov %ah,9(%esp)
12 fldcw 8(%esp)
13 ret
14
15.global ceill
16.type ceill,@function
17ceill:
18 fldt 8(%esp)
19 mov $0xb,%al
20 jmp 1b
21
22.global truncl
23.type truncl,@function
24truncl:
25 fldt 8(%esp)
26 mov $0xf,%al
27 jmp 1b
libc/musl/src/math/x32/fma.c created+23
......@@ -0,0 +1,23 @@
1#include <math.h>
2
3#if __FMA__
4
5double fma(double x, double y, double z)
6{
7 __asm__ ("vfmadd132sd %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
8 return x;
9}
10
11#elif __FMA4__
12
13double fma(double x, double y, double z)
14{
15 __asm__ ("vfmaddsd %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
16 return x;
17}
18
19#else
20
21#include "../fma.c"
22
23#endif
libc/musl/src/math/x32/fmaf.c created+23
......@@ -0,0 +1,23 @@
1#include <math.h>
2
3#if __FMA__
4
5float fmaf(float x, float y, float z)
6{
7 __asm__ ("vfmadd132ss %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
8 return x;
9}
10
11#elif __FMA4__
12
13float fmaf(float x, float y, float z)
14{
15 __asm__ ("vfmaddss %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
16 return x;
17}
18
19#else
20
21#include "../fmaf.c"
22
23#endif
libc/musl/src/math/x32/fmodl.s created+11
......@@ -0,0 +1,11 @@
1.global fmodl
2.type fmodl,@function
3fmodl:
4 fldt 24(%esp)
5 fldt 8(%esp)
61: fprem
7 fnstsw %ax
8 testb $4,%ah
9 jnz 1b
10 fstp %st(1)
11 ret
libc/musl/src/math/x32/llrint.s created+5
......@@ -0,0 +1,5 @@
1.global llrint
2.type llrint,@function
3llrint:
4 cvtsd2si %xmm0,%rax
5 ret
libc/musl/src/math/x32/llrintf.s created+5
......@@ -0,0 +1,5 @@
1.global llrintf
2.type llrintf,@function
3llrintf:
4 cvtss2si %xmm0,%rax
5 ret
libc/musl/src/math/x32/llrintl.s created+7
......@@ -0,0 +1,7 @@
1.global llrintl
2.type llrintl,@function
3llrintl:
4 fldt 8(%esp)
5 fistpll 8(%esp)
6 mov 8(%esp),%rax
7 ret
libc/musl/src/math/x32/log10l.s created+7
......@@ -0,0 +1,7 @@
1.global log10l
2.type log10l,@function
3log10l:
4 fldlg2
5 fldt 8(%esp)
6 fyl2x
7 ret
libc/musl/src/math/x32/log1pl.s created+15
......@@ -0,0 +1,15 @@
1.global log1pl
2.type log1pl,@function
3log1pl:
4 mov 14(%esp),%eax
5 fldln2
6 and $0x7fffffff,%eax
7 fldt 8(%esp)
8 cmp $0x3ffd9400,%eax
9 ja 1f
10 fyl2xp1
11 ret
121: fld1
13 faddp
14 fyl2x
15 ret
libc/musl/src/math/x32/log2l.s created+7
......@@ -0,0 +1,7 @@
1.global log2l
2.type log2l,@function
3log2l:
4 fld1
5 fldt 8(%esp)
6 fyl2x
7 ret
libc/musl/src/math/x32/logl.s created+7
......@@ -0,0 +1,7 @@
1.global logl
2.type logl,@function
3logl:
4 fldln2
5 fldt 8(%esp)
6 fyl2x
7 ret
libc/musl/src/math/x32/lrint.s created+5
......@@ -0,0 +1,5 @@
1.global lrint
2.type lrint,@function
3lrint:
4 cvtsd2si %xmm0,%rax
5 ret
libc/musl/src/math/x32/lrintf.s created+5
......@@ -0,0 +1,5 @@
1.global lrintf
2.type lrintf,@function
3lrintf:
4 cvtss2si %xmm0,%rax
5 ret
libc/musl/src/math/x32/lrintl.s created+7
......@@ -0,0 +1,7 @@
1.global lrintl
2.type lrintl,@function
3lrintl:
4 fldt 8(%esp)
5 fistpll 8(%esp)
6 mov 8(%esp),%rax
7 ret
libc/musl/src/math/x32/remainderl.s created+11
......@@ -0,0 +1,11 @@
1.global remainderl
2.type remainderl,@function
3remainderl:
4 fldt 24(%esp)
5 fldt 8(%esp)
61: fprem1
7 fnstsw %ax
8 testb $4,%ah
9 jnz 1b
10 fstp %st(1)
11 ret
libc/musl/src/math/x32/rintl.s created+6
......@@ -0,0 +1,6 @@
1.global rintl
2.type rintl,@function
3rintl:
4 fldt 8(%esp)
5 frndint
6 ret
libc/musl/src/math/x32/sqrt.s created+4
......@@ -0,0 +1,4 @@
1.global sqrt
2.type sqrt,@function
3sqrt: sqrtsd %xmm0, %xmm0
4 ret
libc/musl/src/math/x32/sqrtf.s created+4
......@@ -0,0 +1,4 @@
1.global sqrtf
2.type sqrtf,@function
3sqrtf: sqrtss %xmm0, %xmm0
4 ret
libc/musl/src/math/x32/sqrtl.s created+5
......@@ -0,0 +1,5 @@
1.global sqrtl
2.type sqrtl,@function
3sqrtl: fldt 8(%esp)
4 fsqrt
5 ret
libc/musl/src/math/x32/truncl.s created+1
......@@ -0,0 +1 @@
1# see floorl.s
libc/musl/src/math/x86_64/__invtrigl.s created
libc/musl/src/math/x86_64/acosl.s created+16
......@@ -0,0 +1,16 @@
1# see ../i386/acos.s
2
3.global acosl
4.type acosl,@function
5acosl:
6 fldt 8(%rsp)
71: fld %st(0)
8 fld1
9 fsub %st(0),%st(1)
10 fadd %st(2)
11 fmulp
12 fsqrt
13 fabs
14 fxch %st(1)
15 fpatan
16 ret
libc/musl/src/math/x86_64/asinl.s created+12
......@@ -0,0 +1,12 @@
1.global asinl
2.type asinl,@function
3asinl:
4 fldt 8(%rsp)
51: fld %st(0)
6 fld1
7 fsub %st(0),%st(1)
8 fadd %st(2)
9 fmulp
10 fsqrt
11 fpatan
12 ret
libc/musl/src/math/x86_64/atan2l.s created+7
......@@ -0,0 +1,7 @@
1.global atan2l
2.type atan2l,@function
3atan2l:
4 fldt 8(%rsp)
5 fldt 24(%rsp)
6 fpatan
7 ret
libc/musl/src/math/x86_64/atanl.s created+7
......@@ -0,0 +1,7 @@
1.global atanl
2.type atanl,@function
3atanl:
4 fldt 8(%rsp)
5 fld1
6 fpatan
7 ret
libc/musl/src/math/x86_64/ceill.s created+1
......@@ -0,0 +1 @@
1# see floorl.s
libc/musl/src/math/x86_64/exp2l.s created+83
......@@ -0,0 +1,83 @@
1.global expm1l
2.type expm1l,@function
3expm1l:
4 fldt 8(%rsp)
5 fldl2e
6 fmulp
7 movl $0xc2820000,-4(%rsp)
8 flds -4(%rsp)
9 fucomip %st(1),%st
10 fld1
11 jb 1f
12 # x*log2e <= -65, return -1 without underflow
13 fstp %st(1)
14 fchs
15 ret
161: fld %st(1)
17 fabs
18 fucomip %st(1),%st
19 fstp %st(0)
20 ja 1f
21 f2xm1
22 ret
231: push %rax
24 call 1f
25 pop %rax
26 fld1
27 fsubrp
28 ret
29
30.global exp2l
31.type exp2l,@function
32exp2l:
33 fldt 8(%rsp)
341: fld %st(0)
35 sub $16,%rsp
36 fstpt (%rsp)
37 mov 8(%rsp),%ax
38 and $0x7fff,%ax
39 cmp $0x3fff+13,%ax
40 jb 4f # |x| < 8192
41 cmp $0x3fff+15,%ax
42 jae 3f # |x| >= 32768
43 fsts (%rsp)
44 cmpl $0xc67ff800,(%rsp)
45 jb 2f # x > -16382
46 movl $0x5f000000,(%rsp)
47 flds (%rsp) # 0x1p63
48 fld %st(1)
49 fsub %st(1)
50 faddp
51 fucomip %st(1),%st
52 je 2f # x - 0x1p63 + 0x1p63 == x
53 movl $1,(%rsp)
54 flds (%rsp) # 0x1p-149
55 fdiv %st(1)
56 fstps (%rsp) # raise underflow
572: fld1
58 fld %st(1)
59 frndint
60 fxch %st(2)
61 fsub %st(2) # st(0)=x-rint(x), st(1)=1, st(2)=rint(x)
62 f2xm1
63 faddp # 2^(x-rint(x))
641: fscale
65 fstp %st(1)
66 add $16,%rsp
67 ret
683: xor %eax,%eax
694: cmp $0x3fff-64,%ax
70 fld1
71 jb 1b # |x| < 0x1p-64
72 fstpt (%rsp)
73 fistl 8(%rsp)
74 fildl 8(%rsp)
75 fsubrp %st(1)
76 addl $0x3fff,8(%rsp)
77 f2xm1
78 fld1
79 faddp # 2^(x-rint(x))
80 fldt (%rsp) # 2^rint(x)
81 fmulp
82 add $16,%rsp
83 ret
libc/musl/src/math/x86_64/expl.s created+101
......@@ -0,0 +1,101 @@
1# exp(x) = 2^hi + 2^hi (2^lo - 1)
2# where hi+lo = log2e*x with 128bit precision
3# exact log2e*x calculation depends on nearest rounding mode
4# using the exact multiplication method of Dekker and Veltkamp
5
6.global expl
7.type expl,@function
8expl:
9 fldt 8(%rsp)
10
11 # interesting case: 0x1p-32 <= |x| < 16384
12 # check if (exponent|0x8000) is in [0xbfff-32, 0xbfff+13]
13 mov 16(%rsp), %ax
14 or $0x8000, %ax
15 sub $0xbfdf, %ax
16 cmp $45, %ax
17 jbe 2f
18 test %ax, %ax
19 fld1
20 js 1f
21 # if |x|>=0x1p14 or nan return 2^trunc(x)
22 fscale
23 fstp %st(1)
24 ret
25 # if |x|<0x1p-32 return 1+x
261: faddp
27 ret
28
29 # should be 0x1.71547652b82fe178p0L == 0x3fff b8aa3b29 5c17f0bc
30 # it will be wrong on non-nearest rounding mode
312: fldl2e
32 subq $48, %rsp
33 # hi = log2e_hi*x
34 # 2^hi = exp2l(hi)
35 fmul %st(1),%st
36 fld %st(0)
37 fstpt (%rsp)
38 fstpt 16(%rsp)
39 fstpt 32(%rsp)
40 call exp2l@PLT
41 # if 2^hi == inf return 2^hi
42 fld %st(0)
43 fstpt (%rsp)
44 cmpw $0x7fff, 8(%rsp)
45 je 1f
46 fldt 32(%rsp)
47 fldt 16(%rsp)
48 # fpu stack: 2^hi x hi
49 # exact mult: x*log2e
50 fld %st(1)
51 # c = 0x1p32+1
52 movq $0x41f0000000100000,%rax
53 pushq %rax
54 fldl (%rsp)
55 # xh = x - c*x + c*x
56 # xl = x - xh
57 fmulp
58 fld %st(2)
59 fsub %st(1), %st
60 faddp
61 fld %st(2)
62 fsub %st(1), %st
63 # yh = log2e_hi - c*log2e_hi + c*log2e_hi
64 movq $0x3ff7154765200000,%rax
65 pushq %rax
66 fldl (%rsp)
67 # fpu stack: 2^hi x hi xh xl yh
68 # lo = hi - xh*yh + xl*yh
69 fld %st(2)
70 fmul %st(1), %st
71 fsubp %st, %st(4)
72 fmul %st(1), %st
73 faddp %st, %st(3)
74 # yl = log2e_hi - yh
75 movq $0x3de705fc2f000000,%rax
76 pushq %rax
77 fldl (%rsp)
78 # fpu stack: 2^hi x lo xh xl yl
79 # lo += xh*yl + xl*yl
80 fmul %st, %st(2)
81 fmulp %st, %st(1)
82 fxch %st(2)
83 faddp
84 faddp
85 # log2e_lo
86 movq $0xbfbe,%rax
87 pushq %rax
88 movq $0x82f0025f2dc582ee,%rax
89 pushq %rax
90 fldt (%rsp)
91 addq $40,%rsp
92 # fpu stack: 2^hi x lo log2e_lo
93 # lo += log2e_lo*x
94 # return 2^hi + 2^hi (2^lo - 1)
95 fmulp %st, %st(2)
96 faddp
97 f2xm1
98 fmul %st(1), %st
99 faddp
1001: addq $48, %rsp
101 ret
libc/musl/src/math/x86_64/expm1l.s created+1
......@@ -0,0 +1 @@
1# see exp2l.s
libc/musl/src/math/x86_64/fabs.s created+9
......@@ -0,0 +1,9 @@
1.global fabs
2.type fabs,@function
3fabs:
4 xor %eax,%eax
5 dec %rax
6 shr %rax
7 movq %rax,%xmm1
8 andpd %xmm1,%xmm0
9 ret
libc/musl/src/math/x86_64/fabsf.s created+7
......@@ -0,0 +1,7 @@
1.global fabsf
2.type fabsf,@function
3fabsf:
4 mov $0x7fffffff,%eax
5 movq %rax,%xmm1
6 andps %xmm1,%xmm0
7 ret
libc/musl/src/math/x86_64/fabsl.s created+6
......@@ -0,0 +1,6 @@
1.global fabsl
2.type fabsl,@function
3fabsl:
4 fldt 8(%rsp)
5 fabs
6 ret
libc/musl/src/math/x86_64/floorl.s created+27
......@@ -0,0 +1,27 @@
1.global floorl
2.type floorl,@function
3floorl:
4 fldt 8(%rsp)
51: mov $0x7,%al
61: fstcw 8(%rsp)
7 mov 9(%rsp),%ah
8 mov %al,9(%rsp)
9 fldcw 8(%rsp)
10 frndint
11 mov %ah,9(%rsp)
12 fldcw 8(%rsp)
13 ret
14
15.global ceill
16.type ceill,@function
17ceill:
18 fldt 8(%rsp)
19 mov $0xb,%al
20 jmp 1b
21
22.global truncl
23.type truncl,@function
24truncl:
25 fldt 8(%rsp)
26 mov $0xf,%al
27 jmp 1b
libc/musl/src/math/x86_64/fma.c created+23
......@@ -0,0 +1,23 @@
1#include <math.h>
2
3#if __FMA__
4
5double fma(double x, double y, double z)
6{
7 __asm__ ("vfmadd132sd %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
8 return x;
9}
10
11#elif __FMA4__
12
13double fma(double x, double y, double z)
14{
15 __asm__ ("vfmaddsd %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
16 return x;
17}
18
19#else
20
21#include "../fma.c"
22
23#endif
libc/musl/src/math/x86_64/fmaf.c created+23
......@@ -0,0 +1,23 @@
1#include <math.h>
2
3#if __FMA__
4
5float fmaf(float x, float y, float z)
6{
7 __asm__ ("vfmadd132ss %1, %2, %0" : "+x" (x) : "x" (y), "x" (z));
8 return x;
9}
10
11#elif __FMA4__
12
13float fmaf(float x, float y, float z)
14{
15 __asm__ ("vfmaddss %3, %2, %1, %0" : "=x" (x) : "x" (x), "x" (y), "x" (z));
16 return x;
17}
18
19#else
20
21#include "../fmaf.c"
22
23#endif
libc/musl/src/math/x86_64/fmodl.s created+11
......@@ -0,0 +1,11 @@
1.global fmodl
2.type fmodl,@function
3fmodl:
4 fldt 24(%rsp)
5 fldt 8(%rsp)
61: fprem
7 fnstsw %ax
8 testb $4,%ah
9 jnz 1b
10 fstp %st(1)
11 ret
libc/musl/src/math/x86_64/llrint.s created+5
......@@ -0,0 +1,5 @@
1.global llrint
2.type llrint,@function
3llrint:
4 cvtsd2si %xmm0,%rax
5 ret
libc/musl/src/math/x86_64/llrintf.s created+5
......@@ -0,0 +1,5 @@
1.global llrintf
2.type llrintf,@function
3llrintf:
4 cvtss2si %xmm0,%rax
5 ret
libc/musl/src/math/x86_64/llrintl.s created+7
......@@ -0,0 +1,7 @@
1.global llrintl
2.type llrintl,@function
3llrintl:
4 fldt 8(%rsp)
5 fistpll 8(%rsp)
6 mov 8(%rsp),%rax
7 ret
libc/musl/src/math/x86_64/log10l.s created+7
......@@ -0,0 +1,7 @@
1.global log10l
2.type log10l,@function
3log10l:
4 fldlg2
5 fldt 8(%rsp)
6 fyl2x
7 ret
libc/musl/src/math/x86_64/log1pl.s created+15
......@@ -0,0 +1,15 @@
1.global log1pl
2.type log1pl,@function
3log1pl:
4 mov 14(%rsp),%eax
5 fldln2
6 and $0x7fffffff,%eax
7 fldt 8(%rsp)
8 cmp $0x3ffd9400,%eax
9 ja 1f
10 fyl2xp1
11 ret
121: fld1
13 faddp
14 fyl2x
15 ret
libc/musl/src/math/x86_64/log2l.s created+7
......@@ -0,0 +1,7 @@
1.global log2l
2.type log2l,@function
3log2l:
4 fld1
5 fldt 8(%rsp)
6 fyl2x
7 ret
libc/musl/src/math/x86_64/logl.s created+7
......@@ -0,0 +1,7 @@
1.global logl
2.type logl,@function
3logl:
4 fldln2
5 fldt 8(%rsp)
6 fyl2x
7 ret
libc/musl/src/math/x86_64/lrint.s created+5
......@@ -0,0 +1,5 @@
1.global lrint
2.type lrint,@function
3lrint:
4 cvtsd2si %xmm0,%rax
5 ret
libc/musl/src/math/x86_64/lrintf.s created+5
......@@ -0,0 +1,5 @@
1.global lrintf
2.type lrintf,@function
3lrintf:
4 cvtss2si %xmm0,%rax
5 ret
libc/musl/src/math/x86_64/lrintl.s created+7
......@@ -0,0 +1,7 @@
1.global lrintl
2.type lrintl,@function
3lrintl:
4 fldt 8(%rsp)
5 fistpll 8(%rsp)
6 mov 8(%rsp),%rax
7 ret
libc/musl/src/math/x86_64/remainderl.s created+11
......@@ -0,0 +1,11 @@
1.global remainderl
2.type remainderl,@function
3remainderl:
4 fldt 24(%rsp)
5 fldt 8(%rsp)
61: fprem1
7 fnstsw %ax
8 testb $4,%ah
9 jnz 1b
10 fstp %st(1)
11 ret
libc/musl/src/math/x86_64/rintl.s created+6
......@@ -0,0 +1,6 @@
1.global rintl
2.type rintl,@function
3rintl:
4 fldt 8(%rsp)
5 frndint
6 ret
libc/musl/src/math/x86_64/sqrt.s created+4
......@@ -0,0 +1,4 @@
1.global sqrt
2.type sqrt,@function
3sqrt: sqrtsd %xmm0, %xmm0
4 ret
libc/musl/src/math/x86_64/sqrtf.s created+4
......@@ -0,0 +1,4 @@
1.global sqrtf
2.type sqrtf,@function
3sqrtf: sqrtss %xmm0, %xmm0
4 ret
libc/musl/src/math/x86_64/sqrtl.s created+5
......@@ -0,0 +1,5 @@
1.global sqrtl
2.type sqrtl,@function
3sqrtl: fldt 8(%rsp)
4 fsqrt
5 ret
libc/musl/src/math/x86_64/truncl.s created+1
......@@ -0,0 +1 @@
1# see floorl.s
libc/musl/src/misc/a64l.c created+29
......@@ -0,0 +1,29 @@
1#include <stdlib.h>
2#include <string.h>
3#include <stdint.h>
4
5static const char digits[] =
6 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
7
8long a64l(const char *s)
9{
10 int e;
11 uint32_t x = 0;
12 for (e=0; e<36 && *s; e+=6, s++) {
13 const char *d = strchr(digits, *s);
14 if (!d) break;
15 x |= (uint32_t)(d-digits)<<e;
16 }
17 return (int32_t)x;
18}
19
20char *l64a(long x0)
21{
22 static char s[7];
23 char *p;
24 uint32_t x = x0;
25 for (p=s; x; p++, x>>=6)
26 *p = digits[x&63];
27 *p = 0;
28 return s;
29}
libc/musl/src/misc/basename.c created+14
......@@ -0,0 +1,14 @@
1#include <string.h>
2#include <libgen.h>
3
4char *basename(char *s)
5{
6 size_t i;
7 if (!s || !*s) return ".";
8 i = strlen(s)-1;
9 for (; i&&s[i]=='/'; i--) s[i] = 0;
10 for (; i&&s[i-1]!='/'; i--);
11 return s+i;
12}
13
14weak_alias(basename, __xpg_basename);
libc/musl/src/misc/dirname.c created+14
......@@ -0,0 +1,14 @@
1#include <string.h>
2#include <libgen.h>
3
4char *dirname(char *s)
5{
6 size_t i;
7 if (!s || !*s) return ".";
8 i = strlen(s)-1;
9 for (; s[i]=='/'; i--) if (!i) return "/";
10 for (; s[i]!='/'; i--) if (!i) return ".";
11 for (; s[i]=='/'; i--) if (!i) return "/";
12 s[i+1] = 0;
13 return s;
14}
libc/musl/src/misc/ffs.c created+7
......@@ -0,0 +1,7 @@
1#include <strings.h>
2#include "atomic.h"
3
4int ffs(int i)
5{
6 return i ? a_ctz_l(i)+1 : 0;
7}
libc/musl/src/misc/ffsl.c created+7
......@@ -0,0 +1,7 @@
1#include <strings.h>
2#include "atomic.h"
3
4int ffsl(long i)
5{
6 return i ? a_ctz_l(i)+1 : 0;
7}
libc/musl/src/misc/ffsll.c created+7
......@@ -0,0 +1,7 @@
1#include <strings.h>
2#include "atomic.h"
3
4int ffsll(long long i)
5{
6 return i ? a_ctz_64(i)+1 : 0;
7}
libc/musl/src/misc/fmtmsg.c created+90
......@@ -0,0 +1,90 @@
1/* Public domain fmtmsg()
2 * Written by Isaac Dunham, 2014
3 */
4#include <fmtmsg.h>
5#include <fcntl.h>
6#include <unistd.h>
7#include <stdio.h>
8#include <string.h>
9#include <stdlib.h>
10#include <pthread.h>
11
12/*
13 * If lstr is the first part of bstr, check that the next char in bstr
14 * is either \0 or :
15 */
16static int _strcolcmp(const char *lstr, const char *bstr)
17{
18 size_t i = 0;
19 while (lstr[i] && bstr[i] && (bstr[i] == lstr[i])) i++;
20 if ( lstr[i] || (bstr[i] && bstr[i] != ':')) return 1;
21 return 0;
22}
23
24int fmtmsg(long classification, const char *label, int severity,
25 const char *text, const char *action, const char *tag)
26{
27 int ret = 0, i, consolefd, verb = 0;
28 char *errstring = MM_NULLSEV, *cmsg = getenv("MSGVERB");
29 char *const msgs[] = {
30 "label", "severity", "text", "action", "tag", NULL
31 };
32 int cs;
33
34 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
35
36 if (severity == MM_HALT) errstring = "HALT: ";
37 else if (severity == MM_ERROR) errstring = "ERROR: ";
38 else if (severity == MM_WARNING) errstring = "WARNING: ";
39 else if (severity == MM_INFO) errstring = "INFO: ";
40
41 if (classification & MM_CONSOLE) {
42 consolefd = open("/dev/console", O_WRONLY);
43 if (consolefd < 0) {
44 ret = MM_NOCON;
45 } else {
46 if (dprintf(consolefd, "%s%s%s%s%s%s%s%s\n",
47 label?label:"", label?": ":"",
48 severity?errstring:"", text?text:"",
49 action?"\nTO FIX: ":"",
50 action?action:"", action?" ":"",
51 tag?tag:"" )<1)
52 ret = MM_NOCON;
53 close(consolefd);
54 }
55 }
56
57 if (classification & MM_PRINT) {
58 while (cmsg && cmsg[0]) {
59 for(i=0; msgs[i]; i++) {
60 if (!_strcolcmp(msgs[i], cmsg)) break;
61 }
62 if (msgs[i] == NULL) {
63 //ignore MSGVERB-unrecognized component
64 verb = 0xFF;
65 break;
66 } else {
67 verb |= (1 << i);
68 cmsg = strchr(cmsg, ':');
69 if (cmsg) cmsg++;
70 }
71 }
72 if (!verb) verb = 0xFF;
73 if (dprintf(2, "%s%s%s%s%s%s%s%s\n",
74 (verb&1 && label) ? label : "",
75 (verb&1 && label) ? ": " : "",
76 (verb&2 && severity) ? errstring : "",
77 (verb&4 && text) ? text : "",
78 (verb&8 && action) ? "\nTO FIX: " : "",
79 (verb&8 && action) ? action : "",
80 (verb&8 && action) ? " " : "",
81 (verb&16 && tag) ? tag : "" ) < 1)
82 ret |= MM_NOMSG;
83 }
84 if ((ret & (MM_NOCON|MM_NOMSG)) == (MM_NOCON|MM_NOMSG))
85 ret = MM_NOTOK;
86
87 pthread_setcancelstate(cs, 0);
88
89 return ret;
90}
libc/musl/src/misc/forkpty.c created+57
......@@ -0,0 +1,57 @@
1#include <pty.h>
2#include <utmp.h>
3#include <unistd.h>
4#include <errno.h>
5#include <fcntl.h>
6#include <sys/wait.h>
7#include <pthread.h>
8
9int forkpty(int *pm, char *name, const struct termios *tio, const struct winsize *ws)
10{
11 int m, s, ec=0, p[2], cs;
12 pid_t pid=-1;
13 sigset_t set, oldset;
14
15 if (openpty(&m, &s, name, tio, ws) < 0) return -1;
16
17 sigfillset(&set);
18 pthread_sigmask(SIG_BLOCK, &set, &oldset);
19 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
20
21 if (pipe2(p, O_CLOEXEC)) {
22 close(s);
23 goto out;
24 }
25
26 pid = fork();
27 if (!pid) {
28 close(m);
29 close(p[0]);
30 if (login_tty(s)) {
31 write(p[1], &errno, sizeof errno);
32 _exit(127);
33 }
34 close(p[1]);
35 pthread_setcancelstate(cs, 0);
36 pthread_sigmask(SIG_SETMASK, &oldset, 0);
37 return 0;
38 }
39 close(s);
40 close(p[1]);
41 if (read(p[0], &ec, sizeof ec) > 0) {
42 int status;
43 waitpid(pid, &status, 0);
44 pid = -1;
45 errno = ec;
46 }
47 close(p[0]);
48
49out:
50 if (pid > 0) *pm = m;
51 else close(m);
52
53 pthread_setcancelstate(cs, 0);
54 pthread_sigmask(SIG_SETMASK, &oldset, 0);
55
56 return pid;
57}
libc/musl/src/misc/get_current_dir_name.c created+15
......@@ -0,0 +1,15 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <string.h>
4#include <limits.h>
5#include <unistd.h>
6#include <sys/stat.h>
7
8char *get_current_dir_name(void) {
9 struct stat a, b;
10 char *res = getenv("PWD");
11 if (res && *res && !stat(res, &a) && !stat(".", &b)
12 && (a.st_dev == b.st_dev) && (a.st_ino == b.st_ino))
13 return strdup(res);
14 return getcwd(0, 0);
15}
libc/musl/src/misc/getauxval.c created+15
......@@ -0,0 +1,15 @@
1#include <sys/auxv.h>
2#include <errno.h>
3#include "libc.h"
4
5unsigned long __getauxval(unsigned long item)
6{
7 size_t *auxv = libc.auxv;
8 if (item == AT_SECURE) return libc.secure;
9 for (; *auxv; auxv+=2)
10 if (*auxv==item) return auxv[1];
11 errno = ENOENT;
12 return 0;
13}
14
15weak_alias(__getauxval, getauxval);
libc/musl/src/misc/getdomainname.c created+17
......@@ -0,0 +1,17 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include <sys/utsname.h>
4#include <string.h>
5#include <errno.h>
6
7int getdomainname(char *name, size_t len)
8{
9 struct utsname temp;
10 uname(&temp);
11 if (!len || strlen(temp.domainname) >= len) {
12 errno = EINVAL;
13 return -1;
14 }
15 strcpy(name, temp.domainname);
16 return 0;
17}
libc/musl/src/misc/getentropy.c created+33
......@@ -0,0 +1,33 @@
1#define _BSD_SOURCE
2#include <unistd.h>
3#include <sys/random.h>
4#include <pthread.h>
5#include <errno.h>
6
7int getentropy(void *buffer, size_t len)
8{
9 int cs, ret;
10 char *pos = buffer;
11
12 if (len > 256) {
13 errno = EIO;
14 return -1;
15 }
16
17 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
18
19 while (len) {
20 ret = getrandom(pos, len, 0);
21 if (ret < 0) {
22 if (errno == EINTR) continue;
23 else break;
24 }
25 pos += ret;
26 len -= ret;
27 ret = 0;
28 }
29
30 pthread_setcancelstate(cs, 0);
31
32 return ret;
33}
libc/musl/src/misc/gethostid.c created+6
......@@ -0,0 +1,6 @@
1#include <unistd.h>
2
3long gethostid()
4{
5 return 0;
6}
libc/musl/src/misc/getopt.c created+104
......@@ -0,0 +1,104 @@
1#include <unistd.h>
2#include <wchar.h>
3#include <string.h>
4#include <limits.h>
5#include <stdlib.h>
6#include "locale_impl.h"
7#include "stdio_impl.h"
8
9char *optarg;
10int optind=1, opterr=1, optopt, __optpos, __optreset=0;
11
12#define optpos __optpos
13weak_alias(__optreset, optreset);
14
15void __getopt_msg(const char *a, const char *b, const char *c, size_t l)
16{
17 FILE *f = stderr;
18 b = __lctrans_cur(b);
19 FLOCK(f);
20 fputs(a, f)>=0
21 && fwrite(b, strlen(b), 1, f)
22 && fwrite(c, 1, l, f)==l
23 && putc('\n', f);
24 FUNLOCK(f);
25}
26
27int getopt(int argc, char * const argv[], const char *optstring)
28{
29 int i;
30 wchar_t c, d;
31 int k, l;
32 char *optchar;
33
34 if (!optind || __optreset) {
35 __optreset = 0;
36 __optpos = 0;
37 optind = 1;
38 }
39
40 if (optind >= argc || !argv[optind])
41 return -1;
42
43 if (argv[optind][0] != '-') {
44 if (optstring[0] == '-') {
45 optarg = argv[optind++];
46 return 1;
47 }
48 return -1;
49 }
50
51 if (!argv[optind][1])
52 return -1;
53
54 if (argv[optind][1] == '-' && !argv[optind][2])
55 return optind++, -1;
56
57 if (!optpos) optpos++;
58 if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) {
59 k = 1;
60 c = 0xfffd; /* replacement char */
61 }
62 optchar = argv[optind]+optpos;
63 optpos += k;
64
65 if (!argv[optind][optpos]) {
66 optind++;
67 optpos = 0;
68 }
69
70 if (optstring[0] == '-' || optstring[0] == '+')
71 optstring++;
72
73 i = 0;
74 d = 0;
75 do {
76 l = mbtowc(&d, optstring+i, MB_LEN_MAX);
77 if (l>0) i+=l; else i++;
78 } while (l && d != c);
79
80 if (d != c || c == ':') {
81 optopt = c;
82 if (optstring[0] != ':' && opterr)
83 __getopt_msg(argv[0], ": unrecognized option: ", optchar, k);
84 return '?';
85 }
86 if (optstring[i] == ':') {
87 optarg = 0;
88 if (optstring[i+1] != ':' || optpos) {
89 optarg = argv[optind++] + optpos;
90 optpos = 0;
91 }
92 if (optind > argc) {
93 optopt = c;
94 if (optstring[0] == ':') return ':';
95 if (opterr) __getopt_msg(argv[0],
96 ": option requires an argument: ",
97 optchar, k);
98 return '?';
99 }
100 }
101 return c;
102}
103
104weak_alias(getopt, __posix_getopt);
libc/musl/src/misc/getopt_long.c created+148
......@@ -0,0 +1,148 @@
1#define _GNU_SOURCE
2#include <stddef.h>
3#include <stdlib.h>
4#include <limits.h>
5#include <getopt.h>
6#include <stdio.h>
7#include <string.h>
8#include "stdio_impl.h"
9
10extern int __optpos, __optreset;
11
12static void permute(char *const *argv, int dest, int src)
13{
14 char **av = (char **)argv;
15 char *tmp = av[src];
16 int i;
17 for (i=src; i>dest; i--)
18 av[i] = av[i-1];
19 av[dest] = tmp;
20}
21
22static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly);
23
24static int __getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
25{
26 int ret, skipped, resumed;
27 if (!optind || __optreset) {
28 __optreset = 0;
29 __optpos = 0;
30 optind = 1;
31 }
32 if (optind >= argc || !argv[optind]) return -1;
33 skipped = optind;
34 if (optstring[0] != '+' && optstring[0] != '-') {
35 int i;
36 for (i=optind; ; i++) {
37 if (i >= argc || !argv[i]) return -1;
38 if (argv[i][0] == '-' && argv[i][1]) break;
39 }
40 optind = i;
41 }
42 resumed = optind;
43 ret = __getopt_long_core(argc, argv, optstring, longopts, idx, longonly);
44 if (resumed > skipped) {
45 int i, cnt = optind-resumed;
46 for (i=0; i<cnt; i++)
47 permute(argv, skipped, optind-1);
48 optind = skipped + cnt;
49 }
50 return ret;
51}
52
53static int __getopt_long_core(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx, int longonly)
54{
55 optarg = 0;
56 if (longopts && argv[optind][0] == '-' &&
57 ((longonly && argv[optind][1] && argv[optind][1] != '-') ||
58 (argv[optind][1] == '-' && argv[optind][2])))
59 {
60 int colon = optstring[optstring[0]=='+'||optstring[0]=='-']==':';
61 int i, cnt, match;
62 char *arg, *opt, *start = argv[optind]+1;
63 for (cnt=i=0; longopts[i].name; i++) {
64 const char *name = longopts[i].name;
65 opt = start;
66 if (*opt == '-') opt++;
67 while (*opt && *opt != '=' && *opt == *name)
68 name++, opt++;
69 if (*opt && *opt != '=') continue;
70 arg = opt;
71 match = i;
72 if (!*name) {
73 cnt = 1;
74 break;
75 }
76 cnt++;
77 }
78 if (cnt==1 && longonly && arg-start == mblen(start, MB_LEN_MAX)) {
79 int l = arg-start;
80 for (i=0; optstring[i]; i++) {
81 int j;
82 for (j=0; j<l && start[j]==optstring[i+j]; j++);
83 if (j==l) {
84 cnt++;
85 break;
86 }
87 }
88 }
89 if (cnt==1) {
90 i = match;
91 opt = arg;
92 optind++;
93 if (*opt == '=') {
94 if (!longopts[i].has_arg) {
95 optopt = longopts[i].val;
96 if (colon || !opterr)
97 return '?';
98 __getopt_msg(argv[0],
99 ": option does not take an argument: ",
100 longopts[i].name,
101 strlen(longopts[i].name));
102 return '?';
103 }
104 optarg = opt+1;
105 } else if (longopts[i].has_arg == required_argument) {
106 if (!(optarg = argv[optind])) {
107 optopt = longopts[i].val;
108 if (colon) return ':';
109 if (!opterr) return '?';
110 __getopt_msg(argv[0],
111 ": option requires an argument: ",
112 longopts[i].name,
113 strlen(longopts[i].name));
114 return '?';
115 }
116 optind++;
117 }
118 if (idx) *idx = i;
119 if (longopts[i].flag) {
120 *longopts[i].flag = longopts[i].val;
121 return 0;
122 }
123 return longopts[i].val;
124 }
125 if (argv[optind][1] == '-') {
126 optopt = 0;
127 if (!colon && opterr)
128 __getopt_msg(argv[0], cnt ?
129 ": option is ambiguous: " :
130 ": unrecognized option: ",
131 argv[optind]+2,
132 strlen(argv[optind]+2));
133 optind++;
134 return '?';
135 }
136 }
137 return getopt(argc, argv, optstring);
138}
139
140int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
141{
142 return __getopt_long(argc, argv, optstring, longopts, idx, 0);
143}
144
145int getopt_long_only(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *idx)
146{
147 return __getopt_long(argc, argv, optstring, longopts, idx, 1);
148}
libc/musl/src/misc/getpriority.c created+9
......@@ -0,0 +1,9 @@
1#include <sys/resource.h>
2#include "syscall.h"
3
4int getpriority(int which, id_t who)
5{
6 int ret = syscall(SYS_getpriority, which, who);
7 if (ret < 0) return ret;
8 return 20-ret;
9}
libc/musl/src/misc/getresgid.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4
5int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
6{
7 return syscall(SYS_getresgid, rgid, egid, sgid);
8}
libc/musl/src/misc/getresuid.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4
5int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
6{
7 return syscall(SYS_getresuid, ruid, euid, suid);
8}
libc/musl/src/misc/getrlimit.c created+26
......@@ -0,0 +1,26 @@
1#include <sys/resource.h>
2#include <errno.h>
3#include "syscall.h"
4
5#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
6
7int getrlimit(int resource, struct rlimit *rlim)
8{
9 unsigned long k_rlim[2];
10 int ret = syscall(SYS_prlimit64, 0, resource, 0, rlim);
11 if (!ret) {
12 FIX(rlim->rlim_cur);
13 FIX(rlim->rlim_max);
14 }
15 if (!ret || errno != ENOSYS)
16 return ret;
17 if (syscall(SYS_getrlimit, resource, k_rlim) < 0)
18 return -1;
19 rlim->rlim_cur = k_rlim[0] == -1UL ? RLIM_INFINITY : k_rlim[0];
20 rlim->rlim_max = k_rlim[1] == -1UL ? RLIM_INFINITY : k_rlim[1];
21 FIX(rlim->rlim_cur);
22 FIX(rlim->rlim_max);
23 return 0;
24}
25
26weak_alias(getrlimit, getrlimit64);
libc/musl/src/misc/getrusage.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/resource.h>
2#include "syscall.h"
3
4int getrusage(int who, struct rusage *ru)
5{
6 return syscall(SYS_getrusage, who, ru);
7}
libc/musl/src/misc/getsubopt.c created+23
......@@ -0,0 +1,23 @@
1#include <stdlib.h>
2#include <string.h>
3
4int getsubopt(char **opt, char *const *keys, char **val)
5{
6 char *s = *opt;
7 int i;
8
9 *val = NULL;
10 *opt = strchr(s, ',');
11 if (*opt) *(*opt)++ = 0;
12 else *opt = s + strlen(s);
13
14 for (i=0; keys[i]; i++) {
15 size_t l = strlen(keys[i]);
16 if (strncmp(keys[i], s, l)) continue;
17 if (s[l] == '=')
18 *val = s + l + 1;
19 else if (s[l]) continue;
20 return i;
21 }
22 return -1;
23}
libc/musl/src/misc/initgroups.c created+11
......@@ -0,0 +1,11 @@
1#define _GNU_SOURCE
2#include <grp.h>
3#include <limits.h>
4
5int initgroups(const char *user, gid_t gid)
6{
7 gid_t groups[NGROUPS_MAX];
8 int count = NGROUPS_MAX;
9 if (getgrouplist(user, gid, groups, &count) < 0) return -1;
10 return setgroups(count, groups);
11}
libc/musl/src/misc/ioctl.c created+13
......@@ -0,0 +1,13 @@
1#include <sys/ioctl.h>
2#include <stdarg.h>
3#include "syscall.h"
4
5int ioctl(int fd, int req, ...)
6{
7 void *arg;
8 va_list ap;
9 va_start(ap, req);
10 arg = va_arg(ap, void *);
11 va_end(ap);
12 return syscall(SYS_ioctl, fd, req, arg);
13}
libc/musl/src/misc/issetugid.c created+8
......@@ -0,0 +1,8 @@
1#define _BSD_SOURCE
2#include <unistd.h>
3#include "libc.h"
4
5int issetugid(void)
6{
7 return libc.secure;
8}
libc/musl/src/misc/lockf.c created+32
......@@ -0,0 +1,32 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include <errno.h>
4
5int lockf(int fd, int op, off_t size)
6{
7 struct flock l = {
8 .l_type = F_WRLCK,
9 .l_whence = SEEK_CUR,
10 .l_len = size,
11 };
12 switch (op) {
13 case F_TEST:
14 l.l_type = F_RDLCK;
15 if (fcntl(fd, F_GETLK, &l) < 0)
16 return -1;
17 if (l.l_type == F_UNLCK || l.l_pid == getpid())
18 return 0;
19 errno = EACCES;
20 return -1;
21 case F_ULOCK:
22 l.l_type = F_UNLCK;
23 case F_TLOCK:
24 return fcntl(fd, F_SETLK, &l);
25 case F_LOCK:
26 return fcntl(fd, F_SETLKW, &l);
27 }
28 errno = EINVAL;
29 return -1;
30}
31
32weak_alias(lockf, lockf64);
libc/musl/src/misc/login_tty.c created+14
......@@ -0,0 +1,14 @@
1#include <utmp.h>
2#include <sys/ioctl.h>
3#include <unistd.h>
4
5int login_tty(int fd)
6{
7 setsid();
8 if (ioctl(fd, TIOCSCTTY, (char *)0)) return -1;
9 dup2(fd, 0);
10 dup2(fd, 1);
11 dup2(fd, 2);
12 if (fd>2) close(fd);
13 return 0;
14}
libc/musl/src/misc/mntent.c created+77
......@@ -0,0 +1,77 @@
1#include <stdio.h>
2#include <string.h>
3#include <mntent.h>
4#include <errno.h>
5
6static char *internal_buf;
7static size_t internal_bufsize;
8
9#define SENTINEL (char *)&internal_buf
10
11FILE *setmntent(const char *name, const char *mode)
12{
13 return fopen(name, mode);
14}
15
16int endmntent(FILE *f)
17{
18 if (f) fclose(f);
19 return 1;
20}
21
22struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen)
23{
24 int cnt, n[8], use_internal = (linebuf == SENTINEL);
25
26 mnt->mnt_freq = 0;
27 mnt->mnt_passno = 0;
28
29 do {
30 if (use_internal) {
31 getline(&internal_buf, &internal_bufsize, f);
32 linebuf = internal_buf;
33 } else {
34 fgets(linebuf, buflen, f);
35 }
36 if (feof(f) || ferror(f)) return 0;
37 if (!strchr(linebuf, '\n')) {
38 fscanf(f, "%*[^\n]%*[\n]");
39 errno = ERANGE;
40 return 0;
41 }
42 cnt = sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d",
43 n, n+1, n+2, n+3, n+4, n+5, n+6, n+7,
44 &mnt->mnt_freq, &mnt->mnt_passno);
45 } while (cnt < 2 || linebuf[n[0]] == '#');
46
47 linebuf[n[1]] = 0;
48 linebuf[n[3]] = 0;
49 linebuf[n[5]] = 0;
50 linebuf[n[7]] = 0;
51
52 mnt->mnt_fsname = linebuf+n[0];
53 mnt->mnt_dir = linebuf+n[2];
54 mnt->mnt_type = linebuf+n[4];
55 mnt->mnt_opts = linebuf+n[6];
56
57 return mnt;
58}
59
60struct mntent *getmntent(FILE *f)
61{
62 static struct mntent mnt;
63 return getmntent_r(f, &mnt, SENTINEL, 0);
64}
65
66int addmntent(FILE *f, const struct mntent *mnt)
67{
68 if (fseek(f, 0, SEEK_END)) return 1;
69 return fprintf(f, "%s\t%s\t%s\t%s\t%d\t%d\n",
70 mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, mnt->mnt_opts,
71 mnt->mnt_freq, mnt->mnt_passno) < 0;
72}
73
74char *hasmntopt(const struct mntent *mnt, const char *opt)
75{
76 return strstr(mnt->mnt_opts, opt);
77}
libc/musl/src/misc/nftw.c created+128
......@@ -0,0 +1,128 @@
1#include <ftw.h>
2#include <dirent.h>
3#include <sys/stat.h>
4#include <errno.h>
5#include <unistd.h>
6#include <string.h>
7#include <limits.h>
8#include <pthread.h>
9
10struct history
11{
12 struct history *chain;
13 dev_t dev;
14 ino_t ino;
15 int level;
16 int base;
17};
18
19#undef dirfd
20#define dirfd(d) (*(int *)d)
21
22static int do_nftw(char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags, struct history *h)
23{
24 size_t l = strlen(path), j = l && path[l-1]=='/' ? l-1 : l;
25 struct stat st;
26 struct history new;
27 int type;
28 int r;
29 struct FTW lev;
30
31 if ((flags & FTW_PHYS) ? lstat(path, &st) : stat(path, &st) < 0) {
32 if (!(flags & FTW_PHYS) && errno==ENOENT && !lstat(path, &st))
33 type = FTW_SLN;
34 else if (errno != EACCES) return -1;
35 else type = FTW_NS;
36 } else if (S_ISDIR(st.st_mode)) {
37 if (access(path, R_OK) < 0) type = FTW_DNR;
38 else if (flags & FTW_DEPTH) type = FTW_DP;
39 else type = FTW_D;
40 } else if (S_ISLNK(st.st_mode)) {
41 if (flags & FTW_PHYS) type = FTW_SL;
42 else type = FTW_SLN;
43 } else {
44 type = FTW_F;
45 }
46
47 if ((flags & FTW_MOUNT) && h && st.st_dev != h->dev)
48 return 0;
49
50 new.chain = h;
51 new.dev = st.st_dev;
52 new.ino = st.st_ino;
53 new.level = h ? h->level+1 : 0;
54 new.base = j+1;
55
56 lev.level = new.level;
57 if (h) {
58 lev.base = h->base;
59 } else {
60 size_t k;
61 for (k=j; k && path[k]=='/'; k--);
62 for (; k && path[k-1]!='/'; k--);
63 lev.base = k;
64 }
65
66 if (!(flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))
67 return r;
68
69 for (; h; h = h->chain)
70 if (h->dev == st.st_dev && h->ino == st.st_ino)
71 return 0;
72
73 if ((type == FTW_D || type == FTW_DP) && fd_limit) {
74 DIR *d = opendir(path);
75 if (d) {
76 struct dirent *de;
77 while ((de = readdir(d))) {
78 if (de->d_name[0] == '.'
79 && (!de->d_name[1]
80 || (de->d_name[1]=='.'
81 && !de->d_name[2]))) continue;
82 if (strlen(de->d_name) >= PATH_MAX-l) {
83 errno = ENAMETOOLONG;
84 closedir(d);
85 return -1;
86 }
87 path[j]='/';
88 strcpy(path+j+1, de->d_name);
89 if ((r=do_nftw(path, fn, fd_limit-1, flags, &new))) {
90 closedir(d);
91 return r;
92 }
93 }
94 closedir(d);
95 } else if (errno != EACCES) {
96 return -1;
97 }
98 }
99
100 path[l] = 0;
101 if ((flags & FTW_DEPTH) && (r=fn(path, &st, type, &lev)))
102 return r;
103
104 return 0;
105}
106
107int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, struct FTW *), int fd_limit, int flags)
108{
109 int r, cs;
110 size_t l;
111 char pathbuf[PATH_MAX+1];
112
113 if (fd_limit <= 0) return 0;
114
115 l = strlen(path);
116 if (l > PATH_MAX) {
117 errno = ENAMETOOLONG;
118 return -1;
119 }
120 memcpy(pathbuf, path, l+1);
121
122 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
123 r = do_nftw(pathbuf, fn, fd_limit, flags, NULL);
124 pthread_setcancelstate(cs, 0);
125 return r;
126}
127
128weak_alias(nftw, nftw64);
libc/musl/src/misc/openpty.c created+40
......@@ -0,0 +1,40 @@
1#include <stdlib.h>
2#include <fcntl.h>
3#include <unistd.h>
4#include <pty.h>
5#include <stdio.h>
6#include <pthread.h>
7
8/* Nonstandard, but vastly superior to the standard functions */
9
10int openpty(int *pm, int *ps, char *name, const struct termios *tio, const struct winsize *ws)
11{
12 int m, s, n=0, cs;
13 char buf[20];
14
15 m = open("/dev/ptmx", O_RDWR|O_NOCTTY);
16 if (m < 0) return -1;
17
18 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
19
20 if (ioctl(m, TIOCSPTLCK, &n) || ioctl (m, TIOCGPTN, &n))
21 goto fail;
22
23 if (!name) name = buf;
24 snprintf(name, sizeof buf, "/dev/pts/%d", n);
25 if ((s = open(name, O_RDWR|O_NOCTTY)) < 0)
26 goto fail;
27
28 if (tio) tcsetattr(s, TCSANOW, tio);
29 if (ws) ioctl(s, TIOCSWINSZ, ws);
30
31 *pm = m;
32 *ps = s;
33
34 pthread_setcancelstate(cs, 0);
35 return 0;
36fail:
37 close(m);
38 pthread_setcancelstate(cs, 0);
39 return -1;
40}
libc/musl/src/misc/ptsname.c created+13
......@@ -0,0 +1,13 @@
1#include <stdlib.h>
2#include <errno.h>
3
4char *ptsname(int fd)
5{
6 static char buf[9 + sizeof(int)*3 + 1];
7 int err = __ptsname_r(fd, buf, sizeof buf);
8 if (err) {
9 errno = err;
10 return 0;
11 }
12 return buf;
13}
libc/musl/src/misc/pty.c created+33
......@@ -0,0 +1,33 @@
1#include <stdlib.h>
2#include <sys/ioctl.h>
3#include <stdio.h>
4#include <fcntl.h>
5#include <errno.h>
6#include "syscall.h"
7
8int posix_openpt(int flags)
9{
10 return open("/dev/ptmx", flags);
11}
12
13int grantpt(int fd)
14{
15 return 0;
16}
17
18int unlockpt(int fd)
19{
20 int unlock = 0;
21 return ioctl(fd, TIOCSPTLCK, &unlock);
22}
23
24int __ptsname_r(int fd, char *buf, size_t len)
25{
26 int pty, err;
27 if (!buf) len = 0;
28 if ((err = __syscall(SYS_ioctl, fd, TIOCGPTN, &pty))) return -err;
29 if (snprintf(buf, len, "/dev/pts/%d", pty) >= len) return ERANGE;
30 return 0;
31}
32
33weak_alias(__ptsname_r, ptsname_r);
libc/musl/src/misc/realpath.c created+43
......@@ -0,0 +1,43 @@
1#include <stdlib.h>
2#include <limits.h>
3#include <sys/stat.h>
4#include <fcntl.h>
5#include <errno.h>
6#include <unistd.h>
7#include <string.h>
8#include "syscall.h"
9
10char *realpath(const char *restrict filename, char *restrict resolved)
11{
12 int fd;
13 ssize_t r;
14 struct stat st1, st2;
15 char buf[15+3*sizeof(int)];
16 char tmp[PATH_MAX];
17
18 if (!filename) {
19 errno = EINVAL;
20 return 0;
21 }
22
23 fd = sys_open(filename, O_PATH|O_NONBLOCK|O_CLOEXEC);
24 if (fd < 0) return 0;
25 __procfdname(buf, fd);
26
27 r = readlink(buf, tmp, sizeof tmp - 1);
28 if (r < 0) goto err;
29 tmp[r] = 0;
30
31 fstat(fd, &st1);
32 r = stat(tmp, &st2);
33 if (r<0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
34 if (!r) errno = ELOOP;
35 goto err;
36 }
37
38 __syscall(SYS_close, fd);
39 return resolved ? strcpy(resolved, tmp) : strdup(tmp);
40err:
41 __syscall(SYS_close, fd);
42 return 0;
43}
libc/musl/src/misc/setdomainname.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4
5int setdomainname(const char *name, size_t len)
6{
7 return syscall(SYS_setdomainname, name, len);
8}
libc/musl/src/misc/setpriority.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/resource.h>
2#include "syscall.h"
3
4int setpriority(int which, id_t who, int prio)
5{
6 return syscall(SYS_setpriority, which, who, prio);
7}
libc/musl/src/misc/setrlimit.c created+50
......@@ -0,0 +1,50 @@
1#include <sys/resource.h>
2#include <errno.h>
3#include "syscall.h"
4#include "libc.h"
5
6#define MIN(a, b) ((a)<(b) ? (a) : (b))
7#define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
8
9static int __setrlimit(int resource, const struct rlimit *rlim)
10{
11 unsigned long k_rlim[2];
12 struct rlimit tmp;
13 if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
14 tmp = *rlim;
15 FIX(tmp.rlim_cur);
16 FIX(tmp.rlim_max);
17 rlim = &tmp;
18 }
19 int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
20 if (ret != -ENOSYS) return ret;
21 k_rlim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY));
22 k_rlim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY));
23 return __syscall(SYS_setrlimit, resource, k_rlim);
24}
25
26struct ctx {
27 const struct rlimit *rlim;
28 int res;
29 int err;
30};
31
32static void do_setrlimit(void *p)
33{
34 struct ctx *c = p;
35 if (c->err>0) return;
36 c->err = -__setrlimit(c->res, c->rlim);
37}
38
39int setrlimit(int resource, const struct rlimit *rlim)
40{
41 struct ctx c = { .res = resource, .rlim = rlim, .err = -1 };
42 __synccall(do_setrlimit, &c);
43 if (c.err) {
44 if (c.err>0) errno = c.err;
45 return -1;
46 }
47 return 0;
48}
49
50weak_alias(setrlimit, setrlimit64);
libc/musl/src/misc/syscall.c created+21
......@@ -0,0 +1,21 @@
1#define _BSD_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4#include <stdarg.h>
5
6#undef syscall
7
8long syscall(long n, ...)
9{
10 va_list ap;
11 syscall_arg_t a,b,c,d,e,f;
12 va_start(ap, n);
13 a=va_arg(ap, syscall_arg_t);
14 b=va_arg(ap, syscall_arg_t);
15 c=va_arg(ap, syscall_arg_t);
16 d=va_arg(ap, syscall_arg_t);
17 e=va_arg(ap, syscall_arg_t);
18 f=va_arg(ap, syscall_arg_t);
19 va_end(ap);
20 return __syscall_ret(__syscall(n,a,b,c,d,e,f));
21}
libc/musl/src/misc/syslog.c created+144
......@@ -0,0 +1,144 @@
1#include <stdarg.h>
2#include <sys/socket.h>
3#include <stdio.h>
4#include <unistd.h>
5#include <syslog.h>
6#include <time.h>
7#include <signal.h>
8#include <string.h>
9#include <pthread.h>
10#include <errno.h>
11#include <fcntl.h>
12#include "lock.h"
13
14static volatile int lock[1];
15static char log_ident[32];
16static int log_opt;
17static int log_facility = LOG_USER;
18static int log_mask = 0xff;
19static int log_fd = -1;
20
21int setlogmask(int maskpri)
22{
23 LOCK(lock);
24 int ret = log_mask;
25 if (maskpri) log_mask = maskpri;
26 UNLOCK(lock);
27 return ret;
28}
29
30static const struct {
31 short sun_family;
32 char sun_path[9];
33} log_addr = {
34 AF_UNIX,
35 "/dev/log"
36};
37
38void closelog(void)
39{
40 int cs;
41 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
42 LOCK(lock);
43 close(log_fd);
44 log_fd = -1;
45 UNLOCK(lock);
46 pthread_setcancelstate(cs, 0);
47}
48
49static void __openlog()
50{
51 log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
52 if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr);
53}
54
55void openlog(const char *ident, int opt, int facility)
56{
57 int cs;
58 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
59 LOCK(lock);
60
61 if (ident) {
62 size_t n = strnlen(ident, sizeof log_ident - 1);
63 memcpy(log_ident, ident, n);
64 log_ident[n] = 0;
65 } else {
66 log_ident[0] = 0;
67 }
68 log_opt = opt;
69 log_facility = facility;
70
71 if ((opt & LOG_NDELAY) && log_fd<0) __openlog();
72
73 UNLOCK(lock);
74 pthread_setcancelstate(cs, 0);
75}
76
77static int is_lost_conn(int e)
78{
79 return e==ECONNREFUSED || e==ECONNRESET || e==ENOTCONN || e==EPIPE;
80}
81
82static void _vsyslog(int priority, const char *message, va_list ap)
83{
84 char timebuf[16];
85 time_t now;
86 struct tm tm;
87 char buf[1024];
88 int errno_save = errno;
89 int pid;
90 int l, l2;
91 int hlen;
92 int fd;
93
94 if (log_fd < 0) __openlog();
95
96 if (!(priority & LOG_FACMASK)) priority |= log_facility;
97
98 now = time(NULL);
99 gmtime_r(&now, &tm);
100 strftime(timebuf, sizeof timebuf, "%b %e %T", &tm);
101
102 pid = (log_opt & LOG_PID) ? getpid() : 0;
103 l = snprintf(buf, sizeof buf, "<%d>%s %n%s%s%.0d%s: ",
104 priority, timebuf, &hlen, log_ident, "["+!pid, pid, "]"+!pid);
105 errno = errno_save;
106 l2 = vsnprintf(buf+l, sizeof buf - l, message, ap);
107 if (l2 >= 0) {
108 if (l2 >= sizeof buf - l) l = sizeof buf - 1;
109 else l += l2;
110 if (buf[l-1] != '\n') buf[l++] = '\n';
111 if (send(log_fd, buf, l, 0) < 0 && (!is_lost_conn(errno)
112 || connect(log_fd, (void *)&log_addr, sizeof log_addr) < 0
113 || send(log_fd, buf, l, 0) < 0)
114 && (log_opt & LOG_CONS)) {
115 fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
116 if (fd >= 0) {
117 dprintf(fd, "%.*s", l-hlen, buf+hlen);
118 close(fd);
119 }
120 }
121 if (log_opt & LOG_PERROR) dprintf(2, "%.*s", l-hlen, buf+hlen);
122 }
123}
124
125static void __vsyslog(int priority, const char *message, va_list ap)
126{
127 int cs;
128 if (!(log_mask & LOG_MASK(priority&7)) || (priority&~0x3ff)) return;
129 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
130 LOCK(lock);
131 _vsyslog(priority, message, ap);
132 UNLOCK(lock);
133 pthread_setcancelstate(cs, 0);
134}
135
136void syslog(int priority, const char *message, ...)
137{
138 va_list ap;
139 va_start(ap, message);
140 __vsyslog(priority, message, ap);
141 va_end(ap);
142}
143
144weak_alias(__vsyslog, vsyslog);
libc/musl/src/misc/uname.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/utsname.h>
2#include "syscall.h"
3
4int uname(struct utsname *uts)
5{
6 return syscall(SYS_uname, uts);
7}
libc/musl/src/misc/wordexp.c created+187
......@@ -0,0 +1,187 @@
1#include <wordexp.h>
2#include <unistd.h>
3#include <stdio.h>
4#include <string.h>
5#include <limits.h>
6#include <stdint.h>
7#include <stdlib.h>
8#include <sys/wait.h>
9#include <signal.h>
10#include <errno.h>
11#include <fcntl.h>
12#include "pthread_impl.h"
13
14static void reap(pid_t pid)
15{
16 int status;
17 while (waitpid(pid, &status, 0) < 0 && errno == EINTR);
18}
19
20static char *getword(FILE *f)
21{
22 char *s = 0;
23 return getdelim(&s, (size_t [1]){0}, 0, f) < 0 ? 0 : s;
24}
25
26static int do_wordexp(const char *s, wordexp_t *we, int flags)
27{
28 size_t i, l;
29 int sq=0, dq=0;
30 size_t np=0;
31 char *w, **tmp;
32 char *redir = (flags & WRDE_SHOWERR) ? "" : "2>/dev/null";
33 int err = 0;
34 FILE *f;
35 size_t wc = 0;
36 char **wv = 0;
37 int p[2];
38 pid_t pid;
39 sigset_t set;
40
41 if (flags & WRDE_REUSE) wordfree(we);
42
43 if (flags & WRDE_NOCMD) for (i=0; s[i]; i++) switch (s[i]) {
44 case '\\':
45 if (!sq && !s[++i]) return WRDE_SYNTAX;
46 break;
47 case '\'':
48 if (!dq) sq^=1;
49 break;
50 case '"':
51 if (!sq) dq^=1;
52 break;
53 case '(':
54 if (np) {
55 np++;
56 break;
57 }
58 case ')':
59 if (np) {
60 np--;
61 break;
62 }
63 case '\n':
64 case '|':
65 case '&':
66 case ';':
67 case '<':
68 case '>':
69 case '{':
70 case '}':
71 if (!(sq|dq|np)) return WRDE_BADCHAR;
72 break;
73 case '$':
74 if (sq) break;
75 if (s[i+1]=='(' && s[i+2]=='(') {
76 i += 2;
77 np += 2;
78 break;
79 } else if (s[i+1] != '(') break;
80 case '`':
81 if (sq) break;
82 return WRDE_CMDSUB;
83 }
84
85 if (flags & WRDE_APPEND) {
86 wc = we->we_wordc;
87 wv = we->we_wordv;
88 }
89
90 i = wc;
91 if (flags & WRDE_DOOFFS) {
92 if (we->we_offs > SIZE_MAX/sizeof(void *)/4)
93 goto nospace;
94 i += we->we_offs;
95 } else {
96 we->we_offs = 0;
97 }
98
99 if (pipe2(p, O_CLOEXEC) < 0) goto nospace;
100 __block_all_sigs(&set);
101 pid = fork();
102 __restore_sigs(&set);
103 if (pid < 0) {
104 close(p[0]);
105 close(p[1]);
106 goto nospace;
107 }
108 if (!pid) {
109 if (p[1] == 1) fcntl(1, F_SETFD, 0);
110 else dup2(p[1], 1);
111 execl("/bin/sh", "sh", "-c",
112 "eval \"printf %s\\\\\\\\0 x $1 $2\"",
113 "sh", s, redir, (char *)0);
114 _exit(1);
115 }
116 close(p[1]);
117
118 f = fdopen(p[0], "r");
119 if (!f) {
120 close(p[0]);
121 kill(pid, SIGKILL);
122 reap(pid);
123 goto nospace;
124 }
125
126 l = wv ? i+1 : 0;
127
128 free(getword(f));
129 if (feof(f)) {
130 fclose(f);
131 reap(pid);
132 return WRDE_SYNTAX;
133 }
134
135 while ((w = getword(f))) {
136 if (i+1 >= l) {
137 l += l/2+10;
138 tmp = realloc(wv, l*sizeof(char *));
139 if (!tmp) break;
140 wv = tmp;
141 }
142 wv[i++] = w;
143 wv[i] = 0;
144 }
145 if (!feof(f)) err = WRDE_NOSPACE;
146
147 fclose(f);
148 reap(pid);
149
150 if (!wv) wv = calloc(i+1, sizeof *wv);
151
152 we->we_wordv = wv;
153 we->we_wordc = i;
154
155 if (flags & WRDE_DOOFFS) {
156 if (wv) for (i=we->we_offs; i; i--)
157 we->we_wordv[i-1] = 0;
158 we->we_wordc -= we->we_offs;
159 }
160 return err;
161
162nospace:
163 if (!(flags & WRDE_APPEND)) {
164 we->we_wordc = 0;
165 we->we_wordv = 0;
166 }
167 return WRDE_NOSPACE;
168}
169
170int wordexp(const char *restrict s, wordexp_t *restrict we, int flags)
171{
172 int r, cs;
173 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
174 r = do_wordexp(s, we, flags);
175 pthread_setcancelstate(cs, 0);
176 return r;
177}
178
179void wordfree(wordexp_t *we)
180{
181 size_t i;
182 if (!we->we_wordv) return;
183 for (i=0; i<we->we_wordc; i++) free(we->we_wordv[we->we_offs+i]);
184 free(we->we_wordv);
185 we->we_wordv = 0;
186 we->we_wordc = 0;
187}
libc/musl/src/mman/madvise.c created+9
......@@ -0,0 +1,9 @@
1#include <sys/mman.h>
2#include "syscall.h"
3
4int __madvise(void *addr, size_t len, int advice)
5{
6 return syscall(SYS_madvise, addr, len, advice);
7}
8
9weak_alias(__madvise, madvise);
libc/musl/src/mman/mincore.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <sys/mman.h>
3#include "syscall.h"
4
5int mincore (void *addr, size_t len, unsigned char *vec)
6{
7 return syscall(SYS_mincore, addr, len, vec);
8}
libc/musl/src/mman/mlock.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/mman.h>
2#include "syscall.h"
3
4int mlock(const void *addr, size_t len)
5{
6 return syscall(SYS_mlock, addr, len);
7}
libc/musl/src/mman/mlockall.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/mman.h>
2#include "syscall.h"
3
4int mlockall(int flags)
5{
6 return syscall(SYS_mlockall, flags);
7}
libc/musl/src/mman/mmap.c created+41
......@@ -0,0 +1,41 @@
1#include <unistd.h>
2#include <sys/mman.h>
3#include <errno.h>
4#include <stdint.h>
5#include <limits.h>
6#include "syscall.h"
7
8static void dummy(void) { }
9weak_alias(dummy, __vm_wait);
10
11#define UNIT SYSCALL_MMAP2_UNIT
12#define OFF_MASK ((-0x2000ULL << (8*sizeof(syscall_arg_t)-1)) | (UNIT-1))
13
14void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
15{
16 long ret;
17 if (off & OFF_MASK) {
18 errno = EINVAL;
19 return MAP_FAILED;
20 }
21 if (len >= PTRDIFF_MAX) {
22 errno = ENOMEM;
23 return MAP_FAILED;
24 }
25 if (flags & MAP_FIXED) {
26 __vm_wait();
27 }
28#ifdef SYS_mmap2
29 ret = __syscall(SYS_mmap2, start, len, prot, flags, fd, off/UNIT);
30#else
31 ret = __syscall(SYS_mmap, start, len, prot, flags, fd, off);
32#endif
33 /* Fixup incorrect EPERM from kernel. */
34 if (ret == -EPERM && !start && (flags&MAP_ANON) && !(flags&MAP_FIXED))
35 ret = -ENOMEM;
36 return (void *)__syscall_ret(ret);
37}
38
39weak_alias(__mmap, mmap);
40
41weak_alias(mmap, mmap64);
libc/musl/src/mman/mprotect.c created+13
......@@ -0,0 +1,13 @@
1#include <sys/mman.h>
2#include "libc.h"
3#include "syscall.h"
4
5int __mprotect(void *addr, size_t len, int prot)
6{
7 size_t start, end;
8 start = (size_t)addr & -PAGE_SIZE;
9 end = (size_t)((char *)addr + len + PAGE_SIZE-1) & -PAGE_SIZE;
10 return syscall(SYS_mprotect, start, end-start, prot);
11}
12
13weak_alias(__mprotect, mprotect);
libc/musl/src/mman/mremap.c created+32
......@@ -0,0 +1,32 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include <sys/mman.h>
4#include <errno.h>
5#include <stdint.h>
6#include <stdarg.h>
7#include "syscall.h"
8
9static void dummy(void) { }
10weak_alias(dummy, __vm_wait);
11
12void *__mremap(void *old_addr, size_t old_len, size_t new_len, int flags, ...)
13{
14 va_list ap;
15 void *new_addr = 0;
16
17 if (new_len >= PTRDIFF_MAX) {
18 errno = ENOMEM;
19 return MAP_FAILED;
20 }
21
22 if (flags & MREMAP_FIXED) {
23 __vm_wait();
24 va_start(ap, flags);
25 new_addr = va_arg(ap, void *);
26 va_end(ap);
27 }
28
29 return (void *)syscall(SYS_mremap, old_addr, old_len, new_len, flags, new_addr);
30}
31
32weak_alias(__mremap, mremap);
libc/musl/src/mman/msync.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/mman.h>
2#include "syscall.h"
3
4int msync(void *start, size_t len, int flags)
5{
6 return syscall_cp(SYS_msync, start, len, flags);
7}
libc/musl/src/mman/munlock.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/mman.h>
2#include "syscall.h"
3
4int munlock(const void *addr, size_t len)
5{
6 return syscall(SYS_munlock, addr, len);
7}
libc/musl/src/mman/munlockall.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/mman.h>
2#include "syscall.h"
3
4int munlockall(void)
5{
6 return syscall(SYS_munlockall);
7}
libc/musl/src/mman/munmap.c created+13
......@@ -0,0 +1,13 @@
1#include <sys/mman.h>
2#include "syscall.h"
3
4static void dummy(void) { }
5weak_alias(dummy, __vm_wait);
6
7int __munmap(void *start, size_t len)
8{
9 __vm_wait();
10 return syscall(SYS_munmap, start, len);
11}
12
13weak_alias(__munmap, munmap);
libc/musl/src/mman/posix_madvise.c created+9
......@@ -0,0 +1,9 @@
1#define _GNU_SOURCE
2#include <sys/mman.h>
3#include "syscall.h"
4
5int posix_madvise(void *addr, size_t len, int advice)
6{
7 if (advice == MADV_DONTNEED) return 0;
8 return -__syscall(SYS_madvise, addr, len, advice);
9}
libc/musl/src/mman/shm_open.c created+43
......@@ -0,0 +1,43 @@
1#include <sys/mman.h>
2#include <errno.h>
3#include <fcntl.h>
4#include <unistd.h>
5#include <string.h>
6#include <limits.h>
7#include <pthread.h>
8
9char *__shm_mapname(const char *name, char *buf)
10{
11 char *p;
12 while (*name == '/') name++;
13 if (*(p = __strchrnul(name, '/')) || p==name ||
14 (p-name <= 2 && name[0]=='.' && p[-1]=='.')) {
15 errno = EINVAL;
16 return 0;
17 }
18 if (p-name > NAME_MAX) {
19 errno = ENAMETOOLONG;
20 return 0;
21 }
22 memcpy(buf, "/dev/shm/", 9);
23 memcpy(buf+9, name, p-name+1);
24 return buf;
25}
26
27int shm_open(const char *name, int flag, mode_t mode)
28{
29 int cs;
30 char buf[NAME_MAX+10];
31 if (!(name = __shm_mapname(name, buf))) return -1;
32 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
33 int fd = open(name, flag|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK, mode);
34 pthread_setcancelstate(cs, 0);
35 return fd;
36}
37
38int shm_unlink(const char *name)
39{
40 char buf[NAME_MAX+10];
41 if (!(name = __shm_mapname(name, buf))) return -1;
42 return unlink(name);
43}
libc/musl/src/mq/mq_close.c created+7
......@@ -0,0 +1,7 @@
1#include <mqueue.h>
2#include "syscall.h"
3
4int mq_close(mqd_t mqd)
5{
6 return syscall(SYS_close, mqd);
7}
libc/musl/src/mq/mq_getattr.c created+7
......@@ -0,0 +1,7 @@
1#include <mqueue.h>
2#include "syscall.h"
3
4int mq_getattr(mqd_t mqd, struct mq_attr *attr)
5{
6 return mq_setattr(mqd, 0, attr);
7}
libc/musl/src/mq/mq_notify.c created+73
......@@ -0,0 +1,73 @@
1#include <mqueue.h>
2#include <pthread.h>
3#include <errno.h>
4#include <sys/socket.h>
5#include <signal.h>
6#include <unistd.h>
7#include "syscall.h"
8
9struct args {
10 pthread_barrier_t barrier;
11 int sock;
12 const struct sigevent *sev;
13};
14
15static void *start(void *p)
16{
17 struct args *args = p;
18 char buf[32];
19 ssize_t n;
20 int s = args->sock;
21 void (*func)(union sigval) = args->sev->sigev_notify_function;
22 union sigval val = args->sev->sigev_value;
23
24 pthread_barrier_wait(&args->barrier);
25 n = recv(s, buf, sizeof(buf), MSG_NOSIGNAL|MSG_WAITALL);
26 close(s);
27 if (n==sizeof buf && buf[sizeof buf - 1] == 1)
28 func(val);
29 return 0;
30}
31
32int mq_notify(mqd_t mqd, const struct sigevent *sev)
33{
34 struct args args = { .sev = sev };
35 pthread_attr_t attr;
36 pthread_t td;
37 int s;
38 struct sigevent sev2;
39 static const char zeros[32];
40
41 if (!sev || sev->sigev_notify != SIGEV_THREAD)
42 return syscall(SYS_mq_notify, mqd, sev);
43
44 s = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, 0);
45 if (s < 0) return -1;
46 args.sock = s;
47
48 if (sev->sigev_notify_attributes) attr = *sev->sigev_notify_attributes;
49 else pthread_attr_init(&attr);
50 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
51 pthread_barrier_init(&args.barrier, 0, 2);
52
53 if (pthread_create(&td, &attr, start, &args)) {
54 __syscall(SYS_close, s);
55 errno = EAGAIN;
56 return -1;
57 }
58
59 pthread_barrier_wait(&args.barrier);
60 pthread_barrier_destroy(&args.barrier);
61
62 sev2.sigev_notify = SIGEV_THREAD;
63 sev2.sigev_signo = s;
64 sev2.sigev_value.sival_ptr = (void *)&zeros;
65
66 if (syscall(SYS_mq_notify, mqd, &sev2) < 0) {
67 pthread_cancel(td);
68 __syscall(SYS_close, s);
69 return -1;
70 }
71
72 return 0;
73}
libc/musl/src/mq/mq_open.c created+19
......@@ -0,0 +1,19 @@
1#include <mqueue.h>
2#include <fcntl.h>
3#include <stdarg.h>
4#include "syscall.h"
5
6mqd_t mq_open(const char *name, int flags, ...)
7{
8 mode_t mode = 0;
9 struct mq_attr *attr = 0;
10 if (*name == '/') name++;
11 if (flags & O_CREAT) {
12 va_list ap;
13 va_start(ap, flags);
14 mode = va_arg(ap, mode_t);
15 attr = va_arg(ap, struct mq_attr *);
16 va_end(ap);
17 }
18 return syscall(SYS_mq_open, name, flags, mode, attr);
19}
libc/musl/src/mq/mq_receive.c created+6
......@@ -0,0 +1,6 @@
1#include <mqueue.h>
2
3ssize_t mq_receive(mqd_t mqd, char *msg, size_t len, unsigned *prio)
4{
5 return mq_timedreceive(mqd, msg, len, prio, 0);
6}
libc/musl/src/mq/mq_send.c created+6
......@@ -0,0 +1,6 @@
1#include <mqueue.h>
2
3int mq_send(mqd_t mqd, const char *msg, size_t len, unsigned prio)
4{
5 return mq_timedsend(mqd, msg, len, prio, 0);
6}
libc/musl/src/mq/mq_setattr.c created+7
......@@ -0,0 +1,7 @@
1#include <mqueue.h>
2#include "syscall.h"
3
4int mq_setattr(mqd_t mqd, const struct mq_attr *restrict new, struct mq_attr *restrict old)
5{
6 return syscall(SYS_mq_getsetattr, mqd, new, old);
7}
libc/musl/src/mq/mq_timedreceive.c created+7
......@@ -0,0 +1,7 @@
1#include <mqueue.h>
2#include "syscall.h"
3
4ssize_t mq_timedreceive(mqd_t mqd, char *restrict msg, size_t len, unsigned *restrict prio, const struct timespec *restrict at)
5{
6 return syscall_cp(SYS_mq_timedreceive, mqd, msg, len, prio, at);
7}
libc/musl/src/mq/mq_timedsend.c created+7
......@@ -0,0 +1,7 @@
1#include <mqueue.h>
2#include "syscall.h"
3
4int mq_timedsend(mqd_t mqd, const char *msg, size_t len, unsigned prio, const struct timespec *at)
5{
6 return syscall_cp(SYS_mq_timedsend, mqd, msg, len, prio, at);
7}
libc/musl/src/mq/mq_unlink.c created+16
......@@ -0,0 +1,16 @@
1#include <mqueue.h>
2#include <errno.h>
3#include "syscall.h"
4
5int mq_unlink(const char *name)
6{
7 int ret;
8 if (*name == '/') name++;
9 ret = __syscall(SYS_mq_unlink, name);
10 if (ret < 0) {
11 if (ret == -EPERM) ret = -EACCES;
12 errno = -ret;
13 return -1;
14 }
15 return ret;
16}
libc/musl/src/multibyte/btowc.c created+10
......@@ -0,0 +1,10 @@
1#include <stdio.h>
2#include <wchar.h>
3#include <stdlib.h>
4#include "internal.h"
5
6wint_t btowc(int c)
7{
8 int b = (unsigned char)c;
9 return b<128U ? b : (MB_CUR_MAX==1 && c!=EOF) ? CODEUNIT(c) : WEOF;
10}
libc/musl/src/multibyte/c16rtomb.c created+35
......@@ -0,0 +1,35 @@
1#include <uchar.h>
2#include <errno.h>
3#include <wchar.h>
4
5size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps)
6{
7 static unsigned internal_state;
8 if (!ps) ps = (void *)&internal_state;
9 unsigned *x = (unsigned *)ps;
10 wchar_t wc;
11
12 if (!s) {
13 if (*x) goto ilseq;
14 return 1;
15 }
16
17 if (!*x && c16 - 0xd800u < 0x400) {
18 *x = c16 - 0xd7c0 << 10;
19 return 0;
20 }
21
22 if (*x) {
23 if (c16 - 0xdc00u >= 0x400) goto ilseq;
24 else wc = *x + c16 - 0xdc00;
25 *x = 0;
26 } else {
27 wc = c16;
28 }
29 return wcrtomb(s, wc, 0);
30
31ilseq:
32 *x = 0;
33 errno = EILSEQ;
34 return -1;
35}
libc/musl/src/multibyte/c32rtomb.c created+7
......@@ -0,0 +1,7 @@
1#include <uchar.h>
2#include <wchar.h>
3
4size_t c32rtomb(char *restrict s, char32_t c32, mbstate_t *restrict ps)
5{
6 return wcrtomb(s, c32, ps);
7}
libc/musl/src/multibyte/internal.c created+26
......@@ -0,0 +1,26 @@
1#include "internal.h"
2
3#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) )
4#define D(x) C((x+16))
5#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \
6 x==0xd ? R(0x80,0xa0) : \
7 R(0x80,0xc0) ) \
8 | ( R(0x80,0xc0) >> 6 ) \
9 | x )
10#define F(x) ( ( x>=5 ? 0 : \
11 x==0 ? R(0x90,0xc0) : \
12 x==4 ? R(0x80,0x90) : \
13 R(0x80,0xc0) ) \
14 | ( R(0x80,0xc0) >> 6 ) \
15 | ( R(0x80,0xc0) >> 12 ) \
16 | x )
17
18const uint32_t bittab[] = {
19 C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7),
20 C(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf),
21 D(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7),
22 D(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf),
23 E(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7),
24 E(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf),
25 F(0x0),F(0x1),F(0x2),F(0x3),F(0x4)
26};
libc/musl/src/multibyte/internal.h created+24
......@@ -0,0 +1,24 @@
1#define bittab __fsmu8
2
3#include <stdint.h>
4#include <features.h>
5
6extern hidden const uint32_t bittab[];
7
8/* Upper 6 state bits are a negative integer offset to bound-check next byte */
9/* equivalent to: ( (b-0x80) | (b+offset) ) & ~0x3f */
10#define OOB(c,b) (((((b)>>3)-0x10)|(((b)>>3)+((int32_t)(c)>>26))) & ~7)
11
12/* Interval [a,b). Either a must be 80 or b must be c0, lower 3 bits clear. */
13#define R(a,b) ((uint32_t)((a==0x80 ? 0x40u-b : 0u-a) << 23))
14#define FAILSTATE R(0x80,0x80)
15
16#define SA 0xc2u
17#define SB 0xf4u
18
19/* Arbitrary encoding for representing code units instead of characters. */
20#define CODEUNIT(c) (0xdfff & (signed char)(c))
21#define IS_CODEUNIT(c) ((unsigned)(c)-0xdf80 < 0x80)
22
23/* Get inline definition of MB_CUR_MAX. */
24#include "locale_impl.h"
libc/musl/src/multibyte/mblen.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3int mblen(const char *s, size_t n)
4{
5 return mbtowc(0, s, n);
6}
libc/musl/src/multibyte/mbrlen.c created+7
......@@ -0,0 +1,7 @@
1#include <wchar.h>
2
3size_t mbrlen(const char *restrict s, size_t n, mbstate_t *restrict st)
4{
5 static unsigned internal;
6 return mbrtowc(0, s, n, st ? st : (mbstate_t *)&internal);
7}
libc/musl/src/multibyte/mbrtoc16.c created+30
......@@ -0,0 +1,30 @@
1#include <uchar.h>
2#include <wchar.h>
3
4size_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps)
5{
6 static unsigned internal_state;
7 if (!ps) ps = (void *)&internal_state;
8 unsigned *pending = (unsigned *)ps;
9
10 if (!s) return mbrtoc16(0, "", 1, ps);
11
12 /* mbrtowc states for partial UTF-8 characters have the high bit set;
13 * we use nonzero states without high bit for pending surrogates. */
14 if ((int)*pending > 0) {
15 if (pc16) *pc16 = *pending;
16 *pending = 0;
17 return -3;
18 }
19
20 wchar_t wc;
21 size_t ret = mbrtowc(&wc, s, n, ps);
22 if (ret <= 4) {
23 if (wc >= 0x10000) {
24 *pending = (wc & 0x3ff) + 0xdc00;
25 wc = 0xd7c0 + (wc >> 10);
26 }
27 if (pc16) *pc16 = wc;
28 }
29 return ret;
30}
libc/musl/src/multibyte/mbrtoc32.c created+13
......@@ -0,0 +1,13 @@
1#include <uchar.h>
2#include <wchar.h>
3
4size_t mbrtoc32(char32_t *restrict pc32, const char *restrict s, size_t n, mbstate_t *restrict ps)
5{
6 static unsigned internal_state;
7 if (!ps) ps = (void *)&internal_state;
8 if (!s) return mbrtoc32(0, "", 1, ps);
9 wchar_t wc;
10 size_t ret = mbrtowc(&wc, s, n, ps);
11 if (ret <= 4 && pc32) *pc32 = wc;
12 return ret;
13}
libc/musl/src/multibyte/mbrtowc.c created+51
......@@ -0,0 +1,51 @@
1#include <stdlib.h>
2#include <wchar.h>
3#include <errno.h>
4#include "internal.h"
5
6size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st)
7{
8 static unsigned internal_state;
9 unsigned c;
10 const unsigned char *s = (const void *)src;
11 const unsigned N = n;
12 wchar_t dummy;
13
14 if (!st) st = (void *)&internal_state;
15 c = *(unsigned *)st;
16
17 if (!s) {
18 if (c) goto ilseq;
19 return 0;
20 } else if (!wc) wc = &dummy;
21
22 if (!n) return -2;
23 if (!c) {
24 if (*s < 0x80) return !!(*wc = *s);
25 if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
26 if (*s-SA > SB-SA) goto ilseq;
27 c = bittab[*s++-SA]; n--;
28 }
29
30 if (n) {
31 if (OOB(c,*s)) goto ilseq;
32loop:
33 c = c<<6 | *s++-0x80; n--;
34 if (!(c&(1U<<31))) {
35 *(unsigned *)st = 0;
36 *wc = c;
37 return N-n;
38 }
39 if (n) {
40 if (*s-0x80u >= 0x40) goto ilseq;
41 goto loop;
42 }
43 }
44
45 *(unsigned *)st = c;
46 return -2;
47ilseq:
48 *(unsigned *)st = 0;
49 errno = EILSEQ;
50 return -1;
51}
libc/musl/src/multibyte/mbsinit.c created+6
......@@ -0,0 +1,6 @@
1#include <wchar.h>
2
3int mbsinit(const mbstate_t *st)
4{
5 return !st || !*(unsigned *)st;
6}
libc/musl/src/multibyte/mbsnrtowcs.c created+55
......@@ -0,0 +1,55 @@
1#include <wchar.h>
2
3size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st)
4{
5 size_t l, cnt=0, n2;
6 wchar_t *ws, wbuf[256];
7 const char *s = *src;
8 const char *tmp_s;
9
10 if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;
11 else ws = wcs;
12
13 /* making sure output buffer size is at most n/4 will ensure
14 * that mbsrtowcs never reads more than n input bytes. thus
15 * we can use mbsrtowcs as long as it's practical.. */
16
17 while ( s && wn && ( (n2=n/4)>=wn || n2>32 ) ) {
18 if (n2>=wn) n2=wn;
19 tmp_s = s;
20 l = mbsrtowcs(ws, &s, n2, st);
21 if (!(l+1)) {
22 cnt = l;
23 wn = 0;
24 break;
25 }
26 if (ws != wbuf) {
27 ws += l;
28 wn -= l;
29 }
30 n = s ? n - (s - tmp_s) : 0;
31 cnt += l;
32 }
33 if (s) while (wn && n) {
34 l = mbrtowc(ws, s, n, st);
35 if (l+2<=2) {
36 if (!(l+1)) {
37 cnt = l;
38 break;
39 }
40 if (!l) {
41 s = 0;
42 break;
43 }
44 /* have to roll back partial character */
45 *(unsigned *)st = 0;
46 break;
47 }
48 s += l; n -= l;
49 /* safe - this loop runs fewer than sizeof(wbuf)/8 times */
50 ws++; wn--;
51 cnt++;
52 }
53 if (wcs) *src = s;
54 return cnt;
55}
libc/musl/src/multibyte/mbsrtowcs.c created+114
......@@ -0,0 +1,114 @@
1#include <stdint.h>
2#include <wchar.h>
3#include <errno.h>
4#include <string.h>
5#include <stdlib.h>
6#include "internal.h"
7
8size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st)
9{
10 const unsigned char *s = (const void *)*src;
11 size_t wn0 = wn;
12 unsigned c = 0;
13
14 if (st && (c = *(unsigned *)st)) {
15 if (ws) {
16 *(unsigned *)st = 0;
17 goto resume;
18 } else {
19 goto resume0;
20 }
21 }
22
23 if (MB_CUR_MAX==1) {
24 if (!ws) return strlen((const char *)s);
25 for (;;) {
26 if (!wn) {
27 *src = (const void *)s;
28 return wn0;
29 }
30 if (!*s) break;
31 c = *s++;
32 *ws++ = CODEUNIT(c);
33 wn--;
34 }
35 *ws = 0;
36 *src = 0;
37 return wn0-wn;
38 }
39
40 if (!ws) for (;;) {
41 if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
42 while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
43 s += 4;
44 wn -= 4;
45 }
46 }
47 if (*s-1u < 0x7f) {
48 s++;
49 wn--;
50 continue;
51 }
52 if (*s-SA > SB-SA) break;
53 c = bittab[*s++-SA];
54resume0:
55 if (OOB(c,*s)) { s--; break; }
56 s++;
57 if (c&(1U<<25)) {
58 if (*s-0x80u >= 0x40) { s-=2; break; }
59 s++;
60 if (c&(1U<<19)) {
61 if (*s-0x80u >= 0x40) { s-=3; break; }
62 s++;
63 }
64 }
65 wn--;
66 c = 0;
67 } else for (;;) {
68 if (!wn) {
69 *src = (const void *)s;
70 return wn0;
71 }
72 if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
73 while (wn>=5 && !(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
74 *ws++ = *s++;
75 *ws++ = *s++;
76 *ws++ = *s++;
77 *ws++ = *s++;
78 wn -= 4;
79 }
80 }
81 if (*s-1u < 0x7f) {
82 *ws++ = *s++;
83 wn--;
84 continue;
85 }
86 if (*s-SA > SB-SA) break;
87 c = bittab[*s++-SA];
88resume:
89 if (OOB(c,*s)) { s--; break; }
90 c = (c<<6) | *s++-0x80;
91 if (c&(1U<<31)) {
92 if (*s-0x80u >= 0x40) { s-=2; break; }
93 c = (c<<6) | *s++-0x80;
94 if (c&(1U<<31)) {
95 if (*s-0x80u >= 0x40) { s-=3; break; }
96 c = (c<<6) | *s++-0x80;
97 }
98 }
99 *ws++ = c;
100 wn--;
101 c = 0;
102 }
103
104 if (!c && !*s) {
105 if (ws) {
106 *ws = 0;
107 *src = 0;
108 }
109 return wn0-wn;
110 }
111 errno = EILSEQ;
112 if (ws) *src = (const void *)s;
113 return -1;
114}
libc/musl/src/multibyte/mbstowcs.c created+7
......@@ -0,0 +1,7 @@
1#include <stdlib.h>
2#include <wchar.h>
3
4size_t mbstowcs(wchar_t *restrict ws, const char *restrict s, size_t wn)
5{
6 return mbsrtowcs(ws, (void*)&s, wn, 0);
7}
libc/musl/src/multibyte/mbtowc.c created+47
......@@ -0,0 +1,47 @@
1#include <stdlib.h>
2#include <wchar.h>
3#include <errno.h>
4#include "internal.h"
5
6int mbtowc(wchar_t *restrict wc, const char *restrict src, size_t n)
7{
8 unsigned c;
9 const unsigned char *s = (const void *)src;
10 wchar_t dummy;
11
12 if (!s) return 0;
13 if (!n) goto ilseq;
14 if (!wc) wc = &dummy;
15
16 if (*s < 0x80) return !!(*wc = *s);
17 if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
18 if (*s-SA > SB-SA) goto ilseq;
19 c = bittab[*s++-SA];
20
21 /* Avoid excessive checks against n: If shifting the state n-1
22 * times does not clear the high bit, then the value of n is
23 * insufficient to read a character */
24 if (n<4 && ((c<<(6*n-6)) & (1U<<31))) goto ilseq;
25
26 if (OOB(c,*s)) goto ilseq;
27 c = c<<6 | *s++-0x80;
28 if (!(c&(1U<<31))) {
29 *wc = c;
30 return 2;
31 }
32
33 if (*s-0x80u >= 0x40) goto ilseq;
34 c = c<<6 | *s++-0x80;
35 if (!(c&(1U<<31))) {
36 *wc = c;
37 return 3;
38 }
39
40 if (*s-0x80u >= 0x40) goto ilseq;
41 *wc = c<<6 | *s++-0x80;
42 return 4;
43
44ilseq:
45 errno = EILSEQ;
46 return -1;
47}
libc/musl/src/multibyte/wcrtomb.c created+37
......@@ -0,0 +1,37 @@
1#include <stdlib.h>
2#include <wchar.h>
3#include <errno.h>
4#include "internal.h"
5
6size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st)
7{
8 if (!s) return 1;
9 if ((unsigned)wc < 0x80) {
10 *s = wc;
11 return 1;
12 } else if (MB_CUR_MAX == 1) {
13 if (!IS_CODEUNIT(wc)) {
14 errno = EILSEQ;
15 return -1;
16 }
17 *s = wc;
18 return 1;
19 } else if ((unsigned)wc < 0x800) {
20 *s++ = 0xc0 | (wc>>6);
21 *s = 0x80 | (wc&0x3f);
22 return 2;
23 } else if ((unsigned)wc < 0xd800 || (unsigned)wc-0xe000 < 0x2000) {
24 *s++ = 0xe0 | (wc>>12);
25 *s++ = 0x80 | ((wc>>6)&0x3f);
26 *s = 0x80 | (wc&0x3f);
27 return 3;
28 } else if ((unsigned)wc-0x10000 < 0x100000) {
29 *s++ = 0xf0 | (wc>>18);
30 *s++ = 0x80 | ((wc>>12)&0x3f);
31 *s++ = 0x80 | ((wc>>6)&0x3f);
32 *s = 0x80 | (wc&0x3f);
33 return 4;
34 }
35 errno = EILSEQ;
36 return -1;
37}
libc/musl/src/multibyte/wcsnrtombs.c created+43
......@@ -0,0 +1,43 @@
1#include <wchar.h>
2
3size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
4{
5 size_t l, cnt=0, n2;
6 char *s, buf[256];
7 const wchar_t *ws = *wcs;
8 const wchar_t *tmp_ws;
9
10 if (!dst) s = buf, n = sizeof buf;
11 else s = dst;
12
13 while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
14 if (n2>=n) n2=n;
15 tmp_ws = ws;
16 l = wcsrtombs(s, &ws, n2, 0);
17 if (!(l+1)) {
18 cnt = l;
19 n = 0;
20 break;
21 }
22 if (s != buf) {
23 s += l;
24 n -= l;
25 }
26 wn = ws ? wn - (ws - tmp_ws) : 0;
27 cnt += l;
28 }
29 if (ws) while (n && wn) {
30 l = wcrtomb(s, *ws, 0);
31 if ((l+1)<=1) {
32 if (!l) ws = 0;
33 else cnt = l;
34 break;
35 }
36 ws++; wn--;
37 /* safe - this loop runs fewer than sizeof(buf) times */
38 s+=l; n-=l;
39 cnt += l;
40 }
41 if (dst) *wcs = ws;
42 return cnt;
43}
libc/musl/src/multibyte/wcsrtombs.c created+55
......@@ -0,0 +1,55 @@
1#include <wchar.h>
2
3size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
4{
5 const wchar_t *ws2;
6 char buf[4];
7 size_t N = n, l;
8 if (!s) {
9 for (n=0, ws2=*ws; *ws2; ws2++) {
10 if (*ws2 >= 0x80u) {
11 l = wcrtomb(buf, *ws2, 0);
12 if (!(l+1)) return -1;
13 n += l;
14 } else n++;
15 }
16 return n;
17 }
18 while (n>=4) {
19 if (**ws-1u >= 0x7fu) {
20 if (!**ws) {
21 *s = 0;
22 *ws = 0;
23 return N-n;
24 }
25 l = wcrtomb(s, **ws, 0);
26 if (!(l+1)) return -1;
27 s += l;
28 n -= l;
29 } else {
30 *s++ = **ws;
31 n--;
32 }
33 (*ws)++;
34 }
35 while (n) {
36 if (**ws-1u >= 0x7fu) {
37 if (!**ws) {
38 *s = 0;
39 *ws = 0;
40 return N-n;
41 }
42 l = wcrtomb(buf, **ws, 0);
43 if (!(l+1)) return -1;
44 if (l>n) return N-n;
45 wcrtomb(s, **ws, 0);
46 s += l;
47 n -= l;
48 } else {
49 *s++ = **ws;
50 n--;
51 }
52 (*ws)++;
53 }
54 return N;
55}
libc/musl/src/multibyte/wcstombs.c created+7
......@@ -0,0 +1,7 @@
1#include <stdlib.h>
2#include <wchar.h>
3
4size_t wcstombs(char *restrict s, const wchar_t *restrict ws, size_t n)
5{
6 return wcsrtombs(s, &(const wchar_t *){ws}, n, 0);
7}
libc/musl/src/multibyte/wctob.c created+11
......@@ -0,0 +1,11 @@
1#include <wchar.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include "internal.h"
5
6int wctob(wint_t c)
7{
8 if (c < 128U) return c;
9 if (MB_CUR_MAX==1 && IS_CODEUNIT(c)) return (unsigned char)c;
10 return EOF;
11}
libc/musl/src/multibyte/wctomb.c created+8
......@@ -0,0 +1,8 @@
1#include <stdlib.h>
2#include <wchar.h>
3
4int wctomb(char *s, wchar_t wc)
5{
6 if (!s) return 0;
7 return wcrtomb(s, wc, 0);
8}
libc/musl/src/network/accept.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4int accept(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
5{
6 return socketcall_cp(accept, fd, addr, len, 0, 0, 0);
7}
libc/musl/src/network/accept4.c created+19
......@@ -0,0 +1,19 @@
1#define _GNU_SOURCE
2#include <sys/socket.h>
3#include <errno.h>
4#include <fcntl.h>
5#include "syscall.h"
6
7int accept4(int fd, struct sockaddr *restrict addr, socklen_t *restrict len, int flg)
8{
9 if (!flg) return accept(fd, addr, len);
10 int ret = socketcall_cp(accept4, fd, addr, len, flg, 0, 0);
11 if (ret>=0 || (errno != ENOSYS && errno != EINVAL)) return ret;
12 ret = accept(fd, addr, len);
13 if (ret<0) return ret;
14 if (flg & SOCK_CLOEXEC)
15 __syscall(SYS_fcntl, ret, F_SETFD, FD_CLOEXEC);
16 if (flg & SOCK_NONBLOCK)
17 __syscall(SYS_fcntl, ret, F_SETFL, O_NONBLOCK);
18 return ret;
19}
libc/musl/src/network/bind.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4int bind(int fd, const struct sockaddr *addr, socklen_t len)
5{
6 return socketcall(bind, fd, addr, len, 0, 0, 0);
7}
libc/musl/src/network/connect.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4int connect(int fd, const struct sockaddr *addr, socklen_t len)
5{
6 return socketcall_cp(connect, fd, addr, len, 0, 0, 0);
7}
libc/musl/src/network/dn_comp.c created+107
......@@ -0,0 +1,107 @@
1#include <string.h>
2#include <resolv.h>
3
4/* RFC 1035 message compression */
5
6/* label start offsets of a compressed domain name s */
7static int getoffs(short *offs, const unsigned char *base, const unsigned char *s)
8{
9 int i=0;
10 for (;;) {
11 while (*s & 0xc0) {
12 if ((*s & 0xc0) != 0xc0) return 0;
13 s = base + ((s[0]&0x3f)<<8 | s[1]);
14 }
15 if (!*s) return i;
16 if (s-base >= 0x4000) return 0;
17 offs[i++] = s-base;
18 s += *s + 1;
19 }
20}
21
22/* label lengths of an ascii domain name s */
23static int getlens(unsigned char *lens, const char *s, int l)
24{
25 int i=0,j=0,k=0;
26 for (;;) {
27 for (; j<l && s[j]!='.'; j++);
28 if (j-k-1u > 62) return 0;
29 lens[i++] = j-k;
30 if (j==l) return i;
31 k = ++j;
32 }
33}
34
35/* longest suffix match of an ascii domain with a compressed domain name dn */
36static int match(int *offset, const unsigned char *base, const unsigned char *dn,
37 const char *end, const unsigned char *lens, int nlen)
38{
39 int l, o, m=0;
40 short offs[128];
41 int noff = getoffs(offs, base, dn);
42 if (!noff) return 0;
43 for (;;) {
44 l = lens[--nlen];
45 o = offs[--noff];
46 end -= l;
47 if (l != base[o] || memcmp(base+o+1, end, l))
48 return m;
49 *offset = o;
50 m += l;
51 if (nlen) m++;
52 if (!nlen || !noff) return m;
53 end--;
54 }
55}
56
57int dn_comp(const char *src, unsigned char *dst, int space, unsigned char **dnptrs, unsigned char **lastdnptr)
58{
59 int i, j, n, m=0, offset, bestlen=0, bestoff;
60 unsigned char lens[127];
61 unsigned char **p;
62 const char *end;
63 size_t l = strnlen(src, 255);
64 if (l && src[l-1] == '.') l--;
65 if (l>253 || space<=0) return -1;
66 if (!l) {
67 *dst = 0;
68 return 1;
69 }
70 end = src+l;
71 n = getlens(lens, src, l);
72 if (!n) return -1;
73
74 p = dnptrs;
75 if (p && *p) for (p++; *p; p++) {
76 m = match(&offset, *dnptrs, *p, end, lens, n);
77 if (m > bestlen) {
78 bestlen = m;
79 bestoff = offset;
80 if (m == l)
81 break;
82 }
83 }
84
85 /* encode unmatched part */
86 if (space < l-bestlen+2+(bestlen-1 < l-1)) return -1;
87 memcpy(dst+1, src, l-bestlen);
88 for (i=j=0; i<l-bestlen; i+=lens[j++]+1)
89 dst[i] = lens[j];
90
91 /* add tail */
92 if (bestlen) {
93 dst[i++] = 0xc0 | bestoff>>8;
94 dst[i++] = bestoff;
95 } else
96 dst[i++] = 0;
97
98 /* save dst pointer */
99 if (i>2 && lastdnptr && dnptrs && *dnptrs) {
100 while (*p) p++;
101 if (p+1 < lastdnptr) {
102 *p++ = dst;
103 *p=0;
104 }
105 }
106 return i;
107}
libc/musl/src/network/dn_expand.c created+33
......@@ -0,0 +1,33 @@
1#include <resolv.h>
2
3int __dn_expand(const unsigned char *base, const unsigned char *end, const unsigned char *src, char *dest, int space)
4{
5 const unsigned char *p = src;
6 char *dend, *dbegin = dest;
7 int len = -1, i, j;
8 if (p==end || space <= 0) return -1;
9 dend = dest + (space > 254 ? 254 : space);
10 /* detect reference loop using an iteration counter */
11 for (i=0; i < end-base; i+=2) {
12 /* loop invariants: p<end, dest<dend */
13 if (*p & 0xc0) {
14 if (p+1==end) return -1;
15 j = ((p[0] & 0x3f) << 8) | p[1];
16 if (len < 0) len = p+2-src;
17 if (j >= end-base) return -1;
18 p = base+j;
19 } else if (*p) {
20 if (dest != dbegin) *dest++ = '.';
21 j = *p++;
22 if (j >= end-p || j >= dend-dest) return -1;
23 while (j--) *dest++ = *p++;
24 } else {
25 *dest = 0;
26 if (len < 0) len = p+1-src;
27 return len;
28 }
29 }
30 return -1;
31}
32
33weak_alias(__dn_expand, dn_expand);
libc/musl/src/network/dn_skipname.c created+12
......@@ -0,0 +1,12 @@
1#include <resolv.h>
2
3int dn_skipname(const unsigned char *s, const unsigned char *end)
4{
5 const unsigned char *p;
6 for (p=s; p<end; p++)
7 if (!*p) return p-s+1;
8 else if (*p>=192)
9 if (p+1<end) return p-s+2;
10 else break;
11 return -1;
12}
libc/musl/src/network/dns_parse.c created+33
......@@ -0,0 +1,33 @@
1#include <string.h>
2#include "lookup.h"
3
4int __dns_parse(const unsigned char *r, int rlen, int (*callback)(void *, int, const void *, int, const void *), void *ctx)
5{
6 int qdcount, ancount;
7 const unsigned char *p;
8 int len;
9
10 if (rlen<12) return -1;
11 if ((r[3]&15)) return 0;
12 p = r+12;
13 qdcount = r[4]*256 + r[5];
14 ancount = r[6]*256 + r[7];
15 if (qdcount+ancount > 64) return -1;
16 while (qdcount--) {
17 while (p-r < rlen && *p-1U < 127) p++;
18 if (*p>193 || (*p==193 && p[1]>254) || p>r+rlen-6)
19 return -1;
20 p += 5 + !!*p;
21 }
22 while (ancount--) {
23 while (p-r < rlen && *p-1U < 127) p++;
24 if (*p>193 || (*p==193 && p[1]>254) || p>r+rlen-6)
25 return -1;
26 p += 1 + !!*p;
27 len = p[8]*256 + p[9];
28 if (p+len > r+rlen) return -1;
29 if (callback(ctx, p[1], p+10, len, r) < 0) return -1;
30 p += 10 + len;
31 }
32 return 0;
33}
libc/musl/src/network/ent.c created+22
......@@ -0,0 +1,22 @@
1#include <netdb.h>
2
3void sethostent(int x)
4{
5}
6
7struct hostent *gethostent()
8{
9 return 0;
10}
11
12struct netent *getnetent()
13{
14 return 0;
15}
16
17void endhostent(void)
18{
19}
20
21weak_alias(sethostent, setnetent);
22weak_alias(endhostent, endnetent);
libc/musl/src/network/ether.c created+58
......@@ -0,0 +1,58 @@
1#include <stdlib.h>
2#include <netinet/ether.h>
3#include <stdio.h>
4
5struct ether_addr *ether_aton_r (const char *x, struct ether_addr *p_a)
6{
7 struct ether_addr a;
8 char *y;
9 for (int ii = 0; ii < 6; ii++) {
10 unsigned long int n;
11 if (ii != 0) {
12 if (x[0] != ':') return 0; /* bad format */
13 else x++;
14 }
15 n = strtoul (x, &y, 16);
16 x = y;
17 if (n > 0xFF) return 0; /* bad byte */
18 a.ether_addr_octet[ii] = n;
19 }
20 if (x[0] != 0) return 0; /* bad format */
21 *p_a = a;
22 return p_a;
23}
24
25struct ether_addr *ether_aton (const char *x)
26{
27 static struct ether_addr a;
28 return ether_aton_r (x, &a);
29}
30
31char *ether_ntoa_r (const struct ether_addr *p_a, char *x) {
32 char *y;
33 y = x;
34 for (int ii = 0; ii < 6; ii++) {
35 x += sprintf (x, ii == 0 ? "%.2X" : ":%.2X", p_a->ether_addr_octet[ii]);
36 }
37 return y;
38}
39
40char *ether_ntoa (const struct ether_addr *p_a) {
41 static char x[18];
42 return ether_ntoa_r (p_a, x);
43}
44
45int ether_line(const char *l, struct ether_addr *e, char *hostname)
46{
47 return -1;
48}
49
50int ether_ntohost(char *hostname, const struct ether_addr *e)
51{
52 return -1;
53}
54
55int ether_hostton(const char *hostname, struct ether_addr *e)
56{
57 return -1;
58}
libc/musl/src/network/freeaddrinfo.c created+16
......@@ -0,0 +1,16 @@
1#include <stdlib.h>
2#include <stddef.h>
3#include <netdb.h>
4#include "lookup.h"
5#include "lock.h"
6
7void freeaddrinfo(struct addrinfo *p)
8{
9 size_t cnt;
10 for (cnt=1; p->ai_next; cnt++, p=p->ai_next);
11 struct aibuf *b = (void *)((char *)p - offsetof(struct aibuf, ai));
12 b -= b->slot;
13 LOCK(b->lock);
14 if (!(b->ref -= cnt)) free(b);
15 else UNLOCK(b->lock);
16}
libc/musl/src/network/gai_strerror.c created+25
......@@ -0,0 +1,25 @@
1#include <netdb.h>
2#include "locale_impl.h"
3
4static const char msgs[] =
5 "Invalid flags\0"
6 "Name does not resolve\0"
7 "Try again\0"
8 "Non-recoverable error\0"
9 "Unknown error\0"
10 "Unrecognized address family or invalid length\0"
11 "Unrecognized socket type\0"
12 "Unrecognized service\0"
13 "Unknown error\0"
14 "Out of memory\0"
15 "System error\0"
16 "Overflow\0"
17 "\0Unknown error";
18
19const char *gai_strerror(int ecode)
20{
21 const char *s;
22 for (s=msgs, ecode++; ecode && *s; ecode++, s++) for (; *s; s++);
23 if (!*s) s++;
24 return LCTRANS_CUR(s);
25}
libc/musl/src/network/getaddrinfo.c created+136
......@@ -0,0 +1,136 @@
1#include <stdlib.h>
2#include <sys/socket.h>
3#include <netinet/in.h>
4#include <netdb.h>
5#include <string.h>
6#include <pthread.h>
7#include <unistd.h>
8#include <endian.h>
9#include <errno.h>
10#include "lookup.h"
11
12int getaddrinfo(const char *restrict host, const char *restrict serv, const struct addrinfo *restrict hint, struct addrinfo **restrict res)
13{
14 struct service ports[MAXSERVS];
15 struct address addrs[MAXADDRS];
16 char canon[256], *outcanon;
17 int nservs, naddrs, nais, canon_len, i, j, k;
18 int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0;
19 struct aibuf *out;
20
21 if (!host && !serv) return EAI_NONAME;
22
23 if (hint) {
24 family = hint->ai_family;
25 flags = hint->ai_flags;
26 proto = hint->ai_protocol;
27 socktype = hint->ai_socktype;
28
29 const int mask = AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST |
30 AI_V4MAPPED | AI_ALL | AI_ADDRCONFIG | AI_NUMERICSERV;
31 if ((flags & mask) != flags)
32 return EAI_BADFLAGS;
33
34 switch (family) {
35 case AF_INET:
36 case AF_INET6:
37 case AF_UNSPEC:
38 break;
39 default:
40 return EAI_FAMILY;
41 }
42 }
43
44 if (flags & AI_ADDRCONFIG) {
45 /* Define the "an address is configured" condition for address
46 * families via ability to create a socket for the family plus
47 * routability of the loopback address for the family. */
48 static const struct sockaddr_in lo4 = {
49 .sin_family = AF_INET, .sin_port = 65535,
50 .sin_addr.s_addr = __BYTE_ORDER == __BIG_ENDIAN
51 ? 0x7f000001 : 0x0100007f
52 };
53 static const struct sockaddr_in6 lo6 = {
54 .sin6_family = AF_INET6, .sin6_port = 65535,
55 .sin6_addr = IN6ADDR_LOOPBACK_INIT
56 };
57 int tf[2] = { AF_INET, AF_INET6 };
58 const void *ta[2] = { &lo4, &lo6 };
59 socklen_t tl[2] = { sizeof lo4, sizeof lo6 };
60 for (i=0; i<2; i++) {
61 if (family==tf[1-i]) continue;
62 int s = socket(tf[i], SOCK_CLOEXEC|SOCK_DGRAM,
63 IPPROTO_UDP);
64 if (s>=0) {
65 int cs;
66 pthread_setcancelstate(
67 PTHREAD_CANCEL_DISABLE, &cs);
68 int r = connect(s, ta[i], tl[i]);
69 pthread_setcancelstate(cs, 0);
70 close(s);
71 if (!r) continue;
72 }
73 switch (errno) {
74 case EADDRNOTAVAIL:
75 case EAFNOSUPPORT:
76 case EHOSTUNREACH:
77 case ENETDOWN:
78 case ENETUNREACH:
79 break;
80 default:
81 return EAI_SYSTEM;
82 }
83 if (family == tf[i]) return EAI_NONAME;
84 family = tf[1-i];
85 }
86 }
87
88 nservs = __lookup_serv(ports, serv, proto, socktype, flags);
89 if (nservs < 0) return nservs;
90
91 naddrs = __lookup_name(addrs, canon, host, family, flags);
92 if (naddrs < 0) return naddrs;
93
94 nais = nservs * naddrs;
95 canon_len = strlen(canon);
96 out = calloc(1, nais * sizeof(*out) + canon_len + 1);
97 if (!out) return EAI_MEMORY;
98
99 if (canon_len) {
100 outcanon = (void *)&out[nais];
101 memcpy(outcanon, canon, canon_len+1);
102 } else {
103 outcanon = 0;
104 }
105
106 for (k=i=0; i<naddrs; i++) for (j=0; j<nservs; j++, k++) {
107 out[k].slot = i;
108 out[k].ai = (struct addrinfo){
109 .ai_family = addrs[i].family,
110 .ai_socktype = ports[j].socktype,
111 .ai_protocol = ports[j].proto,
112 .ai_addrlen = addrs[i].family == AF_INET
113 ? sizeof(struct sockaddr_in)
114 : sizeof(struct sockaddr_in6),
115 .ai_addr = (void *)&out[k].sa,
116 .ai_canonname = outcanon,
117 .ai_next = &out[k+1].ai };
118 switch (addrs[i].family) {
119 case AF_INET:
120 out[k].sa.sin.sin_family = AF_INET;
121 out[k].sa.sin.sin_port = htons(ports[j].port);
122 memcpy(&out[k].sa.sin.sin_addr, &addrs[i].addr, 4);
123 break;
124 case AF_INET6:
125 out[k].sa.sin6.sin6_family = AF_INET6;
126 out[k].sa.sin6.sin6_port = htons(ports[j].port);
127 out[k].sa.sin6.sin6_scope_id = addrs[i].scopeid;
128 memcpy(&out[k].sa.sin6.sin6_addr, &addrs[i].addr, 16);
129 break;
130 }
131 }
132 out[0].ref = nais;
133 out[nais-1].ai.ai_next = 0;
134 *res = &out->ai;
135 return 0;
136}
libc/musl/src/network/gethostbyaddr.c created+24
......@@ -0,0 +1,24 @@
1#define _GNU_SOURCE
2
3#include <netdb.h>
4#include <errno.h>
5#include <stdlib.h>
6
7struct hostent *gethostbyaddr(const void *a, socklen_t l, int af)
8{
9 static struct hostent *h;
10 size_t size = 63;
11 struct hostent *res;
12 int err;
13 do {
14 free(h);
15 h = malloc(size+=size+1);
16 if (!h) {
17 h_errno = NO_RECOVERY;
18 return 0;
19 }
20 err = gethostbyaddr_r(a, l, af, h,
21 (void *)(h+1), size-sizeof *h, &res, &h_errno);
22 } while (err == ERANGE);
23 return err ? 0 : h;
24}
libc/musl/src/network/gethostbyaddr_r.c created+71
......@@ -0,0 +1,71 @@
1#define _GNU_SOURCE
2
3#include <sys/socket.h>
4#include <netdb.h>
5#include <string.h>
6#include <netinet/in.h>
7#include <errno.h>
8#include <inttypes.h>
9
10int gethostbyaddr_r(const void *a, socklen_t l, int af,
11 struct hostent *h, char *buf, size_t buflen,
12 struct hostent **res, int *err)
13{
14 union {
15 struct sockaddr_in sin;
16 struct sockaddr_in6 sin6;
17 } sa = { .sin.sin_family = af };
18 socklen_t sl = af==AF_INET6 ? sizeof sa.sin6 : sizeof sa.sin;
19 int i;
20
21 *res = 0;
22
23 /* Load address argument into sockaddr structure */
24 if (af==AF_INET6 && l==16) memcpy(&sa.sin6.sin6_addr, a, 16);
25 else if (af==AF_INET && l==4) memcpy(&sa.sin.sin_addr, a, 4);
26 else {
27 *err = NO_RECOVERY;
28 return EINVAL;
29 }
30
31 /* Align buffer and check for space for pointers and ip address */
32 i = (uintptr_t)buf & sizeof(char *)-1;
33 if (!i) i = sizeof(char *);
34 if (buflen <= 5*sizeof(char *)-i + l) return ERANGE;
35 buf += sizeof(char *)-i;
36 buflen -= 5*sizeof(char *)-i + l;
37
38 h->h_addr_list = (void *)buf;
39 buf += 2*sizeof(char *);
40 h->h_aliases = (void *)buf;
41 buf += 2*sizeof(char *);
42
43 h->h_addr_list[0] = buf;
44 memcpy(h->h_addr_list[0], a, l);
45 buf += l;
46 h->h_addr_list[1] = 0;
47 h->h_aliases[0] = buf;
48 h->h_aliases[1] = 0;
49
50 switch (getnameinfo((void *)&sa, sl, buf, buflen, 0, 0, 0)) {
51 case EAI_AGAIN:
52 *err = TRY_AGAIN;
53 return EAGAIN;
54 case EAI_OVERFLOW:
55 return ERANGE;
56 default:
57 case EAI_MEMORY:
58 case EAI_SYSTEM:
59 case EAI_FAIL:
60 *err = NO_RECOVERY;
61 return errno;
62 case 0:
63 break;
64 }
65
66 h->h_addrtype = af;
67 h->h_length = l;
68 h->h_name = h->h_aliases[0];
69 *res = h;
70 return 0;
71}
libc/musl/src/network/gethostbyname.c created+11
......@@ -0,0 +1,11 @@
1#define _GNU_SOURCE
2
3#include <sys/socket.h>
4#include <netdb.h>
5#include <string.h>
6#include <netinet/in.h>
7
8struct hostent *gethostbyname(const char *name)
9{
10 return gethostbyname2(name, AF_INET);
11}
libc/musl/src/network/gethostbyname2.c created+25
......@@ -0,0 +1,25 @@
1#define _GNU_SOURCE
2
3#include <sys/socket.h>
4#include <netdb.h>
5#include <errno.h>
6#include <stdlib.h>
7
8struct hostent *gethostbyname2(const char *name, int af)
9{
10 static struct hostent *h;
11 size_t size = 63;
12 struct hostent *res;
13 int err;
14 do {
15 free(h);
16 h = malloc(size+=size+1);
17 if (!h) {
18 h_errno = NO_RECOVERY;
19 return 0;
20 }
21 err = gethostbyname2_r(name, af, h,
22 (void *)(h+1), size-sizeof *h, &res, &h_errno);
23 } while (err == ERANGE);
24 return err ? 0 : h;
25}
libc/musl/src/network/gethostbyname2_r.c created+80
......@@ -0,0 +1,80 @@
1#define _GNU_SOURCE
2
3#include <sys/socket.h>
4#include <netdb.h>
5#include <string.h>
6#include <netinet/in.h>
7#include <errno.h>
8#include <stdint.h>
9#include "lookup.h"
10
11int gethostbyname2_r(const char *name, int af,
12 struct hostent *h, char *buf, size_t buflen,
13 struct hostent **res, int *err)
14{
15 struct address addrs[MAXADDRS];
16 char canon[256];
17 int i, cnt;
18 size_t align, need;
19
20 *res = 0;
21 cnt = __lookup_name(addrs, canon, name, af, AI_CANONNAME);
22 if (cnt<0) switch (cnt) {
23 case EAI_NONAME:
24 *err = HOST_NOT_FOUND;
25 return ENOENT;
26 case EAI_AGAIN:
27 *err = TRY_AGAIN;
28 return EAGAIN;
29 default:
30 case EAI_FAIL:
31 *err = NO_RECOVERY;
32 return EBADMSG;
33 case EAI_MEMORY:
34 case EAI_SYSTEM:
35 *err = NO_RECOVERY;
36 return errno;
37 }
38
39 h->h_addrtype = af;
40 h->h_length = af==AF_INET6 ? 16 : 4;
41
42 /* Align buffer */
43 align = -(uintptr_t)buf & sizeof(char *)-1;
44
45 need = 4*sizeof(char *);
46 need += (cnt + 1) * (sizeof(char *) + h->h_length);
47 need += strlen(name)+1;
48 need += strlen(canon)+1;
49 need += align;
50
51 if (need > buflen) return ERANGE;
52
53 buf += align;
54 h->h_aliases = (void *)buf;
55 buf += 3*sizeof(char *);
56 h->h_addr_list = (void *)buf;
57 buf += (cnt+1)*sizeof(char *);
58
59 for (i=0; i<cnt; i++) {
60 h->h_addr_list[i] = (void *)buf;
61 buf += h->h_length;
62 memcpy(h->h_addr_list[i], addrs[i].addr, h->h_length);
63 }
64 h->h_addr_list[i] = 0;
65
66 h->h_name = h->h_aliases[0] = buf;
67 strcpy(h->h_name, canon);
68 buf += strlen(h->h_name)+1;
69
70 if (strcmp(h->h_name, name)) {
71 h->h_aliases[1] = buf;
72 strcpy(h->h_aliases[1], name);
73 buf += strlen(h->h_aliases[1])+1;
74 } else h->h_aliases[1] = 0;
75
76 h->h_aliases[2] = 0;
77
78 *res = h;
79 return 0;
80}
libc/musl/src/network/gethostbyname_r.c created+11
......@@ -0,0 +1,11 @@
1#define _GNU_SOURCE
2
3#include <sys/socket.h>
4#include <netdb.h>
5
6int gethostbyname_r(const char *name,
7 struct hostent *h, char *buf, size_t buflen,
8 struct hostent **res, int *err)
9{
10 return gethostbyname2_r(name, AF_INET, h, buf, buflen, res, err);
11}
libc/musl/src/network/getifaddrs.c created+216
......@@ -0,0 +1,216 @@
1#define _GNU_SOURCE
2#include <errno.h>
3#include <string.h>
4#include <stdlib.h>
5#include <unistd.h>
6#include <ifaddrs.h>
7#include <syscall.h>
8#include <net/if.h>
9#include <netinet/in.h>
10#include "netlink.h"
11
12#define IFADDRS_HASH_SIZE 64
13
14/* getifaddrs() reports hardware addresses with PF_PACKET that implies
15 * struct sockaddr_ll. But e.g. Infiniband socket address length is
16 * longer than sockaddr_ll.ssl_addr[8] can hold. Use this hack struct
17 * to extend ssl_addr - callers should be able to still use it. */
18struct sockaddr_ll_hack {
19 unsigned short sll_family, sll_protocol;
20 int sll_ifindex;
21 unsigned short sll_hatype;
22 unsigned char sll_pkttype, sll_halen;
23 unsigned char sll_addr[24];
24};
25
26union sockany {
27 struct sockaddr sa;
28 struct sockaddr_ll_hack ll;
29 struct sockaddr_in v4;
30 struct sockaddr_in6 v6;
31};
32
33struct ifaddrs_storage {
34 struct ifaddrs ifa;
35 struct ifaddrs_storage *hash_next;
36 union sockany addr, netmask, ifu;
37 unsigned int index;
38 char name[IFNAMSIZ+1];
39};
40
41struct ifaddrs_ctx {
42 struct ifaddrs_storage *first;
43 struct ifaddrs_storage *last;
44 struct ifaddrs_storage *hash[IFADDRS_HASH_SIZE];
45};
46
47void freeifaddrs(struct ifaddrs *ifp)
48{
49 struct ifaddrs *n;
50 while (ifp) {
51 n = ifp->ifa_next;
52 free(ifp);
53 ifp = n;
54 }
55}
56
57static void copy_addr(struct sockaddr **r, int af, union sockany *sa, void *addr, size_t addrlen, int ifindex)
58{
59 uint8_t *dst;
60 int len;
61
62 switch (af) {
63 case AF_INET:
64 dst = (uint8_t*) &sa->v4.sin_addr;
65 len = 4;
66 break;
67 case AF_INET6:
68 dst = (uint8_t*) &sa->v6.sin6_addr;
69 len = 16;
70 if (IN6_IS_ADDR_LINKLOCAL(addr) || IN6_IS_ADDR_MC_LINKLOCAL(addr))
71 sa->v6.sin6_scope_id = ifindex;
72 break;
73 default:
74 return;
75 }
76 if (addrlen < len) return;
77 sa->sa.sa_family = af;
78 memcpy(dst, addr, len);
79 *r = &sa->sa;
80}
81
82static void gen_netmask(struct sockaddr **r, int af, union sockany *sa, int prefixlen)
83{
84 uint8_t addr[16] = {0};
85 int i;
86
87 if (prefixlen > 8*sizeof(addr)) prefixlen = 8*sizeof(addr);
88 i = prefixlen / 8;
89 memset(addr, 0xff, i);
90 if (i < sizeof(addr)) addr[i++] = 0xff << (8 - (prefixlen % 8));
91 copy_addr(r, af, sa, addr, sizeof(addr), 0);
92}
93
94static void copy_lladdr(struct sockaddr **r, union sockany *sa, void *addr, size_t addrlen, int ifindex, unsigned short hatype)
95{
96 if (addrlen > sizeof(sa->ll.sll_addr)) return;
97 sa->ll.sll_family = AF_PACKET;
98 sa->ll.sll_ifindex = ifindex;
99 sa->ll.sll_hatype = hatype;
100 sa->ll.sll_halen = addrlen;
101 memcpy(sa->ll.sll_addr, addr, addrlen);
102 *r = &sa->sa;
103}
104
105static int netlink_msg_to_ifaddr(void *pctx, struct nlmsghdr *h)
106{
107 struct ifaddrs_ctx *ctx = pctx;
108 struct ifaddrs_storage *ifs, *ifs0;
109 struct ifinfomsg *ifi = NLMSG_DATA(h);
110 struct ifaddrmsg *ifa = NLMSG_DATA(h);
111 struct rtattr *rta;
112 int stats_len = 0;
113
114 if (h->nlmsg_type == RTM_NEWLINK) {
115 for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
116 if (rta->rta_type != IFLA_STATS) continue;
117 stats_len = RTA_DATALEN(rta);
118 break;
119 }
120 } else {
121 for (ifs0 = ctx->hash[ifa->ifa_index % IFADDRS_HASH_SIZE]; ifs0; ifs0 = ifs0->hash_next)
122 if (ifs0->index == ifa->ifa_index)
123 break;
124 if (!ifs0) return 0;
125 }
126
127 ifs = calloc(1, sizeof(struct ifaddrs_storage) + stats_len);
128 if (ifs == 0) return -1;
129
130 if (h->nlmsg_type == RTM_NEWLINK) {
131 ifs->index = ifi->ifi_index;
132 ifs->ifa.ifa_flags = ifi->ifi_flags;
133
134 for (rta = NLMSG_RTA(h, sizeof(*ifi)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
135 switch (rta->rta_type) {
136 case IFLA_IFNAME:
137 if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
138 memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
139 ifs->ifa.ifa_name = ifs->name;
140 }
141 break;
142 case IFLA_ADDRESS:
143 copy_lladdr(&ifs->ifa.ifa_addr, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
144 break;
145 case IFLA_BROADCAST:
146 copy_lladdr(&ifs->ifa.ifa_broadaddr, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifi->ifi_index, ifi->ifi_type);
147 break;
148 case IFLA_STATS:
149 ifs->ifa.ifa_data = (void*)(ifs+1);
150 memcpy(ifs->ifa.ifa_data, RTA_DATA(rta), RTA_DATALEN(rta));
151 break;
152 }
153 }
154 if (ifs->ifa.ifa_name) {
155 unsigned int bucket = ifs->index % IFADDRS_HASH_SIZE;
156 ifs->hash_next = ctx->hash[bucket];
157 ctx->hash[bucket] = ifs;
158 }
159 } else {
160 ifs->ifa.ifa_name = ifs0->ifa.ifa_name;
161 ifs->ifa.ifa_flags = ifs0->ifa.ifa_flags;
162 for (rta = NLMSG_RTA(h, sizeof(*ifa)); NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
163 switch (rta->rta_type) {
164 case IFA_ADDRESS:
165 /* If ifa_addr is already set we, received an IFA_LOCAL before
166 * so treat this as destination address */
167 if (ifs->ifa.ifa_addr)
168 copy_addr(&ifs->ifa.ifa_dstaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
169 else
170 copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
171 break;
172 case IFA_BROADCAST:
173 copy_addr(&ifs->ifa.ifa_broadaddr, ifa->ifa_family, &ifs->ifu, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
174 break;
175 case IFA_LOCAL:
176 /* If ifa_addr is set and we get IFA_LOCAL, assume we have
177 * a point-to-point network. Move address to correct field. */
178 if (ifs->ifa.ifa_addr) {
179 ifs->ifu = ifs->addr;
180 ifs->ifa.ifa_dstaddr = &ifs->ifu.sa;
181 memset(&ifs->addr, 0, sizeof(ifs->addr));
182 }
183 copy_addr(&ifs->ifa.ifa_addr, ifa->ifa_family, &ifs->addr, RTA_DATA(rta), RTA_DATALEN(rta), ifa->ifa_index);
184 break;
185 case IFA_LABEL:
186 if (RTA_DATALEN(rta) < sizeof(ifs->name)) {
187 memcpy(ifs->name, RTA_DATA(rta), RTA_DATALEN(rta));
188 ifs->ifa.ifa_name = ifs->name;
189 }
190 break;
191 }
192 }
193 if (ifs->ifa.ifa_addr)
194 gen_netmask(&ifs->ifa.ifa_netmask, ifa->ifa_family, &ifs->netmask, ifa->ifa_prefixlen);
195 }
196
197 if (ifs->ifa.ifa_name) {
198 if (!ctx->first) ctx->first = ifs;
199 if (ctx->last) ctx->last->ifa.ifa_next = &ifs->ifa;
200 ctx->last = ifs;
201 } else {
202 free(ifs);
203 }
204 return 0;
205}
206
207int getifaddrs(struct ifaddrs **ifap)
208{
209 struct ifaddrs_ctx _ctx, *ctx = &_ctx;
210 int r;
211 memset(ctx, 0, sizeof *ctx);
212 r = __rtnetlink_enumerate(AF_UNSPEC, AF_UNSPEC, netlink_msg_to_ifaddr, ctx);
213 if (r == 0) *ifap = &ctx->first->ifa;
214 else freeifaddrs(&ctx->first->ifa);
215 return r;
216}
libc/musl/src/network/getnameinfo.c created+199
......@@ -0,0 +1,199 @@
1#include <netdb.h>
2#include <limits.h>
3#include <string.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <sys/socket.h>
7#include <netinet/in.h>
8#include <arpa/inet.h>
9#include <net/if.h>
10#include <ctype.h>
11#include <resolv.h>
12#include "lookup.h"
13#include "stdio_impl.h"
14
15#define PTR_MAX (64 + sizeof ".in-addr.arpa")
16#define RR_PTR 12
17
18static char *itoa(char *p, unsigned x) {
19 p += 3*sizeof(int);
20 *--p = 0;
21 do {
22 *--p = '0' + x % 10;
23 x /= 10;
24 } while (x);
25 return p;
26}
27
28static void mkptr4(char *s, const unsigned char *ip)
29{
30 sprintf(s, "%d.%d.%d.%d.in-addr.arpa",
31 ip[3], ip[2], ip[1], ip[0]);
32}
33
34static void mkptr6(char *s, const unsigned char *ip)
35{
36 static const char xdigits[] = "0123456789abcdef";
37 int i;
38 for (i=15; i>=0; i--) {
39 *s++ = xdigits[ip[i]&15]; *s++ = '.';
40 *s++ = xdigits[ip[i]>>4]; *s++ = '.';
41 }
42 strcpy(s, "ip6.arpa");
43}
44
45static void reverse_hosts(char *buf, const unsigned char *a, unsigned scopeid, int family)
46{
47 char line[512], *p, *z;
48 unsigned char _buf[1032], atmp[16];
49 struct address iplit;
50 FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
51 if (!f) return;
52 if (family == AF_INET) {
53 memcpy(atmp+12, a, 4);
54 memcpy(atmp, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
55 a = atmp;
56 }
57 while (fgets(line, sizeof line, f)) {
58 if ((p=strchr(line, '#'))) *p++='\n', *p=0;
59
60 for (p=line; *p && !isspace(*p); p++);
61 *p++ = 0;
62 if (__lookup_ipliteral(&iplit, line, AF_UNSPEC)<=0)
63 continue;
64
65 if (iplit.family == AF_INET) {
66 memcpy(iplit.addr+12, iplit.addr, 4);
67 memcpy(iplit.addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
68 iplit.scopeid = 0;
69 }
70
71 if (memcmp(a, iplit.addr, 16) || iplit.scopeid != scopeid)
72 continue;
73
74 for (; *p && isspace(*p); p++);
75 for (z=p; *z && !isspace(*z); z++);
76 *z = 0;
77 if (z-p < 256) {
78 memcpy(buf, p, z-p+1);
79 break;
80 }
81 }
82 __fclose_ca(f);
83}
84
85static void reverse_services(char *buf, int port, int dgram)
86{
87 unsigned long svport;
88 char line[128], *p, *z;
89 unsigned char _buf[1032];
90 FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
91 if (!f) return;
92 while (fgets(line, sizeof line, f)) {
93 if ((p=strchr(line, '#'))) *p++='\n', *p=0;
94
95 for (p=line; *p && !isspace(*p); p++);
96 if (!*p) continue;
97 *p++ = 0;
98 svport = strtoul(p, &z, 10);
99
100 if (svport != port || z==p) continue;
101 if (dgram && strncmp(z, "/udp", 4)) continue;
102 if (!dgram && strncmp(z, "/tcp", 4)) continue;
103 if (p-line > 32) continue;
104
105 memcpy(buf, line, p-line);
106 break;
107 }
108 __fclose_ca(f);
109}
110
111static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
112{
113 if (rr != RR_PTR) return 0;
114 if (__dn_expand(packet, (const unsigned char *)packet + 512,
115 data, c, 256) <= 0)
116 *(char *)c = 0;
117 return 0;
118
119}
120
121int getnameinfo(const struct sockaddr *restrict sa, socklen_t sl,
122 char *restrict node, socklen_t nodelen,
123 char *restrict serv, socklen_t servlen,
124 int flags)
125{
126 char ptr[PTR_MAX];
127 char buf[256], num[3*sizeof(int)+1];
128 int af = sa->sa_family;
129 unsigned char *a;
130 unsigned scopeid;
131
132 switch (af) {
133 case AF_INET:
134 a = (void *)&((struct sockaddr_in *)sa)->sin_addr;
135 if (sl < sizeof(struct sockaddr_in)) return EAI_FAMILY;
136 mkptr4(ptr, a);
137 scopeid = 0;
138 break;
139 case AF_INET6:
140 a = (void *)&((struct sockaddr_in6 *)sa)->sin6_addr;
141 if (sl < sizeof(struct sockaddr_in6)) return EAI_FAMILY;
142 if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12))
143 mkptr6(ptr, a);
144 else
145 mkptr4(ptr, a+12);
146 scopeid = ((struct sockaddr_in6 *)sa)->sin6_scope_id;
147 break;
148 default:
149 return EAI_FAMILY;
150 }
151
152 if (node && nodelen) {
153 buf[0] = 0;
154 if (!(flags & NI_NUMERICHOST)) {
155 reverse_hosts(buf, a, scopeid, af);
156 }
157 if (!*buf && !(flags & NI_NUMERICHOST)) {
158 unsigned char query[18+PTR_MAX], reply[512];
159 int qlen = __res_mkquery(0, ptr, 1, RR_PTR,
160 0, 0, 0, query, sizeof query);
161 int rlen = __res_send(query, qlen, reply, sizeof reply);
162 buf[0] = 0;
163 if (rlen > 0)
164 __dns_parse(reply, rlen, dns_parse_callback, buf);
165 }
166 if (!*buf) {
167 if (flags & NI_NAMEREQD) return EAI_NONAME;
168 inet_ntop(af, a, buf, sizeof buf);
169 if (scopeid) {
170 char *p = 0, tmp[IF_NAMESIZE+1];
171 if (!(flags & NI_NUMERICSCOPE) &&
172 (IN6_IS_ADDR_LINKLOCAL(a) ||
173 IN6_IS_ADDR_MC_LINKLOCAL(a)))
174 p = if_indextoname(scopeid, tmp+1);
175 if (!p)
176 p = itoa(num, scopeid);
177 *--p = '%';
178 strcat(buf, p);
179 }
180 }
181 if (strlen(buf) >= nodelen) return EAI_OVERFLOW;
182 strcpy(node, buf);
183 }
184
185 if (serv && servlen) {
186 char *p = buf;
187 int port = ntohs(((struct sockaddr_in *)sa)->sin_port);
188 buf[0] = 0;
189 if (!(flags & NI_NUMERICSERV))
190 reverse_services(buf, port, flags & NI_DGRAM);
191 if (!*p)
192 p = itoa(num, port);
193 if (strlen(p) >= servlen)
194 return EAI_OVERFLOW;
195 strcpy(serv, p);
196 }
197
198 return 0;
199}
libc/musl/src/network/getpeername.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4int getpeername(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
5{
6 return socketcall(getpeername, fd, addr, len, 0, 0, 0);
7}
libc/musl/src/network/getservbyname.c created+12
......@@ -0,0 +1,12 @@
1#define _GNU_SOURCE
2#include <netdb.h>
3
4struct servent *getservbyname(const char *name, const char *prots)
5{
6 static struct servent se;
7 static char *buf[2];
8 struct servent *res;
9 if (getservbyname_r(name, prots, &se, (void *)buf, sizeof buf, &res))
10 return 0;
11 return &se;
12}
libc/musl/src/network/getservbyname_r.c created+55
......@@ -0,0 +1,55 @@
1#define _GNU_SOURCE
2#include <sys/socket.h>
3#include <netinet/in.h>
4#include <netdb.h>
5#include <inttypes.h>
6#include <errno.h>
7#include <string.h>
8#include <stdlib.h>
9#include "lookup.h"
10
11#define ALIGN (sizeof(struct { char a; char *b; }) - sizeof(char *))
12
13int getservbyname_r(const char *name, const char *prots,
14 struct servent *se, char *buf, size_t buflen, struct servent **res)
15{
16 struct service servs[MAXSERVS];
17 int cnt, proto, align;
18
19 *res = 0;
20
21 /* Don't treat numeric port number strings as service records. */
22 char *end = "";
23 strtoul(name, &end, 10);
24 if (!*end) return ENOENT;
25
26 /* Align buffer */
27 align = -(uintptr_t)buf & ALIGN-1;
28 if (buflen < 2*sizeof(char *)+align)
29 return ERANGE;
30 buf += align;
31
32 if (!prots) proto = 0;
33 else if (!strcmp(prots, "tcp")) proto = IPPROTO_TCP;
34 else if (!strcmp(prots, "udp")) proto = IPPROTO_UDP;
35 else return EINVAL;
36
37 cnt = __lookup_serv(servs, name, proto, 0, 0);
38 if (cnt<0) switch (cnt) {
39 case EAI_MEMORY:
40 case EAI_SYSTEM:
41 return ENOMEM;
42 default:
43 return ENOENT;
44 }
45
46 se->s_name = (char *)name;
47 se->s_aliases = (void *)buf;
48 se->s_aliases[0] = se->s_name;
49 se->s_aliases[1] = 0;
50 se->s_port = htons(servs[0].port);
51 se->s_proto = servs[0].proto == IPPROTO_TCP ? "tcp" : "udp";
52
53 *res = se;
54 return 0;
55}
libc/musl/src/network/getservbyport.c created+12
......@@ -0,0 +1,12 @@
1#define _GNU_SOURCE
2#include <netdb.h>
3
4struct servent *getservbyport(int port, const char *prots)
5{
6 static struct servent se;
7 static long buf[32/sizeof(long)];
8 struct servent *res;
9 if (getservbyport_r(port, prots, &se, (void *)buf, sizeof buf, &res))
10 return 0;
11 return &se;
12}
libc/musl/src/network/getservbyport_r.c created+60
......@@ -0,0 +1,60 @@
1#define _GNU_SOURCE
2#include <sys/socket.h>
3#include <netinet/in.h>
4#include <netdb.h>
5#include <inttypes.h>
6#include <errno.h>
7#include <string.h>
8#include <stdlib.h>
9
10int getservbyport_r(int port, const char *prots,
11 struct servent *se, char *buf, size_t buflen, struct servent **res)
12{
13 int i;
14 struct sockaddr_in sin = {
15 .sin_family = AF_INET,
16 .sin_port = port,
17 };
18
19 if (!prots) {
20 int r = getservbyport_r(port, "tcp", se, buf, buflen, res);
21 if (r) r = getservbyport_r(port, "udp", se, buf, buflen, res);
22 return r;
23 }
24 *res = 0;
25
26 /* Align buffer */
27 i = (uintptr_t)buf & sizeof(char *)-1;
28 if (!i) i = sizeof(char *);
29 if (buflen < 3*sizeof(char *)-i)
30 return ERANGE;
31 buf += sizeof(char *)-i;
32 buflen -= sizeof(char *)-i;
33
34 if (strcmp(prots, "tcp") && strcmp(prots, "udp")) return EINVAL;
35
36 se->s_port = port;
37 se->s_proto = (char *)prots;
38 se->s_aliases = (void *)buf;
39 buf += 2*sizeof(char *);
40 buflen -= 2*sizeof(char *);
41 se->s_aliases[1] = 0;
42 se->s_aliases[0] = se->s_name = buf;
43
44 switch (getnameinfo((void *)&sin, sizeof sin, 0, 0, buf, buflen,
45 strcmp(prots, "udp") ? 0 : NI_DGRAM)) {
46 case EAI_MEMORY:
47 case EAI_SYSTEM:
48 return ENOMEM;
49 default:
50 return ENOENT;
51 case 0:
52 break;
53 }
54
55 /* A numeric port string is not a service record. */
56 if (strtol(buf, 0, 10)==ntohs(port)) return ENOENT;
57
58 *res = se;
59 return 0;
60}
libc/musl/src/network/getsockname.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4int getsockname(int fd, struct sockaddr *restrict addr, socklen_t *restrict len)
5{
6 return socketcall(getsockname, fd, addr, len, 0, 0, 0);
7}
libc/musl/src/network/getsockopt.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4int getsockopt(int fd, int level, int optname, void *restrict optval, socklen_t *restrict optlen)
5{
6 return socketcall(getsockopt, fd, level, optname, optval, optlen, 0);
7}
libc/musl/src/network/h_errno.c created+9
......@@ -0,0 +1,9 @@
1#include <netdb.h>
2
3#undef h_errno
4int h_errno;
5
6int *__h_errno_location(void)
7{
8 return &h_errno;
9}
libc/musl/src/network/herror.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3#include <netdb.h>
4
5void herror(const char *msg)
6{
7 fprintf(stderr, "%s%s%s", msg?msg:"", msg?": ":"", hstrerror(h_errno));
8}
libc/musl/src/network/hstrerror.c created+18
......@@ -0,0 +1,18 @@
1#define _GNU_SOURCE
2#include <netdb.h>
3#include "locale_impl.h"
4
5static const char msgs[] =
6 "Host not found\0"
7 "Try again\0"
8 "Non-recoverable error\0"
9 "Address not available\0"
10 "\0Unknown error";
11
12const char *hstrerror(int ecode)
13{
14 const char *s;
15 for (s=msgs, ecode--; ecode && *s; ecode--, s++) for (; *s; s++);
16 if (!*s) s++;
17 return LCTRANS_CUR(s);
18}
libc/musl/src/network/htonl.c created+8
......@@ -0,0 +1,8 @@
1#include <netinet/in.h>
2#include <byteswap.h>
3
4uint32_t htonl(uint32_t n)
5{
6 union { int i; char c; } u = { 1 };
7 return u.c ? bswap_32(n) : n;
8}
libc/musl/src/network/htons.c created+8
......@@ -0,0 +1,8 @@
1#include <netinet/in.h>
2#include <byteswap.h>
3
4uint16_t htons(uint16_t n)
5{
6 union { int i; char c; } u = { 1 };
7 return u.c ? bswap_16(n) : n;
8}
libc/musl/src/network/if_freenameindex.c created+7
......@@ -0,0 +1,7 @@
1#include <net/if.h>
2#include <stdlib.h>
3
4void if_freenameindex(struct if_nameindex *idx)
5{
6 free(idx);
7}
libc/musl/src/network/if_indextoname.c created+23
......@@ -0,0 +1,23 @@
1#define _GNU_SOURCE
2#include <net/if.h>
3#include <sys/socket.h>
4#include <sys/ioctl.h>
5#include <string.h>
6#include <errno.h>
7#include "syscall.h"
8
9char *if_indextoname(unsigned index, char *name)
10{
11 struct ifreq ifr;
12 int fd, r;
13
14 if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
15 ifr.ifr_ifindex = index;
16 r = ioctl(fd, SIOCGIFNAME, &ifr);
17 __syscall(SYS_close, fd);
18 if (r < 0) {
19 if (errno == ENODEV) errno = ENXIO;
20 return 0;
21 }
22 return strncpy(name, ifr.ifr_name, IF_NAMESIZE);
23}
libc/musl/src/network/if_nameindex.c created+114
......@@ -0,0 +1,114 @@
1#define _GNU_SOURCE
2#include <net/if.h>
3#include <errno.h>
4#include <unistd.h>
5#include <stdlib.h>
6#include <string.h>
7#include <pthread.h>
8#include "netlink.h"
9
10#define IFADDRS_HASH_SIZE 64
11
12struct ifnamemap {
13 unsigned int hash_next;
14 unsigned int index;
15 unsigned char namelen;
16 char name[IFNAMSIZ];
17};
18
19struct ifnameindexctx {
20 unsigned int num, allocated, str_bytes;
21 struct ifnamemap *list;
22 unsigned int hash[IFADDRS_HASH_SIZE];
23};
24
25static int netlink_msg_to_nameindex(void *pctx, struct nlmsghdr *h)
26{
27 struct ifnameindexctx *ctx = pctx;
28 struct ifnamemap *map;
29 struct rtattr *rta;
30 unsigned int i;
31 int index, type, namelen, bucket;
32
33 if (h->nlmsg_type == RTM_NEWLINK) {
34 struct ifinfomsg *ifi = NLMSG_DATA(h);
35 index = ifi->ifi_index;
36 type = IFLA_IFNAME;
37 rta = NLMSG_RTA(h, sizeof(*ifi));
38 } else {
39 struct ifaddrmsg *ifa = NLMSG_DATA(h);
40 index = ifa->ifa_index;
41 type = IFA_LABEL;
42 rta = NLMSG_RTA(h, sizeof(*ifa));
43 }
44 for (; NLMSG_RTAOK(rta, h); rta = RTA_NEXT(rta)) {
45 if (rta->rta_type != type) continue;
46
47 namelen = RTA_DATALEN(rta) - 1;
48 if (namelen > IFNAMSIZ) return 0;
49
50 /* suppress duplicates */
51 bucket = index % IFADDRS_HASH_SIZE;
52 i = ctx->hash[bucket];
53 while (i) {
54 map = &ctx->list[i-1];
55 if (map->index == index &&
56 map->namelen == namelen &&
57 memcmp(map->name, RTA_DATA(rta), namelen) == 0)
58 return 0;
59 i = map->hash_next;
60 }
61
62 if (ctx->num >= ctx->allocated) {
63 size_t a = ctx->allocated ? ctx->allocated * 2 + 1 : 8;
64 if (a > SIZE_MAX/sizeof *map) return -1;
65 map = realloc(ctx->list, a * sizeof *map);
66 if (!map) return -1;
67 ctx->list = map;
68 ctx->allocated = a;
69 }
70 map = &ctx->list[ctx->num];
71 map->index = index;
72 map->namelen = namelen;
73 memcpy(map->name, RTA_DATA(rta), namelen);
74 ctx->str_bytes += namelen + 1;
75 ctx->num++;
76 map->hash_next = ctx->hash[bucket];
77 ctx->hash[bucket] = ctx->num;
78 return 0;
79 }
80 return 0;
81}
82
83struct if_nameindex *if_nameindex()
84{
85 struct ifnameindexctx _ctx, *ctx = &_ctx;
86 struct if_nameindex *ifs = 0, *d;
87 struct ifnamemap *s;
88 char *p;
89 int i;
90 int cs;
91
92 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
93 memset(ctx, 0, sizeof(*ctx));
94 if (__rtnetlink_enumerate(AF_UNSPEC, AF_INET, netlink_msg_to_nameindex, ctx) < 0) goto err;
95
96 ifs = malloc(sizeof(struct if_nameindex[ctx->num+1]) + ctx->str_bytes);
97 if (!ifs) goto err;
98
99 p = (char*)(ifs + ctx->num + 1);
100 for (i = ctx->num, d = ifs, s = ctx->list; i; i--, s++, d++) {
101 d->if_index = s->index;
102 d->if_name = p;
103 memcpy(p, s->name, s->namelen);
104 p += s->namelen;
105 *p++ = 0;
106 }
107 d->if_index = 0;
108 d->if_name = 0;
109err:
110 pthread_setcancelstate(cs, 0);
111 free(ctx->list);
112 errno = ENOBUFS;
113 return ifs;
114}
libc/musl/src/network/if_nametoindex.c created+18
......@@ -0,0 +1,18 @@
1#define _GNU_SOURCE
2#include <net/if.h>
3#include <sys/socket.h>
4#include <sys/ioctl.h>
5#include <string.h>
6#include "syscall.h"
7
8unsigned if_nametoindex(const char *name)
9{
10 struct ifreq ifr;
11 int fd, r;
12
13 if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) return 0;
14 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
15 r = ioctl(fd, SIOCGIFINDEX, &ifr);
16 __syscall(SYS_close, fd);
17 return r < 0 ? 0 : ifr.ifr_ifindex;
18}
libc/musl/src/network/in6addr_any.c created+3
......@@ -0,0 +1,3 @@
1#include <netinet/in.h>
2
3const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
libc/musl/src/network/in6addr_loopback.c created+3
......@@ -0,0 +1,3 @@
1#include <netinet/in.h>
2
3const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
libc/musl/src/network/inet_addr.c created+10
......@@ -0,0 +1,10 @@
1#include <sys/socket.h>
2#include <netinet/in.h>
3#include <arpa/inet.h>
4
5in_addr_t inet_addr(const char *p)
6{
7 struct in_addr a;
8 if (!__inet_aton(p, &a)) return -1;
9 return a.s_addr;
10}
libc/musl/src/network/inet_aton.c created+41
......@@ -0,0 +1,41 @@
1#include <ctype.h>
2#include <sys/socket.h>
3#include <netinet/in.h>
4#include <arpa/inet.h>
5#include <stdlib.h>
6
7int __inet_aton(const char *s0, struct in_addr *dest)
8{
9 const char *s = s0;
10 unsigned char *d = (void *)dest;
11 unsigned long a[4] = { 0 };
12 char *z;
13 int i;
14
15 for (i=0; i<4; i++) {
16 a[i] = strtoul(s, &z, 0);
17 if (z==s || (*z && *z != '.') || !isdigit(*s))
18 return 0;
19 if (!*z) break;
20 s=z+1;
21 }
22 if (i==4) return 0;
23 switch (i) {
24 case 0:
25 a[1] = a[0] & 0xffffff;
26 a[0] >>= 24;
27 case 1:
28 a[2] = a[1] & 0xffff;
29 a[1] >>= 16;
30 case 2:
31 a[3] = a[2] & 0xff;
32 a[2] >>= 8;
33 }
34 for (i=0; i<4; i++) {
35 if (a[i] > 255) return 0;
36 d[i] = a[i];
37 }
38 return 1;
39}
40
41weak_alias(__inet_aton, inet_aton);
libc/musl/src/network/inet_legacy.c created+32
......@@ -0,0 +1,32 @@
1#include <sys/socket.h>
2#include <netinet/in.h>
3#include <arpa/inet.h>
4
5in_addr_t inet_network(const char *p)
6{
7 return ntohl(inet_addr(p));
8}
9
10struct in_addr inet_makeaddr(in_addr_t n, in_addr_t h)
11{
12 if (n < 256) h |= n<<24;
13 else if (n < 65536) h |= n<<16;
14 else h |= n<<8;
15 return (struct in_addr){ h };
16}
17
18in_addr_t inet_lnaof(struct in_addr in)
19{
20 uint32_t h = in.s_addr;
21 if (h>>24 < 128) return h & 0xffffff;
22 if (h>>24 < 192) return h & 0xffff;
23 return h & 0xff;
24}
25
26in_addr_t inet_netof(struct in_addr in)
27{
28 uint32_t h = in.s_addr;
29 if (h>>24 < 128) return h >> 24;
30 if (h>>24 < 192) return h >> 16;
31 return h >> 8;
32}
libc/musl/src/network/inet_ntoa.c created+10
......@@ -0,0 +1,10 @@
1#include <arpa/inet.h>
2#include <stdio.h>
3
4char *inet_ntoa(struct in_addr in)
5{
6 static char buf[16];
7 unsigned char *a = (void *)&in;
8 snprintf(buf, sizeof buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
9 return buf;
10}
libc/musl/src/network/inet_ntop.c created+54
......@@ -0,0 +1,54 @@
1#include <sys/socket.h>
2#include <arpa/inet.h>
3#include <errno.h>
4#include <stdio.h>
5#include <string.h>
6
7const char *inet_ntop(int af, const void *restrict a0, char *restrict s, socklen_t l)
8{
9 const unsigned char *a = a0;
10 int i, j, max, best;
11 char buf[100];
12
13 switch (af) {
14 case AF_INET:
15 if (snprintf(s, l, "%d.%d.%d.%d", a[0],a[1],a[2],a[3]) < l)
16 return s;
17 break;
18 case AF_INET6:
19 if (memcmp(a, "\0\0\0\0\0\0\0\0\0\0\377\377", 12))
20 snprintf(buf, sizeof buf,
21 "%x:%x:%x:%x:%x:%x:%x:%x",
22 256*a[0]+a[1],256*a[2]+a[3],
23 256*a[4]+a[5],256*a[6]+a[7],
24 256*a[8]+a[9],256*a[10]+a[11],
25 256*a[12]+a[13],256*a[14]+a[15]);
26 else
27 snprintf(buf, sizeof buf,
28 "%x:%x:%x:%x:%x:%x:%d.%d.%d.%d",
29 256*a[0]+a[1],256*a[2]+a[3],
30 256*a[4]+a[5],256*a[6]+a[7],
31 256*a[8]+a[9],256*a[10]+a[11],
32 a[12],a[13],a[14],a[15]);
33 /* Replace longest /(^0|:)[:0]{2,}/ with "::" */
34 for (i=best=0, max=2; buf[i]; i++) {
35 if (i && buf[i] != ':') continue;
36 j = strspn(buf+i, ":0");
37 if (j>max) best=i, max=j;
38 }
39 if (max>3) {
40 buf[best] = buf[best+1] = ':';
41 memmove(buf+best+2, buf+best+max, i-best-max+1);
42 }
43 if (strlen(buf) < l) {
44 strcpy(s, buf);
45 return s;
46 }
47 break;
48 default:
49 errno = EAFNOSUPPORT;
50 return 0;
51 }
52 errno = ENOSPC;
53 return 0;
54}
libc/musl/src/network/inet_pton.c created+71
......@@ -0,0 +1,71 @@
1#include <sys/socket.h>
2#include <arpa/inet.h>
3#include <ctype.h>
4#include <errno.h>
5#include <string.h>
6
7static int hexval(unsigned c)
8{
9 if (c-'0'<10) return c-'0';
10 c |= 32;
11 if (c-'a'<6) return c-'a'+10;
12 return -1;
13}
14
15int inet_pton(int af, const char *restrict s, void *restrict a0)
16{
17 uint16_t ip[8];
18 unsigned char *a = a0;
19 int i, j, v, d, brk=-1, need_v4=0;
20
21 if (af==AF_INET) {
22 for (i=0; i<4; i++) {
23 for (v=j=0; j<3 && isdigit(s[j]); j++)
24 v = 10*v + s[j]-'0';
25 if (j==0 || (j>1 && s[0]=='0') || v>255) return 0;
26 a[i] = v;
27 if (s[j]==0 && i==3) return 1;
28 if (s[j]!='.') return 0;
29 s += j+1;
30 }
31 return 0;
32 } else if (af!=AF_INET6) {
33 errno = EAFNOSUPPORT;
34 return -1;
35 }
36
37 if (*s==':' && *++s!=':') return 0;
38
39 for (i=0; ; i++) {
40 if (s[0]==':' && brk<0) {
41 brk=i;
42 ip[i&7]=0;
43 if (!*++s) break;
44 if (i==7) return 0;
45 continue;
46 }
47 for (v=j=0; j<4 && (d=hexval(s[j]))>=0; j++)
48 v=16*v+d;
49 if (j==0) return 0;
50 ip[i&7] = v;
51 if (!s[j] && (brk>=0 || i==7)) break;
52 if (i==7) return 0;
53 if (s[j]!=':') {
54 if (s[j]!='.' || (i<6 && brk<0)) return 0;
55 need_v4=1;
56 i++;
57 break;
58 }
59 s += j+1;
60 }
61 if (brk>=0) {
62 memmove(ip+brk+7-i, ip+brk, 2*(i+1-brk));
63 for (j=0; j<7-i; j++) ip[brk+j] = 0;
64 }
65 for (j=0; j<8; j++) {
66 *a++ = ip[j]>>8;
67 *a++ = ip[j];
68 }
69 if (need_v4 && inet_pton(AF_INET, (void *)s, a-4) <= 0) return 0;
70 return 1;
71}
libc/musl/src/network/listen.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4int listen(int fd, int backlog)
5{
6 return socketcall(listen, fd, backlog, 0, 0, 0, 0);
7}
libc/musl/src/network/lookup.h created+55
......@@ -0,0 +1,55 @@
1#ifndef LOOKUP_H
2#define LOOKUP_H
3
4#include <stdint.h>
5#include <stddef.h>
6#include <features.h>
7#include <netinet/in.h>
8#include <netdb.h>
9
10struct aibuf {
11 struct addrinfo ai;
12 union sa {
13 struct sockaddr_in sin;
14 struct sockaddr_in6 sin6;
15 } sa;
16 volatile int lock[1];
17 short slot, ref;
18};
19
20struct address {
21 int family;
22 unsigned scopeid;
23 uint8_t addr[16];
24 int sortkey;
25};
26
27struct service {
28 uint16_t port;
29 unsigned char proto, socktype;
30};
31
32#define MAXNS 3
33
34struct resolvconf {
35 struct address ns[MAXNS];
36 unsigned nns, attempts, ndots;
37 unsigned timeout;
38};
39
40/* The limit of 48 results is a non-sharp bound on the number of addresses
41 * that can fit in one 512-byte DNS packet full of v4 results and a second
42 * packet full of v6 results. Due to headers, the actual limit is lower. */
43#define MAXADDRS 48
44#define MAXSERVS 2
45
46hidden int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags);
47hidden int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags);
48hidden int __lookup_ipliteral(struct address buf[static 1], const char *name, int family);
49
50hidden int __get_resolv_conf(struct resolvconf *, char *, size_t);
51hidden int __res_msend_rc(int, const unsigned char *const *, const int *, unsigned char *const *, int *, int, const struct resolvconf *);
52
53hidden int __dns_parse(const unsigned char *, int, int (*)(void *, int, const void *, int, const void *), void *);
54
55#endif
libc/musl/src/network/lookup_ipliteral.c created+55
......@@ -0,0 +1,55 @@
1#include <sys/socket.h>
2#include <netinet/in.h>
3#include <netdb.h>
4#include <net/if.h>
5#include <arpa/inet.h>
6#include <limits.h>
7#include <stdlib.h>
8#include <string.h>
9#include <ctype.h>
10#include "lookup.h"
11
12int __lookup_ipliteral(struct address buf[static 1], const char *name, int family)
13{
14 struct in_addr a4;
15 struct in6_addr a6;
16 if (__inet_aton(name, &a4) > 0) {
17 if (family == AF_INET6) /* wrong family */
18 return EAI_NONAME;
19 memcpy(&buf[0].addr, &a4, sizeof a4);
20 buf[0].family = AF_INET;
21 buf[0].scopeid = 0;
22 return 1;
23 }
24
25 char tmp[64];
26 char *p = strchr(name, '%'), *z;
27 unsigned long long scopeid = 0;
28 if (p && p-name < 64) {
29 memcpy(tmp, name, p-name);
30 tmp[p-name] = 0;
31 name = tmp;
32 }
33
34 if (inet_pton(AF_INET6, name, &a6) <= 0)
35 return 0;
36 if (family == AF_INET) /* wrong family */
37 return EAI_NONAME;
38
39 memcpy(&buf[0].addr, &a6, sizeof a6);
40 buf[0].family = AF_INET6;
41 if (p) {
42 if (isdigit(*++p)) scopeid = strtoull(p, &z, 10);
43 else z = p-1;
44 if (*z) {
45 if (!IN6_IS_ADDR_LINKLOCAL(&a6) &&
46 !IN6_IS_ADDR_MC_LINKLOCAL(&a6))
47 return EAI_NONAME;
48 scopeid = if_nametoindex(p);
49 if (!scopeid) return EAI_NONAME;
50 }
51 if (scopeid > UINT_MAX) return EAI_NONAME;
52 }
53 buf[0].scopeid = scopeid;
54 return 1;
55}
libc/musl/src/network/lookup_name.c created+416
......@@ -0,0 +1,416 @@
1#include <sys/socket.h>
2#include <netinet/in.h>
3#include <netdb.h>
4#include <net/if.h>
5#include <arpa/inet.h>
6#include <ctype.h>
7#include <stdlib.h>
8#include <string.h>
9#include <fcntl.h>
10#include <unistd.h>
11#include <pthread.h>
12#include <errno.h>
13#include <resolv.h>
14#include "lookup.h"
15#include "stdio_impl.h"
16#include "syscall.h"
17
18static int is_valid_hostname(const char *host)
19{
20 const unsigned char *s;
21 if (strnlen(host, 255)-1 >= 254 || mbstowcs(0, host, 0) == -1) return 0;
22 for (s=(void *)host; *s>=0x80 || *s=='.' || *s=='-' || isalnum(*s); s++);
23 return !*s;
24}
25
26static int name_from_null(struct address buf[static 2], const char *name, int family, int flags)
27{
28 int cnt = 0;
29 if (name) return 0;
30 if (flags & AI_PASSIVE) {
31 if (family != AF_INET6)
32 buf[cnt++] = (struct address){ .family = AF_INET };
33 if (family != AF_INET)
34 buf[cnt++] = (struct address){ .family = AF_INET6 };
35 } else {
36 if (family != AF_INET6)
37 buf[cnt++] = (struct address){ .family = AF_INET, .addr = { 127,0,0,1 } };
38 if (family != AF_INET)
39 buf[cnt++] = (struct address){ .family = AF_INET6, .addr = { [15] = 1 } };
40 }
41 return cnt;
42}
43
44static int name_from_numeric(struct address buf[static 1], const char *name, int family)
45{
46 return __lookup_ipliteral(buf, name, family);
47}
48
49static int name_from_hosts(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
50{
51 char line[512];
52 size_t l = strlen(name);
53 int cnt = 0, badfam = 0;
54 unsigned char _buf[1032];
55 FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
56 if (!f) switch (errno) {
57 case ENOENT:
58 case ENOTDIR:
59 case EACCES:
60 return 0;
61 default:
62 return EAI_SYSTEM;
63 }
64 while (fgets(line, sizeof line, f) && cnt < MAXADDRS) {
65 char *p, *z;
66
67 if ((p=strchr(line, '#'))) *p++='\n', *p=0;
68 for(p=line+1; (p=strstr(p, name)) &&
69 (!isspace(p[-1]) || !isspace(p[l])); p++);
70 if (!p) continue;
71
72 /* Isolate IP address to parse */
73 for (p=line; *p && !isspace(*p); p++);
74 *p++ = 0;
75 switch (name_from_numeric(buf+cnt, line, family)) {
76 case 1:
77 cnt++;
78 break;
79 case 0:
80 continue;
81 default:
82 badfam = EAI_NONAME;
83 continue;
84 }
85
86 /* Extract first name as canonical name */
87 for (; *p && isspace(*p); p++);
88 for (z=p; *z && !isspace(*z); z++);
89 *z = 0;
90 if (is_valid_hostname(p)) memcpy(canon, p, z-p+1);
91 }
92 __fclose_ca(f);
93 return cnt ? cnt : badfam;
94}
95
96struct dpc_ctx {
97 struct address *addrs;
98 char *canon;
99 int cnt;
100};
101
102#define RR_A 1
103#define RR_CNAME 5
104#define RR_AAAA 28
105
106static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
107{
108 char tmp[256];
109 struct dpc_ctx *ctx = c;
110 if (ctx->cnt >= MAXADDRS) return -1;
111 switch (rr) {
112 case RR_A:
113 if (len != 4) return -1;
114 ctx->addrs[ctx->cnt].family = AF_INET;
115 ctx->addrs[ctx->cnt].scopeid = 0;
116 memcpy(ctx->addrs[ctx->cnt++].addr, data, 4);
117 break;
118 case RR_AAAA:
119 if (len != 16) return -1;
120 ctx->addrs[ctx->cnt].family = AF_INET6;
121 ctx->addrs[ctx->cnt].scopeid = 0;
122 memcpy(ctx->addrs[ctx->cnt++].addr, data, 16);
123 break;
124 case RR_CNAME:
125 if (__dn_expand(packet, (const unsigned char *)packet + 512,
126 data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
127 strcpy(ctx->canon, tmp);
128 break;
129 }
130 return 0;
131}
132
133static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf)
134{
135 unsigned char qbuf[2][280], abuf[2][512];
136 const unsigned char *qp[2] = { qbuf[0], qbuf[1] };
137 unsigned char *ap[2] = { abuf[0], abuf[1] };
138 int qlens[2], alens[2];
139 int i, nq = 0;
140 struct dpc_ctx ctx = { .addrs = buf, .canon = canon };
141 static const struct { int af; int rr; } afrr[2] = {
142 { .af = AF_INET6, .rr = RR_A },
143 { .af = AF_INET, .rr = RR_AAAA },
144 };
145
146 for (i=0; i<2; i++) {
147 if (family != afrr[i].af) {
148 qlens[nq] = __res_mkquery(0, name, 1, afrr[i].rr,
149 0, 0, 0, qbuf[nq], sizeof *qbuf);
150 if (qlens[nq] == -1)
151 return EAI_NONAME;
152 nq++;
153 }
154 }
155
156 if (__res_msend_rc(nq, qp, qlens, ap, alens, sizeof *abuf, conf) < 0)
157 return EAI_SYSTEM;
158
159 for (i=0; i<nq; i++)
160 __dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
161
162 if (ctx.cnt) return ctx.cnt;
163 if (alens[0] < 4 || (abuf[0][3] & 15) == 2) return EAI_AGAIN;
164 if ((abuf[0][3] & 15) == 0) return EAI_NONAME;
165 if ((abuf[0][3] & 15) == 3) return 0;
166 return EAI_FAIL;
167}
168
169static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
170{
171 char search[256];
172 struct resolvconf conf;
173 size_t l, dots;
174 char *p, *z;
175
176 if (__get_resolv_conf(&conf, search, sizeof search) < 0) return -1;
177
178 /* Count dots, suppress search when >=ndots or name ends in
179 * a dot, which is an explicit request for global scope. */
180 for (dots=l=0; name[l]; l++) if (name[l]=='.') dots++;
181 if (dots >= conf.ndots || name[l-1]=='.') *search = 0;
182
183 /* Strip final dot for canon, fail if multiple trailing dots. */
184 if (name[l-1]=='.') l--;
185 if (!l || name[l-1]=='.') return EAI_NONAME;
186
187 /* This can never happen; the caller already checked length. */
188 if (l >= 256) return EAI_NONAME;
189
190 /* Name with search domain appended is setup in canon[]. This both
191 * provides the desired default canonical name (if the requested
192 * name is not a CNAME record) and serves as a buffer for passing
193 * the full requested name to name_from_dns. */
194 memcpy(canon, name, l);
195 canon[l] = '.';
196
197 for (p=search; *p; p=z) {
198 for (; isspace(*p); p++);
199 for (z=p; *z && !isspace(*z); z++);
200 if (z==p) break;
201 if (z-p < 256 - l - 1) {
202 memcpy(canon+l+1, p, z-p);
203 canon[z-p+1+l] = 0;
204 int cnt = name_from_dns(buf, canon, canon, family, &conf);
205 if (cnt) return cnt;
206 }
207 }
208
209 canon[l] = 0;
210 return name_from_dns(buf, canon, name, family, &conf);
211}
212
213static const struct policy {
214 unsigned char addr[16];
215 unsigned char len, mask;
216 unsigned char prec, label;
217} defpolicy[] = {
218 { "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1", 15, 0xff, 50, 0 },
219 { "\0\0\0\0\0\0\0\0\0\0\xff\xff", 11, 0xff, 35, 4 },
220 { "\x20\2", 1, 0xff, 30, 2 },
221 { "\x20\1", 3, 0xff, 5, 5 },
222 { "\xfc", 0, 0xfe, 3, 13 },
223#if 0
224 /* These are deprecated and/or returned to the address
225 * pool, so despite the RFC, treating them as special
226 * is probably wrong. */
227 { "", 11, 0xff, 1, 3 },
228 { "\xfe\xc0", 1, 0xc0, 1, 11 },
229 { "\x3f\xfe", 1, 0xff, 1, 12 },
230#endif
231 /* Last rule must match all addresses to stop loop. */
232 { "", 0, 0, 40, 1 },
233};
234
235static const struct policy *policyof(const struct in6_addr *a)
236{
237 int i;
238 for (i=0; ; i++) {
239 if (memcmp(a->s6_addr, defpolicy[i].addr, defpolicy[i].len))
240 continue;
241 if ((a->s6_addr[defpolicy[i].len] & defpolicy[i].mask)
242 != defpolicy[i].addr[defpolicy[i].len])
243 continue;
244 return defpolicy+i;
245 }
246}
247
248static int labelof(const struct in6_addr *a)
249{
250 return policyof(a)->label;
251}
252
253static int scopeof(const struct in6_addr *a)
254{
255 if (IN6_IS_ADDR_MULTICAST(a)) return a->s6_addr[1] & 15;
256 if (IN6_IS_ADDR_LINKLOCAL(a)) return 2;
257 if (IN6_IS_ADDR_LOOPBACK(a)) return 2;
258 if (IN6_IS_ADDR_SITELOCAL(a)) return 5;
259 return 14;
260}
261
262static int prefixmatch(const struct in6_addr *s, const struct in6_addr *d)
263{
264 /* FIXME: The common prefix length should be limited to no greater
265 * than the nominal length of the prefix portion of the source
266 * address. However the definition of the source prefix length is
267 * not clear and thus this limiting is not yet implemented. */
268 unsigned i;
269 for (i=0; i<128 && !((s->s6_addr[i/8]^d->s6_addr[i/8])&(128>>(i%8))); i++);
270 return i;
271}
272
273#define DAS_USABLE 0x40000000
274#define DAS_MATCHINGSCOPE 0x20000000
275#define DAS_MATCHINGLABEL 0x10000000
276#define DAS_PREC_SHIFT 20
277#define DAS_SCOPE_SHIFT 16
278#define DAS_PREFIX_SHIFT 8
279#define DAS_ORDER_SHIFT 0
280
281static int addrcmp(const void *_a, const void *_b)
282{
283 const struct address *a = _a, *b = _b;
284 return b->sortkey - a->sortkey;
285}
286
287int __lookup_name(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, int flags)
288{
289 int cnt = 0, i, j;
290
291 *canon = 0;
292 if (name) {
293 /* reject empty name and check len so it fits into temp bufs */
294 size_t l = strnlen(name, 255);
295 if (l-1 >= 254)
296 return EAI_NONAME;
297 memcpy(canon, name, l+1);
298 }
299
300 /* Procedurally, a request for v6 addresses with the v4-mapped
301 * flag set is like a request for unspecified family, followed
302 * by filtering of the results. */
303 if (flags & AI_V4MAPPED) {
304 if (family == AF_INET6) family = AF_UNSPEC;
305 else flags -= AI_V4MAPPED;
306 }
307
308 /* Try each backend until there's at least one result. */
309 cnt = name_from_null(buf, name, family, flags);
310 if (!cnt) cnt = name_from_numeric(buf, name, family);
311 if (!cnt && !(flags & AI_NUMERICHOST)) {
312 cnt = name_from_hosts(buf, canon, name, family);
313 if (!cnt) cnt = name_from_dns_search(buf, canon, name, family);
314 }
315 if (cnt<=0) return cnt ? cnt : EAI_NONAME;
316
317 /* Filter/transform results for v4-mapped lookup, if requested. */
318 if (flags & AI_V4MAPPED) {
319 if (!(flags & AI_ALL)) {
320 /* If any v6 results exist, remove v4 results. */
321 for (i=0; i<cnt && buf[i].family != AF_INET6; i++);
322 if (i<cnt) {
323 for (j=0; i<cnt; i++) {
324 if (buf[i].family == AF_INET6)
325 buf[j++] = buf[i];
326 }
327 cnt = i = j;
328 }
329 }
330 /* Translate any remaining v4 results to v6 */
331 for (i=0; i<cnt; i++) {
332 if (buf[i].family != AF_INET) continue;
333 memcpy(buf[i].addr+12, buf[i].addr, 4);
334 memcpy(buf[i].addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
335 buf[i].family = AF_INET6;
336 }
337 }
338
339 /* No further processing is needed if there are fewer than 2
340 * results or if there are only IPv4 results. */
341 if (cnt<2 || family==AF_INET) return cnt;
342 for (i=0; i<cnt; i++) if (buf[i].family != AF_INET) break;
343 if (i==cnt) return cnt;
344
345 int cs;
346 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
347
348 /* The following implements a subset of RFC 3484/6724 destination
349 * address selection by generating a single 31-bit sort key for
350 * each address. Rules 3, 4, and 7 are omitted for having
351 * excessive runtime and code size cost and dubious benefit.
352 * So far the label/precedence table cannot be customized. */
353 for (i=0; i<cnt; i++) {
354 int family = buf[i].family;
355 int key = 0;
356 struct sockaddr_in6 sa6 = { 0 }, da6 = {
357 .sin6_family = AF_INET6,
358 .sin6_scope_id = buf[i].scopeid,
359 .sin6_port = 65535
360 };
361 struct sockaddr_in sa4 = { 0 }, da4 = {
362 .sin_family = AF_INET,
363 .sin_port = 65535
364 };
365 void *sa, *da;
366 socklen_t salen, dalen;
367 if (family == AF_INET6) {
368 memcpy(da6.sin6_addr.s6_addr, buf[i].addr, 16);
369 da = &da6; dalen = sizeof da6;
370 sa = &sa6; salen = sizeof sa6;
371 } else {
372 memcpy(sa6.sin6_addr.s6_addr,
373 "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
374 memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4);
375 memcpy(da6.sin6_addr.s6_addr,
376 "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
377 memcpy(da6.sin6_addr.s6_addr+12, buf[i].addr, 4);
378 memcpy(&da4.sin_addr, buf[i].addr, 4);
379 da = &da4; dalen = sizeof da4;
380 sa = &sa4; salen = sizeof sa4;
381 }
382 const struct policy *dpolicy = policyof(&da6.sin6_addr);
383 int dscope = scopeof(&da6.sin6_addr);
384 int dlabel = dpolicy->label;
385 int dprec = dpolicy->prec;
386 int prefixlen = 0;
387 int fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP);
388 if (fd >= 0) {
389 if (!connect(fd, da, dalen)) {
390 key |= DAS_USABLE;
391 if (!getsockname(fd, sa, &salen)) {
392 if (family == AF_INET) memcpy(
393 sa6.sin6_addr.s6_addr+12,
394 &sa4.sin_addr, 4);
395 if (dscope == scopeof(&sa6.sin6_addr))
396 key |= DAS_MATCHINGSCOPE;
397 if (dlabel == labelof(&sa6.sin6_addr))
398 key |= DAS_MATCHINGLABEL;
399 prefixlen = prefixmatch(&sa6.sin6_addr,
400 &da6.sin6_addr);
401 }
402 }
403 close(fd);
404 }
405 key |= dprec << DAS_PREC_SHIFT;
406 key |= (15-dscope) << DAS_SCOPE_SHIFT;
407 key |= prefixlen << DAS_PREFIX_SHIFT;
408 key |= (MAXADDRS-i) << DAS_ORDER_SHIFT;
409 buf[i].sortkey = key;
410 }
411 qsort(buf, cnt, sizeof *buf, addrcmp);
412
413 pthread_setcancelstate(cs, 0);
414
415 return cnt;
416}
libc/musl/src/network/lookup_serv.c created+114
......@@ -0,0 +1,114 @@
1#include <sys/socket.h>
2#include <netinet/in.h>
3#include <netdb.h>
4#include <ctype.h>
5#include <string.h>
6#include <stdlib.h>
7#include <fcntl.h>
8#include <errno.h>
9#include "lookup.h"
10#include "stdio_impl.h"
11
12int __lookup_serv(struct service buf[static MAXSERVS], const char *name, int proto, int socktype, int flags)
13{
14 char line[128];
15 int cnt = 0;
16 char *p, *z = "";
17 unsigned long port = 0;
18
19 switch (socktype) {
20 case SOCK_STREAM:
21 switch (proto) {
22 case 0:
23 proto = IPPROTO_TCP;
24 case IPPROTO_TCP:
25 break;
26 default:
27 return EAI_SERVICE;
28 }
29 break;
30 case SOCK_DGRAM:
31 switch (proto) {
32 case 0:
33 proto = IPPROTO_UDP;
34 case IPPROTO_UDP:
35 break;
36 default:
37 return EAI_SERVICE;
38 }
39 case 0:
40 break;
41 default:
42 if (name) return EAI_SERVICE;
43 buf[0].port = 0;
44 buf[0].proto = proto;
45 buf[0].socktype = socktype;
46 return 1;
47 }
48
49 if (name) {
50 if (!*name) return EAI_SERVICE;
51 port = strtoul(name, &z, 10);
52 }
53 if (!*z) {
54 if (port > 65535) return EAI_SERVICE;
55 if (proto != IPPROTO_UDP) {
56 buf[cnt].port = port;
57 buf[cnt].socktype = SOCK_STREAM;
58 buf[cnt++].proto = IPPROTO_TCP;
59 }
60 if (proto != IPPROTO_TCP) {
61 buf[cnt].port = port;
62 buf[cnt].socktype = SOCK_DGRAM;
63 buf[cnt++].proto = IPPROTO_UDP;
64 }
65 return cnt;
66 }
67
68 if (flags & AI_NUMERICSERV) return EAI_NONAME;
69
70 size_t l = strlen(name);
71
72 unsigned char _buf[1032];
73 FILE _f, *f = __fopen_rb_ca("/etc/services", &_f, _buf, sizeof _buf);
74 if (!f) switch (errno) {
75 case ENOENT:
76 case ENOTDIR:
77 case EACCES:
78 return EAI_SERVICE;
79 default:
80 return EAI_SYSTEM;
81 }
82
83 while (fgets(line, sizeof line, f) && cnt < MAXSERVS) {
84 if ((p=strchr(line, '#'))) *p++='\n', *p=0;
85
86 /* Find service name */
87 for(p=line; (p=strstr(p, name)); p++) {
88 if (p>line && !isspace(p[-1])) continue;
89 if (p[l] && !isspace(p[l])) continue;
90 break;
91 }
92 if (!p) continue;
93
94 /* Skip past canonical name at beginning of line */
95 for (p=line; *p && !isspace(*p); p++);
96
97 port = strtoul(p, &z, 10);
98 if (port > 65535 || z==p) continue;
99 if (!strncmp(z, "/udp", 4)) {
100 if (proto == IPPROTO_TCP) continue;
101 buf[cnt].port = port;
102 buf[cnt].socktype = SOCK_DGRAM;
103 buf[cnt++].proto = IPPROTO_UDP;
104 }
105 if (!strncmp(z, "/tcp", 4)) {
106 if (proto == IPPROTO_UDP) continue;
107 buf[cnt].port = port;
108 buf[cnt].socktype = SOCK_STREAM;
109 buf[cnt++].proto = IPPROTO_TCP;
110 }
111 }
112 __fclose_ca(f);
113 return cnt > 0 ? cnt : EAI_SERVICE;
114}
libc/musl/src/network/netlink.c created+52
......@@ -0,0 +1,52 @@
1#include <errno.h>
2#include <string.h>
3#include <syscall.h>
4#include <sys/socket.h>
5#include "netlink.h"
6
7static int __netlink_enumerate(int fd, unsigned int seq, int type, int af,
8 int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
9{
10 struct nlmsghdr *h;
11 union {
12 uint8_t buf[8192];
13 struct {
14 struct nlmsghdr nlh;
15 struct rtgenmsg g;
16 } req;
17 struct nlmsghdr reply;
18 } u;
19 int r, ret;
20
21 memset(&u.req, 0, sizeof(u.req));
22 u.req.nlh.nlmsg_len = sizeof(u.req);
23 u.req.nlh.nlmsg_type = type;
24 u.req.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
25 u.req.nlh.nlmsg_seq = seq;
26 u.req.g.rtgen_family = af;
27 r = send(fd, &u.req, sizeof(u.req), 0);
28 if (r < 0) return r;
29
30 while (1) {
31 r = recv(fd, u.buf, sizeof(u.buf), MSG_DONTWAIT);
32 if (r <= 0) return -1;
33 for (h = &u.reply; NLMSG_OK(h, (void*)&u.buf[r]); h = NLMSG_NEXT(h)) {
34 if (h->nlmsg_type == NLMSG_DONE) return 0;
35 if (h->nlmsg_type == NLMSG_ERROR) return -1;
36 ret = cb(ctx, h);
37 if (ret) return ret;
38 }
39 }
40}
41
42int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx)
43{
44 int fd, r;
45
46 fd = socket(PF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE);
47 if (fd < 0) return -1;
48 r = __netlink_enumerate(fd, 1, RTM_GETLINK, link_af, cb, ctx);
49 if (!r) r = __netlink_enumerate(fd, 2, RTM_GETADDR, addr_af, cb, ctx);
50 __syscall(SYS_close,fd);
51 return r;
52}
libc/musl/src/network/netlink.h created+94
......@@ -0,0 +1,94 @@
1#include <stdint.h>
2
3/* linux/netlink.h */
4
5#define NETLINK_ROUTE 0
6
7struct nlmsghdr {
8 uint32_t nlmsg_len;
9 uint16_t nlmsg_type;
10 uint16_t nlmsg_flags;
11 uint32_t nlmsg_seq;
12 uint32_t nlmsg_pid;
13};
14
15#define NLM_F_REQUEST 1
16#define NLM_F_MULTI 2
17#define NLM_F_ACK 4
18
19#define NLM_F_ROOT 0x100
20#define NLM_F_MATCH 0x200
21#define NLM_F_ATOMIC 0x400
22#define NLM_F_DUMP (NLM_F_ROOT|NLM_F_MATCH)
23
24#define NLMSG_NOOP 0x1
25#define NLMSG_ERROR 0x2
26#define NLMSG_DONE 0x3
27#define NLMSG_OVERRUN 0x4
28
29/* linux/rtnetlink.h */
30
31#define RTM_NEWLINK 16
32#define RTM_GETLINK 18
33#define RTM_NEWADDR 20
34#define RTM_GETADDR 22
35
36struct rtattr {
37 unsigned short rta_len;
38 unsigned short rta_type;
39};
40
41struct rtgenmsg {
42 unsigned char rtgen_family;
43};
44
45struct ifinfomsg {
46 unsigned char ifi_family;
47 unsigned char __ifi_pad;
48 unsigned short ifi_type;
49 int ifi_index;
50 unsigned ifi_flags;
51 unsigned ifi_change;
52};
53
54/* linux/if_link.h */
55
56#define IFLA_ADDRESS 1
57#define IFLA_BROADCAST 2
58#define IFLA_IFNAME 3
59#define IFLA_STATS 7
60
61/* linux/if_addr.h */
62
63struct ifaddrmsg {
64 uint8_t ifa_family;
65 uint8_t ifa_prefixlen;
66 uint8_t ifa_flags;
67 uint8_t ifa_scope;
68 uint32_t ifa_index;
69};
70
71#define IFA_ADDRESS 1
72#define IFA_LOCAL 2
73#define IFA_LABEL 3
74#define IFA_BROADCAST 4
75
76/* musl */
77
78#define NETLINK_ALIGN(len) (((len)+3) & ~3)
79#define NLMSG_DATA(nlh) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr)))
80#define NLMSG_DATALEN(nlh) ((nlh)->nlmsg_len-sizeof(struct nlmsghdr))
81#define NLMSG_DATAEND(nlh) ((char*)(nlh)+(nlh)->nlmsg_len)
82#define NLMSG_NEXT(nlh) (struct nlmsghdr*)((char*)(nlh)+NETLINK_ALIGN((nlh)->nlmsg_len))
83#define NLMSG_OK(nlh,end) ((char*)(end)-(char*)(nlh) >= sizeof(struct nlmsghdr))
84
85#define RTA_DATA(rta) ((void*)((char*)(rta)+sizeof(struct rtattr)))
86#define RTA_DATALEN(rta) ((rta)->rta_len-sizeof(struct rtattr))
87#define RTA_DATAEND(rta) ((char*)(rta)+(rta)->rta_len)
88#define RTA_NEXT(rta) (struct rtattr*)((char*)(rta)+NETLINK_ALIGN((rta)->rta_len))
89#define RTA_OK(nlh,end) ((char*)(end)-(char*)(rta) >= sizeof(struct rtattr))
90
91#define NLMSG_RTA(nlh,len) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr)+NETLINK_ALIGN(len)))
92#define NLMSG_RTAOK(rta,nlh) RTA_OK(rta,NLMSG_DATAEND(nlh))
93
94hidden int __rtnetlink_enumerate(int link_af, int addr_af, int (*cb)(void *ctx, struct nlmsghdr *h), void *ctx);
libc/musl/src/network/netname.c created+12
......@@ -0,0 +1,12 @@
1#include <netdb.h>
2
3struct netent *getnetbyaddr(uint32_t net, int type)
4{
5 return 0;
6}
7
8struct netent *getnetbyname(const char *name)
9{
10 return 0;
11}
12
libc/musl/src/network/ns_parse.c created+171
......@@ -0,0 +1,171 @@
1#define _BSD_SOURCE
2#include <errno.h>
3#include <stddef.h>
4#include <resolv.h>
5#include <arpa/nameser.h>
6
7const struct _ns_flagdata _ns_flagdata[16] = {
8 { 0x8000, 15 },
9 { 0x7800, 11 },
10 { 0x0400, 10 },
11 { 0x0200, 9 },
12 { 0x0100, 8 },
13 { 0x0080, 7 },
14 { 0x0040, 6 },
15 { 0x0020, 5 },
16 { 0x0010, 4 },
17 { 0x000f, 0 },
18 { 0x0000, 0 },
19 { 0x0000, 0 },
20 { 0x0000, 0 },
21 { 0x0000, 0 },
22 { 0x0000, 0 },
23 { 0x0000, 0 },
24};
25
26unsigned ns_get16(const unsigned char *cp)
27{
28 return cp[0]<<8 | cp[1];
29}
30
31unsigned long ns_get32(const unsigned char *cp)
32{
33 return (unsigned)cp[0]<<24 | cp[1]<<16 | cp[2]<<8 | cp[3];
34}
35
36void ns_put16(unsigned s, unsigned char *cp)
37{
38 *cp++ = s>>8;
39 *cp++ = s;
40}
41
42void ns_put32(unsigned long l, unsigned char *cp)
43{
44 *cp++ = l>>24;
45 *cp++ = l>>16;
46 *cp++ = l>>8;
47 *cp++ = l;
48}
49
50int ns_initparse(const unsigned char *msg, int msglen, ns_msg *handle)
51{
52 int i, r;
53
54 handle->_msg = msg;
55 handle->_eom = msg + msglen;
56 if (msglen < (2 + ns_s_max) * NS_INT16SZ) goto bad;
57 NS_GET16(handle->_id, msg);
58 NS_GET16(handle->_flags, msg);
59 for (i = 0; i < ns_s_max; i++) NS_GET16(handle->_counts[i], msg);
60 for (i = 0; i < ns_s_max; i++) {
61 if (handle->_counts[i]) {
62 handle->_sections[i] = msg;
63 r = ns_skiprr(msg, handle->_eom, i, handle->_counts[i]);
64 if (r < 0) return -1;
65 msg += r;
66 } else {
67 handle->_sections[i] = NULL;
68 }
69 }
70 if (msg != handle->_eom) goto bad;
71 handle->_sect = ns_s_max;
72 handle->_rrnum = -1;
73 handle->_msg_ptr = NULL;
74 return 0;
75bad:
76 errno = EMSGSIZE;
77 return -1;
78}
79
80int ns_skiprr(const unsigned char *ptr, const unsigned char *eom, ns_sect section, int count)
81{
82 const unsigned char *p = ptr;
83 int r;
84
85 while (count--) {
86 r = dn_skipname(p, eom);
87 if (r < 0) goto bad;
88 if (r + 2 * NS_INT16SZ > eom - p) goto bad;
89 p += r + 2 * NS_INT16SZ;
90 if (section != ns_s_qd) {
91 if (NS_INT32SZ + NS_INT16SZ > eom - p) goto bad;
92 p += NS_INT32SZ;
93 NS_GET16(r, p);
94 if (r > eom - p) goto bad;
95 p += r;
96 }
97 }
98 return p - ptr;
99bad:
100 errno = EMSGSIZE;
101 return -1;
102}
103
104int ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr)
105{
106 int r;
107
108 if (section < 0 || section >= ns_s_max) goto bad;
109 if (section != handle->_sect) {
110 handle->_sect = section;
111 handle->_rrnum = 0;
112 handle->_msg_ptr = handle->_sections[section];
113 }
114 if (rrnum == -1) rrnum = handle->_rrnum;
115 if (rrnum < 0 || rrnum >= handle->_counts[section]) goto bad;
116 if (rrnum < handle->_rrnum) {
117 handle->_rrnum = 0;
118 handle->_msg_ptr = handle->_sections[section];
119 }
120 if (rrnum > handle->_rrnum) {
121 r = ns_skiprr(handle->_msg_ptr, handle->_eom, section, rrnum - handle->_rrnum);
122 if (r < 0) return -1;
123 handle->_msg_ptr += r;
124 handle->_rrnum = rrnum;
125 }
126 r = ns_name_uncompress(handle->_msg, handle->_eom, handle->_msg_ptr, rr->name, NS_MAXDNAME);
127 if (r < 0) return -1;
128 handle->_msg_ptr += r;
129 if (2 * NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
130 NS_GET16(rr->type, handle->_msg_ptr);
131 NS_GET16(rr->rr_class, handle->_msg_ptr);
132 if (section != ns_s_qd) {
133 if (NS_INT32SZ + NS_INT16SZ > handle->_eom - handle->_msg_ptr) goto size;
134 NS_GET32(rr->ttl, handle->_msg_ptr);
135 NS_GET16(rr->rdlength, handle->_msg_ptr);
136 if (rr->rdlength > handle->_eom - handle->_msg_ptr) goto size;
137 rr->rdata = handle->_msg_ptr;
138 handle->_msg_ptr += rr->rdlength;
139 } else {
140 rr->ttl = 0;
141 rr->rdlength = 0;
142 rr->rdata = NULL;
143 }
144 handle->_rrnum++;
145 if (handle->_rrnum > handle->_counts[section]) {
146 handle->_sect = section + 1;
147 if (handle->_sect == ns_s_max) {
148 handle->_rrnum = -1;
149 handle->_msg_ptr = NULL;
150 } else {
151 handle->_rrnum = 0;
152 }
153 }
154 return 0;
155bad:
156 errno = ENODEV;
157 return -1;
158size:
159 errno = EMSGSIZE;
160 return -1;
161}
162
163int ns_name_uncompress(const unsigned char *msg, const unsigned char *eom,
164 const unsigned char *src, char *dst, size_t dstsiz)
165{
166 int r;
167 r = dn_expand(msg, eom, src, dst, dstsiz);
168 if (r < 0) errno = EMSGSIZE;
169 return r;
170}
171
libc/musl/src/network/ntohl.c created+8
......@@ -0,0 +1,8 @@
1#include <netinet/in.h>
2#include <byteswap.h>
3
4uint32_t ntohl(uint32_t n)
5{
6 union { int i; char c; } u = { 1 };
7 return u.c ? bswap_32(n) : n;
8}
libc/musl/src/network/ntohs.c created+8
......@@ -0,0 +1,8 @@
1#include <netinet/in.h>
2#include <byteswap.h>
3
4uint16_t ntohs(uint16_t n)
5{
6 union { int i; char c; } u = { 1 };
7 return u.c ? bswap_16(n) : n;
8}
libc/musl/src/network/proto.c created+84
......@@ -0,0 +1,84 @@
1#include <netdb.h>
2#include <string.h>
3
4/* do we really need all these?? */
5
6static int idx;
7static const unsigned char protos[] = {
8 "\000ip\0"
9 "\001icmp\0"
10 "\002igmp\0"
11 "\003ggp\0"
12 "\004ipencap\0"
13 "\005st\0"
14 "\006tcp\0"
15 "\010egp\0"
16 "\014pup\0"
17 "\021udp\0"
18 "\024hmp\0"
19 "\026xns-idp\0"
20 "\033rdp\0"
21 "\035iso-tp4\0"
22 "\044xtp\0"
23 "\045ddp\0"
24 "\046idpr-cmtp\0"
25 "\051ipv6\0"
26 "\053ipv6-route\0"
27 "\054ipv6-frag\0"
28 "\055idrp\0"
29 "\056rsvp\0"
30 "\057gre\0"
31 "\062esp\0"
32 "\063ah\0"
33 "\071skip\0"
34 "\072ipv6-icmp\0"
35 "\073ipv6-nonxt\0"
36 "\074ipv6-opts\0"
37 "\111rspf\0"
38 "\121vmtp\0"
39 "\131ospf\0"
40 "\136ipip\0"
41 "\142encap\0"
42 "\147pim\0"
43 "\377raw"
44};
45
46void endprotoent(void)
47{
48 idx = 0;
49}
50
51void setprotoent(int stayopen)
52{
53 idx = 0;
54}
55
56struct protoent *getprotoent(void)
57{
58 static struct protoent p;
59 static const char *aliases;
60 if (idx >= sizeof protos) return NULL;
61 p.p_proto = protos[idx];
62 p.p_name = (char *)&protos[idx+1];
63 p.p_aliases = (char **)&aliases;
64 idx += strlen(p.p_name) + 2;
65 return &p;
66}
67
68struct protoent *getprotobyname(const char *name)
69{
70 struct protoent *p;
71 endprotoent();
72 do p = getprotoent();
73 while (p && strcmp(name, p->p_name));
74 return p;
75}
76
77struct protoent *getprotobynumber(int num)
78{
79 struct protoent *p;
80 endprotoent();
81 do p = getprotoent();
82 while (p && p->p_proto != num);
83 return p;
84}
libc/musl/src/network/recv.c created+6
......@@ -0,0 +1,6 @@
1#include <sys/socket.h>
2
3ssize_t recv(int fd, void *buf, size_t len, int flags)
4{
5 return recvfrom(fd, buf, len, flags, 0, 0);
6}
libc/musl/src/network/recvfrom.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4ssize_t recvfrom(int fd, void *restrict buf, size_t len, int flags, struct sockaddr *restrict addr, socklen_t *restrict alen)
5{
6 return socketcall_cp(recvfrom, fd, buf, len, flags, addr, alen);
7}
libc/musl/src/network/recvmmsg.c created+15
......@@ -0,0 +1,15 @@
1#define _GNU_SOURCE
2#include <sys/socket.h>
3#include <limits.h>
4#include "syscall.h"
5
6int recvmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags, struct timespec *timeout)
7{
8#if LONG_MAX > INT_MAX
9 struct mmsghdr *mh = msgvec;
10 unsigned int i;
11 for (i = vlen; i; i--, mh++)
12 mh->msg_hdr.__pad1 = mh->msg_hdr.__pad2 = 0;
13#endif
14 return syscall_cp(SYS_recvmmsg, fd, msgvec, vlen, flags, timeout);
15}
libc/musl/src/network/recvmsg.c created+21
......@@ -0,0 +1,21 @@
1#include <sys/socket.h>
2#include <limits.h>
3#include "syscall.h"
4
5ssize_t recvmsg(int fd, struct msghdr *msg, int flags)
6{
7 ssize_t r;
8#if LONG_MAX > INT_MAX
9 struct msghdr h, *orig = msg;
10 if (msg) {
11 h = *msg;
12 h.__pad1 = h.__pad2 = 0;
13 msg = &h;
14 }
15#endif
16 r = socketcall_cp(recvmsg, fd, msg, flags, 0, 0, 0);
17#if LONG_MAX > INT_MAX
18 if (orig) *orig = h;
19#endif
20 return r;
21}
libc/musl/src/network/res_init.c created+6
......@@ -0,0 +1,6 @@
1#include <resolv.h>
2
3int res_init()
4{
5 return 0;
6}
libc/musl/src/network/res_mkquery.c created+43
......@@ -0,0 +1,43 @@
1#include <resolv.h>
2#include <string.h>
3#include <time.h>
4
5int __res_mkquery(int op, const char *dname, int class, int type,
6 const unsigned char *data, int datalen,
7 const unsigned char *newrr, unsigned char *buf, int buflen)
8{
9 int id, i, j;
10 unsigned char q[280];
11 struct timespec ts;
12 size_t l = strnlen(dname, 255);
13 int n;
14
15 if (l && dname[l-1]=='.') l--;
16 n = 17+l+!!l;
17 if (l>253 || buflen<n || op>15u || class>255u || type>255u)
18 return -1;
19
20 /* Construct query template - ID will be filled later */
21 memset(q, 0, n);
22 q[2] = op*8 + 1;
23 q[5] = 1;
24 memcpy((char *)q+13, dname, l);
25 for (i=13; q[i]; i=j+1) {
26 for (j=i; q[j] && q[j] != '.'; j++);
27 if (j-i-1u > 62u) return -1;
28 q[i-1] = j-i;
29 }
30 q[i+1] = type;
31 q[i+3] = class;
32
33 /* Make a reasonably unpredictable id */
34 clock_gettime(CLOCK_REALTIME, &ts);
35 id = ts.tv_nsec + ts.tv_nsec/65536UL & 0xffff;
36 q[0] = id/256;
37 q[1] = id;
38
39 memcpy(buf, q, n);
40 return n;
41}
42
43weak_alias(__res_mkquery, res_mkquery);
libc/musl/src/network/res_msend.c created+188
......@@ -0,0 +1,188 @@
1#include <sys/socket.h>
2#include <netinet/in.h>
3#include <netdb.h>
4#include <arpa/inet.h>
5#include <stdint.h>
6#include <string.h>
7#include <poll.h>
8#include <time.h>
9#include <ctype.h>
10#include <unistd.h>
11#include <errno.h>
12#include <pthread.h>
13#include "stdio_impl.h"
14#include "syscall.h"
15#include "lookup.h"
16
17static void cleanup(void *p)
18{
19 __syscall(SYS_close, (intptr_t)p);
20}
21
22static unsigned long mtime()
23{
24 struct timespec ts;
25 clock_gettime(CLOCK_REALTIME, &ts);
26 return (unsigned long)ts.tv_sec * 1000
27 + ts.tv_nsec / 1000000;
28}
29
30int __res_msend_rc(int nqueries, const unsigned char *const *queries,
31 const int *qlens, unsigned char *const *answers, int *alens, int asize,
32 const struct resolvconf *conf)
33{
34 int fd;
35 int timeout, attempts, retry_interval, servfail_retry;
36 union {
37 struct sockaddr_in sin;
38 struct sockaddr_in6 sin6;
39 } sa = {0}, ns[MAXNS] = {{0}};
40 socklen_t sl = sizeof sa.sin;
41 int nns = 0;
42 int family = AF_INET;
43 int rlen;
44 int next;
45 int i, j;
46 int cs;
47 struct pollfd pfd;
48 unsigned long t0, t1, t2;
49
50 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
51
52 timeout = 1000*conf->timeout;
53 attempts = conf->attempts;
54
55 for (nns=0; nns<conf->nns; nns++) {
56 const struct address *iplit = &conf->ns[nns];
57 if (iplit->family == AF_INET) {
58 memcpy(&ns[nns].sin.sin_addr, iplit->addr, 4);
59 ns[nns].sin.sin_port = htons(53);
60 ns[nns].sin.sin_family = AF_INET;
61 } else {
62 sl = sizeof sa.sin6;
63 memcpy(&ns[nns].sin6.sin6_addr, iplit->addr, 16);
64 ns[nns].sin6.sin6_port = htons(53);
65 ns[nns].sin6.sin6_scope_id = iplit->scopeid;
66 ns[nns].sin6.sin6_family = family = AF_INET6;
67 }
68 }
69
70 /* Get local address and open/bind a socket */
71 sa.sin.sin_family = family;
72 fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
73
74 /* Handle case where system lacks IPv6 support */
75 if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
76 fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
77 family = AF_INET;
78 }
79 if (fd < 0 || bind(fd, (void *)&sa, sl) < 0) {
80 if (fd >= 0) close(fd);
81 pthread_setcancelstate(cs, 0);
82 return -1;
83 }
84
85 /* Past this point, there are no errors. Each individual query will
86 * yield either no reply (indicated by zero length) or an answer
87 * packet which is up to the caller to interpret. */
88
89 pthread_cleanup_push(cleanup, (void *)(intptr_t)fd);
90 pthread_setcancelstate(cs, 0);
91
92 /* Convert any IPv4 addresses in a mixed environment to v4-mapped */
93 if (family == AF_INET6) {
94 setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &(int){0}, sizeof 0);
95 for (i=0; i<nns; i++) {
96 if (ns[i].sin.sin_family != AF_INET) continue;
97 memcpy(ns[i].sin6.sin6_addr.s6_addr+12,
98 &ns[i].sin.sin_addr, 4);
99 memcpy(ns[i].sin6.sin6_addr.s6_addr,
100 "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
101 ns[i].sin6.sin6_family = AF_INET6;
102 ns[i].sin6.sin6_flowinfo = 0;
103 ns[i].sin6.sin6_scope_id = 0;
104 }
105 }
106
107 memset(alens, 0, sizeof *alens * nqueries);
108
109 pfd.fd = fd;
110 pfd.events = POLLIN;
111 retry_interval = timeout / attempts;
112 next = 0;
113 t0 = t2 = mtime();
114 t1 = t2 - retry_interval;
115
116 for (; t2-t0 < timeout; t2=mtime()) {
117 if (t2-t1 >= retry_interval) {
118 /* Query all configured namservers in parallel */
119 for (i=0; i<nqueries; i++)
120 if (!alens[i])
121 for (j=0; j<nns; j++)
122 sendto(fd, queries[i],
123 qlens[i], MSG_NOSIGNAL,
124 (void *)&ns[j], sl);
125 t1 = t2;
126 servfail_retry = 2 * nqueries;
127 }
128
129 /* Wait for a response, or until time to retry */
130 if (poll(&pfd, 1, t1+retry_interval-t2) <= 0) continue;
131
132 while ((rlen = recvfrom(fd, answers[next], asize, 0,
133 (void *)&sa, (socklen_t[1]){sl})) >= 0) {
134
135 /* Ignore non-identifiable packets */
136 if (rlen < 4) continue;
137
138 /* Ignore replies from addresses we didn't send to */
139 for (j=0; j<nns && memcmp(ns+j, &sa, sl); j++);
140 if (j==nns) continue;
141
142 /* Find which query this answer goes with, if any */
143 for (i=next; i<nqueries && (
144 answers[next][0] != queries[i][0] ||
145 answers[next][1] != queries[i][1] ); i++);
146 if (i==nqueries) continue;
147 if (alens[i]) continue;
148
149 /* Only accept positive or negative responses;
150 * retry immediately on server failure, and ignore
151 * all other codes such as refusal. */
152 switch (answers[next][3] & 15) {
153 case 0:
154 case 3:
155 break;
156 case 2:
157 if (servfail_retry && servfail_retry--)
158 sendto(fd, queries[i],
159 qlens[i], MSG_NOSIGNAL,
160 (void *)&ns[j], sl);
161 default:
162 continue;
163 }
164
165 /* Store answer in the right slot, or update next
166 * available temp slot if it's already in place. */
167 alens[i] = rlen;
168 if (i == next)
169 for (; next<nqueries && alens[next]; next++);
170 else
171 memcpy(answers[i], answers[next], rlen);
172
173 if (next == nqueries) goto out;
174 }
175 }
176out:
177 pthread_cleanup_pop(1);
178
179 return 0;
180}
181
182int __res_msend(int nqueries, const unsigned char *const *queries,
183 const int *qlens, unsigned char *const *answers, int *alens, int asize)
184{
185 struct resolvconf conf;
186 if (__get_resolv_conf(&conf, 0, 0) < 0) return -1;
187 return __res_msend_rc(nqueries, queries, qlens, answers, alens, asize, &conf);
188}
libc/musl/src/network/res_query.c created+12
......@@ -0,0 +1,12 @@
1#include <resolv.h>
2#include <netdb.h>
3
4int res_query(const char *name, int class, int type, unsigned char *dest, int len)
5{
6 unsigned char q[280];
7 int ql = __res_mkquery(0, name, class, type, 0, 0, 0, q, sizeof q);
8 if (ql < 0) return ql;
9 return __res_send(q, ql, dest, len);
10}
11
12weak_alias(res_query, res_search);
libc/musl/src/network/res_querydomain.c created+14
......@@ -0,0 +1,14 @@
1#include <resolv.h>
2#include <string.h>
3
4int res_querydomain(const char *name, const char *domain, int class, int type, unsigned char *dest, int len)
5{
6 char tmp[255];
7 size_t nl = strnlen(name, 255);
8 size_t dl = strnlen(domain, 255);
9 if (nl+dl+1 > 254) return -1;
10 memcpy(tmp, name, nl);
11 tmp[nl] = '.';
12 memcpy(tmp+nl+1, domain, dl+1);
13 return res_query(tmp, class, type, dest, len);
14}
libc/musl/src/network/res_send.c created+9
......@@ -0,0 +1,9 @@
1#include <resolv.h>
2
3int __res_send(const unsigned char *msg, int msglen, unsigned char *answer, int anslen)
4{
5 int r = __res_msend(1, &msg, &msglen, &answer, &anslen, anslen);
6 return r<0 ? r : anslen;
7}
8
9weak_alias(__res_send, res_send);
libc/musl/src/network/res_state.c created+9
......@@ -0,0 +1,9 @@
1#include <resolv.h>
2
3/* This is completely unused, and exists purely to satisfy broken apps. */
4
5struct __res_state *__res_state()
6{
7 static struct __res_state res;
8 return &res;
9}
libc/musl/src/network/resolvconf.c created+94
......@@ -0,0 +1,94 @@
1#include "lookup.h"
2#include "stdio_impl.h"
3#include <ctype.h>
4#include <errno.h>
5#include <string.h>
6#include <stdlib.h>
7#include <netinet/in.h>
8
9int __get_resolv_conf(struct resolvconf *conf, char *search, size_t search_sz)
10{
11 char line[256];
12 unsigned char _buf[256];
13 FILE *f, _f;
14 int nns = 0;
15
16 conf->ndots = 1;
17 conf->timeout = 5;
18 conf->attempts = 2;
19 if (search) *search = 0;
20
21 f = __fopen_rb_ca("/etc/resolv.conf", &_f, _buf, sizeof _buf);
22 if (!f) switch (errno) {
23 case ENOENT:
24 case ENOTDIR:
25 case EACCES:
26 goto no_resolv_conf;
27 default:
28 return -1;
29 }
30
31 while (fgets(line, sizeof line, f)) {
32 char *p, *z;
33 if (!strchr(line, '\n') && !feof(f)) {
34 /* Ignore lines that get truncated rather than
35 * potentially misinterpreting them. */
36 int c;
37 do c = getc(f);
38 while (c != '\n' && c != EOF);
39 continue;
40 }
41 if (!strncmp(line, "options", 7) && isspace(line[7])) {
42 p = strstr(line, "ndots:");
43 if (p && isdigit(p[6])) {
44 p += 6;
45 unsigned long x = strtoul(p, &z, 10);
46 if (z != p) conf->ndots = x > 15 ? 15 : x;
47 }
48 p = strstr(line, "attempts:");
49 if (p && isdigit(p[9])) {
50 p += 9;
51 unsigned long x = strtoul(p, &z, 10);
52 if (z != p) conf->attempts = x > 10 ? 10 : x;
53 }
54 p = strstr(line, "timeout:");
55 if (p && (isdigit(p[8]) || p[8]=='.')) {
56 p += 8;
57 unsigned long x = strtoul(p, &z, 10);
58 if (z != p) conf->timeout = x > 60 ? 60 : x;
59 }
60 continue;
61 }
62 if (!strncmp(line, "nameserver", 10) && isspace(line[10])) {
63 if (nns >= MAXNS) continue;
64 for (p=line+11; isspace(*p); p++);
65 for (z=p; *z && !isspace(*z); z++);
66 *z=0;
67 if (__lookup_ipliteral(conf->ns+nns, p, AF_UNSPEC) > 0)
68 nns++;
69 continue;
70 }
71
72 if (!search) continue;
73 if ((strncmp(line, "domain", 6) && strncmp(line, "search", 6))
74 || !isspace(line[6]))
75 continue;
76 for (p=line+7; isspace(*p); p++);
77 size_t l = strlen(p);
78 /* This can never happen anyway with chosen buffer sizes. */
79 if (l >= search_sz) continue;
80 memcpy(search, p, l+1);
81 }
82
83 __fclose_ca(f);
84
85no_resolv_conf:
86 if (!nns) {
87 __lookup_ipliteral(conf->ns, "127.0.0.1", AF_UNSPEC);
88 nns = 1;
89 }
90
91 conf->nns = nns;
92
93 return 0;
94}
libc/musl/src/network/send.c created+6
......@@ -0,0 +1,6 @@
1#include <sys/socket.h>
2
3ssize_t send(int fd, const void *buf, size_t len, int flags)
4{
5 return sendto(fd, buf, len, flags, 0, 0);
6}
libc/musl/src/network/sendmmsg.c created+30
......@@ -0,0 +1,30 @@
1#define _GNU_SOURCE
2#include <sys/socket.h>
3#include <limits.h>
4#include <errno.h>
5#include "syscall.h"
6
7int sendmmsg(int fd, struct mmsghdr *msgvec, unsigned int vlen, unsigned int flags)
8{
9#if LONG_MAX > INT_MAX
10 /* Can't use the syscall directly because the kernel has the wrong
11 * idea for the types of msg_iovlen, msg_controllen, and cmsg_len,
12 * and the cmsg blocks cannot be modified in-place. */
13 int i;
14 if (vlen > IOV_MAX) vlen = IOV_MAX; /* This matches the kernel. */
15 if (!vlen) return 0;
16 for (i=0; i<vlen; i++) {
17 /* As an unfortunate inconsistency, the sendmmsg API uses
18 * unsigned int for the resulting msg_len, despite sendmsg
19 * returning ssize_t. However Linux limits the total bytes
20 * sent by sendmsg to INT_MAX, so the assignment is safe. */
21 ssize_t r = sendmsg(fd, &msgvec[i].msg_hdr, flags);
22 if (r < 0) goto error;
23 msgvec[i].msg_len = r;
24 }
25error:
26 return i ? i : -1;
27#else
28 return syscall_cp(SYS_sendmmsg, fd, msgvec, vlen, flags);
29#endif
30}
libc/musl/src/network/sendmsg.c created+29
......@@ -0,0 +1,29 @@
1#include <sys/socket.h>
2#include <limits.h>
3#include <string.h>
4#include <errno.h>
5#include "syscall.h"
6
7ssize_t sendmsg(int fd, const struct msghdr *msg, int flags)
8{
9#if LONG_MAX > INT_MAX
10 struct msghdr h;
11 struct cmsghdr chbuf[1024/sizeof(struct cmsghdr)+1], *c;
12 if (msg) {
13 h = *msg;
14 h.__pad1 = h.__pad2 = 0;
15 msg = &h;
16 if (h.msg_controllen) {
17 if (h.msg_controllen > 1024) {
18 errno = ENOMEM;
19 return -1;
20 }
21 memcpy(chbuf, h.msg_control, h.msg_controllen);
22 h.msg_control = chbuf;
23 for (c=CMSG_FIRSTHDR(&h); c; c=CMSG_NXTHDR(&h,c))
24 c->__pad1 = 0;
25 }
26 }
27#endif
28 return socketcall_cp(sendmsg, fd, msg, flags, 0, 0, 0);
29}
libc/musl/src/network/sendto.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4ssize_t sendto(int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t alen)
5{
6 return socketcall_cp(sendto, fd, buf, len, flags, addr, alen);
7}
libc/musl/src/network/serv.c created+14
......@@ -0,0 +1,14 @@
1#include <netdb.h>
2
3void endservent(void)
4{
5}
6
7void setservent(int stayopen)
8{
9}
10
11struct servent *getservent(void)
12{
13 return 0;
14}
libc/musl/src/network/setsockopt.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4int setsockopt(int fd, int level, int optname, const void *optval, socklen_t optlen)
5{
6 return socketcall(setsockopt, fd, level, optname, optval, optlen, 0);
7}
libc/musl/src/network/shutdown.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/socket.h>
2#include "syscall.h"
3
4int shutdown(int fd, int how)
5{
6 return socketcall(shutdown, fd, how, 0, 0, 0, 0);
7}
libc/musl/src/network/sockatmark.c created+10
......@@ -0,0 +1,10 @@
1#include <sys/socket.h>
2#include <sys/ioctl.h>
3
4int sockatmark(int s)
5{
6 int ret;
7 if (ioctl(s, SIOCATMARK, &ret) < 0)
8 return -1;
9 return ret;
10}
libc/musl/src/network/socket.c created+21
......@@ -0,0 +1,21 @@
1#include <sys/socket.h>
2#include <fcntl.h>
3#include <errno.h>
4#include "syscall.h"
5
6int socket(int domain, int type, int protocol)
7{
8 int s = socketcall(socket, domain, type, protocol, 0, 0, 0);
9 if (s<0 && (errno==EINVAL || errno==EPROTONOSUPPORT)
10 && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) {
11 s = socketcall(socket, domain,
12 type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK),
13 protocol, 0, 0, 0);
14 if (s < 0) return s;
15 if (type & SOCK_CLOEXEC)
16 __syscall(SYS_fcntl, s, F_SETFD, FD_CLOEXEC);
17 if (type & SOCK_NONBLOCK)
18 __syscall(SYS_fcntl, s, F_SETFL, O_NONBLOCK);
19 }
20 return s;
21}
libc/musl/src/network/socketpair.c created+25
......@@ -0,0 +1,25 @@
1#include <sys/socket.h>
2#include <fcntl.h>
3#include <errno.h>
4#include "syscall.h"
5
6int socketpair(int domain, int type, int protocol, int fd[2])
7{
8 int r = socketcall(socketpair, domain, type, protocol, fd, 0, 0);
9 if (r<0 && (errno==EINVAL || errno==EPROTONOSUPPORT)
10 && (type&(SOCK_CLOEXEC|SOCK_NONBLOCK))) {
11 r = socketcall(socketpair, domain,
12 type & ~(SOCK_CLOEXEC|SOCK_NONBLOCK),
13 protocol, fd, 0, 0);
14 if (r < 0) return r;
15 if (type & SOCK_CLOEXEC) {
16 __syscall(SYS_fcntl, fd[0], F_SETFD, FD_CLOEXEC);
17 __syscall(SYS_fcntl, fd[1], F_SETFD, FD_CLOEXEC);
18 }
19 if (type & SOCK_NONBLOCK) {
20 __syscall(SYS_fcntl, fd[0], F_SETFL, O_NONBLOCK);
21 __syscall(SYS_fcntl, fd[1], F_SETFL, O_NONBLOCK);
22 }
23 }
24 return r;
25}
libc/musl/src/passwd/fgetgrent.c created+12
......@@ -0,0 +1,12 @@
1#define _GNU_SOURCE
2#include "pwf.h"
3
4struct group *fgetgrent(FILE *f)
5{
6 static char *line, **mem;
7 static struct group gr;
8 struct group *res;
9 size_t size=0, nmem=0;
10 __getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
11 return res;
12}
libc/musl/src/passwd/fgetpwent.c created+12
......@@ -0,0 +1,12 @@
1#define _GNU_SOURCE
2#include "pwf.h"
3
4struct passwd *fgetpwent(FILE *f)
5{
6 static char *line;
7 static struct passwd pw;
8 size_t size=0;
9 struct passwd *res;
10 __getpwent_a(f, &pw, &line, &size, &res);
11 return res;
12}
libc/musl/src/passwd/fgetspent.c created+15
......@@ -0,0 +1,15 @@
1#include "pwf.h"
2#include <pthread.h>
3
4struct spwd *fgetspent(FILE *f)
5{
6 static char *line;
7 static struct spwd sp;
8 size_t size = 0;
9 struct spwd *res = 0;
10 int cs;
11 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
12 if (getline(&line, &size, f) >= 0 && __parsespent(line, &sp) >= 0) res = &sp;
13 pthread_setcancelstate(cs, 0);
14 return res;
15}
libc/musl/src/passwd/getgr_a.c created+169
......@@ -0,0 +1,169 @@
1#include <pthread.h>
2#include <byteswap.h>
3#include <string.h>
4#include <unistd.h>
5#include "pwf.h"
6#include "nscd.h"
7
8static char *itoa(char *p, uint32_t x)
9{
10 // number of digits in a uint32_t + NUL
11 p += 11;
12 *--p = 0;
13 do {
14 *--p = '0' + x % 10;
15 x /= 10;
16 } while (x);
17 return p;
18}
19
20int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res)
21{
22 FILE *f;
23 int rv = 0;
24 int cs;
25
26 *res = 0;
27
28 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
29 f = fopen("/etc/group", "rbe");
30 if (!f) {
31 rv = errno;
32 goto done;
33 }
34
35 while (!(rv = __getgrent_a(f, gr, buf, size, mem, nmem, res)) && *res) {
36 if (name && !strcmp(name, (*res)->gr_name)
37 || !name && (*res)->gr_gid == gid) {
38 break;
39 }
40 }
41 fclose(f);
42
43 if (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) {
44 int32_t req = name ? GETGRBYNAME : GETGRBYGID;
45 int32_t i;
46 const char *key;
47 int32_t groupbuf[GR_LEN] = {0};
48 size_t len = 0;
49 size_t grlist_len = 0;
50 char gidbuf[11] = {0};
51 int swap = 0;
52 char *ptr;
53
54 if (name) {
55 key = name;
56 } else {
57 if (gid < 0 || gid > UINT32_MAX) {
58 rv = 0;
59 goto done;
60 }
61 key = itoa(gidbuf, gid);
62 }
63
64 f = __nscd_query(req, key, groupbuf, sizeof groupbuf, &swap);
65 if (!f) { rv = errno; goto done; }
66
67 if (!groupbuf[GRFOUND]) { rv = 0; goto cleanup_f; }
68
69 if (!groupbuf[GRNAMELEN] || !groupbuf[GRPASSWDLEN]) {
70 rv = EIO;
71 goto cleanup_f;
72 }
73
74 if (groupbuf[GRNAMELEN] > SIZE_MAX - groupbuf[GRPASSWDLEN]) {
75 rv = ENOMEM;
76 goto cleanup_f;
77 }
78 len = groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];
79
80 for (i = 0; i < groupbuf[GRMEMCNT]; i++) {
81 uint32_t name_len;
82 if (fread(&name_len, sizeof name_len, 1, f) < 1) {
83 rv = ferror(f) ? errno : EIO;
84 goto cleanup_f;
85 }
86 if (swap) {
87 name_len = bswap_32(name_len);
88 }
89 if (name_len > SIZE_MAX - grlist_len
90 || name_len > SIZE_MAX - len) {
91 rv = ENOMEM;
92 goto cleanup_f;
93 }
94 len += name_len;
95 grlist_len += name_len;
96 }
97
98 if (len > *size || !*buf) {
99 char *tmp = realloc(*buf, len);
100 if (!tmp) {
101 rv = errno;
102 goto cleanup_f;
103 }
104 *buf = tmp;
105 *size = len;
106 }
107
108 if (!fread(*buf, len, 1, f)) {
109 rv = ferror(f) ? errno : EIO;
110 goto cleanup_f;
111 }
112
113 if (groupbuf[GRMEMCNT] + 1 > *nmem) {
114 if (groupbuf[GRMEMCNT] + 1 > SIZE_MAX/sizeof(char*)) {
115 rv = ENOMEM;
116 goto cleanup_f;
117 }
118 char **tmp = realloc(*mem, (groupbuf[GRMEMCNT]+1)*sizeof(char*));
119 if (!tmp) {
120 rv = errno;
121 goto cleanup_f;
122 }
123 *mem = tmp;
124 *nmem = groupbuf[GRMEMCNT] + 1;
125 }
126
127 if (groupbuf[GRMEMCNT]) {
128 mem[0][0] = *buf + groupbuf[GRNAMELEN] + groupbuf[GRPASSWDLEN];
129 for (ptr = mem[0][0], i = 0; ptr != mem[0][0]+grlist_len; ptr++)
130 if (!*ptr) mem[0][++i] = ptr+1;
131 mem[0][i] = 0;
132
133 if (i != groupbuf[GRMEMCNT]) {
134 rv = EIO;
135 goto cleanup_f;
136 }
137 } else {
138 mem[0][0] = 0;
139 }
140
141 gr->gr_name = *buf;
142 gr->gr_passwd = gr->gr_name + groupbuf[GRNAMELEN];
143 gr->gr_gid = groupbuf[GRGID];
144 gr->gr_mem = *mem;
145
146 if (gr->gr_passwd[-1]
147 || gr->gr_passwd[groupbuf[GRPASSWDLEN]-1]) {
148 rv = EIO;
149 goto cleanup_f;
150 }
151
152 if (name && strcmp(name, gr->gr_name)
153 || !name && gid != gr->gr_gid) {
154 rv = EIO;
155 goto cleanup_f;
156 }
157
158 *res = gr;
159
160cleanup_f:
161 fclose(f);
162 goto done;
163 }
164
165done:
166 pthread_setcancelstate(cs, 0);
167 if (rv) errno = rv;
168 return rv;
169}
libc/musl/src/passwd/getgr_r.c created+49
......@@ -0,0 +1,49 @@
1#include "pwf.h"
2#include <pthread.h>
3
4#define FIX(x) (gr->gr_##x = gr->gr_##x-line+buf)
5
6static int getgr_r(const char *name, gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
7{
8 char *line = 0;
9 size_t len = 0;
10 char **mem = 0;
11 size_t nmem = 0;
12 int rv = 0;
13 size_t i;
14 int cs;
15
16 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
17
18 rv = __getgr_a(name, gid, gr, &line, &len, &mem, &nmem, res);
19 if (*res && size < len + (nmem+1)*sizeof(char *) + 32) {
20 *res = 0;
21 rv = ERANGE;
22 }
23 if (*res) {
24 buf += (16-(uintptr_t)buf)%16;
25 gr->gr_mem = (void *)buf;
26 buf += (nmem+1)*sizeof(char *);
27 memcpy(buf, line, len);
28 FIX(name);
29 FIX(passwd);
30 for (i=0; mem[i]; i++)
31 gr->gr_mem[i] = mem[i]-line+buf;
32 gr->gr_mem[i] = 0;
33 }
34 free(mem);
35 free(line);
36 pthread_setcancelstate(cs, 0);
37 if (rv) errno = rv;
38 return rv;
39}
40
41int getgrnam_r(const char *name, struct group *gr, char *buf, size_t size, struct group **res)
42{
43 return getgr_r(name, 0, gr, buf, size, res);
44}
45
46int getgrgid_r(gid_t gid, struct group *gr, char *buf, size_t size, struct group **res)
47{
48 return getgr_r(0, gid, gr, buf, size, res);
49}
libc/musl/src/passwd/getgrent.c created+39
......@@ -0,0 +1,39 @@
1#include "pwf.h"
2
3static FILE *f;
4static char *line, **mem;
5static struct group gr;
6
7void setgrent()
8{
9 if (f) fclose(f);
10 f = 0;
11}
12
13weak_alias(setgrent, endgrent);
14
15struct group *getgrent()
16{
17 struct group *res;
18 size_t size=0, nmem=0;
19 if (!f) f = fopen("/etc/group", "rbe");
20 if (!f) return 0;
21 __getgrent_a(f, &gr, &line, &size, &mem, &nmem, &res);
22 return res;
23}
24
25struct group *getgrgid(gid_t gid)
26{
27 struct group *res;
28 size_t size=0, nmem=0;
29 __getgr_a(0, gid, &gr, &line, &size, &mem, &nmem, &res);
30 return res;
31}
32
33struct group *getgrnam(const char *name)
34{
35 struct group *res;
36 size_t size=0, nmem=0;
37 __getgr_a(name, 0, &gr, &line, &size, &mem, &nmem, &res);
38 return res;
39}
libc/musl/src/passwd/getgrent_a.c created+68
......@@ -0,0 +1,68 @@
1#include "pwf.h"
2#include <pthread.h>
3
4static unsigned atou(char **s)
5{
6 unsigned x;
7 for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
8 return x;
9}
10
11int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res)
12{
13 ssize_t l;
14 char *s, *mems;
15 size_t i;
16 int rv = 0;
17 int cs;
18 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
19 for (;;) {
20 if ((l=getline(line, size, f)) < 0) {
21 rv = ferror(f) ? errno : 0;
22 free(*line);
23 *line = 0;
24 gr = 0;
25 goto end;
26 }
27 line[0][l-1] = 0;
28
29 s = line[0];
30 gr->gr_name = s++;
31 if (!(s = strchr(s, ':'))) continue;
32
33 *s++ = 0; gr->gr_passwd = s;
34 if (!(s = strchr(s, ':'))) continue;
35
36 *s++ = 0; gr->gr_gid = atou(&s);
37 if (*s != ':') continue;
38
39 *s++ = 0; mems = s;
40 break;
41 }
42
43 for (*nmem=!!*s; *s; s++)
44 if (*s==',') ++*nmem;
45 free(*mem);
46 *mem = calloc(sizeof(char *), *nmem+1);
47 if (!*mem) {
48 rv = errno;
49 free(*line);
50 *line = 0;
51 gr = 0;
52 goto end;
53 }
54 if (*mems) {
55 mem[0][0] = mems;
56 for (s=mems, i=0; *s; s++)
57 if (*s==',') *s++ = 0, mem[0][++i] = s;
58 mem[0][++i] = 0;
59 } else {
60 mem[0][0] = 0;
61 }
62 gr->gr_mem = *mem;
63end:
64 pthread_setcancelstate(cs, 0);
65 *res = gr;
66 if(rv) errno = rv;
67 return rv;
68}
libc/musl/src/passwd/getgrouplist.c created+80
......@@ -0,0 +1,80 @@
1#define _GNU_SOURCE
2#include "pwf.h"
3#include <grp.h>
4#include <string.h>
5#include <limits.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <byteswap.h>
9#include <errno.h>
10#include "nscd.h"
11
12int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
13{
14 int rv, nlim, ret = -1;
15 ssize_t i, n = 1;
16 struct group gr;
17 struct group *res;
18 FILE *f;
19 int swap = 0;
20 int32_t resp[INITGR_LEN];
21 uint32_t *nscdbuf = 0;
22 char *buf = 0;
23 char **mem = 0;
24 size_t nmem = 0;
25 size_t size;
26 nlim = *ngroups;
27 if (nlim >= 1) *groups++ = gid;
28
29 f = __nscd_query(GETINITGR, user, resp, sizeof resp, &swap);
30 if (!f) goto cleanup;
31 if (resp[INITGRFOUND]) {
32 nscdbuf = calloc(resp[INITGRNGRPS], sizeof(uint32_t));
33 if (!nscdbuf) goto cleanup;
34 if (!fread(nscdbuf, sizeof(*nscdbuf)*resp[INITGRNGRPS], 1, f)) {
35 if (!ferror(f)) errno = EIO;
36 goto cleanup;
37 }
38 if (swap) {
39 for (i = 0; i < resp[INITGRNGRPS]; i++)
40 nscdbuf[i] = bswap_32(nscdbuf[i]);
41 }
42 }
43 fclose(f);
44
45 f = fopen("/etc/group", "rbe");
46 if (!f && errno != ENOENT && errno != ENOTDIR)
47 goto cleanup;
48
49 if (f) {
50 while (!(rv = __getgrent_a(f, &gr, &buf, &size, &mem, &nmem, &res)) && res) {
51 if (nscdbuf)
52 for (i=0; i < resp[INITGRNGRPS]; i++) {
53 if (nscdbuf[i] == gr.gr_gid) nscdbuf[i] = gid;
54 }
55 for (i=0; gr.gr_mem[i] && strcmp(user, gr.gr_mem[i]); i++);
56 if (!gr.gr_mem[i]) continue;
57 if (++n <= nlim) *groups++ = gr.gr_gid;
58 }
59 if (rv) {
60 errno = rv;
61 goto cleanup;
62 }
63 }
64 if (nscdbuf) {
65 for(i=0; i < resp[INITGRNGRPS]; i++) {
66 if (nscdbuf[i] != gid)
67 if(++n <= nlim) *groups++ = nscdbuf[i];
68 }
69 }
70
71 ret = n > nlim ? -1 : n;
72 *ngroups = n;
73
74cleanup:
75 if (f) fclose(f);
76 free(nscdbuf);
77 free(buf);
78 free(mem);
79 return ret;
80}
libc/musl/src/passwd/getpw_a.c created+142
......@@ -0,0 +1,142 @@
1#include <pthread.h>
2#include <byteswap.h>
3#include <string.h>
4#include <unistd.h>
5#include "pwf.h"
6#include "nscd.h"
7
8static char *itoa(char *p, uint32_t x)
9{
10 // number of digits in a uint32_t + NUL
11 p += 11;
12 *--p = 0;
13 do {
14 *--p = '0' + x % 10;
15 x /= 10;
16 } while (x);
17 return p;
18}
19
20int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res)
21{
22 FILE *f;
23 int cs;
24 int rv = 0;
25
26 *res = 0;
27
28 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
29
30 f = fopen("/etc/passwd", "rbe");
31 if (!f) {
32 rv = errno;
33 goto done;
34 }
35
36 while (!(rv = __getpwent_a(f, pw, buf, size, res)) && *res) {
37 if (name && !strcmp(name, (*res)->pw_name)
38 || !name && (*res)->pw_uid == uid)
39 break;
40 }
41 fclose(f);
42
43 if (!*res && (rv == 0 || rv == ENOENT || rv == ENOTDIR)) {
44 int32_t req = name ? GETPWBYNAME : GETPWBYUID;
45 const char *key;
46 int32_t passwdbuf[PW_LEN] = {0};
47 size_t len = 0;
48 char uidbuf[11] = {0};
49
50 if (name) {
51 key = name;
52 } else {
53 /* uid outside of this range can't be queried with the
54 * nscd interface, but might happen if uid_t ever
55 * happens to be a larger type (this is not true as of
56 * now)
57 */
58 if(uid < 0 || uid > UINT32_MAX) {
59 rv = 0;
60 goto done;
61 }
62 key = itoa(uidbuf, uid);
63 }
64
65 f = __nscd_query(req, key, passwdbuf, sizeof passwdbuf, (int[]){0});
66 if (!f) { rv = errno; goto done; }
67
68 if(!passwdbuf[PWFOUND]) { rv = 0; goto cleanup_f; }
69
70 /* A zero length response from nscd is invalid. We ignore
71 * invalid responses and just report an error, rather than
72 * trying to do something with them.
73 */
74 if (!passwdbuf[PWNAMELEN] || !passwdbuf[PWPASSWDLEN]
75 || !passwdbuf[PWGECOSLEN] || !passwdbuf[PWDIRLEN]
76 || !passwdbuf[PWSHELLLEN]) {
77 rv = EIO;
78 goto cleanup_f;
79 }
80
81 if ((passwdbuf[PWNAMELEN]|passwdbuf[PWPASSWDLEN]
82 |passwdbuf[PWGECOSLEN]|passwdbuf[PWDIRLEN]
83 |passwdbuf[PWSHELLLEN]) >= SIZE_MAX/8) {
84 rv = ENOMEM;
85 goto cleanup_f;
86 }
87
88 len = passwdbuf[PWNAMELEN] + passwdbuf[PWPASSWDLEN]
89 + passwdbuf[PWGECOSLEN] + passwdbuf[PWDIRLEN]
90 + passwdbuf[PWSHELLLEN];
91
92 if (len > *size || !*buf) {
93 char *tmp = realloc(*buf, len);
94 if (!tmp) {
95 rv = errno;
96 goto cleanup_f;
97 }
98 *buf = tmp;
99 *size = len;
100 }
101
102 if (!fread(*buf, len, 1, f)) {
103 rv = ferror(f) ? errno : EIO;
104 goto cleanup_f;
105 }
106
107 pw->pw_name = *buf;
108 pw->pw_passwd = pw->pw_name + passwdbuf[PWNAMELEN];
109 pw->pw_gecos = pw->pw_passwd + passwdbuf[PWPASSWDLEN];
110 pw->pw_dir = pw->pw_gecos + passwdbuf[PWGECOSLEN];
111 pw->pw_shell = pw->pw_dir + passwdbuf[PWDIRLEN];
112 pw->pw_uid = passwdbuf[PWUID];
113 pw->pw_gid = passwdbuf[PWGID];
114
115 /* Don't assume that nscd made sure to null terminate strings.
116 * It's supposed to, but malicious nscd should be ignored
117 * rather than causing a crash.
118 */
119 if (pw->pw_passwd[-1] || pw->pw_gecos[-1] || pw->pw_dir[-1]
120 || pw->pw_shell[passwdbuf[PWSHELLLEN]-1]) {
121 rv = EIO;
122 goto cleanup_f;
123 }
124
125 if (name && strcmp(name, pw->pw_name)
126 || !name && uid != pw->pw_uid) {
127 rv = EIO;
128 goto cleanup_f;
129 }
130
131
132 *res = pw;
133cleanup_f:
134 fclose(f);
135 goto done;
136 }
137
138done:
139 pthread_setcancelstate(cs, 0);
140 if (rv) errno = rv;
141 return rv;
142}
libc/musl/src/passwd/getpw_r.c created+42
......@@ -0,0 +1,42 @@
1#include "pwf.h"
2#include <pthread.h>
3
4#define FIX(x) (pw->pw_##x = pw->pw_##x-line+buf)
5
6static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
7{
8 char *line = 0;
9 size_t len = 0;
10 int rv = 0;
11 int cs;
12
13 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
14
15 rv = __getpw_a(name, uid, pw, &line, &len, res);
16 if (*res && size < len) {
17 *res = 0;
18 rv = ERANGE;
19 }
20 if (*res) {
21 memcpy(buf, line, len);
22 FIX(name);
23 FIX(passwd);
24 FIX(gecos);
25 FIX(dir);
26 FIX(shell);
27 }
28 free(line);
29 pthread_setcancelstate(cs, 0);
30 if (rv) errno = rv;
31 return rv;
32}
33
34int getpwnam_r(const char *name, struct passwd *pw, char *buf, size_t size, struct passwd **res)
35{
36 return getpw_r(name, 0, pw, buf, size, res);
37}
38
39int getpwuid_r(uid_t uid, struct passwd *pw, char *buf, size_t size, struct passwd **res)
40{
41 return getpw_r(0, uid, pw, buf, size, res);
42}
libc/musl/src/passwd/getpwent.c created+37
......@@ -0,0 +1,37 @@
1#include "pwf.h"
2
3static FILE *f;
4static char *line;
5static struct passwd pw;
6static size_t size;
7
8void setpwent()
9{
10 if (f) fclose(f);
11 f = 0;
12}
13
14weak_alias(setpwent, endpwent);
15
16struct passwd *getpwent()
17{
18 struct passwd *res;
19 if (!f) f = fopen("/etc/passwd", "rbe");
20 if (!f) return 0;
21 __getpwent_a(f, &pw, &line, &size, &res);
22 return res;
23}
24
25struct passwd *getpwuid(uid_t uid)
26{
27 struct passwd *res;
28 __getpw_a(0, uid, &pw, &line, &size, &res);
29 return res;
30}
31
32struct passwd *getpwnam(const char *name)
33{
34 struct passwd *res;
35 __getpw_a(name, 0, &pw, &line, &size, &res);
36 return res;
37}
libc/musl/src/passwd/getpwent_a.c created+54
......@@ -0,0 +1,54 @@
1#include "pwf.h"
2#include <pthread.h>
3
4static unsigned atou(char **s)
5{
6 unsigned x;
7 for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
8 return x;
9}
10
11int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res)
12{
13 ssize_t l;
14 char *s;
15 int rv = 0;
16 int cs;
17 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
18 for (;;) {
19 if ((l=getline(line, size, f)) < 0) {
20 rv = ferror(f) ? errno : 0;
21 free(*line);
22 *line = 0;
23 pw = 0;
24 break;
25 }
26 line[0][l-1] = 0;
27
28 s = line[0];
29 pw->pw_name = s++;
30 if (!(s = strchr(s, ':'))) continue;
31
32 *s++ = 0; pw->pw_passwd = s;
33 if (!(s = strchr(s, ':'))) continue;
34
35 *s++ = 0; pw->pw_uid = atou(&s);
36 if (*s != ':') continue;
37
38 *s++ = 0; pw->pw_gid = atou(&s);
39 if (*s != ':') continue;
40
41 *s++ = 0; pw->pw_gecos = s;
42 if (!(s = strchr(s, ':'))) continue;
43
44 *s++ = 0; pw->pw_dir = s;
45 if (!(s = strchr(s, ':'))) continue;
46
47 *s++ = 0; pw->pw_shell = s;
48 break;
49 }
50 pthread_setcancelstate(cs, 0);
51 *res = pw;
52 if (rv) errno = rv;
53 return rv;
54}
libc/musl/src/passwd/getspent.c created+14
......@@ -0,0 +1,14 @@
1#include "pwf.h"
2
3void setspent()
4{
5}
6
7void endspent()
8{
9}
10
11struct spwd *getspent()
12{
13 return 0;
14}
libc/musl/src/passwd/getspnam.c created+18
......@@ -0,0 +1,18 @@
1#include "pwf.h"
2
3#define LINE_LIM 256
4
5struct spwd *getspnam(const char *name)
6{
7 static struct spwd sp;
8 static char *line;
9 struct spwd *res;
10 int e;
11 int orig_errno = errno;
12
13 if (!line) line = malloc(LINE_LIM);
14 if (!line) return 0;
15 e = getspnam_r(name, &sp, line, LINE_LIM, &res);
16 errno = e ? e : orig_errno;
17 return res;
18}
libc/musl/src/passwd/getspnam_r.c created+125
......@@ -0,0 +1,125 @@
1#include <fcntl.h>
2#include <unistd.h>
3#include <sys/stat.h>
4#include <ctype.h>
5#include <pthread.h>
6#include "pwf.h"
7
8/* This implementation support Openwall-style TCB passwords in place of
9 * traditional shadow, if the appropriate directories and files exist.
10 * Thus, it is careful to avoid following symlinks or blocking on fifos
11 * which a malicious user might create in place of his or her TCB shadow
12 * file. It also avoids any allocation to prevent memory-exhaustion
13 * attacks via huge TCB shadow files. */
14
15static long xatol(char **s)
16{
17 long x;
18 if (**s == ':' || **s == '\n') return -1;
19 for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
20 return x;
21}
22
23int __parsespent(char *s, struct spwd *sp)
24{
25 sp->sp_namp = s;
26 if (!(s = strchr(s, ':'))) return -1;
27 *s = 0;
28
29 sp->sp_pwdp = ++s;
30 if (!(s = strchr(s, ':'))) return -1;
31 *s = 0;
32
33 s++; sp->sp_lstchg = xatol(&s);
34 if (*s != ':') return -1;
35
36 s++; sp->sp_min = xatol(&s);
37 if (*s != ':') return -1;
38
39 s++; sp->sp_max = xatol(&s);
40 if (*s != ':') return -1;
41
42 s++; sp->sp_warn = xatol(&s);
43 if (*s != ':') return -1;
44
45 s++; sp->sp_inact = xatol(&s);
46 if (*s != ':') return -1;
47
48 s++; sp->sp_expire = xatol(&s);
49 if (*s != ':') return -1;
50
51 s++; sp->sp_flag = xatol(&s);
52 if (*s != '\n') return -1;
53 return 0;
54}
55
56static void cleanup(void *p)
57{
58 fclose(p);
59}
60
61int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct spwd **res)
62{
63 char path[20+NAME_MAX];
64 FILE *f = 0;
65 int rv = 0;
66 int fd;
67 size_t k, l = strlen(name);
68 int skip = 0;
69 int cs;
70 int orig_errno = errno;
71
72 *res = 0;
73
74 /* Disallow potentially-malicious user names */
75 if (*name=='.' || strchr(name, '/') || !l)
76 return errno = EINVAL;
77
78 /* Buffer size must at least be able to hold name, plus some.. */
79 if (size < l+100)
80 return errno = ERANGE;
81
82 /* Protect against truncation */
83 if (snprintf(path, sizeof path, "/etc/tcb/%s/shadow", name) >= sizeof path)
84 return errno = EINVAL;
85
86 fd = open(path, O_RDONLY|O_NOFOLLOW|O_NONBLOCK|O_CLOEXEC);
87 if (fd >= 0) {
88 struct stat st = { 0 };
89 errno = EINVAL;
90 if (fstat(fd, &st) || !S_ISREG(st.st_mode) || !(f = fdopen(fd, "rb"))) {
91 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
92 close(fd);
93 pthread_setcancelstate(cs, 0);
94 return errno;
95 }
96 } else {
97 if (errno != ENOENT && errno != ENOTDIR)
98 return errno;
99 f = fopen("/etc/shadow", "rbe");
100 if (!f) {
101 if (errno != ENOENT && errno != ENOTDIR)
102 return errno;
103 return 0;
104 }
105 }
106
107 pthread_cleanup_push(cleanup, f);
108 while (fgets(buf, size, f) && (k=strlen(buf))>0) {
109 if (skip || strncmp(name, buf, l) || buf[l]!=':') {
110 skip = buf[k-1] != '\n';
111 continue;
112 }
113 if (buf[k-1] != '\n') {
114 rv = ERANGE;
115 break;
116 }
117
118 if (__parsespent(buf, sp) < 0) continue;
119 *res = sp;
120 break;
121 }
122 pthread_cleanup_pop(1);
123 errno = rv ? rv : orig_errno;
124 return rv;
125}
libc/musl/src/passwd/lckpwdf.c created+11
......@@ -0,0 +1,11 @@
1#include <shadow.h>
2
3int lckpwdf()
4{
5 return 0;
6}
7
8int ulckpwdf()
9{
10 return 0;
11}
libc/musl/src/passwd/nscd.h created+44
......@@ -0,0 +1,44 @@
1#ifndef NSCD_H
2#define NSCD_H
3
4#include <stdint.h>
5
6#define NSCDVERSION 2
7#define GETPWBYNAME 0
8#define GETPWBYUID 1
9#define GETGRBYNAME 2
10#define GETGRBYGID 3
11#define GETINITGR 15
12
13#define REQVERSION 0
14#define REQTYPE 1
15#define REQKEYLEN 2
16#define REQ_LEN 3
17
18#define PWVERSION 0
19#define PWFOUND 1
20#define PWNAMELEN 2
21#define PWPASSWDLEN 3
22#define PWUID 4
23#define PWGID 5
24#define PWGECOSLEN 6
25#define PWDIRLEN 7
26#define PWSHELLLEN 8
27#define PW_LEN 9
28
29#define GRVERSION 0
30#define GRFOUND 1
31#define GRNAMELEN 2
32#define GRPASSWDLEN 3
33#define GRGID 4
34#define GRMEMCNT 5
35#define GR_LEN 6
36
37#define INITGRVERSION 0
38#define INITGRFOUND 1
39#define INITGRNGRPS 2
40#define INITGR_LEN 3
41
42hidden FILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *swap);
43
44#endif
libc/musl/src/passwd/nscd_query.c created+107
......@@ -0,0 +1,107 @@
1#include <sys/socket.h>
2#include <byteswap.h>
3#include <unistd.h>
4#include <stdio.h>
5#include <string.h>
6#include <errno.h>
7#include <limits.h>
8#include "nscd.h"
9
10static const struct {
11 short sun_family;
12 char sun_path[21];
13} addr = {
14 AF_UNIX,
15 "/var/run/nscd/socket"
16};
17
18FILE *__nscd_query(int32_t req, const char *key, int32_t *buf, size_t len, int *swap)
19{
20 size_t i;
21 int fd;
22 FILE *f = 0;
23 int32_t req_buf[REQ_LEN] = {
24 NSCDVERSION,
25 req,
26 strnlen(key,LOGIN_NAME_MAX)+1
27 };
28 struct msghdr msg = {
29 .msg_iov = (struct iovec[]){
30 {&req_buf, sizeof(req_buf)},
31 {(char*)key, strlen(key)+1}
32 },
33 .msg_iovlen = 2
34 };
35 int errno_save = errno;
36
37 *swap = 0;
38retry:
39 memset(buf, 0, len);
40 buf[0] = NSCDVERSION;
41
42 fd = socket(PF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
43 if (fd < 0) return NULL;
44
45 if(!(f = fdopen(fd, "r"))) {
46 close(fd);
47 return 0;
48 }
49
50 if (req_buf[2] > LOGIN_NAME_MAX)
51 return f;
52
53 if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
54 /* If there isn't a running nscd we simulate a "not found"
55 * result and the caller is responsible for calling
56 * fclose on the (unconnected) socket. The value of
57 * errno must be left unchanged in this case. */
58 if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT) {
59 errno = errno_save;
60 return f;
61 }
62 goto error;
63 }
64
65 if (sendmsg(fd, &msg, MSG_NOSIGNAL) < 0)
66 goto error;
67
68 if (!fread(buf, len, 1, f)) {
69 /* If the VERSION entry mismatches nscd will disconnect. The
70 * most likely cause is that the endianness mismatched. So, we
71 * byteswap and try once more. (if we already swapped, just
72 * fail out)
73 */
74 if (ferror(f)) goto error;
75 if (!*swap) {
76 fclose(f);
77 for (i = 0; i < sizeof(req_buf)/sizeof(req_buf[0]); i++) {
78 req_buf[i] = bswap_32(req_buf[i]);
79 }
80 *swap = 1;
81 goto retry;
82 } else {
83 errno = EIO;
84 goto error;
85 }
86 }
87
88 if (*swap) {
89 for (i = 0; i < len/sizeof(buf[0]); i++) {
90 buf[i] = bswap_32(buf[i]);
91 }
92 }
93
94 /* The first entry in every nscd response is the version number. This
95 * really shouldn't happen, and is evidence of some form of malformed
96 * response.
97 */
98 if(buf[0] != NSCDVERSION) {
99 errno = EIO;
100 goto error;
101 }
102
103 return f;
104error:
105 fclose(f);
106 return 0;
107}
libc/musl/src/passwd/putgrent.c created+17
......@@ -0,0 +1,17 @@
1#define _GNU_SOURCE
2#include <grp.h>
3#include <stdio.h>
4
5int putgrent(const struct group *gr, FILE *f)
6{
7 int r;
8 size_t i;
9 flockfile(f);
10 if ((r = fprintf(f, "%s:%s:%d:", gr->gr_name, gr->gr_passwd, gr->gr_gid))<0) goto done;
11 if (gr->gr_mem) for (i=0; gr->gr_mem[i]; i++)
12 if ((r = fprintf(f, "%s%s", i?",":"", gr->gr_mem[i]))<0) goto done;
13 r = fputc('\n', f);
14done:
15 funlockfile(f);
16 return r<0 ? -1 : 0;
17}
libc/musl/src/passwd/putpwent.c created+10
......@@ -0,0 +1,10 @@
1#define _GNU_SOURCE
2#include <pwd.h>
3#include <stdio.h>
4
5int putpwent(const struct passwd *pw, FILE *f)
6{
7 return fprintf(f, "%s:%s:%d:%d:%s:%s:%s\n",
8 pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
9 pw->pw_gecos, pw->pw_dir, pw->pw_shell)<0 ? -1 : 0;
10}
libc/musl/src/passwd/putspent.c created+13
......@@ -0,0 +1,13 @@
1#include <shadow.h>
2#include <stdio.h>
3
4#define NUM(n) ((n) == -1 ? 0 : -1), ((n) == -1 ? 0 : (n))
5#define STR(s) ((s) ? (s) : "")
6
7int putspent(const struct spwd *sp, FILE *f)
8{
9 return fprintf(f, "%s:%s:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*ld:%.*lu\n",
10 STR(sp->sp_namp), STR(sp->sp_pwdp), NUM(sp->sp_lstchg),
11 NUM(sp->sp_min), NUM(sp->sp_max), NUM(sp->sp_warn),
12 NUM(sp->sp_inact), NUM(sp->sp_expire), NUM(sp->sp_flag)) < 0 ? -1 : 0;
13}
libc/musl/src/passwd/pwf.h created+15
......@@ -0,0 +1,15 @@
1#include <pwd.h>
2#include <grp.h>
3#include <shadow.h>
4#include <stdio.h>
5#include <errno.h>
6#include <stdint.h>
7#include <stdlib.h>
8#include <string.h>
9#include <limits.h>
10
11hidden int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res);
12hidden int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res);
13hidden int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res);
14hidden int __getgr_a(const char *name, gid_t gid, struct group *gr, char **buf, size_t *size, char ***mem, size_t *nmem, struct group **res);
15hidden int __parsespent(char *s, struct spwd *sp);
libc/musl/src/prng/__rand48_step.c created+14
......@@ -0,0 +1,14 @@
1#include <stdint.h>
2#include "rand48.h"
3
4uint64_t __rand48_step(unsigned short *xi, unsigned short *lc)
5{
6 uint64_t a, x;
7 x = xi[0] | xi[1]+0U<<16 | xi[2]+0ULL<<32;
8 a = lc[0] | lc[1]+0U<<16 | lc[2]+0ULL<<32;
9 x = a*x + lc[3];
10 xi[0] = x;
11 xi[1] = x>>16;
12 xi[2] = x>>32;
13 return x & 0xffffffffffffull;
14}
libc/musl/src/prng/__seed48.c created+3
......@@ -0,0 +1,3 @@
1#include "rand48.h"
2
3unsigned short __seed48[7] = { 0, 0, 0, 0xe66d, 0xdeec, 0x5, 0xb };
libc/musl/src/prng/drand48.c created+17
......@@ -0,0 +1,17 @@
1#include <stdlib.h>
2#include <inttypes.h>
3#include "rand48.h"
4
5double erand48(unsigned short s[3])
6{
7 union {
8 uint64_t u;
9 double f;
10 } x = { 0x3ff0000000000000ULL | __rand48_step(s, __seed48+3)<<4 };
11 return x.f - 1.0;
12}
13
14double drand48(void)
15{
16 return erand48(__seed48);
17}
libc/musl/src/prng/lcong48.c created+8
......@@ -0,0 +1,8 @@
1#include <stdlib.h>
2#include <string.h>
3#include "rand48.h"
4
5void lcong48(unsigned short p[7])
6{
7 memcpy(__seed48, p, sizeof __seed48);
8}
libc/musl/src/prng/lrand48.c created+13
......@@ -0,0 +1,13 @@
1#include <stdlib.h>
2#include <inttypes.h>
3#include "rand48.h"
4
5long nrand48(unsigned short s[3])
6{
7 return __rand48_step(s, __seed48+3) >> 17;
8}
9
10long lrand48(void)
11{
12 return nrand48(__seed48);
13}
libc/musl/src/prng/mrand48.c created+13
......@@ -0,0 +1,13 @@
1#include <stdlib.h>
2#include <inttypes.h>
3#include "rand48.h"
4
5long jrand48(unsigned short s[3])
6{
7 return (int32_t)(__rand48_step(s, __seed48+3) >> 16);
8}
9
10long mrand48(void)
11{
12 return jrand48(__seed48);
13}
libc/musl/src/prng/rand.c created+15
......@@ -0,0 +1,15 @@
1#include <stdlib.h>
2#include <stdint.h>
3
4static uint64_t seed;
5
6void srand(unsigned s)
7{
8 seed = s-1;
9}
10
11int rand(void)
12{
13 seed = 6364136223846793005ULL*seed + 1;
14 return seed>>33;
15}
libc/musl/src/prng/rand48.h created+5
......@@ -0,0 +1,5 @@
1#include <stdint.h>
2#include <features.h>
3
4hidden uint64_t __rand48_step(unsigned short *xi, unsigned short *lc);
5extern hidden unsigned short __seed48[7];
libc/musl/src/prng/rand_r.c created+15
......@@ -0,0 +1,15 @@
1#include <stdlib.h>
2
3static unsigned temper(unsigned x)
4{
5 x ^= x>>11;
6 x ^= x<<7 & 0x9D2C5680;
7 x ^= x<<15 & 0xEFC60000;
8 x ^= x>>18;
9 return x;
10}
11
12int rand_r(unsigned *seed)
13{
14 return temper(*seed = *seed * 1103515245 + 12345)/2;
15}
libc/musl/src/prng/random.c created+122
......@@ -0,0 +1,122 @@
1#include <stdlib.h>
2#include <stdint.h>
3#include "lock.h"
4
5/*
6this code uses the same lagged fibonacci generator as the
7original bsd random implementation except for the seeding
8which was broken in the original
9*/
10
11static uint32_t init[] = {
120x00000000,0x5851f42d,0xc0b18ccf,0xcbb5f646,
130xc7033129,0x30705b04,0x20fd5db4,0x9a8b7f78,
140x502959d8,0xab894868,0x6c0356a7,0x88cdb7ff,
150xb477d43f,0x70a3a52b,0xa8e4baf1,0xfd8341fc,
160x8ae16fd9,0x742d2f7a,0x0d1f0796,0x76035e09,
170x40f7702c,0x6fa72ca5,0xaaa84157,0x58a0df74,
180xc74a0364,0xae533cc4,0x04185faf,0x6de3b115,
190x0cab8628,0xf043bfa4,0x398150e9,0x37521657};
20
21static int n = 31;
22static int i = 3;
23static int j = 0;
24static uint32_t *x = init+1;
25static volatile int lock[1];
26
27static uint32_t lcg31(uint32_t x) {
28 return (1103515245*x + 12345) & 0x7fffffff;
29}
30
31static uint64_t lcg64(uint64_t x) {
32 return 6364136223846793005ull*x + 1;
33}
34
35static void *savestate() {
36 x[-1] = (n<<16)|(i<<8)|j;
37 return x-1;
38}
39
40static void loadstate(uint32_t *state) {
41 x = state+1;
42 n = x[-1]>>16;
43 i = (x[-1]>>8)&0xff;
44 j = x[-1]&0xff;
45}
46
47static void __srandom(unsigned seed) {
48 int k;
49 uint64_t s = seed;
50
51 if (n == 0) {
52 x[0] = s;
53 return;
54 }
55 i = n == 31 || n == 7 ? 3 : 1;
56 j = 0;
57 for (k = 0; k < n; k++) {
58 s = lcg64(s);
59 x[k] = s>>32;
60 }
61 /* make sure x contains at least one odd number */
62 x[0] |= 1;
63}
64
65void srandom(unsigned seed) {
66 LOCK(lock);
67 __srandom(seed);
68 UNLOCK(lock);
69}
70
71char *initstate(unsigned seed, char *state, size_t size) {
72 void *old;
73
74 if (size < 8)
75 return 0;
76 LOCK(lock);
77 old = savestate();
78 if (size < 32)
79 n = 0;
80 else if (size < 64)
81 n = 7;
82 else if (size < 128)
83 n = 15;
84 else if (size < 256)
85 n = 31;
86 else
87 n = 63;
88 x = (uint32_t*)state + 1;
89 __srandom(seed);
90 savestate();
91 UNLOCK(lock);
92 return old;
93}
94
95char *setstate(char *state) {
96 void *old;
97
98 LOCK(lock);
99 old = savestate();
100 loadstate((uint32_t*)state);
101 UNLOCK(lock);
102 return old;
103}
104
105long random(void) {
106 long k;
107
108 LOCK(lock);
109 if (n == 0) {
110 k = x[0] = lcg31(x[0]);
111 goto end;
112 }
113 x[i] += x[j];
114 k = x[i]>>1;
115 if (++i == n)
116 i = 0;
117 if (++j == n)
118 j = 0;
119end:
120 UNLOCK(lock);
121 return k;
122}
libc/musl/src/prng/seed48.c created+11
......@@ -0,0 +1,11 @@
1#include <stdlib.h>
2#include <string.h>
3#include "rand48.h"
4
5unsigned short *seed48(unsigned short *s)
6{
7 static unsigned short p[3];
8 memcpy(p, __seed48, sizeof p);
9 memcpy(__seed48, s, sizeof p);
10 return p;
11}
libc/musl/src/prng/srand48.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3void srand48(long seed)
4{
5 seed48((unsigned short [3]){ 0x330e, seed, seed>>16 });
6}
libc/musl/src/process/arm/vfork.s created+10
......@@ -0,0 +1,10 @@
1.syntax unified
2.global vfork
3.type vfork,%function
4vfork:
5 mov ip, r7
6 mov r7, 190
7 svc 0
8 mov r7, ip
9 .hidden __syscall_ret
10 b __syscall_ret
libc/musl/src/process/execl.c created+22
......@@ -0,0 +1,22 @@
1#include <unistd.h>
2#include <stdarg.h>
3
4int execl(const char *path, const char *argv0, ...)
5{
6 int argc;
7 va_list ap;
8 va_start(ap, argv0);
9 for (argc=1; va_arg(ap, const char *); argc++);
10 va_end(ap);
11 {
12 int i;
13 char *argv[argc+1];
14 va_start(ap, argv0);
15 argv[0] = (char *)argv0;
16 for (i=1; i<argc; i++)
17 argv[i] = va_arg(ap, char *);
18 argv[i] = NULL;
19 va_end(ap);
20 return execv(path, argv);
21 }
22}
libc/musl/src/process/execle.c created+23
......@@ -0,0 +1,23 @@
1#include <unistd.h>
2#include <stdarg.h>
3
4int execle(const char *path, const char *argv0, ...)
5{
6 int argc;
7 va_list ap;
8 va_start(ap, argv0);
9 for (argc=1; va_arg(ap, const char *); argc++);
10 va_end(ap);
11 {
12 int i;
13 char *argv[argc+1];
14 char **envp;
15 va_start(ap, argv0);
16 argv[0] = (char *)argv0;
17 for (i=1; i<=argc; i++)
18 argv[i] = va_arg(ap, char *);
19 envp = va_arg(ap, char **);
20 va_end(ap);
21 return execve(path, argv, envp);
22 }
23}
libc/musl/src/process/execlp.c created+22
......@@ -0,0 +1,22 @@
1#include <unistd.h>
2#include <stdarg.h>
3
4int execlp(const char *file, const char *argv0, ...)
5{
6 int argc;
7 va_list ap;
8 va_start(ap, argv0);
9 for (argc=1; va_arg(ap, const char *); argc++);
10 va_end(ap);
11 {
12 int i;
13 char *argv[argc+1];
14 va_start(ap, argv0);
15 argv[0] = (char *)argv0;
16 for (i=1; i<argc; i++)
17 argv[i] = va_arg(ap, char *);
18 argv[i] = NULL;
19 va_end(ap);
20 return execvp(file, argv);
21 }
22}
libc/musl/src/process/execv.c created+8
......@@ -0,0 +1,8 @@
1#include <unistd.h>
2
3extern char **__environ;
4
5int execv(const char *path, char *const argv[])
6{
7 return execve(path, argv, __environ);
8}
libc/musl/src/process/execve.c created+8
......@@ -0,0 +1,8 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int execve(const char *path, char *const argv[], char *const envp[])
5{
6 /* do we need to use environ if envp is null? */
7 return syscall(SYS_execve, path, argv, envp);
8}
libc/musl/src/process/execvp.c created+61
......@@ -0,0 +1,61 @@
1#include <stdlib.h>
2#include <string.h>
3#include <unistd.h>
4#include <errno.h>
5#include <limits.h>
6
7extern char **__environ;
8
9int __execvpe(const char *file, char *const argv[], char *const envp[])
10{
11 const char *p, *z, *path = getenv("PATH");
12 size_t l, k;
13 int seen_eacces = 0;
14
15 errno = ENOENT;
16 if (!*file) return -1;
17
18 if (strchr(file, '/'))
19 return execve(file, argv, envp);
20
21 if (!path) path = "/usr/local/bin:/bin:/usr/bin";
22 k = strnlen(file, NAME_MAX+1);
23 if (k > NAME_MAX) {
24 errno = ENAMETOOLONG;
25 return -1;
26 }
27 l = strnlen(path, PATH_MAX-1)+1;
28
29 for(p=path; ; p=z) {
30 char b[l+k+1];
31 z = strchr(p, ':');
32 if (!z) z = p+strlen(p);
33 if (z-p >= l) {
34 if (!*z++) break;
35 continue;
36 }
37 memcpy(b, p, z-p);
38 b[z-p] = '/';
39 memcpy(b+(z-p)+(z>p), file, k+1);
40 execve(b, argv, envp);
41 switch (errno) {
42 case EACCES:
43 seen_eacces = 1;
44 case ENOENT:
45 case ENOTDIR:
46 break;
47 default:
48 return -1;
49 }
50 if (!*z++) break;
51 }
52 if (seen_eacces) errno = EACCES;
53 return -1;
54}
55
56int execvp(const char *file, char *const argv[])
57{
58 return __execvpe(file, argv, __environ);
59}
60
61weak_alias(__execvpe, execvpe);
libc/musl/src/process/fdop.h created+10
......@@ -0,0 +1,10 @@
1#define FDOP_CLOSE 1
2#define FDOP_DUP2 2
3#define FDOP_OPEN 3
4
5struct fdop {
6 struct fdop *next, *prev;
7 int cmd, fd, srcfd, oflag;
8 mode_t mode;
9 char path[];
10};
libc/musl/src/process/fexecve.c created+16
......@@ -0,0 +1,16 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include <errno.h>
4#include <fcntl.h>
5#include "syscall.h"
6
7int fexecve(int fd, char *const argv[], char *const envp[])
8{
9 int r = __syscall(SYS_execveat, fd, "", argv, envp, AT_EMPTY_PATH);
10 if (r != -ENOSYS) return __syscall_ret(r);
11 char buf[15 + 3*sizeof(int)];
12 __procfdname(buf, fd);
13 execve(buf, argv, envp);
14 if (errno == ENOENT) errno = EBADF;
15 return -1;
16}
libc/musl/src/process/fork.c created+35
......@@ -0,0 +1,35 @@
1#include <unistd.h>
2#include <string.h>
3#include <signal.h>
4#include "syscall.h"
5#include "libc.h"
6#include "pthread_impl.h"
7
8static void dummy(int x)
9{
10}
11
12weak_alias(dummy, __fork_handler);
13
14pid_t fork(void)
15{
16 pid_t ret;
17 sigset_t set;
18 __fork_handler(-1);
19 __block_all_sigs(&set);
20#ifdef SYS_fork
21 ret = __syscall(SYS_fork);
22#else
23 ret = __syscall(SYS_clone, SIGCHLD, 0);
24#endif
25 if (!ret) {
26 pthread_t self = __pthread_self();
27 self->tid = __syscall(SYS_gettid);
28 self->robust_list.off = 0;
29 self->robust_list.pending = 0;
30 libc.threads_minus_1 = 0;
31 }
32 __restore_sigs(&set);
33 __fork_handler(!ret);
34 return __syscall_ret(ret);
35}
libc/musl/src/process/i386/vfork.s created+12
......@@ -0,0 +1,12 @@
1.global vfork
2.type vfork,@function
3vfork:
4 pop %edx
5 mov $190,%eax
6 int $128
7 push %edx
8 push %eax
9 .hidden __syscall_ret
10 call __syscall_ret
11 pop %edx
12 ret
libc/musl/src/process/posix_spawn.c created+192
......@@ -0,0 +1,192 @@
1#define _GNU_SOURCE
2#include <spawn.h>
3#include <sched.h>
4#include <unistd.h>
5#include <signal.h>
6#include <fcntl.h>
7#include <sys/wait.h>
8#include "syscall.h"
9#include "pthread_impl.h"
10#include "fdop.h"
11
12struct args {
13 int p[2];
14 sigset_t oldmask;
15 const char *path;
16 const posix_spawn_file_actions_t *fa;
17 const posix_spawnattr_t *restrict attr;
18 char *const *argv, *const *envp;
19};
20
21static int __sys_dup2(int old, int new)
22{
23#ifdef SYS_dup2
24 return __syscall(SYS_dup2, old, new);
25#else
26 return __syscall(SYS_dup3, old, new, 0);
27#endif
28}
29
30static int child(void *args_vp)
31{
32 int i, ret;
33 struct sigaction sa = {0};
34 struct args *args = args_vp;
35 int p = args->p[1];
36 const posix_spawn_file_actions_t *fa = args->fa;
37 const posix_spawnattr_t *restrict attr = args->attr;
38 sigset_t hset;
39
40 close(args->p[0]);
41
42 /* All signal dispositions must be either SIG_DFL or SIG_IGN
43 * before signals are unblocked. Otherwise a signal handler
44 * from the parent might get run in the child while sharing
45 * memory, with unpredictable and dangerous results. To
46 * reduce overhead, sigaction has tracked for us which signals
47 * potentially have a signal handler. */
48 __get_handler_set(&hset);
49 for (i=1; i<_NSIG; i++) {
50 if ((attr->__flags & POSIX_SPAWN_SETSIGDEF)
51 && sigismember(&attr->__def, i)) {
52 sa.sa_handler = SIG_DFL;
53 } else if (sigismember(&hset, i)) {
54 if (i-32<3U) {
55 sa.sa_handler = SIG_IGN;
56 } else {
57 __libc_sigaction(i, 0, &sa);
58 if (sa.sa_handler==SIG_IGN) continue;
59 sa.sa_handler = SIG_DFL;
60 }
61 } else {
62 continue;
63 }
64 __libc_sigaction(i, &sa, 0);
65 }
66
67 if (attr->__flags & POSIX_SPAWN_SETSID)
68 if ((ret=__syscall(SYS_setsid)) < 0)
69 goto fail;
70
71 if (attr->__flags & POSIX_SPAWN_SETPGROUP)
72 if ((ret=__syscall(SYS_setpgid, 0, attr->__pgrp)))
73 goto fail;
74
75 /* Use syscalls directly because the library functions attempt
76 * to do a multi-threaded synchronized id-change, which would
77 * trash the parent's state. */
78 if (attr->__flags & POSIX_SPAWN_RESETIDS)
79 if ((ret=__syscall(SYS_setgid, __syscall(SYS_getgid))) ||
80 (ret=__syscall(SYS_setuid, __syscall(SYS_getuid))) )
81 goto fail;
82
83 if (fa && fa->__actions) {
84 struct fdop *op;
85 int fd;
86 for (op = fa->__actions; op->next; op = op->next);
87 for (; op; op = op->prev) {
88 /* It's possible that a file operation would clobber
89 * the pipe fd used for synchronizing with the
90 * parent. To avoid that, we dup the pipe onto
91 * an unoccupied fd. */
92 if (op->fd == p) {
93 ret = __syscall(SYS_dup, p);
94 if (ret < 0) goto fail;
95 __syscall(SYS_close, p);
96 p = ret;
97 }
98 switch(op->cmd) {
99 case FDOP_CLOSE:
100 __syscall(SYS_close, op->fd);
101 break;
102 case FDOP_DUP2:
103 fd = op->srcfd;
104 if (fd != op->fd) {
105 if ((ret=__sys_dup2(fd, op->fd))<0)
106 goto fail;
107 } else {
108 ret = __syscall(SYS_fcntl, fd, F_GETFD);
109 ret = __syscall(SYS_fcntl, fd, F_SETFD,
110 ret & ~FD_CLOEXEC);
111 if (ret<0)
112 goto fail;
113 }
114 break;
115 case FDOP_OPEN:
116 fd = __sys_open(op->path, op->oflag, op->mode);
117 if ((ret=fd) < 0) goto fail;
118 if (fd != op->fd) {
119 if ((ret=__sys_dup2(fd, op->fd))<0)
120 goto fail;
121 __syscall(SYS_close, fd);
122 }
123 break;
124 }
125 }
126 }
127
128 /* Close-on-exec flag may have been lost if we moved the pipe
129 * to a different fd. We don't use F_DUPFD_CLOEXEC above because
130 * it would fail on older kernels and atomicity is not needed --
131 * in this process there are no threads or signal handlers. */
132 __syscall(SYS_fcntl, p, F_SETFD, FD_CLOEXEC);
133
134 pthread_sigmask(SIG_SETMASK, (attr->__flags & POSIX_SPAWN_SETSIGMASK)
135 ? &attr->__mask : &args->oldmask, 0);
136
137 int (*exec)(const char *, char *const *, char *const *) =
138 attr->__fn ? (int (*)())attr->__fn : execve;
139
140 exec(args->path, args->argv, args->envp);
141 ret = -errno;
142
143fail:
144 /* Since sizeof errno < PIPE_BUF, the write is atomic. */
145 ret = -ret;
146 if (ret) while (__syscall(SYS_write, p, &ret, sizeof ret) < 0);
147 _exit(127);
148}
149
150
151int posix_spawn(pid_t *restrict res, const char *restrict path,
152 const posix_spawn_file_actions_t *fa,
153 const posix_spawnattr_t *restrict attr,
154 char *const argv[restrict], char *const envp[restrict])
155{
156 pid_t pid;
157 char stack[1024+PATH_MAX];
158 int ec=0, cs;
159 struct args args;
160
161 if (pipe2(args.p, O_CLOEXEC))
162 return errno;
163
164 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
165
166 args.path = path;
167 args.fa = fa;
168 args.attr = attr ? attr : &(const posix_spawnattr_t){0};
169 args.argv = argv;
170 args.envp = envp;
171 pthread_sigmask(SIG_BLOCK, SIGALL_SET, &args.oldmask);
172
173 pid = __clone(child, stack+sizeof stack,
174 CLONE_VM|CLONE_VFORK|SIGCHLD, &args);
175 close(args.p[1]);
176
177 if (pid > 0) {
178 if (read(args.p[0], &ec, sizeof ec) != sizeof ec) ec = 0;
179 else waitpid(pid, &(int){0}, 0);
180 } else {
181 ec = -pid;
182 }
183
184 close(args.p[0]);
185
186 if (!ec && res) *res = pid;
187
188 pthread_sigmask(SIG_SETMASK, &args.oldmask, 0);
189 pthread_setcancelstate(cs, 0);
190
191 return ec;
192}
libc/musl/src/process/posix_spawn_file_actions_addclose.c created+16
......@@ -0,0 +1,16 @@
1#include <spawn.h>
2#include <stdlib.h>
3#include <errno.h>
4#include "fdop.h"
5
6int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *fa, int fd)
7{
8 struct fdop *op = malloc(sizeof *op);
9 if (!op) return ENOMEM;
10 op->cmd = FDOP_CLOSE;
11 op->fd = fd;
12 if ((op->next = fa->__actions)) op->next->prev = op;
13 op->prev = 0;
14 fa->__actions = op;
15 return 0;
16}
libc/musl/src/process/posix_spawn_file_actions_adddup2.c created+17
......@@ -0,0 +1,17 @@
1#include <spawn.h>
2#include <stdlib.h>
3#include <errno.h>
4#include "fdop.h"
5
6int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *fa, int srcfd, int fd)
7{
8 struct fdop *op = malloc(sizeof *op);
9 if (!op) return ENOMEM;
10 op->cmd = FDOP_DUP2;
11 op->srcfd = srcfd;
12 op->fd = fd;
13 if ((op->next = fa->__actions)) op->next->prev = op;
14 op->prev = 0;
15 fa->__actions = op;
16 return 0;
17}
libc/musl/src/process/posix_spawn_file_actions_addopen.c created+20
......@@ -0,0 +1,20 @@
1#include <spawn.h>
2#include <stdlib.h>
3#include <string.h>
4#include <errno.h>
5#include "fdop.h"
6
7int posix_spawn_file_actions_addopen(posix_spawn_file_actions_t *restrict fa, int fd, const char *restrict path, int flags, mode_t mode)
8{
9 struct fdop *op = malloc(sizeof *op + strlen(path) + 1);
10 if (!op) return ENOMEM;
11 op->cmd = FDOP_OPEN;
12 op->fd = fd;
13 op->oflag = flags;
14 op->mode = mode;
15 strcpy(op->path, path);
16 if ((op->next = fa->__actions)) op->next->prev = op;
17 op->prev = 0;
18 fa->__actions = op;
19 return 0;
20}
libc/musl/src/process/posix_spawn_file_actions_destroy.c created+14
......@@ -0,0 +1,14 @@
1#include <spawn.h>
2#include <stdlib.h>
3#include "fdop.h"
4
5int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *fa)
6{
7 struct fdop *op = fa->__actions, *next;
8 while (op) {
9 next = op->next;
10 free(op);
11 op = next;
12 }
13 return 0;
14}
libc/musl/src/process/posix_spawn_file_actions_init.c created+7
......@@ -0,0 +1,7 @@
1#include <spawn.h>
2
3int posix_spawn_file_actions_init(posix_spawn_file_actions_t *fa)
4{
5 fa->__actions = 0;
6 return 0;
7}
libc/musl/src/process/posix_spawnattr_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include <spawn.h>
2
3int posix_spawnattr_destroy(posix_spawnattr_t *attr)
4{
5 return 0;
6}
libc/musl/src/process/posix_spawnattr_getflags.c created+7
......@@ -0,0 +1,7 @@
1#include <spawn.h>
2
3int posix_spawnattr_getflags(const posix_spawnattr_t *restrict attr, short *restrict flags)
4{
5 *flags = attr->__flags;
6 return 0;
7}
libc/musl/src/process/posix_spawnattr_getpgroup.c created+7
......@@ -0,0 +1,7 @@
1#include <spawn.h>
2
3int posix_spawnattr_getpgroup(const posix_spawnattr_t *restrict attr, pid_t *restrict pgrp)
4{
5 *pgrp = attr->__pgrp;
6 return 0;
7}
libc/musl/src/process/posix_spawnattr_getsigdefault.c created+7
......@@ -0,0 +1,7 @@
1#include <spawn.h>
2
3int posix_spawnattr_getsigdefault(const posix_spawnattr_t *restrict attr, sigset_t *restrict def)
4{
5 *def = attr->__def;
6 return 0;
7}
libc/musl/src/process/posix_spawnattr_getsigmask.c created+7
......@@ -0,0 +1,7 @@
1#include <spawn.h>
2
3int posix_spawnattr_getsigmask(const posix_spawnattr_t *restrict attr, sigset_t *restrict mask)
4{
5 *mask = attr->__mask;
6 return 0;
7}
libc/musl/src/process/posix_spawnattr_init.c created+7
......@@ -0,0 +1,7 @@
1#include <spawn.h>
2
3int posix_spawnattr_init(posix_spawnattr_t *attr)
4{
5 *attr = (posix_spawnattr_t){ 0 };
6 return 0;
7}
libc/musl/src/process/posix_spawnattr_sched.c created+25
......@@ -0,0 +1,25 @@
1#include <spawn.h>
2#include <sched.h>
3#include <errno.h>
4
5int posix_spawnattr_getschedparam(const posix_spawnattr_t *restrict attr,
6 struct sched_param *restrict schedparam)
7{
8 return ENOSYS;
9}
10
11int posix_spawnattr_setschedparam(posix_spawnattr_t *restrict attr,
12 const struct sched_param *restrict schedparam)
13{
14 return ENOSYS;
15}
16
17int posix_spawnattr_getschedpolicy(const posix_spawnattr_t *restrict attr, int *restrict policy)
18{
19 return ENOSYS;
20}
21
22int posix_spawnattr_setschedpolicy(posix_spawnattr_t *attr, int policy)
23{
24 return ENOSYS;
25}
libc/musl/src/process/posix_spawnattr_setflags.c created+18
......@@ -0,0 +1,18 @@
1#include <spawn.h>
2#include <errno.h>
3
4int posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags)
5{
6 const unsigned all_flags =
7 POSIX_SPAWN_RESETIDS |
8 POSIX_SPAWN_SETPGROUP |
9 POSIX_SPAWN_SETSIGDEF |
10 POSIX_SPAWN_SETSIGMASK |
11 POSIX_SPAWN_SETSCHEDPARAM |
12 POSIX_SPAWN_SETSCHEDULER |
13 POSIX_SPAWN_USEVFORK |
14 POSIX_SPAWN_SETSID;
15 if (flags & ~all_flags) return EINVAL;
16 attr->__flags = flags;
17 return 0;
18}
libc/musl/src/process/posix_spawnattr_setpgroup.c created+7
......@@ -0,0 +1,7 @@
1#include <spawn.h>
2
3int posix_spawnattr_setpgroup(posix_spawnattr_t *attr, pid_t pgrp)
4{
5 attr->__pgrp = pgrp;
6 return 0;
7}
libc/musl/src/process/posix_spawnattr_setsigdefault.c created+7
......@@ -0,0 +1,7 @@
1#include <spawn.h>
2
3int posix_spawnattr_setsigdefault(posix_spawnattr_t *restrict attr, const sigset_t *restrict def)
4{
5 attr->__def = *def;
6 return 0;
7}
libc/musl/src/process/posix_spawnattr_setsigmask.c created+7
......@@ -0,0 +1,7 @@
1#include <spawn.h>
2
3int posix_spawnattr_setsigmask(posix_spawnattr_t *restrict attr, const sigset_t *restrict mask)
4{
5 attr->__mask = *mask;
6 return 0;
7}
libc/musl/src/process/posix_spawnp.c created+13
......@@ -0,0 +1,13 @@
1#include <spawn.h>
2#include <unistd.h>
3
4int posix_spawnp(pid_t *restrict res, const char *restrict file,
5 const posix_spawn_file_actions_t *fa,
6 const posix_spawnattr_t *restrict attr,
7 char *const argv[restrict], char *const envp[restrict])
8{
9 posix_spawnattr_t spawnp_attr = { 0 };
10 if (attr) spawnp_attr = *attr;
11 spawnp_attr.__fn = (void *)__execvpe;
12 return posix_spawn(res, file, fa, &spawnp_attr, argv, envp);
13}
libc/musl/src/process/s390x/vfork.s created+6
......@@ -0,0 +1,6 @@
1 .global vfork
2 .type vfork,%function
3vfork:
4 svc 190
5 .hidden __syscall_ret
6 jg __syscall_ret
libc/musl/src/process/sh/vfork.s created+20
......@@ -0,0 +1,20 @@
1.global vfork
2.type vfork,@function
3vfork:
4 mov #95, r3
5 add r3, r3
6
7 trapa #31
8 or r0, r0
9 or r0, r0
10 or r0, r0
11 or r0, r0
12 or r0, r0
13
14 mov r0, r4
15 mov.l 1f, r0
162: braf r0
17 nop
18 .align 2
19 .hidden __syscall_ret
201: .long __syscall_ret@PLT-(2b+4-.)
libc/musl/src/process/system.c created+46
......@@ -0,0 +1,46 @@
1#include <unistd.h>
2#include <stdlib.h>
3#include <signal.h>
4#include <sys/wait.h>
5#include <spawn.h>
6#include <errno.h>
7#include "pthread_impl.h"
8
9extern char **__environ;
10
11int system(const char *cmd)
12{
13 pid_t pid;
14 sigset_t old, reset;
15 struct sigaction sa = { .sa_handler = SIG_IGN }, oldint, oldquit;
16 int status = -1, ret;
17 posix_spawnattr_t attr;
18
19 pthread_testcancel();
20
21 if (!cmd) return 1;
22
23 sigaction(SIGINT, &sa, &oldint);
24 sigaction(SIGQUIT, &sa, &oldquit);
25 sigaddset(&sa.sa_mask, SIGCHLD);
26 sigprocmask(SIG_BLOCK, &sa.sa_mask, &old);
27
28 sigemptyset(&reset);
29 if (oldint.sa_handler != SIG_IGN) sigaddset(&reset, SIGINT);
30 if (oldquit.sa_handler != SIG_IGN) sigaddset(&reset, SIGQUIT);
31 posix_spawnattr_init(&attr);
32 posix_spawnattr_setsigmask(&attr, &old);
33 posix_spawnattr_setsigdefault(&attr, &reset);
34 posix_spawnattr_setflags(&attr, POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
35 ret = posix_spawn(&pid, "/bin/sh", 0, &attr,
36 (char *[]){"sh", "-c", (char *)cmd, 0}, __environ);
37 posix_spawnattr_destroy(&attr);
38
39 if (!ret) while (waitpid(pid, &status, 0)<0 && errno == EINTR);
40 sigaction(SIGINT, &oldint, NULL);
41 sigaction(SIGQUIT, &oldquit, NULL);
42 sigprocmask(SIG_SETMASK, &old, NULL);
43
44 if (ret) errno = ret;
45 return status;
46}
libc/musl/src/process/vfork.c created+14
......@@ -0,0 +1,14 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include <signal.h>
4#include "syscall.h"
5
6pid_t vfork(void)
7{
8 /* vfork syscall cannot be made from C code */
9#ifdef SYS_fork
10 return syscall(SYS_fork);
11#else
12 return syscall(SYS_clone, SIGCHLD, 0);
13#endif
14}
libc/musl/src/process/wait.c created+6
......@@ -0,0 +1,6 @@
1#include <sys/wait.h>
2
3pid_t wait(int *status)
4{
5 return waitpid((pid_t)-1, status, 0);
6}
libc/musl/src/process/waitid.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/wait.h>
2#include "syscall.h"
3
4int waitid(idtype_t type, id_t id, siginfo_t *info, int options)
5{
6 return syscall_cp(SYS_waitid, type, id, info, options, 0);
7}
libc/musl/src/process/waitpid.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/wait.h>
2#include "syscall.h"
3
4pid_t waitpid(pid_t pid, int *status, int options)
5{
6 return syscall_cp(SYS_wait4, pid, status, options, 0);
7}
libc/musl/src/process/x32/vfork.s created+10
......@@ -0,0 +1,10 @@
1.global vfork
2.type vfork,@function
3vfork:
4 pop %rdx
5 mov $0x4000003a,%eax /* SYS_vfork */
6 syscall
7 push %rdx
8 mov %rax,%rdi
9 .hidden __syscall_ret
10 jmp __syscall_ret
libc/musl/src/process/x86_64/vfork.s created+10
......@@ -0,0 +1,10 @@
1.global vfork
2.type vfork,@function
3vfork:
4 pop %rdx
5 mov $58,%eax
6 syscall
7 push %rdx
8 mov %rax,%rdi
9 .hidden __syscall_ret
10 jmp __syscall_ret
libc/musl/src/regex/fnmatch.c created+321
......@@ -0,0 +1,321 @@
1/*
2 * An implementation of what I call the "Sea of Stars" algorithm for
3 * POSIX fnmatch(). The basic idea is that we factor the pattern into
4 * a head component (which we match first and can reject without ever
5 * measuring the length of the string), an optional tail component
6 * (which only exists if the pattern contains at least one star), and
7 * an optional "sea of stars", a set of star-separated components
8 * between the head and tail. After the head and tail matches have
9 * been removed from the input string, the components in the "sea of
10 * stars" are matched sequentially by searching for their first
11 * occurrence past the end of the previous match.
12 *
13 * - Rich Felker, April 2012
14 */
15
16#include <string.h>
17#include <fnmatch.h>
18#include <stdlib.h>
19#include <wchar.h>
20#include <wctype.h>
21#include "locale_impl.h"
22
23#define END 0
24#define UNMATCHABLE -2
25#define BRACKET -3
26#define QUESTION -4
27#define STAR -5
28
29static int str_next(const char *str, size_t n, size_t *step)
30{
31 if (!n) {
32 *step = 0;
33 return 0;
34 }
35 if (str[0] >= 128U) {
36 wchar_t wc;
37 int k = mbtowc(&wc, str, n);
38 if (k<0) {
39 *step = 1;
40 return -1;
41 }
42 *step = k;
43 return wc;
44 }
45 *step = 1;
46 return str[0];
47}
48
49static int pat_next(const char *pat, size_t m, size_t *step, int flags)
50{
51 int esc = 0;
52 if (!m || !*pat) {
53 *step = 0;
54 return END;
55 }
56 *step = 1;
57 if (pat[0]=='\\' && pat[1] && !(flags & FNM_NOESCAPE)) {
58 *step = 2;
59 pat++;
60 esc = 1;
61 goto escaped;
62 }
63 if (pat[0]=='[') {
64 size_t k = 1;
65 if (k<m) if (pat[k] == '^' || pat[k] == '!') k++;
66 if (k<m) if (pat[k] == ']') k++;
67 for (; k<m && pat[k] && pat[k]!=']'; k++) {
68 if (k+1<m && pat[k+1] && pat[k]=='[' && (pat[k+1]==':' || pat[k+1]=='.' || pat[k+1]=='=')) {
69 int z = pat[k+1];
70 k+=2;
71 if (k<m && pat[k]) k++;
72 while (k<m && pat[k] && (pat[k-1]!=z || pat[k]!=']')) k++;
73 if (k==m || !pat[k]) break;
74 }
75 }
76 if (k==m || !pat[k]) {
77 *step = 1;
78 return '[';
79 }
80 *step = k+1;
81 return BRACKET;
82 }
83 if (pat[0] == '*')
84 return STAR;
85 if (pat[0] == '?')
86 return QUESTION;
87escaped:
88 if (pat[0] >= 128U) {
89 wchar_t wc;
90 int k = mbtowc(&wc, pat, m);
91 if (k<0) {
92 *step = 0;
93 return UNMATCHABLE;
94 }
95 *step = k + esc;
96 return wc;
97 }
98 return pat[0];
99}
100
101static int casefold(int k)
102{
103 int c = towupper(k);
104 return c == k ? towlower(k) : c;
105}
106
107static int match_bracket(const char *p, int k, int kfold)
108{
109 wchar_t wc;
110 int inv = 0;
111 p++;
112 if (*p=='^' || *p=='!') {
113 inv = 1;
114 p++;
115 }
116 if (*p==']') {
117 if (k==']') return !inv;
118 p++;
119 } else if (*p=='-') {
120 if (k=='-') return !inv;
121 p++;
122 }
123 wc = p[-1];
124 for (; *p != ']'; p++) {
125 if (p[0]=='-' && p[1]!=']') {
126 wchar_t wc2;
127 int l = mbtowc(&wc2, p+1, 4);
128 if (l < 0) return 0;
129 if (wc <= wc2)
130 if ((unsigned)k-wc <= wc2-wc ||
131 (unsigned)kfold-wc <= wc2-wc)
132 return !inv;
133 p += l-1;
134 continue;
135 }
136 if (p[0]=='[' && (p[1]==':' || p[1]=='.' || p[1]=='=')) {
137 const char *p0 = p+2;
138 int z = p[1];
139 p+=3;
140 while (p[-1]!=z || p[0]!=']') p++;
141 if (z == ':' && p-1-p0 < 16) {
142 char buf[16];
143 memcpy(buf, p0, p-1-p0);
144 buf[p-1-p0] = 0;
145 if (iswctype(k, wctype(buf)) ||
146 iswctype(kfold, wctype(buf)))
147 return !inv;
148 }
149 continue;
150 }
151 if (*p < 128U) {
152 wc = (unsigned char)*p;
153 } else {
154 int l = mbtowc(&wc, p, 4);
155 if (l < 0) return 0;
156 p += l-1;
157 }
158 if (wc==k || wc==kfold) return !inv;
159 }
160 return inv;
161}
162
163static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n, int flags)
164{
165 const char *p, *ptail, *endpat;
166 const char *s, *stail, *endstr;
167 size_t pinc, sinc, tailcnt=0;
168 int c, k, kfold;
169
170 if (flags & FNM_PERIOD) {
171 if (*str == '.' && *pat != '.')
172 return FNM_NOMATCH;
173 }
174 for (;;) {
175 switch ((c = pat_next(pat, m, &pinc, flags))) {
176 case UNMATCHABLE:
177 return FNM_NOMATCH;
178 case STAR:
179 pat++;
180 m--;
181 break;
182 default:
183 k = str_next(str, n, &sinc);
184 if (k <= 0)
185 return (c==END) ? 0 : FNM_NOMATCH;
186 str += sinc;
187 n -= sinc;
188 kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
189 if (c == BRACKET) {
190 if (!match_bracket(pat, k, kfold))
191 return FNM_NOMATCH;
192 } else if (c != QUESTION && k != c && kfold != c) {
193 return FNM_NOMATCH;
194 }
195 pat+=pinc;
196 m-=pinc;
197 continue;
198 }
199 break;
200 }
201
202 /* Compute real pat length if it was initially unknown/-1 */
203 m = strnlen(pat, m);
204 endpat = pat + m;
205
206 /* Find the last * in pat and count chars needed after it */
207 for (p=ptail=pat; p<endpat; p+=pinc) {
208 switch (pat_next(p, endpat-p, &pinc, flags)) {
209 case UNMATCHABLE:
210 return FNM_NOMATCH;
211 case STAR:
212 tailcnt=0;
213 ptail = p+1;
214 break;
215 default:
216 tailcnt++;
217 break;
218 }
219 }
220
221 /* Past this point we need not check for UNMATCHABLE in pat,
222 * because all of pat has already been parsed once. */
223
224 /* Compute real str length if it was initially unknown/-1 */
225 n = strnlen(str, n);
226 endstr = str + n;
227 if (n < tailcnt) return FNM_NOMATCH;
228
229 /* Find the final tailcnt chars of str, accounting for UTF-8.
230 * On illegal sequences we may get it wrong, but in that case
231 * we necessarily have a matching failure anyway. */
232 for (s=endstr; s>str && tailcnt; tailcnt--) {
233 if (s[-1] < 128U || MB_CUR_MAX==1) s--;
234 else while ((unsigned char)*--s-0x80U<0x40 && s>str);
235 }
236 if (tailcnt) return FNM_NOMATCH;
237 stail = s;
238
239 /* Check that the pat and str tails match */
240 p = ptail;
241 for (;;) {
242 c = pat_next(p, endpat-p, &pinc, flags);
243 p += pinc;
244 if ((k = str_next(s, endstr-s, &sinc)) <= 0) {
245 if (c != END) return FNM_NOMATCH;
246 break;
247 }
248 s += sinc;
249 kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
250 if (c == BRACKET) {
251 if (!match_bracket(p-pinc, k, kfold))
252 return FNM_NOMATCH;
253 } else if (c != QUESTION && k != c && kfold != c) {
254 return FNM_NOMATCH;
255 }
256 }
257
258 /* We're all done with the tails now, so throw them out */
259 endstr = stail;
260 endpat = ptail;
261
262 /* Match pattern components until there are none left */
263 while (pat<endpat) {
264 p = pat;
265 s = str;
266 for (;;) {
267 c = pat_next(p, endpat-p, &pinc, flags);
268 p += pinc;
269 /* Encountering * completes/commits a component */
270 if (c == STAR) {
271 pat = p;
272 str = s;
273 break;
274 }
275 k = str_next(s, endstr-s, &sinc);
276 if (!k)
277 return FNM_NOMATCH;
278 kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
279 if (c == BRACKET) {
280 if (!match_bracket(p-pinc, k, kfold))
281 break;
282 } else if (c != QUESTION && k != c && kfold != c) {
283 break;
284 }
285 s += sinc;
286 }
287 if (c == STAR) continue;
288 /* If we failed, advance str, by 1 char if it's a valid
289 * char, or past all invalid bytes otherwise. */
290 k = str_next(str, endstr-str, &sinc);
291 if (k > 0) str += sinc;
292 else for (str++; str_next(str, endstr-str, &sinc)<0; str++);
293 }
294
295 return 0;
296}
297
298int fnmatch(const char *pat, const char *str, int flags)
299{
300 const char *s, *p;
301 size_t inc;
302 int c;
303 if (flags & FNM_PATHNAME) for (;;) {
304 for (s=str; *s && *s!='/'; s++);
305 for (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc);
306 if (c!=*s && (!*s || !(flags & FNM_LEADING_DIR)))
307 return FNM_NOMATCH;
308 if (fnmatch_internal(pat, p-pat, str, s-str, flags))
309 return FNM_NOMATCH;
310 if (!c) return 0;
311 str = s+1;
312 pat = p+inc;
313 } else if (flags & FNM_LEADING_DIR) {
314 for (s=str; *s; s++) {
315 if (*s != '/') continue;
316 if (!fnmatch_internal(pat, -1, str, s-str, flags))
317 return 0;
318 }
319 }
320 return fnmatch_internal(pat, -1, str, -1, flags);
321}
libc/musl/src/regex/glob.c created+264
......@@ -0,0 +1,264 @@
1#define _BSD_SOURCE
2#include <glob.h>
3#include <fnmatch.h>
4#include <sys/stat.h>
5#include <dirent.h>
6#include <limits.h>
7#include <string.h>
8#include <stdlib.h>
9#include <errno.h>
10#include <stddef.h>
11
12struct match
13{
14 struct match *next;
15 char name[];
16};
17
18static int append(struct match **tail, const char *name, size_t len, int mark)
19{
20 struct match *new = malloc(sizeof(struct match) + len + 2);
21 if (!new) return -1;
22 (*tail)->next = new;
23 new->next = NULL;
24 memcpy(new->name, name, len+1);
25 if (mark && len && name[len-1]!='/') {
26 new->name[len] = '/';
27 new->name[len+1] = 0;
28 }
29 *tail = new;
30 return 0;
31}
32
33static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*errfunc)(const char *path, int err), struct match **tail)
34{
35 /* If GLOB_MARK is unused, we don't care about type. */
36 if (!type && !(flags & GLOB_MARK)) type = DT_REG;
37
38 /* Special-case the remaining pattern being all slashes, in
39 * which case we can use caller-passed type if it's a dir. */
40 if (*pat && type!=DT_DIR) type = 0;
41 while (pos+1 < PATH_MAX && *pat=='/') buf[pos++] = *pat++;
42
43 /* Consume maximal [escaped-]literal prefix of pattern, copying
44 * and un-escaping it to the running buffer as we go. */
45 ptrdiff_t i=0, j=0;
46 int in_bracket = 0, overflow = 0;
47 for (; pat[i]!='*' && pat[i]!='?' && (!in_bracket || pat[i]!=']'); i++) {
48 if (!pat[i]) {
49 if (overflow) return 0;
50 pat += i;
51 pos += j;
52 i = j = 0;
53 break;
54 } else if (pat[i] == '[') {
55 in_bracket = 1;
56 } else if (pat[i] == '\\' && !(flags & GLOB_NOESCAPE)) {
57 /* Backslashes inside a bracket are (at least by
58 * our interpretation) non-special, so if next
59 * char is ']' we have a complete expression. */
60 if (in_bracket && pat[i+1]==']') break;
61 /* Unpaired final backslash never matches. */
62 if (!pat[i+1]) return 0;
63 i++;
64 }
65 if (pat[i] == '/') {
66 if (overflow) return 0;
67 in_bracket = 0;
68 pat += i+1;
69 i = -1;
70 pos += j+1;
71 j = -1;
72 }
73 /* Only store a character if it fits in the buffer, but if
74 * a potential bracket expression is open, the overflow
75 * must be remembered and handled later only if the bracket
76 * is unterminated (and thereby a literal), so as not to
77 * disallow long bracket expressions with short matches. */
78 if (pos+(j+1) < PATH_MAX) {
79 buf[pos+j++] = pat[i];
80 } else if (in_bracket) {
81 overflow = 1;
82 } else {
83 return 0;
84 }
85 /* If we consume any new components, the caller-passed type
86 * or dummy type from above is no longer valid. */
87 type = 0;
88 }
89 buf[pos] = 0;
90 if (!*pat) {
91 /* If we consumed any components above, or if GLOB_MARK is
92 * requested and we don't yet know if the match is a dir,
93 * we must call stat to confirm the file exists and/or
94 * determine its type. */
95 struct stat st;
96 if ((flags & GLOB_MARK) && type==DT_LNK) type = 0;
97 if (!type && stat(buf, &st)) {
98 if (errno!=ENOENT && (errfunc(buf, errno) || (flags & GLOB_ERR)))
99 return GLOB_ABORTED;
100 return 0;
101 }
102 if (!type && S_ISDIR(st.st_mode)) type = DT_DIR;
103 if (append(tail, buf, pos, (flags & GLOB_MARK) && type==DT_DIR))
104 return GLOB_NOSPACE;
105 return 0;
106 }
107 char *p2 = strchr(pat, '/'), saved_sep = '/';
108 /* Check if the '/' was escaped and, if so, remove the escape char
109 * so that it will not be unpaired when passed to fnmatch. */
110 if (p2 && !(flags & GLOB_NOESCAPE)) {
111 char *p;
112 for (p=p2; p>pat && p[-1]=='\\'; p--);
113 if ((p2-p)%2) {
114 p2--;
115 saved_sep = '\\';
116 }
117 }
118 DIR *dir = opendir(pos ? buf : ".");
119 if (!dir) {
120 if (errfunc(buf, errno) || (flags & GLOB_ERR))
121 return GLOB_ABORTED;
122 return 0;
123 }
124 int old_errno = errno;
125 struct dirent *de;
126 while (errno=0, de=readdir(dir)) {
127 /* Quickly skip non-directories when there's pattern left. */
128 if (p2 && de->d_type && de->d_type!=DT_DIR && de->d_type!=DT_LNK)
129 continue;
130
131 size_t l = strlen(de->d_name);
132 if (l >= PATH_MAX-pos) continue;
133
134 if (p2) *p2 = 0;
135
136 int fnm_flags= ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
137 | ((!(flags & GLOB_PERIOD)) ? FNM_PERIOD : 0);
138
139 if (fnmatch(pat, de->d_name, fnm_flags))
140 continue;
141
142 /* With GLOB_PERIOD, don't allow matching . or .. unless
143 * fnmatch would match them with FNM_PERIOD rules in effect. */
144 if (p2 && (flags & GLOB_PERIOD) && de->d_name[0]=='.'
145 && (!de->d_name[1] || de->d_name[1]=='.' && !de->d_name[2])
146 && fnmatch(pat, de->d_name, fnm_flags | FNM_PERIOD))
147 continue;
148
149 memcpy(buf+pos, de->d_name, l+1);
150 if (p2) *p2 = saved_sep;
151 int r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : "", flags, errfunc, tail);
152 if (r) {
153 closedir(dir);
154 return r;
155 }
156 }
157 int readerr = errno;
158 if (p2) *p2 = saved_sep;
159 closedir(dir);
160 if (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR)))
161 return GLOB_ABORTED;
162 errno = old_errno;
163 return 0;
164}
165
166static int ignore_err(const char *path, int err)
167{
168 return 0;
169}
170
171static void freelist(struct match *head)
172{
173 struct match *match, *next;
174 for (match=head->next; match; match=next) {
175 next = match->next;
176 free(match);
177 }
178}
179
180static int sort(const void *a, const void *b)
181{
182 return strcmp(*(const char **)a, *(const char **)b);
183}
184
185int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g)
186{
187 struct match head = { .next = NULL }, *tail = &head;
188 size_t cnt, i;
189 size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;
190 int error = 0;
191 char buf[PATH_MAX];
192
193 if (!errfunc) errfunc = ignore_err;
194
195 if (!(flags & GLOB_APPEND)) {
196 g->gl_offs = offs;
197 g->gl_pathc = 0;
198 g->gl_pathv = NULL;
199 }
200
201 if (*pat) {
202 char *p = strdup(pat);
203 if (!p) return GLOB_NOSPACE;
204 buf[0] = 0;
205 error = do_glob(buf, 0, 0, p, flags, errfunc, &tail);
206 free(p);
207 }
208
209 if (error == GLOB_NOSPACE) {
210 freelist(&head);
211 return error;
212 }
213
214 for (cnt=0, tail=head.next; tail; tail=tail->next, cnt++);
215 if (!cnt) {
216 if (flags & GLOB_NOCHECK) {
217 tail = &head;
218 if (append(&tail, pat, strlen(pat), 0))
219 return GLOB_NOSPACE;
220 cnt++;
221 } else
222 return GLOB_NOMATCH;
223 }
224
225 if (flags & GLOB_APPEND) {
226 char **pathv = realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *));
227 if (!pathv) {
228 freelist(&head);
229 return GLOB_NOSPACE;
230 }
231 g->gl_pathv = pathv;
232 offs += g->gl_pathc;
233 } else {
234 g->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *));
235 if (!g->gl_pathv) {
236 freelist(&head);
237 return GLOB_NOSPACE;
238 }
239 for (i=0; i<offs; i++)
240 g->gl_pathv[i] = NULL;
241 }
242 for (i=0, tail=head.next; i<cnt; tail=tail->next, i++)
243 g->gl_pathv[offs + i] = tail->name;
244 g->gl_pathv[offs + i] = NULL;
245 g->gl_pathc += cnt;
246
247 if (!(flags & GLOB_NOSORT))
248 qsort(g->gl_pathv+offs, cnt, sizeof(char *), sort);
249
250 return error;
251}
252
253void globfree(glob_t *g)
254{
255 size_t i;
256 for (i=0; i<g->gl_pathc; i++)
257 free(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name));
258 free(g->gl_pathv);
259 g->gl_pathc = 0;
260 g->gl_pathv = NULL;
261}
262
263weak_alias(glob, glob64);
264weak_alias(globfree, globfree64);
libc/musl/src/regex/regcomp.c created+2953
......@@ -0,0 +1,2953 @@
1/*
2 regcomp.c - TRE POSIX compatible regex compilation functions.
3
4 Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
19 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30*/
31
32#include <string.h>
33#include <stdlib.h>
34#include <regex.h>
35#include <limits.h>
36#include <stdint.h>
37#include <ctype.h>
38
39#include "tre.h"
40
41#include <assert.h>
42
43/***********************************************************************
44 from tre-compile.h
45***********************************************************************/
46
47typedef struct {
48 int position;
49 int code_min;
50 int code_max;
51 int *tags;
52 int assertions;
53 tre_ctype_t class;
54 tre_ctype_t *neg_classes;
55 int backref;
56} tre_pos_and_tags_t;
57
58
59/***********************************************************************
60 from tre-ast.c and tre-ast.h
61***********************************************************************/
62
63/* The different AST node types. */
64typedef enum {
65 LITERAL,
66 CATENATION,
67 ITERATION,
68 UNION
69} tre_ast_type_t;
70
71/* Special subtypes of TRE_LITERAL. */
72#define EMPTY -1 /* Empty leaf (denotes empty string). */
73#define ASSERTION -2 /* Assertion leaf. */
74#define TAG -3 /* Tag leaf. */
75#define BACKREF -4 /* Back reference leaf. */
76
77#define IS_SPECIAL(x) ((x)->code_min < 0)
78#define IS_EMPTY(x) ((x)->code_min == EMPTY)
79#define IS_ASSERTION(x) ((x)->code_min == ASSERTION)
80#define IS_TAG(x) ((x)->code_min == TAG)
81#define IS_BACKREF(x) ((x)->code_min == BACKREF)
82
83
84/* A generic AST node. All AST nodes consist of this node on the top
85 level with `obj' pointing to the actual content. */
86typedef struct {
87 tre_ast_type_t type; /* Type of the node. */
88 void *obj; /* Pointer to actual node. */
89 int nullable;
90 int submatch_id;
91 int num_submatches;
92 int num_tags;
93 tre_pos_and_tags_t *firstpos;
94 tre_pos_and_tags_t *lastpos;
95} tre_ast_node_t;
96
97
98/* A "literal" node. These are created for assertions, back references,
99 tags, matching parameter settings, and all expressions that match one
100 character. */
101typedef struct {
102 long code_min;
103 long code_max;
104 int position;
105 tre_ctype_t class;
106 tre_ctype_t *neg_classes;
107} tre_literal_t;
108
109/* A "catenation" node. These are created when two regexps are concatenated.
110 If there are more than one subexpressions in sequence, the `left' part
111 holds all but the last, and `right' part holds the last subexpression
112 (catenation is left associative). */
113typedef struct {
114 tre_ast_node_t *left;
115 tre_ast_node_t *right;
116} tre_catenation_t;
117
118/* An "iteration" node. These are created for the "*", "+", "?", and "{m,n}"
119 operators. */
120typedef struct {
121 /* Subexpression to match. */
122 tre_ast_node_t *arg;
123 /* Minimum number of consecutive matches. */
124 int min;
125 /* Maximum number of consecutive matches. */
126 int max;
127 /* If 0, match as many characters as possible, if 1 match as few as
128 possible. Note that this does not always mean the same thing as
129 matching as many/few repetitions as possible. */
130 unsigned int minimal:1;
131} tre_iteration_t;
132
133/* An "union" node. These are created for the "|" operator. */
134typedef struct {
135 tre_ast_node_t *left;
136 tre_ast_node_t *right;
137} tre_union_t;
138
139
140static tre_ast_node_t *
141tre_ast_new_node(tre_mem_t mem, int type, void *obj)
142{
143 tre_ast_node_t *node = tre_mem_calloc(mem, sizeof *node);
144 if (!node || !obj)
145 return 0;
146 node->obj = obj;
147 node->type = type;
148 node->nullable = -1;
149 node->submatch_id = -1;
150 return node;
151}
152
153static tre_ast_node_t *
154tre_ast_new_literal(tre_mem_t mem, int code_min, int code_max, int position)
155{
156 tre_ast_node_t *node;
157 tre_literal_t *lit;
158
159 lit = tre_mem_calloc(mem, sizeof *lit);
160 node = tre_ast_new_node(mem, LITERAL, lit);
161 if (!node)
162 return 0;
163 lit->code_min = code_min;
164 lit->code_max = code_max;
165 lit->position = position;
166 return node;
167}
168
169static tre_ast_node_t *
170tre_ast_new_iter(tre_mem_t mem, tre_ast_node_t *arg, int min, int max, int minimal)
171{
172 tre_ast_node_t *node;
173 tre_iteration_t *iter;
174
175 iter = tre_mem_calloc(mem, sizeof *iter);
176 node = tre_ast_new_node(mem, ITERATION, iter);
177 if (!node)
178 return 0;
179 iter->arg = arg;
180 iter->min = min;
181 iter->max = max;
182 iter->minimal = minimal;
183 node->num_submatches = arg->num_submatches;
184 return node;
185}
186
187static tre_ast_node_t *
188tre_ast_new_union(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
189{
190 tre_ast_node_t *node;
191 tre_union_t *un;
192
193 if (!left)
194 return right;
195 un = tre_mem_calloc(mem, sizeof *un);
196 node = tre_ast_new_node(mem, UNION, un);
197 if (!node || !right)
198 return 0;
199 un->left = left;
200 un->right = right;
201 node->num_submatches = left->num_submatches + right->num_submatches;
202 return node;
203}
204
205static tre_ast_node_t *
206tre_ast_new_catenation(tre_mem_t mem, tre_ast_node_t *left, tre_ast_node_t *right)
207{
208 tre_ast_node_t *node;
209 tre_catenation_t *cat;
210
211 if (!left)
212 return right;
213 cat = tre_mem_calloc(mem, sizeof *cat);
214 node = tre_ast_new_node(mem, CATENATION, cat);
215 if (!node)
216 return 0;
217 cat->left = left;
218 cat->right = right;
219 node->num_submatches = left->num_submatches + right->num_submatches;
220 return node;
221}
222
223
224/***********************************************************************
225 from tre-stack.c and tre-stack.h
226***********************************************************************/
227
228typedef struct tre_stack_rec tre_stack_t;
229
230/* Creates a new stack object. `size' is initial size in bytes, `max_size'
231 is maximum size, and `increment' specifies how much more space will be
232 allocated with realloc() if all space gets used up. Returns the stack
233 object or NULL if out of memory. */
234static tre_stack_t *
235tre_stack_new(int size, int max_size, int increment);
236
237/* Frees the stack object. */
238static void
239tre_stack_destroy(tre_stack_t *s);
240
241/* Returns the current number of objects in the stack. */
242static int
243tre_stack_num_objects(tre_stack_t *s);
244
245/* Each tre_stack_push_*(tre_stack_t *s, <type> value) function pushes
246 `value' on top of stack `s'. Returns REG_ESPACE if out of memory.
247 This tries to realloc() more space before failing if maximum size
248 has not yet been reached. Returns REG_OK if successful. */
249#define declare_pushf(typetag, type) \
250 static reg_errcode_t tre_stack_push_ ## typetag(tre_stack_t *s, type value)
251
252declare_pushf(voidptr, void *);
253declare_pushf(int, int);
254
255/* Each tre_stack_pop_*(tre_stack_t *s) function pops the topmost
256 element off of stack `s' and returns it. The stack must not be
257 empty. */
258#define declare_popf(typetag, type) \
259 static type tre_stack_pop_ ## typetag(tre_stack_t *s)
260
261declare_popf(voidptr, void *);
262declare_popf(int, int);
263
264/* Just to save some typing. */
265#define STACK_PUSH(s, typetag, value) \
266 do \
267 { \
268 status = tre_stack_push_ ## typetag(s, value); \
269 } \
270 while (/*CONSTCOND*/0)
271
272#define STACK_PUSHX(s, typetag, value) \
273 { \
274 status = tre_stack_push_ ## typetag(s, value); \
275 if (status != REG_OK) \
276 break; \
277 }
278
279#define STACK_PUSHR(s, typetag, value) \
280 { \
281 reg_errcode_t _status; \
282 _status = tre_stack_push_ ## typetag(s, value); \
283 if (_status != REG_OK) \
284 return _status; \
285 }
286
287union tre_stack_item {
288 void *voidptr_value;
289 int int_value;
290};
291
292struct tre_stack_rec {
293 int size;
294 int max_size;
295 int increment;
296 int ptr;
297 union tre_stack_item *stack;
298};
299
300
301static tre_stack_t *
302tre_stack_new(int size, int max_size, int increment)
303{
304 tre_stack_t *s;
305
306 s = xmalloc(sizeof(*s));
307 if (s != NULL)
308 {
309 s->stack = xmalloc(sizeof(*s->stack) * size);
310 if (s->stack == NULL)
311 {
312 xfree(s);
313 return NULL;
314 }
315 s->size = size;
316 s->max_size = max_size;
317 s->increment = increment;
318 s->ptr = 0;
319 }
320 return s;
321}
322
323static void
324tre_stack_destroy(tre_stack_t *s)
325{
326 xfree(s->stack);
327 xfree(s);
328}
329
330static int
331tre_stack_num_objects(tre_stack_t *s)
332{
333 return s->ptr;
334}
335
336static reg_errcode_t
337tre_stack_push(tre_stack_t *s, union tre_stack_item value)
338{
339 if (s->ptr < s->size)
340 {
341 s->stack[s->ptr] = value;
342 s->ptr++;
343 }
344 else
345 {
346 if (s->size >= s->max_size)
347 {
348 return REG_ESPACE;
349 }
350 else
351 {
352 union tre_stack_item *new_buffer;
353 int new_size;
354 new_size = s->size + s->increment;
355 if (new_size > s->max_size)
356 new_size = s->max_size;
357 new_buffer = xrealloc(s->stack, sizeof(*new_buffer) * new_size);
358 if (new_buffer == NULL)
359 {
360 return REG_ESPACE;
361 }
362 assert(new_size > s->size);
363 s->size = new_size;
364 s->stack = new_buffer;
365 tre_stack_push(s, value);
366 }
367 }
368 return REG_OK;
369}
370
371#define define_pushf(typetag, type) \
372 declare_pushf(typetag, type) { \
373 union tre_stack_item item; \
374 item.typetag ## _value = value; \
375 return tre_stack_push(s, item); \
376}
377
378define_pushf(int, int)
379define_pushf(voidptr, void *)
380
381#define define_popf(typetag, type) \
382 declare_popf(typetag, type) { \
383 return s->stack[--s->ptr].typetag ## _value; \
384 }
385
386define_popf(int, int)
387define_popf(voidptr, void *)
388
389
390/***********************************************************************
391 from tre-parse.c and tre-parse.h
392***********************************************************************/
393
394/* Parse context. */
395typedef struct {
396 /* Memory allocator. The AST is allocated using this. */
397 tre_mem_t mem;
398 /* Stack used for keeping track of regexp syntax. */
399 tre_stack_t *stack;
400 /* The parsed node after a parse function returns. */
401 tre_ast_node_t *n;
402 /* Position in the regexp pattern after a parse function returns. */
403 const char *s;
404 /* The first character of the last subexpression parsed. */
405 const char *start;
406 /* Current submatch ID. */
407 int submatch_id;
408 /* Current position (number of literal). */
409 int position;
410 /* The highest back reference or -1 if none seen so far. */
411 int max_backref;
412 /* Compilation flags. */
413 int cflags;
414} tre_parse_ctx_t;
415
416/* Some macros for expanding \w, \s, etc. */
417static const struct {
418 char c;
419 const char *expansion;
420} tre_macros[] = {
421 {'t', "\t"}, {'n', "\n"}, {'r', "\r"},
422 {'f', "\f"}, {'a', "\a"}, {'e', "\033"},
423 {'w', "[[:alnum:]_]"}, {'W', "[^[:alnum:]_]"}, {'s', "[[:space:]]"},
424 {'S', "[^[:space:]]"}, {'d', "[[:digit:]]"}, {'D', "[^[:digit:]]"},
425 { 0, 0 }
426};
427
428/* Expands a macro delimited by `regex' and `regex_end' to `buf', which
429 must have at least `len' items. Sets buf[0] to zero if the there
430 is no match in `tre_macros'. */
431static const char *tre_expand_macro(const char *s)
432{
433 int i;
434 for (i = 0; tre_macros[i].c && tre_macros[i].c != *s; i++);
435 return tre_macros[i].expansion;
436}
437
438static int
439tre_compare_lit(const void *a, const void *b)
440{
441 const tre_literal_t *const *la = a;
442 const tre_literal_t *const *lb = b;
443 /* assumes the range of valid code_min is < INT_MAX */
444 return la[0]->code_min - lb[0]->code_min;
445}
446
447struct literals {
448 tre_mem_t mem;
449 tre_literal_t **a;
450 int len;
451 int cap;
452};
453
454static tre_literal_t *tre_new_lit(struct literals *p)
455{
456 tre_literal_t **a;
457 if (p->len >= p->cap) {
458 if (p->cap >= 1<<15)
459 return 0;
460 p->cap *= 2;
461 a = xrealloc(p->a, p->cap * sizeof *p->a);
462 if (!a)
463 return 0;
464 p->a = a;
465 }
466 a = p->a + p->len++;
467 *a = tre_mem_calloc(p->mem, sizeof **a);
468 return *a;
469}
470
471static int add_icase_literals(struct literals *ls, int min, int max)
472{
473 tre_literal_t *lit;
474 int b, e, c;
475 for (c=min; c<=max; ) {
476 /* assumes islower(c) and isupper(c) are exclusive
477 and toupper(c)!=c if islower(c).
478 multiple opposite case characters are not supported */
479 if (tre_islower(c)) {
480 b = e = tre_toupper(c);
481 for (c++, e++; c<=max; c++, e++)
482 if (tre_toupper(c) != e) break;
483 } else if (tre_isupper(c)) {
484 b = e = tre_tolower(c);
485 for (c++, e++; c<=max; c++, e++)
486 if (tre_tolower(c) != e) break;
487 } else {
488 c++;
489 continue;
490 }
491 lit = tre_new_lit(ls);
492 if (!lit)
493 return -1;
494 lit->code_min = b;
495 lit->code_max = e-1;
496 lit->position = -1;
497 }
498 return 0;
499}
500
501
502/* Maximum number of character classes in a negated bracket expression. */
503#define MAX_NEG_CLASSES 64
504
505struct neg {
506 int negate;
507 int len;
508 tre_ctype_t a[MAX_NEG_CLASSES];
509};
510
511// TODO: parse bracket into a set of non-overlapping [lo,hi] ranges
512
513/*
514bracket grammar:
515Bracket = '[' List ']' | '[^' List ']'
516List = Term | List Term
517Term = Char | Range | Chclass | Eqclass
518Range = Char '-' Char | Char '-' '-'
519Char = Coll | coll_single
520Meta = ']' | '-'
521Coll = '[.' coll_single '.]' | '[.' coll_multi '.]' | '[.' Meta '.]'
522Eqclass = '[=' coll_single '=]' | '[=' coll_multi '=]'
523Chclass = '[:' class ':]'
524
525coll_single is a single char collating element but it can be
526 '-' only at the beginning or end of a List and
527 ']' only at the beginning of a List and
528 '^' anywhere except after the openning '['
529*/
530
531static reg_errcode_t parse_bracket_terms(tre_parse_ctx_t *ctx, const char *s, struct literals *ls, struct neg *neg)
532{
533 const char *start = s;
534 tre_ctype_t class;
535 int min, max;
536 wchar_t wc;
537 int len;
538
539 for (;;) {
540 class = 0;
541 len = mbtowc(&wc, s, -1);
542 if (len <= 0)
543 return *s ? REG_BADPAT : REG_EBRACK;
544 if (*s == ']' && s != start) {
545 ctx->s = s+1;
546 return REG_OK;
547 }
548 if (*s == '-' && s != start && s[1] != ']' &&
549 /* extension: [a-z--@] is accepted as [a-z]|[--@] */
550 (s[1] != '-' || s[2] == ']'))
551 return REG_ERANGE;
552 if (*s == '[' && (s[1] == '.' || s[1] == '='))
553 /* collating symbols and equivalence classes are not supported */
554 return REG_ECOLLATE;
555 if (*s == '[' && s[1] == ':') {
556 char tmp[CHARCLASS_NAME_MAX+1];
557 s += 2;
558 for (len=0; len < CHARCLASS_NAME_MAX && s[len]; len++) {
559 if (s[len] == ':') {
560 memcpy(tmp, s, len);
561 tmp[len] = 0;
562 class = tre_ctype(tmp);
563 break;
564 }
565 }
566 if (!class || s[len+1] != ']')
567 return REG_ECTYPE;
568 min = 0;
569 max = TRE_CHAR_MAX;
570 s += len+2;
571 } else {
572 min = max = wc;
573 s += len;
574 if (*s == '-' && s[1] != ']') {
575 s++;
576 len = mbtowc(&wc, s, -1);
577 max = wc;
578 /* XXX - Should use collation order instead of
579 encoding values in character ranges. */
580 if (len <= 0 || min > max)
581 return REG_ERANGE;
582 s += len;
583 }
584 }
585
586 if (class && neg->negate) {
587 if (neg->len >= MAX_NEG_CLASSES)
588 return REG_ESPACE;
589 neg->a[neg->len++] = class;
590 } else {
591 tre_literal_t *lit = tre_new_lit(ls);
592 if (!lit)
593 return REG_ESPACE;
594 lit->code_min = min;
595 lit->code_max = max;
596 lit->class = class;
597 lit->position = -1;
598
599 /* Add opposite-case codepoints if REG_ICASE is present.
600 It seems that POSIX requires that bracket negation
601 should happen before case-folding, but most practical
602 implementations do it the other way around. Changing
603 the order would need efficient representation of
604 case-fold ranges and bracket range sets even with
605 simple patterns so this is ok for now. */
606 if (ctx->cflags & REG_ICASE && !class)
607 if (add_icase_literals(ls, min, max))
608 return REG_ESPACE;
609 }
610 }
611}
612
613static reg_errcode_t parse_bracket(tre_parse_ctx_t *ctx, const char *s)
614{
615 int i, max, min, negmax, negmin;
616 tre_ast_node_t *node = 0, *n;
617 tre_ctype_t *nc = 0;
618 tre_literal_t *lit;
619 struct literals ls;
620 struct neg neg;
621 reg_errcode_t err;
622
623 ls.mem = ctx->mem;
624 ls.len = 0;
625 ls.cap = 32;
626 ls.a = xmalloc(ls.cap * sizeof *ls.a);
627 if (!ls.a)
628 return REG_ESPACE;
629 neg.len = 0;
630 neg.negate = *s == '^';
631 if (neg.negate)
632 s++;
633
634 err = parse_bracket_terms(ctx, s, &ls, &neg);
635 if (err != REG_OK)
636 goto parse_bracket_done;
637
638 if (neg.negate) {
639 /*
640 * With REG_NEWLINE, POSIX requires that newlines are not matched by
641 * any form of a non-matching list.
642 */
643 if (ctx->cflags & REG_NEWLINE) {
644 lit = tre_new_lit(&ls);
645 if (!lit) {
646 err = REG_ESPACE;
647 goto parse_bracket_done;
648 }
649 lit->code_min = '\n';
650 lit->code_max = '\n';
651 lit->position = -1;
652 }
653 /* Sort the array if we need to negate it. */
654 qsort(ls.a, ls.len, sizeof *ls.a, tre_compare_lit);
655 /* extra lit for the last negated range */
656 lit = tre_new_lit(&ls);
657 if (!lit) {
658 err = REG_ESPACE;
659 goto parse_bracket_done;
660 }
661 lit->code_min = TRE_CHAR_MAX+1;
662 lit->code_max = TRE_CHAR_MAX+1;
663 lit->position = -1;
664 /* negated classes */
665 if (neg.len) {
666 nc = tre_mem_alloc(ctx->mem, (neg.len+1)*sizeof *neg.a);
667 if (!nc) {
668 err = REG_ESPACE;
669 goto parse_bracket_done;
670 }
671 memcpy(nc, neg.a, neg.len*sizeof *neg.a);
672 nc[neg.len] = 0;
673 }
674 }
675
676 /* Build a union of the items in the array, negated if necessary. */
677 negmax = negmin = 0;
678 for (i = 0; i < ls.len; i++) {
679 lit = ls.a[i];
680 min = lit->code_min;
681 max = lit->code_max;
682 if (neg.negate) {
683 if (min <= negmin) {
684 /* Overlap. */
685 negmin = MAX(max + 1, negmin);
686 continue;
687 }
688 negmax = min - 1;
689 lit->code_min = negmin;
690 lit->code_max = negmax;
691 negmin = max + 1;
692 }
693 lit->position = ctx->position;
694 lit->neg_classes = nc;
695 n = tre_ast_new_node(ctx->mem, LITERAL, lit);
696 node = tre_ast_new_union(ctx->mem, node, n);
697 if (!node) {
698 err = REG_ESPACE;
699 break;
700 }
701 }
702
703parse_bracket_done:
704 xfree(ls.a);
705 ctx->position++;
706 ctx->n = node;
707 return err;
708}
709
710static const char *parse_dup_count(const char *s, int *n)
711{
712 *n = -1;
713 if (!isdigit(*s))
714 return s;
715 *n = 0;
716 for (;;) {
717 *n = 10 * *n + (*s - '0');
718 s++;
719 if (!isdigit(*s) || *n > RE_DUP_MAX)
720 break;
721 }
722 return s;
723}
724
725static const char *parse_dup(const char *s, int ere, int *pmin, int *pmax)
726{
727 int min, max;
728
729 s = parse_dup_count(s, &min);
730 if (*s == ',')
731 s = parse_dup_count(s+1, &max);
732 else
733 max = min;
734
735 if (
736 (max < min && max >= 0) ||
737 max > RE_DUP_MAX ||
738 min > RE_DUP_MAX ||
739 min < 0 ||
740 (!ere && *s++ != '\\') ||
741 *s++ != '}'
742 )
743 return 0;
744 *pmin = min;
745 *pmax = max;
746 return s;
747}
748
749static int hexval(unsigned c)
750{
751 if (c-'0'<10) return c-'0';
752 c |= 32;
753 if (c-'a'<6) return c-'a'+10;
754 return -1;
755}
756
757static reg_errcode_t marksub(tre_parse_ctx_t *ctx, tre_ast_node_t *node, int subid)
758{
759 if (node->submatch_id >= 0) {
760 tre_ast_node_t *n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
761 if (!n)
762 return REG_ESPACE;
763 n = tre_ast_new_catenation(ctx->mem, n, node);
764 if (!n)
765 return REG_ESPACE;
766 n->num_submatches = node->num_submatches;
767 node = n;
768 }
769 node->submatch_id = subid;
770 node->num_submatches++;
771 ctx->n = node;
772 return REG_OK;
773}
774
775/*
776BRE grammar:
777Regex = Branch | '^' | '$' | '^$' | '^' Branch | Branch '$' | '^' Branch '$'
778Branch = Atom | Branch Atom
779Atom = char | quoted_char | '.' | Bracket | Atom Dup | '\(' Branch '\)' | back_ref
780Dup = '*' | '\{' Count '\}' | '\{' Count ',\}' | '\{' Count ',' Count '\}'
781
782(leading ^ and trailing $ in a sub expr may be an anchor or literal as well)
783
784ERE grammar:
785Regex = Branch | Regex '|' Branch
786Branch = Atom | Branch Atom
787Atom = char | quoted_char | '.' | Bracket | Atom Dup | '(' Regex ')' | '^' | '$'
788Dup = '*' | '+' | '?' | '{' Count '}' | '{' Count ',}' | '{' Count ',' Count '}'
789
790(a*+?, ^*, $+, \X, {, (|a) are unspecified)
791*/
792
793static reg_errcode_t parse_atom(tre_parse_ctx_t *ctx, const char *s)
794{
795 int len, ere = ctx->cflags & REG_EXTENDED;
796 const char *p;
797 tre_ast_node_t *node;
798 wchar_t wc;
799 switch (*s) {
800 case '[':
801 return parse_bracket(ctx, s+1);
802 case '\\':
803 p = tre_expand_macro(s+1);
804 if (p) {
805 /* assume \X expansion is a single atom */
806 reg_errcode_t err = parse_atom(ctx, p);
807 ctx->s = s+2;
808 return err;
809 }
810 /* extensions: \b, \B, \<, \>, \xHH \x{HHHH} */
811 switch (*++s) {
812 case 0:
813 return REG_EESCAPE;
814 case 'b':
815 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB, -1);
816 break;
817 case 'B':
818 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_WB_NEG, -1);
819 break;
820 case '<':
821 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOW, -1);
822 break;
823 case '>':
824 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOW, -1);
825 break;
826 case 'x':
827 s++;
828 int i, v = 0, c;
829 len = 2;
830 if (*s == '{') {
831 len = 8;
832 s++;
833 }
834 for (i=0; i<len && v<0x110000; i++) {
835 c = hexval(s[i]);
836 if (c < 0) break;
837 v = 16*v + c;
838 }
839 s += i;
840 if (len == 8) {
841 if (*s != '}')
842 return REG_EBRACE;
843 s++;
844 }
845 node = tre_ast_new_literal(ctx->mem, v, v, ctx->position++);
846 s--;
847 break;
848 case '{':
849 case '+':
850 case '?':
851 /* extension: treat \+, \? as repetitions in BRE */
852 /* reject repetitions after empty expression in BRE */
853 if (!ere)
854 return REG_BADRPT;
855 case '|':
856 /* extension: treat \| as alternation in BRE */
857 if (!ere) {
858 node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
859 s--;
860 goto end;
861 }
862 /* fallthrough */
863 default:
864 if (!ere && (unsigned)*s-'1' < 9) {
865 /* back reference */
866 int val = *s - '0';
867 node = tre_ast_new_literal(ctx->mem, BACKREF, val, ctx->position++);
868 ctx->max_backref = MAX(val, ctx->max_backref);
869 } else {
870 /* extension: accept unknown escaped char
871 as a literal */
872 goto parse_literal;
873 }
874 }
875 s++;
876 break;
877 case '.':
878 if (ctx->cflags & REG_NEWLINE) {
879 tre_ast_node_t *tmp1, *tmp2;
880 tmp1 = tre_ast_new_literal(ctx->mem, 0, '\n'-1, ctx->position++);
881 tmp2 = tre_ast_new_literal(ctx->mem, '\n'+1, TRE_CHAR_MAX, ctx->position++);
882 if (tmp1 && tmp2)
883 node = tre_ast_new_union(ctx->mem, tmp1, tmp2);
884 else
885 node = 0;
886 } else {
887 node = tre_ast_new_literal(ctx->mem, 0, TRE_CHAR_MAX, ctx->position++);
888 }
889 s++;
890 break;
891 case '^':
892 /* '^' has a special meaning everywhere in EREs, and at beginning of BRE. */
893 if (!ere && s != ctx->start)
894 goto parse_literal;
895 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_BOL, -1);
896 s++;
897 break;
898 case '$':
899 /* '$' is special everywhere in EREs, and at the end of a BRE subexpression. */
900 if (!ere && s[1] && (s[1]!='\\'|| (s[2]!=')' && s[2]!='|')))
901 goto parse_literal;
902 node = tre_ast_new_literal(ctx->mem, ASSERTION, ASSERT_AT_EOL, -1);
903 s++;
904 break;
905 case '*':
906 case '{':
907 case '+':
908 case '?':
909 /* reject repetitions after empty expression in ERE */
910 if (ere)
911 return REG_BADRPT;
912 case '|':
913 if (!ere)
914 goto parse_literal;
915 case 0:
916 node = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
917 break;
918 default:
919parse_literal:
920 len = mbtowc(&wc, s, -1);
921 if (len < 0)
922 return REG_BADPAT;
923 if (ctx->cflags & REG_ICASE && (tre_isupper(wc) || tre_islower(wc))) {
924 tre_ast_node_t *tmp1, *tmp2;
925 /* multiple opposite case characters are not supported */
926 tmp1 = tre_ast_new_literal(ctx->mem, tre_toupper(wc), tre_toupper(wc), ctx->position);
927 tmp2 = tre_ast_new_literal(ctx->mem, tre_tolower(wc), tre_tolower(wc), ctx->position);
928 if (tmp1 && tmp2)
929 node = tre_ast_new_union(ctx->mem, tmp1, tmp2);
930 else
931 node = 0;
932 } else {
933 node = tre_ast_new_literal(ctx->mem, wc, wc, ctx->position);
934 }
935 ctx->position++;
936 s += len;
937 break;
938 }
939end:
940 if (!node)
941 return REG_ESPACE;
942 ctx->n = node;
943 ctx->s = s;
944 return REG_OK;
945}
946
947#define PUSHPTR(err, s, v) do { \
948 if ((err = tre_stack_push_voidptr(s, v)) != REG_OK) \
949 return err; \
950} while(0)
951
952#define PUSHINT(err, s, v) do { \
953 if ((err = tre_stack_push_int(s, v)) != REG_OK) \
954 return err; \
955} while(0)
956
957static reg_errcode_t tre_parse(tre_parse_ctx_t *ctx)
958{
959 tre_ast_node_t *nbranch=0, *nunion=0;
960 int ere = ctx->cflags & REG_EXTENDED;
961 const char *s = ctx->start;
962 int subid = 0;
963 int depth = 0;
964 reg_errcode_t err;
965 tre_stack_t *stack = ctx->stack;
966
967 PUSHINT(err, stack, subid++);
968 for (;;) {
969 if ((!ere && *s == '\\' && s[1] == '(') ||
970 (ere && *s == '(')) {
971 PUSHPTR(err, stack, nunion);
972 PUSHPTR(err, stack, nbranch);
973 PUSHINT(err, stack, subid++);
974 s++;
975 if (!ere)
976 s++;
977 depth++;
978 nbranch = nunion = 0;
979 ctx->start = s;
980 continue;
981 }
982 if ((!ere && *s == '\\' && s[1] == ')') ||
983 (ere && *s == ')' && depth)) {
984 ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
985 if (!ctx->n)
986 return REG_ESPACE;
987 } else {
988 err = parse_atom(ctx, s);
989 if (err != REG_OK)
990 return err;
991 s = ctx->s;
992 }
993
994 parse_iter:
995 for (;;) {
996 int min, max;
997
998 if (*s!='\\' && *s!='*') {
999 if (!ere)
1000 break;
1001 if (*s!='+' && *s!='?' && *s!='{')
1002 break;
1003 }
1004 if (*s=='\\' && ere)
1005 break;
1006 /* extension: treat \+, \? as repetitions in BRE */
1007 if (*s=='\\' && s[1]!='+' && s[1]!='?' && s[1]!='{')
1008 break;
1009 if (*s=='\\')
1010 s++;
1011
1012 /* handle ^* at the start of a BRE. */
1013 if (!ere && s==ctx->start+1 && s[-1]=='^')
1014 break;
1015
1016 /* extension: multiple consecutive *+?{,} is unspecified,
1017 but (a+)+ has to be supported so accepting a++ makes
1018 sense, note however that the RE_DUP_MAX limit can be
1019 circumvented: (a{255}){255} uses a lot of memory.. */
1020 if (*s=='{') {
1021 s = parse_dup(s+1, ere, &min, &max);
1022 if (!s)
1023 return REG_BADBR;
1024 } else {
1025 min=0;
1026 max=-1;
1027 if (*s == '+')
1028 min = 1;
1029 if (*s == '?')
1030 max = 1;
1031 s++;
1032 }
1033 if (max == 0)
1034 ctx->n = tre_ast_new_literal(ctx->mem, EMPTY, -1, -1);
1035 else
1036 ctx->n = tre_ast_new_iter(ctx->mem, ctx->n, min, max, 0);
1037 if (!ctx->n)
1038 return REG_ESPACE;
1039 }
1040
1041 nbranch = tre_ast_new_catenation(ctx->mem, nbranch, ctx->n);
1042 if ((ere && *s == '|') ||
1043 (ere && *s == ')' && depth) ||
1044 (!ere && *s == '\\' && s[1] == ')') ||
1045 /* extension: treat \| as alternation in BRE */
1046 (!ere && *s == '\\' && s[1] == '|') ||
1047 !*s) {
1048 /* extension: empty branch is unspecified (), (|a), (a|)
1049 here they are not rejected but match on empty string */
1050 int c = *s;
1051 nunion = tre_ast_new_union(ctx->mem, nunion, nbranch);
1052 nbranch = 0;
1053
1054 if (c == '\\' && s[1] == '|') {
1055 s+=2;
1056 ctx->start = s;
1057 } else if (c == '|') {
1058 s++;
1059 ctx->start = s;
1060 } else {
1061 if (c == '\\') {
1062 if (!depth) return REG_EPAREN;
1063 s+=2;
1064 } else if (c == ')')
1065 s++;
1066 depth--;
1067 err = marksub(ctx, nunion, tre_stack_pop_int(stack));
1068 if (err != REG_OK)
1069 return err;
1070 if (!c && depth<0) {
1071 ctx->submatch_id = subid;
1072 return REG_OK;
1073 }
1074 if (!c || depth<0)
1075 return REG_EPAREN;
1076 nbranch = tre_stack_pop_voidptr(stack);
1077 nunion = tre_stack_pop_voidptr(stack);
1078 goto parse_iter;
1079 }
1080 }
1081 }
1082}
1083
1084
1085/***********************************************************************
1086 from tre-compile.c
1087***********************************************************************/
1088
1089
1090/*
1091 TODO:
1092 - Fix tre_ast_to_tnfa() to recurse using a stack instead of recursive
1093 function calls.
1094*/
1095
1096/*
1097 Algorithms to setup tags so that submatch addressing can be done.
1098*/
1099
1100
1101/* Inserts a catenation node to the root of the tree given in `node'.
1102 As the left child a new tag with number `tag_id' to `node' is added,
1103 and the right child is the old root. */
1104static reg_errcode_t
1105tre_add_tag_left(tre_mem_t mem, tre_ast_node_t *node, int tag_id)
1106{
1107 tre_catenation_t *c;
1108
1109 c = tre_mem_alloc(mem, sizeof(*c));
1110 if (c == NULL)
1111 return REG_ESPACE;
1112 c->left = tre_ast_new_literal(mem, TAG, tag_id, -1);
1113 if (c->left == NULL)
1114 return REG_ESPACE;
1115 c->right = tre_mem_alloc(mem, sizeof(tre_ast_node_t));
1116 if (c->right == NULL)
1117 return REG_ESPACE;
1118
1119 c->right->obj = node->obj;
1120 c->right->type = node->type;
1121 c->right->nullable = -1;
1122 c->right->submatch_id = -1;
1123 c->right->firstpos = NULL;
1124 c->right->lastpos = NULL;
1125 c->right->num_tags = 0;
1126 c->right->num_submatches = 0;
1127 node->obj = c;
1128 node->type = CATENATION;
1129 return REG_OK;
1130}
1131
1132/* Inserts a catenation node to the root of the tree given in `node'.
1133 As the right child a new tag with number `tag_id' to `node' is added,
1134 and the left child is the old root. */
1135static reg_errcode_t
1136tre_add_tag_right(tre_mem_t mem, tre_ast_node_t *node, int tag_id)
1137{
1138 tre_catenation_t *c;
1139
1140 c = tre_mem_alloc(mem, sizeof(*c));
1141 if (c == NULL)
1142 return REG_ESPACE;
1143 c->right = tre_ast_new_literal(mem, TAG, tag_id, -1);
1144 if (c->right == NULL)
1145 return REG_ESPACE;
1146 c->left = tre_mem_alloc(mem, sizeof(tre_ast_node_t));
1147 if (c->left == NULL)
1148 return REG_ESPACE;
1149
1150 c->left->obj = node->obj;
1151 c->left->type = node->type;
1152 c->left->nullable = -1;
1153 c->left->submatch_id = -1;
1154 c->left->firstpos = NULL;
1155 c->left->lastpos = NULL;
1156 c->left->num_tags = 0;
1157 c->left->num_submatches = 0;
1158 node->obj = c;
1159 node->type = CATENATION;
1160 return REG_OK;
1161}
1162
1163typedef enum {
1164 ADDTAGS_RECURSE,
1165 ADDTAGS_AFTER_ITERATION,
1166 ADDTAGS_AFTER_UNION_LEFT,
1167 ADDTAGS_AFTER_UNION_RIGHT,
1168 ADDTAGS_AFTER_CAT_LEFT,
1169 ADDTAGS_AFTER_CAT_RIGHT,
1170 ADDTAGS_SET_SUBMATCH_END
1171} tre_addtags_symbol_t;
1172
1173
1174typedef struct {
1175 int tag;
1176 int next_tag;
1177} tre_tag_states_t;
1178
1179
1180/* Go through `regset' and set submatch data for submatches that are
1181 using this tag. */
1182static void
1183tre_purge_regset(int *regset, tre_tnfa_t *tnfa, int tag)
1184{
1185 int i;
1186
1187 for (i = 0; regset[i] >= 0; i++)
1188 {
1189 int id = regset[i] / 2;
1190 int start = !(regset[i] % 2);
1191 if (start)
1192 tnfa->submatch_data[id].so_tag = tag;
1193 else
1194 tnfa->submatch_data[id].eo_tag = tag;
1195 }
1196 regset[0] = -1;
1197}
1198
1199
1200/* Adds tags to appropriate locations in the parse tree in `tree', so that
1201 subexpressions marked for submatch addressing can be traced. */
1202static reg_errcode_t
1203tre_add_tags(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree,
1204 tre_tnfa_t *tnfa)
1205{
1206 reg_errcode_t status = REG_OK;
1207 tre_addtags_symbol_t symbol;
1208 tre_ast_node_t *node = tree; /* Tree node we are currently looking at. */
1209 int bottom = tre_stack_num_objects(stack);
1210 /* True for first pass (counting number of needed tags) */
1211 int first_pass = (mem == NULL || tnfa == NULL);
1212 int *regset, *orig_regset;
1213 int num_tags = 0; /* Total number of tags. */
1214 int num_minimals = 0; /* Number of special minimal tags. */
1215 int tag = 0; /* The tag that is to be added next. */
1216 int next_tag = 1; /* Next tag to use after this one. */
1217 int *parents; /* Stack of submatches the current submatch is
1218 contained in. */
1219 int minimal_tag = -1; /* Tag that marks the beginning of a minimal match. */
1220 tre_tag_states_t *saved_states;
1221
1222 tre_tag_direction_t direction = TRE_TAG_MINIMIZE;
1223 if (!first_pass)
1224 {
1225 tnfa->end_tag = 0;
1226 tnfa->minimal_tags[0] = -1;
1227 }
1228
1229 regset = xmalloc(sizeof(*regset) * ((tnfa->num_submatches + 1) * 2));
1230 if (regset == NULL)
1231 return REG_ESPACE;
1232 regset[0] = -1;
1233 orig_regset = regset;
1234
1235 parents = xmalloc(sizeof(*parents) * (tnfa->num_submatches + 1));
1236 if (parents == NULL)
1237 {
1238 xfree(regset);
1239 return REG_ESPACE;
1240 }
1241 parents[0] = -1;
1242
1243 saved_states = xmalloc(sizeof(*saved_states) * (tnfa->num_submatches + 1));
1244 if (saved_states == NULL)
1245 {
1246 xfree(regset);
1247 xfree(parents);
1248 return REG_ESPACE;
1249 }
1250 else
1251 {
1252 unsigned int i;
1253 for (i = 0; i <= tnfa->num_submatches; i++)
1254 saved_states[i].tag = -1;
1255 }
1256
1257 STACK_PUSH(stack, voidptr, node);
1258 STACK_PUSH(stack, int, ADDTAGS_RECURSE);
1259
1260 while (tre_stack_num_objects(stack) > bottom)
1261 {
1262 if (status != REG_OK)
1263 break;
1264
1265 symbol = (tre_addtags_symbol_t)tre_stack_pop_int(stack);
1266 switch (symbol)
1267 {
1268
1269 case ADDTAGS_SET_SUBMATCH_END:
1270 {
1271 int id = tre_stack_pop_int(stack);
1272 int i;
1273
1274 /* Add end of this submatch to regset. */
1275 for (i = 0; regset[i] >= 0; i++);
1276 regset[i] = id * 2 + 1;
1277 regset[i + 1] = -1;
1278
1279 /* Pop this submatch from the parents stack. */
1280 for (i = 0; parents[i] >= 0; i++);
1281 parents[i - 1] = -1;
1282 break;
1283 }
1284
1285 case ADDTAGS_RECURSE:
1286 node = tre_stack_pop_voidptr(stack);
1287
1288 if (node->submatch_id >= 0)
1289 {
1290 int id = node->submatch_id;
1291 int i;
1292
1293
1294 /* Add start of this submatch to regset. */
1295 for (i = 0; regset[i] >= 0; i++);
1296 regset[i] = id * 2;
1297 regset[i + 1] = -1;
1298
1299 if (!first_pass)
1300 {
1301 for (i = 0; parents[i] >= 0; i++);
1302 tnfa->submatch_data[id].parents = NULL;
1303 if (i > 0)
1304 {
1305 int *p = xmalloc(sizeof(*p) * (i + 1));
1306 if (p == NULL)
1307 {
1308 status = REG_ESPACE;
1309 break;
1310 }
1311 assert(tnfa->submatch_data[id].parents == NULL);
1312 tnfa->submatch_data[id].parents = p;
1313 for (i = 0; parents[i] >= 0; i++)
1314 p[i] = parents[i];
1315 p[i] = -1;
1316 }
1317 }
1318
1319 /* Add end of this submatch to regset after processing this
1320 node. */
1321 STACK_PUSHX(stack, int, node->submatch_id);
1322 STACK_PUSHX(stack, int, ADDTAGS_SET_SUBMATCH_END);
1323 }
1324
1325 switch (node->type)
1326 {
1327 case LITERAL:
1328 {
1329 tre_literal_t *lit = node->obj;
1330
1331 if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
1332 {
1333 int i;
1334 if (regset[0] >= 0)
1335 {
1336 /* Regset is not empty, so add a tag before the
1337 literal or backref. */
1338 if (!first_pass)
1339 {
1340 status = tre_add_tag_left(mem, node, tag);
1341 tnfa->tag_directions[tag] = direction;
1342 if (minimal_tag >= 0)
1343 {
1344 for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
1345 tnfa->minimal_tags[i] = tag;
1346 tnfa->minimal_tags[i + 1] = minimal_tag;
1347 tnfa->minimal_tags[i + 2] = -1;
1348 minimal_tag = -1;
1349 num_minimals++;
1350 }
1351 tre_purge_regset(regset, tnfa, tag);
1352 }
1353 else
1354 {
1355 node->num_tags = 1;
1356 }
1357
1358 regset[0] = -1;
1359 tag = next_tag;
1360 num_tags++;
1361 next_tag++;
1362 }
1363 }
1364 else
1365 {
1366 assert(!IS_TAG(lit));
1367 }
1368 break;
1369 }
1370 case CATENATION:
1371 {
1372 tre_catenation_t *cat = node->obj;
1373 tre_ast_node_t *left = cat->left;
1374 tre_ast_node_t *right = cat->right;
1375 int reserved_tag = -1;
1376
1377
1378 /* After processing right child. */
1379 STACK_PUSHX(stack, voidptr, node);
1380 STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_RIGHT);
1381
1382 /* Process right child. */
1383 STACK_PUSHX(stack, voidptr, right);
1384 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1385
1386 /* After processing left child. */
1387 STACK_PUSHX(stack, int, next_tag + left->num_tags);
1388 if (left->num_tags > 0 && right->num_tags > 0)
1389 {
1390 /* Reserve the next tag to the right child. */
1391 reserved_tag = next_tag;
1392 next_tag++;
1393 }
1394 STACK_PUSHX(stack, int, reserved_tag);
1395 STACK_PUSHX(stack, int, ADDTAGS_AFTER_CAT_LEFT);
1396
1397 /* Process left child. */
1398 STACK_PUSHX(stack, voidptr, left);
1399 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1400
1401 }
1402 break;
1403 case ITERATION:
1404 {
1405 tre_iteration_t *iter = node->obj;
1406
1407 if (first_pass)
1408 {
1409 STACK_PUSHX(stack, int, regset[0] >= 0 || iter->minimal);
1410 }
1411 else
1412 {
1413 STACK_PUSHX(stack, int, tag);
1414 STACK_PUSHX(stack, int, iter->minimal);
1415 }
1416 STACK_PUSHX(stack, voidptr, node);
1417 STACK_PUSHX(stack, int, ADDTAGS_AFTER_ITERATION);
1418
1419 STACK_PUSHX(stack, voidptr, iter->arg);
1420 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1421
1422 /* Regset is not empty, so add a tag here. */
1423 if (regset[0] >= 0 || iter->minimal)
1424 {
1425 if (!first_pass)
1426 {
1427 int i;
1428 status = tre_add_tag_left(mem, node, tag);
1429 if (iter->minimal)
1430 tnfa->tag_directions[tag] = TRE_TAG_MAXIMIZE;
1431 else
1432 tnfa->tag_directions[tag] = direction;
1433 if (minimal_tag >= 0)
1434 {
1435 for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
1436 tnfa->minimal_tags[i] = tag;
1437 tnfa->minimal_tags[i + 1] = minimal_tag;
1438 tnfa->minimal_tags[i + 2] = -1;
1439 minimal_tag = -1;
1440 num_minimals++;
1441 }
1442 tre_purge_regset(regset, tnfa, tag);
1443 }
1444
1445 regset[0] = -1;
1446 tag = next_tag;
1447 num_tags++;
1448 next_tag++;
1449 }
1450 direction = TRE_TAG_MINIMIZE;
1451 }
1452 break;
1453 case UNION:
1454 {
1455 tre_union_t *uni = node->obj;
1456 tre_ast_node_t *left = uni->left;
1457 tre_ast_node_t *right = uni->right;
1458 int left_tag;
1459 int right_tag;
1460
1461 if (regset[0] >= 0)
1462 {
1463 left_tag = next_tag;
1464 right_tag = next_tag + 1;
1465 }
1466 else
1467 {
1468 left_tag = tag;
1469 right_tag = next_tag;
1470 }
1471
1472 /* After processing right child. */
1473 STACK_PUSHX(stack, int, right_tag);
1474 STACK_PUSHX(stack, int, left_tag);
1475 STACK_PUSHX(stack, voidptr, regset);
1476 STACK_PUSHX(stack, int, regset[0] >= 0);
1477 STACK_PUSHX(stack, voidptr, node);
1478 STACK_PUSHX(stack, voidptr, right);
1479 STACK_PUSHX(stack, voidptr, left);
1480 STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_RIGHT);
1481
1482 /* Process right child. */
1483 STACK_PUSHX(stack, voidptr, right);
1484 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1485
1486 /* After processing left child. */
1487 STACK_PUSHX(stack, int, ADDTAGS_AFTER_UNION_LEFT);
1488
1489 /* Process left child. */
1490 STACK_PUSHX(stack, voidptr, left);
1491 STACK_PUSHX(stack, int, ADDTAGS_RECURSE);
1492
1493 /* Regset is not empty, so add a tag here. */
1494 if (regset[0] >= 0)
1495 {
1496 if (!first_pass)
1497 {
1498 int i;
1499 status = tre_add_tag_left(mem, node, tag);
1500 tnfa->tag_directions[tag] = direction;
1501 if (minimal_tag >= 0)
1502 {
1503 for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
1504 tnfa->minimal_tags[i] = tag;
1505 tnfa->minimal_tags[i + 1] = minimal_tag;
1506 tnfa->minimal_tags[i + 2] = -1;
1507 minimal_tag = -1;
1508 num_minimals++;
1509 }
1510 tre_purge_regset(regset, tnfa, tag);
1511 }
1512
1513 regset[0] = -1;
1514 tag = next_tag;
1515 num_tags++;
1516 next_tag++;
1517 }
1518
1519 if (node->num_submatches > 0)
1520 {
1521 /* The next two tags are reserved for markers. */
1522 next_tag++;
1523 tag = next_tag;
1524 next_tag++;
1525 }
1526
1527 break;
1528 }
1529 }
1530
1531 if (node->submatch_id >= 0)
1532 {
1533 int i;
1534 /* Push this submatch on the parents stack. */
1535 for (i = 0; parents[i] >= 0; i++);
1536 parents[i] = node->submatch_id;
1537 parents[i + 1] = -1;
1538 }
1539
1540 break; /* end case: ADDTAGS_RECURSE */
1541
1542 case ADDTAGS_AFTER_ITERATION:
1543 {
1544 int minimal = 0;
1545 int enter_tag;
1546 node = tre_stack_pop_voidptr(stack);
1547 if (first_pass)
1548 {
1549 node->num_tags = ((tre_iteration_t *)node->obj)->arg->num_tags
1550 + tre_stack_pop_int(stack);
1551 minimal_tag = -1;
1552 }
1553 else
1554 {
1555 minimal = tre_stack_pop_int(stack);
1556 enter_tag = tre_stack_pop_int(stack);
1557 if (minimal)
1558 minimal_tag = enter_tag;
1559 }
1560
1561 if (!first_pass)
1562 {
1563 if (minimal)
1564 direction = TRE_TAG_MINIMIZE;
1565 else
1566 direction = TRE_TAG_MAXIMIZE;
1567 }
1568 break;
1569 }
1570
1571 case ADDTAGS_AFTER_CAT_LEFT:
1572 {
1573 int new_tag = tre_stack_pop_int(stack);
1574 next_tag = tre_stack_pop_int(stack);
1575 if (new_tag >= 0)
1576 {
1577 tag = new_tag;
1578 }
1579 break;
1580 }
1581
1582 case ADDTAGS_AFTER_CAT_RIGHT:
1583 node = tre_stack_pop_voidptr(stack);
1584 if (first_pass)
1585 node->num_tags = ((tre_catenation_t *)node->obj)->left->num_tags
1586 + ((tre_catenation_t *)node->obj)->right->num_tags;
1587 break;
1588
1589 case ADDTAGS_AFTER_UNION_LEFT:
1590 /* Lift the bottom of the `regset' array so that when processing
1591 the right operand the items currently in the array are
1592 invisible. The original bottom was saved at ADDTAGS_UNION and
1593 will be restored at ADDTAGS_AFTER_UNION_RIGHT below. */
1594 while (*regset >= 0)
1595 regset++;
1596 break;
1597
1598 case ADDTAGS_AFTER_UNION_RIGHT:
1599 {
1600 int added_tags, tag_left, tag_right;
1601 tre_ast_node_t *left = tre_stack_pop_voidptr(stack);
1602 tre_ast_node_t *right = tre_stack_pop_voidptr(stack);
1603 node = tre_stack_pop_voidptr(stack);
1604 added_tags = tre_stack_pop_int(stack);
1605 if (first_pass)
1606 {
1607 node->num_tags = ((tre_union_t *)node->obj)->left->num_tags
1608 + ((tre_union_t *)node->obj)->right->num_tags + added_tags
1609 + ((node->num_submatches > 0) ? 2 : 0);
1610 }
1611 regset = tre_stack_pop_voidptr(stack);
1612 tag_left = tre_stack_pop_int(stack);
1613 tag_right = tre_stack_pop_int(stack);
1614
1615 /* Add tags after both children, the left child gets a smaller
1616 tag than the right child. This guarantees that we prefer
1617 the left child over the right child. */
1618 /* XXX - This is not always necessary (if the children have
1619 tags which must be seen for every match of that child). */
1620 /* XXX - Check if this is the only place where tre_add_tag_right
1621 is used. If so, use tre_add_tag_left (putting the tag before
1622 the child as opposed after the child) and throw away
1623 tre_add_tag_right. */
1624 if (node->num_submatches > 0)
1625 {
1626 if (!first_pass)
1627 {
1628 status = tre_add_tag_right(mem, left, tag_left);
1629 tnfa->tag_directions[tag_left] = TRE_TAG_MAXIMIZE;
1630 if (status == REG_OK)
1631 status = tre_add_tag_right(mem, right, tag_right);
1632 tnfa->tag_directions[tag_right] = TRE_TAG_MAXIMIZE;
1633 }
1634 num_tags += 2;
1635 }
1636 direction = TRE_TAG_MAXIMIZE;
1637 break;
1638 }
1639
1640 default:
1641 assert(0);
1642 break;
1643
1644 } /* end switch(symbol) */
1645 } /* end while(tre_stack_num_objects(stack) > bottom) */
1646
1647 if (!first_pass)
1648 tre_purge_regset(regset, tnfa, tag);
1649
1650 if (!first_pass && minimal_tag >= 0)
1651 {
1652 int i;
1653 for (i = 0; tnfa->minimal_tags[i] >= 0; i++);
1654 tnfa->minimal_tags[i] = tag;
1655 tnfa->minimal_tags[i + 1] = minimal_tag;
1656 tnfa->minimal_tags[i + 2] = -1;
1657 minimal_tag = -1;
1658 num_minimals++;
1659 }
1660
1661 assert(tree->num_tags == num_tags);
1662 tnfa->end_tag = num_tags;
1663 tnfa->num_tags = num_tags;
1664 tnfa->num_minimals = num_minimals;
1665 xfree(orig_regset);
1666 xfree(parents);
1667 xfree(saved_states);
1668 return status;
1669}
1670
1671
1672
1673/*
1674 AST to TNFA compilation routines.
1675*/
1676
1677typedef enum {
1678 COPY_RECURSE,
1679 COPY_SET_RESULT_PTR
1680} tre_copyast_symbol_t;
1681
1682/* Flags for tre_copy_ast(). */
1683#define COPY_REMOVE_TAGS 1
1684#define COPY_MAXIMIZE_FIRST_TAG 2
1685
1686static reg_errcode_t
1687tre_copy_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
1688 int flags, int *pos_add, tre_tag_direction_t *tag_directions,
1689 tre_ast_node_t **copy, int *max_pos)
1690{
1691 reg_errcode_t status = REG_OK;
1692 int bottom = tre_stack_num_objects(stack);
1693 int num_copied = 0;
1694 int first_tag = 1;
1695 tre_ast_node_t **result = copy;
1696 tre_copyast_symbol_t symbol;
1697
1698 STACK_PUSH(stack, voidptr, ast);
1699 STACK_PUSH(stack, int, COPY_RECURSE);
1700
1701 while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
1702 {
1703 tre_ast_node_t *node;
1704 if (status != REG_OK)
1705 break;
1706
1707 symbol = (tre_copyast_symbol_t)tre_stack_pop_int(stack);
1708 switch (symbol)
1709 {
1710 case COPY_SET_RESULT_PTR:
1711 result = tre_stack_pop_voidptr(stack);
1712 break;
1713 case COPY_RECURSE:
1714 node = tre_stack_pop_voidptr(stack);
1715 switch (node->type)
1716 {
1717 case LITERAL:
1718 {
1719 tre_literal_t *lit = node->obj;
1720 int pos = lit->position;
1721 int min = lit->code_min;
1722 int max = lit->code_max;
1723 if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
1724 {
1725 /* XXX - e.g. [ab] has only one position but two
1726 nodes, so we are creating holes in the state space
1727 here. Not fatal, just wastes memory. */
1728 pos += *pos_add;
1729 num_copied++;
1730 }
1731 else if (IS_TAG(lit) && (flags & COPY_REMOVE_TAGS))
1732 {
1733 /* Change this tag to empty. */
1734 min = EMPTY;
1735 max = pos = -1;
1736 }
1737 else if (IS_TAG(lit) && (flags & COPY_MAXIMIZE_FIRST_TAG)
1738 && first_tag)
1739 {
1740 /* Maximize the first tag. */
1741 tag_directions[max] = TRE_TAG_MAXIMIZE;
1742 first_tag = 0;
1743 }
1744 *result = tre_ast_new_literal(mem, min, max, pos);
1745 if (*result == NULL)
1746 status = REG_ESPACE;
1747 else {
1748 tre_literal_t *p = (*result)->obj;
1749 p->class = lit->class;
1750 p->neg_classes = lit->neg_classes;
1751 }
1752
1753 if (pos > *max_pos)
1754 *max_pos = pos;
1755 break;
1756 }
1757 case UNION:
1758 {
1759 tre_union_t *uni = node->obj;
1760 tre_union_t *tmp;
1761 *result = tre_ast_new_union(mem, uni->left, uni->right);
1762 if (*result == NULL)
1763 {
1764 status = REG_ESPACE;
1765 break;
1766 }
1767 tmp = (*result)->obj;
1768 result = &tmp->left;
1769 STACK_PUSHX(stack, voidptr, uni->right);
1770 STACK_PUSHX(stack, int, COPY_RECURSE);
1771 STACK_PUSHX(stack, voidptr, &tmp->right);
1772 STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
1773 STACK_PUSHX(stack, voidptr, uni->left);
1774 STACK_PUSHX(stack, int, COPY_RECURSE);
1775 break;
1776 }
1777 case CATENATION:
1778 {
1779 tre_catenation_t *cat = node->obj;
1780 tre_catenation_t *tmp;
1781 *result = tre_ast_new_catenation(mem, cat->left, cat->right);
1782 if (*result == NULL)
1783 {
1784 status = REG_ESPACE;
1785 break;
1786 }
1787 tmp = (*result)->obj;
1788 tmp->left = NULL;
1789 tmp->right = NULL;
1790 result = &tmp->left;
1791
1792 STACK_PUSHX(stack, voidptr, cat->right);
1793 STACK_PUSHX(stack, int, COPY_RECURSE);
1794 STACK_PUSHX(stack, voidptr, &tmp->right);
1795 STACK_PUSHX(stack, int, COPY_SET_RESULT_PTR);
1796 STACK_PUSHX(stack, voidptr, cat->left);
1797 STACK_PUSHX(stack, int, COPY_RECURSE);
1798 break;
1799 }
1800 case ITERATION:
1801 {
1802 tre_iteration_t *iter = node->obj;
1803 STACK_PUSHX(stack, voidptr, iter->arg);
1804 STACK_PUSHX(stack, int, COPY_RECURSE);
1805 *result = tre_ast_new_iter(mem, iter->arg, iter->min,
1806 iter->max, iter->minimal);
1807 if (*result == NULL)
1808 {
1809 status = REG_ESPACE;
1810 break;
1811 }
1812 iter = (*result)->obj;
1813 result = &iter->arg;
1814 break;
1815 }
1816 default:
1817 assert(0);
1818 break;
1819 }
1820 break;
1821 }
1822 }
1823 *pos_add += num_copied;
1824 return status;
1825}
1826
1827typedef enum {
1828 EXPAND_RECURSE,
1829 EXPAND_AFTER_ITER
1830} tre_expand_ast_symbol_t;
1831
1832/* Expands each iteration node that has a finite nonzero minimum or maximum
1833 iteration count to a catenated sequence of copies of the node. */
1834static reg_errcode_t
1835tre_expand_ast(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *ast,
1836 int *position, tre_tag_direction_t *tag_directions)
1837{
1838 reg_errcode_t status = REG_OK;
1839 int bottom = tre_stack_num_objects(stack);
1840 int pos_add = 0;
1841 int pos_add_total = 0;
1842 int max_pos = 0;
1843 int iter_depth = 0;
1844
1845 STACK_PUSHR(stack, voidptr, ast);
1846 STACK_PUSHR(stack, int, EXPAND_RECURSE);
1847 while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
1848 {
1849 tre_ast_node_t *node;
1850 tre_expand_ast_symbol_t symbol;
1851
1852 if (status != REG_OK)
1853 break;
1854
1855 symbol = (tre_expand_ast_symbol_t)tre_stack_pop_int(stack);
1856 node = tre_stack_pop_voidptr(stack);
1857 switch (symbol)
1858 {
1859 case EXPAND_RECURSE:
1860 switch (node->type)
1861 {
1862 case LITERAL:
1863 {
1864 tre_literal_t *lit= node->obj;
1865 if (!IS_SPECIAL(lit) || IS_BACKREF(lit))
1866 {
1867 lit->position += pos_add;
1868 if (lit->position > max_pos)
1869 max_pos = lit->position;
1870 }
1871 break;
1872 }
1873 case UNION:
1874 {
1875 tre_union_t *uni = node->obj;
1876 STACK_PUSHX(stack, voidptr, uni->right);
1877 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1878 STACK_PUSHX(stack, voidptr, uni->left);
1879 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1880 break;
1881 }
1882 case CATENATION:
1883 {
1884 tre_catenation_t *cat = node->obj;
1885 STACK_PUSHX(stack, voidptr, cat->right);
1886 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1887 STACK_PUSHX(stack, voidptr, cat->left);
1888 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1889 break;
1890 }
1891 case ITERATION:
1892 {
1893 tre_iteration_t *iter = node->obj;
1894 STACK_PUSHX(stack, int, pos_add);
1895 STACK_PUSHX(stack, voidptr, node);
1896 STACK_PUSHX(stack, int, EXPAND_AFTER_ITER);
1897 STACK_PUSHX(stack, voidptr, iter->arg);
1898 STACK_PUSHX(stack, int, EXPAND_RECURSE);
1899 /* If we are going to expand this node at EXPAND_AFTER_ITER
1900 then don't increase the `pos' fields of the nodes now, it
1901 will get done when expanding. */
1902 if (iter->min > 1 || iter->max > 1)
1903 pos_add = 0;
1904 iter_depth++;
1905 break;
1906 }
1907 default:
1908 assert(0);
1909 break;
1910 }
1911 break;
1912 case EXPAND_AFTER_ITER:
1913 {
1914 tre_iteration_t *iter = node->obj;
1915 int pos_add_last;
1916 pos_add = tre_stack_pop_int(stack);
1917 pos_add_last = pos_add;
1918 if (iter->min > 1 || iter->max > 1)
1919 {
1920 tre_ast_node_t *seq1 = NULL, *seq2 = NULL;
1921 int j;
1922 int pos_add_save = pos_add;
1923
1924 /* Create a catenated sequence of copies of the node. */
1925 for (j = 0; j < iter->min; j++)
1926 {
1927 tre_ast_node_t *copy;
1928 /* Remove tags from all but the last copy. */
1929 int flags = ((j + 1 < iter->min)
1930 ? COPY_REMOVE_TAGS
1931 : COPY_MAXIMIZE_FIRST_TAG);
1932 pos_add_save = pos_add;
1933 status = tre_copy_ast(mem, stack, iter->arg, flags,
1934 &pos_add, tag_directions, &copy,
1935 &max_pos);
1936 if (status != REG_OK)
1937 return status;
1938 if (seq1 != NULL)
1939 seq1 = tre_ast_new_catenation(mem, seq1, copy);
1940 else
1941 seq1 = copy;
1942 if (seq1 == NULL)
1943 return REG_ESPACE;
1944 }
1945
1946 if (iter->max == -1)
1947 {
1948 /* No upper limit. */
1949 pos_add_save = pos_add;
1950 status = tre_copy_ast(mem, stack, iter->arg, 0,
1951 &pos_add, NULL, &seq2, &max_pos);
1952 if (status != REG_OK)
1953 return status;
1954 seq2 = tre_ast_new_iter(mem, seq2, 0, -1, 0);
1955 if (seq2 == NULL)
1956 return REG_ESPACE;
1957 }
1958 else
1959 {
1960 for (j = iter->min; j < iter->max; j++)
1961 {
1962 tre_ast_node_t *tmp, *copy;
1963 pos_add_save = pos_add;
1964 status = tre_copy_ast(mem, stack, iter->arg, 0,
1965 &pos_add, NULL, &copy, &max_pos);
1966 if (status != REG_OK)
1967 return status;
1968 if (seq2 != NULL)
1969 seq2 = tre_ast_new_catenation(mem, copy, seq2);
1970 else
1971 seq2 = copy;
1972 if (seq2 == NULL)
1973 return REG_ESPACE;
1974 tmp = tre_ast_new_literal(mem, EMPTY, -1, -1);
1975 if (tmp == NULL)
1976 return REG_ESPACE;
1977 seq2 = tre_ast_new_union(mem, tmp, seq2);
1978 if (seq2 == NULL)
1979 return REG_ESPACE;
1980 }
1981 }
1982
1983 pos_add = pos_add_save;
1984 if (seq1 == NULL)
1985 seq1 = seq2;
1986 else if (seq2 != NULL)
1987 seq1 = tre_ast_new_catenation(mem, seq1, seq2);
1988 if (seq1 == NULL)
1989 return REG_ESPACE;
1990 node->obj = seq1->obj;
1991 node->type = seq1->type;
1992 }
1993
1994 iter_depth--;
1995 pos_add_total += pos_add - pos_add_last;
1996 if (iter_depth == 0)
1997 pos_add = pos_add_total;
1998
1999 break;
2000 }
2001 default:
2002 assert(0);
2003 break;
2004 }
2005 }
2006
2007 *position += pos_add_total;
2008
2009 /* `max_pos' should never be larger than `*position' if the above
2010 code works, but just an extra safeguard let's make sure
2011 `*position' is set large enough so enough memory will be
2012 allocated for the transition table. */
2013 if (max_pos > *position)
2014 *position = max_pos;
2015
2016 return status;
2017}
2018
2019static tre_pos_and_tags_t *
2020tre_set_empty(tre_mem_t mem)
2021{
2022 tre_pos_and_tags_t *new_set;
2023
2024 new_set = tre_mem_calloc(mem, sizeof(*new_set));
2025 if (new_set == NULL)
2026 return NULL;
2027
2028 new_set[0].position = -1;
2029 new_set[0].code_min = -1;
2030 new_set[0].code_max = -1;
2031
2032 return new_set;
2033}
2034
2035static tre_pos_and_tags_t *
2036tre_set_one(tre_mem_t mem, int position, int code_min, int code_max,
2037 tre_ctype_t class, tre_ctype_t *neg_classes, int backref)
2038{
2039 tre_pos_and_tags_t *new_set;
2040
2041 new_set = tre_mem_calloc(mem, sizeof(*new_set) * 2);
2042 if (new_set == NULL)
2043 return NULL;
2044
2045 new_set[0].position = position;
2046 new_set[0].code_min = code_min;
2047 new_set[0].code_max = code_max;
2048 new_set[0].class = class;
2049 new_set[0].neg_classes = neg_classes;
2050 new_set[0].backref = backref;
2051 new_set[1].position = -1;
2052 new_set[1].code_min = -1;
2053 new_set[1].code_max = -1;
2054
2055 return new_set;
2056}
2057
2058static tre_pos_and_tags_t *
2059tre_set_union(tre_mem_t mem, tre_pos_and_tags_t *set1, tre_pos_and_tags_t *set2,
2060 int *tags, int assertions)
2061{
2062 int s1, s2, i, j;
2063 tre_pos_and_tags_t *new_set;
2064 int *new_tags;
2065 int num_tags;
2066
2067 for (num_tags = 0; tags != NULL && tags[num_tags] >= 0; num_tags++);
2068 for (s1 = 0; set1[s1].position >= 0; s1++);
2069 for (s2 = 0; set2[s2].position >= 0; s2++);
2070 new_set = tre_mem_calloc(mem, sizeof(*new_set) * (s1 + s2 + 1));
2071 if (!new_set )
2072 return NULL;
2073
2074 for (s1 = 0; set1[s1].position >= 0; s1++)
2075 {
2076 new_set[s1].position = set1[s1].position;
2077 new_set[s1].code_min = set1[s1].code_min;
2078 new_set[s1].code_max = set1[s1].code_max;
2079 new_set[s1].assertions = set1[s1].assertions | assertions;
2080 new_set[s1].class = set1[s1].class;
2081 new_set[s1].neg_classes = set1[s1].neg_classes;
2082 new_set[s1].backref = set1[s1].backref;
2083 if (set1[s1].tags == NULL && tags == NULL)
2084 new_set[s1].tags = NULL;
2085 else
2086 {
2087 for (i = 0; set1[s1].tags != NULL && set1[s1].tags[i] >= 0; i++);
2088 new_tags = tre_mem_alloc(mem, (sizeof(*new_tags)
2089 * (i + num_tags + 1)));
2090 if (new_tags == NULL)
2091 return NULL;
2092 for (j = 0; j < i; j++)
2093 new_tags[j] = set1[s1].tags[j];
2094 for (i = 0; i < num_tags; i++)
2095 new_tags[j + i] = tags[i];
2096 new_tags[j + i] = -1;
2097 new_set[s1].tags = new_tags;
2098 }
2099 }
2100
2101 for (s2 = 0; set2[s2].position >= 0; s2++)
2102 {
2103 new_set[s1 + s2].position = set2[s2].position;
2104 new_set[s1 + s2].code_min = set2[s2].code_min;
2105 new_set[s1 + s2].code_max = set2[s2].code_max;
2106 /* XXX - why not | assertions here as well? */
2107 new_set[s1 + s2].assertions = set2[s2].assertions;
2108 new_set[s1 + s2].class = set2[s2].class;
2109 new_set[s1 + s2].neg_classes = set2[s2].neg_classes;
2110 new_set[s1 + s2].backref = set2[s2].backref;
2111 if (set2[s2].tags == NULL)
2112 new_set[s1 + s2].tags = NULL;
2113 else
2114 {
2115 for (i = 0; set2[s2].tags[i] >= 0; i++);
2116 new_tags = tre_mem_alloc(mem, sizeof(*new_tags) * (i + 1));
2117 if (new_tags == NULL)
2118 return NULL;
2119 for (j = 0; j < i; j++)
2120 new_tags[j] = set2[s2].tags[j];
2121 new_tags[j] = -1;
2122 new_set[s1 + s2].tags = new_tags;
2123 }
2124 }
2125 new_set[s1 + s2].position = -1;
2126 return new_set;
2127}
2128
2129/* Finds the empty path through `node' which is the one that should be
2130 taken according to POSIX.2 rules, and adds the tags on that path to
2131 `tags'. `tags' may be NULL. If `num_tags_seen' is not NULL, it is
2132 set to the number of tags seen on the path. */
2133static reg_errcode_t
2134tre_match_empty(tre_stack_t *stack, tre_ast_node_t *node, int *tags,
2135 int *assertions, int *num_tags_seen)
2136{
2137 tre_literal_t *lit;
2138 tre_union_t *uni;
2139 tre_catenation_t *cat;
2140 tre_iteration_t *iter;
2141 int i;
2142 int bottom = tre_stack_num_objects(stack);
2143 reg_errcode_t status = REG_OK;
2144 if (num_tags_seen)
2145 *num_tags_seen = 0;
2146
2147 status = tre_stack_push_voidptr(stack, node);
2148
2149 /* Walk through the tree recursively. */
2150 while (status == REG_OK && tre_stack_num_objects(stack) > bottom)
2151 {
2152 node = tre_stack_pop_voidptr(stack);
2153
2154 switch (node->type)
2155 {
2156 case LITERAL:
2157 lit = (tre_literal_t *)node->obj;
2158 switch (lit->code_min)
2159 {
2160 case TAG:
2161 if (lit->code_max >= 0)
2162 {
2163 if (tags != NULL)
2164 {
2165 /* Add the tag to `tags'. */
2166 for (i = 0; tags[i] >= 0; i++)
2167 if (tags[i] == lit->code_max)
2168 break;
2169 if (tags[i] < 0)
2170 {
2171 tags[i] = lit->code_max;
2172 tags[i + 1] = -1;
2173 }
2174 }
2175 if (num_tags_seen)
2176 (*num_tags_seen)++;
2177 }
2178 break;
2179 case ASSERTION:
2180 assert(lit->code_max >= 1
2181 || lit->code_max <= ASSERT_LAST);
2182 if (assertions != NULL)
2183 *assertions |= lit->code_max;
2184 break;
2185 case EMPTY:
2186 break;
2187 default:
2188 assert(0);
2189 break;
2190 }
2191 break;
2192
2193 case UNION:
2194 /* Subexpressions starting earlier take priority over ones
2195 starting later, so we prefer the left subexpression over the
2196 right subexpression. */
2197 uni = (tre_union_t *)node->obj;
2198 if (uni->left->nullable)
2199 STACK_PUSHX(stack, voidptr, uni->left)
2200 else if (uni->right->nullable)
2201 STACK_PUSHX(stack, voidptr, uni->right)
2202 else
2203 assert(0);
2204 break;
2205
2206 case CATENATION:
2207 /* The path must go through both children. */
2208 cat = (tre_catenation_t *)node->obj;
2209 assert(cat->left->nullable);
2210 assert(cat->right->nullable);
2211 STACK_PUSHX(stack, voidptr, cat->left);
2212 STACK_PUSHX(stack, voidptr, cat->right);
2213 break;
2214
2215 case ITERATION:
2216 /* A match with an empty string is preferred over no match at
2217 all, so we go through the argument if possible. */
2218 iter = (tre_iteration_t *)node->obj;
2219 if (iter->arg->nullable)
2220 STACK_PUSHX(stack, voidptr, iter->arg);
2221 break;
2222
2223 default:
2224 assert(0);
2225 break;
2226 }
2227 }
2228
2229 return status;
2230}
2231
2232
2233typedef enum {
2234 NFL_RECURSE,
2235 NFL_POST_UNION,
2236 NFL_POST_CATENATION,
2237 NFL_POST_ITERATION
2238} tre_nfl_stack_symbol_t;
2239
2240
2241/* Computes and fills in the fields `nullable', `firstpos', and `lastpos' for
2242 the nodes of the AST `tree'. */
2243static reg_errcode_t
2244tre_compute_nfl(tre_mem_t mem, tre_stack_t *stack, tre_ast_node_t *tree)
2245{
2246 int bottom = tre_stack_num_objects(stack);
2247
2248 STACK_PUSHR(stack, voidptr, tree);
2249 STACK_PUSHR(stack, int, NFL_RECURSE);
2250
2251 while (tre_stack_num_objects(stack) > bottom)
2252 {
2253 tre_nfl_stack_symbol_t symbol;
2254 tre_ast_node_t *node;
2255
2256 symbol = (tre_nfl_stack_symbol_t)tre_stack_pop_int(stack);
2257 node = tre_stack_pop_voidptr(stack);
2258 switch (symbol)
2259 {
2260 case NFL_RECURSE:
2261 switch (node->type)
2262 {
2263 case LITERAL:
2264 {
2265 tre_literal_t *lit = (tre_literal_t *)node->obj;
2266 if (IS_BACKREF(lit))
2267 {
2268 /* Back references: nullable = false, firstpos = {i},
2269 lastpos = {i}. */
2270 node->nullable = 0;
2271 node->firstpos = tre_set_one(mem, lit->position, 0,
2272 TRE_CHAR_MAX, 0, NULL, -1);
2273 if (!node->firstpos)
2274 return REG_ESPACE;
2275 node->lastpos = tre_set_one(mem, lit->position, 0,
2276 TRE_CHAR_MAX, 0, NULL,
2277 (int)lit->code_max);
2278 if (!node->lastpos)
2279 return REG_ESPACE;
2280 }
2281 else if (lit->code_min < 0)
2282 {
2283 /* Tags, empty strings, params, and zero width assertions:
2284 nullable = true, firstpos = {}, and lastpos = {}. */
2285 node->nullable = 1;
2286 node->firstpos = tre_set_empty(mem);
2287 if (!node->firstpos)
2288 return REG_ESPACE;
2289 node->lastpos = tre_set_empty(mem);
2290 if (!node->lastpos)
2291 return REG_ESPACE;
2292 }
2293 else
2294 {
2295 /* Literal at position i: nullable = false, firstpos = {i},
2296 lastpos = {i}. */
2297 node->nullable = 0;
2298 node->firstpos =
2299 tre_set_one(mem, lit->position, (int)lit->code_min,
2300 (int)lit->code_max, 0, NULL, -1);
2301 if (!node->firstpos)
2302 return REG_ESPACE;
2303 node->lastpos = tre_set_one(mem, lit->position,
2304 (int)lit->code_min,
2305 (int)lit->code_max,
2306 lit->class, lit->neg_classes,
2307 -1);
2308 if (!node->lastpos)
2309 return REG_ESPACE;
2310 }
2311 break;
2312 }
2313
2314 case UNION:
2315 /* Compute the attributes for the two subtrees, and after that
2316 for this node. */
2317 STACK_PUSHR(stack, voidptr, node);
2318 STACK_PUSHR(stack, int, NFL_POST_UNION);
2319 STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->right);
2320 STACK_PUSHR(stack, int, NFL_RECURSE);
2321 STACK_PUSHR(stack, voidptr, ((tre_union_t *)node->obj)->left);
2322 STACK_PUSHR(stack, int, NFL_RECURSE);
2323 break;
2324
2325 case CATENATION:
2326 /* Compute the attributes for the two subtrees, and after that
2327 for this node. */
2328 STACK_PUSHR(stack, voidptr, node);
2329 STACK_PUSHR(stack, int, NFL_POST_CATENATION);
2330 STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->right);
2331 STACK_PUSHR(stack, int, NFL_RECURSE);
2332 STACK_PUSHR(stack, voidptr, ((tre_catenation_t *)node->obj)->left);
2333 STACK_PUSHR(stack, int, NFL_RECURSE);
2334 break;
2335
2336 case ITERATION:
2337 /* Compute the attributes for the subtree, and after that for
2338 this node. */
2339 STACK_PUSHR(stack, voidptr, node);
2340 STACK_PUSHR(stack, int, NFL_POST_ITERATION);
2341 STACK_PUSHR(stack, voidptr, ((tre_iteration_t *)node->obj)->arg);
2342 STACK_PUSHR(stack, int, NFL_RECURSE);
2343 break;
2344 }
2345 break; /* end case: NFL_RECURSE */
2346
2347 case NFL_POST_UNION:
2348 {
2349 tre_union_t *uni = (tre_union_t *)node->obj;
2350 node->nullable = uni->left->nullable || uni->right->nullable;
2351 node->firstpos = tre_set_union(mem, uni->left->firstpos,
2352 uni->right->firstpos, NULL, 0);
2353 if (!node->firstpos)
2354 return REG_ESPACE;
2355 node->lastpos = tre_set_union(mem, uni->left->lastpos,
2356 uni->right->lastpos, NULL, 0);
2357 if (!node->lastpos)
2358 return REG_ESPACE;
2359 break;
2360 }
2361
2362 case NFL_POST_ITERATION:
2363 {
2364 tre_iteration_t *iter = (tre_iteration_t *)node->obj;
2365
2366 if (iter->min == 0 || iter->arg->nullable)
2367 node->nullable = 1;
2368 else
2369 node->nullable = 0;
2370 node->firstpos = iter->arg->firstpos;
2371 node->lastpos = iter->arg->lastpos;
2372 break;
2373 }
2374
2375 case NFL_POST_CATENATION:
2376 {
2377 int num_tags, *tags, assertions;
2378 reg_errcode_t status;
2379 tre_catenation_t *cat = node->obj;
2380 node->nullable = cat->left->nullable && cat->right->nullable;
2381
2382 /* Compute firstpos. */
2383 if (cat->left->nullable)
2384 {
2385 /* The left side matches the empty string. Make a first pass
2386 with tre_match_empty() to get the number of tags and
2387 parameters. */
2388 status = tre_match_empty(stack, cat->left,
2389 NULL, NULL, &num_tags);
2390 if (status != REG_OK)
2391 return status;
2392 /* Allocate arrays for the tags and parameters. */
2393 tags = xmalloc(sizeof(*tags) * (num_tags + 1));
2394 if (!tags)
2395 return REG_ESPACE;
2396 tags[0] = -1;
2397 assertions = 0;
2398 /* Second pass with tre_mach_empty() to get the list of
2399 tags and parameters. */
2400 status = tre_match_empty(stack, cat->left, tags,
2401 &assertions, NULL);
2402 if (status != REG_OK)
2403 {
2404 xfree(tags);
2405 return status;
2406 }
2407 node->firstpos =
2408 tre_set_union(mem, cat->right->firstpos, cat->left->firstpos,
2409 tags, assertions);
2410 xfree(tags);
2411 if (!node->firstpos)
2412 return REG_ESPACE;
2413 }
2414 else
2415 {
2416 node->firstpos = cat->left->firstpos;
2417 }
2418
2419 /* Compute lastpos. */
2420 if (cat->right->nullable)
2421 {
2422 /* The right side matches the empty string. Make a first pass
2423 with tre_match_empty() to get the number of tags and
2424 parameters. */
2425 status = tre_match_empty(stack, cat->right,
2426 NULL, NULL, &num_tags);
2427 if (status != REG_OK)
2428 return status;
2429 /* Allocate arrays for the tags and parameters. */
2430 tags = xmalloc(sizeof(int) * (num_tags + 1));
2431 if (!tags)
2432 return REG_ESPACE;
2433 tags[0] = -1;
2434 assertions = 0;
2435 /* Second pass with tre_mach_empty() to get the list of
2436 tags and parameters. */
2437 status = tre_match_empty(stack, cat->right, tags,
2438 &assertions, NULL);
2439 if (status != REG_OK)
2440 {
2441 xfree(tags);
2442 return status;
2443 }
2444 node->lastpos =
2445 tre_set_union(mem, cat->left->lastpos, cat->right->lastpos,
2446 tags, assertions);
2447 xfree(tags);
2448 if (!node->lastpos)
2449 return REG_ESPACE;
2450 }
2451 else
2452 {
2453 node->lastpos = cat->right->lastpos;
2454 }
2455 break;
2456 }
2457
2458 default:
2459 assert(0);
2460 break;
2461 }
2462 }
2463
2464 return REG_OK;
2465}
2466
2467
2468/* Adds a transition from each position in `p1' to each position in `p2'. */
2469static reg_errcode_t
2470tre_make_trans(tre_pos_and_tags_t *p1, tre_pos_and_tags_t *p2,
2471 tre_tnfa_transition_t *transitions,
2472 int *counts, int *offs)
2473{
2474 tre_pos_and_tags_t *orig_p2 = p2;
2475 tre_tnfa_transition_t *trans;
2476 int i, j, k, l, dup, prev_p2_pos;
2477
2478 if (transitions != NULL)
2479 while (p1->position >= 0)
2480 {
2481 p2 = orig_p2;
2482 prev_p2_pos = -1;
2483 while (p2->position >= 0)
2484 {
2485 /* Optimization: if this position was already handled, skip it. */
2486 if (p2->position == prev_p2_pos)
2487 {
2488 p2++;
2489 continue;
2490 }
2491 prev_p2_pos = p2->position;
2492 /* Set `trans' to point to the next unused transition from
2493 position `p1->position'. */
2494 trans = transitions + offs[p1->position];
2495 while (trans->state != NULL)
2496 {
2497#if 0
2498 /* If we find a previous transition from `p1->position' to
2499 `p2->position', it is overwritten. This can happen only
2500 if there are nested loops in the regexp, like in "((a)*)*".
2501 In POSIX.2 repetition using the outer loop is always
2502 preferred over using the inner loop. Therefore the
2503 transition for the inner loop is useless and can be thrown
2504 away. */
2505 /* XXX - The same position is used for all nodes in a bracket
2506 expression, so this optimization cannot be used (it will
2507 break bracket expressions) unless I figure out a way to
2508 detect it here. */
2509 if (trans->state_id == p2->position)
2510 {
2511 break;
2512 }
2513#endif
2514 trans++;
2515 }
2516
2517 if (trans->state == NULL)
2518 (trans + 1)->state = NULL;
2519 /* Use the character ranges, assertions, etc. from `p1' for
2520 the transition from `p1' to `p2'. */
2521 trans->code_min = p1->code_min;
2522 trans->code_max = p1->code_max;
2523 trans->state = transitions + offs[p2->position];
2524 trans->state_id = p2->position;
2525 trans->assertions = p1->assertions | p2->assertions
2526 | (p1->class ? ASSERT_CHAR_CLASS : 0)
2527 | (p1->neg_classes != NULL ? ASSERT_CHAR_CLASS_NEG : 0);
2528 if (p1->backref >= 0)
2529 {
2530 assert((trans->assertions & ASSERT_CHAR_CLASS) == 0);
2531 assert(p2->backref < 0);
2532 trans->u.backref = p1->backref;
2533 trans->assertions |= ASSERT_BACKREF;
2534 }
2535 else
2536 trans->u.class = p1->class;
2537 if (p1->neg_classes != NULL)
2538 {
2539 for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++);
2540 trans->neg_classes =
2541 xmalloc(sizeof(*trans->neg_classes) * (i + 1));
2542 if (trans->neg_classes == NULL)
2543 return REG_ESPACE;
2544 for (i = 0; p1->neg_classes[i] != (tre_ctype_t)0; i++)
2545 trans->neg_classes[i] = p1->neg_classes[i];
2546 trans->neg_classes[i] = (tre_ctype_t)0;
2547 }
2548 else
2549 trans->neg_classes = NULL;
2550
2551 /* Find out how many tags this transition has. */
2552 i = 0;
2553 if (p1->tags != NULL)
2554 while(p1->tags[i] >= 0)
2555 i++;
2556 j = 0;
2557 if (p2->tags != NULL)
2558 while(p2->tags[j] >= 0)
2559 j++;
2560
2561 /* If we are overwriting a transition, free the old tag array. */
2562 if (trans->tags != NULL)
2563 xfree(trans->tags);
2564 trans->tags = NULL;
2565
2566 /* If there were any tags, allocate an array and fill it. */
2567 if (i + j > 0)
2568 {
2569 trans->tags = xmalloc(sizeof(*trans->tags) * (i + j + 1));
2570 if (!trans->tags)
2571 return REG_ESPACE;
2572 i = 0;
2573 if (p1->tags != NULL)
2574 while(p1->tags[i] >= 0)
2575 {
2576 trans->tags[i] = p1->tags[i];
2577 i++;
2578 }
2579 l = i;
2580 j = 0;
2581 if (p2->tags != NULL)
2582 while (p2->tags[j] >= 0)
2583 {
2584 /* Don't add duplicates. */
2585 dup = 0;
2586 for (k = 0; k < i; k++)
2587 if (trans->tags[k] == p2->tags[j])
2588 {
2589 dup = 1;
2590 break;
2591 }
2592 if (!dup)
2593 trans->tags[l++] = p2->tags[j];
2594 j++;
2595 }
2596 trans->tags[l] = -1;
2597 }
2598
2599 p2++;
2600 }
2601 p1++;
2602 }
2603 else
2604 /* Compute a maximum limit for the number of transitions leaving
2605 from each state. */
2606 while (p1->position >= 0)
2607 {
2608 p2 = orig_p2;
2609 while (p2->position >= 0)
2610 {
2611 counts[p1->position]++;
2612 p2++;
2613 }
2614 p1++;
2615 }
2616 return REG_OK;
2617}
2618
2619/* Converts the syntax tree to a TNFA. All the transitions in the TNFA are
2620 labelled with one character range (there are no transitions on empty
2621 strings). The TNFA takes O(n^2) space in the worst case, `n' is size of
2622 the regexp. */
2623static reg_errcode_t
2624tre_ast_to_tnfa(tre_ast_node_t *node, tre_tnfa_transition_t *transitions,
2625 int *counts, int *offs)
2626{
2627 tre_union_t *uni;
2628 tre_catenation_t *cat;
2629 tre_iteration_t *iter;
2630 reg_errcode_t errcode = REG_OK;
2631
2632 /* XXX - recurse using a stack!. */
2633 switch (node->type)
2634 {
2635 case LITERAL:
2636 break;
2637 case UNION:
2638 uni = (tre_union_t *)node->obj;
2639 errcode = tre_ast_to_tnfa(uni->left, transitions, counts, offs);
2640 if (errcode != REG_OK)
2641 return errcode;
2642 errcode = tre_ast_to_tnfa(uni->right, transitions, counts, offs);
2643 break;
2644
2645 case CATENATION:
2646 cat = (tre_catenation_t *)node->obj;
2647 /* Add a transition from each position in cat->left->lastpos
2648 to each position in cat->right->firstpos. */
2649 errcode = tre_make_trans(cat->left->lastpos, cat->right->firstpos,
2650 transitions, counts, offs);
2651 if (errcode != REG_OK)
2652 return errcode;
2653 errcode = tre_ast_to_tnfa(cat->left, transitions, counts, offs);
2654 if (errcode != REG_OK)
2655 return errcode;
2656 errcode = tre_ast_to_tnfa(cat->right, transitions, counts, offs);
2657 break;
2658
2659 case ITERATION:
2660 iter = (tre_iteration_t *)node->obj;
2661 assert(iter->max == -1 || iter->max == 1);
2662
2663 if (iter->max == -1)
2664 {
2665 assert(iter->min == 0 || iter->min == 1);
2666 /* Add a transition from each last position in the iterated
2667 expression to each first position. */
2668 errcode = tre_make_trans(iter->arg->lastpos, iter->arg->firstpos,
2669 transitions, counts, offs);
2670 if (errcode != REG_OK)
2671 return errcode;
2672 }
2673 errcode = tre_ast_to_tnfa(iter->arg, transitions, counts, offs);
2674 break;
2675 }
2676 return errcode;
2677}
2678
2679
2680#define ERROR_EXIT(err) \
2681 do \
2682 { \
2683 errcode = err; \
2684 if (/*CONSTCOND*/1) \
2685 goto error_exit; \
2686 } \
2687 while (/*CONSTCOND*/0)
2688
2689
2690int
2691regcomp(regex_t *restrict preg, const char *restrict regex, int cflags)
2692{
2693 tre_stack_t *stack;
2694 tre_ast_node_t *tree, *tmp_ast_l, *tmp_ast_r;
2695 tre_pos_and_tags_t *p;
2696 int *counts = NULL, *offs = NULL;
2697 int i, add = 0;
2698 tre_tnfa_transition_t *transitions, *initial;
2699 tre_tnfa_t *tnfa = NULL;
2700 tre_submatch_data_t *submatch_data;
2701 tre_tag_direction_t *tag_directions = NULL;
2702 reg_errcode_t errcode;
2703 tre_mem_t mem;
2704
2705 /* Parse context. */
2706 tre_parse_ctx_t parse_ctx;
2707
2708 /* Allocate a stack used throughout the compilation process for various
2709 purposes. */
2710 stack = tre_stack_new(512, 1024000, 128);
2711 if (!stack)
2712 return REG_ESPACE;
2713 /* Allocate a fast memory allocator. */
2714 mem = tre_mem_new();
2715 if (!mem)
2716 {
2717 tre_stack_destroy(stack);
2718 return REG_ESPACE;
2719 }
2720
2721 /* Parse the regexp. */
2722 memset(&parse_ctx, 0, sizeof(parse_ctx));
2723 parse_ctx.mem = mem;
2724 parse_ctx.stack = stack;
2725 parse_ctx.start = regex;
2726 parse_ctx.cflags = cflags;
2727 parse_ctx.max_backref = -1;
2728 errcode = tre_parse(&parse_ctx);
2729 if (errcode != REG_OK)
2730 ERROR_EXIT(errcode);
2731 preg->re_nsub = parse_ctx.submatch_id - 1;
2732 tree = parse_ctx.n;
2733
2734#ifdef TRE_DEBUG
2735 tre_ast_print(tree);
2736#endif /* TRE_DEBUG */
2737
2738 /* Referring to nonexistent subexpressions is illegal. */
2739 if (parse_ctx.max_backref > (int)preg->re_nsub)
2740 ERROR_EXIT(REG_ESUBREG);
2741
2742 /* Allocate the TNFA struct. */
2743 tnfa = xcalloc(1, sizeof(tre_tnfa_t));
2744 if (tnfa == NULL)
2745 ERROR_EXIT(REG_ESPACE);
2746 tnfa->have_backrefs = parse_ctx.max_backref >= 0;
2747 tnfa->have_approx = 0;
2748 tnfa->num_submatches = parse_ctx.submatch_id;
2749
2750 /* Set up tags for submatch addressing. If REG_NOSUB is set and the
2751 regexp does not have back references, this can be skipped. */
2752 if (tnfa->have_backrefs || !(cflags & REG_NOSUB))
2753 {
2754
2755 /* Figure out how many tags we will need. */
2756 errcode = tre_add_tags(NULL, stack, tree, tnfa);
2757 if (errcode != REG_OK)
2758 ERROR_EXIT(errcode);
2759
2760 if (tnfa->num_tags > 0)
2761 {
2762 tag_directions = xmalloc(sizeof(*tag_directions)
2763 * (tnfa->num_tags + 1));
2764 if (tag_directions == NULL)
2765 ERROR_EXIT(REG_ESPACE);
2766 tnfa->tag_directions = tag_directions;
2767 memset(tag_directions, -1,
2768 sizeof(*tag_directions) * (tnfa->num_tags + 1));
2769 }
2770 tnfa->minimal_tags = xcalloc((unsigned)tnfa->num_tags * 2 + 1,
2771 sizeof(*tnfa->minimal_tags));
2772 if (tnfa->minimal_tags == NULL)
2773 ERROR_EXIT(REG_ESPACE);
2774
2775 submatch_data = xcalloc((unsigned)parse_ctx.submatch_id,
2776 sizeof(*submatch_data));
2777 if (submatch_data == NULL)
2778 ERROR_EXIT(REG_ESPACE);
2779 tnfa->submatch_data = submatch_data;
2780
2781 errcode = tre_add_tags(mem, stack, tree, tnfa);
2782 if (errcode != REG_OK)
2783 ERROR_EXIT(errcode);
2784
2785 }
2786
2787 /* Expand iteration nodes. */
2788 errcode = tre_expand_ast(mem, stack, tree, &parse_ctx.position,
2789 tag_directions);
2790 if (errcode != REG_OK)
2791 ERROR_EXIT(errcode);
2792
2793 /* Add a dummy node for the final state.
2794 XXX - For certain patterns this dummy node can be optimized away,
2795 for example "a*" or "ab*". Figure out a simple way to detect
2796 this possibility. */
2797 tmp_ast_l = tree;
2798 tmp_ast_r = tre_ast_new_literal(mem, 0, 0, parse_ctx.position++);
2799 if (tmp_ast_r == NULL)
2800 ERROR_EXIT(REG_ESPACE);
2801
2802 tree = tre_ast_new_catenation(mem, tmp_ast_l, tmp_ast_r);
2803 if (tree == NULL)
2804 ERROR_EXIT(REG_ESPACE);
2805
2806 errcode = tre_compute_nfl(mem, stack, tree);
2807 if (errcode != REG_OK)
2808 ERROR_EXIT(errcode);
2809
2810 counts = xmalloc(sizeof(int) * parse_ctx.position);
2811 if (counts == NULL)
2812 ERROR_EXIT(REG_ESPACE);
2813
2814 offs = xmalloc(sizeof(int) * parse_ctx.position);
2815 if (offs == NULL)
2816 ERROR_EXIT(REG_ESPACE);
2817
2818 for (i = 0; i < parse_ctx.position; i++)
2819 counts[i] = 0;
2820 tre_ast_to_tnfa(tree, NULL, counts, NULL);
2821
2822 add = 0;
2823 for (i = 0; i < parse_ctx.position; i++)
2824 {
2825 offs[i] = add;
2826 add += counts[i] + 1;
2827 counts[i] = 0;
2828 }
2829 transitions = xcalloc((unsigned)add + 1, sizeof(*transitions));
2830 if (transitions == NULL)
2831 ERROR_EXIT(REG_ESPACE);
2832 tnfa->transitions = transitions;
2833 tnfa->num_transitions = add;
2834
2835 errcode = tre_ast_to_tnfa(tree, transitions, counts, offs);
2836 if (errcode != REG_OK)
2837 ERROR_EXIT(errcode);
2838
2839 tnfa->firstpos_chars = NULL;
2840
2841 p = tree->firstpos;
2842 i = 0;
2843 while (p->position >= 0)
2844 {
2845 i++;
2846 p++;
2847 }
2848
2849 initial = xcalloc((unsigned)i + 1, sizeof(tre_tnfa_transition_t));
2850 if (initial == NULL)
2851 ERROR_EXIT(REG_ESPACE);
2852 tnfa->initial = initial;
2853
2854 i = 0;
2855 for (p = tree->firstpos; p->position >= 0; p++)
2856 {
2857 initial[i].state = transitions + offs[p->position];
2858 initial[i].state_id = p->position;
2859 initial[i].tags = NULL;
2860 /* Copy the arrays p->tags, and p->params, they are allocated
2861 from a tre_mem object. */
2862 if (p->tags)
2863 {
2864 int j;
2865 for (j = 0; p->tags[j] >= 0; j++);
2866 initial[i].tags = xmalloc(sizeof(*p->tags) * (j + 1));
2867 if (!initial[i].tags)
2868 ERROR_EXIT(REG_ESPACE);
2869 memcpy(initial[i].tags, p->tags, sizeof(*p->tags) * (j + 1));
2870 }
2871 initial[i].assertions = p->assertions;
2872 i++;
2873 }
2874 initial[i].state = NULL;
2875
2876 tnfa->num_transitions = add;
2877 tnfa->final = transitions + offs[tree->lastpos[0].position];
2878 tnfa->num_states = parse_ctx.position;
2879 tnfa->cflags = cflags;
2880
2881 tre_mem_destroy(mem);
2882 tre_stack_destroy(stack);
2883 xfree(counts);
2884 xfree(offs);
2885
2886 preg->TRE_REGEX_T_FIELD = (void *)tnfa;
2887 return REG_OK;
2888
2889 error_exit:
2890 /* Free everything that was allocated and return the error code. */
2891 tre_mem_destroy(mem);
2892 if (stack != NULL)
2893 tre_stack_destroy(stack);
2894 if (counts != NULL)
2895 xfree(counts);
2896 if (offs != NULL)
2897 xfree(offs);
2898 preg->TRE_REGEX_T_FIELD = (void *)tnfa;
2899 regfree(preg);
2900 return errcode;
2901}
2902
2903
2904
2905
2906void
2907regfree(regex_t *preg)
2908{
2909 tre_tnfa_t *tnfa;
2910 unsigned int i;
2911 tre_tnfa_transition_t *trans;
2912
2913 tnfa = (void *)preg->TRE_REGEX_T_FIELD;
2914 if (!tnfa)
2915 return;
2916
2917 for (i = 0; i < tnfa->num_transitions; i++)
2918 if (tnfa->transitions[i].state)
2919 {
2920 if (tnfa->transitions[i].tags)
2921 xfree(tnfa->transitions[i].tags);
2922 if (tnfa->transitions[i].neg_classes)
2923 xfree(tnfa->transitions[i].neg_classes);
2924 }
2925 if (tnfa->transitions)
2926 xfree(tnfa->transitions);
2927
2928 if (tnfa->initial)
2929 {
2930 for (trans = tnfa->initial; trans->state; trans++)
2931 {
2932 if (trans->tags)
2933 xfree(trans->tags);
2934 }
2935 xfree(tnfa->initial);
2936 }
2937
2938 if (tnfa->submatch_data)
2939 {
2940 for (i = 0; i < tnfa->num_submatches; i++)
2941 if (tnfa->submatch_data[i].parents)
2942 xfree(tnfa->submatch_data[i].parents);
2943 xfree(tnfa->submatch_data);
2944 }
2945
2946 if (tnfa->tag_directions)
2947 xfree(tnfa->tag_directions);
2948 if (tnfa->firstpos_chars)
2949 xfree(tnfa->firstpos_chars);
2950 if (tnfa->minimal_tags)
2951 xfree(tnfa->minimal_tags);
2952 xfree(tnfa);
2953}
libc/musl/src/regex/regerror.c created+37
......@@ -0,0 +1,37 @@
1#include <string.h>
2#include <regex.h>
3#include <stdio.h>
4#include "locale_impl.h"
5
6/* Error message strings for error codes listed in `regex.h'. This list
7 needs to be in sync with the codes listed there, naturally. */
8
9/* Converted to single string by Rich Felker to remove the need for
10 * data relocations at runtime, 27 Feb 2006. */
11
12static const char messages[] = {
13 "No error\0"
14 "No match\0"
15 "Invalid regexp\0"
16 "Unknown collating element\0"
17 "Unknown character class name\0"
18 "Trailing backslash\0"
19 "Invalid back reference\0"
20 "Missing ']'\0"
21 "Missing ')'\0"
22 "Missing '}'\0"
23 "Invalid contents of {}\0"
24 "Invalid character range\0"
25 "Out of memory\0"
26 "Repetition not preceded by valid expression\0"
27 "\0Unknown error"
28};
29
30size_t regerror(int e, const regex_t *restrict preg, char *restrict buf, size_t size)
31{
32 const char *s;
33 for (s=messages; e && *s; e--, s+=strlen(s)+1);
34 if (!*s) s++;
35 s = LCTRANS_CUR(s);
36 return 1+snprintf(buf, size, "%s", s);
37}
libc/musl/src/regex/regexec.c created+1028
......@@ -0,0 +1,1028 @@
1/*
2 regexec.c - TRE POSIX compatible matching functions (and more).
3
4 Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
19 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30*/
31
32#include <stdlib.h>
33#include <string.h>
34#include <wchar.h>
35#include <wctype.h>
36#include <limits.h>
37#include <stdint.h>
38
39#include <regex.h>
40
41#include "tre.h"
42
43#include <assert.h>
44
45static void
46tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
47 const tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo);
48
49/***********************************************************************
50 from tre-match-utils.h
51***********************************************************************/
52
53#define GET_NEXT_WCHAR() do { \
54 prev_c = next_c; pos += pos_add_next; \
55 if ((pos_add_next = mbtowc(&next_c, str_byte, MB_LEN_MAX)) <= 0) { \
56 if (pos_add_next < 0) { ret = REG_NOMATCH; goto error_exit; } \
57 else pos_add_next++; \
58 } \
59 str_byte += pos_add_next; \
60 } while (0)
61
62#define IS_WORD_CHAR(c) ((c) == L'_' || tre_isalnum(c))
63
64#define CHECK_ASSERTIONS(assertions) \
65 (((assertions & ASSERT_AT_BOL) \
66 && (pos > 0 || reg_notbol) \
67 && (prev_c != L'\n' || !reg_newline)) \
68 || ((assertions & ASSERT_AT_EOL) \
69 && (next_c != L'\0' || reg_noteol) \
70 && (next_c != L'\n' || !reg_newline)) \
71 || ((assertions & ASSERT_AT_BOW) \
72 && (IS_WORD_CHAR(prev_c) || !IS_WORD_CHAR(next_c))) \
73 || ((assertions & ASSERT_AT_EOW) \
74 && (!IS_WORD_CHAR(prev_c) || IS_WORD_CHAR(next_c))) \
75 || ((assertions & ASSERT_AT_WB) \
76 && (pos != 0 && next_c != L'\0' \
77 && IS_WORD_CHAR(prev_c) == IS_WORD_CHAR(next_c))) \
78 || ((assertions & ASSERT_AT_WB_NEG) \
79 && (pos == 0 || next_c == L'\0' \
80 || IS_WORD_CHAR(prev_c) != IS_WORD_CHAR(next_c))))
81
82#define CHECK_CHAR_CLASSES(trans_i, tnfa, eflags) \
83 (((trans_i->assertions & ASSERT_CHAR_CLASS) \
84 && !(tnfa->cflags & REG_ICASE) \
85 && !tre_isctype((tre_cint_t)prev_c, trans_i->u.class)) \
86 || ((trans_i->assertions & ASSERT_CHAR_CLASS) \
87 && (tnfa->cflags & REG_ICASE) \
88 && !tre_isctype(tre_tolower((tre_cint_t)prev_c),trans_i->u.class) \
89 && !tre_isctype(tre_toupper((tre_cint_t)prev_c),trans_i->u.class)) \
90 || ((trans_i->assertions & ASSERT_CHAR_CLASS_NEG) \
91 && tre_neg_char_classes_match(trans_i->neg_classes,(tre_cint_t)prev_c,\
92 tnfa->cflags & REG_ICASE)))
93
94
95
96
97/* Returns 1 if `t1' wins `t2', 0 otherwise. */
98static int
99tre_tag_order(int num_tags, tre_tag_direction_t *tag_directions,
100 regoff_t *t1, regoff_t *t2)
101{
102 int i;
103 for (i = 0; i < num_tags; i++)
104 {
105 if (tag_directions[i] == TRE_TAG_MINIMIZE)
106 {
107 if (t1[i] < t2[i])
108 return 1;
109 if (t1[i] > t2[i])
110 return 0;
111 }
112 else
113 {
114 if (t1[i] > t2[i])
115 return 1;
116 if (t1[i] < t2[i])
117 return 0;
118 }
119 }
120 /* assert(0);*/
121 return 0;
122}
123
124static int
125tre_neg_char_classes_match(tre_ctype_t *classes, tre_cint_t wc, int icase)
126{
127 while (*classes != (tre_ctype_t)0)
128 if ((!icase && tre_isctype(wc, *classes))
129 || (icase && (tre_isctype(tre_toupper(wc), *classes)
130 || tre_isctype(tre_tolower(wc), *classes))))
131 return 1; /* Match. */
132 else
133 classes++;
134 return 0; /* No match. */
135}
136
137
138/***********************************************************************
139 from tre-match-parallel.c
140***********************************************************************/
141
142/*
143 This algorithm searches for matches basically by reading characters
144 in the searched string one by one, starting at the beginning. All
145 matching paths in the TNFA are traversed in parallel. When two or
146 more paths reach the same state, exactly one is chosen according to
147 tag ordering rules; if returning submatches is not required it does
148 not matter which path is chosen.
149
150 The worst case time required for finding the leftmost and longest
151 match, or determining that there is no match, is always linearly
152 dependent on the length of the text being searched.
153
154 This algorithm cannot handle TNFAs with back referencing nodes.
155 See `tre-match-backtrack.c'.
156*/
157
158typedef struct {
159 tre_tnfa_transition_t *state;
160 regoff_t *tags;
161} tre_tnfa_reach_t;
162
163typedef struct {
164 regoff_t pos;
165 regoff_t **tags;
166} tre_reach_pos_t;
167
168
169static reg_errcode_t
170tre_tnfa_run_parallel(const tre_tnfa_t *tnfa, const void *string,
171 regoff_t *match_tags, int eflags,
172 regoff_t *match_end_ofs)
173{
174 /* State variables required by GET_NEXT_WCHAR. */
175 tre_char_t prev_c = 0, next_c = 0;
176 const char *str_byte = string;
177 regoff_t pos = -1;
178 regoff_t pos_add_next = 1;
179#ifdef TRE_MBSTATE
180 mbstate_t mbstate;
181#endif /* TRE_MBSTATE */
182 int reg_notbol = eflags & REG_NOTBOL;
183 int reg_noteol = eflags & REG_NOTEOL;
184 int reg_newline = tnfa->cflags & REG_NEWLINE;
185 reg_errcode_t ret;
186
187 char *buf;
188 tre_tnfa_transition_t *trans_i;
189 tre_tnfa_reach_t *reach, *reach_next, *reach_i, *reach_next_i;
190 tre_reach_pos_t *reach_pos;
191 int *tag_i;
192 int num_tags, i;
193
194 regoff_t match_eo = -1; /* end offset of match (-1 if no match found yet) */
195 int new_match = 0;
196 regoff_t *tmp_tags = NULL;
197 regoff_t *tmp_iptr;
198
199#ifdef TRE_MBSTATE
200 memset(&mbstate, '\0', sizeof(mbstate));
201#endif /* TRE_MBSTATE */
202
203 if (!match_tags)
204 num_tags = 0;
205 else
206 num_tags = tnfa->num_tags;
207
208 /* Allocate memory for temporary data required for matching. This needs to
209 be done for every matching operation to be thread safe. This allocates
210 everything in a single large block with calloc(). */
211 {
212 size_t tbytes, rbytes, pbytes, xbytes, total_bytes;
213 char *tmp_buf;
214
215 /* Ensure that tbytes and xbytes*num_states cannot overflow, and that
216 * they don't contribute more than 1/8 of SIZE_MAX to total_bytes. */
217 if (num_tags > SIZE_MAX/(8 * sizeof(regoff_t) * tnfa->num_states))
218 return REG_ESPACE;
219
220 /* Likewise check rbytes. */
221 if (tnfa->num_states+1 > SIZE_MAX/(8 * sizeof(*reach_next)))
222 return REG_ESPACE;
223
224 /* Likewise check pbytes. */
225 if (tnfa->num_states > SIZE_MAX/(8 * sizeof(*reach_pos)))
226 return REG_ESPACE;
227
228 /* Compute the length of the block we need. */
229 tbytes = sizeof(*tmp_tags) * num_tags;
230 rbytes = sizeof(*reach_next) * (tnfa->num_states + 1);
231 pbytes = sizeof(*reach_pos) * tnfa->num_states;
232 xbytes = sizeof(regoff_t) * num_tags;
233 total_bytes =
234 (sizeof(long) - 1) * 4 /* for alignment paddings */
235 + (rbytes + xbytes * tnfa->num_states) * 2 + tbytes + pbytes;
236
237 /* Allocate the memory. */
238 buf = calloc(total_bytes, 1);
239 if (buf == NULL)
240 return REG_ESPACE;
241
242 /* Get the various pointers within tmp_buf (properly aligned). */
243 tmp_tags = (void *)buf;
244 tmp_buf = buf + tbytes;
245 tmp_buf += ALIGN(tmp_buf, long);
246 reach_next = (void *)tmp_buf;
247 tmp_buf += rbytes;
248 tmp_buf += ALIGN(tmp_buf, long);
249 reach = (void *)tmp_buf;
250 tmp_buf += rbytes;
251 tmp_buf += ALIGN(tmp_buf, long);
252 reach_pos = (void *)tmp_buf;
253 tmp_buf += pbytes;
254 tmp_buf += ALIGN(tmp_buf, long);
255 for (i = 0; i < tnfa->num_states; i++)
256 {
257 reach[i].tags = (void *)tmp_buf;
258 tmp_buf += xbytes;
259 reach_next[i].tags = (void *)tmp_buf;
260 tmp_buf += xbytes;
261 }
262 }
263
264 for (i = 0; i < tnfa->num_states; i++)
265 reach_pos[i].pos = -1;
266
267 GET_NEXT_WCHAR();
268 pos = 0;
269
270 reach_next_i = reach_next;
271 while (1)
272 {
273 /* If no match found yet, add the initial states to `reach_next'. */
274 if (match_eo < 0)
275 {
276 trans_i = tnfa->initial;
277 while (trans_i->state != NULL)
278 {
279 if (reach_pos[trans_i->state_id].pos < pos)
280 {
281 if (trans_i->assertions
282 && CHECK_ASSERTIONS(trans_i->assertions))
283 {
284 trans_i++;
285 continue;
286 }
287
288 reach_next_i->state = trans_i->state;
289 for (i = 0; i < num_tags; i++)
290 reach_next_i->tags[i] = -1;
291 tag_i = trans_i->tags;
292 if (tag_i)
293 while (*tag_i >= 0)
294 {
295 if (*tag_i < num_tags)
296 reach_next_i->tags[*tag_i] = pos;
297 tag_i++;
298 }
299 if (reach_next_i->state == tnfa->final)
300 {
301 match_eo = pos;
302 new_match = 1;
303 for (i = 0; i < num_tags; i++)
304 match_tags[i] = reach_next_i->tags[i];
305 }
306 reach_pos[trans_i->state_id].pos = pos;
307 reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
308 reach_next_i++;
309 }
310 trans_i++;
311 }
312 reach_next_i->state = NULL;
313 }
314 else
315 {
316 if (num_tags == 0 || reach_next_i == reach_next)
317 /* We have found a match. */
318 break;
319 }
320
321 /* Check for end of string. */
322 if (!next_c) break;
323
324 GET_NEXT_WCHAR();
325
326 /* Swap `reach' and `reach_next'. */
327 reach_i = reach;
328 reach = reach_next;
329 reach_next = reach_i;
330
331 /* For each state in `reach', weed out states that don't fulfill the
332 minimal matching conditions. */
333 if (tnfa->num_minimals && new_match)
334 {
335 new_match = 0;
336 reach_next_i = reach_next;
337 for (reach_i = reach; reach_i->state; reach_i++)
338 {
339 int skip = 0;
340 for (i = 0; tnfa->minimal_tags[i] >= 0; i += 2)
341 {
342 int end = tnfa->minimal_tags[i];
343 int start = tnfa->minimal_tags[i + 1];
344 if (end >= num_tags)
345 {
346 skip = 1;
347 break;
348 }
349 else if (reach_i->tags[start] == match_tags[start]
350 && reach_i->tags[end] < match_tags[end])
351 {
352 skip = 1;
353 break;
354 }
355 }
356 if (!skip)
357 {
358 reach_next_i->state = reach_i->state;
359 tmp_iptr = reach_next_i->tags;
360 reach_next_i->tags = reach_i->tags;
361 reach_i->tags = tmp_iptr;
362 reach_next_i++;
363 }
364 }
365 reach_next_i->state = NULL;
366
367 /* Swap `reach' and `reach_next'. */
368 reach_i = reach;
369 reach = reach_next;
370 reach_next = reach_i;
371 }
372
373 /* For each state in `reach' see if there is a transition leaving with
374 the current input symbol to a state not yet in `reach_next', and
375 add the destination states to `reach_next'. */
376 reach_next_i = reach_next;
377 for (reach_i = reach; reach_i->state; reach_i++)
378 {
379 for (trans_i = reach_i->state; trans_i->state; trans_i++)
380 {
381 /* Does this transition match the input symbol? */
382 if (trans_i->code_min <= (tre_cint_t)prev_c &&
383 trans_i->code_max >= (tre_cint_t)prev_c)
384 {
385 if (trans_i->assertions
386 && (CHECK_ASSERTIONS(trans_i->assertions)
387 || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))
388 {
389 continue;
390 }
391
392 /* Compute the tags after this transition. */
393 for (i = 0; i < num_tags; i++)
394 tmp_tags[i] = reach_i->tags[i];
395 tag_i = trans_i->tags;
396 if (tag_i != NULL)
397 while (*tag_i >= 0)
398 {
399 if (*tag_i < num_tags)
400 tmp_tags[*tag_i] = pos;
401 tag_i++;
402 }
403
404 if (reach_pos[trans_i->state_id].pos < pos)
405 {
406 /* Found an unvisited node. */
407 reach_next_i->state = trans_i->state;
408 tmp_iptr = reach_next_i->tags;
409 reach_next_i->tags = tmp_tags;
410 tmp_tags = tmp_iptr;
411 reach_pos[trans_i->state_id].pos = pos;
412 reach_pos[trans_i->state_id].tags = &reach_next_i->tags;
413
414 if (reach_next_i->state == tnfa->final
415 && (match_eo == -1
416 || (num_tags > 0
417 && reach_next_i->tags[0] <= match_tags[0])))
418 {
419 match_eo = pos;
420 new_match = 1;
421 for (i = 0; i < num_tags; i++)
422 match_tags[i] = reach_next_i->tags[i];
423 }
424 reach_next_i++;
425
426 }
427 else
428 {
429 assert(reach_pos[trans_i->state_id].pos == pos);
430 /* Another path has also reached this state. We choose
431 the winner by examining the tag values for both
432 paths. */
433 if (tre_tag_order(num_tags, tnfa->tag_directions,
434 tmp_tags,
435 *reach_pos[trans_i->state_id].tags))
436 {
437 /* The new path wins. */
438 tmp_iptr = *reach_pos[trans_i->state_id].tags;
439 *reach_pos[trans_i->state_id].tags = tmp_tags;
440 if (trans_i->state == tnfa->final)
441 {
442 match_eo = pos;
443 new_match = 1;
444 for (i = 0; i < num_tags; i++)
445 match_tags[i] = tmp_tags[i];
446 }
447 tmp_tags = tmp_iptr;
448 }
449 }
450 }
451 }
452 }
453 reach_next_i->state = NULL;
454 }
455
456 *match_end_ofs = match_eo;
457 ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
458error_exit:
459 xfree(buf);
460 return ret;
461}
462
463
464
465/***********************************************************************
466 from tre-match-backtrack.c
467***********************************************************************/
468
469/*
470 This matcher is for regexps that use back referencing. Regexp matching
471 with back referencing is an NP-complete problem on the number of back
472 references. The easiest way to match them is to use a backtracking
473 routine which basically goes through all possible paths in the TNFA
474 and chooses the one which results in the best (leftmost and longest)
475 match. This can be spectacularly expensive and may run out of stack
476 space, but there really is no better known generic algorithm. Quoting
477 Henry Spencer from comp.compilers:
478 <URL: http://compilers.iecc.com/comparch/article/93-03-102>
479
480 POSIX.2 REs require longest match, which is really exciting to
481 implement since the obsolete ("basic") variant also includes
482 \<digit>. I haven't found a better way of tackling this than doing
483 a preliminary match using a DFA (or simulation) on a modified RE
484 that just replicates subREs for \<digit>, and then doing a
485 backtracking match to determine whether the subRE matches were
486 right. This can be rather slow, but I console myself with the
487 thought that people who use \<digit> deserve very slow execution.
488 (Pun unintentional but very appropriate.)
489
490*/
491
492typedef struct {
493 regoff_t pos;
494 const char *str_byte;
495 tre_tnfa_transition_t *state;
496 int state_id;
497 int next_c;
498 regoff_t *tags;
499#ifdef TRE_MBSTATE
500 mbstate_t mbstate;
501#endif /* TRE_MBSTATE */
502} tre_backtrack_item_t;
503
504typedef struct tre_backtrack_struct {
505 tre_backtrack_item_t item;
506 struct tre_backtrack_struct *prev;
507 struct tre_backtrack_struct *next;
508} *tre_backtrack_t;
509
510#ifdef TRE_MBSTATE
511#define BT_STACK_MBSTATE_IN stack->item.mbstate = (mbstate)
512#define BT_STACK_MBSTATE_OUT (mbstate) = stack->item.mbstate
513#else /* !TRE_MBSTATE */
514#define BT_STACK_MBSTATE_IN
515#define BT_STACK_MBSTATE_OUT
516#endif /* !TRE_MBSTATE */
517
518#define tre_bt_mem_new tre_mem_new
519#define tre_bt_mem_alloc tre_mem_alloc
520#define tre_bt_mem_destroy tre_mem_destroy
521
522
523#define BT_STACK_PUSH(_pos, _str_byte, _str_wide, _state, _state_id, _next_c, _tags, _mbstate) \
524 do \
525 { \
526 int i; \
527 if (!stack->next) \
528 { \
529 tre_backtrack_t s; \
530 s = tre_bt_mem_alloc(mem, sizeof(*s)); \
531 if (!s) \
532 { \
533 tre_bt_mem_destroy(mem); \
534 if (tags) \
535 xfree(tags); \
536 if (pmatch) \
537 xfree(pmatch); \
538 if (states_seen) \
539 xfree(states_seen); \
540 return REG_ESPACE; \
541 } \
542 s->prev = stack; \
543 s->next = NULL; \
544 s->item.tags = tre_bt_mem_alloc(mem, \
545 sizeof(*tags) * tnfa->num_tags); \
546 if (!s->item.tags) \
547 { \
548 tre_bt_mem_destroy(mem); \
549 if (tags) \
550 xfree(tags); \
551 if (pmatch) \
552 xfree(pmatch); \
553 if (states_seen) \
554 xfree(states_seen); \
555 return REG_ESPACE; \
556 } \
557 stack->next = s; \
558 stack = s; \
559 } \
560 else \
561 stack = stack->next; \
562 stack->item.pos = (_pos); \
563 stack->item.str_byte = (_str_byte); \
564 stack->item.state = (_state); \
565 stack->item.state_id = (_state_id); \
566 stack->item.next_c = (_next_c); \
567 for (i = 0; i < tnfa->num_tags; i++) \
568 stack->item.tags[i] = (_tags)[i]; \
569 BT_STACK_MBSTATE_IN; \
570 } \
571 while (0)
572
573#define BT_STACK_POP() \
574 do \
575 { \
576 int i; \
577 assert(stack->prev); \
578 pos = stack->item.pos; \
579 str_byte = stack->item.str_byte; \
580 state = stack->item.state; \
581 next_c = stack->item.next_c; \
582 for (i = 0; i < tnfa->num_tags; i++) \
583 tags[i] = stack->item.tags[i]; \
584 BT_STACK_MBSTATE_OUT; \
585 stack = stack->prev; \
586 } \
587 while (0)
588
589#undef MIN
590#define MIN(a, b) ((a) <= (b) ? (a) : (b))
591
592static reg_errcode_t
593tre_tnfa_run_backtrack(const tre_tnfa_t *tnfa, const void *string,
594 regoff_t *match_tags, int eflags, regoff_t *match_end_ofs)
595{
596 /* State variables required by GET_NEXT_WCHAR. */
597 tre_char_t prev_c = 0, next_c = 0;
598 const char *str_byte = string;
599 regoff_t pos = 0;
600 regoff_t pos_add_next = 1;
601#ifdef TRE_MBSTATE
602 mbstate_t mbstate;
603#endif /* TRE_MBSTATE */
604 int reg_notbol = eflags & REG_NOTBOL;
605 int reg_noteol = eflags & REG_NOTEOL;
606 int reg_newline = tnfa->cflags & REG_NEWLINE;
607
608 /* These are used to remember the necessary values of the above
609 variables to return to the position where the current search
610 started from. */
611 int next_c_start;
612 const char *str_byte_start;
613 regoff_t pos_start = -1;
614#ifdef TRE_MBSTATE
615 mbstate_t mbstate_start;
616#endif /* TRE_MBSTATE */
617
618 /* End offset of best match so far, or -1 if no match found yet. */
619 regoff_t match_eo = -1;
620 /* Tag arrays. */
621 int *next_tags;
622 regoff_t *tags = NULL;
623 /* Current TNFA state. */
624 tre_tnfa_transition_t *state;
625 int *states_seen = NULL;
626
627 /* Memory allocator to for allocating the backtracking stack. */
628 tre_mem_t mem = tre_bt_mem_new();
629
630 /* The backtracking stack. */
631 tre_backtrack_t stack;
632
633 tre_tnfa_transition_t *trans_i;
634 regmatch_t *pmatch = NULL;
635 int ret;
636
637#ifdef TRE_MBSTATE
638 memset(&mbstate, '\0', sizeof(mbstate));
639#endif /* TRE_MBSTATE */
640
641 if (!mem)
642 return REG_ESPACE;
643 stack = tre_bt_mem_alloc(mem, sizeof(*stack));
644 if (!stack)
645 {
646 ret = REG_ESPACE;
647 goto error_exit;
648 }
649 stack->prev = NULL;
650 stack->next = NULL;
651
652 if (tnfa->num_tags)
653 {
654 tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
655 if (!tags)
656 {
657 ret = REG_ESPACE;
658 goto error_exit;
659 }
660 }
661 if (tnfa->num_submatches)
662 {
663 pmatch = xmalloc(sizeof(*pmatch) * tnfa->num_submatches);
664 if (!pmatch)
665 {
666 ret = REG_ESPACE;
667 goto error_exit;
668 }
669 }
670 if (tnfa->num_states)
671 {
672 states_seen = xmalloc(sizeof(*states_seen) * tnfa->num_states);
673 if (!states_seen)
674 {
675 ret = REG_ESPACE;
676 goto error_exit;
677 }
678 }
679
680 retry:
681 {
682 int i;
683 for (i = 0; i < tnfa->num_tags; i++)
684 {
685 tags[i] = -1;
686 if (match_tags)
687 match_tags[i] = -1;
688 }
689 for (i = 0; i < tnfa->num_states; i++)
690 states_seen[i] = 0;
691 }
692
693 state = NULL;
694 pos = pos_start;
695 GET_NEXT_WCHAR();
696 pos_start = pos;
697 next_c_start = next_c;
698 str_byte_start = str_byte;
699#ifdef TRE_MBSTATE
700 mbstate_start = mbstate;
701#endif /* TRE_MBSTATE */
702
703 /* Handle initial states. */
704 next_tags = NULL;
705 for (trans_i = tnfa->initial; trans_i->state; trans_i++)
706 {
707 if (trans_i->assertions && CHECK_ASSERTIONS(trans_i->assertions))
708 {
709 continue;
710 }
711 if (state == NULL)
712 {
713 /* Start from this state. */
714 state = trans_i->state;
715 next_tags = trans_i->tags;
716 }
717 else
718 {
719 /* Backtrack to this state. */
720 BT_STACK_PUSH(pos, str_byte, 0, trans_i->state,
721 trans_i->state_id, next_c, tags, mbstate);
722 {
723 int *tmp = trans_i->tags;
724 if (tmp)
725 while (*tmp >= 0)
726 stack->item.tags[*tmp++] = pos;
727 }
728 }
729 }
730
731 if (next_tags)
732 for (; *next_tags >= 0; next_tags++)
733 tags[*next_tags] = pos;
734
735
736 if (state == NULL)
737 goto backtrack;
738
739 while (1)
740 {
741 tre_tnfa_transition_t *next_state;
742 int empty_br_match;
743
744 if (state == tnfa->final)
745 {
746 if (match_eo < pos
747 || (match_eo == pos
748 && match_tags
749 && tre_tag_order(tnfa->num_tags, tnfa->tag_directions,
750 tags, match_tags)))
751 {
752 int i;
753 /* This match wins the previous match. */
754 match_eo = pos;
755 if (match_tags)
756 for (i = 0; i < tnfa->num_tags; i++)
757 match_tags[i] = tags[i];
758 }
759 /* Our TNFAs never have transitions leaving from the final state,
760 so we jump right to backtracking. */
761 goto backtrack;
762 }
763
764 /* Go to the next character in the input string. */
765 empty_br_match = 0;
766 trans_i = state;
767 if (trans_i->state && trans_i->assertions & ASSERT_BACKREF)
768 {
769 /* This is a back reference state. All transitions leaving from
770 this state have the same back reference "assertion". Instead
771 of reading the next character, we match the back reference. */
772 regoff_t so, eo;
773 int bt = trans_i->u.backref;
774 regoff_t bt_len;
775 int result;
776
777 /* Get the substring we need to match against. Remember to
778 turn off REG_NOSUB temporarily. */
779 tre_fill_pmatch(bt + 1, pmatch, tnfa->cflags & ~REG_NOSUB,
780 tnfa, tags, pos);
781 so = pmatch[bt].rm_so;
782 eo = pmatch[bt].rm_eo;
783 bt_len = eo - so;
784
785 result = strncmp((const char*)string + so, str_byte - 1,
786 (size_t)bt_len);
787
788 if (result == 0)
789 {
790 /* Back reference matched. Check for infinite loop. */
791 if (bt_len == 0)
792 empty_br_match = 1;
793 if (empty_br_match && states_seen[trans_i->state_id])
794 {
795 goto backtrack;
796 }
797
798 states_seen[trans_i->state_id] = empty_br_match;
799
800 /* Advance in input string and resync `prev_c', `next_c'
801 and pos. */
802 str_byte += bt_len - 1;
803 pos += bt_len - 1;
804 GET_NEXT_WCHAR();
805 }
806 else
807 {
808 goto backtrack;
809 }
810 }
811 else
812 {
813 /* Check for end of string. */
814 if (next_c == L'\0')
815 goto backtrack;
816
817 /* Read the next character. */
818 GET_NEXT_WCHAR();
819 }
820
821 next_state = NULL;
822 for (trans_i = state; trans_i->state; trans_i++)
823 {
824 if (trans_i->code_min <= (tre_cint_t)prev_c
825 && trans_i->code_max >= (tre_cint_t)prev_c)
826 {
827 if (trans_i->assertions
828 && (CHECK_ASSERTIONS(trans_i->assertions)
829 || CHECK_CHAR_CLASSES(trans_i, tnfa, eflags)))
830 {
831 continue;
832 }
833
834 if (next_state == NULL)
835 {
836 /* First matching transition. */
837 next_state = trans_i->state;
838 next_tags = trans_i->tags;
839 }
840 else
841 {
842 /* Second matching transition. We may need to backtrack here
843 to take this transition instead of the first one, so we
844 push this transition in the backtracking stack so we can
845 jump back here if needed. */
846 BT_STACK_PUSH(pos, str_byte, 0, trans_i->state,
847 trans_i->state_id, next_c, tags, mbstate);
848 {
849 int *tmp;
850 for (tmp = trans_i->tags; tmp && *tmp >= 0; tmp++)
851 stack->item.tags[*tmp] = pos;
852 }
853#if 0 /* XXX - it's important not to look at all transitions here to keep
854 the stack small! */
855 break;
856#endif
857 }
858 }
859 }
860
861 if (next_state != NULL)
862 {
863 /* Matching transitions were found. Take the first one. */
864 state = next_state;
865
866 /* Update the tag values. */
867 if (next_tags)
868 while (*next_tags >= 0)
869 tags[*next_tags++] = pos;
870 }
871 else
872 {
873 backtrack:
874 /* A matching transition was not found. Try to backtrack. */
875 if (stack->prev)
876 {
877 if (stack->item.state->assertions & ASSERT_BACKREF)
878 {
879 states_seen[stack->item.state_id] = 0;
880 }
881
882 BT_STACK_POP();
883 }
884 else if (match_eo < 0)
885 {
886 /* Try starting from a later position in the input string. */
887 /* Check for end of string. */
888 if (next_c == L'\0')
889 {
890 break;
891 }
892 next_c = next_c_start;
893#ifdef TRE_MBSTATE
894 mbstate = mbstate_start;
895#endif /* TRE_MBSTATE */
896 str_byte = str_byte_start;
897 goto retry;
898 }
899 else
900 {
901 break;
902 }
903 }
904 }
905
906 ret = match_eo >= 0 ? REG_OK : REG_NOMATCH;
907 *match_end_ofs = match_eo;
908
909 error_exit:
910 tre_bt_mem_destroy(mem);
911#ifndef TRE_USE_ALLOCA
912 if (tags)
913 xfree(tags);
914 if (pmatch)
915 xfree(pmatch);
916 if (states_seen)
917 xfree(states_seen);
918#endif /* !TRE_USE_ALLOCA */
919
920 return ret;
921}
922
923/***********************************************************************
924 from regexec.c
925***********************************************************************/
926
927/* Fills the POSIX.2 regmatch_t array according to the TNFA tag and match
928 endpoint values. */
929static void
930tre_fill_pmatch(size_t nmatch, regmatch_t pmatch[], int cflags,
931 const tre_tnfa_t *tnfa, regoff_t *tags, regoff_t match_eo)
932{
933 tre_submatch_data_t *submatch_data;
934 unsigned int i, j;
935 int *parents;
936
937 i = 0;
938 if (match_eo >= 0 && !(cflags & REG_NOSUB))
939 {
940 /* Construct submatch offsets from the tags. */
941 submatch_data = tnfa->submatch_data;
942 while (i < tnfa->num_submatches && i < nmatch)
943 {
944 if (submatch_data[i].so_tag == tnfa->end_tag)
945 pmatch[i].rm_so = match_eo;
946 else
947 pmatch[i].rm_so = tags[submatch_data[i].so_tag];
948
949 if (submatch_data[i].eo_tag == tnfa->end_tag)
950 pmatch[i].rm_eo = match_eo;
951 else
952 pmatch[i].rm_eo = tags[submatch_data[i].eo_tag];
953
954 /* If either of the endpoints were not used, this submatch
955 was not part of the match. */
956 if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1)
957 pmatch[i].rm_so = pmatch[i].rm_eo = -1;
958
959 i++;
960 }
961 /* Reset all submatches that are not within all of their parent
962 submatches. */
963 i = 0;
964 while (i < tnfa->num_submatches && i < nmatch)
965 {
966 if (pmatch[i].rm_eo == -1)
967 assert(pmatch[i].rm_so == -1);
968 assert(pmatch[i].rm_so <= pmatch[i].rm_eo);
969
970 parents = submatch_data[i].parents;
971 if (parents != NULL)
972 for (j = 0; parents[j] >= 0; j++)
973 {
974 if (pmatch[i].rm_so < pmatch[parents[j]].rm_so
975 || pmatch[i].rm_eo > pmatch[parents[j]].rm_eo)
976 pmatch[i].rm_so = pmatch[i].rm_eo = -1;
977 }
978 i++;
979 }
980 }
981
982 while (i < nmatch)
983 {
984 pmatch[i].rm_so = -1;
985 pmatch[i].rm_eo = -1;
986 i++;
987 }
988}
989
990
991/*
992 Wrapper functions for POSIX compatible regexp matching.
993*/
994
995int
996regexec(const regex_t *restrict preg, const char *restrict string,
997 size_t nmatch, regmatch_t pmatch[restrict], int eflags)
998{
999 tre_tnfa_t *tnfa = (void *)preg->TRE_REGEX_T_FIELD;
1000 reg_errcode_t status;
1001 regoff_t *tags = NULL, eo;
1002 if (tnfa->cflags & REG_NOSUB) nmatch = 0;
1003 if (tnfa->num_tags > 0 && nmatch > 0)
1004 {
1005 tags = xmalloc(sizeof(*tags) * tnfa->num_tags);
1006 if (tags == NULL)
1007 return REG_ESPACE;
1008 }
1009
1010 /* Dispatch to the appropriate matcher. */
1011 if (tnfa->have_backrefs)
1012 {
1013 /* The regex has back references, use the backtracking matcher. */
1014 status = tre_tnfa_run_backtrack(tnfa, string, tags, eflags, &eo);
1015 }
1016 else
1017 {
1018 /* Exact matching, no back references, use the parallel matcher. */
1019 status = tre_tnfa_run_parallel(tnfa, string, tags, eflags, &eo);
1020 }
1021
1022 if (status == REG_OK)
1023 /* A match was found, so fill the submatch registers. */
1024 tre_fill_pmatch(nmatch, pmatch, tnfa->cflags, tnfa, tags, eo);
1025 if (tags)
1026 xfree(tags);
1027 return status;
1028}
libc/musl/src/regex/tre-mem.c created+158
......@@ -0,0 +1,158 @@
1/*
2 tre-mem.c - TRE memory allocator
3
4 Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
19 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30*/
31
32/*
33 This memory allocator is for allocating small memory blocks efficiently
34 in terms of memory overhead and execution speed. The allocated blocks
35 cannot be freed individually, only all at once. There can be multiple
36 allocators, though.
37*/
38
39#include <stdlib.h>
40#include <string.h>
41
42#include "tre.h"
43
44/*
45 This memory allocator is for allocating small memory blocks efficiently
46 in terms of memory overhead and execution speed. The allocated blocks
47 cannot be freed individually, only all at once. There can be multiple
48 allocators, though.
49*/
50
51/* Returns a new memory allocator or NULL if out of memory. */
52tre_mem_t
53tre_mem_new_impl(int provided, void *provided_block)
54{
55 tre_mem_t mem;
56 if (provided)
57 {
58 mem = provided_block;
59 memset(mem, 0, sizeof(*mem));
60 }
61 else
62 mem = xcalloc(1, sizeof(*mem));
63 if (mem == NULL)
64 return NULL;
65 return mem;
66}
67
68
69/* Frees the memory allocator and all memory allocated with it. */
70void
71tre_mem_destroy(tre_mem_t mem)
72{
73 tre_list_t *tmp, *l = mem->blocks;
74
75 while (l != NULL)
76 {
77 xfree(l->data);
78 tmp = l->next;
79 xfree(l);
80 l = tmp;
81 }
82 xfree(mem);
83}
84
85
86/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the
87 allocated block or NULL if an underlying malloc() failed. */
88void *
89tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
90 int zero, size_t size)
91{
92 void *ptr;
93
94 if (mem->failed)
95 {
96 return NULL;
97 }
98
99 if (mem->n < size)
100 {
101 /* We need more memory than is available in the current block.
102 Allocate a new block. */
103 tre_list_t *l;
104 if (provided)
105 {
106 if (provided_block == NULL)
107 {
108 mem->failed = 1;
109 return NULL;
110 }
111 mem->ptr = provided_block;
112 mem->n = TRE_MEM_BLOCK_SIZE;
113 }
114 else
115 {
116 int block_size;
117 if (size * 8 > TRE_MEM_BLOCK_SIZE)
118 block_size = size * 8;
119 else
120 block_size = TRE_MEM_BLOCK_SIZE;
121 l = xmalloc(sizeof(*l));
122 if (l == NULL)
123 {
124 mem->failed = 1;
125 return NULL;
126 }
127 l->data = xmalloc(block_size);
128 if (l->data == NULL)
129 {
130 xfree(l);
131 mem->failed = 1;
132 return NULL;
133 }
134 l->next = NULL;
135 if (mem->current != NULL)
136 mem->current->next = l;
137 if (mem->blocks == NULL)
138 mem->blocks = l;
139 mem->current = l;
140 mem->ptr = l->data;
141 mem->n = block_size;
142 }
143 }
144
145 /* Make sure the next pointer will be aligned. */
146 size += ALIGN(mem->ptr + size, long);
147
148 /* Allocate from current block. */
149 ptr = mem->ptr;
150 mem->ptr += size;
151 mem->n -= size;
152
153 /* Set to zero if needed. */
154 if (zero)
155 memset(ptr, 0, size);
156
157 return ptr;
158}
libc/musl/src/regex/tre.h created+231
......@@ -0,0 +1,231 @@
1/*
2 tre-internal.h - TRE internal definitions
3
4 Copyright (c) 2001-2009 Ville Laurikari <vl@iki.fi>
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 2. Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
19 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30*/
31
32#include <regex.h>
33#include <wchar.h>
34#include <wctype.h>
35
36#undef TRE_MBSTATE
37
38#define NDEBUG
39
40#define TRE_REGEX_T_FIELD __opaque
41typedef int reg_errcode_t;
42
43typedef wchar_t tre_char_t;
44
45#define DPRINT(msg) do { } while(0)
46
47#define elementsof(x) ( sizeof(x) / sizeof(x[0]) )
48
49#define tre_mbrtowc(pwc, s, n, ps) (mbtowc((pwc), (s), (n)))
50
51/* Wide characters. */
52typedef wint_t tre_cint_t;
53#define TRE_CHAR_MAX 0x10ffff
54
55#define tre_isalnum iswalnum
56#define tre_isalpha iswalpha
57#define tre_isblank iswblank
58#define tre_iscntrl iswcntrl
59#define tre_isdigit iswdigit
60#define tre_isgraph iswgraph
61#define tre_islower iswlower
62#define tre_isprint iswprint
63#define tre_ispunct iswpunct
64#define tre_isspace iswspace
65#define tre_isupper iswupper
66#define tre_isxdigit iswxdigit
67
68#define tre_tolower towlower
69#define tre_toupper towupper
70#define tre_strlen wcslen
71
72/* Use system provided iswctype() and wctype(). */
73typedef wctype_t tre_ctype_t;
74#define tre_isctype iswctype
75#define tre_ctype wctype
76
77/* Returns number of bytes to add to (char *)ptr to make it
78 properly aligned for the type. */
79#define ALIGN(ptr, type) \
80 ((((long)ptr) % sizeof(type)) \
81 ? (sizeof(type) - (((long)ptr) % sizeof(type))) \
82 : 0)
83
84#undef MAX
85#undef MIN
86#define MAX(a, b) (((a) >= (b)) ? (a) : (b))
87#define MIN(a, b) (((a) <= (b)) ? (a) : (b))
88
89/* TNFA transition type. A TNFA state is an array of transitions,
90 the terminator is a transition with NULL `state'. */
91typedef struct tnfa_transition tre_tnfa_transition_t;
92
93struct tnfa_transition {
94 /* Range of accepted characters. */
95 tre_cint_t code_min;
96 tre_cint_t code_max;
97 /* Pointer to the destination state. */
98 tre_tnfa_transition_t *state;
99 /* ID number of the destination state. */
100 int state_id;
101 /* -1 terminated array of tags (or NULL). */
102 int *tags;
103 /* Assertion bitmap. */
104 int assertions;
105 /* Assertion parameters. */
106 union {
107 /* Character class assertion. */
108 tre_ctype_t class;
109 /* Back reference assertion. */
110 int backref;
111 } u;
112 /* Negative character class assertions. */
113 tre_ctype_t *neg_classes;
114};
115
116
117/* Assertions. */
118#define ASSERT_AT_BOL 1 /* Beginning of line. */
119#define ASSERT_AT_EOL 2 /* End of line. */
120#define ASSERT_CHAR_CLASS 4 /* Character class in `class'. */
121#define ASSERT_CHAR_CLASS_NEG 8 /* Character classes in `neg_classes'. */
122#define ASSERT_AT_BOW 16 /* Beginning of word. */
123#define ASSERT_AT_EOW 32 /* End of word. */
124#define ASSERT_AT_WB 64 /* Word boundary. */
125#define ASSERT_AT_WB_NEG 128 /* Not a word boundary. */
126#define ASSERT_BACKREF 256 /* A back reference in `backref'. */
127#define ASSERT_LAST 256
128
129/* Tag directions. */
130typedef enum {
131 TRE_TAG_MINIMIZE = 0,
132 TRE_TAG_MAXIMIZE = 1
133} tre_tag_direction_t;
134
135/* Instructions to compute submatch register values from tag values
136 after a successful match. */
137struct tre_submatch_data {
138 /* Tag that gives the value for rm_so (submatch start offset). */
139 int so_tag;
140 /* Tag that gives the value for rm_eo (submatch end offset). */
141 int eo_tag;
142 /* List of submatches this submatch is contained in. */
143 int *parents;
144};
145
146typedef struct tre_submatch_data tre_submatch_data_t;
147
148
149/* TNFA definition. */
150typedef struct tnfa tre_tnfa_t;
151
152struct tnfa {
153 tre_tnfa_transition_t *transitions;
154 unsigned int num_transitions;
155 tre_tnfa_transition_t *initial;
156 tre_tnfa_transition_t *final;
157 tre_submatch_data_t *submatch_data;
158 char *firstpos_chars;
159 int first_char;
160 unsigned int num_submatches;
161 tre_tag_direction_t *tag_directions;
162 int *minimal_tags;
163 int num_tags;
164 int num_minimals;
165 int end_tag;
166 int num_states;
167 int cflags;
168 int have_backrefs;
169 int have_approx;
170};
171
172/* from tre-mem.h: */
173
174#define TRE_MEM_BLOCK_SIZE 1024
175
176typedef struct tre_list {
177 void *data;
178 struct tre_list *next;
179} tre_list_t;
180
181typedef struct tre_mem_struct {
182 tre_list_t *blocks;
183 tre_list_t *current;
184 char *ptr;
185 size_t n;
186 int failed;
187 void **provided;
188} *tre_mem_t;
189
190#define tre_mem_new_impl __tre_mem_new_impl
191#define tre_mem_alloc_impl __tre_mem_alloc_impl
192#define tre_mem_destroy __tre_mem_destroy
193
194hidden tre_mem_t tre_mem_new_impl(int provided, void *provided_block);
195hidden void *tre_mem_alloc_impl(tre_mem_t mem, int provided, void *provided_block,
196 int zero, size_t size);
197
198/* Returns a new memory allocator or NULL if out of memory. */
199#define tre_mem_new() tre_mem_new_impl(0, NULL)
200
201/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the
202 allocated block or NULL if an underlying malloc() failed. */
203#define tre_mem_alloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 0, size)
204
205/* Allocates a block of `size' bytes from `mem'. Returns a pointer to the
206 allocated block or NULL if an underlying malloc() failed. The memory
207 is set to zero. */
208#define tre_mem_calloc(mem, size) tre_mem_alloc_impl(mem, 0, NULL, 1, size)
209
210#ifdef TRE_USE_ALLOCA
211/* alloca() versions. Like above, but memory is allocated with alloca()
212 instead of malloc(). */
213
214#define tre_mem_newa() \
215 tre_mem_new_impl(1, alloca(sizeof(struct tre_mem_struct)))
216
217#define tre_mem_alloca(mem, size) \
218 ((mem)->n >= (size) \
219 ? tre_mem_alloc_impl((mem), 1, NULL, 0, (size)) \
220 : tre_mem_alloc_impl((mem), 1, alloca(TRE_MEM_BLOCK_SIZE), 0, (size)))
221#endif /* TRE_USE_ALLOCA */
222
223
224/* Frees the memory allocator and all memory allocated with it. */
225hidden void tre_mem_destroy(tre_mem_t mem);
226
227#define xmalloc malloc
228#define xcalloc calloc
229#define xfree free
230#define xrealloc realloc
231
libc/musl/src/sched/affinity.c created+33
......@@ -0,0 +1,33 @@
1#define _GNU_SOURCE
2#include <sched.h>
3#include <string.h>
4#include "pthread_impl.h"
5#include "syscall.h"
6
7int sched_setaffinity(pid_t tid, size_t size, const cpu_set_t *set)
8{
9 return syscall(SYS_sched_setaffinity, tid, size, set);
10}
11
12int pthread_setaffinity_np(pthread_t td, size_t size, const cpu_set_t *set)
13{
14 return -__syscall(SYS_sched_setaffinity, td->tid, size, set);
15}
16
17static int do_getaffinity(pid_t tid, size_t size, cpu_set_t *set)
18{
19 long ret = __syscall(SYS_sched_getaffinity, tid, size, set);
20 if (ret < 0) return ret;
21 if (ret < size) memset((char *)set+ret, 0, size-ret);
22 return 0;
23}
24
25int sched_getaffinity(pid_t tid, size_t size, cpu_set_t *set)
26{
27 return __syscall_ret(do_getaffinity(tid, size, set));
28}
29
30int pthread_getaffinity_np(pthread_t td, size_t size, cpu_set_t *set)
31{
32 return -do_getaffinity(td->tid, size, set);
33}
libc/musl/src/sched/sched_cpucount.c created+11
......@@ -0,0 +1,11 @@
1#define _GNU_SOURCE
2#include <sched.h>
3
4int __sched_cpucount(size_t size, const cpu_set_t *set)
5{
6 size_t i, j, cnt=0;
7 const unsigned char *p = (const void *)set;
8 for (i=0; i<size; i++) for (j=0; j<8; j++)
9 if (p[i] & (1<<j)) cnt++;
10 return cnt;
11}
libc/musl/src/sched/sched_get_priority_max.c created+12
......@@ -0,0 +1,12 @@
1#include <sched.h>
2#include "syscall.h"
3
4int sched_get_priority_max(int policy)
5{
6 return syscall(SYS_sched_get_priority_max, policy);
7}
8
9int sched_get_priority_min(int policy)
10{
11 return syscall(SYS_sched_get_priority_min, policy);
12}
libc/musl/src/sched/sched_getcpu.c created+42
......@@ -0,0 +1,42 @@
1#define _GNU_SOURCE
2#include <errno.h>
3#include <sched.h>
4#include "syscall.h"
5#include "atomic.h"
6
7#ifdef VDSO_GETCPU_SYM
8
9static void *volatile vdso_func;
10
11typedef long (*getcpu_f)(unsigned *, unsigned *, void *);
12
13static long getcpu_init(unsigned *cpu, unsigned *node, void *unused)
14{
15 void *p = __vdsosym(VDSO_GETCPU_VER, VDSO_GETCPU_SYM);
16 getcpu_f f = (getcpu_f)p;
17 a_cas_p(&vdso_func, (void *)getcpu_init, p);
18 return f ? f(cpu, node, unused) : -ENOSYS;
19}
20
21static void *volatile vdso_func = (void *)getcpu_init;
22
23#endif
24
25int sched_getcpu(void)
26{
27 int r;
28 unsigned cpu;
29
30#ifdef VDSO_GETCPU_SYM
31 getcpu_f f = (getcpu_f)vdso_func;
32 if (f) {
33 r = f(&cpu, 0, 0);
34 if (!r) return cpu;
35 if (r != -ENOSYS) return __syscall_ret(r);
36 }
37#endif
38
39 r = __syscall(SYS_getcpu, &cpu, 0, 0);
40 if (!r) return cpu;
41 return __syscall_ret(r);
42}
libc/musl/src/sched/sched_getparam.c created+8
......@@ -0,0 +1,8 @@
1#include <sched.h>
2#include <errno.h>
3#include "syscall.h"
4
5int sched_getparam(pid_t pid, struct sched_param *param)
6{
7 return __syscall_ret(-ENOSYS);
8}
libc/musl/src/sched/sched_getscheduler.c created+8
......@@ -0,0 +1,8 @@
1#include <sched.h>
2#include <errno.h>
3#include "syscall.h"
4
5int sched_getscheduler(pid_t pid)
6{
7 return __syscall_ret(-ENOSYS);
8}
libc/musl/src/sched/sched_rr_get_interval.c created+7
......@@ -0,0 +1,7 @@
1#include <sched.h>
2#include "syscall.h"
3
4int sched_rr_get_interval(pid_t pid, struct timespec *ts)
5{
6 return syscall(SYS_sched_rr_get_interval, pid, ts);
7}
libc/musl/src/sched/sched_setparam.c created+8
......@@ -0,0 +1,8 @@
1#include <sched.h>
2#include <errno.h>
3#include "syscall.h"
4
5int sched_setparam(pid_t pid, const struct sched_param *param)
6{
7 return __syscall_ret(-ENOSYS);
8}
libc/musl/src/sched/sched_setscheduler.c created+8
......@@ -0,0 +1,8 @@
1#include <sched.h>
2#include <errno.h>
3#include "syscall.h"
4
5int sched_setscheduler(pid_t pid, int sched, const struct sched_param *param)
6{
7 return __syscall_ret(-ENOSYS);
8}
libc/musl/src/sched/sched_yield.c created+7
......@@ -0,0 +1,7 @@
1#include <sched.h>
2#include "syscall.h"
3
4int sched_yield()
5{
6 return syscall(SYS_sched_yield);
7}
libc/musl/src/search/hsearch.c created+153
......@@ -0,0 +1,153 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <string.h>
4#include <search.h>
5
6/*
7open addressing hash table with 2^n table size
8quadratic probing is used in case of hash collision
9tab indices and hash are size_t
10after resize fails with ENOMEM the state of tab is still usable
11
12with the posix api items cannot be iterated and length cannot be queried
13*/
14
15#define MINSIZE 8
16#define MAXSIZE ((size_t)-1/2 + 1)
17
18struct __tab {
19 ENTRY *entries;
20 size_t mask;
21 size_t used;
22};
23
24static struct hsearch_data htab;
25
26static int __hcreate_r(size_t, struct hsearch_data *);
27static void __hdestroy_r(struct hsearch_data *);
28static int __hsearch_r(ENTRY, ACTION, ENTRY **, struct hsearch_data *);
29
30static size_t keyhash(char *k)
31{
32 unsigned char *p = (void *)k;
33 size_t h = 0;
34
35 while (*p)
36 h = 31*h + *p++;
37 return h;
38}
39
40static int resize(size_t nel, struct hsearch_data *htab)
41{
42 size_t newsize;
43 size_t i, j;
44 ENTRY *e, *newe;
45 ENTRY *oldtab = htab->__tab->entries;
46 ENTRY *oldend = htab->__tab->entries + htab->__tab->mask + 1;
47
48 if (nel > MAXSIZE)
49 nel = MAXSIZE;
50 for (newsize = MINSIZE; newsize < nel; newsize *= 2);
51 htab->__tab->entries = calloc(newsize, sizeof *htab->__tab->entries);
52 if (!htab->__tab->entries) {
53 htab->__tab->entries = oldtab;
54 return 0;
55 }
56 htab->__tab->mask = newsize - 1;
57 if (!oldtab)
58 return 1;
59 for (e = oldtab; e < oldend; e++)
60 if (e->key) {
61 for (i=keyhash(e->key),j=1; ; i+=j++) {
62 newe = htab->__tab->entries + (i & htab->__tab->mask);
63 if (!newe->key)
64 break;
65 }
66 *newe = *e;
67 }
68 free(oldtab);
69 return 1;
70}
71
72int hcreate(size_t nel)
73{
74 return __hcreate_r(nel, &htab);
75}
76
77void hdestroy(void)
78{
79 __hdestroy_r(&htab);
80}
81
82static ENTRY *lookup(char *key, size_t hash, struct hsearch_data *htab)
83{
84 size_t i, j;
85 ENTRY *e;
86
87 for (i=hash,j=1; ; i+=j++) {
88 e = htab->__tab->entries + (i & htab->__tab->mask);
89 if (!e->key || strcmp(e->key, key) == 0)
90 break;
91 }
92 return e;
93}
94
95ENTRY *hsearch(ENTRY item, ACTION action)
96{
97 ENTRY *e;
98
99 __hsearch_r(item, action, &e, &htab);
100 return e;
101}
102
103static int __hcreate_r(size_t nel, struct hsearch_data *htab)
104{
105 int r;
106
107 htab->__tab = calloc(1, sizeof *htab->__tab);
108 if (!htab->__tab)
109 return 0;
110 r = resize(nel, htab);
111 if (r == 0) {
112 free(htab->__tab);
113 htab->__tab = 0;
114 }
115 return r;
116}
117weak_alias(__hcreate_r, hcreate_r);
118
119static void __hdestroy_r(struct hsearch_data *htab)
120{
121 if (htab->__tab) free(htab->__tab->entries);
122 free(htab->__tab);
123 htab->__tab = 0;
124}
125weak_alias(__hdestroy_r, hdestroy_r);
126
127static int __hsearch_r(ENTRY item, ACTION action, ENTRY **retval, struct hsearch_data *htab)
128{
129 size_t hash = keyhash(item.key);
130 ENTRY *e = lookup(item.key, hash, htab);
131
132 if (e->key) {
133 *retval = e;
134 return 1;
135 }
136 if (action == FIND) {
137 *retval = 0;
138 return 0;
139 }
140 *e = item;
141 if (++htab->__tab->used > htab->__tab->mask - htab->__tab->mask/4) {
142 if (!resize(2*htab->__tab->used, htab)) {
143 htab->__tab->used--;
144 e->key = 0;
145 *retval = 0;
146 return 0;
147 }
148 e = lookup(item.key, hash, htab);
149 }
150 *retval = e;
151 return 1;
152}
153weak_alias(__hsearch_r, hsearch_r);
libc/musl/src/search/insque.c created+32
......@@ -0,0 +1,32 @@
1#include <search.h>
2
3struct node {
4 struct node *next;
5 struct node *prev;
6};
7
8void insque(void *element, void *pred)
9{
10 struct node *e = element;
11 struct node *p = pred;
12
13 if (!p) {
14 e->next = e->prev = 0;
15 return;
16 }
17 e->next = p->next;
18 e->prev = p;
19 p->next = e;
20 if (e->next)
21 e->next->prev = e;
22}
23
24void remque(void *element)
25{
26 struct node *e = element;
27
28 if (e->next)
29 e->next->prev = e->prev;
30 if (e->prev)
31 e->prev->next = e->next;
32}
libc/musl/src/search/lsearch.c created+31
......@@ -0,0 +1,31 @@
1#include <search.h>
2#include <string.h>
3
4void *lsearch(const void *key, void *base, size_t *nelp, size_t width,
5 int (*compar)(const void *, const void *))
6{
7 char (*p)[width] = base;
8 size_t n = *nelp;
9 size_t i;
10
11 for (i = 0; i < n; i++)
12 if (compar(key, p[i]) == 0)
13 return p[i];
14 *nelp = n+1;
15 return memcpy(p[n], key, width);
16}
17
18void *lfind(const void *key, const void *base, size_t *nelp,
19 size_t width, int (*compar)(const void *, const void *))
20{
21 char (*p)[width] = (void *)base;
22 size_t n = *nelp;
23 size_t i;
24
25 for (i = 0; i < n; i++)
26 if (compar(key, p[i]) == 0)
27 return p[i];
28 return 0;
29}
30
31
libc/musl/src/search/tdelete.c created+49
......@@ -0,0 +1,49 @@
1#include <stdlib.h>
2#include <search.h>
3#include "tsearch.h"
4
5void *tdelete(const void *restrict key, void **restrict rootp,
6 int(*cmp)(const void *, const void *))
7{
8 if (!rootp)
9 return 0;
10
11 void **a[MAXH+1];
12 struct node *n = *rootp;
13 struct node *parent;
14 struct node *child;
15 int i=0;
16 /* *a[0] is an arbitrary non-null pointer that is returned when
17 the root node is deleted. */
18 a[i++] = rootp;
19 a[i++] = rootp;
20 for (;;) {
21 if (!n)
22 return 0;
23 int c = cmp(key, n->key);
24 if (!c)
25 break;
26 a[i++] = &n->a[c>0];
27 n = n->a[c>0];
28 }
29 parent = *a[i-2];
30 if (n->a[0]) {
31 /* free the preceding node instead of the deleted one. */
32 struct node *deleted = n;
33 a[i++] = &n->a[0];
34 n = n->a[0];
35 while (n->a[1]) {
36 a[i++] = &n->a[1];
37 n = n->a[1];
38 }
39 deleted->key = n->key;
40 child = n->a[0];
41 } else {
42 child = n->a[1];
43 }
44 /* freed node has at most one child, move it up and rebalance. */
45 free(n);
46 *a[--i] = child;
47 while (--i && __tsearch_balance(a[i]));
48 return parent;
49}
libc/musl/src/search/tdestroy.c created+16
......@@ -0,0 +1,16 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <search.h>
4#include "tsearch.h"
5
6void tdestroy(void *root, void (*freekey)(void *))
7{
8 struct node *r = root;
9
10 if (r == 0)
11 return;
12 tdestroy(r->a[0], freekey);
13 tdestroy(r->a[1], freekey);
14 if (freekey) freekey((void *)r->key);
15 free(r);
16}
libc/musl/src/search/tfind.c created+20
......@@ -0,0 +1,20 @@
1#include <search.h>
2#include "tsearch.h"
3
4void *tfind(const void *key, void *const *rootp,
5 int(*cmp)(const void *, const void *))
6{
7 if (!rootp)
8 return 0;
9
10 struct node *n = *rootp;
11 for (;;) {
12 if (!n)
13 break;
14 int c = cmp(key, n->key);
15 if (!c)
16 break;
17 n = n->a[c>0];
18 }
19 return n;
20}
libc/musl/src/search/tsearch.c created+92
......@@ -0,0 +1,92 @@
1#include <stdlib.h>
2#include <search.h>
3#include "tsearch.h"
4
5static inline int height(struct node *n) { return n ? n->h : 0; }
6
7static int rot(void **p, struct node *x, int dir /* deeper side */)
8{
9 struct node *y = x->a[dir];
10 struct node *z = y->a[!dir];
11 int hx = x->h;
12 int hz = height(z);
13 if (hz > height(y->a[dir])) {
14 /*
15 * x
16 * / \ dir z
17 * A y / \
18 * / \ --> x y
19 * z D /| |\
20 * / \ A B C D
21 * B C
22 */
23 x->a[dir] = z->a[!dir];
24 y->a[!dir] = z->a[dir];
25 z->a[!dir] = x;
26 z->a[dir] = y;
27 x->h = hz;
28 y->h = hz;
29 z->h = hz+1;
30 } else {
31 /*
32 * x y
33 * / \ / \
34 * A y --> x D
35 * / \ / \
36 * z D A z
37 */
38 x->a[dir] = z;
39 y->a[!dir] = x;
40 x->h = hz+1;
41 y->h = hz+2;
42 z = y;
43 }
44 *p = z;
45 return z->h - hx;
46}
47
48/* balance *p, return 0 if height is unchanged. */
49int __tsearch_balance(void **p)
50{
51 struct node *n = *p;
52 int h0 = height(n->a[0]);
53 int h1 = height(n->a[1]);
54 if (h0 - h1 + 1u < 3u) {
55 int old = n->h;
56 n->h = h0<h1 ? h1+1 : h0+1;
57 return n->h - old;
58 }
59 return rot(p, n, h0<h1);
60}
61
62void *tsearch(const void *key, void **rootp,
63 int (*cmp)(const void *, const void *))
64{
65 if (!rootp)
66 return 0;
67
68 void **a[MAXH];
69 struct node *n = *rootp;
70 struct node *r;
71 int i=0;
72 a[i++] = rootp;
73 for (;;) {
74 if (!n)
75 break;
76 int c = cmp(key, n->key);
77 if (!c)
78 return n;
79 a[i++] = &n->a[c>0];
80 n = n->a[c>0];
81 }
82 r = malloc(sizeof *r);
83 if (!r)
84 return 0;
85 r->key = key;
86 r->a[0] = r->a[1] = 0;
87 r->h = 1;
88 /* insert new node, rebalance ancestors. */
89 *a[--i] = r;
90 while (i && __tsearch_balance(a[--i]));
91 return r;
92}
libc/musl/src/search/tsearch.h created+13
......@@ -0,0 +1,13 @@
1#include <search.h>
2#include <features.h>
3
4/* AVL tree height < 1.44*log2(nodes+2)-0.3, MAXH is a safe upper bound. */
5#define MAXH (sizeof(void*)*8*3/2)
6
7struct node {
8 const void *key;
9 void *a[2];
10 int h;
11};
12
13hidden int __tsearch_balance(void **);
libc/musl/src/search/twalk.c created+22
......@@ -0,0 +1,22 @@
1#include <search.h>
2#include "tsearch.h"
3
4static void walk(const struct node *r, void (*action)(const void *, VISIT, int), int d)
5{
6 if (!r)
7 return;
8 if (r->h == 1)
9 action(r, leaf, d);
10 else {
11 action(r, preorder, d);
12 walk(r->a[0], action, d+1);
13 action(r, postorder, d);
14 walk(r->a[1], action, d+1);
15 action(r, endorder, d);
16 }
17}
18
19void twalk(const void *root, void (*action)(const void *, VISIT, int))
20{
21 walk(root, action, 0);
22}
libc/musl/src/select/poll.c created+15
......@@ -0,0 +1,15 @@
1#include <poll.h>
2#include <time.h>
3#include <signal.h>
4#include "syscall.h"
5
6int poll(struct pollfd *fds, nfds_t n, int timeout)
7{
8#ifdef SYS_poll
9 return syscall_cp(SYS_poll, fds, n, timeout);
10#else
11 return syscall_cp(SYS_ppoll, fds, n, timeout>=0 ?
12 &((struct timespec){ .tv_sec = timeout/1000,
13 .tv_nsec = timeout%1000*1000000 }) : 0, 0, _NSIG/8);
14#endif
15}
libc/musl/src/select/pselect.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/select.h>
2#include <signal.h>
3#include <stdint.h>
4#include "syscall.h"
5
6int pselect(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, const struct timespec *restrict ts, const sigset_t *restrict mask)
7{
8 syscall_arg_t data[2] = { (uintptr_t)mask, _NSIG/8 };
9 struct timespec ts_tmp;
10 if (ts) ts_tmp = *ts;
11 return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, ts ? &ts_tmp : 0, data);
12}
libc/musl/src/select/select.c created+25
......@@ -0,0 +1,25 @@
1#include <sys/select.h>
2#include <signal.h>
3#include <stdint.h>
4#include <errno.h>
5#include "syscall.h"
6
7int select(int n, fd_set *restrict rfds, fd_set *restrict wfds, fd_set *restrict efds, struct timeval *restrict tv)
8{
9#ifdef SYS_select
10 return syscall_cp(SYS_select, n, rfds, wfds, efds, tv);
11#else
12 syscall_arg_t data[2] = { 0, _NSIG/8 };
13 struct timespec ts;
14 if (tv) {
15 if (tv->tv_sec < 0 || tv->tv_usec < 0)
16 return __syscall_ret(-EINVAL);
17 time_t extra_secs = tv->tv_usec / 1000000;
18 ts.tv_nsec = tv->tv_usec % 1000000 * 1000;
19 const time_t max_time = (1ULL<<8*sizeof(time_t)-1)-1;
20 ts.tv_sec = extra_secs > max_time - tv->tv_sec ?
21 max_time : tv->tv_sec + extra_secs;
22 }
23 return syscall_cp(SYS_pselect6, n, rfds, wfds, efds, tv ? &ts : 0, data);
24#endif
25}
libc/musl/src/setjmp/aarch64/longjmp.s created+24
......@@ -0,0 +1,24 @@
1.global _longjmp
2.global longjmp
3.type _longjmp,%function
4.type longjmp,%function
5_longjmp:
6longjmp:
7 // IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
8 ldp x19, x20, [x0,#0]
9 ldp x21, x22, [x0,#16]
10 ldp x23, x24, [x0,#32]
11 ldp x25, x26, [x0,#48]
12 ldp x27, x28, [x0,#64]
13 ldp x29, x30, [x0,#80]
14 ldr x2, [x0,#104]
15 mov sp, x2
16 ldp d8 , d9, [x0,#112]
17 ldp d10, d11, [x0,#128]
18 ldp d12, d13, [x0,#144]
19 ldp d14, d15, [x0,#160]
20
21 mov x0, x1
22 cbnz x1, 1f
23 mov x0, #1
241: br x30
libc/musl/src/setjmp/aarch64/setjmp.s created+24
......@@ -0,0 +1,24 @@
1.global __setjmp
2.global _setjmp
3.global setjmp
4.type __setjmp,@function
5.type _setjmp,@function
6.type setjmp,@function
7__setjmp:
8_setjmp:
9setjmp:
10 // IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers
11 stp x19, x20, [x0,#0]
12 stp x21, x22, [x0,#16]
13 stp x23, x24, [x0,#32]
14 stp x25, x26, [x0,#48]
15 stp x27, x28, [x0,#64]
16 stp x29, x30, [x0,#80]
17 mov x2, sp
18 str x2, [x0,#104]
19 stp d8, d9, [x0,#112]
20 stp d10, d11, [x0,#128]
21 stp d12, d13, [x0,#144]
22 stp d14, d15, [x0,#160]
23 mov x0, #0
24 ret
libc/musl/src/setjmp/arm/longjmp.s created+43
......@@ -0,0 +1,43 @@
1.syntax unified
2.global _longjmp
3.global longjmp
4.type _longjmp,%function
5.type longjmp,%function
6_longjmp:
7longjmp:
8 mov ip,r0
9 movs r0,r1
10 moveq r0,#1
11 ldmia ip!, {v1,v2,v3,v4,v5,v6,sl,fp}
12 ldmia ip!, {r2,lr}
13 mov sp,r2
14
15 adr r1,1f
16 ldr r2,1f
17 ldr r1,[r1,r2]
18
19 tst r1,#0x260
20 beq 3f
21 tst r1,#0x20
22 beq 2f
23 ldc p2, cr4, [ip], #48
242: tst r1,#0x40
25 beq 2f
26 .fpu vfp
27 vldmia ip!, {d8-d15}
28 .fpu softvfp
29 .eabi_attribute 10, 0
30 .eabi_attribute 27, 0
312: tst r1,#0x200
32 beq 3f
33 ldcl p1, cr10, [ip], #8
34 ldcl p1, cr11, [ip], #8
35 ldcl p1, cr12, [ip], #8
36 ldcl p1, cr13, [ip], #8
37 ldcl p1, cr14, [ip], #8
38 ldcl p1, cr15, [ip], #8
393: bx lr
40
41.hidden __hwcap
42.align 2
431: .word __hwcap-1b
libc/musl/src/setjmp/arm/setjmp.s created+45
......@@ -0,0 +1,45 @@
1.syntax unified
2.global __setjmp
3.global _setjmp
4.global setjmp
5.type __setjmp,%function
6.type _setjmp,%function
7.type setjmp,%function
8__setjmp:
9_setjmp:
10setjmp:
11 mov ip,r0
12 stmia ip!,{v1,v2,v3,v4,v5,v6,sl,fp}
13 mov r2,sp
14 stmia ip!,{r2,lr}
15 mov r0,#0
16
17 adr r1,1f
18 ldr r2,1f
19 ldr r1,[r1,r2]
20
21 tst r1,#0x260
22 beq 3f
23 tst r1,#0x20
24 beq 2f
25 stc p2, cr4, [ip], #48
262: tst r1,#0x40
27 beq 2f
28 .fpu vfp
29 vstmia ip!, {d8-d15}
30 .fpu softvfp
31 .eabi_attribute 10, 0
32 .eabi_attribute 27, 0
332: tst r1,#0x200
34 beq 3f
35 stcl p1, cr10, [ip], #8
36 stcl p1, cr11, [ip], #8
37 stcl p1, cr12, [ip], #8
38 stcl p1, cr13, [ip], #8
39 stcl p1, cr14, [ip], #8
40 stcl p1, cr15, [ip], #8
413: bx lr
42
43.hidden __hwcap
44.align 2
451: .word __hwcap-1b
libc/musl/src/setjmp/i386/longjmp.s created+20
......@@ -0,0 +1,20 @@
1.global _longjmp
2.global longjmp
3.type _longjmp,@function
4.type longjmp,@function
5_longjmp:
6longjmp:
7 mov 4(%esp),%edx
8 mov 8(%esp),%eax
9 test %eax,%eax
10 jnz 1f
11 inc %eax
121:
13 mov (%edx),%ebx
14 mov 4(%edx),%esi
15 mov 8(%edx),%edi
16 mov 12(%edx),%ebp
17 mov 16(%edx),%ecx
18 mov %ecx,%esp
19 mov 20(%edx),%ecx
20 jmp *%ecx
libc/musl/src/setjmp/i386/setjmp.s created+23
......@@ -0,0 +1,23 @@
1.global ___setjmp
2.hidden ___setjmp
3.global __setjmp
4.global _setjmp
5.global setjmp
6.type __setjmp,@function
7.type _setjmp,@function
8.type setjmp,@function
9___setjmp:
10__setjmp:
11_setjmp:
12setjmp:
13 mov 4(%esp), %eax
14 mov %ebx, (%eax)
15 mov %esi, 4(%eax)
16 mov %edi, 8(%eax)
17 mov %ebp, 12(%eax)
18 lea 4(%esp), %ecx
19 mov %ecx, 16(%eax)
20 mov (%esp), %ecx
21 mov %ecx, 20(%eax)
22 xor %eax, %eax
23 ret
libc/musl/src/setjmp/longjmp.c created
libc/musl/src/setjmp/m68k/longjmp.s created+14
......@@ -0,0 +1,14 @@
1.global _longjmp
2.global longjmp
3.type _longjmp,@function
4.type longjmp,@function
5_longjmp:
6longjmp:
7 movea.l 4(%sp),%a0
8 move.l 8(%sp),%d0
9 bne 1f
10 move.l #1,%d0
111: movem.l (%a0),%d2-%d7/%a2-%a7
12 fmovem.x 52(%a0),%fp2-%fp7
13 move.l 48(%a0),(%sp)
14 rts
libc/musl/src/setjmp/m68k/setjmp.s created+18
......@@ -0,0 +1,18 @@
1.global ___setjmp
2.hidden ___setjmp
3.global __setjmp
4.global _setjmp
5.global setjmp
6.type __setjmp,@function
7.type _setjmp,@function
8.type setjmp,@function
9___setjmp:
10__setjmp:
11_setjmp:
12setjmp:
13 movea.l 4(%sp),%a0
14 movem.l %d2-%d7/%a2-%a7,(%a0)
15 move.l (%sp),48(%a0)
16 fmovem.x %fp2-%fp7,52(%a0)
17 clr.l %d0
18 rts
libc/musl/src/setjmp/microblaze/longjmp.s created+29
......@@ -0,0 +1,29 @@
1.global _longjmp
2.global longjmp
3.type _longjmp,@function
4.type longjmp,@function
5_longjmp:
6longjmp:
7 addi r3, r6, 0
8 bnei r3, 1f
9 addi r3, r3, 1
101: lwi r1, r5, 0
11 lwi r15, r5, 4
12 lwi r2, r5, 8
13 lwi r13, r5, 12
14 lwi r18, r5, 16
15 lwi r19, r5, 20
16 lwi r20, r5, 24
17 lwi r21, r5, 28
18 lwi r22, r5, 32
19 lwi r23, r5, 36
20 lwi r24, r5, 40
21 lwi r25, r5, 44
22 lwi r26, r5, 48
23 lwi r27, r5, 52
24 lwi r28, r5, 56
25 lwi r29, r5, 60
26 lwi r30, r5, 64
27 lwi r31, r5, 68
28 rtsd r15, 8
29 nop
libc/musl/src/setjmp/microblaze/setjmp.s created+32
......@@ -0,0 +1,32 @@
1.global ___setjmp
2.hidden ___setjmp
3.global __setjmp
4.global _setjmp
5.global setjmp
6.type __setjmp,@function
7.type _setjmp,@function
8.type setjmp,@function
9___setjmp:
10__setjmp:
11_setjmp:
12setjmp:
13 swi r1, r5, 0
14 swi r15, r5, 4
15 swi r2, r5, 8
16 swi r13, r5, 12
17 swi r18, r5, 16
18 swi r19, r5, 20
19 swi r20, r5, 24
20 swi r21, r5, 28
21 swi r22, r5, 32
22 swi r23, r5, 36
23 swi r24, r5, 40
24 swi r25, r5, 44
25 swi r26, r5, 48
26 swi r27, r5, 52
27 swi r28, r5, 56
28 swi r29, r5, 60
29 swi r30, r5, 64
30 swi r31, r5, 68
31 rtsd r15, 8
32 ori r3, r0, 0
libc/musl/src/setjmp/mips/longjmp.S created+40
......@@ -0,0 +1,40 @@
1.set noreorder
2
3.global _longjmp
4.global longjmp
5.type _longjmp,@function
6.type longjmp,@function
7_longjmp:
8longjmp:
9 move $2, $5
10 bne $2, $0, 1f
11 nop
12 addu $2, $2, 1
131:
14#ifndef __mips_soft_float
15 lwc1 $20, 56($4)
16 lwc1 $21, 60($4)
17 lwc1 $22, 64($4)
18 lwc1 $23, 68($4)
19 lwc1 $24, 72($4)
20 lwc1 $25, 76($4)
21 lwc1 $26, 80($4)
22 lwc1 $27, 84($4)
23 lwc1 $28, 88($4)
24 lwc1 $29, 92($4)
25 lwc1 $30, 96($4)
26 lwc1 $31, 100($4)
27#endif
28 lw $ra, 0($4)
29 lw $sp, 4($4)
30 lw $16, 8($4)
31 lw $17, 12($4)
32 lw $18, 16($4)
33 lw $19, 20($4)
34 lw $20, 24($4)
35 lw $21, 28($4)
36 lw $22, 32($4)
37 lw $23, 36($4)
38 lw $30, 40($4)
39 jr $ra
40 lw $28, 44($4)
libc/musl/src/setjmp/mips/setjmp.S created+39
......@@ -0,0 +1,39 @@
1.set noreorder
2
3.global __setjmp
4.global _setjmp
5.global setjmp
6.type __setjmp,@function
7.type _setjmp,@function
8.type setjmp,@function
9__setjmp:
10_setjmp:
11setjmp:
12 sw $ra, 0($4)
13 sw $sp, 4($4)
14 sw $16, 8($4)
15 sw $17, 12($4)
16 sw $18, 16($4)
17 sw $19, 20($4)
18 sw $20, 24($4)
19 sw $21, 28($4)
20 sw $22, 32($4)
21 sw $23, 36($4)
22 sw $30, 40($4)
23 sw $28, 44($4)
24#ifndef __mips_soft_float
25 swc1 $20, 56($4)
26 swc1 $21, 60($4)
27 swc1 $22, 64($4)
28 swc1 $23, 68($4)
29 swc1 $24, 72($4)
30 swc1 $25, 76($4)
31 swc1 $26, 80($4)
32 swc1 $27, 84($4)
33 swc1 $28, 88($4)
34 swc1 $29, 92($4)
35 swc1 $30, 96($4)
36 swc1 $31, 100($4)
37#endif
38 jr $ra
39 li $2, 0
libc/musl/src/setjmp/mips64/longjmp.S created+37
......@@ -0,0 +1,37 @@
1.set noreorder
2.global _longjmp
3.global longjmp
4.type _longjmp,@function
5.type longjmp,@function
6_longjmp:
7longjmp:
8 move $2, $5
9
10 bne $2, $0, 1f
11 nop
12 daddu $2, $2, 1
131:
14#ifndef __mips_soft_float
15 ldc1 $24, 96($4)
16 ldc1 $25, 104($4)
17 ldc1 $26, 112($4)
18 ldc1 $27, 120($4)
19 ldc1 $28, 128($4)
20 ldc1 $29, 136($4)
21 ldc1 $30, 144($4)
22 ldc1 $31, 152($4)
23#endif
24 ld $ra, 0($4)
25 ld $sp, 8($4)
26 ld $gp, 16($4)
27 ld $16, 24($4)
28 ld $17, 32($4)
29 ld $18, 40($4)
30 ld $19, 48($4)
31 ld $20, 56($4)
32 ld $21, 64($4)
33 ld $22, 72($4)
34 ld $23, 80($4)
35 ld $30, 88($4)
36 jr $ra
37 nop
libc/musl/src/setjmp/mips64/setjmp.S created+34
......@@ -0,0 +1,34 @@
1.set noreorder
2.global __setjmp
3.global _setjmp
4.global setjmp
5.type __setjmp,@function
6.type _setjmp,@function
7.type setjmp,@function
8__setjmp:
9_setjmp:
10setjmp:
11 sd $ra, 0($4)
12 sd $sp, 8($4)
13 sd $gp, 16($4)
14 sd $16, 24($4)
15 sd $17, 32($4)
16 sd $18, 40($4)
17 sd $19, 48($4)
18 sd $20, 56($4)
19 sd $21, 64($4)
20 sd $22, 72($4)
21 sd $23, 80($4)
22 sd $30, 88($4)
23#ifndef __mips_soft_float
24 sdc1 $24, 96($4)
25 sdc1 $25, 104($4)
26 sdc1 $26, 112($4)
27 sdc1 $27, 120($4)
28 sdc1 $28, 128($4)
29 sdc1 $29, 136($4)
30 sdc1 $30, 144($4)
31 sdc1 $31, 152($4)
32#endif
33 jr $ra
34 li $2, 0
libc/musl/src/setjmp/mipsn32/longjmp.S created+36
......@@ -0,0 +1,36 @@
1.set noreorder
2.global _longjmp
3.global longjmp
4.type _longjmp,@function
5.type longjmp,@function
6_longjmp:
7longjmp:
8 move $2, $5
9 bne $2, $0, 1f
10 nop
11 addu $2, $2, 1
121:
13#ifndef __mips_soft_float
14 ldc1 $24, 96($4)
15 ldc1 $25, 104($4)
16 ldc1 $26, 112($4)
17 ldc1 $27, 120($4)
18 ldc1 $28, 128($4)
19 ldc1 $29, 136($4)
20 ldc1 $30, 144($4)
21 ldc1 $31, 152($4)
22#endif
23 ld $ra, 0($4)
24 ld $sp, 8($4)
25 ld $gp, 16($4)
26 ld $16, 24($4)
27 ld $17, 32($4)
28 ld $18, 40($4)
29 ld $19, 48($4)
30 ld $20, 56($4)
31 ld $21, 64($4)
32 ld $22, 72($4)
33 ld $23, 80($4)
34 ld $30, 88($4)
35 jr $ra
36 nop
libc/musl/src/setjmp/mipsn32/setjmp.S created+34
......@@ -0,0 +1,34 @@
1.set noreorder
2.global __setjmp
3.global _setjmp
4.global setjmp
5.type __setjmp,@function
6.type _setjmp,@function
7.type setjmp,@function
8__setjmp:
9_setjmp:
10setjmp:
11 sd $ra, 0($4)
12 sd $sp, 8($4)
13 sd $gp, 16($4)
14 sd $16, 24($4)
15 sd $17, 32($4)
16 sd $18, 40($4)
17 sd $19, 48($4)
18 sd $20, 56($4)
19 sd $21, 64($4)
20 sd $22, 72($4)
21 sd $23, 80($4)
22 sd $30, 88($4)
23#ifndef __mips_soft_float
24 sdc1 $24, 96($4)
25 sdc1 $25, 104($4)
26 sdc1 $26, 112($4)
27 sdc1 $27, 120($4)
28 sdc1 $28, 128($4)
29 sdc1 $29, 136($4)
30 sdc1 $30, 144($4)
31 sdc1 $31, 152($4)
32#endif
33 jr $ra
34 li $2, 0
libc/musl/src/setjmp/or1k/longjmp.s created+25
......@@ -0,0 +1,25 @@
1.global _longjmp
2.global longjmp
3.type _longjmp,@function
4.type longjmp,@function
5_longjmp:
6longjmp:
7 l.sfeqi r4, 0
8 l.bnf 1f
9 l.addi r11, r4,0
10 l.ori r11, r0, 1
111: l.lwz r1, 0(r3)
12 l.lwz r2, 4(r3)
13 l.lwz r9, 8(r3)
14 l.lwz r10, 12(r3)
15 l.lwz r14, 16(r3)
16 l.lwz r16, 20(r3)
17 l.lwz r18, 24(r3)
18 l.lwz r20, 28(r3)
19 l.lwz r22, 32(r3)
20 l.lwz r24, 36(r3)
21 l.lwz r26, 40(r3)
22 l.lwz r28, 44(r3)
23 l.lwz r30, 48(r3)
24 l.jr r9
25 l.nop
libc/musl/src/setjmp/or1k/setjmp.s created+27
......@@ -0,0 +1,27 @@
1.global ___setjmp
2.hidden ___setjmp
3.global __setjmp
4.global _setjmp
5.global setjmp
6.type __setjmp,@function
7.type _setjmp,@function
8.type setjmp,@function
9___setjmp:
10__setjmp:
11_setjmp:
12setjmp:
13 l.sw 0(r3), r1
14 l.sw 4(r3), r2
15 l.sw 8(r3), r9
16 l.sw 12(r3), r10
17 l.sw 16(r3), r14
18 l.sw 20(r3), r16
19 l.sw 24(r3), r18
20 l.sw 28(r3), r20
21 l.sw 32(r3), r22
22 l.sw 36(r3), r24
23 l.sw 40(r3), r26
24 l.sw 44(r3), r28
25 l.sw 48(r3), r30
26 l.jr r9
27 l.ori r11,r0,0
libc/musl/src/setjmp/powerpc/longjmp.S created+69
......@@ -0,0 +1,69 @@
1 .global _longjmp
2 .global longjmp
3 .type _longjmp,@function
4 .type longjmp,@function
5_longjmp:
6longjmp:
7 /*
8 * void longjmp(jmp_buf env, int val);
9 * put val into return register and restore the env saved in setjmp
10 * if val(r4) is 0, put 1 there.
11 */
12 /* 0) move old return address into r0 */
13 lwz 0, 0(3)
14 /* 1) put it into link reg */
15 mtlr 0
16 /* 2 ) restore stack ptr */
17 lwz 1, 4(3)
18 /* 3) restore control reg */
19 lwz 0, 8(3)
20 mtcr 0
21 /* 4) restore r14-r31 */
22 lwz 14, 12(3)
23 lwz 15, 16(3)
24 lwz 16, 20(3)
25 lwz 17, 24(3)
26 lwz 18, 28(3)
27 lwz 19, 32(3)
28 lwz 20, 36(3)
29 lwz 21, 40(3)
30 lwz 22, 44(3)
31 lwz 23, 48(3)
32 lwz 24, 52(3)
33 lwz 25, 56(3)
34 lwz 26, 60(3)
35 lwz 27, 64(3)
36 lwz 28, 68(3)
37 lwz 29, 72(3)
38 lwz 30, 76(3)
39 lwz 31, 80(3)
40#ifndef _SOFT_FLOAT
41 lfd 14,88(3)
42 lfd 15,96(3)
43 lfd 16,104(3)
44 lfd 17,112(3)
45 lfd 18,120(3)
46 lfd 19,128(3)
47 lfd 20,136(3)
48 lfd 21,144(3)
49 lfd 22,152(3)
50 lfd 23,160(3)
51 lfd 24,168(3)
52 lfd 25,176(3)
53 lfd 26,184(3)
54 lfd 27,192(3)
55 lfd 28,200(3)
56 lfd 29,208(3)
57 lfd 30,216(3)
58 lfd 31,224(3)
59#endif
60 /* 5) put val into return reg r3 */
61 mr 3, 4
62
63 /* 6) check if return value is 0, make it 1 in that case */
64 cmpwi cr7, 4, 0
65 bne cr7, 1f
66 li 3, 1
671:
68 blr
69
libc/musl/src/setjmp/powerpc/setjmp.S created+63
......@@ -0,0 +1,63 @@
1 .global ___setjmp
2 .hidden ___setjmp
3 .global __setjmp
4 .global _setjmp
5 .global setjmp
6 .type __setjmp,@function
7 .type _setjmp,@function
8 .type setjmp,@function
9___setjmp:
10__setjmp:
11_setjmp:
12setjmp:
13 /* 0) store IP int 0, then into the jmpbuf pointed to by r3 (first arg) */
14 mflr 0
15 stw 0, 0(3)
16 /* 1) store reg1 (SP) */
17 stw 1, 4(3)
18 /* 2) store cr */
19 mfcr 0
20 stw 0, 8(3)
21 /* 3) store r14-31 */
22 stw 14, 12(3)
23 stw 15, 16(3)
24 stw 16, 20(3)
25 stw 17, 24(3)
26 stw 18, 28(3)
27 stw 19, 32(3)
28 stw 20, 36(3)
29 stw 21, 40(3)
30 stw 22, 44(3)
31 stw 23, 48(3)
32 stw 24, 52(3)
33 stw 25, 56(3)
34 stw 26, 60(3)
35 stw 27, 64(3)
36 stw 28, 68(3)
37 stw 29, 72(3)
38 stw 30, 76(3)
39 stw 31, 80(3)
40#ifndef _SOFT_FLOAT
41 stfd 14,88(3)
42 stfd 15,96(3)
43 stfd 16,104(3)
44 stfd 17,112(3)
45 stfd 18,120(3)
46 stfd 19,128(3)
47 stfd 20,136(3)
48 stfd 21,144(3)
49 stfd 22,152(3)
50 stfd 23,160(3)
51 stfd 24,168(3)
52 stfd 25,176(3)
53 stfd 26,184(3)
54 stfd 27,192(3)
55 stfd 28,200(3)
56 stfd 29,208(3)
57 stfd 30,216(3)
58 stfd 31,224(3)
59#endif
60 /* 4) set return value to 0 */
61 li 3, 0
62 /* 5) return */
63 blr
libc/musl/src/setjmp/powerpc64/longjmp.s created+81
......@@ -0,0 +1,81 @@
1 .global _longjmp
2 .global longjmp
3 .type _longjmp,@function
4 .type longjmp,@function
5_longjmp:
6longjmp:
7 # 0) move old return address into the link register
8 ld 0, 0*8(3)
9 mtlr 0
10 # 1) restore cr
11 ld 0, 1*8(3)
12 mtcr 0
13 # 2) restore SP
14 ld 1, 2*8(3)
15 # 3) restore TOC into both r2 and the caller's stack.
16 # Which location is required depends on whether setjmp was called
17 # locally or non-locally, but it's always safe to restore to both.
18 ld 2, 3*8(3)
19 std 2, 24(1)
20 # 4) restore r14-r31
21 ld 14, 4*8(3)
22 ld 15, 5*8(3)
23 ld 16, 6*8(3)
24 ld 17, 7*8(3)
25 ld 18, 8*8(3)
26 ld 19, 9*8(3)
27 ld 20, 10*8(3)
28 ld 21, 11*8(3)
29 ld 22, 12*8(3)
30 ld 23, 13*8(3)
31 ld 24, 14*8(3)
32 ld 25, 15*8(3)
33 ld 26, 16*8(3)
34 ld 27, 17*8(3)
35 ld 28, 18*8(3)
36 ld 29, 19*8(3)
37 ld 30, 20*8(3)
38 ld 31, 21*8(3)
39 # 5) restore floating point registers f14-f31
40 lfd 14, 22*8(3)
41 lfd 15, 23*8(3)
42 lfd 16, 24*8(3)
43 lfd 17, 25*8(3)
44 lfd 18, 26*8(3)
45 lfd 19, 27*8(3)
46 lfd 20, 28*8(3)
47 lfd 21, 29*8(3)
48 lfd 22, 30*8(3)
49 lfd 23, 31*8(3)
50 lfd 24, 32*8(3)
51 lfd 25, 33*8(3)
52 lfd 26, 34*8(3)
53 lfd 27, 35*8(3)
54 lfd 28, 36*8(3)
55 lfd 29, 37*8(3)
56 lfd 30, 38*8(3)
57 lfd 31, 39*8(3)
58
59 # 6) restore vector registers v20-v31
60 addi 3, 3, 40*8
61 lvx 20, 0, 3 ; addi 3, 3, 16
62 lvx 21, 0, 3 ; addi 3, 3, 16
63 lvx 22, 0, 3 ; addi 3, 3, 16
64 lvx 23, 0, 3 ; addi 3, 3, 16
65 lvx 24, 0, 3 ; addi 3, 3, 16
66 lvx 25, 0, 3 ; addi 3, 3, 16
67 lvx 26, 0, 3 ; addi 3, 3, 16
68 lvx 27, 0, 3 ; addi 3, 3, 16
69 lvx 28, 0, 3 ; addi 3, 3, 16
70 lvx 29, 0, 3 ; addi 3, 3, 16
71 lvx 30, 0, 3 ; addi 3, 3, 16
72 lvx 31, 0, 3
73
74 # 7) return r4 ? r4 : 1
75 mr 3, 4
76 cmpwi cr7, 4, 0
77 bne cr7, 1f
78 li 3, 1
791:
80 blr
81
libc/musl/src/setjmp/powerpc64/setjmp.s created+89
......@@ -0,0 +1,89 @@
1 .global __setjmp
2 .global _setjmp
3 .global setjmp
4 .type __setjmp,@function
5 .type _setjmp,@function
6 .type setjmp,@function
7__setjmp:
8_setjmp:
9setjmp:
10 ld 5, 24(1) # load from the TOC slot in the caller's stack frame
11 b __setjmp_toc
12
13 .localentry __setjmp,.-__setjmp
14 .localentry _setjmp,.-_setjmp
15 .localentry setjmp,.-setjmp
16 mr 5, 2
17
18 .global __setjmp_toc
19 .hidden __setjmp_toc
20 # same as normal setjmp, except TOC pointer to save is provided in r5.
21 # r4 would normally be the 2nd parameter, but we're using r5 to simplify calling from sigsetjmp.
22 # solves the problem of knowing whether to save the TOC pointer from r2 or the caller's stack frame.
23__setjmp_toc:
24 # 0) store IP into 0, then into the jmpbuf pointed to by r3 (first arg)
25 mflr 0
26 std 0, 0*8(3)
27 # 1) store cr
28 mfcr 0
29 std 0, 1*8(3)
30 # 2) store SP and TOC
31 std 1, 2*8(3)
32 std 5, 3*8(3)
33 # 3) store r14-31
34 std 14, 4*8(3)
35 std 15, 5*8(3)
36 std 16, 6*8(3)
37 std 17, 7*8(3)
38 std 18, 8*8(3)
39 std 19, 9*8(3)
40 std 20, 10*8(3)
41 std 21, 11*8(3)
42 std 22, 12*8(3)
43 std 23, 13*8(3)
44 std 24, 14*8(3)
45 std 25, 15*8(3)
46 std 26, 16*8(3)
47 std 27, 17*8(3)
48 std 28, 18*8(3)
49 std 29, 19*8(3)
50 std 30, 20*8(3)
51 std 31, 21*8(3)
52 # 4) store floating point registers f14-f31
53 stfd 14, 22*8(3)
54 stfd 15, 23*8(3)
55 stfd 16, 24*8(3)
56 stfd 17, 25*8(3)
57 stfd 18, 26*8(3)
58 stfd 19, 27*8(3)
59 stfd 20, 28*8(3)
60 stfd 21, 29*8(3)
61 stfd 22, 30*8(3)
62 stfd 23, 31*8(3)
63 stfd 24, 32*8(3)
64 stfd 25, 33*8(3)
65 stfd 26, 34*8(3)
66 stfd 27, 35*8(3)
67 stfd 28, 36*8(3)
68 stfd 29, 37*8(3)
69 stfd 30, 38*8(3)
70 stfd 31, 39*8(3)
71
72 # 5) store vector registers v20-v31
73 addi 3, 3, 40*8
74 stvx 20, 0, 3 ; addi 3, 3, 16
75 stvx 21, 0, 3 ; addi 3, 3, 16
76 stvx 22, 0, 3 ; addi 3, 3, 16
77 stvx 23, 0, 3 ; addi 3, 3, 16
78 stvx 24, 0, 3 ; addi 3, 3, 16
79 stvx 25, 0, 3 ; addi 3, 3, 16
80 stvx 26, 0, 3 ; addi 3, 3, 16
81 stvx 27, 0, 3 ; addi 3, 3, 16
82 stvx 28, 0, 3 ; addi 3, 3, 16
83 stvx 29, 0, 3 ; addi 3, 3, 16
84 stvx 30, 0, 3 ; addi 3, 3, 16
85 stvx 31, 0, 3
86
87 # 6) return 0
88 li 3, 0
89 blr
libc/musl/src/setjmp/s390x/longjmp.s created+23
......@@ -0,0 +1,23 @@
1 .global _longjmp
2 .global longjmp
3 .type _longjmp,@function
4 .type longjmp,@function
5_longjmp:
6longjmp:
7
81:
9 lmg %r6, %r15, 0(%r2)
10
11 ld %f8, 10*8(%r2)
12 ld %f9, 11*8(%r2)
13 ld %f10, 12*8(%r2)
14 ld %f11, 13*8(%r2)
15 ld %f12, 14*8(%r2)
16 ld %f13, 15*8(%r2)
17 ld %f14, 16*8(%r2)
18 ld %f15, 17*8(%r2)
19
20 ltgr %r2, %r3
21 bnzr %r14
22 lhi %r2, 1
23 br %r14
libc/musl/src/setjmp/s390x/setjmp.s created+25
......@@ -0,0 +1,25 @@
1 .global ___setjmp
2 .hidden ___setjmp
3 .global __setjmp
4 .global _setjmp
5 .global setjmp
6 .type __setjmp,@function
7 .type _setjmp,@function
8 .type setjmp,@function
9___setjmp:
10__setjmp:
11_setjmp:
12setjmp:
13 stmg %r6, %r15, 0(%r2)
14
15 std %f8, 10*8(%r2)
16 std %f9, 11*8(%r2)
17 std %f10, 12*8(%r2)
18 std %f11, 13*8(%r2)
19 std %f12, 14*8(%r2)
20 std %f13, 15*8(%r2)
21 std %f14, 16*8(%r2)
22 std %f15, 17*8(%r2)
23
24 lghi %r2, 0
25 br %r14
libc/musl/src/setjmp/setjmp.c created
libc/musl/src/setjmp/sh/longjmp.S created+28
......@@ -0,0 +1,28 @@
1.global _longjmp
2.global longjmp
3.type _longjmp, @function
4.type longjmp, @function
5_longjmp:
6longjmp:
7 mov.l @r4+, r8
8 mov.l @r4+, r9
9 mov.l @r4+, r10
10 mov.l @r4+, r11
11 mov.l @r4+, r12
12 mov.l @r4+, r13
13 mov.l @r4+, r14
14 mov.l @r4+, r15
15 lds.l @r4+, pr
16#if __SH_FPU_ANY__ || __SH4__
17 fmov.s @r4+, fr12
18 fmov.s @r4+, fr13
19 fmov.s @r4+, fr14
20 fmov.s @r4+, fr15
21#endif
22
23 tst r5, r5
24 movt r0
25 add r5, r0
26
27 rts
28 nop
libc/musl/src/setjmp/sh/setjmp.S created+32
......@@ -0,0 +1,32 @@
1.global ___setjmp
2.hidden ___setjmp
3.global __setjmp
4.global _setjmp
5.global setjmp
6.type __setjmp, @function
7.type _setjmp, @function
8.type setjmp, @function
9___setjmp:
10__setjmp:
11_setjmp:
12setjmp:
13#if __SH_FPU_ANY__ || __SH4__
14 add #52, r4
15 fmov.s fr15, @-r4
16 fmov.s fr14, @-r4
17 fmov.s fr13, @-r4
18 fmov.s fr12, @-r4
19#else
20 add #36, r4
21#endif
22 sts.l pr, @-r4
23 mov.l r15, @-r4
24 mov.l r14, @-r4
25 mov.l r13, @-r4
26 mov.l r12, @-r4
27 mov.l r11, @-r4
28 mov.l r10, @-r4
29 mov.l r9, @-r4
30 mov.l r8, @-r4
31 rts
32 mov #0, r0
libc/musl/src/setjmp/x32/longjmp.s created+22
......@@ -0,0 +1,22 @@
1/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
2.global _longjmp
3.global longjmp
4.type _longjmp,@function
5.type longjmp,@function
6_longjmp:
7longjmp:
8 mov %rsi,%rax /* val will be longjmp return */
9 test %rax,%rax
10 jnz 1f
11 inc %rax /* if val==0, val=1 per longjmp semantics */
121:
13 mov (%rdi),%rbx /* rdi is the jmp_buf, restore regs from it */
14 mov 8(%rdi),%rbp
15 mov 16(%rdi),%r12
16 mov 24(%rdi),%r13
17 mov 32(%rdi),%r14
18 mov 40(%rdi),%r15
19 mov 48(%rdi),%rdx /* this ends up being the stack pointer */
20 mov %rdx,%rsp
21 mov 56(%rdi),%rdx /* this is the instruction pointer */
22 jmp *%rdx /* goto saved address without altering rsp */
libc/musl/src/setjmp/x32/setjmp.s created+22
......@@ -0,0 +1,22 @@
1/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
2.global __setjmp
3.global _setjmp
4.global setjmp
5.type __setjmp,@function
6.type _setjmp,@function
7.type setjmp,@function
8__setjmp:
9_setjmp:
10setjmp:
11 mov %rbx,(%rdi) /* rdi is jmp_buf, move registers onto it */
12 mov %rbp,8(%rdi)
13 mov %r12,16(%rdi)
14 mov %r13,24(%rdi)
15 mov %r14,32(%rdi)
16 mov %r15,40(%rdi)
17 lea 8(%rsp),%rdx /* this is our rsp WITHOUT current ret addr */
18 mov %rdx,48(%rdi)
19 mov (%rsp),%rdx /* save return addr ptr for new rip */
20 mov %rdx,56(%rdi)
21 xor %rax,%rax /* always return 0 */
22 ret
libc/musl/src/setjmp/x86_64/longjmp.s created+22
......@@ -0,0 +1,22 @@
1/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
2.global _longjmp
3.global longjmp
4.type _longjmp,@function
5.type longjmp,@function
6_longjmp:
7longjmp:
8 mov %rsi,%rax /* val will be longjmp return */
9 test %rax,%rax
10 jnz 1f
11 inc %rax /* if val==0, val=1 per longjmp semantics */
121:
13 mov (%rdi),%rbx /* rdi is the jmp_buf, restore regs from it */
14 mov 8(%rdi),%rbp
15 mov 16(%rdi),%r12
16 mov 24(%rdi),%r13
17 mov 32(%rdi),%r14
18 mov 40(%rdi),%r15
19 mov 48(%rdi),%rdx /* this ends up being the stack pointer */
20 mov %rdx,%rsp
21 mov 56(%rdi),%rdx /* this is the instruction pointer */
22 jmp *%rdx /* goto saved address without altering rsp */
libc/musl/src/setjmp/x86_64/setjmp.s created+22
......@@ -0,0 +1,22 @@
1/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
2.global __setjmp
3.global _setjmp
4.global setjmp
5.type __setjmp,@function
6.type _setjmp,@function
7.type setjmp,@function
8__setjmp:
9_setjmp:
10setjmp:
11 mov %rbx,(%rdi) /* rdi is jmp_buf, move registers onto it */
12 mov %rbp,8(%rdi)
13 mov %r12,16(%rdi)
14 mov %r13,24(%rdi)
15 mov %r14,32(%rdi)
16 mov %r15,40(%rdi)
17 lea 8(%rsp),%rdx /* this is our rsp WITHOUT current ret addr */
18 mov %rdx,48(%rdi)
19 mov (%rsp),%rdx /* save return addr ptr for new rip */
20 mov %rdx,56(%rdi)
21 xor %rax,%rax /* always return 0 */
22 ret
libc/musl/src/signal/aarch64/restore.s created+10
......@@ -0,0 +1,10 @@
1.global __restore
2.hidden __restore
3.type __restore,%function
4__restore:
5.global __restore_rt
6.hidden __restore_rt
7.type __restore_rt,%function
8__restore_rt:
9 mov x8,#139 // SYS_rt_sigreturn
10 svc 0
libc/musl/src/signal/aarch64/sigsetjmp.s created+21
......@@ -0,0 +1,21 @@
1.global sigsetjmp
2.global __sigsetjmp
3.type sigsetjmp,%function
4.type __sigsetjmp,%function
5sigsetjmp:
6__sigsetjmp:
7 cbz x1,setjmp
8
9 str x30,[x0,#176]
10 str x19,[x0,#176+8+8]
11 mov x19,x0
12
13 bl setjmp
14
15 mov w1,w0
16 mov x0,x19
17 ldr x30,[x0,#176]
18 ldr x19,[x0,#176+8+8]
19
20.hidden __sigsetjmp_tail
21 b __sigsetjmp_tail
libc/musl/src/signal/arm/restore.s created+15
......@@ -0,0 +1,15 @@
1.syntax unified
2
3.global __restore
4.hidden __restore
5.type __restore,%function
6__restore:
7 mov r7,#119
8 swi 0x0
9
10.global __restore_rt
11.hidden __restore_rt
12.type __restore_rt,%function
13__restore_rt:
14 mov r7,#173
15 swi 0x0
libc/musl/src/signal/arm/sigsetjmp.s created+23
......@@ -0,0 +1,23 @@
1.syntax unified
2.global sigsetjmp
3.global __sigsetjmp
4.type sigsetjmp,%function
5.type __sigsetjmp,%function
6sigsetjmp:
7__sigsetjmp:
8 tst r1,r1
9 beq setjmp
10
11 str lr,[r0,#256]
12 str r4,[r0,#260+8]
13 mov r4,r0
14
15 bl setjmp
16
17 mov r1,r0
18 mov r0,r4
19 ldr lr,[r0,#256]
20 ldr r4,[r0,#260+8]
21
22.hidden __sigsetjmp_tail
23 b __sigsetjmp_tail
libc/musl/src/signal/block.c created+44
......@@ -0,0 +1,44 @@
1#include "pthread_impl.h"
2#include "syscall.h"
3#include <signal.h>
4
5static const unsigned long all_mask[] = {
6#if ULONG_MAX == 0xffffffff && _NSIG == 129
7 -1UL, -1UL, -1UL, -1UL
8#elif ULONG_MAX == 0xffffffff
9 -1UL, -1UL
10#else
11 -1UL
12#endif
13};
14
15static const unsigned long app_mask[] = {
16#if ULONG_MAX == 0xffffffff
17#if _NSIG == 65
18 0x7fffffff, 0xfffffffc
19#else
20 0x7fffffff, 0xfffffffc, -1UL, -1UL
21#endif
22#else
23#if _NSIG == 65
24 0xfffffffc7fffffff
25#else
26 0xfffffffc7fffffff, -1UL
27#endif
28#endif
29};
30
31void __block_all_sigs(void *set)
32{
33 __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &all_mask, set, _NSIG/8);
34}
35
36void __block_app_sigs(void *set)
37{
38 __syscall(SYS_rt_sigprocmask, SIG_BLOCK, &app_mask, set, _NSIG/8);
39}
40
41void __restore_sigs(void *set)
42{
43 __syscall(SYS_rt_sigprocmask, SIG_SETMASK, set, 0, _NSIG/8);
44}
libc/musl/src/signal/getitimer.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/time.h>
2#include "syscall.h"
3
4int getitimer(int which, struct itimerval *old)
5{
6 return syscall(SYS_getitimer, which, old);
7}
libc/musl/src/signal/i386/restore.s created+14
......@@ -0,0 +1,14 @@
1.global __restore
2.hidden __restore
3.type __restore,@function
4__restore:
5 popl %eax
6 movl $119, %eax
7 int $0x80
8
9.global __restore_rt
10.hidden __restore_rt
11.type __restore_rt,@function
12__restore_rt:
13 movl $173, %eax
14 int $0x80
libc/musl/src/signal/i386/sigsetjmp.s created+26
......@@ -0,0 +1,26 @@
1.global sigsetjmp
2.global __sigsetjmp
3.type sigsetjmp,@function
4.type __sigsetjmp,@function
5sigsetjmp:
6__sigsetjmp:
7 mov 8(%esp),%ecx
8 jecxz 1f
9
10 mov 4(%esp),%eax
11 popl 24(%eax)
12 mov %ebx,28+8(%eax)
13 mov %eax,%ebx
14
15.hidden ___setjmp
16 call ___setjmp
17
18 pushl 24(%ebx)
19 mov %ebx,4(%esp)
20 mov %eax,8(%esp)
21 mov 28+8(%ebx),%ebx
22
23.hidden __sigsetjmp_tail
24 jmp __sigsetjmp_tail
25
261: jmp ___setjmp
libc/musl/src/signal/kill.c created+7
......@@ -0,0 +1,7 @@
1#include <signal.h>
2#include "syscall.h"
3
4int kill(pid_t pid, int sig)
5{
6 return syscall(SYS_kill, pid, sig);
7}
libc/musl/src/signal/killpg.c created+11
......@@ -0,0 +1,11 @@
1#include <signal.h>
2#include <errno.h>
3
4int killpg(pid_t pgid, int sig)
5{
6 if (pgid < 0) {
7 errno = EINVAL;
8 return -1;
9 }
10 return kill(-pgid, sig);
11}
libc/musl/src/signal/m68k/sigsetjmp.s created+29
......@@ -0,0 +1,29 @@
1.global sigsetjmp
2.global __sigsetjmp
3.type sigsetjmp,@function
4.type __sigsetjmp,@function
5sigsetjmp:
6__sigsetjmp:
7 move.l 8(%sp),%d0
8 beq 1f
9
10 movea.l 4(%sp),%a1
11 move.l (%sp)+,156(%a1)
12 move.l %a2,156+4+8(%a1)
13 movea.l %a1,%a2
14
15.hidden ___setjmp
16 lea ___setjmp-.-8,%a1
17 jsr (%pc,%a1)
18
19 move.l 156(%a2),-(%sp)
20 move.l %a2,4(%sp)
21 move.l %d0,8(%sp)
22 movea.l 156+4+8(%a2),%a2
23
24.hidden __sigsetjmp_tail
25 lea __sigsetjmp_tail-.-8,%a1
26 jmp (%pc,%a1)
27
281: lea ___setjmp-.-8,%a1
29 jmp (%pc,%a1)
libc/musl/src/signal/microblaze/restore.s created+13
......@@ -0,0 +1,13 @@
1.global __restore
2.hidden __restore
3.type __restore,@function
4__restore:
5 ori r12, r0, 119
6 brki r14, 0x8
7
8.global __restore_rt
9.hidden __restore_rt
10.type __restore_rt,@function
11__restore_rt:
12 ori r12, r0, 173
13 brki r14, 0x8
libc/musl/src/signal/microblaze/sigsetjmp.s created+22
......@@ -0,0 +1,22 @@
1.global sigsetjmp
2.global __sigsetjmp
3.type sigsetjmp,@function
4.type __sigsetjmp,@function
5sigsetjmp:
6__sigsetjmp:
7.hidden ___setjmp
8 beqi r6, ___setjmp
9
10 swi r15,r5,72
11 swi r19,r5,72+4+8
12
13 brlid r15,___setjmp
14 ori r19,r5,0
15
16 ori r6,r3,0
17 ori r5,r19,0
18 lwi r15,r5,72
19 lwi r19,r5,72+4+8
20
21.hidden __sigsetjmp_tail
22 bri __sigsetjmp_tail
libc/musl/src/signal/mips/restore.s created+15
......@@ -0,0 +1,15 @@
1.set noreorder
2
3.global __restore_rt
4.hidden __restore_rt
5.type __restore_rt,@function
6__restore_rt:
7 li $2, 4193
8 syscall
9
10.global __restore
11.hidden __restore
12.type __restore,@function
13__restore:
14 li $2, 4119
15 syscall
libc/musl/src/signal/mips/sigsetjmp.s created+33
......@@ -0,0 +1,33 @@
1.set noreorder
2
3.global sigsetjmp
4.global __sigsetjmp
5.type sigsetjmp,@function
6.type __sigsetjmp,@function
7sigsetjmp:
8__sigsetjmp:
9 lui $gp, %hi(_gp_disp)
10 addiu $gp, %lo(_gp_disp)
11 beq $5, $0, 1f
12 addu $gp, $gp, $25
13
14 sw $ra, 104($4)
15 sw $16, 104+4+16($4)
16
17 lw $25, %call16(setjmp)($gp)
18 jalr $25
19 move $16, $4
20
21 move $5,$2
22 move $4,$16
23 lw $ra, 104($4)
24 lw $16, 104+4+16($4)
25
26.hidden __sigsetjmp_tail
27 lw $25, %call16(__sigsetjmp_tail)($gp)
28 jr $25
29 nop
30
311: lw $25, %call16(setjmp)($gp)
32 jr $25
33 nop
libc/musl/src/signal/mips64/restore.s created+11
......@@ -0,0 +1,11 @@
1.set noreorder
2.global __restore_rt
3.global __restore
4.hidden __restore_rt
5.hidden __restore
6.type __restore_rt,@function
7.type __restore,@function
8__restore_rt:
9__restore:
10 li $2,5211
11 syscall
libc/musl/src/signal/mips64/sigsetjmp.s created+38
......@@ -0,0 +1,38 @@
1.set noreorder
2.global sigsetjmp
3.global __sigsetjmp
4.type sigsetjmp,@function
5.type __sigsetjmp,@function
6sigsetjmp:
7__sigsetjmp:
8 lui $3, %hi(%neg(%gp_rel(sigsetjmp)))
9 daddiu $3, $3, %lo(%neg(%gp_rel(sigsetjmp)))
10
11 # comparing save mask with 0, if equals to 0 then
12 # sigsetjmp is equal to setjmp.
13 beq $5, $0, 1f
14 daddu $3, $3, $25
15 sd $ra, 160($4)
16 sd $16, 168($4)
17
18 # save base of got so that we can use it later
19 # once we return from 'longjmp'
20 sd $3, 176($4)
21 ld $25, %got_disp(setjmp)($3)
22 jalr $25
23 move $16, $4
24
25 move $5, $2 # Return from 'setjmp' or 'longjmp'
26 move $4, $16 # Restore the pointer-to-sigjmp_buf
27 ld $ra, 160($4) # Restore ra of sigsetjmp
28 ld $16, 168($4) # Restore $16 of sigsetjmp
29 ld $3, 176($4) # Restore base of got
30
31.hidden __sigsetjmp_tail
32 ld $25, %got_disp(__sigsetjmp_tail)($3)
33 jr $25
34 nop
351:
36 ld $25, %got_disp(setjmp)($3)
37 jr $25
38 nop
libc/musl/src/signal/mipsn32/restore.s created+11
......@@ -0,0 +1,11 @@
1.set noreorder
2.global __restore_rt
3.global __restore
4.hidden __restore_rt
5.hidden __restore
6.type __restore_rt,@function
7.type __restore,@function
8__restore_rt:
9__restore:
10 li $2,6211
11 syscall
libc/musl/src/signal/mipsn32/sigsetjmp.s created+38
......@@ -0,0 +1,38 @@
1.set noreorder
2.global sigsetjmp
3.global __sigsetjmp
4.type sigsetjmp,@function
5.type __sigsetjmp,@function
6sigsetjmp:
7__sigsetjmp:
8 lui $3, %hi(%neg(%gp_rel(sigsetjmp)))
9 addiu $3, $3, %lo(%neg(%gp_rel(sigsetjmp)))
10
11 # comparing save mask with 0, if equals to 0 then
12 # sigsetjmp is equal to setjmp.
13 beq $5, $0, 1f
14 addu $3, $3, $25
15 sd $ra, 160($4)
16 sd $16, 168($4)
17
18 # save base of got so that we can use it later
19 # once we return from 'longjmp'
20 sd $3, 176($4)
21 lw $25, %got_disp(setjmp)($3)
22 jalr $25
23 move $16, $4
24
25 move $5, $2 # Return from 'setjmp' or 'longjmp'
26 move $4, $16 # Restore the pointer-to-sigjmp_buf
27 ld $ra, 160($4) # Restore ra of sigsetjmp
28 ld $16, 168($4) # Restore $16 of sigsetjmp
29 ld $3, 176($4) # Restore base of got
30
31.hidden __sigsetjmp_tail
32 lw $25, %got_disp(__sigsetjmp_tail)($3)
33 jr $25
34 nop
351:
36 lw $25, %got_disp(setjmp)($3)
37 jr $25
38 nop
libc/musl/src/signal/or1k/sigsetjmp.s created+24
......@@ -0,0 +1,24 @@
1.global sigsetjmp
2.global __sigsetjmp
3.type sigsetjmp,@function
4.type __sigsetjmp,@function
5sigsetjmp:
6__sigsetjmp:
7 l.sfeq r4, r0
8.hidden ___setjmp
9 l.bf ___setjmp
10
11 l.sw 52(r3), r9
12 l.sw 52+4+8(r3), r20
13
14 l.jal ___setjmp
15 l.ori r20, r3, 0
16
17 l.ori r4, r11, 0
18 l.ori r3, r20, 0
19
20 l.lwz r9, 52(r3)
21
22.hidden __sigsetjmp_tail
23 l.j __sigsetjmp_tail
24 l.lwz r20, 52+4+8(r3)
libc/musl/src/signal/powerpc/restore.s created+13
......@@ -0,0 +1,13 @@
1 .global __restore
2 .hidden __restore
3 .type __restore,%function
4__restore:
5 li 0, 119 #__NR_sigreturn
6 sc
7
8 .global __restore_rt
9 .hidden __restore_rt
10 .type __restore_rt,%function
11__restore_rt:
12 li 0, 172 # __NR_rt_sigreturn
13 sc
libc/musl/src/signal/powerpc/sigsetjmp.s created+27
......@@ -0,0 +1,27 @@
1 .global sigsetjmp
2 .global __sigsetjmp
3 .type sigsetjmp,%function
4 .type __sigsetjmp,%function
5sigsetjmp:
6__sigsetjmp:
7 cmpwi cr7, 4, 0
8 beq- cr7, 1f
9
10 mflr 5
11 stw 5, 448(3)
12 stw 16, 448+4+8(3)
13 mr 16, 3
14
15.hidden ___setjmp
16 bl ___setjmp
17
18 mr 4, 3
19 mr 3, 16
20 lwz 5, 448(3)
21 mtlr 5
22 lwz 16, 448+4+8(3)
23
24.hidden __sigsetjmp_tail
25 b __sigsetjmp_tail
26
271: b ___setjmp
libc/musl/src/signal/powerpc64/restore.s created+13
......@@ -0,0 +1,13 @@
1 .global __restore
2 .hidden __restore
3 .type __restore,%function
4__restore:
5 li 0, 119 #__NR_sigreturn
6 sc
7
8 .global __restore_rt
9 .hidden __restore_rt
10 .type __restore_rt,%function
11__restore_rt:
12 li 0, 172 # __NR_rt_sigreturn
13 sc
libc/musl/src/signal/powerpc64/sigsetjmp.s created+37
......@@ -0,0 +1,37 @@
1 .global sigsetjmp
2 .global __sigsetjmp
3 .type sigsetjmp,%function
4 .type __sigsetjmp,%function
5 .hidden __setjmp_toc
6sigsetjmp:
7__sigsetjmp:
8 addis 2, 12, .TOC.-__sigsetjmp@ha
9 addi 2, 2, .TOC.-__sigsetjmp@l
10 ld 5, 24(1) # load from the TOC slot in the caller's stack frame
11 b 1f
12
13 .localentry sigsetjmp,.-sigsetjmp
14 .localentry __sigsetjmp,.-__sigsetjmp
15 mr 5, 2
16
171:
18 cmpwi cr7, 4, 0
19 beq- cr7, __setjmp_toc
20
21 mflr 6
22 std 6, 512(3)
23 std 2, 512+16(3)
24 std 16, 512+24(3)
25 mr 16, 3
26
27 bl __setjmp_toc
28
29 mr 4, 3
30 mr 3, 16
31 ld 5, 512(3)
32 mtlr 5
33 ld 2, 512+16(3)
34 ld 16, 512+24(3)
35
36.hidden __sigsetjmp_tail
37 b __sigsetjmp_tail
libc/musl/src/signal/psiginfo.c created+6
......@@ -0,0 +1,6 @@
1#include <signal.h>
2
3void psiginfo(const siginfo_t *si, const char *msg)
4{
5 psignal(si->si_signo, msg);
6}
libc/musl/src/signal/psignal.c created+27
......@@ -0,0 +1,27 @@
1#include "stdio_impl.h"
2#include <string.h>
3#include <signal.h>
4#include <errno.h>
5
6void psignal(int sig, const char *msg)
7{
8 FILE *f = stderr;
9 char *s = strsignal(sig);
10
11 FLOCK(f);
12
13 /* Save stderr's orientation and encoding rule, since psignal is not
14 * permitted to change them. Save errno and restore it if there is no
15 * error since fprintf might change it even on success but psignal is
16 * not permitted to do so. */
17 void *old_locale = f->locale;
18 int old_mode = f->mode;
19 int old_errno = errno;
20
21 if (fprintf(f, "%s%s%s\n", msg?msg:"", msg?": ":"", s)>=0)
22 errno = old_errno;
23 f->mode = old_mode;
24 f->locale = old_locale;
25
26 FUNLOCK(f);
27}
libc/musl/src/signal/raise.c created+13
......@@ -0,0 +1,13 @@
1#include <signal.h>
2#include <stdint.h>
3#include "syscall.h"
4#include "pthread_impl.h"
5
6int raise(int sig)
7{
8 sigset_t set;
9 __block_app_sigs(&set);
10 int ret = syscall(SYS_tkill, __pthread_self()->tid, sig);
11 __restore_sigs(&set);
12 return ret;
13}
libc/musl/src/signal/restore.c created+12
......@@ -0,0 +1,12 @@
1#include <features.h>
2
3/* These functions will not work, but suffice for targets where the
4 * kernel sigaction structure does not actually use sa_restorer. */
5
6hidden void __restore()
7{
8}
9
10hidden void __restore_rt()
11{
12}
libc/musl/src/signal/s390x/restore.s created+11
......@@ -0,0 +1,11 @@
1 .global __restore
2 .hidden __restore
3 .type __restore,%function
4__restore:
5 svc 119 #__NR_sigreturn
6
7 .global __restore_rt
8 .hidden __restore_rt
9 .type __restore_rt,%function
10__restore_rt:
11 svc 173 # __NR_rt_sigreturn
libc/musl/src/signal/s390x/sigsetjmp.s created+23
......@@ -0,0 +1,23 @@
1 .global sigsetjmp
2 .global __sigsetjmp
3 .type sigsetjmp,%function
4 .type __sigsetjmp,%function
5 .hidden ___setjmp
6sigsetjmp:
7__sigsetjmp:
8 ltgr %r3, %r3
9 jz ___setjmp
10
11 stg %r14, 18*8(%r2)
12 stg %r6, 20*8(%r2)
13 lgr %r6, %r2
14
15 brasl %r14, ___setjmp
16
17 lgr %r3, %r2
18 lgr %r2, %r6
19 lg %r14, 18*8(%r2)
20 lg %r6, 20*8(%r2)
21
22.hidden __sigsetjmp_tail
23 jg __sigsetjmp_tail
libc/musl/src/signal/setitimer.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/time.h>
2#include "syscall.h"
3
4int setitimer(int which, const struct itimerval *restrict new, struct itimerval *restrict old)
5{
6 return syscall(SYS_setitimer, which, new, old);
7}
libc/musl/src/signal/sh/restore.s created+24
......@@ -0,0 +1,24 @@
1.global __restore
2.hidden __restore
3__restore:
4 mov #119, r3 !__NR_sigreturn
5 trapa #31
6
7 or r0, r0
8 or r0, r0
9 or r0, r0
10 or r0, r0
11 or r0, r0
12
13.global __restore_rt
14.hidden __restore_rt
15__restore_rt:
16 mov #100, r3 !__NR_rt_sigreturn
17 add #73, r3
18 trapa #31
19
20 or r0, r0
21 or r0, r0
22 or r0, r0
23 or r0, r0
24 or r0, r0
libc/musl/src/signal/sh/sigsetjmp.s created+41
......@@ -0,0 +1,41 @@
1.global sigsetjmp
2.global __sigsetjmp
3.type sigsetjmp,@function
4.type __sigsetjmp,@function
5sigsetjmp:
6__sigsetjmp:
7 tst r5, r5
8 bt 9f
9
10 mov r4, r6
11 add #60, r6
12 sts pr, r0
13 mov.l r0, @r6
14 mov.l r8, @(4+8,r6)
15
16 mov.l 1f, r0
172: bsrf r0
18 mov r4, r8
19
20 mov r0, r5
21 mov r8, r4
22 mov r4, r6
23 add #60, r6
24
25 mov.l @r6, r0
26 lds r0, pr
27
28 mov.l 3f, r0
294: braf r0
30 mov.l @(4+8,r4), r8
31
329: mov.l 5f, r0
336: braf r0
34 nop
35
36.align 2
37.hidden ___setjmp
381: .long ___setjmp@PLT-(2b+4-.)
39.hidden __sigsetjmp_tail
403: .long __sigsetjmp_tail@PLT-(4b+4-.)
415: .long ___setjmp@PLT-(6b+4-.)
libc/musl/src/signal/sigaction.c created+88
......@@ -0,0 +1,88 @@
1#include <signal.h>
2#include <errno.h>
3#include <string.h>
4#include "syscall.h"
5#include "pthread_impl.h"
6#include "libc.h"
7#include "lock.h"
8#include "ksigaction.h"
9
10volatile int dummy_lock[1] = { 0 };
11
12extern hidden volatile int __abort_lock[1];
13
14weak_alias(dummy_lock, __abort_lock);
15
16static int unmask_done;
17static unsigned long handler_set[_NSIG/(8*sizeof(long))];
18
19void __get_handler_set(sigset_t *set)
20{
21 memcpy(set, handler_set, sizeof handler_set);
22}
23
24volatile int __eintr_valid_flag;
25
26int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
27{
28 struct k_sigaction ksa, ksa_old;
29 unsigned long set[_NSIG/(8*sizeof(long))];
30 if (sa) {
31 if ((uintptr_t)sa->sa_handler > 1UL) {
32 a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
33 1UL<<(sig-1)%(8*sizeof(long)));
34
35 /* If pthread_create has not yet been called,
36 * implementation-internal signals might not
37 * yet have been unblocked. They must be
38 * unblocked before any signal handler is
39 * installed, so that an application cannot
40 * receive an illegal sigset_t (with them
41 * blocked) as part of the ucontext_t passed
42 * to the signal handler. */
43 if (!libc.threaded && !unmask_done) {
44 __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
45 SIGPT_SET, 0, _NSIG/8);
46 unmask_done = 1;
47 }
48
49 if (!(sa->sa_flags & SA_RESTART)) {
50 a_store(&__eintr_valid_flag, 1);
51 }
52 }
53 /* Changing the disposition of SIGABRT to anything but
54 * SIG_DFL requires a lock, so that it cannot be changed
55 * while abort is terminating the process after simply
56 * calling raise(SIGABRT) failed to do so. */
57 if (sa->sa_handler != SIG_DFL && sig == SIGABRT) {
58 __block_all_sigs(&set);
59 LOCK(__abort_lock);
60 }
61 ksa.handler = sa->sa_handler;
62 ksa.flags = sa->sa_flags | SA_RESTORER;
63 ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
64 memcpy(&ksa.mask, &sa->sa_mask, _NSIG/8);
65 }
66 int r = __syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, _NSIG/8);
67 if (sig == SIGABRT && sa && sa->sa_handler != SIG_DFL) {
68 UNLOCK(__abort_lock);
69 __restore_sigs(&set);
70 }
71 if (old && !r) {
72 old->sa_handler = ksa_old.handler;
73 old->sa_flags = ksa_old.flags;
74 memcpy(&old->sa_mask, &ksa_old.mask, _NSIG/8);
75 }
76 return __syscall_ret(r);
77}
78
79int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
80{
81 if (sig-32U < 3 || sig-1U >= _NSIG-1) {
82 errno = EINVAL;
83 return -1;
84 }
85 return __libc_sigaction(sig, sa, old);
86}
87
88weak_alias(__sigaction, sigaction);
libc/musl/src/signal/sigaddset.c created+13
......@@ -0,0 +1,13 @@
1#include <signal.h>
2#include <errno.h>
3
4int sigaddset(sigset_t *set, int sig)
5{
6 unsigned s = sig-1;
7 if (s >= _NSIG-1 || sig-32U < 3) {
8 errno = EINVAL;
9 return -1;
10 }
11 set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
12 return 0;
13}
libc/musl/src/signal/sigaltstack.c created+18
......@@ -0,0 +1,18 @@
1#include <signal.h>
2#include <errno.h>
3#include "syscall.h"
4
5int sigaltstack(const stack_t *restrict ss, stack_t *restrict old)
6{
7 if (ss) {
8 if (ss->ss_size < MINSIGSTKSZ) {
9 errno = ENOMEM;
10 return -1;
11 }
12 if (ss->ss_flags & ~SS_DISABLE) {
13 errno = EINVAL;
14 return -1;
15 }
16 }
17 return syscall(SYS_sigaltstack, ss, old);
18}
libc/musl/src/signal/sigandset.c created+12
......@@ -0,0 +1,12 @@
1#define _GNU_SOURCE
2#include <signal.h>
3
4#define SST_SIZE (_NSIG/8/sizeof(long))
5
6int sigandset(sigset_t *dest, const sigset_t *left, const sigset_t *right)
7{
8 unsigned long i = 0, *d = (void*) dest, *l = (void*) left, *r = (void*) right;
9 for(; i < SST_SIZE; i++) d[i] = l[i] & r[i];
10 return 0;
11}
12
libc/musl/src/signal/sigdelset.c created+13
......@@ -0,0 +1,13 @@
1#include <signal.h>
2#include <errno.h>
3
4int sigdelset(sigset_t *set, int sig)
5{
6 unsigned s = sig-1;
7 if (s >= _NSIG-1 || sig-32U < 3) {
8 errno = EINVAL;
9 return -1;
10 }
11 set->__bits[s/8/sizeof *set->__bits] &=~(1UL<<(s&8*sizeof *set->__bits-1));
12 return 0;
13}
libc/musl/src/signal/sigemptyset.c created+13
......@@ -0,0 +1,13 @@
1#include <signal.h>
2#include <string.h>
3
4int sigemptyset(sigset_t *set)
5{
6 set->__bits[0] = 0;
7 if (sizeof(long)==4 || _NSIG > 65) set->__bits[1] = 0;
8 if (sizeof(long)==4 && _NSIG > 65) {
9 set->__bits[2] = 0;
10 set->__bits[3] = 0;
11 }
12 return 0;
13}
libc/musl/src/signal/sigfillset.c created+18
......@@ -0,0 +1,18 @@
1#include <signal.h>
2#include <limits.h>
3
4int sigfillset(sigset_t *set)
5{
6#if ULONG_MAX == 0xffffffff
7 set->__bits[0] = 0x7ffffffful;
8 set->__bits[1] = 0xfffffffcul;
9 if (_NSIG > 65) {
10 set->__bits[2] = 0xfffffffful;
11 set->__bits[3] = 0xfffffffful;
12 }
13#else
14 set->__bits[0] = 0xfffffffc7ffffffful;
15 if (_NSIG > 65) set->__bits[1] = 0xfffffffffffffffful;
16#endif
17 return 0;
18}
libc/musl/src/signal/sighold.c created+10
......@@ -0,0 +1,10 @@
1#include <signal.h>
2
3int sighold(int sig)
4{
5 sigset_t mask;
6
7 sigemptyset(&mask);
8 if (sigaddset(&mask, sig) < 0) return -1;
9 return sigprocmask(SIG_BLOCK, &mask, 0);
10}
libc/musl/src/signal/sigignore.c created+11
......@@ -0,0 +1,11 @@
1#include <signal.h>
2
3int sigignore(int sig)
4{
5 struct sigaction sa;
6
7 sigemptyset(&sa.sa_mask);
8 sa.sa_handler = SIG_IGN;
9 sa.sa_flags = 0;
10 return sigaction(sig, &sa, 0);
11}
libc/musl/src/signal/siginterrupt.c created+12
......@@ -0,0 +1,12 @@
1#include <signal.h>
2
3int siginterrupt(int sig, int flag)
4{
5 struct sigaction sa;
6
7 sigaction(sig, 0, &sa);
8 if (flag) sa.sa_flags &= ~SA_RESTART;
9 else sa.sa_flags |= SA_RESTART;
10
11 return sigaction(sig, &sa, 0);
12}
libc/musl/src/signal/sigisemptyset.c created+10
......@@ -0,0 +1,10 @@
1#define _GNU_SOURCE
2#include <signal.h>
3#include <string.h>
4
5int sigisemptyset(const sigset_t *set)
6{
7 for (size_t i=0; i<_NSIG/8/sizeof *set->__bits; i++)
8 if (set->__bits[i]) return 0;
9 return 1;
10}
libc/musl/src/signal/sigismember.c created+8
......@@ -0,0 +1,8 @@
1#include <signal.h>
2
3int sigismember(const sigset_t *set, int sig)
4{
5 unsigned s = sig-1;
6 if (s >= _NSIG-1) return 0;
7 return !!(set->__bits[s/8/sizeof *set->__bits] & 1UL<<(s&8*sizeof *set->__bits-1));
8}
libc/musl/src/signal/siglongjmp.c created+9
......@@ -0,0 +1,9 @@
1#include <setjmp.h>
2#include <signal.h>
3#include "syscall.h"
4#include "pthread_impl.h"
5
6_Noreturn void siglongjmp(sigjmp_buf buf, int ret)
7{
8 longjmp(buf, ret);
9}
libc/musl/src/signal/signal.c created+13
......@@ -0,0 +1,13 @@
1#include <signal.h>
2#include "syscall.h"
3
4void (*signal(int sig, void (*func)(int)))(int)
5{
6 struct sigaction sa_old, sa = { .sa_handler = func, .sa_flags = SA_RESTART };
7 if (__sigaction(sig, &sa, &sa_old) < 0)
8 return SIG_ERR;
9 return sa_old.sa_handler;
10}
11
12weak_alias(signal, bsd_signal);
13weak_alias(signal, __sysv_signal);
libc/musl/src/signal/sigorset.c created+12
......@@ -0,0 +1,12 @@
1#define _GNU_SOURCE
2#include <signal.h>
3
4#define SST_SIZE (_NSIG/8/sizeof(long))
5
6int sigorset(sigset_t *dest, const sigset_t *left, const sigset_t *right)
7{
8 unsigned long i = 0, *d = (void*) dest, *l = (void*) left, *r = (void*) right;
9 for(; i < SST_SIZE; i++) d[i] = l[i] | r[i];
10 return 0;
11}
12
libc/musl/src/signal/sigpause.c created+9
......@@ -0,0 +1,9 @@
1#include <signal.h>
2
3int sigpause(int sig)
4{
5 sigset_t mask;
6 sigprocmask(0, 0, &mask);
7 sigdelset(&mask, sig);
8 return sigsuspend(&mask);
9}
libc/musl/src/signal/sigpending.c created+7
......@@ -0,0 +1,7 @@
1#include <signal.h>
2#include "syscall.h"
3
4int sigpending(sigset_t *set)
5{
6 return syscall(SYS_rt_sigpending, set, _NSIG/8);
7}
libc/musl/src/signal/sigprocmask.c created+10
......@@ -0,0 +1,10 @@
1#include <signal.h>
2#include <errno.h>
3
4int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
5{
6 int r = pthread_sigmask(how, set, old);
7 if (!r) return r;
8 errno = r;
9 return -1;
10}
libc/musl/src/signal/sigqueue.c created+22
......@@ -0,0 +1,22 @@
1#include <signal.h>
2#include <string.h>
3#include <unistd.h>
4#include "syscall.h"
5#include "pthread_impl.h"
6
7int sigqueue(pid_t pid, int sig, const union sigval value)
8{
9 siginfo_t si;
10 sigset_t set;
11 int r;
12 memset(&si, 0, sizeof si);
13 si.si_signo = sig;
14 si.si_code = SI_QUEUE;
15 si.si_value = value;
16 si.si_uid = getuid();
17 __block_app_sigs(&set);
18 si.si_pid = getpid();
19 r = syscall(SYS_rt_sigqueueinfo, pid, sig, &si);
20 __restore_sigs(&set);
21 return r;
22}
libc/musl/src/signal/sigrelse.c created+10
......@@ -0,0 +1,10 @@
1#include <signal.h>
2
3int sigrelse(int sig)
4{
5 sigset_t mask;
6
7 sigemptyset(&mask);
8 if (sigaddset(&mask, sig) < 0) return -1;
9 return sigprocmask(SIG_UNBLOCK, &mask, 0);
10}
libc/musl/src/signal/sigrtmax.c created+6
......@@ -0,0 +1,6 @@
1#include <signal.h>
2
3int __libc_current_sigrtmax()
4{
5 return _NSIG-1;
6}
libc/musl/src/signal/sigrtmin.c created+6
......@@ -0,0 +1,6 @@
1#include <signal.h>
2
3int __libc_current_sigrtmin()
4{
5 return 35;
6}
libc/musl/src/signal/sigset.c created+27
......@@ -0,0 +1,27 @@
1#include <signal.h>
2
3void (*sigset(int sig, void (*handler)(int)))(int)
4{
5 struct sigaction sa, sa_old;
6 sigset_t mask;
7
8 sigemptyset(&mask);
9 if (sigaddset(&mask, sig) < 0)
10 return SIG_ERR;
11
12 if (handler == SIG_HOLD) {
13 if (sigaction(sig, 0, &sa_old) < 0)
14 return SIG_ERR;
15 if (sigprocmask(SIG_BLOCK, &mask, &mask) < 0)
16 return SIG_ERR;
17 } else {
18 sa.sa_handler = handler;
19 sa.sa_flags = 0;
20 sigemptyset(&sa.sa_mask);
21 if (sigaction(sig, &sa, &sa_old) < 0)
22 return SIG_ERR;
23 if (sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0)
24 return SIG_ERR;
25 }
26 return sigismember(&mask, sig) ? SIG_HOLD : sa_old.sa_handler;
27}
libc/musl/src/signal/sigsetjmp.c created
libc/musl/src/signal/sigsetjmp_tail.c created+10
......@@ -0,0 +1,10 @@
1#include <setjmp.h>
2#include <signal.h>
3#include "syscall.h"
4
5hidden int __sigsetjmp_tail(sigjmp_buf jb, int ret)
6{
7 void *p = jb->__ss;
8 __syscall(SYS_rt_sigprocmask, SIG_SETMASK, ret?p:0, ret?0:p, _NSIG/8);
9 return ret;
10}
libc/musl/src/signal/sigsuspend.c created+7
......@@ -0,0 +1,7 @@
1#include <signal.h>
2#include "syscall.h"
3
4int sigsuspend(const sigset_t *mask)
5{
6 return syscall_cp(SYS_rt_sigsuspend, mask, _NSIG/8);
7}
libc/musl/src/signal/sigtimedwait.c created+12
......@@ -0,0 +1,12 @@
1#include <signal.h>
2#include <errno.h>
3#include "syscall.h"
4
5int sigtimedwait(const sigset_t *restrict mask, siginfo_t *restrict si, const struct timespec *restrict timeout)
6{
7 int ret;
8 do ret = syscall_cp(SYS_rt_sigtimedwait, mask,
9 si, timeout, _NSIG/8);
10 while (ret<0 && errno==EINTR);
11 return ret;
12}
libc/musl/src/signal/sigwait.c created+10
......@@ -0,0 +1,10 @@
1#include <signal.h>
2
3int sigwait(const sigset_t *restrict mask, int *restrict sig)
4{
5 siginfo_t si;
6 if (sigtimedwait(mask, &si, 0) < 0)
7 return -1;
8 *sig = si.si_signo;
9 return 0;
10}
libc/musl/src/signal/sigwaitinfo.c created+6
......@@ -0,0 +1,6 @@
1#include <signal.h>
2
3int sigwaitinfo(const sigset_t *restrict mask, siginfo_t *restrict si)
4{
5 return sigtimedwait(mask, si, 0);
6}
libc/musl/src/signal/x32/restore.s created+8
......@@ -0,0 +1,8 @@
1 nop
2.global __restore_rt
3.hidden __restore_rt
4.type __restore_rt,@function
5__restore_rt:
6 mov $0x40000201, %rax /* SYS_rt_sigreturn */
7 syscall
8.size __restore_rt,.-__restore_rt
libc/musl/src/signal/x32/sigsetjmp.s created+25
......@@ -0,0 +1,25 @@
1.global sigsetjmp
2.global __sigsetjmp
3.type sigsetjmp,@function
4.type __sigsetjmp,@function
5sigsetjmp:
6__sigsetjmp:
7 test %esi,%esi
8 jz 1f
9
10 popq 64(%rdi)
11 mov %rbx,72+8(%rdi)
12 mov %rdi,%rbx
13
14 call setjmp@PLT
15
16 pushq 64(%rbx)
17 movl $0, 4(%rsp)
18 mov %rbx,%rdi
19 mov %eax,%esi
20 mov 72+8(%rbx),%rbx
21
22.hidden __sigsetjmp_tail
23 jmp __sigsetjmp_tail
24
251: jmp setjmp@PLT
libc/musl/src/signal/x86_64/restore.s created+8
......@@ -0,0 +1,8 @@
1 nop
2.global __restore_rt
3.hidden __restore_rt
4.type __restore_rt,@function
5__restore_rt:
6 mov $15, %rax
7 syscall
8.size __restore_rt,.-__restore_rt
libc/musl/src/signal/x86_64/sigsetjmp.s created+24
......@@ -0,0 +1,24 @@
1.global sigsetjmp
2.global __sigsetjmp
3.type sigsetjmp,@function
4.type __sigsetjmp,@function
5sigsetjmp:
6__sigsetjmp:
7 test %esi,%esi
8 jz 1f
9
10 popq 64(%rdi)
11 mov %rbx,72+8(%rdi)
12 mov %rdi,%rbx
13
14 call setjmp@PLT
15
16 pushq 64(%rbx)
17 mov %rbx,%rdi
18 mov %eax,%esi
19 mov 72+8(%rbx),%rbx
20
21.hidden __sigsetjmp_tail
22 jmp __sigsetjmp_tail
23
241: jmp setjmp@PLT
libc/musl/src/stat/__xstat.c created+36
......@@ -0,0 +1,36 @@
1#include <sys/stat.h>
2
3int __fxstat(int ver, int fd, struct stat *buf)
4{
5 return fstat(fd, buf);
6}
7
8int __fxstatat(int ver, int fd, const char *path, struct stat *buf, int flag)
9{
10 return fstatat(fd, path, buf, flag);
11}
12
13int __lxstat(int ver, const char *path, struct stat *buf)
14{
15 return lstat(path, buf);
16}
17
18int __xstat(int ver, const char *path, struct stat *buf)
19{
20 return stat(path, buf);
21}
22
23weak_alias(__fxstat, __fxstat64);
24weak_alias(__fxstatat, __fxstatat64);
25weak_alias(__lxstat, __lxstat64);
26weak_alias(__xstat, __xstat64);
27
28int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev)
29{
30 return mknod(path, mode, *dev);
31}
32
33int __xmknodat(int ver, int fd, const char *path, mode_t mode, dev_t *dev)
34{
35 return mknodat(fd, path, mode, *dev);
36}
libc/musl/src/stat/chmod.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/stat.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int chmod(const char *path, mode_t mode)
6{
7#ifdef SYS_chmod
8 return syscall(SYS_chmod, path, mode);
9#else
10 return syscall(SYS_fchmodat, AT_FDCWD, path, mode);
11#endif
12}
libc/musl/src/stat/fchmod.c created+19
......@@ -0,0 +1,19 @@
1#include <sys/stat.h>
2#include <errno.h>
3#include <fcntl.h>
4#include "syscall.h"
5
6int fchmod(int fd, mode_t mode)
7{
8 int ret = __syscall(SYS_fchmod, fd, mode);
9 if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
10 return __syscall_ret(ret);
11
12 char buf[15+3*sizeof(int)];
13 __procfdname(buf, fd);
14#ifdef SYS_chmod
15 return syscall(SYS_chmod, buf, mode);
16#else
17 return syscall(SYS_fchmodat, AT_FDCWD, buf, mode);
18#endif
19}
libc/musl/src/stat/fchmodat.c created+37
......@@ -0,0 +1,37 @@
1#include <sys/stat.h>
2#include <fcntl.h>
3#include <errno.h>
4#include "syscall.h"
5
6int fchmodat(int fd, const char *path, mode_t mode, int flag)
7{
8 if (!flag) return syscall(SYS_fchmodat, fd, path, mode, flag);
9
10 if (flag != AT_SYMLINK_NOFOLLOW)
11 return __syscall_ret(-EINVAL);
12
13 struct stat st;
14 int ret, fd2;
15 char proc[15+3*sizeof(int)];
16
17 if ((ret = __syscall(SYS_fstatat, fd, path, &st, flag)))
18 return __syscall_ret(ret);
19 if (S_ISLNK(st.st_mode))
20 return __syscall_ret(-EOPNOTSUPP);
21
22 if ((fd2 = __syscall(SYS_openat, fd, path, O_RDONLY|O_PATH|O_NOFOLLOW|O_NOCTTY|O_CLOEXEC)) < 0) {
23 if (fd2 == -ELOOP)
24 return __syscall_ret(-EOPNOTSUPP);
25 return __syscall_ret(fd2);
26 }
27
28 __procfdname(proc, fd2);
29 ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0);
30 if (!ret) {
31 if (S_ISLNK(st.st_mode)) ret = -EOPNOTSUPP;
32 else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
33 }
34
35 __syscall(SYS_close, fd2);
36 return __syscall_ret(ret);
37}
libc/musl/src/stat/fstat.c created+21
......@@ -0,0 +1,21 @@
1#include <sys/stat.h>
2#include <errno.h>
3#include <fcntl.h>
4#include "syscall.h"
5
6int fstat(int fd, struct stat *st)
7{
8 int ret = __syscall(SYS_fstat, fd, st);
9 if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
10 return __syscall_ret(ret);
11
12 char buf[15+3*sizeof(int)];
13 __procfdname(buf, fd);
14#ifdef SYS_stat
15 return syscall(SYS_stat, buf, st);
16#else
17 return syscall(SYS_fstatat, AT_FDCWD, buf, st, 0);
18#endif
19}
20
21weak_alias(fstat, fstat64);
libc/musl/src/stat/fstatat.c created+9
......@@ -0,0 +1,9 @@
1#include <sys/stat.h>
2#include "syscall.h"
3
4int fstatat(int fd, const char *restrict path, struct stat *restrict buf, int flag)
5{
6 return syscall(SYS_fstatat, fd, path, buf, flag);
7}
8
9weak_alias(fstatat, fstatat64);
libc/musl/src/stat/futimens.c created+6
......@@ -0,0 +1,6 @@
1#include <sys/stat.h>
2
3int futimens(int fd, const struct timespec times[2])
4{
5 return utimensat(fd, 0, times, 0);
6}
libc/musl/src/stat/futimesat.c created+22
......@@ -0,0 +1,22 @@
1#define _GNU_SOURCE
2#include <sys/time.h>
3#include <sys/stat.h>
4#include <errno.h>
5#include "syscall.h"
6
7int __futimesat(int dirfd, const char *pathname, const struct timeval times[2])
8{
9 struct timespec ts[2];
10 if (times) {
11 int i;
12 for (i=0; i<2; i++) {
13 if (times[i].tv_usec >= 1000000ULL)
14 return __syscall_ret(-EINVAL);
15 ts[i].tv_sec = times[i].tv_sec;
16 ts[i].tv_nsec = times[i].tv_usec * 1000;
17 }
18 }
19 return utimensat(dirfd, pathname, times ? ts : 0, 0);
20}
21
22weak_alias(__futimesat, futimesat);
libc/musl/src/stat/lchmod.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <sys/stat.h>
3#include <fcntl.h>
4
5int lchmod(const char *path, mode_t mode)
6{
7 return fchmodat(AT_FDCWD, path, mode, AT_SYMLINK_NOFOLLOW);
8}
libc/musl/src/stat/lstat.c created+14
......@@ -0,0 +1,14 @@
1#include <sys/stat.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int lstat(const char *restrict path, struct stat *restrict buf)
6{
7#ifdef SYS_lstat
8 return syscall(SYS_lstat, path, buf);
9#else
10 return syscall(SYS_fstatat, AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
11#endif
12}
13
14weak_alias(lstat, lstat64);
libc/musl/src/stat/mkdir.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/stat.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int mkdir(const char *path, mode_t mode)
6{
7#ifdef SYS_mkdir
8 return syscall(SYS_mkdir, path, mode);
9#else
10 return syscall(SYS_mkdirat, AT_FDCWD, path, mode);
11#endif
12}
libc/musl/src/stat/mkdirat.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/stat.h>
2#include "syscall.h"
3
4int mkdirat(int fd, const char *path, mode_t mode)
5{
6 return syscall(SYS_mkdirat, fd, path, mode);
7}
libc/musl/src/stat/mkfifo.c created+6
......@@ -0,0 +1,6 @@
1#include <sys/stat.h>
2
3int mkfifo(const char *path, mode_t mode)
4{
5 return mknod(path, mode | S_IFIFO, 0);
6}
libc/musl/src/stat/mkfifoat.c created+6
......@@ -0,0 +1,6 @@
1#include <sys/stat.h>
2
3int mkfifoat(int fd, const char *path, mode_t mode)
4{
5 return mknodat(fd, path, mode | S_IFIFO, 0);
6}
libc/musl/src/stat/mknod.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/stat.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int mknod(const char *path, mode_t mode, dev_t dev)
6{
7#ifdef SYS_mknod
8 return syscall(SYS_mknod, path, mode, dev);
9#else
10 return syscall(SYS_mknodat, AT_FDCWD, path, mode, dev);
11#endif
12}
libc/musl/src/stat/mknodat.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/stat.h>
2#include "syscall.h"
3
4int mknodat(int fd, const char *path, mode_t mode, dev_t dev)
5{
6 return syscall(SYS_mknodat, fd, path, mode, dev);
7}
libc/musl/src/stat/stat.c created+14
......@@ -0,0 +1,14 @@
1#include <sys/stat.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int stat(const char *restrict path, struct stat *restrict buf)
6{
7#ifdef SYS_stat
8 return syscall(SYS_stat, path, buf);
9#else
10 return syscall(SYS_fstatat, AT_FDCWD, path, buf, 0);
11#endif
12}
13
14weak_alias(stat, stat64);
libc/musl/src/stat/statvfs.c created+63
......@@ -0,0 +1,63 @@
1#include <sys/statvfs.h>
2#include <sys/statfs.h>
3#include "syscall.h"
4
5static int __statfs(const char *path, struct statfs *buf)
6{
7 *buf = (struct statfs){0};
8#ifdef SYS_statfs64
9 return syscall(SYS_statfs64, path, sizeof *buf, buf);
10#else
11 return syscall(SYS_statfs, path, buf);
12#endif
13}
14
15static int __fstatfs(int fd, struct statfs *buf)
16{
17 *buf = (struct statfs){0};
18#ifdef SYS_fstatfs64
19 return syscall(SYS_fstatfs64, fd, sizeof *buf, buf);
20#else
21 return syscall(SYS_fstatfs, fd, buf);
22#endif
23}
24
25weak_alias(__statfs, statfs);
26weak_alias(__fstatfs, fstatfs);
27
28static void fixup(struct statvfs *out, const struct statfs *in)
29{
30 *out = (struct statvfs){0};
31 out->f_bsize = in->f_bsize;
32 out->f_frsize = in->f_frsize ? in->f_frsize : in->f_bsize;
33 out->f_blocks = in->f_blocks;
34 out->f_bfree = in->f_bfree;
35 out->f_bavail = in->f_bavail;
36 out->f_files = in->f_files;
37 out->f_ffree = in->f_ffree;
38 out->f_favail = in->f_ffree;
39 out->f_fsid = in->f_fsid.__val[0];
40 out->f_flag = in->f_flags;
41 out->f_namemax = in->f_namelen;
42}
43
44int statvfs(const char *restrict path, struct statvfs *restrict buf)
45{
46 struct statfs kbuf;
47 if (__statfs(path, &kbuf)<0) return -1;
48 fixup(buf, &kbuf);
49 return 0;
50}
51
52int fstatvfs(int fd, struct statvfs *buf)
53{
54 struct statfs kbuf;
55 if (__fstatfs(fd, &kbuf)<0) return -1;
56 fixup(buf, &kbuf);
57 return 0;
58}
59
60weak_alias(statvfs, statvfs64);
61weak_alias(statfs, statfs64);
62weak_alias(fstatvfs, fstatvfs64);
63weak_alias(fstatfs, fstatfs64);
libc/musl/src/stat/umask.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/stat.h>
2#include "syscall.h"
3
4mode_t umask(mode_t mode)
5{
6 return syscall(SYS_umask, mode);
7}
libc/musl/src/stat/utimensat.c created+37
......@@ -0,0 +1,37 @@
1#include <sys/stat.h>
2#include <sys/time.h>
3#include <fcntl.h>
4#include <errno.h>
5#include "syscall.h"
6
7int utimensat(int fd, const char *path, const struct timespec times[2], int flags)
8{
9 int r = __syscall(SYS_utimensat, fd, path, times, flags);
10#ifdef SYS_futimesat
11 if (r != -ENOSYS || flags) return __syscall_ret(r);
12 struct timeval *tv = 0, tmp[2];
13 if (times) {
14 int i;
15 tv = tmp;
16 for (i=0; i<2; i++) {
17 if (times[i].tv_nsec >= 1000000000ULL) {
18 if (times[i].tv_nsec == UTIME_NOW &&
19 times[1-i].tv_nsec == UTIME_NOW) {
20 tv = 0;
21 break;
22 }
23 if (times[i].tv_nsec == UTIME_OMIT)
24 return __syscall_ret(-ENOSYS);
25 return __syscall_ret(-EINVAL);
26 }
27 tmp[i].tv_sec = times[i].tv_sec;
28 tmp[i].tv_usec = times[i].tv_nsec / 1000;
29 }
30 }
31
32 r = __syscall(SYS_futimesat, fd, path, tv);
33 if (r != -ENOSYS || fd != AT_FDCWD) return __syscall_ret(r);
34 r = __syscall(SYS_utimes, path, tv);
35#endif
36 return __syscall_ret(r);
37}
libc/musl/src/stdio/__fclose_ca.c created+6
......@@ -0,0 +1,6 @@
1#include "stdio_impl.h"
2
3int __fclose_ca(FILE *f)
4{
5 return f->close(f);
6}
libc/musl/src/stdio/__fdopen.c created+61
......@@ -0,0 +1,61 @@
1#include "stdio_impl.h"
2#include <stdlib.h>
3#include <sys/ioctl.h>
4#include <fcntl.h>
5#include <errno.h>
6#include <string.h>
7#include "libc.h"
8
9FILE *__fdopen(int fd, const char *mode)
10{
11 FILE *f;
12 struct winsize wsz;
13
14 /* Check for valid initial mode character */
15 if (!strchr("rwa", *mode)) {
16 errno = EINVAL;
17 return 0;
18 }
19
20 /* Allocate FILE+buffer or fail */
21 if (!(f=malloc(sizeof *f + UNGET + BUFSIZ))) return 0;
22
23 /* Zero-fill only the struct, not the buffer */
24 memset(f, 0, sizeof *f);
25
26 /* Impose mode restrictions */
27 if (!strchr(mode, '+')) f->flags = (*mode == 'r') ? F_NOWR : F_NORD;
28
29 /* Apply close-on-exec flag */
30 if (strchr(mode, 'e')) __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
31
32 /* Set append mode on fd if opened for append */
33 if (*mode == 'a') {
34 int flags = __syscall(SYS_fcntl, fd, F_GETFL);
35 if (!(flags & O_APPEND))
36 __syscall(SYS_fcntl, fd, F_SETFL, flags | O_APPEND);
37 f->flags |= F_APP;
38 }
39
40 f->fd = fd;
41 f->buf = (unsigned char *)f + sizeof *f + UNGET;
42 f->buf_size = BUFSIZ;
43
44 /* Activate line buffered mode for terminals */
45 f->lbf = EOF;
46 if (!(f->flags & F_NOWR) && !__syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz))
47 f->lbf = '\n';
48
49 /* Initialize op ptrs. No problem if some are unneeded. */
50 f->read = __stdio_read;
51 f->write = __stdio_write;
52 f->seek = __stdio_seek;
53 f->close = __stdio_close;
54
55 if (!libc.threaded) f->lock = -1;
56
57 /* Add new FILE to open file list */
58 return __ofl_add(f);
59}
60
61weak_alias(__fdopen, fdopen);
libc/musl/src/stdio/__fmodeflags.c created+16
......@@ -0,0 +1,16 @@
1#include <fcntl.h>
2#include <string.h>
3
4int __fmodeflags(const char *mode)
5{
6 int flags;
7 if (strchr(mode, '+')) flags = O_RDWR;
8 else if (*mode == 'r') flags = O_RDONLY;
9 else flags = O_WRONLY;
10 if (strchr(mode, 'x')) flags |= O_EXCL;
11 if (strchr(mode, 'e')) flags |= O_CLOEXEC;
12 if (*mode != 'r') flags |= O_CREAT;
13 if (*mode == 'w') flags |= O_TRUNC;
14 if (*mode == 'a') flags |= O_APPEND;
15 return flags;
16}
libc/musl/src/stdio/__fopen_rb_ca.c created+22
......@@ -0,0 +1,22 @@
1#include "stdio_impl.h"
2#include <fcntl.h>
3#include <string.h>
4
5FILE *__fopen_rb_ca(const char *filename, FILE *f, unsigned char *buf, size_t len)
6{
7 memset(f, 0, sizeof *f);
8
9 f->fd = sys_open(filename, O_RDONLY|O_CLOEXEC);
10 if (f->fd < 0) return 0;
11 __syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
12
13 f->flags = F_NOWR | F_PERM;
14 f->buf = buf + UNGET;
15 f->buf_size = len - UNGET;
16 f->read = __stdio_read;
17 f->seek = __stdio_seek;
18 f->close = __stdio_close;
19 f->lock = -1;
20
21 return f;
22}
libc/musl/src/stdio/__lockfile.c created+23
......@@ -0,0 +1,23 @@
1#include "stdio_impl.h"
2#include "pthread_impl.h"
3
4int __lockfile(FILE *f)
5{
6 int owner = f->lock, tid = __pthread_self()->tid;
7 if ((owner & ~MAYBE_WAITERS) == tid)
8 return 0;
9 owner = a_cas(&f->lock, 0, tid);
10 if (!owner) return 1;
11 while ((owner = a_cas(&f->lock, 0, tid|MAYBE_WAITERS))) {
12 if ((owner & MAYBE_WAITERS) ||
13 a_cas(&f->lock, owner, owner|MAYBE_WAITERS)==owner)
14 __futexwait(&f->lock, owner|MAYBE_WAITERS, 1);
15 }
16 return 1;
17}
18
19void __unlockfile(FILE *f)
20{
21 if (a_swap(&f->lock, 0) & MAYBE_WAITERS)
22 __wake(&f->lock, 1, 1);
23}
libc/musl/src/stdio/__overflow.c created+10
......@@ -0,0 +1,10 @@
1#include "stdio_impl.h"
2
3int __overflow(FILE *f, int _c)
4{
5 unsigned char c = _c;
6 if (!f->wend && __towrite(f)) return EOF;
7 if (f->wpos != f->wend && c != f->lbf) return *f->wpos++ = c;
8 if (f->write(f, &c, 1)!=1) return EOF;
9 return c;
10}
libc/musl/src/stdio/__stdio_close.c created+13
......@@ -0,0 +1,13 @@
1#include "stdio_impl.h"
2
3static int dummy(int fd)
4{
5 return fd;
6}
7
8weak_alias(dummy, __aio_close);
9
10int __stdio_close(FILE *f)
11{
12 return syscall(SYS_close, __aio_close(f->fd));
13}
libc/musl/src/stdio/__stdio_exit.c created+25
......@@ -0,0 +1,25 @@
1#include "stdio_impl.h"
2
3static FILE *volatile dummy_file = 0;
4weak_alias(dummy_file, __stdin_used);
5weak_alias(dummy_file, __stdout_used);
6weak_alias(dummy_file, __stderr_used);
7
8static void close_file(FILE *f)
9{
10 if (!f) return;
11 FFINALLOCK(f);
12 if (f->wpos != f->wbase) f->write(f, 0, 0);
13 if (f->rpos != f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);
14}
15
16void __stdio_exit(void)
17{
18 FILE *f;
19 for (f=*__ofl_lock(); f; f=f->next) close_file(f);
20 close_file(__stdin_used);
21 close_file(__stdout_used);
22 close_file(__stderr_used);
23}
24
25weak_alias(__stdio_exit, __stdio_exit_needed);
libc/musl/src/stdio/__stdio_read.c created+24
......@@ -0,0 +1,24 @@
1#include "stdio_impl.h"
2#include <sys/uio.h>
3
4size_t __stdio_read(FILE *f, unsigned char *buf, size_t len)
5{
6 struct iovec iov[2] = {
7 { .iov_base = buf, .iov_len = len - !!f->buf_size },
8 { .iov_base = f->buf, .iov_len = f->buf_size }
9 };
10 ssize_t cnt;
11
12 cnt = iov[0].iov_len ? syscall(SYS_readv, f->fd, iov, 2)
13 : syscall(SYS_read, f->fd, iov[1].iov_base, iov[1].iov_len);
14 if (cnt <= 0) {
15 f->flags |= cnt ? F_ERR : F_EOF;
16 return 0;
17 }
18 if (cnt <= iov[0].iov_len) return cnt;
19 cnt -= iov[0].iov_len;
20 f->rpos = f->buf;
21 f->rend = f->buf + cnt;
22 if (f->buf_size) buf[len-1] = *f->rpos++;
23 return len;
24}
libc/musl/src/stdio/__stdio_seek.c created+13
......@@ -0,0 +1,13 @@
1#include "stdio_impl.h"
2
3off_t __stdio_seek(FILE *f, off_t off, int whence)
4{
5 off_t ret;
6#ifdef SYS__llseek
7 if (syscall(SYS__llseek, f->fd, off>>32, off, &ret, whence)<0)
8 ret = -1;
9#else
10 ret = syscall(SYS_lseek, f->fd, off, whence);
11#endif
12 return ret;
13}
libc/musl/src/stdio/__stdio_write.c created+34
......@@ -0,0 +1,34 @@
1#include "stdio_impl.h"
2#include <sys/uio.h>
3
4size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
5{
6 struct iovec iovs[2] = {
7 { .iov_base = f->wbase, .iov_len = f->wpos-f->wbase },
8 { .iov_base = (void *)buf, .iov_len = len }
9 };
10 struct iovec *iov = iovs;
11 size_t rem = iov[0].iov_len + iov[1].iov_len;
12 int iovcnt = 2;
13 ssize_t cnt;
14 for (;;) {
15 cnt = syscall(SYS_writev, f->fd, iov, iovcnt);
16 if (cnt == rem) {
17 f->wend = f->buf + f->buf_size;
18 f->wpos = f->wbase = f->buf;
19 return len;
20 }
21 if (cnt < 0) {
22 f->wpos = f->wbase = f->wend = 0;
23 f->flags |= F_ERR;
24 return iovcnt == 2 ? 0 : len-iov[0].iov_len;
25 }
26 rem -= cnt;
27 if (cnt > iov[0].iov_len) {
28 cnt -= iov[0].iov_len;
29 iov++; iovcnt--;
30 }
31 iov[0].iov_base = (char *)iov[0].iov_base + cnt;
32 iov[0].iov_len -= cnt;
33 }
34}
libc/musl/src/stdio/__stdout_write.c created+11
......@@ -0,0 +1,11 @@
1#include "stdio_impl.h"
2#include <sys/ioctl.h>
3
4size_t __stdout_write(FILE *f, const unsigned char *buf, size_t len)
5{
6 struct winsize wsz;
7 f->write = __stdio_write;
8 if (!(f->flags & F_SVB) && __syscall(SYS_ioctl, f->fd, TIOCGWINSZ, &wsz))
9 f->lbf = -1;
10 return __stdio_write(f, buf, len);
11}
libc/musl/src/stdio/__string_read.c created+16
......@@ -0,0 +1,16 @@
1#include "stdio_impl.h"
2#include <string.h>
3
4size_t __string_read(FILE *f, unsigned char *buf, size_t len)
5{
6 char *src = f->cookie;
7 size_t k = len+256;
8 char *end = memchr(src, 0, k);
9 if (end) k = end-src;
10 if (k < len) len = k;
11 memcpy(buf, src, len);
12 f->rpos = (void *)(src+len);
13 f->rend = (void *)(src+k);
14 f->cookie = src+k;
15 return len;
16}
libc/musl/src/stdio/__toread.c created+19
......@@ -0,0 +1,19 @@
1#include <stdio_impl.h>
2
3int __toread(FILE *f)
4{
5 f->mode |= f->mode-1;
6 if (f->wpos != f->wbase) f->write(f, 0, 0);
7 f->wpos = f->wbase = f->wend = 0;
8 if (f->flags & F_NORD) {
9 f->flags |= F_ERR;
10 return EOF;
11 }
12 f->rpos = f->rend = f->buf + f->buf_size;
13 return (f->flags & F_EOF) ? EOF : 0;
14}
15
16hidden void __toread_needs_stdio_exit()
17{
18 __stdio_exit_needed();
19}
libc/musl/src/stdio/__towrite.c created+23
......@@ -0,0 +1,23 @@
1#include "stdio_impl.h"
2
3int __towrite(FILE *f)
4{
5 f->mode |= f->mode-1;
6 if (f->flags & F_NOWR) {
7 f->flags |= F_ERR;
8 return EOF;
9 }
10 /* Clear read buffer (easier than summoning nasal demons) */
11 f->rpos = f->rend = 0;
12
13 /* Activate write through the buffer. */
14 f->wpos = f->wbase = f->buf;
15 f->wend = f->buf + f->buf_size;
16
17 return 0;
18}
19
20hidden void __towrite_needs_stdio_exit()
21{
22 __stdio_exit_needed();
23}
libc/musl/src/stdio/__uflow.c created+11
......@@ -0,0 +1,11 @@
1#include "stdio_impl.h"
2
3/* This function assumes it will never be called if there is already
4 * data buffered for reading. */
5
6int __uflow(FILE *f)
7{
8 unsigned char c;
9 if (!__toread(f) && f->read(f, &c, 1)==1) return c;
10 return EOF;
11}
libc/musl/src/stdio/asprintf.c created+13
......@@ -0,0 +1,13 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3#include <stdarg.h>
4
5int asprintf(char **s, const char *fmt, ...)
6{
7 int ret;
8 va_list ap;
9 va_start(ap, fmt);
10 ret = vasprintf(s, fmt, ap);
11 va_end(ap);
12 return ret;
13}
libc/musl/src/stdio/clearerr.c created+10
......@@ -0,0 +1,10 @@
1#include "stdio_impl.h"
2
3void clearerr(FILE *f)
4{
5 FLOCK(f);
6 f->flags &= ~(F_EOF|F_ERR);
7 FUNLOCK(f);
8}
9
10weak_alias(clearerr, clearerr_unlocked);
libc/musl/src/stdio/dprintf.c created+12
......@@ -0,0 +1,12 @@
1#include <stdio.h>
2#include <stdarg.h>
3
4int dprintf(int fd, const char *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vdprintf(fd, fmt, ap);
10 va_end(ap);
11 return ret;
12}
libc/musl/src/stdio/ext.c created+57
......@@ -0,0 +1,57 @@
1#define _GNU_SOURCE
2#include "stdio_impl.h"
3#include <stdio_ext.h>
4
5void _flushlbf(void)
6{
7 fflush(0);
8}
9
10int __fsetlocking(FILE *f, int type)
11{
12 return 0;
13}
14
15int __fwriting(FILE *f)
16{
17 return (f->flags & F_NORD) || f->wend;
18}
19
20int __freading(FILE *f)
21{
22 return (f->flags & F_NOWR) || f->rend;
23}
24
25int __freadable(FILE *f)
26{
27 return !(f->flags & F_NORD);
28}
29
30int __fwritable(FILE *f)
31{
32 return !(f->flags & F_NOWR);
33}
34
35int __flbf(FILE *f)
36{
37 return f->lbf >= 0;
38}
39
40size_t __fbufsize(FILE *f)
41{
42 return f->buf_size;
43}
44
45size_t __fpending(FILE *f)
46{
47 return f->wend ? f->wpos - f->wbase : 0;
48}
49
50int __fpurge(FILE *f)
51{
52 f->wpos = f->wbase = f->wend = 0;
53 f->rpos = f->rend = 0;
54 return 0;
55}
56
57weak_alias(__fpurge, fpurge);
libc/musl/src/stdio/ext2.c created+24
......@@ -0,0 +1,24 @@
1#include "stdio_impl.h"
2#include <stdio_ext.h>
3
4size_t __freadahead(FILE *f)
5{
6 return f->rend ? f->rend - f->rpos : 0;
7}
8
9const char *__freadptr(FILE *f, size_t *sizep)
10{
11 if (f->rpos == f->rend) return 0;
12 *sizep = f->rend - f->rpos;
13 return (const char *)f->rpos;
14}
15
16void __freadptrinc(FILE *f, size_t inc)
17{
18 f->rpos += inc;
19}
20
21void __fseterr(FILE *f)
22{
23 f->flags |= F_ERR;
24}
libc/musl/src/stdio/fclose.c created+38
......@@ -0,0 +1,38 @@
1#include "stdio_impl.h"
2#include <stdlib.h>
3
4static void dummy(FILE *f) { }
5weak_alias(dummy, __unlist_locked_file);
6
7int fclose(FILE *f)
8{
9 int r;
10
11 FLOCK(f);
12 r = fflush(f);
13 r |= f->close(f);
14 FUNLOCK(f);
15
16 /* Past this point, f is closed and any further explict access
17 * to it is undefined. However, it still exists as an entry in
18 * the open file list and possibly in the thread's locked files
19 * list, if it was closed while explicitly locked. Functions
20 * which process these lists must tolerate dead FILE objects
21 * (which necessarily have inactive buffer pointers) without
22 * producing any side effects. */
23
24 if (f->flags & F_PERM) return r;
25
26 __unlist_locked_file(f);
27
28 FILE **head = __ofl_lock();
29 if (f->prev) f->prev->next = f->next;
30 if (f->next) f->next->prev = f->prev;
31 if (*head == f) *head = f->next;
32 __ofl_unlock();
33
34 free(f->getln_buf);
35 free(f);
36
37 return r;
38}
libc/musl/src/stdio/feof.c created+14
......@@ -0,0 +1,14 @@
1#include "stdio_impl.h"
2
3#undef feof
4
5int feof(FILE *f)
6{
7 FLOCK(f);
8 int ret = !!(f->flags & F_EOF);
9 FUNLOCK(f);
10 return ret;
11}
12
13weak_alias(feof, feof_unlocked);
14weak_alias(feof, _IO_feof_unlocked);
libc/musl/src/stdio/ferror.c created+14
......@@ -0,0 +1,14 @@
1#include "stdio_impl.h"
2
3#undef ferror
4
5int ferror(FILE *f)
6{
7 FLOCK(f);
8 int ret = !!(f->flags & F_ERR);
9 FUNLOCK(f);
10 return ret;
11}
12
13weak_alias(ferror, ferror_unlocked);
14weak_alias(ferror, _IO_ferror_unlocked);
libc/musl/src/stdio/fflush.c created+47
......@@ -0,0 +1,47 @@
1#include "stdio_impl.h"
2
3/* stdout.c will override this if linked */
4static FILE *volatile dummy = 0;
5weak_alias(dummy, __stdout_used);
6weak_alias(dummy, __stderr_used);
7
8int fflush(FILE *f)
9{
10 if (!f) {
11 int r = 0;
12 if (__stdout_used) r |= fflush(__stdout_used);
13 if (__stderr_used) r |= fflush(__stderr_used);
14
15 for (f=*__ofl_lock(); f; f=f->next) {
16 FLOCK(f);
17 if (f->wpos != f->wbase) r |= fflush(f);
18 FUNLOCK(f);
19 }
20 __ofl_unlock();
21
22 return r;
23 }
24
25 FLOCK(f);
26
27 /* If writing, flush output */
28 if (f->wpos != f->wbase) {
29 f->write(f, 0, 0);
30 if (!f->wpos) {
31 FUNLOCK(f);
32 return EOF;
33 }
34 }
35
36 /* If reading, sync position, per POSIX */
37 if (f->rpos != f->rend) f->seek(f, f->rpos-f->rend, SEEK_CUR);
38
39 /* Clear read and write modes */
40 f->wpos = f->wbase = f->wend = 0;
41 f->rpos = f->rend = 0;
42
43 FUNLOCK(f);
44 return 0;
45}
46
47weak_alias(fflush, fflush_unlocked);
libc/musl/src/stdio/fgetc.c created+7
......@@ -0,0 +1,7 @@
1#include <stdio.h>
2#include "getc.h"
3
4int fgetc(FILE *f)
5{
6 return do_getc(f);
7}
libc/musl/src/stdio/fgetln.c created+21
......@@ -0,0 +1,21 @@
1#define _GNU_SOURCE
2#include "stdio_impl.h"
3#include <string.h>
4
5char *fgetln(FILE *f, size_t *plen)
6{
7 char *ret = 0, *z;
8 ssize_t l;
9 FLOCK(f);
10 ungetc(getc_unlocked(f), f);
11 if (f->rend && (z=memchr(f->rpos, '\n', f->rend - f->rpos))) {
12 ret = (char *)f->rpos;
13 *plen = ++z - ret;
14 f->rpos = (void *)z;
15 } else if ((l = getline(&f->getln_buf, (size_t[]){0}, f)) > 0) {
16 *plen = l;
17 ret = f->getln_buf;
18 }
19 FUNLOCK(f);
20 return ret;
21}
libc/musl/src/stdio/fgetpos.c created+11
......@@ -0,0 +1,11 @@
1#include "stdio_impl.h"
2
3int fgetpos(FILE *restrict f, fpos_t *restrict pos)
4{
5 off_t off = __ftello(f);
6 if (off < 0) return -1;
7 *(long long *)pos = off;
8 return 0;
9}
10
11weak_alias(fgetpos, fgetpos64);
libc/musl/src/stdio/fgets.c created+48
......@@ -0,0 +1,48 @@
1#include "stdio_impl.h"
2#include <string.h>
3
4#define MIN(a,b) ((a)<(b) ? (a) : (b))
5
6char *fgets(char *restrict s, int n, FILE *restrict f)
7{
8 char *p = s;
9 unsigned char *z;
10 size_t k;
11 int c;
12
13 FLOCK(f);
14
15 if (n--<=1) {
16 f->mode |= f->mode-1;
17 FUNLOCK(f);
18 if (n) return 0;
19 *s = 0;
20 return s;
21 }
22
23 while (n) {
24 if (f->rpos != f->rend) {
25 z = memchr(f->rpos, '\n', f->rend - f->rpos);
26 k = z ? z - f->rpos + 1 : f->rend - f->rpos;
27 k = MIN(k, n);
28 memcpy(p, f->rpos, k);
29 f->rpos += k;
30 p += k;
31 n -= k;
32 if (z || !n) break;
33 }
34 if ((c = getc_unlocked(f)) < 0) {
35 if (p==s || !feof(f)) s = 0;
36 break;
37 }
38 n--;
39 if ((*p++ = c) == '\n') break;
40 }
41 if (s) *p = 0;
42
43 FUNLOCK(f);
44
45 return s;
46}
47
48weak_alias(fgets, fgets_unlocked);
libc/musl/src/stdio/fgetwc.c created+62
......@@ -0,0 +1,62 @@
1#include "stdio_impl.h"
2#include "locale_impl.h"
3#include <wchar.h>
4#include <errno.h>
5
6static wint_t __fgetwc_unlocked_internal(FILE *f)
7{
8 wchar_t wc;
9 int c;
10 size_t l;
11
12 /* Convert character from buffer if possible */
13 if (f->rpos != f->rend) {
14 l = mbtowc(&wc, (void *)f->rpos, f->rend - f->rpos);
15 if (l+1 >= 1) {
16 f->rpos += l + !l; /* l==0 means 1 byte, null */
17 return wc;
18 }
19 }
20
21 /* Convert character byte-by-byte */
22 mbstate_t st = { 0 };
23 unsigned char b;
24 int first = 1;
25 do {
26 b = c = getc_unlocked(f);
27 if (c < 0) {
28 if (!first) errno = EILSEQ;
29 return WEOF;
30 }
31 l = mbrtowc(&wc, (void *)&b, 1, &st);
32 if (l == -1) {
33 if (!first) ungetc(b, f);
34 return WEOF;
35 }
36 first = 0;
37 } while (l == -2);
38
39 return wc;
40}
41
42wint_t __fgetwc_unlocked(FILE *f)
43{
44 locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
45 if (f->mode <= 0) fwide(f, 1);
46 *ploc = f->locale;
47 wchar_t wc = __fgetwc_unlocked_internal(f);
48 *ploc = loc;
49 return wc;
50}
51
52wint_t fgetwc(FILE *f)
53{
54 wint_t c;
55 FLOCK(f);
56 c = __fgetwc_unlocked(f);
57 FUNLOCK(f);
58 return c;
59}
60
61weak_alias(__fgetwc_unlocked, fgetwc_unlocked);
62weak_alias(__fgetwc_unlocked, getwc_unlocked);
libc/musl/src/stdio/fgetws.c created+33
......@@ -0,0 +1,33 @@
1#include "stdio_impl.h"
2#include <wchar.h>
3#include <errno.h>
4
5wint_t __fgetwc_unlocked(FILE *);
6
7wchar_t *fgetws(wchar_t *restrict s, int n, FILE *restrict f)
8{
9 wchar_t *p = s;
10
11 if (!n--) return s;
12
13 FLOCK(f);
14
15 /* Setup a dummy errno so we can detect EILSEQ. This is
16 * the only way to catch encoding errors in the form of a
17 * partial character just before EOF. */
18 errno = EAGAIN;
19 for (; n; n--) {
20 wint_t c = __fgetwc_unlocked(f);
21 if (c == WEOF) break;
22 *p++ = c;
23 if (c == '\n') break;
24 }
25 *p = 0;
26 if (ferror(f) || errno==EILSEQ) p = s;
27
28 FUNLOCK(f);
29
30 return (p == s) ? NULL : s;
31}
32
33weak_alias(fgetws, fgetws_unlocked);
libc/musl/src/stdio/fileno.c created+16
......@@ -0,0 +1,16 @@
1#include "stdio_impl.h"
2#include <errno.h>
3
4int fileno(FILE *f)
5{
6 FLOCK(f);
7 int fd = f->fd;
8 FUNLOCK(f);
9 if (fd < 0) {
10 errno = EBADF;
11 return -1;
12 }
13 return fd;
14}
15
16weak_alias(fileno, fileno_unlocked);
libc/musl/src/stdio/flockfile.c created+9
......@@ -0,0 +1,9 @@
1#include "stdio_impl.h"
2#include "pthread_impl.h"
3
4void flockfile(FILE *f)
5{
6 if (!ftrylockfile(f)) return;
7 __lockfile(f);
8 __register_locked_file(f, __pthread_self());
9}
libc/musl/src/stdio/fmemopen.c created+127
......@@ -0,0 +1,127 @@
1#include "stdio_impl.h"
2#include <errno.h>
3#include <string.h>
4#include <stdlib.h>
5#include <inttypes.h>
6#include "libc.h"
7
8struct cookie {
9 size_t pos, len, size;
10 unsigned char *buf;
11 int mode;
12};
13
14struct mem_FILE {
15 FILE f;
16 struct cookie c;
17 unsigned char buf[UNGET+BUFSIZ], buf2[];
18};
19
20static off_t mseek(FILE *f, off_t off, int whence)
21{
22 ssize_t base;
23 struct cookie *c = f->cookie;
24 if (whence>2U) {
25fail:
26 errno = EINVAL;
27 return -1;
28 }
29 base = (size_t [3]){0, c->pos, c->len}[whence];
30 if (off < -base || off > (ssize_t)c->size-base) goto fail;
31 return c->pos = base+off;
32}
33
34static size_t mread(FILE *f, unsigned char *buf, size_t len)
35{
36 struct cookie *c = f->cookie;
37 size_t rem = c->len - c->pos;
38 if (c->pos > c->len) rem = 0;
39 if (len > rem) {
40 len = rem;
41 f->flags |= F_EOF;
42 }
43 memcpy(buf, c->buf+c->pos, len);
44 c->pos += len;
45 rem -= len;
46 if (rem > f->buf_size) rem = f->buf_size;
47 f->rpos = f->buf;
48 f->rend = f->buf + rem;
49 memcpy(f->rpos, c->buf+c->pos, rem);
50 c->pos += rem;
51 return len;
52}
53
54static size_t mwrite(FILE *f, const unsigned char *buf, size_t len)
55{
56 struct cookie *c = f->cookie;
57 size_t rem;
58 size_t len2 = f->wpos - f->wbase;
59 if (len2) {
60 f->wpos = f->wbase;
61 if (mwrite(f, f->wpos, len2) < len2) return 0;
62 }
63 if (c->mode == 'a') c->pos = c->len;
64 rem = c->size - c->pos;
65 if (len > rem) len = rem;
66 memcpy(c->buf+c->pos, buf, len);
67 c->pos += len;
68 if (c->pos > c->len) {
69 c->len = c->pos;
70 if (c->len < c->size) c->buf[c->len] = 0;
71 else if ((f->flags&F_NORD) && c->size) c->buf[c->size-1] = 0;
72 }
73 return len;
74}
75
76static int mclose(FILE *m)
77{
78 return 0;
79}
80
81FILE *fmemopen(void *restrict buf, size_t size, const char *restrict mode)
82{
83 struct mem_FILE *f;
84 int plus = !!strchr(mode, '+');
85
86 if (!size || !strchr("rwa", *mode)) {
87 errno = EINVAL;
88 return 0;
89 }
90
91 if (!buf && size > PTRDIFF_MAX) {
92 errno = ENOMEM;
93 return 0;
94 }
95
96 f = malloc(sizeof *f + (buf?0:size));
97 if (!f) return 0;
98 memset(&f->f, 0, sizeof f->f);
99 f->f.cookie = &f->c;
100 f->f.fd = -1;
101 f->f.lbf = EOF;
102 f->f.buf = f->buf + UNGET;
103 f->f.buf_size = sizeof f->buf - UNGET;
104 if (!buf) {
105 buf = f->buf2;;
106 memset(buf, 0, size);
107 }
108
109 memset(&f->c, 0, sizeof f->c);
110 f->c.buf = buf;
111 f->c.size = size;
112 f->c.mode = *mode;
113
114 if (!plus) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD;
115 if (*mode == 'r') f->c.len = size;
116 else if (*mode == 'a') f->c.len = f->c.pos = strnlen(buf, size);
117 else if (plus) *f->c.buf = 0;
118
119 f->f.read = mread;
120 f->f.write = mwrite;
121 f->f.seek = mseek;
122 f->f.close = mclose;
123
124 if (!libc.threaded) f->f.lock = -1;
125
126 return __ofl_add(&f->f);
127}
libc/musl/src/stdio/fopen.c created+33
......@@ -0,0 +1,33 @@
1#include "stdio_impl.h"
2#include <fcntl.h>
3#include <string.h>
4#include <errno.h>
5
6FILE *fopen(const char *restrict filename, const char *restrict mode)
7{
8 FILE *f;
9 int fd;
10 int flags;
11
12 /* Check for valid initial mode character */
13 if (!strchr("rwa", *mode)) {
14 errno = EINVAL;
15 return 0;
16 }
17
18 /* Compute the flags to pass to open() */
19 flags = __fmodeflags(mode);
20
21 fd = sys_open(filename, flags, 0666);
22 if (fd < 0) return 0;
23 if (flags & O_CLOEXEC)
24 __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
25
26 f = __fdopen(fd, mode);
27 if (f) return f;
28
29 __syscall(SYS_close, fd);
30 return 0;
31}
32
33weak_alias(fopen, fopen64);
libc/musl/src/stdio/fopencookie.c created+135
......@@ -0,0 +1,135 @@
1#define _GNU_SOURCE
2#include "stdio_impl.h"
3#include <stdlib.h>
4#include <sys/ioctl.h>
5#include <fcntl.h>
6#include <errno.h>
7#include <string.h>
8
9struct fcookie {
10 void *cookie;
11 cookie_io_functions_t iofuncs;
12};
13
14struct cookie_FILE {
15 FILE f;
16 struct fcookie fc;
17 unsigned char buf[UNGET+BUFSIZ];
18};
19
20static size_t cookieread(FILE *f, unsigned char *buf, size_t len)
21{
22 struct fcookie *fc = f->cookie;
23 ssize_t ret = -1;
24 size_t remain = len, readlen = 0;
25 size_t len2 = len - !!f->buf_size;
26
27 if (!fc->iofuncs.read) goto bail;
28
29 if (len2) {
30 ret = fc->iofuncs.read(fc->cookie, (char *) buf, len2);
31 if (ret <= 0) goto bail;
32
33 readlen += ret;
34 remain -= ret;
35 }
36
37 if (!f->buf_size || remain > !!f->buf_size) return readlen;
38
39 f->rpos = f->buf;
40 ret = fc->iofuncs.read(fc->cookie, (char *) f->rpos, f->buf_size);
41 if (ret <= 0) goto bail;
42 f->rend = f->rpos + ret;
43
44 buf[readlen++] = *f->rpos++;
45
46 return readlen;
47
48bail:
49 f->flags |= ret == 0 ? F_EOF : F_ERR;
50 f->rpos = f->rend = f->buf;
51 return readlen;
52}
53
54static size_t cookiewrite(FILE *f, const unsigned char *buf, size_t len)
55{
56 struct fcookie *fc = f->cookie;
57 ssize_t ret;
58 size_t len2 = f->wpos - f->wbase;
59 if (!fc->iofuncs.write) return len;
60 if (len2) {
61 f->wpos = f->wbase;
62 if (cookiewrite(f, f->wpos, len2) < len2) return 0;
63 }
64 ret = fc->iofuncs.write(fc->cookie, (const char *) buf, len);
65 if (ret < 0) {
66 f->wpos = f->wbase = f->wend = 0;
67 f->flags |= F_ERR;
68 return 0;
69 }
70 return ret;
71}
72
73static off_t cookieseek(FILE *f, off_t off, int whence)
74{
75 struct fcookie *fc = f->cookie;
76 int res;
77 if (whence > 2U) {
78 errno = EINVAL;
79 return -1;
80 }
81 if (!fc->iofuncs.seek) {
82 errno = ENOTSUP;
83 return -1;
84 }
85 res = fc->iofuncs.seek(fc->cookie, &off, whence);
86 if (res < 0)
87 return res;
88 return off;
89}
90
91static int cookieclose(FILE *f)
92{
93 struct fcookie *fc = f->cookie;
94 if (fc->iofuncs.close) return fc->iofuncs.close(fc->cookie);
95 return 0;
96}
97
98FILE *fopencookie(void *cookie, const char *mode, cookie_io_functions_t iofuncs)
99{
100 struct cookie_FILE *f;
101
102 /* Check for valid initial mode character */
103 if (!strchr("rwa", *mode)) {
104 errno = EINVAL;
105 return 0;
106 }
107
108 /* Allocate FILE+fcookie+buffer or fail */
109 if (!(f=malloc(sizeof *f))) return 0;
110
111 /* Zero-fill only the struct, not the buffer */
112 memset(&f->f, 0, sizeof f->f);
113
114 /* Impose mode restrictions */
115 if (!strchr(mode, '+')) f->f.flags = (*mode == 'r') ? F_NOWR : F_NORD;
116
117 /* Set up our fcookie */
118 f->fc.cookie = cookie;
119 f->fc.iofuncs = iofuncs;
120
121 f->f.fd = -1;
122 f->f.cookie = &f->fc;
123 f->f.buf = f->buf + UNGET;
124 f->f.buf_size = sizeof f->buf - UNGET;
125 f->f.lbf = EOF;
126
127 /* Initialize op ptrs. No problem if some are unneeded. */
128 f->f.read = cookieread;
129 f->f.write = cookiewrite;
130 f->f.seek = cookieseek;
131 f->f.close = cookieclose;
132
133 /* Add new FILE to open file list */
134 return __ofl_add(&f->f);
135}
libc/musl/src/stdio/fprintf.c created+12
......@@ -0,0 +1,12 @@
1#include <stdio.h>
2#include <stdarg.h>
3
4int fprintf(FILE *restrict f, const char *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vfprintf(f, fmt, ap);
10 va_end(ap);
11 return ret;
12}
libc/musl/src/stdio/fputc.c created+7
......@@ -0,0 +1,7 @@
1#include <stdio.h>
2#include "putc.h"
3
4int fputc(int c, FILE *f)
5{
6 return do_putc(c, f);
7}
libc/musl/src/stdio/fputs.c created+10
......@@ -0,0 +1,10 @@
1#include "stdio_impl.h"
2#include <string.h>
3
4int fputs(const char *restrict s, FILE *restrict f)
5{
6 size_t l = strlen(s);
7 return (fwrite(s, 1, l, f)==l) - 1;
8}
9
10weak_alias(fputs, fputs_unlocked);
libc/musl/src/stdio/fputwc.c created+40
......@@ -0,0 +1,40 @@
1#include "stdio_impl.h"
2#include "locale_impl.h"
3#include <wchar.h>
4#include <limits.h>
5#include <ctype.h>
6
7wint_t __fputwc_unlocked(wchar_t c, FILE *f)
8{
9 char mbc[MB_LEN_MAX];
10 int l;
11 locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
12
13 if (f->mode <= 0) fwide(f, 1);
14 *ploc = f->locale;
15
16 if (isascii(c)) {
17 c = putc_unlocked(c, f);
18 } else if (f->wpos + MB_LEN_MAX < f->wend) {
19 l = wctomb((void *)f->wpos, c);
20 if (l < 0) c = WEOF;
21 else f->wpos += l;
22 } else {
23 l = wctomb(mbc, c);
24 if (l < 0 || __fwritex((void *)mbc, l, f) < l) c = WEOF;
25 }
26 if (c==WEOF) f->flags |= F_ERR;
27 *ploc = loc;
28 return c;
29}
30
31wint_t fputwc(wchar_t c, FILE *f)
32{
33 FLOCK(f);
34 c = __fputwc_unlocked(c, f);
35 FUNLOCK(f);
36 return c;
37}
38
39weak_alias(__fputwc_unlocked, fputwc_unlocked);
40weak_alias(__fputwc_unlocked, putwc_unlocked);
libc/musl/src/stdio/fputws.c created+29
......@@ -0,0 +1,29 @@
1#include "stdio_impl.h"
2#include "locale_impl.h"
3#include <wchar.h>
4
5int fputws(const wchar_t *restrict ws, FILE *restrict f)
6{
7 unsigned char buf[BUFSIZ];
8 size_t l=0;
9 locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
10
11 FLOCK(f);
12
13 fwide(f, 1);
14 *ploc = f->locale;
15
16 while (ws && (l = wcsrtombs((void *)buf, (void*)&ws, sizeof buf, 0))+1 > 1)
17 if (__fwritex(buf, l, f) < l) {
18 FUNLOCK(f);
19 *ploc = loc;
20 return -1;
21 }
22
23 FUNLOCK(f);
24
25 *ploc = loc;
26 return l; /* 0 or -1 */
27}
28
29weak_alias(fputws, fputws_unlocked);
libc/musl/src/stdio/fread.c created+38
......@@ -0,0 +1,38 @@
1#include "stdio_impl.h"
2#include <string.h>
3
4#define MIN(a,b) ((a)<(b) ? (a) : (b))
5
6size_t fread(void *restrict destv, size_t size, size_t nmemb, FILE *restrict f)
7{
8 unsigned char *dest = destv;
9 size_t len = size*nmemb, l = len, k;
10 if (!size) nmemb = 0;
11
12 FLOCK(f);
13
14 f->mode |= f->mode-1;
15
16 if (f->rpos != f->rend) {
17 /* First exhaust the buffer. */
18 k = MIN(f->rend - f->rpos, l);
19 memcpy(dest, f->rpos, k);
20 f->rpos += k;
21 dest += k;
22 l -= k;
23 }
24
25 /* Read the remainder directly */
26 for (; l; l-=k, dest+=k) {
27 k = __toread(f) ? 0 : f->read(f, dest, l);
28 if (!k) {
29 FUNLOCK(f);
30 return (len-l)/size;
31 }
32 }
33
34 FUNLOCK(f);
35 return nmemb;
36}
37
38weak_alias(fread, fread_unlocked);
libc/musl/src/stdio/freopen.c created+53
......@@ -0,0 +1,53 @@
1#include "stdio_impl.h"
2#include <fcntl.h>
3#include <unistd.h>
4
5/* The basic idea of this implementation is to open a new FILE,
6 * hack the necessary parts of the new FILE into the old one, then
7 * close the new FILE. */
8
9/* Locking IS necessary because another thread may provably hold the
10 * lock, via flockfile or otherwise, when freopen is called, and in that
11 * case, freopen cannot act until the lock is released. */
12
13FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *restrict f)
14{
15 int fl = __fmodeflags(mode);
16 FILE *f2;
17
18 FLOCK(f);
19
20 fflush(f);
21
22 if (!filename) {
23 if (fl&O_CLOEXEC)
24 __syscall(SYS_fcntl, f->fd, F_SETFD, FD_CLOEXEC);
25 fl &= ~(O_CREAT|O_EXCL|O_CLOEXEC);
26 if (syscall(SYS_fcntl, f->fd, F_SETFL, fl) < 0)
27 goto fail;
28 } else {
29 f2 = fopen(filename, mode);
30 if (!f2) goto fail;
31 if (f2->fd == f->fd) f2->fd = -1; /* avoid closing in fclose */
32 else if (__dup3(f2->fd, f->fd, fl&O_CLOEXEC)<0) goto fail2;
33
34 f->flags = (f->flags & F_PERM) | f2->flags;
35 f->read = f2->read;
36 f->write = f2->write;
37 f->seek = f2->seek;
38 f->close = f2->close;
39
40 fclose(f2);
41 }
42
43 FUNLOCK(f);
44 return f;
45
46fail2:
47 fclose(f2);
48fail:
49 fclose(f);
50 return NULL;
51}
52
53weak_alias(freopen, freopen64);
libc/musl/src/stdio/fscanf.c created+14
......@@ -0,0 +1,14 @@
1#include <stdio.h>
2#include <stdarg.h>
3
4int fscanf(FILE *restrict f, const char *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vfscanf(f, fmt, ap);
10 va_end(ap);
11 return ret;
12}
13
14weak_alias(fscanf, __isoc99_fscanf);
libc/musl/src/stdio/fseek.c created+43
......@@ -0,0 +1,43 @@
1#include "stdio_impl.h"
2
3int __fseeko_unlocked(FILE *f, off_t off, int whence)
4{
5 /* Adjust relative offset for unread data in buffer, if any. */
6 if (whence == SEEK_CUR && f->rend) off -= f->rend - f->rpos;
7
8 /* Flush write buffer, and report error on failure. */
9 if (f->wpos != f->wbase) {
10 f->write(f, 0, 0);
11 if (!f->wpos) return -1;
12 }
13
14 /* Leave writing mode */
15 f->wpos = f->wbase = f->wend = 0;
16
17 /* Perform the underlying seek. */
18 if (f->seek(f, off, whence) < 0) return -1;
19
20 /* If seek succeeded, file is seekable and we discard read buffer. */
21 f->rpos = f->rend = 0;
22 f->flags &= ~F_EOF;
23
24 return 0;
25}
26
27int __fseeko(FILE *f, off_t off, int whence)
28{
29 int result;
30 FLOCK(f);
31 result = __fseeko_unlocked(f, off, whence);
32 FUNLOCK(f);
33 return result;
34}
35
36int fseek(FILE *f, long off, int whence)
37{
38 return __fseeko(f, off, whence);
39}
40
41weak_alias(__fseeko, fseeko);
42
43weak_alias(fseeko, fseeko64);
libc/musl/src/stdio/fsetpos.c created+8
......@@ -0,0 +1,8 @@
1#include "stdio_impl.h"
2
3int fsetpos(FILE *f, const fpos_t *pos)
4{
5 return __fseeko(f, *(const long long *)pos, SEEK_SET);
6}
7
8weak_alias(fsetpos, fsetpos64);
libc/musl/src/stdio/ftell.c created+41
......@@ -0,0 +1,41 @@
1#include "stdio_impl.h"
2#include <limits.h>
3#include <errno.h>
4
5off_t __ftello_unlocked(FILE *f)
6{
7 off_t pos = f->seek(f, 0,
8 (f->flags & F_APP) && f->wpos != f->wbase
9 ? SEEK_END : SEEK_CUR);
10 if (pos < 0) return pos;
11
12 /* Adjust for data in buffer. */
13 if (f->rend)
14 pos += f->rpos - f->rend;
15 else if (f->wbase)
16 pos += f->wpos - f->wbase;
17 return pos;
18}
19
20off_t __ftello(FILE *f)
21{
22 off_t pos;
23 FLOCK(f);
24 pos = __ftello_unlocked(f);
25 FUNLOCK(f);
26 return pos;
27}
28
29long ftell(FILE *f)
30{
31 off_t pos = __ftello(f);
32 if (pos > LONG_MAX) {
33 errno = EOVERFLOW;
34 return -1;
35 }
36 return pos;
37}
38
39weak_alias(__ftello, ftello);
40
41weak_alias(ftello, ftello64);
libc/musl/src/stdio/ftrylockfile.c created+46
......@@ -0,0 +1,46 @@
1#include "stdio_impl.h"
2#include "pthread_impl.h"
3#include <limits.h>
4
5void __do_orphaned_stdio_locks()
6{
7 FILE *f;
8 for (f=__pthread_self()->stdio_locks; f; f=f->next_locked)
9 a_store(&f->lock, 0x40000000);
10}
11
12void __unlist_locked_file(FILE *f)
13{
14 if (f->lockcount) {
15 if (f->next_locked) f->next_locked->prev_locked = f->prev_locked;
16 if (f->prev_locked) f->prev_locked->next_locked = f->next_locked;
17 else __pthread_self()->stdio_locks = f->next_locked;
18 }
19}
20
21void __register_locked_file(FILE *f, pthread_t self)
22{
23 f->lockcount = 1;
24 f->prev_locked = 0;
25 f->next_locked = self->stdio_locks;
26 if (f->next_locked) f->next_locked->prev_locked = f;
27 self->stdio_locks = f;
28}
29
30int ftrylockfile(FILE *f)
31{
32 pthread_t self = __pthread_self();
33 int tid = self->tid;
34 int owner = f->lock;
35 if ((owner & ~MAYBE_WAITERS) == tid) {
36 if (f->lockcount == LONG_MAX)
37 return -1;
38 f->lockcount++;
39 return 0;
40 }
41 if (owner < 0) f->lock = owner = 0;
42 if (owner || a_cas(&f->lock, 0, tid))
43 return -1;
44 __register_locked_file(f, self);
45 return 0;
46}
libc/musl/src/stdio/funlockfile.c created+13
......@@ -0,0 +1,13 @@
1#include "stdio_impl.h"
2#include "pthread_impl.h"
3
4void funlockfile(FILE *f)
5{
6 if (f->lockcount == 1) {
7 __unlist_locked_file(f);
8 f->lockcount = 0;
9 __unlockfile(f);
10 } else {
11 f->lockcount--;
12 }
13}
libc/musl/src/stdio/fwide.c created+16
......@@ -0,0 +1,16 @@
1#include <wchar.h>
2#include "stdio_impl.h"
3#include "locale_impl.h"
4
5int fwide(FILE *f, int mode)
6{
7 FLOCK(f);
8 if (mode) {
9 if (!f->locale) f->locale = MB_CUR_MAX==1
10 ? C_LOCALE : UTF8_LOCALE;
11 if (!f->mode) f->mode = mode>0 ? 1 : -1;
12 }
13 mode = f->mode;
14 FUNLOCK(f);
15 return mode;
16}
libc/musl/src/stdio/fwprintf.c created+13
......@@ -0,0 +1,13 @@
1#include <stdio.h>
2#include <stdarg.h>
3#include <wchar.h>
4
5int fwprintf(FILE *restrict f, const wchar_t *restrict fmt, ...)
6{
7 int ret;
8 va_list ap;
9 va_start(ap, fmt);
10 ret = vfwprintf(f, fmt, ap);
11 va_end(ap);
12 return ret;
13}
libc/musl/src/stdio/fwrite.c created+38
......@@ -0,0 +1,38 @@
1#include "stdio_impl.h"
2#include <string.h>
3
4size_t __fwritex(const unsigned char *restrict s, size_t l, FILE *restrict f)
5{
6 size_t i=0;
7
8 if (!f->wend && __towrite(f)) return 0;
9
10 if (l > f->wend - f->wpos) return f->write(f, s, l);
11
12 if (f->lbf >= 0) {
13 /* Match /^(.*\n|)/ */
14 for (i=l; i && s[i-1] != '\n'; i--);
15 if (i) {
16 size_t n = f->write(f, s, i);
17 if (n < i) return n;
18 s += i;
19 l -= i;
20 }
21 }
22
23 memcpy(f->wpos, s, l);
24 f->wpos += l;
25 return l+i;
26}
27
28size_t fwrite(const void *restrict src, size_t size, size_t nmemb, FILE *restrict f)
29{
30 size_t k, l = size*nmemb;
31 if (!size) nmemb = 0;
32 FLOCK(f);
33 k = __fwritex(src, l, f);
34 FUNLOCK(f);
35 return k==l ? nmemb : k/size;
36}
37
38weak_alias(fwrite, fwrite_unlocked);
libc/musl/src/stdio/fwscanf.c created+15
......@@ -0,0 +1,15 @@
1#include <stdio.h>
2#include <stdarg.h>
3#include <wchar.h>
4
5int fwscanf(FILE *restrict f, const wchar_t *restrict fmt, ...)
6{
7 int ret;
8 va_list ap;
9 va_start(ap, fmt);
10 ret = vfwscanf(f, fmt, ap);
11 va_end(ap);
12 return ret;
13}
14
15weak_alias(fwscanf,__isoc99_fwscanf);
libc/musl/src/stdio/getc.c created+9
......@@ -0,0 +1,9 @@
1#include <stdio.h>
2#include "getc.h"
3
4int getc(FILE *f)
5{
6 return do_getc(f);
7}
8
9weak_alias(getc, _IO_getc);
libc/musl/src/stdio/getc.h created+22
......@@ -0,0 +1,22 @@
1#include "stdio_impl.h"
2#include "pthread_impl.h"
3
4#ifdef __GNUC__
5__attribute__((__noinline__))
6#endif
7static int locking_getc(FILE *f)
8{
9 if (a_cas(&f->lock, 0, MAYBE_WAITERS-1)) __lockfile(f);
10 int c = getc_unlocked(f);
11 if (a_swap(&f->lock, 0) & MAYBE_WAITERS)
12 __wake(&f->lock, 1, 1);
13 return c;
14}
15
16static inline int do_getc(FILE *f)
17{
18 int l = f->lock;
19 if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid)
20 return getc_unlocked(f);
21 return locking_getc(f);
22}
libc/musl/src/stdio/getc_unlocked.c created+9
......@@ -0,0 +1,9 @@
1#include "stdio_impl.h"
2
3int (getc_unlocked)(FILE *f)
4{
5 return getc_unlocked(f);
6}
7
8weak_alias (getc_unlocked, fgetc_unlocked);
9weak_alias (getc_unlocked, _IO_getc_unlocked);
libc/musl/src/stdio/getchar.c created+7
......@@ -0,0 +1,7 @@
1#include <stdio.h>
2#include "getc.h"
3
4int getchar(void)
5{
6 return do_getc(stdin);
7}
libc/musl/src/stdio/getchar_unlocked.c created+6
......@@ -0,0 +1,6 @@
1#include "stdio_impl.h"
2
3int getchar_unlocked(void)
4{
5 return getc_unlocked(stdin);
6}
libc/musl/src/stdio/getdelim.c created+81
......@@ -0,0 +1,81 @@
1#include "stdio_impl.h"
2#include <string.h>
3#include <stdlib.h>
4#include <inttypes.h>
5#include <errno.h>
6
7ssize_t getdelim(char **restrict s, size_t *restrict n, int delim, FILE *restrict f)
8{
9 char *tmp;
10 unsigned char *z;
11 size_t k;
12 size_t i=0;
13 int c;
14
15 FLOCK(f);
16
17 if (!n || !s) {
18 f->mode |= f->mode-1;
19 f->flags |= F_ERR;
20 FUNLOCK(f);
21 errno = EINVAL;
22 return -1;
23 }
24
25 if (!*s) *n=0;
26
27 for (;;) {
28 if (f->rpos != f->rend) {
29 z = memchr(f->rpos, delim, f->rend - f->rpos);
30 k = z ? z - f->rpos + 1 : f->rend - f->rpos;
31 } else {
32 z = 0;
33 k = 0;
34 }
35 if (i+k >= *n) {
36 size_t m = i+k+2;
37 if (!z && m < SIZE_MAX/4) m += m/2;
38 tmp = realloc(*s, m);
39 if (!tmp) {
40 m = i+k+2;
41 tmp = realloc(*s, m);
42 if (!tmp) {
43 /* Copy as much as fits and ensure no
44 * pushback remains in the FILE buf. */
45 k = *n-i;
46 memcpy(*s+i, f->rpos, k);
47 f->rpos += k;
48 f->mode |= f->mode-1;
49 f->flags |= F_ERR;
50 FUNLOCK(f);
51 errno = ENOMEM;
52 return -1;
53 }
54 }
55 *s = tmp;
56 *n = m;
57 }
58 memcpy(*s+i, f->rpos, k);
59 f->rpos += k;
60 i += k;
61 if (z) break;
62 if ((c = getc_unlocked(f)) == EOF) {
63 if (!i || !feof(f)) {
64 FUNLOCK(f);
65 return -1;
66 }
67 break;
68 }
69 /* If the byte read by getc won't fit without growing the
70 * output buffer, push it back for next iteration. */
71 if (i+1 >= *n) *--f->rpos = c;
72 else if (((*s)[i++] = c) == delim) break;
73 }
74 (*s)[i] = 0;
75
76 FUNLOCK(f);
77
78 return i;
79}
80
81weak_alias(getdelim, __getdelim);
libc/musl/src/stdio/getline.c created+6
......@@ -0,0 +1,6 @@
1#include <stdio.h>
2
3ssize_t getline(char **restrict s, size_t *restrict n, FILE *restrict f)
4{
5 return getdelim(s, n, '\n', f);
6}
libc/musl/src/stdio/gets.c created+10
......@@ -0,0 +1,10 @@
1#include "stdio_impl.h"
2#include <limits.h>
3#include <string.h>
4
5char *gets(char *s)
6{
7 char *ret = fgets(s, INT_MAX, stdin);
8 if (ret && s[strlen(s)-1] == '\n') s[strlen(s)-1] = 0;
9 return ret;
10}
libc/musl/src/stdio/getw.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3
4int getw(FILE *f)
5{
6 int x;
7 return fread(&x, sizeof x, 1, f) ? x : EOF;
8}
libc/musl/src/stdio/getwc.c created+7
......@@ -0,0 +1,7 @@
1#include "stdio_impl.h"
2#include <wchar.h>
3
4wint_t getwc(FILE *f)
5{
6 return fgetwc(f);
7}
libc/musl/src/stdio/getwchar.c created+9
......@@ -0,0 +1,9 @@
1#include "stdio_impl.h"
2#include <wchar.h>
3
4wint_t getwchar(void)
5{
6 return fgetwc(stdin);
7}
8
9weak_alias(getwchar, getwchar_unlocked);
libc/musl/src/stdio/ofl.c created+16
......@@ -0,0 +1,16 @@
1#include "stdio_impl.h"
2#include "lock.h"
3
4static FILE *ofl_head;
5static volatile int ofl_lock[1];
6
7FILE **__ofl_lock()
8{
9 LOCK(ofl_lock);
10 return &ofl_head;
11}
12
13void __ofl_unlock()
14{
15 UNLOCK(ofl_lock);
16}
libc/musl/src/stdio/ofl_add.c created+11
......@@ -0,0 +1,11 @@
1#include "stdio_impl.h"
2
3FILE *__ofl_add(FILE *f)
4{
5 FILE **head = __ofl_lock();
6 f->next = *head;
7 if (*head) (*head)->prev = f;
8 *head = f;
9 __ofl_unlock();
10 return f;
11}
libc/musl/src/stdio/open_memstream.c created+99
......@@ -0,0 +1,99 @@
1#include "stdio_impl.h"
2#include <errno.h>
3#include <limits.h>
4#include <string.h>
5#include <stdlib.h>
6#include "libc.h"
7
8struct cookie {
9 char **bufp;
10 size_t *sizep;
11 size_t pos;
12 char *buf;
13 size_t len;
14 size_t space;
15};
16
17struct ms_FILE {
18 FILE f;
19 struct cookie c;
20 unsigned char buf[BUFSIZ];
21};
22
23static off_t ms_seek(FILE *f, off_t off, int whence)
24{
25 ssize_t base;
26 struct cookie *c = f->cookie;
27 if (whence>2U) {
28fail:
29 errno = EINVAL;
30 return -1;
31 }
32 base = (size_t [3]){0, c->pos, c->len}[whence];
33 if (off < -base || off > SSIZE_MAX-base) goto fail;
34 return c->pos = base+off;
35}
36
37static size_t ms_write(FILE *f, const unsigned char *buf, size_t len)
38{
39 struct cookie *c = f->cookie;
40 size_t len2 = f->wpos - f->wbase;
41 char *newbuf;
42 if (len2) {
43 f->wpos = f->wbase;
44 if (ms_write(f, f->wbase, len2) < len2) return 0;
45 }
46 if (len + c->pos >= c->space) {
47 len2 = 2*c->space+1 | c->pos+len+1;
48 newbuf = realloc(c->buf, len2);
49 if (!newbuf) return 0;
50 *c->bufp = c->buf = newbuf;
51 memset(c->buf + c->space, 0, len2 - c->space);
52 c->space = len2;
53 }
54 memcpy(c->buf+c->pos, buf, len);
55 c->pos += len;
56 if (c->pos >= c->len) c->len = c->pos;
57 *c->sizep = c->pos;
58 return len;
59}
60
61static int ms_close(FILE *f)
62{
63 return 0;
64}
65
66FILE *open_memstream(char **bufp, size_t *sizep)
67{
68 struct ms_FILE *f;
69 char *buf;
70
71 if (!(f=malloc(sizeof *f))) return 0;
72 if (!(buf=malloc(sizeof *buf))) {
73 free(f);
74 return 0;
75 }
76 memset(&f->f, 0, sizeof f->f);
77 memset(&f->c, 0, sizeof f->c);
78 f->f.cookie = &f->c;
79
80 f->c.bufp = bufp;
81 f->c.sizep = sizep;
82 f->c.pos = f->c.len = f->c.space = *sizep = 0;
83 f->c.buf = *bufp = buf;
84 *buf = 0;
85
86 f->f.flags = F_NORD;
87 f->f.fd = -1;
88 f->f.buf = f->buf;
89 f->f.buf_size = sizeof f->buf;
90 f->f.lbf = EOF;
91 f->f.write = ms_write;
92 f->f.seek = ms_seek;
93 f->f.close = ms_close;
94 f->f.mode = -1;
95
96 if (!libc.threaded) f->f.lock = -1;
97
98 return __ofl_add(&f->f);
99}
libc/musl/src/stdio/open_wmemstream.c created+102
......@@ -0,0 +1,102 @@
1#include "stdio_impl.h"
2#include <wchar.h>
3#include <errno.h>
4#include <limits.h>
5#include <string.h>
6#include <stdlib.h>
7#include "libc.h"
8
9struct cookie {
10 wchar_t **bufp;
11 size_t *sizep;
12 size_t pos;
13 wchar_t *buf;
14 size_t len;
15 size_t space;
16 mbstate_t mbs;
17};
18
19struct wms_FILE {
20 FILE f;
21 struct cookie c;
22 unsigned char buf[1];
23};
24
25static off_t wms_seek(FILE *f, off_t off, int whence)
26{
27 ssize_t base;
28 struct cookie *c = f->cookie;
29 if (whence>2U) {
30fail:
31 errno = EINVAL;
32 return -1;
33 }
34 base = (size_t [3]){0, c->pos, c->len}[whence];
35 if (off < -base || off > SSIZE_MAX/4-base) goto fail;
36 memset(&c->mbs, 0, sizeof c->mbs);
37 return c->pos = base+off;
38}
39
40static size_t wms_write(FILE *f, const unsigned char *buf, size_t len)
41{
42 struct cookie *c = f->cookie;
43 size_t len2;
44 wchar_t *newbuf;
45 if (len + c->pos >= c->space) {
46 len2 = 2*c->space+1 | c->pos+len+1;
47 if (len2 > SSIZE_MAX/4) return 0;
48 newbuf = realloc(c->buf, len2*4);
49 if (!newbuf) return 0;
50 *c->bufp = c->buf = newbuf;
51 memset(c->buf + c->space, 0, 4*(len2 - c->space));
52 c->space = len2;
53 }
54
55 len2 = mbsnrtowcs(c->buf+c->pos, (void *)&buf, len, c->space-c->pos, &c->mbs);
56 if (len2 == -1) return 0;
57 c->pos += len2;
58 if (c->pos >= c->len) c->len = c->pos;
59 *c->sizep = c->pos;
60 return len;
61}
62
63static int wms_close(FILE *f)
64{
65 return 0;
66}
67
68FILE *open_wmemstream(wchar_t **bufp, size_t *sizep)
69{
70 struct wms_FILE *f;
71 wchar_t *buf;
72
73 if (!(f=malloc(sizeof *f))) return 0;
74 if (!(buf=malloc(sizeof *buf))) {
75 free(f);
76 return 0;
77 }
78 memset(&f->f, 0, sizeof f->f);
79 memset(&f->c, 0, sizeof f->c);
80 f->f.cookie = &f->c;
81
82 f->c.bufp = bufp;
83 f->c.sizep = sizep;
84 f->c.pos = f->c.len = f->c.space = *sizep = 0;
85 f->c.buf = *bufp = buf;
86 *buf = 0;
87
88 f->f.flags = F_NORD;
89 f->f.fd = -1;
90 f->f.buf = f->buf;
91 f->f.buf_size = 0;
92 f->f.lbf = EOF;
93 f->f.write = wms_write;
94 f->f.seek = wms_seek;
95 f->f.close = wms_close;
96
97 if (!libc.threaded) f->f.lock = -1;
98
99 fwide(&f->f, 1);
100
101 return __ofl_add(&f->f);
102}
libc/musl/src/stdio/pclose.c created+13
......@@ -0,0 +1,13 @@
1#include "stdio_impl.h"
2#include <errno.h>
3#include <unistd.h>
4
5int pclose(FILE *f)
6{
7 int status, r;
8 pid_t pid = f->pipe_pid;
9 fclose(f);
10 while ((r=__syscall(SYS_wait4, pid, &status, 0, 0)) == -EINTR);
11 if (r<0) return __syscall_ret(r);
12 return status;
13}
libc/musl/src/stdio/perror.c created+30
......@@ -0,0 +1,30 @@
1#include <stdio.h>
2#include <string.h>
3#include <errno.h>
4#include "stdio_impl.h"
5
6void perror(const char *msg)
7{
8 FILE *f = stderr;
9 char *errstr = strerror(errno);
10
11 FLOCK(f);
12
13 /* Save stderr's orientation and encoding rule, since perror is not
14 * permitted to change them. */
15 void *old_locale = f->locale;
16 int old_mode = f->mode;
17
18 if (msg && *msg) {
19 fwrite(msg, strlen(msg), 1, f);
20 fputc(':', f);
21 fputc(' ', f);
22 }
23 fwrite(errstr, strlen(errstr), 1, f);
24 fputc('\n', f);
25
26 f->mode = old_mode;
27 f->locale = old_locale;
28
29 FUNLOCK(f);
30}
libc/musl/src/stdio/popen.c created+73
......@@ -0,0 +1,73 @@
1#include <fcntl.h>
2#include <unistd.h>
3#include <errno.h>
4#include <string.h>
5#include <spawn.h>
6#include "stdio_impl.h"
7#include "syscall.h"
8
9extern char **__environ;
10
11FILE *popen(const char *cmd, const char *mode)
12{
13 int p[2], op, e;
14 pid_t pid;
15 FILE *f;
16 posix_spawn_file_actions_t fa;
17
18 if (*mode == 'r') {
19 op = 0;
20 } else if (*mode == 'w') {
21 op = 1;
22 } else {
23 errno = EINVAL;
24 return 0;
25 }
26
27 if (pipe2(p, O_CLOEXEC)) return NULL;
28 f = fdopen(p[op], mode);
29 if (!f) {
30 __syscall(SYS_close, p[0]);
31 __syscall(SYS_close, p[1]);
32 return NULL;
33 }
34 FLOCK(f);
35
36 /* If the child's end of the pipe happens to already be on the final
37 * fd number to which it will be assigned (either 0 or 1), it must
38 * be moved to a different fd. Otherwise, there is no safe way to
39 * remove the close-on-exec flag in the child without also creating
40 * a file descriptor leak race condition in the parent. */
41 if (p[1-op] == 1-op) {
42 int tmp = fcntl(1-op, F_DUPFD_CLOEXEC, 0);
43 if (tmp < 0) {
44 e = errno;
45 goto fail;
46 }
47 __syscall(SYS_close, p[1-op]);
48 p[1-op] = tmp;
49 }
50
51 e = ENOMEM;
52 if (!posix_spawn_file_actions_init(&fa)) {
53 if (!posix_spawn_file_actions_adddup2(&fa, p[1-op], 1-op)) {
54 if (!(e = posix_spawn(&pid, "/bin/sh", &fa, 0,
55 (char *[]){ "sh", "-c", (char *)cmd, 0 }, __environ))) {
56 posix_spawn_file_actions_destroy(&fa);
57 f->pipe_pid = pid;
58 if (!strchr(mode, 'e'))
59 fcntl(p[op], F_SETFD, 0);
60 __syscall(SYS_close, p[1-op]);
61 FUNLOCK(f);
62 return f;
63 }
64 }
65 posix_spawn_file_actions_destroy(&fa);
66 }
67fail:
68 fclose(f);
69 __syscall(SYS_close, p[1-op]);
70
71 errno = e;
72 return 0;
73}
libc/musl/src/stdio/printf.c created+12
......@@ -0,0 +1,12 @@
1#include <stdio.h>
2#include <stdarg.h>
3
4int printf(const char *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vfprintf(stdout, fmt, ap);
10 va_end(ap);
11 return ret;
12}
libc/musl/src/stdio/putc.c created+9
......@@ -0,0 +1,9 @@
1#include <stdio.h>
2#include "putc.h"
3
4int putc(int c, FILE *f)
5{
6 return do_putc(c, f);
7}
8
9weak_alias(putc, _IO_putc);
libc/musl/src/stdio/putc.h created+22
......@@ -0,0 +1,22 @@
1#include "stdio_impl.h"
2#include "pthread_impl.h"
3
4#ifdef __GNUC__
5__attribute__((__noinline__))
6#endif
7static int locking_putc(int c, FILE *f)
8{
9 if (a_cas(&f->lock, 0, MAYBE_WAITERS-1)) __lockfile(f);
10 c = putc_unlocked(c, f);
11 if (a_swap(&f->lock, 0) & MAYBE_WAITERS)
12 __wake(&f->lock, 1, 1);
13 return c;
14}
15
16static inline int do_putc(int c, FILE *f)
17{
18 int l = f->lock;
19 if (l < 0 || l && (l & ~MAYBE_WAITERS) == __pthread_self()->tid)
20 return putc_unlocked(c, f);
21 return locking_putc(c, f);
22}
libc/musl/src/stdio/putc_unlocked.c created+9
......@@ -0,0 +1,9 @@
1#include "stdio_impl.h"
2
3int (putc_unlocked)(int c, FILE *f)
4{
5 return putc_unlocked(c, f);
6}
7
8weak_alias(putc_unlocked, fputc_unlocked);
9weak_alias(putc_unlocked, _IO_putc_unlocked);
libc/musl/src/stdio/putchar.c created+7
......@@ -0,0 +1,7 @@
1#include <stdio.h>
2#include "putc.h"
3
4int putchar(int c)
5{
6 return do_putc(c, stdout);
7}
libc/musl/src/stdio/putchar_unlocked.c created+6
......@@ -0,0 +1,6 @@
1#include "stdio_impl.h"
2
3int putchar_unlocked(int c)
4{
5 return putc_unlocked(c, stdout);
6}
libc/musl/src/stdio/puts.c created+10
......@@ -0,0 +1,10 @@
1#include "stdio_impl.h"
2
3int puts(const char *s)
4{
5 int r;
6 FLOCK(stdout);
7 r = -(fputs(s, stdout) < 0 || putc_unlocked('\n', stdout) < 0);
8 FUNLOCK(stdout);
9 return r;
10}
libc/musl/src/stdio/putw.c created+7
......@@ -0,0 +1,7 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3
4int putw(int x, FILE *f)
5{
6 return (int)fwrite(&x, sizeof x, 1, f)-1;
7}
libc/musl/src/stdio/putwc.c created+7
......@@ -0,0 +1,7 @@
1#include "stdio_impl.h"
2#include <wchar.h>
3
4wint_t putwc(wchar_t c, FILE *f)
5{
6 return fputwc(c, f);
7}
libc/musl/src/stdio/putwchar.c created+9
......@@ -0,0 +1,9 @@
1#include "stdio_impl.h"
2#include <wchar.h>
3
4wint_t putwchar(wchar_t c)
5{
6 return fputwc(c, stdout);
7}
8
9weak_alias(putwchar, putwchar_unlocked);
libc/musl/src/stdio/remove.c created+19
......@@ -0,0 +1,19 @@
1#include <stdio.h>
2#include <errno.h>
3#include <fcntl.h>
4#include "syscall.h"
5
6int remove(const char *path)
7{
8#ifdef SYS_unlink
9 int r = __syscall(SYS_unlink, path);
10#else
11 int r = __syscall(SYS_unlinkat, AT_FDCWD, path, 0);
12#endif
13#ifdef SYS_rmdir
14 if (r==-EISDIR) r = __syscall(SYS_rmdir, path);
15#else
16 if (r==-EISDIR) r = __syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
17#endif
18 return __syscall_ret(r);
19}
libc/musl/src/stdio/rename.c created+12
......@@ -0,0 +1,12 @@
1#include <stdio.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int rename(const char *old, const char *new)
6{
7#ifdef SYS_rename
8 return syscall(SYS_rename, old, new);
9#else
10 return syscall(SYS_renameat, AT_FDCWD, old, AT_FDCWD, new);
11#endif
12}
libc/musl/src/stdio/rewind.c created+9
......@@ -0,0 +1,9 @@
1#include "stdio_impl.h"
2
3void rewind(FILE *f)
4{
5 FLOCK(f);
6 __fseeko_unlocked(f, 0, SEEK_SET);
7 f->flags &= ~F_ERR;
8 FUNLOCK(f);
9}
libc/musl/src/stdio/scanf.c created+14
......@@ -0,0 +1,14 @@
1#include <stdio.h>
2#include <stdarg.h>
3
4int scanf(const char *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vscanf(fmt, ap);
10 va_end(ap);
11 return ret;
12}
13
14weak_alias(scanf,__isoc99_scanf);
libc/musl/src/stdio/setbuf.c created+6
......@@ -0,0 +1,6 @@
1#include <stdio.h>
2
3void setbuf(FILE *restrict f, char *restrict buf)
4{
5 setvbuf(f, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
6}
libc/musl/src/stdio/setbuffer.c created+7
......@@ -0,0 +1,7 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3
4void setbuffer(FILE *f, char *buf, size_t size)
5{
6 setvbuf(f, buf, buf ? _IOFBF : _IONBF, size);
7}
libc/musl/src/stdio/setlinebuf.c created+7
......@@ -0,0 +1,7 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3
4void setlinebuf(FILE *f)
5{
6 setvbuf(f, 0, _IOLBF, 0);
7}
libc/musl/src/stdio/setvbuf.c created+27
......@@ -0,0 +1,27 @@
1#include "stdio_impl.h"
2
3/* The behavior of this function is undefined except when it is the first
4 * operation on the stream, so the presence or absence of locking is not
5 * observable in a program whose behavior is defined. Thus no locking is
6 * performed here. No allocation of buffers is performed, but a buffer
7 * provided by the caller is used as long as it is suitably sized. */
8
9int setvbuf(FILE *restrict f, char *restrict buf, int type, size_t size)
10{
11 f->lbf = EOF;
12
13 if (type == _IONBF) {
14 f->buf_size = 0;
15 } else {
16 if (buf && size >= UNGET) {
17 f->buf = (void *)(buf + UNGET);
18 f->buf_size = size - UNGET;
19 }
20 if (type == _IOLBF && f->buf_size)
21 f->lbf = '\n';
22 }
23
24 f->flags |= F_SVB;
25
26 return 0;
27}
libc/musl/src/stdio/snprintf.c created+13
......@@ -0,0 +1,13 @@
1#include <stdio.h>
2#include <stdarg.h>
3
4int snprintf(char *restrict s, size_t n, const char *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vsnprintf(s, n, fmt, ap);
10 va_end(ap);
11 return ret;
12}
13
libc/musl/src/stdio/sprintf.c created+12
......@@ -0,0 +1,12 @@
1#include <stdio.h>
2#include <stdarg.h>
3
4int sprintf(char *restrict s, const char *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vsprintf(s, fmt, ap);
10 va_end(ap);
11 return ret;
12}
libc/musl/src/stdio/sscanf.c created+14
......@@ -0,0 +1,14 @@
1#include <stdio.h>
2#include <stdarg.h>
3
4int sscanf(const char *restrict s, const char *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vsscanf(s, fmt, ap);
10 va_end(ap);
11 return ret;
12}
13
14weak_alias(sscanf,__isoc99_sscanf);
libc/musl/src/stdio/stderr.c created+18
......@@ -0,0 +1,18 @@
1#include "stdio_impl.h"
2
3#undef stderr
4
5static unsigned char buf[UNGET];
6hidden FILE __stderr_FILE = {
7 .buf = buf+UNGET,
8 .buf_size = 0,
9 .fd = 2,
10 .flags = F_PERM | F_NORD,
11 .lbf = -1,
12 .write = __stdio_write,
13 .seek = __stdio_seek,
14 .close = __stdio_close,
15 .lock = -1,
16};
17FILE *const stderr = &__stderr_FILE;
18FILE *volatile __stderr_used = &__stderr_FILE;
libc/musl/src/stdio/stdin.c created+17
......@@ -0,0 +1,17 @@
1#include "stdio_impl.h"
2
3#undef stdin
4
5static unsigned char buf[BUFSIZ+UNGET];
6hidden FILE __stdin_FILE = {
7 .buf = buf+UNGET,
8 .buf_size = sizeof buf-UNGET,
9 .fd = 0,
10 .flags = F_PERM | F_NOWR,
11 .read = __stdio_read,
12 .seek = __stdio_seek,
13 .close = __stdio_close,
14 .lock = -1,
15};
16FILE *const stdin = &__stdin_FILE;
17FILE *volatile __stdin_used = &__stdin_FILE;
libc/musl/src/stdio/stdout.c created+18
......@@ -0,0 +1,18 @@
1#include "stdio_impl.h"
2
3#undef stdout
4
5static unsigned char buf[BUFSIZ+UNGET];
6hidden FILE __stdout_FILE = {
7 .buf = buf+UNGET,
8 .buf_size = sizeof buf-UNGET,
9 .fd = 1,
10 .flags = F_PERM | F_NORD,
11 .lbf = '\n',
12 .write = __stdout_write,
13 .seek = __stdio_seek,
14 .close = __stdio_close,
15 .lock = -1,
16};
17FILE *const stdout = &__stdout_FILE;
18FILE *volatile __stdout_used = &__stdout_FILE;
libc/musl/src/stdio/swprintf.c created+13
......@@ -0,0 +1,13 @@
1#include <stdarg.h>
2#include <wchar.h>
3
4int swprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vswprintf(s, n, fmt, ap);
10 va_end(ap);
11 return ret;
12}
13
libc/musl/src/stdio/swscanf.c created+14
......@@ -0,0 +1,14 @@
1#include <stdarg.h>
2#include <wchar.h>
3
4int swscanf(const wchar_t *restrict s, const wchar_t *restrict fmt, ...)
5{
6 int ret;
7 va_list ap;
8 va_start(ap, fmt);
9 ret = vswscanf(s, fmt, ap);
10 va_end(ap);
11 return ret;
12}
13
14weak_alias(swscanf,__isoc99_swscanf);
libc/musl/src/stdio/tempnam.c created+48
......@@ -0,0 +1,48 @@
1#include <stdio.h>
2#include <fcntl.h>
3#include <errno.h>
4#include <sys/stat.h>
5#include <limits.h>
6#include <string.h>
7#include <stdlib.h>
8#include "syscall.h"
9
10#define MAXTRIES 100
11
12char *tempnam(const char *dir, const char *pfx)
13{
14 char s[PATH_MAX];
15 size_t l, dl, pl;
16 int try;
17 int r;
18
19 if (!dir) dir = P_tmpdir;
20 if (!pfx) pfx = "temp";
21
22 dl = strlen(dir);
23 pl = strlen(pfx);
24 l = dl + 1 + pl + 1 + 6;
25
26 if (l >= PATH_MAX) {
27 errno = ENAMETOOLONG;
28 return 0;
29 }
30
31 memcpy(s, dir, dl);
32 s[dl] = '/';
33 memcpy(s+dl+1, pfx, pl);
34 s[dl+1+pl] = '_';
35 s[l] = 0;
36
37 for (try=0; try<MAXTRIES; try++) {
38 __randname(s+l-6);
39#ifdef SYS_lstat
40 r = __syscall(SYS_lstat, s, &(struct stat){0});
41#else
42 r = __syscall(SYS_fstatat, AT_FDCWD, s,
43 &(struct stat){0}, AT_SYMLINK_NOFOLLOW);
44#endif
45 if (r == -ENOENT) return strdup(s);
46 }
47 return 0;
48}
libc/musl/src/stdio/tmpfile.c created+31
......@@ -0,0 +1,31 @@
1#include <stdio.h>
2#include <fcntl.h>
3#include <stdlib.h>
4#include "stdio_impl.h"
5
6#define MAXTRIES 100
7
8FILE *tmpfile(void)
9{
10 char s[] = "/tmp/tmpfile_XXXXXX";
11 int fd;
12 FILE *f;
13 int try;
14 for (try=0; try<MAXTRIES; try++) {
15 __randname(s+13);
16 fd = sys_open(s, O_RDWR|O_CREAT|O_EXCL, 0600);
17 if (fd >= 0) {
18#ifdef SYS_unlink
19 __syscall(SYS_unlink, s);
20#else
21 __syscall(SYS_unlinkat, AT_FDCWD, s, 0);
22#endif
23 f = __fdopen(fd, "w+");
24 if (!f) __syscall(SYS_close, fd);
25 return f;
26 }
27 }
28 return 0;
29}
30
31weak_alias(tmpfile, tmpfile64);
libc/musl/src/stdio/tmpnam.c created+28
......@@ -0,0 +1,28 @@
1#include <stdio.h>
2#include <fcntl.h>
3#include <errno.h>
4#include <sys/stat.h>
5#include <string.h>
6#include <stdlib.h>
7#include "syscall.h"
8
9#define MAXTRIES 100
10
11char *tmpnam(char *buf)
12{
13 static char internal[L_tmpnam];
14 char s[] = "/tmp/tmpnam_XXXXXX";
15 int try;
16 int r;
17 for (try=0; try<MAXTRIES; try++) {
18 __randname(s+12);
19#ifdef SYS_lstat
20 r = __syscall(SYS_lstat, s, &(struct stat){0});
21#else
22 r = __syscall(SYS_fstatat, AT_FDCWD, s,
23 &(struct stat){0}, AT_SYMLINK_NOFOLLOW);
24#endif
25 if (r == -ENOENT) return strcpy(buf ? buf : internal, s);
26 }
27 return 0;
28}
libc/musl/src/stdio/ungetc.c created+20
......@@ -0,0 +1,20 @@
1#include "stdio_impl.h"
2
3int ungetc(int c, FILE *f)
4{
5 if (c == EOF) return c;
6
7 FLOCK(f);
8
9 if (!f->rpos) __toread(f);
10 if (!f->rpos || f->rpos <= f->buf - UNGET) {
11 FUNLOCK(f);
12 return EOF;
13 }
14
15 *--f->rpos = c;
16 f->flags &= ~F_EOF;
17
18 FUNLOCK(f);
19 return c;
20}
libc/musl/src/stdio/ungetwc.c created+35
......@@ -0,0 +1,35 @@
1#include "stdio_impl.h"
2#include "locale_impl.h"
3#include <wchar.h>
4#include <limits.h>
5#include <ctype.h>
6#include <string.h>
7
8wint_t ungetwc(wint_t c, FILE *f)
9{
10 unsigned char mbc[MB_LEN_MAX];
11 int l;
12 locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
13
14 FLOCK(f);
15
16 if (f->mode <= 0) fwide(f, 1);
17 *ploc = f->locale;
18
19 if (!f->rpos) __toread(f);
20 if (!f->rpos || c == WEOF || (l = wcrtomb((void *)mbc, c, 0)) < 0 ||
21 f->rpos < f->buf - UNGET + l) {
22 FUNLOCK(f);
23 *ploc = loc;
24 return WEOF;
25 }
26
27 if (isascii(c)) *--f->rpos = c;
28 else memcpy(f->rpos -= l, mbc, l);
29
30 f->flags &= ~F_EOF;
31
32 FUNLOCK(f);
33 *ploc = loc;
34 return c;
35}
libc/musl/src/stdio/vasprintf.c created+15
......@@ -0,0 +1,15 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3#include <stdarg.h>
4#include <stdlib.h>
5
6int vasprintf(char **s, const char *fmt, va_list ap)
7{
8 va_list ap2;
9 va_copy(ap2, ap);
10 int l = vsnprintf(0, 0, fmt, ap2);
11 va_end(ap2);
12
13 if (l<0 || !(*s=malloc(l+1U))) return -1;
14 return vsnprintf(*s, l+1U, fmt, ap);
15}
libc/musl/src/stdio/vdprintf.c created+16
......@@ -0,0 +1,16 @@
1#include "stdio_impl.h"
2
3static size_t wrap_write(FILE *f, const unsigned char *buf, size_t len)
4{
5 return __stdio_write(f, buf, len);
6}
7
8int vdprintf(int fd, const char *restrict fmt, va_list ap)
9{
10 FILE f = {
11 .fd = fd, .lbf = EOF, .write = wrap_write,
12 .buf = (void *)fmt, .buf_size = 0,
13 .lock = -1
14 };
15 return vfprintf(&f, fmt, ap);
16}
libc/musl/src/stdio/vfprintf.c created+696
......@@ -0,0 +1,696 @@
1#include "stdio_impl.h"
2#include <errno.h>
3#include <ctype.h>
4#include <limits.h>
5#include <string.h>
6#include <stdarg.h>
7#include <stddef.h>
8#include <stdlib.h>
9#include <wchar.h>
10#include <inttypes.h>
11#include <math.h>
12#include <float.h>
13
14/* Some useful macros */
15
16#define MAX(a,b) ((a)>(b) ? (a) : (b))
17#define MIN(a,b) ((a)<(b) ? (a) : (b))
18
19/* Convenient bit representation for modifier flags, which all fall
20 * within 31 codepoints of the space character. */
21
22#define ALT_FORM (1U<<'#'-' ')
23#define ZERO_PAD (1U<<'0'-' ')
24#define LEFT_ADJ (1U<<'-'-' ')
25#define PAD_POS (1U<<' '-' ')
26#define MARK_POS (1U<<'+'-' ')
27#define GROUPED (1U<<'\''-' ')
28
29#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
30
31/* State machine to accept length modifiers + conversion specifiers.
32 * Result is 0 on failure, or an argument type to pop on success. */
33
34enum {
35 BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
36 ZTPRE, JPRE,
37 STOP,
38 PTR, INT, UINT, ULLONG,
39 LONG, ULONG,
40 SHORT, USHORT, CHAR, UCHAR,
41 LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
42 DBL, LDBL,
43 NOARG,
44 MAXSTATE
45};
46
47#define S(x) [(x)-'A']
48
49static const unsigned char states[]['z'-'A'+1] = {
50 { /* 0: bare types */
51 S('d') = INT, S('i') = INT,
52 S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
53 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
54 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
55 S('c') = CHAR, S('C') = INT,
56 S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
57 S('m') = NOARG,
58 S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
59 S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
60 }, { /* 1: l-prefixed */
61 S('d') = LONG, S('i') = LONG,
62 S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
63 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
64 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
65 S('c') = INT, S('s') = PTR, S('n') = PTR,
66 S('l') = LLPRE,
67 }, { /* 2: ll-prefixed */
68 S('d') = LLONG, S('i') = LLONG,
69 S('o') = ULLONG, S('u') = ULLONG,
70 S('x') = ULLONG, S('X') = ULLONG,
71 S('n') = PTR,
72 }, { /* 3: h-prefixed */
73 S('d') = SHORT, S('i') = SHORT,
74 S('o') = USHORT, S('u') = USHORT,
75 S('x') = USHORT, S('X') = USHORT,
76 S('n') = PTR,
77 S('h') = HHPRE,
78 }, { /* 4: hh-prefixed */
79 S('d') = CHAR, S('i') = CHAR,
80 S('o') = UCHAR, S('u') = UCHAR,
81 S('x') = UCHAR, S('X') = UCHAR,
82 S('n') = PTR,
83 }, { /* 5: L-prefixed */
84 S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
85 S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
86 S('n') = PTR,
87 }, { /* 6: z- or t-prefixed (assumed to be same size) */
88 S('d') = PDIFF, S('i') = PDIFF,
89 S('o') = SIZET, S('u') = SIZET,
90 S('x') = SIZET, S('X') = SIZET,
91 S('n') = PTR,
92 }, { /* 7: j-prefixed */
93 S('d') = IMAX, S('i') = IMAX,
94 S('o') = UMAX, S('u') = UMAX,
95 S('x') = UMAX, S('X') = UMAX,
96 S('n') = PTR,
97 }
98};
99
100#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
101
102union arg
103{
104 uintmax_t i;
105 long double f;
106 void *p;
107};
108
109static void pop_arg(union arg *arg, int type, va_list *ap)
110{
111 switch (type) {
112 case PTR: arg->p = va_arg(*ap, void *);
113 break; case INT: arg->i = va_arg(*ap, int);
114 break; case UINT: arg->i = va_arg(*ap, unsigned int);
115 break; case LONG: arg->i = va_arg(*ap, long);
116 break; case ULONG: arg->i = va_arg(*ap, unsigned long);
117 break; case ULLONG: arg->i = va_arg(*ap, unsigned long long);
118 break; case SHORT: arg->i = (short)va_arg(*ap, int);
119 break; case USHORT: arg->i = (unsigned short)va_arg(*ap, int);
120 break; case CHAR: arg->i = (signed char)va_arg(*ap, int);
121 break; case UCHAR: arg->i = (unsigned char)va_arg(*ap, int);
122 break; case LLONG: arg->i = va_arg(*ap, long long);
123 break; case SIZET: arg->i = va_arg(*ap, size_t);
124 break; case IMAX: arg->i = va_arg(*ap, intmax_t);
125 break; case UMAX: arg->i = va_arg(*ap, uintmax_t);
126 break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t);
127 break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *);
128 break; case DBL: arg->f = va_arg(*ap, double);
129 break; case LDBL: arg->f = va_arg(*ap, long double);
130 }
131}
132
133static void out(FILE *f, const char *s, size_t l)
134{
135 if (!(f->flags & F_ERR)) __fwritex((void *)s, l, f);
136}
137
138static void pad(FILE *f, char c, int w, int l, int fl)
139{
140 char pad[256];
141 if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return;
142 l = w - l;
143 memset(pad, c, l>sizeof pad ? sizeof pad : l);
144 for (; l >= sizeof pad; l -= sizeof pad)
145 out(f, pad, sizeof pad);
146 out(f, pad, l);
147}
148
149static const char xdigits[16] = {
150 "0123456789ABCDEF"
151};
152
153static char *fmt_x(uintmax_t x, char *s, int lower)
154{
155 for (; x; x>>=4) *--s = xdigits[(x&15)]|lower;
156 return s;
157}
158
159static char *fmt_o(uintmax_t x, char *s)
160{
161 for (; x; x>>=3) *--s = '0' + (x&7);
162 return s;
163}
164
165static char *fmt_u(uintmax_t x, char *s)
166{
167 unsigned long y;
168 for ( ; x>ULONG_MAX; x/=10) *--s = '0' + x%10;
169 for (y=x; y; y/=10) *--s = '0' + y%10;
170 return s;
171}
172
173/* Do not override this check. The floating point printing code below
174 * depends on the float.h constants being right. If they are wrong, it
175 * may overflow the stack. */
176#if LDBL_MANT_DIG == 53
177typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)];
178#endif
179
180static int fmt_fp(FILE *f, long double y, int w, int p, int fl, int t)
181{
182 uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion
183 + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion
184 uint32_t *a, *d, *r, *z;
185 int e2=0, e, i, j, l;
186 char buf[9+LDBL_MANT_DIG/4], *s;
187 const char *prefix="-0X+0X 0X-0x+0x 0x";
188 int pl;
189 char ebuf0[3*sizeof(int)], *ebuf=&ebuf0[3*sizeof(int)], *estr;
190
191 pl=1;
192 if (signbit(y)) {
193 y=-y;
194 } else if (fl & MARK_POS) {
195 prefix+=3;
196 } else if (fl & PAD_POS) {
197 prefix+=6;
198 } else prefix++, pl=0;
199
200 if (!isfinite(y)) {
201 char *s = (t&32)?"inf":"INF";
202 if (y!=y) s=(t&32)?"nan":"NAN";
203 pad(f, ' ', w, 3+pl, fl&~ZERO_PAD);
204 out(f, prefix, pl);
205 out(f, s, 3);
206 pad(f, ' ', w, 3+pl, fl^LEFT_ADJ);
207 return MAX(w, 3+pl);
208 }
209
210 y = frexpl(y, &e2) * 2;
211 if (y) e2--;
212
213 if ((t|32)=='a') {
214 long double round = 8.0;
215 int re;
216
217 if (t&32) prefix += 9;
218 pl += 2;
219
220 if (p<0 || p>=LDBL_MANT_DIG/4-1) re=0;
221 else re=LDBL_MANT_DIG/4-1-p;
222
223 if (re) {
224 round *= 1<<(LDBL_MANT_DIG%4);
225 while (re--) round*=16;
226 if (*prefix=='-') {
227 y=-y;
228 y-=round;
229 y+=round;
230 y=-y;
231 } else {
232 y+=round;
233 y-=round;
234 }
235 }
236
237 estr=fmt_u(e2<0 ? -e2 : e2, ebuf);
238 if (estr==ebuf) *--estr='0';
239 *--estr = (e2<0 ? '-' : '+');
240 *--estr = t+('p'-'a');
241
242 s=buf;
243 do {
244 int x=y;
245 *s++=xdigits[x]|(t&32);
246 y=16*(y-x);
247 if (s-buf==1 && (y||p>0||(fl&ALT_FORM))) *s++='.';
248 } while (y);
249
250 if (p > INT_MAX-2-(ebuf-estr)-pl)
251 return -1;
252 if (p && s-buf-2 < p)
253 l = (p+2) + (ebuf-estr);
254 else
255 l = (s-buf) + (ebuf-estr);
256
257 pad(f, ' ', w, pl+l, fl);
258 out(f, prefix, pl);
259 pad(f, '0', w, pl+l, fl^ZERO_PAD);
260 out(f, buf, s-buf);
261 pad(f, '0', l-(ebuf-estr)-(s-buf), 0, 0);
262 out(f, estr, ebuf-estr);
263 pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
264 return MAX(w, pl+l);
265 }
266 if (p<0) p=6;
267
268 if (y) y *= 0x1p28, e2-=28;
269
270 if (e2<0) a=r=z=big;
271 else a=r=z=big+sizeof(big)/sizeof(*big) - LDBL_MANT_DIG - 1;
272
273 do {
274 *z = y;
275 y = 1000000000*(y-*z++);
276 } while (y);
277
278 while (e2>0) {
279 uint32_t carry=0;
280 int sh=MIN(29,e2);
281 for (d=z-1; d>=a; d--) {
282 uint64_t x = ((uint64_t)*d<<sh)+carry;
283 *d = x % 1000000000;
284 carry = x / 1000000000;
285 }
286 if (carry) *--a = carry;
287 while (z>a && !z[-1]) z--;
288 e2-=sh;
289 }
290 while (e2<0) {
291 uint32_t carry=0, *b;
292 int sh=MIN(9,-e2), need=1+(p+LDBL_MANT_DIG/3U+8)/9;
293 for (d=a; d<z; d++) {
294 uint32_t rm = *d & (1<<sh)-1;
295 *d = (*d>>sh) + carry;
296 carry = (1000000000>>sh) * rm;
297 }
298 if (!*a) a++;
299 if (carry) *z++ = carry;
300 /* Avoid (slow!) computation past requested precision */
301 b = (t|32)=='f' ? r : a;
302 if (z-b > need) z = b+need;
303 e2+=sh;
304 }
305
306 if (a<z) for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
307 else e=0;
308
309 /* Perform rounding: j is precision after the radix (possibly neg) */
310 j = p - ((t|32)!='f')*e - ((t|32)=='g' && p);
311 if (j < 9*(z-r-1)) {
312 uint32_t x;
313 /* We avoid C's broken division of negative numbers */
314 d = r + 1 + ((j+9*LDBL_MAX_EXP)/9 - LDBL_MAX_EXP);
315 j += 9*LDBL_MAX_EXP;
316 j %= 9;
317 for (i=10, j++; j<9; i*=10, j++);
318 x = *d % i;
319 /* Are there any significant digits past j? */
320 if (x || d+1!=z) {
321 long double round = 2/LDBL_EPSILON;
322 long double small;
323 if ((*d/i & 1) || (i==1000000000 && d>a && (d[-1]&1)))
324 round += 2;
325 if (x<i/2) small=0x0.8p0;
326 else if (x==i/2 && d+1==z) small=0x1.0p0;
327 else small=0x1.8p0;
328 if (pl && *prefix=='-') round*=-1, small*=-1;
329 *d -= x;
330 /* Decide whether to round by probing round+small */
331 if (round+small != round) {
332 *d = *d + i;
333 while (*d > 999999999) {
334 *d--=0;
335 if (d<a) *--a=0;
336 (*d)++;
337 }
338 for (i=10, e=9*(r-a); *a>=i; i*=10, e++);
339 }
340 }
341 if (z>d+1) z=d+1;
342 }
343 for (; z>a && !z[-1]; z--);
344
345 if ((t|32)=='g') {
346 if (!p) p++;
347 if (p>e && e>=-4) {
348 t--;
349 p-=e+1;
350 } else {
351 t-=2;
352 p--;
353 }
354 if (!(fl&ALT_FORM)) {
355 /* Count trailing zeros in last place */
356 if (z>a && z[-1]) for (i=10, j=0; z[-1]%i==0; i*=10, j++);
357 else j=9;
358 if ((t|32)=='f')
359 p = MIN(p,MAX(0,9*(z-r-1)-j));
360 else
361 p = MIN(p,MAX(0,9*(z-r-1)+e-j));
362 }
363 }
364 if (p > INT_MAX-1-(p || (fl&ALT_FORM)))
365 return -1;
366 l = 1 + p + (p || (fl&ALT_FORM));
367 if ((t|32)=='f') {
368 if (e > INT_MAX-l) return -1;
369 if (e>0) l+=e;
370 } else {
371 estr=fmt_u(e<0 ? -e : e, ebuf);
372 while(ebuf-estr<2) *--estr='0';
373 *--estr = (e<0 ? '-' : '+');
374 *--estr = t;
375 if (ebuf-estr > INT_MAX-l) return -1;
376 l += ebuf-estr;
377 }
378
379 if (l > INT_MAX-pl) return -1;
380 pad(f, ' ', w, pl+l, fl);
381 out(f, prefix, pl);
382 pad(f, '0', w, pl+l, fl^ZERO_PAD);
383
384 if ((t|32)=='f') {
385 if (a>r) a=r;
386 for (d=a; d<=r; d++) {
387 char *s = fmt_u(*d, buf+9);
388 if (d!=a) while (s>buf) *--s='0';
389 else if (s==buf+9) *--s='0';
390 out(f, s, buf+9-s);
391 }
392 if (p || (fl&ALT_FORM)) out(f, ".", 1);
393 for (; d<z && p>0; d++, p-=9) {
394 char *s = fmt_u(*d, buf+9);
395 while (s>buf) *--s='0';
396 out(f, s, MIN(9,p));
397 }
398 pad(f, '0', p+9, 9, 0);
399 } else {
400 if (z<=a) z=a+1;
401 for (d=a; d<z && p>=0; d++) {
402 char *s = fmt_u(*d, buf+9);
403 if (s==buf+9) *--s='0';
404 if (d!=a) while (s>buf) *--s='0';
405 else {
406 out(f, s++, 1);
407 if (p>0||(fl&ALT_FORM)) out(f, ".", 1);
408 }
409 out(f, s, MIN(buf+9-s, p));
410 p -= buf+9-s;
411 }
412 pad(f, '0', p+18, 18, 0);
413 out(f, estr, ebuf-estr);
414 }
415
416 pad(f, ' ', w, pl+l, fl^LEFT_ADJ);
417
418 return MAX(w, pl+l);
419}
420
421static int getint(char **s) {
422 int i;
423 for (i=0; isdigit(**s); (*s)++) {
424 if (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;
425 else i = 10*i + (**s-'0');
426 }
427 return i;
428}
429
430static int printf_core(FILE *f, const char *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
431{
432 char *a, *z, *s=(char *)fmt;
433 unsigned l10n=0, fl;
434 int w, p, xp;
435 union arg arg;
436 int argpos;
437 unsigned st, ps;
438 int cnt=0, l=0;
439 size_t i;
440 char buf[sizeof(uintmax_t)*3+3+LDBL_MANT_DIG/4];
441 const char *prefix;
442 int t, pl;
443 wchar_t wc[2], *ws;
444 char mb[4];
445
446 for (;;) {
447 /* This error is only specified for snprintf, but since it's
448 * unspecified for other forms, do the same. Stop immediately
449 * on overflow; otherwise %n could produce wrong results. */
450 if (l > INT_MAX - cnt) goto overflow;
451
452 /* Update output count, end loop when fmt is exhausted */
453 cnt += l;
454 if (!*s) break;
455
456 /* Handle literal text and %% format specifiers */
457 for (a=s; *s && *s!='%'; s++);
458 for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);
459 if (z-a > INT_MAX-cnt) goto overflow;
460 l = z-a;
461 if (f) out(f, a, l);
462 if (l) continue;
463
464 if (isdigit(s[1]) && s[2]=='$') {
465 l10n=1;
466 argpos = s[1]-'0';
467 s+=3;
468 } else {
469 argpos = -1;
470 s++;
471 }
472
473 /* Read modifier flags */
474 for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
475 fl |= 1U<<*s-' ';
476
477 /* Read field width */
478 if (*s=='*') {
479 if (isdigit(s[1]) && s[2]=='$') {
480 l10n=1;
481 nl_type[s[1]-'0'] = INT;
482 w = nl_arg[s[1]-'0'].i;
483 s+=3;
484 } else if (!l10n) {
485 w = f ? va_arg(*ap, int) : 0;
486 s++;
487 } else goto inval;
488 if (w<0) fl|=LEFT_ADJ, w=-w;
489 } else if ((w=getint(&s))<0) goto overflow;
490
491 /* Read precision */
492 if (*s=='.' && s[1]=='*') {
493 if (isdigit(s[2]) && s[3]=='$') {
494 nl_type[s[2]-'0'] = INT;
495 p = nl_arg[s[2]-'0'].i;
496 s+=4;
497 } else if (!l10n) {
498 p = f ? va_arg(*ap, int) : 0;
499 s+=2;
500 } else goto inval;
501 xp = (p>=0);
502 } else if (*s=='.') {
503 s++;
504 p = getint(&s);
505 xp = 1;
506 } else {
507 p = -1;
508 xp = 0;
509 }
510
511 /* Format specifier state machine */
512 st=0;
513 do {
514 if (OOB(*s)) goto inval;
515 ps=st;
516 st=states[st]S(*s++);
517 } while (st-1<STOP);
518 if (!st) goto inval;
519
520 /* Check validity of argument type (nl/normal) */
521 if (st==NOARG) {
522 if (argpos>=0) goto inval;
523 } else {
524 if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
525 else if (f) pop_arg(&arg, st, ap);
526 else return 0;
527 }
528
529 if (!f) continue;
530
531 z = buf + sizeof(buf);
532 prefix = "-+ 0X0x";
533 pl = 0;
534 t = s[-1];
535
536 /* Transform ls,lc -> S,C */
537 if (ps && (t&15)==3) t&=~32;
538
539 /* - and 0 flags are mutually exclusive */
540 if (fl & LEFT_ADJ) fl &= ~ZERO_PAD;
541
542 switch(t) {
543 case 'n':
544 switch(ps) {
545 case BARE: *(int *)arg.p = cnt; break;
546 case LPRE: *(long *)arg.p = cnt; break;
547 case LLPRE: *(long long *)arg.p = cnt; break;
548 case HPRE: *(unsigned short *)arg.p = cnt; break;
549 case HHPRE: *(unsigned char *)arg.p = cnt; break;
550 case ZTPRE: *(size_t *)arg.p = cnt; break;
551 case JPRE: *(uintmax_t *)arg.p = cnt; break;
552 }
553 continue;
554 case 'p':
555 p = MAX(p, 2*sizeof(void*));
556 t = 'x';
557 fl |= ALT_FORM;
558 case 'x': case 'X':
559 a = fmt_x(arg.i, z, t&32);
560 if (arg.i && (fl & ALT_FORM)) prefix+=(t>>4), pl=2;
561 if (0) {
562 case 'o':
563 a = fmt_o(arg.i, z);
564 if ((fl&ALT_FORM) && p<z-a+1) p=z-a+1;
565 } if (0) {
566 case 'd': case 'i':
567 pl=1;
568 if (arg.i>INTMAX_MAX) {
569 arg.i=-arg.i;
570 } else if (fl & MARK_POS) {
571 prefix++;
572 } else if (fl & PAD_POS) {
573 prefix+=2;
574 } else pl=0;
575 case 'u':
576 a = fmt_u(arg.i, z);
577 }
578 if (xp && p<0) goto overflow;
579 if (xp) fl &= ~ZERO_PAD;
580 if (!arg.i && !p) {
581 a=z;
582 break;
583 }
584 p = MAX(p, z-a + !arg.i);
585 break;
586 case 'c':
587 *(a=z-(p=1))=arg.i;
588 fl &= ~ZERO_PAD;
589 break;
590 case 'm':
591 if (1) a = strerror(errno); else
592 case 's':
593 a = arg.p ? arg.p : "(null)";
594 z = a + strnlen(a, p<0 ? INT_MAX : p);
595 if (p<0 && *z) goto overflow;
596 p = z-a;
597 fl &= ~ZERO_PAD;
598 break;
599 case 'C':
600 wc[0] = arg.i;
601 wc[1] = 0;
602 arg.p = wc;
603 p = -1;
604 case 'S':
605 ws = arg.p;
606 for (i=l=0; i<p && *ws && (l=wctomb(mb, *ws++))>=0 && l<=p-i; i+=l);
607 if (l<0) return -1;
608 if (i > INT_MAX) goto overflow;
609 p = i;
610 pad(f, ' ', w, p, fl);
611 ws = arg.p;
612 for (i=0; i<0U+p && *ws && i+(l=wctomb(mb, *ws++))<=p; i+=l)
613 out(f, mb, l);
614 pad(f, ' ', w, p, fl^LEFT_ADJ);
615 l = w>p ? w : p;
616 continue;
617 case 'e': case 'f': case 'g': case 'a':
618 case 'E': case 'F': case 'G': case 'A':
619 if (xp && p<0) goto overflow;
620 l = fmt_fp(f, arg.f, w, p, fl, t);
621 if (l<0) goto overflow;
622 continue;
623 }
624
625 if (p < z-a) p = z-a;
626 if (p > INT_MAX-pl) goto overflow;
627 if (w < pl+p) w = pl+p;
628 if (w > INT_MAX-cnt) goto overflow;
629
630 pad(f, ' ', w, pl+p, fl);
631 out(f, prefix, pl);
632 pad(f, '0', w, pl+p, fl^ZERO_PAD);
633 pad(f, '0', p, z-a, 0);
634 out(f, a, z-a);
635 pad(f, ' ', w, pl+p, fl^LEFT_ADJ);
636
637 l = w;
638 }
639
640 if (f) return cnt;
641 if (!l10n) return 0;
642
643 for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
644 pop_arg(nl_arg+i, nl_type[i], ap);
645 for (; i<=NL_ARGMAX && !nl_type[i]; i++);
646 if (i<=NL_ARGMAX) goto inval;
647 return 1;
648
649inval:
650 errno = EINVAL;
651 return -1;
652overflow:
653 errno = EOVERFLOW;
654 return -1;
655}
656
657int vfprintf(FILE *restrict f, const char *restrict fmt, va_list ap)
658{
659 va_list ap2;
660 int nl_type[NL_ARGMAX+1] = {0};
661 union arg nl_arg[NL_ARGMAX+1];
662 unsigned char internal_buf[80], *saved_buf = 0;
663 int olderr;
664 int ret;
665
666 /* the copy allows passing va_list* even if va_list is an array */
667 va_copy(ap2, ap);
668 if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {
669 va_end(ap2);
670 return -1;
671 }
672
673 FLOCK(f);
674 olderr = f->flags & F_ERR;
675 if (f->mode < 1) f->flags &= ~F_ERR;
676 if (!f->buf_size) {
677 saved_buf = f->buf;
678 f->buf = internal_buf;
679 f->buf_size = sizeof internal_buf;
680 f->wpos = f->wbase = f->wend = 0;
681 }
682 if (!f->wend && __towrite(f)) ret = -1;
683 else ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
684 if (saved_buf) {
685 f->write(f, 0, 0);
686 if (!f->wpos) ret = -1;
687 f->buf = saved_buf;
688 f->buf_size = 0;
689 f->wpos = f->wbase = f->wend = 0;
690 }
691 if (f->flags & F_ERR) ret = -1;
692 f->flags |= olderr;
693 FUNLOCK(f);
694 va_end(ap2);
695 return ret;
696}
libc/musl/src/stdio/vfscanf.c created+336
......@@ -0,0 +1,336 @@
1#include <stdlib.h>
2#include <stdarg.h>
3#include <ctype.h>
4#include <wchar.h>
5#include <wctype.h>
6#include <limits.h>
7#include <string.h>
8#include <stdint.h>
9
10#include "stdio_impl.h"
11#include "shgetc.h"
12#include "intscan.h"
13#include "floatscan.h"
14
15#define SIZE_hh -2
16#define SIZE_h -1
17#define SIZE_def 0
18#define SIZE_l 1
19#define SIZE_L 2
20#define SIZE_ll 3
21
22static void store_int(void *dest, int size, unsigned long long i)
23{
24 if (!dest) return;
25 switch (size) {
26 case SIZE_hh:
27 *(char *)dest = i;
28 break;
29 case SIZE_h:
30 *(short *)dest = i;
31 break;
32 case SIZE_def:
33 *(int *)dest = i;
34 break;
35 case SIZE_l:
36 *(long *)dest = i;
37 break;
38 case SIZE_ll:
39 *(long long *)dest = i;
40 break;
41 }
42}
43
44static void *arg_n(va_list ap, unsigned int n)
45{
46 void *p;
47 unsigned int i;
48 va_list ap2;
49 va_copy(ap2, ap);
50 for (i=n; i>1; i--) va_arg(ap2, void *);
51 p = va_arg(ap2, void *);
52 va_end(ap2);
53 return p;
54}
55
56int vfscanf(FILE *restrict f, const char *restrict fmt, va_list ap)
57{
58 int width;
59 int size;
60 int alloc;
61 int base;
62 const unsigned char *p;
63 int c, t;
64 char *s;
65 wchar_t *wcs;
66 mbstate_t st;
67 void *dest=NULL;
68 int invert;
69 int matches=0;
70 unsigned long long x;
71 long double y;
72 off_t pos = 0;
73 unsigned char scanset[257];
74 size_t i, k;
75 wchar_t wc;
76
77 FLOCK(f);
78
79 for (p=(const unsigned char *)fmt; *p; p++) {
80
81 alloc = 0;
82
83 if (isspace(*p)) {
84 while (isspace(p[1])) p++;
85 shlim(f, 0);
86 while (isspace(shgetc(f)));
87 shunget(f);
88 pos += shcnt(f);
89 continue;
90 }
91 if (*p != '%' || p[1] == '%') {
92 shlim(f, 0);
93 if (*p == '%') {
94 p++;
95 while (isspace((c=shgetc(f))));
96 } else {
97 c = shgetc(f);
98 }
99 if (c!=*p) {
100 shunget(f);
101 if (c<0) goto input_fail;
102 goto match_fail;
103 }
104 pos += shcnt(f);
105 continue;
106 }
107
108 p++;
109 if (*p=='*') {
110 dest = 0; p++;
111 } else if (isdigit(*p) && p[1]=='$') {
112 dest = arg_n(ap, *p-'0'); p+=2;
113 } else {
114 dest = va_arg(ap, void *);
115 }
116
117 for (width=0; isdigit(*p); p++) {
118 width = 10*width + *p - '0';
119 }
120
121 if (*p=='m') {
122 wcs = 0;
123 s = 0;
124 alloc = !!dest;
125 p++;
126 } else {
127 alloc = 0;
128 }
129
130 size = SIZE_def;
131 switch (*p++) {
132 case 'h':
133 if (*p == 'h') p++, size = SIZE_hh;
134 else size = SIZE_h;
135 break;
136 case 'l':
137 if (*p == 'l') p++, size = SIZE_ll;
138 else size = SIZE_l;
139 break;
140 case 'j':
141 size = SIZE_ll;
142 break;
143 case 'z':
144 case 't':
145 size = SIZE_l;
146 break;
147 case 'L':
148 size = SIZE_L;
149 break;
150 case 'd': case 'i': case 'o': case 'u': case 'x':
151 case 'a': case 'e': case 'f': case 'g':
152 case 'A': case 'E': case 'F': case 'G': case 'X':
153 case 's': case 'c': case '[':
154 case 'S': case 'C':
155 case 'p': case 'n':
156 p--;
157 break;
158 default:
159 goto fmt_fail;
160 }
161
162 t = *p;
163
164 /* C or S */
165 if ((t&0x2f) == 3) {
166 t |= 32;
167 size = SIZE_l;
168 }
169
170 switch (t) {
171 case 'c':
172 if (width < 1) width = 1;
173 case '[':
174 break;
175 case 'n':
176 store_int(dest, size, pos);
177 /* do not increment match count, etc! */
178 continue;
179 default:
180 shlim(f, 0);
181 while (isspace(shgetc(f)));
182 shunget(f);
183 pos += shcnt(f);
184 }
185
186 shlim(f, width);
187 if (shgetc(f) < 0) goto input_fail;
188 shunget(f);
189
190 switch (t) {
191 case 's':
192 case 'c':
193 case '[':
194 if (t == 'c' || t == 's') {
195 memset(scanset, -1, sizeof scanset);
196 scanset[0] = 0;
197 if (t == 's') {
198 scanset[1+'\t'] = 0;
199 scanset[1+'\n'] = 0;
200 scanset[1+'\v'] = 0;
201 scanset[1+'\f'] = 0;
202 scanset[1+'\r'] = 0;
203 scanset[1+' '] = 0;
204 }
205 } else {
206 if (*++p == '^') p++, invert = 1;
207 else invert = 0;
208 memset(scanset, invert, sizeof scanset);
209 scanset[0] = 0;
210 if (*p == '-') p++, scanset[1+'-'] = 1-invert;
211 else if (*p == ']') p++, scanset[1+']'] = 1-invert;
212 for (; *p != ']'; p++) {
213 if (!*p) goto fmt_fail;
214 if (*p=='-' && p[1] && p[1] != ']')
215 for (c=p++[-1]; c<*p; c++)
216 scanset[1+c] = 1-invert;
217 scanset[1+*p] = 1-invert;
218 }
219 }
220 wcs = 0;
221 s = 0;
222 i = 0;
223 k = t=='c' ? width+1U : 31;
224 if (size == SIZE_l) {
225 if (alloc) {
226 wcs = malloc(k*sizeof(wchar_t));
227 if (!wcs) goto alloc_fail;
228 } else {
229 wcs = dest;
230 }
231 st = (mbstate_t){0};
232 while (scanset[(c=shgetc(f))+1]) {
233 switch (mbrtowc(&wc, &(char){c}, 1, &st)) {
234 case -1:
235 goto input_fail;
236 case -2:
237 continue;
238 }
239 if (wcs) wcs[i++] = wc;
240 if (alloc && i==k) {
241 k+=k+1;
242 wchar_t *tmp = realloc(wcs, k*sizeof(wchar_t));
243 if (!tmp) goto alloc_fail;
244 wcs = tmp;
245 }
246 }
247 if (!mbsinit(&st)) goto input_fail;
248 } else if (alloc) {
249 s = malloc(k);
250 if (!s) goto alloc_fail;
251 while (scanset[(c=shgetc(f))+1]) {
252 s[i++] = c;
253 if (i==k) {
254 k+=k+1;
255 char *tmp = realloc(s, k);
256 if (!tmp) goto alloc_fail;
257 s = tmp;
258 }
259 }
260 } else if ((s = dest)) {
261 while (scanset[(c=shgetc(f))+1])
262 s[i++] = c;
263 } else {
264 while (scanset[(c=shgetc(f))+1]);
265 }
266 shunget(f);
267 if (!shcnt(f)) goto match_fail;
268 if (t == 'c' && shcnt(f) != width) goto match_fail;
269 if (alloc) {
270 if (size == SIZE_l) *(wchar_t **)dest = wcs;
271 else *(char **)dest = s;
272 }
273 if (t != 'c') {
274 if (wcs) wcs[i] = 0;
275 if (s) s[i] = 0;
276 }
277 break;
278 case 'p':
279 case 'X':
280 case 'x':
281 base = 16;
282 goto int_common;
283 case 'o':
284 base = 8;
285 goto int_common;
286 case 'd':
287 case 'u':
288 base = 10;
289 goto int_common;
290 case 'i':
291 base = 0;
292 int_common:
293 x = __intscan(f, base, 0, ULLONG_MAX);
294 if (!shcnt(f)) goto match_fail;
295 if (t=='p' && dest) *(void **)dest = (void *)(uintptr_t)x;
296 else store_int(dest, size, x);
297 break;
298 case 'a': case 'A':
299 case 'e': case 'E':
300 case 'f': case 'F':
301 case 'g': case 'G':
302 y = __floatscan(f, size, 0);
303 if (!shcnt(f)) goto match_fail;
304 if (dest) switch (size) {
305 case SIZE_def:
306 *(float *)dest = y;
307 break;
308 case SIZE_l:
309 *(double *)dest = y;
310 break;
311 case SIZE_L:
312 *(long double *)dest = y;
313 break;
314 }
315 break;
316 }
317
318 pos += shcnt(f);
319 if (dest) matches++;
320 }
321 if (0) {
322fmt_fail:
323alloc_fail:
324input_fail:
325 if (!matches) matches--;
326match_fail:
327 if (alloc) {
328 free(s);
329 free(wcs);
330 }
331 }
332 FUNLOCK(f);
333 return matches;
334}
335
336weak_alias(vfscanf,__isoc99_vfscanf);
libc/musl/src/stdio/vfwprintf.c created+363
......@@ -0,0 +1,363 @@
1#include "stdio_impl.h"
2#include <errno.h>
3#include <ctype.h>
4#include <limits.h>
5#include <string.h>
6#include <stdarg.h>
7#include <stddef.h>
8#include <stdlib.h>
9#include <wchar.h>
10#include <inttypes.h>
11
12/* Convenient bit representation for modifier flags, which all fall
13 * within 31 codepoints of the space character. */
14
15#define ALT_FORM (1U<<'#'-' ')
16#define ZERO_PAD (1U<<'0'-' ')
17#define LEFT_ADJ (1U<<'-'-' ')
18#define PAD_POS (1U<<' '-' ')
19#define MARK_POS (1U<<'+'-' ')
20#define GROUPED (1U<<'\''-' ')
21
22#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS|GROUPED)
23
24/* State machine to accept length modifiers + conversion specifiers.
25 * Result is 0 on failure, or an argument type to pop on success. */
26
27enum {
28 BARE, LPRE, LLPRE, HPRE, HHPRE, BIGLPRE,
29 ZTPRE, JPRE,
30 STOP,
31 PTR, INT, UINT, ULLONG,
32 LONG, ULONG,
33 SHORT, USHORT, CHAR, UCHAR,
34 LLONG, SIZET, IMAX, UMAX, PDIFF, UIPTR,
35 DBL, LDBL,
36 NOARG,
37 MAXSTATE
38};
39
40#define S(x) [(x)-'A']
41
42static const unsigned char states[]['z'-'A'+1] = {
43 { /* 0: bare types */
44 S('d') = INT, S('i') = INT,
45 S('o') = UINT, S('u') = UINT, S('x') = UINT, S('X') = UINT,
46 S('e') = DBL, S('f') = DBL, S('g') = DBL, S('a') = DBL,
47 S('E') = DBL, S('F') = DBL, S('G') = DBL, S('A') = DBL,
48 S('c') = CHAR, S('C') = INT,
49 S('s') = PTR, S('S') = PTR, S('p') = UIPTR, S('n') = PTR,
50 S('m') = NOARG,
51 S('l') = LPRE, S('h') = HPRE, S('L') = BIGLPRE,
52 S('z') = ZTPRE, S('j') = JPRE, S('t') = ZTPRE,
53 }, { /* 1: l-prefixed */
54 S('d') = LONG, S('i') = LONG,
55 S('o') = ULONG, S('u') = ULONG, S('x') = ULONG, S('X') = ULONG,
56 S('c') = INT, S('s') = PTR, S('n') = PTR,
57 S('l') = LLPRE,
58 }, { /* 2: ll-prefixed */
59 S('d') = LLONG, S('i') = LLONG,
60 S('o') = ULLONG, S('u') = ULLONG,
61 S('x') = ULLONG, S('X') = ULLONG,
62 S('n') = PTR,
63 }, { /* 3: h-prefixed */
64 S('d') = SHORT, S('i') = SHORT,
65 S('o') = USHORT, S('u') = USHORT,
66 S('x') = USHORT, S('X') = USHORT,
67 S('n') = PTR,
68 S('h') = HHPRE,
69 }, { /* 4: hh-prefixed */
70 S('d') = CHAR, S('i') = CHAR,
71 S('o') = UCHAR, S('u') = UCHAR,
72 S('x') = UCHAR, S('X') = UCHAR,
73 S('n') = PTR,
74 }, { /* 5: L-prefixed */
75 S('e') = LDBL, S('f') = LDBL, S('g') = LDBL, S('a') = LDBL,
76 S('E') = LDBL, S('F') = LDBL, S('G') = LDBL, S('A') = LDBL,
77 S('n') = PTR,
78 }, { /* 6: z- or t-prefixed (assumed to be same size) */
79 S('d') = PDIFF, S('i') = PDIFF,
80 S('o') = SIZET, S('u') = SIZET,
81 S('x') = SIZET, S('X') = SIZET,
82 S('n') = PTR,
83 }, { /* 7: j-prefixed */
84 S('d') = IMAX, S('i') = IMAX,
85 S('o') = UMAX, S('u') = UMAX,
86 S('x') = UMAX, S('X') = UMAX,
87 S('n') = PTR,
88 }
89};
90
91#define OOB(x) ((unsigned)(x)-'A' > 'z'-'A')
92
93union arg
94{
95 uintmax_t i;
96 long double f;
97 void *p;
98};
99
100static void pop_arg(union arg *arg, int type, va_list *ap)
101{
102 switch (type) {
103 case PTR: arg->p = va_arg(*ap, void *);
104 break; case INT: arg->i = va_arg(*ap, int);
105 break; case UINT: arg->i = va_arg(*ap, unsigned int);
106 break; case LONG: arg->i = va_arg(*ap, long);
107 break; case ULONG: arg->i = va_arg(*ap, unsigned long);
108 break; case ULLONG: arg->i = va_arg(*ap, unsigned long long);
109 break; case SHORT: arg->i = (short)va_arg(*ap, int);
110 break; case USHORT: arg->i = (unsigned short)va_arg(*ap, int);
111 break; case CHAR: arg->i = (signed char)va_arg(*ap, int);
112 break; case UCHAR: arg->i = (unsigned char)va_arg(*ap, int);
113 break; case LLONG: arg->i = va_arg(*ap, long long);
114 break; case SIZET: arg->i = va_arg(*ap, size_t);
115 break; case IMAX: arg->i = va_arg(*ap, intmax_t);
116 break; case UMAX: arg->i = va_arg(*ap, uintmax_t);
117 break; case PDIFF: arg->i = va_arg(*ap, ptrdiff_t);
118 break; case UIPTR: arg->i = (uintptr_t)va_arg(*ap, void *);
119 break; case DBL: arg->f = va_arg(*ap, double);
120 break; case LDBL: arg->f = va_arg(*ap, long double);
121 }
122}
123
124static void out(FILE *f, const wchar_t *s, size_t l)
125{
126 while (l-- && !(f->flags & F_ERR)) fputwc(*s++, f);
127}
128
129static int getint(wchar_t **s) {
130 int i;
131 for (i=0; iswdigit(**s); (*s)++) {
132 if (i > INT_MAX/10U || **s-'0' > INT_MAX-10*i) i = -1;
133 else i = 10*i + (**s-'0');
134 }
135 return i;
136}
137
138static const char sizeprefix['y'-'a'] = {
139['a'-'a']='L', ['e'-'a']='L', ['f'-'a']='L', ['g'-'a']='L',
140['d'-'a']='j', ['i'-'a']='j', ['o'-'a']='j', ['u'-'a']='j', ['x'-'a']='j',
141['p'-'a']='j'
142};
143
144static int wprintf_core(FILE *f, const wchar_t *fmt, va_list *ap, union arg *nl_arg, int *nl_type)
145{
146 wchar_t *a, *z, *s=(wchar_t *)fmt;
147 unsigned l10n=0, fl;
148 int w, p, xp;
149 union arg arg;
150 int argpos;
151 unsigned st, ps;
152 int cnt=0, l=0;
153 int i;
154 int t;
155 char *bs;
156 char charfmt[16];
157 wchar_t wc;
158
159 for (;;) {
160 /* This error is only specified for snprintf, but since it's
161 * unspecified for other forms, do the same. Stop immediately
162 * on overflow; otherwise %n could produce wrong results. */
163 if (l > INT_MAX - cnt) goto overflow;
164
165 /* Update output count, end loop when fmt is exhausted */
166 cnt += l;
167 if (!*s) break;
168
169 /* Handle literal text and %% format specifiers */
170 for (a=s; *s && *s!='%'; s++);
171 for (z=s; s[0]=='%' && s[1]=='%'; z++, s+=2);
172 if (z-a > INT_MAX-cnt) goto overflow;
173 l = z-a;
174 if (f) out(f, a, l);
175 if (l) continue;
176
177 if (iswdigit(s[1]) && s[2]=='$') {
178 l10n=1;
179 argpos = s[1]-'0';
180 s+=3;
181 } else {
182 argpos = -1;
183 s++;
184 }
185
186 /* Read modifier flags */
187 for (fl=0; (unsigned)*s-' '<32 && (FLAGMASK&(1U<<*s-' ')); s++)
188 fl |= 1U<<*s-' ';
189
190 /* Read field width */
191 if (*s=='*') {
192 if (iswdigit(s[1]) && s[2]=='$') {
193 l10n=1;
194 nl_type[s[1]-'0'] = INT;
195 w = nl_arg[s[1]-'0'].i;
196 s+=3;
197 } else if (!l10n) {
198 w = f ? va_arg(*ap, int) : 0;
199 s++;
200 } else goto inval;
201 if (w<0) fl|=LEFT_ADJ, w=-w;
202 } else if ((w=getint(&s))<0) goto overflow;
203
204 /* Read precision */
205 if (*s=='.' && s[1]=='*') {
206 if (isdigit(s[2]) && s[3]=='$') {
207 nl_type[s[2]-'0'] = INT;
208 p = nl_arg[s[2]-'0'].i;
209 s+=4;
210 } else if (!l10n) {
211 p = f ? va_arg(*ap, int) : 0;
212 s+=2;
213 } else goto inval;
214 xp = (p>=0);
215 } else if (*s=='.') {
216 s++;
217 p = getint(&s);
218 xp = 1;
219 } else {
220 p = -1;
221 xp = 0;
222 }
223
224 /* Format specifier state machine */
225 st=0;
226 do {
227 if (OOB(*s)) goto inval;
228 ps=st;
229 st=states[st]S(*s++);
230 } while (st-1<STOP);
231 if (!st) goto inval;
232
233 /* Check validity of argument type (nl/normal) */
234 if (st==NOARG) {
235 if (argpos>=0) goto inval;
236 } else {
237 if (argpos>=0) nl_type[argpos]=st, arg=nl_arg[argpos];
238 else if (f) pop_arg(&arg, st, ap);
239 else return 0;
240 }
241
242 if (!f) continue;
243 t = s[-1];
244 if (ps && (t&15)==3) t&=~32;
245
246 switch (t) {
247 case 'n':
248 switch(ps) {
249 case BARE: *(int *)arg.p = cnt; break;
250 case LPRE: *(long *)arg.p = cnt; break;
251 case LLPRE: *(long long *)arg.p = cnt; break;
252 case HPRE: *(unsigned short *)arg.p = cnt; break;
253 case HHPRE: *(unsigned char *)arg.p = cnt; break;
254 case ZTPRE: *(size_t *)arg.p = cnt; break;
255 case JPRE: *(uintmax_t *)arg.p = cnt; break;
256 }
257 continue;
258 case 'c':
259 if (w<1) w=1;
260 if (w>1 && !(fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, "");
261 fputwc(btowc(arg.i), f);
262 if (w>1 && (fl&LEFT_ADJ)) fprintf(f, "%*s", w-1, "");
263 l = w;
264 continue;
265 case 'C':
266 fputwc(arg.i, f);
267 l = 1;
268 continue;
269 case 'S':
270 a = arg.p;
271 z = a + wcsnlen(a, p<0 ? INT_MAX : p);
272 if (p<0 && *z) goto overflow;
273 p = z-a;
274 if (w<p) w=p;
275 if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
276 out(f, a, p);
277 if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
278 l=w;
279 continue;
280 case 'm':
281 arg.p = strerror(errno);
282 case 's':
283 if (!arg.p) arg.p = "(null)";
284 bs = arg.p;
285 for (i=l=0; l<(p<0?INT_MAX:p) && (i=mbtowc(&wc, bs, MB_LEN_MAX))>0; bs+=i, l++);
286 if (i<0) return -1;
287 if (p<0 && *bs) goto overflow;
288 p=l;
289 if (w<p) w=p;
290 if (!(fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
291 bs = arg.p;
292 while (l--) {
293 i=mbtowc(&wc, bs, MB_LEN_MAX);
294 bs+=i;
295 fputwc(wc, f);
296 }
297 if ((fl&LEFT_ADJ)) fprintf(f, "%*s", w-p, "");
298 l=w;
299 continue;
300 }
301
302 if (xp && p<0) goto overflow;
303 snprintf(charfmt, sizeof charfmt, "%%%s%s%s%s%s*.*%c%c",
304 "#"+!(fl & ALT_FORM),
305 "+"+!(fl & MARK_POS),
306 "-"+!(fl & LEFT_ADJ),
307 " "+!(fl & PAD_POS),
308 "0"+!(fl & ZERO_PAD),
309 sizeprefix[(t|32)-'a'], t);
310
311 switch (t|32) {
312 case 'a': case 'e': case 'f': case 'g':
313 l = fprintf(f, charfmt, w, p, arg.f);
314 break;
315 case 'd': case 'i': case 'o': case 'u': case 'x': case 'p':
316 l = fprintf(f, charfmt, w, p, arg.i);
317 break;
318 }
319 }
320
321 if (f) return cnt;
322 if (!l10n) return 0;
323
324 for (i=1; i<=NL_ARGMAX && nl_type[i]; i++)
325 pop_arg(nl_arg+i, nl_type[i], ap);
326 for (; i<=NL_ARGMAX && !nl_type[i]; i++);
327 if (i<=NL_ARGMAX) return -1;
328 return 1;
329
330inval:
331 errno = EINVAL;
332 return -1;
333overflow:
334 errno = EOVERFLOW;
335 return -1;
336}
337
338int vfwprintf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
339{
340 va_list ap2;
341 int nl_type[NL_ARGMAX] = {0};
342 union arg nl_arg[NL_ARGMAX];
343 int olderr;
344 int ret;
345
346 /* the copy allows passing va_list* even if va_list is an array */
347 va_copy(ap2, ap);
348 if (wprintf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) {
349 va_end(ap2);
350 return -1;
351 }
352
353 FLOCK(f);
354 fwide(f, 1);
355 olderr = f->flags & F_ERR;
356 f->flags &= ~F_ERR;
357 ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
358 if (f->flags & F_ERR) ret = -1;
359 f->flags |= olderr;
360 FUNLOCK(f);
361 va_end(ap2);
362 return ret;
363}
libc/musl/src/stdio/vfwscanf.c created+332
......@@ -0,0 +1,332 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <stdarg.h>
4#include <ctype.h>
5#include <wchar.h>
6#include <wctype.h>
7#include <limits.h>
8#include <string.h>
9
10#include "stdio_impl.h"
11#include "shgetc.h"
12#include "intscan.h"
13#include "floatscan.h"
14
15#define SIZE_hh -2
16#define SIZE_h -1
17#define SIZE_def 0
18#define SIZE_l 1
19#define SIZE_L 2
20#define SIZE_ll 3
21
22static void store_int(void *dest, int size, unsigned long long i)
23{
24 if (!dest) return;
25 switch (size) {
26 case SIZE_hh:
27 *(char *)dest = i;
28 break;
29 case SIZE_h:
30 *(short *)dest = i;
31 break;
32 case SIZE_def:
33 *(int *)dest = i;
34 break;
35 case SIZE_l:
36 *(long *)dest = i;
37 break;
38 case SIZE_ll:
39 *(long long *)dest = i;
40 break;
41 }
42}
43
44static void *arg_n(va_list ap, unsigned int n)
45{
46 void *p;
47 unsigned int i;
48 va_list ap2;
49 va_copy(ap2, ap);
50 for (i=n; i>1; i--) va_arg(ap2, void *);
51 p = va_arg(ap2, void *);
52 va_end(ap2);
53 return p;
54}
55
56static int in_set(const wchar_t *set, int c)
57{
58 int j;
59 const wchar_t *p = set;
60 if (*p == '-') {
61 if (c=='-') return 1;
62 p++;
63 } else if (*p == ']') {
64 if (c==']') return 1;
65 p++;
66 }
67 for (; *p && *p != ']'; p++) {
68 if (*p=='-' && p[1] && p[1] != ']')
69 for (j=p++[-1]; j<*p; j++)
70 if (c==j) return 1;
71 if (c==*p) return 1;
72 }
73 return 0;
74}
75
76#if 1
77#undef getwc
78#define getwc(f) \
79 ((f)->rpos != (f)->rend && *(f)->rpos < 128 ? *(f)->rpos++ : (getwc)(f))
80
81#undef ungetwc
82#define ungetwc(c,f) \
83 ((f)->rend && (c)<128U ? *--(f)->rpos : ungetwc((c),(f)))
84#endif
85
86int vfwscanf(FILE *restrict f, const wchar_t *restrict fmt, va_list ap)
87{
88 int width;
89 int size;
90 int alloc;
91 const wchar_t *p;
92 int c, t;
93 char *s;
94 wchar_t *wcs;
95 void *dest=NULL;
96 int invert;
97 int matches=0;
98 off_t pos = 0, cnt;
99 static const char size_pfx[][3] = { "hh", "h", "", "l", "L", "ll" };
100 char tmp[3*sizeof(int)+10];
101 const wchar_t *set;
102 size_t i, k;
103
104 FLOCK(f);
105
106 fwide(f, 1);
107
108 for (p=fmt; *p; p++) {
109
110 alloc = 0;
111
112 if (iswspace(*p)) {
113 while (iswspace(p[1])) p++;
114 while (iswspace((c=getwc(f)))) pos++;
115 ungetwc(c, f);
116 continue;
117 }
118 if (*p != '%' || p[1] == '%') {
119 if (*p == '%') {
120 p++;
121 while (iswspace((c=getwc(f)))) pos++;
122 } else {
123 c = getwc(f);
124 }
125 if (c!=*p) {
126 ungetwc(c, f);
127 if (c<0) goto input_fail;
128 goto match_fail;
129 }
130 pos++;
131 continue;
132 }
133
134 p++;
135 if (*p=='*') {
136 dest = 0; p++;
137 } else if (iswdigit(*p) && p[1]=='$') {
138 dest = arg_n(ap, *p-'0'); p+=2;
139 } else {
140 dest = va_arg(ap, void *);
141 }
142
143 for (width=0; iswdigit(*p); p++) {
144 width = 10*width + *p - '0';
145 }
146
147 if (*p=='m') {
148 wcs = 0;
149 s = 0;
150 alloc = !!dest;
151 p++;
152 } else {
153 alloc = 0;
154 }
155
156 size = SIZE_def;
157 switch (*p++) {
158 case 'h':
159 if (*p == 'h') p++, size = SIZE_hh;
160 else size = SIZE_h;
161 break;
162 case 'l':
163 if (*p == 'l') p++, size = SIZE_ll;
164 else size = SIZE_l;
165 break;
166 case 'j':
167 size = SIZE_ll;
168 break;
169 case 'z':
170 case 't':
171 size = SIZE_l;
172 break;
173 case 'L':
174 size = SIZE_L;
175 break;
176 case 'd': case 'i': case 'o': case 'u': case 'x':
177 case 'a': case 'e': case 'f': case 'g':
178 case 'A': case 'E': case 'F': case 'G': case 'X':
179 case 's': case 'c': case '[':
180 case 'S': case 'C':
181 case 'p': case 'n':
182 p--;
183 break;
184 default:
185 goto fmt_fail;
186 }
187
188 t = *p;
189
190 /* Transform S,C -> ls,lc */
191 if ((t&0x2f)==3) {
192 size = SIZE_l;
193 t |= 32;
194 }
195
196 if (t != 'n') {
197 if (t != '[' && (t|32) != 'c')
198 while (iswspace((c=getwc(f)))) pos++;
199 else
200 c=getwc(f);
201 if (c < 0) goto input_fail;
202 ungetwc(c, f);
203 }
204
205 switch (t) {
206 case 'n':
207 store_int(dest, size, pos);
208 /* do not increment match count, etc! */
209 continue;
210
211 case 's':
212 case 'c':
213 case '[':
214 if (t == 'c') {
215 if (width<1) width = 1;
216 invert = 1;
217 set = L"";
218 } else if (t == 's') {
219 invert = 1;
220 static const wchar_t spaces[] = {
221 ' ', '\t', '\n', '\r', 11, 12, 0x0085,
222 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005,
223 0x2006, 0x2008, 0x2009, 0x200a,
224 0x2028, 0x2029, 0x205f, 0x3000, 0 };
225 set = spaces;
226 } else {
227 if (*++p == '^') p++, invert = 1;
228 else invert = 0;
229 set = p;
230 if (*p==']') p++;
231 while (*p!=']') {
232 if (!*p) goto fmt_fail;
233 p++;
234 }
235 }
236
237 s = (size == SIZE_def) ? dest : 0;
238 wcs = (size == SIZE_l) ? dest : 0;
239
240 int gotmatch = 0;
241
242 if (width < 1) width = -1;
243
244 i = 0;
245 if (alloc) {
246 k = t=='c' ? width+1U : 31;
247 if (size == SIZE_l) {
248 wcs = malloc(k*sizeof(wchar_t));
249 if (!wcs) goto alloc_fail;
250 } else {
251 s = malloc(k);
252 if (!s) goto alloc_fail;
253 }
254 }
255 while (width) {
256 if ((c=getwc(f))<0) break;
257 if (in_set(set, c) == invert)
258 break;
259 if (wcs) {
260 wcs[i++] = c;
261 if (alloc && i==k) {
262 k += k+1;
263 wchar_t *tmp = realloc(wcs, k*sizeof(wchar_t));
264 if (!tmp) goto alloc_fail;
265 wcs = tmp;
266 }
267 } else if (size != SIZE_l) {
268 int l = wctomb(s?s+i:tmp, c);
269 if (l<0) goto input_fail;
270 i += l;
271 if (alloc && i > k-4) {
272 k += k+1;
273 char *tmp = realloc(s, k);
274 if (!tmp) goto alloc_fail;
275 s = tmp;
276 }
277 }
278 pos++;
279 width-=(width>0);
280 gotmatch=1;
281 }
282 if (width) {
283 ungetwc(c, f);
284 if (t == 'c' || !gotmatch) goto match_fail;
285 }
286
287 if (alloc) {
288 if (size == SIZE_l) *(wchar_t **)dest = wcs;
289 else *(char **)dest = s;
290 }
291 if (t != 'c') {
292 if (wcs) wcs[i] = 0;
293 if (s) s[i] = 0;
294 }
295 break;
296
297 case 'd': case 'i': case 'o': case 'u': case 'x':
298 case 'a': case 'e': case 'f': case 'g':
299 case 'A': case 'E': case 'F': case 'G': case 'X':
300 case 'p':
301 if (width < 1) width = 0;
302 snprintf(tmp, sizeof tmp, "%.*s%.0d%s%c%%lln",
303 1+!dest, "%*", width, size_pfx[size+2], t);
304 cnt = 0;
305 if (fscanf(f, tmp, dest?dest:&cnt, &cnt) == -1)
306 goto input_fail;
307 else if (!cnt)
308 goto match_fail;
309 pos += cnt;
310 break;
311 default:
312 goto fmt_fail;
313 }
314
315 if (dest) matches++;
316 }
317 if (0) {
318fmt_fail:
319alloc_fail:
320input_fail:
321 if (!matches) matches--;
322match_fail:
323 if (alloc) {
324 free(s);
325 free(wcs);
326 }
327 }
328 FUNLOCK(f);
329 return matches;
330}
331
332weak_alias(vfwscanf,__isoc99_vfwscanf);
libc/musl/src/stdio/vprintf.c created+6
......@@ -0,0 +1,6 @@
1#include <stdio.h>
2
3int vprintf(const char *restrict fmt, va_list ap)
4{
5 return vfprintf(stdout, fmt, ap);
6}
libc/musl/src/stdio/vscanf.c created+9
......@@ -0,0 +1,9 @@
1#include <stdio.h>
2#include <stdarg.h>
3
4int vscanf(const char *restrict fmt, va_list ap)
5{
6 return vfscanf(stdin, fmt, ap);
7}
8
9weak_alias(vscanf,__isoc99_vscanf);
libc/musl/src/stdio/vsnprintf.c created+55
......@@ -0,0 +1,55 @@
1#include "stdio_impl.h"
2#include <limits.h>
3#include <string.h>
4#include <errno.h>
5#include <stdint.h>
6
7struct cookie {
8 char *s;
9 size_t n;
10};
11
12#define MIN(a, b) ((a) < (b) ? (a) : (b))
13
14static size_t sn_write(FILE *f, const unsigned char *s, size_t l)
15{
16 struct cookie *c = f->cookie;
17 size_t k = MIN(c->n, f->wpos - f->wbase);
18 if (k) {
19 memcpy(c->s, f->wbase, k);
20 c->s += k;
21 c->n -= k;
22 }
23 k = MIN(c->n, l);
24 if (k) {
25 memcpy(c->s, s, k);
26 c->s += k;
27 c->n -= k;
28 }
29 *c->s = 0;
30 f->wpos = f->wbase = f->buf;
31 /* pretend to succeed, even if we discarded extra data */
32 return l;
33}
34
35int vsnprintf(char *restrict s, size_t n, const char *restrict fmt, va_list ap)
36{
37 unsigned char buf[1];
38 char dummy[1];
39 struct cookie c = { .s = n ? s : dummy, .n = n ? n-1 : 0 };
40 FILE f = {
41 .lbf = EOF,
42 .write = sn_write,
43 .lock = -1,
44 .buf = buf,
45 .cookie = &c,
46 };
47
48 if (n > INT_MAX) {
49 errno = EOVERFLOW;
50 return -1;
51 }
52
53 *c.s = 0;
54 return vfprintf(&f, fmt, ap);
55}
libc/musl/src/stdio/vsprintf.c created+7
......@@ -0,0 +1,7 @@
1#include <stdio.h>
2#include <limits.h>
3
4int vsprintf(char *restrict s, const char *restrict fmt, va_list ap)
5{
6 return vsnprintf(s, INT_MAX, fmt, ap);
7}
libc/musl/src/stdio/vsscanf.c created+17
......@@ -0,0 +1,17 @@
1#include "stdio_impl.h"
2
3static size_t do_read(FILE *f, unsigned char *buf, size_t len)
4{
5 return __string_read(f, buf, len);
6}
7
8int vsscanf(const char *restrict s, const char *restrict fmt, va_list ap)
9{
10 FILE f = {
11 .buf = (void *)s, .cookie = (void *)s,
12 .read = do_read, .lock = -1
13 };
14 return vfscanf(&f, fmt, ap);
15}
16
17weak_alias(vsscanf,__isoc99_vsscanf);
libc/musl/src/stdio/vswprintf.c created+60
......@@ -0,0 +1,60 @@
1#include "stdio_impl.h"
2#include <limits.h>
3#include <errno.h>
4#include <stdint.h>
5#include <stdlib.h>
6#include <wchar.h>
7
8struct cookie {
9 wchar_t *ws;
10 size_t l;
11};
12
13static size_t sw_write(FILE *f, const unsigned char *s, size_t l)
14{
15 size_t l0 = l;
16 int i = 0;
17 struct cookie *c = f->cookie;
18 if (s!=f->wbase && sw_write(f, f->wbase, f->wpos-f->wbase)==-1)
19 return -1;
20 while (c->l && l && (i=mbtowc(c->ws, (void *)s, l))>=0) {
21 s+=i;
22 l-=i;
23 c->l--;
24 c->ws++;
25 }
26 *c->ws = 0;
27 if (i < 0) {
28 f->wpos = f->wbase = f->wend = 0;
29 f->flags |= F_ERR;
30 return i;
31 }
32 f->wend = f->buf + f->buf_size;
33 f->wpos = f->wbase = f->buf;
34 return l0;
35}
36
37int vswprintf(wchar_t *restrict s, size_t n, const wchar_t *restrict fmt, va_list ap)
38{
39 int r;
40 unsigned char buf[256];
41 struct cookie c = { s, n-1 };
42 FILE f = {
43 .lbf = EOF,
44 .write = sw_write,
45 .lock = -1,
46 .buf = buf,
47 .buf_size = sizeof buf,
48 .cookie = &c,
49 };
50
51 if (!n) {
52 return -1;
53 } else if (n > INT_MAX) {
54 errno = EOVERFLOW;
55 return -1;
56 }
57 r = vfwprintf(&f, fmt, ap);
58 sw_write(&f, 0, 0);
59 return r>=n ? -1 : r;
60}
libc/musl/src/stdio/vswscanf.c created+38
......@@ -0,0 +1,38 @@
1#include "stdio_impl.h"
2#include <wchar.h>
3
4static size_t wstring_read(FILE *f, unsigned char *buf, size_t len)
5{
6 const wchar_t *src = f->cookie;
7 size_t k;
8
9 if (!src) return 0;
10
11 k = wcsrtombs((void *)f->buf, &src, f->buf_size, 0);
12 if (k==(size_t)-1) {
13 f->rpos = f->rend = 0;
14 return 0;
15 }
16
17 f->rpos = f->buf;
18 f->rend = f->buf + k;
19 f->cookie = (void *)src;
20
21 if (!len || !k) return 0;
22
23 *buf = *f->rpos++;
24 return 1;
25}
26
27int vswscanf(const wchar_t *restrict s, const wchar_t *restrict fmt, va_list ap)
28{
29 unsigned char buf[256];
30 FILE f = {
31 .buf = buf, .buf_size = sizeof buf,
32 .cookie = (void *)s,
33 .read = wstring_read, .lock = -1
34 };
35 return vfwscanf(&f, fmt, ap);
36}
37
38weak_alias(vswscanf,__isoc99_vswscanf);
libc/musl/src/stdio/vwprintf.c created+7
......@@ -0,0 +1,7 @@
1#include <stdio.h>
2#include <wchar.h>
3
4int vwprintf(const wchar_t *restrict fmt, va_list ap)
5{
6 return vfwprintf(stdout, fmt, ap);
7}
libc/musl/src/stdio/vwscanf.c created+10
......@@ -0,0 +1,10 @@
1#include <stdio.h>
2#include <stdarg.h>
3#include <wchar.h>
4
5int vwscanf(const wchar_t *restrict fmt, va_list ap)
6{
7 return vfwscanf(stdin, fmt, ap);
8}
9
10weak_alias(vwscanf,__isoc99_vwscanf);
libc/musl/src/stdio/wprintf.c created+13
......@@ -0,0 +1,13 @@
1#include <stdio.h>
2#include <stdarg.h>
3#include <wchar.h>
4
5int wprintf(const wchar_t *restrict fmt, ...)
6{
7 int ret;
8 va_list ap;
9 va_start(ap, fmt);
10 ret = vwprintf(fmt, ap);
11 va_end(ap);
12 return ret;
13}
libc/musl/src/stdio/wscanf.c created+15
......@@ -0,0 +1,15 @@
1#include <stdio.h>
2#include <stdarg.h>
3#include <wchar.h>
4
5int wscanf(const wchar_t *restrict fmt, ...)
6{
7 int ret;
8 va_list ap;
9 va_start(ap, fmt);
10 ret = vwscanf(fmt, ap);
11 va_end(ap);
12 return ret;
13}
14
15weak_alias(wscanf,__isoc99_wscanf);
libc/musl/src/stdlib/abs.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3int abs(int a)
4{
5 return a>0 ? a : -a;
6}
libc/musl/src/stdlib/atof.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3double atof(const char *s)
4{
5 return strtod(s, 0);
6}
libc/musl/src/stdlib/atoi.c created+16
......@@ -0,0 +1,16 @@
1#include <stdlib.h>
2#include <ctype.h>
3
4int atoi(const char *s)
5{
6 int n=0, neg=0;
7 while (isspace(*s)) s++;
8 switch (*s) {
9 case '-': neg=1;
10 case '+': s++;
11 }
12 /* Compute n as a negative number to avoid overflow on INT_MIN */
13 while (isdigit(*s))
14 n = 10*n - (*s++ - '0');
15 return neg ? n : -n;
16}
libc/musl/src/stdlib/atol.c created+17
......@@ -0,0 +1,17 @@
1#include <stdlib.h>
2#include <ctype.h>
3
4long atol(const char *s)
5{
6 long n=0;
7 int neg=0;
8 while (isspace(*s)) s++;
9 switch (*s) {
10 case '-': neg=1;
11 case '+': s++;
12 }
13 /* Compute n as a negative number to avoid overflow on LONG_MIN */
14 while (isdigit(*s))
15 n = 10*n - (*s++ - '0');
16 return neg ? n : -n;
17}
libc/musl/src/stdlib/atoll.c created+17
......@@ -0,0 +1,17 @@
1#include <stdlib.h>
2#include <ctype.h>
3
4long long atoll(const char *s)
5{
6 long long n=0;
7 int neg=0;
8 while (isspace(*s)) s++;
9 switch (*s) {
10 case '-': neg=1;
11 case '+': s++;
12 }
13 /* Compute n as a negative number to avoid overflow on LLONG_MIN */
14 while (isdigit(*s))
15 n = 10*n - (*s++ - '0');
16 return neg ? n : -n;
17}
libc/musl/src/stdlib/bsearch.c created+20
......@@ -0,0 +1,20 @@
1#include <stdlib.h>
2
3void *bsearch(const void *key, const void *base, size_t nel, size_t width, int (*cmp)(const void *, const void *))
4{
5 void *try;
6 int sign;
7 while (nel > 0) {
8 try = (char *)base + width*(nel/2);
9 sign = cmp(key, try);
10 if (sign < 0) {
11 nel /= 2;
12 } else if (sign > 0) {
13 base = (char *)try + width;
14 nel -= nel/2+1;
15 } else {
16 return try;
17 }
18 }
19 return NULL;
20}
libc/musl/src/stdlib/div.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3div_t div(int num, int den)
4{
5 return (div_t){ num/den, num%den };
6}
libc/musl/src/stdlib/ecvt.c created+20
......@@ -0,0 +1,20 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <stdio.h>
4
5char *ecvt(double x, int n, int *dp, int *sign)
6{
7 static char buf[16];
8 char tmp[32];
9 int i, j;
10
11 if (n-1U > 15) n = 15;
12 sprintf(tmp, "%.*e", n-1, x);
13 i = *sign = (tmp[0]=='-');
14 for (j=0; tmp[i]!='e'; j+=(tmp[i++]!='.'))
15 buf[j] = tmp[i];
16 buf[j] = 0;
17 *dp = atoi(tmp+i+1)+1;
18
19 return buf;
20}
libc/musl/src/stdlib/fcvt.c created+25
......@@ -0,0 +1,25 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5
6char *fcvt(double x, int n, int *dp, int *sign)
7{
8 char tmp[1500];
9 int i, lz;
10
11 if (n > 1400U) n = 1400;
12 sprintf(tmp, "%.*f", n, x);
13 i = (tmp[0] == '-');
14 if (tmp[i] == '0') lz = strspn(tmp+i+2, "0");
15 else lz = -(int)strcspn(tmp+i, ".");
16
17 if (n<=lz) {
18 *sign = i;
19 *dp = 1;
20 if (n>14U) n = 14;
21 return "000000000000000"+14-n;
22 }
23
24 return ecvt(x, n-lz, dp, sign);
25}
libc/musl/src/stdlib/gcvt.c created+9
......@@ -0,0 +1,9 @@
1#define _GNU_SOURCE
2#include <stdlib.h>
3#include <stdio.h>
4
5char *gcvt(double x, int n, char *b)
6{
7 sprintf(b, "%.*g", n, x);
8 return b;
9}
libc/musl/src/stdlib/imaxabs.c created+6
......@@ -0,0 +1,6 @@
1#include <inttypes.h>
2
3intmax_t imaxabs(intmax_t a)
4{
5 return a>0 ? a : -a;
6}
libc/musl/src/stdlib/imaxdiv.c created+6
......@@ -0,0 +1,6 @@
1#include <inttypes.h>
2
3imaxdiv_t imaxdiv(intmax_t num, intmax_t den)
4{
5 return (imaxdiv_t){ num/den, num%den };
6}
libc/musl/src/stdlib/labs.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3long labs(long a)
4{
5 return a>0 ? a : -a;
6}
libc/musl/src/stdlib/ldiv.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3ldiv_t ldiv(long num, long den)
4{
5 return (ldiv_t){ num/den, num%den };
6}
libc/musl/src/stdlib/llabs.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3long long llabs(long long a)
4{
5 return a>0 ? a : -a;
6}
libc/musl/src/stdlib/lldiv.c created+6
......@@ -0,0 +1,6 @@
1#include <stdlib.h>
2
3lldiv_t lldiv(long long num, long long den)
4{
5 return (lldiv_t){ num/den, num%den };
6}
libc/musl/src/stdlib/qsort.c created+218
......@@ -0,0 +1,218 @@
1/* Copyright (C) 2011 by Valentin Ochs
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to
5 * deal in the Software without restriction, including without limitation the
6 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7 * sell copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19 * IN THE SOFTWARE.
20 */
21
22/* Minor changes by Rich Felker for integration in musl, 2011-04-27. */
23
24/* Smoothsort, an adaptive variant of Heapsort. Memory usage: O(1).
25 Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */
26
27#include <stdint.h>
28#include <stdlib.h>
29#include <string.h>
30
31#include "atomic.h"
32#define ntz(x) a_ctz_l((x))
33
34typedef int (*cmpfun)(const void *, const void *);
35
36static inline int pntz(size_t p[2]) {
37 int r = ntz(p[0] - 1);
38 if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) {
39 return r;
40 }
41 return 0;
42}
43
44static void cycle(size_t width, unsigned char* ar[], int n)
45{
46 unsigned char tmp[256];
47 size_t l;
48 int i;
49
50 if(n < 2) {
51 return;
52 }
53
54 ar[n] = tmp;
55 while(width) {
56 l = sizeof(tmp) < width ? sizeof(tmp) : width;
57 memcpy(ar[n], ar[0], l);
58 for(i = 0; i < n; i++) {
59 memcpy(ar[i], ar[i + 1], l);
60 ar[i] += l;
61 }
62 width -= l;
63 }
64}
65
66/* shl() and shr() need n > 0 */
67static inline void shl(size_t p[2], int n)
68{
69 if(n >= 8 * sizeof(size_t)) {
70 n -= 8 * sizeof(size_t);
71 p[1] = p[0];
72 p[0] = 0;
73 }
74 p[1] <<= n;
75 p[1] |= p[0] >> (sizeof(size_t) * 8 - n);
76 p[0] <<= n;
77}
78
79static inline void shr(size_t p[2], int n)
80{
81 if(n >= 8 * sizeof(size_t)) {
82 n -= 8 * sizeof(size_t);
83 p[0] = p[1];
84 p[1] = 0;
85 }
86 p[0] >>= n;
87 p[0] |= p[1] << (sizeof(size_t) * 8 - n);
88 p[1] >>= n;
89}
90
91static void sift(unsigned char *head, size_t width, cmpfun cmp, int pshift, size_t lp[])
92{
93 unsigned char *rt, *lf;
94 unsigned char *ar[14 * sizeof(size_t) + 1];
95 int i = 1;
96
97 ar[0] = head;
98 while(pshift > 1) {
99 rt = head - width;
100 lf = head - width - lp[pshift - 2];
101
102 if((*cmp)(ar[0], lf) >= 0 && (*cmp)(ar[0], rt) >= 0) {
103 break;
104 }
105 if((*cmp)(lf, rt) >= 0) {
106 ar[i++] = lf;
107 head = lf;
108 pshift -= 1;
109 } else {
110 ar[i++] = rt;
111 head = rt;
112 pshift -= 2;
113 }
114 }
115 cycle(width, ar, i);
116}
117
118static void trinkle(unsigned char *head, size_t width, cmpfun cmp, size_t pp[2], int pshift, int trusty, size_t lp[])
119{
120 unsigned char *stepson,
121 *rt, *lf;
122 size_t p[2];
123 unsigned char *ar[14 * sizeof(size_t) + 1];
124 int i = 1;
125 int trail;
126
127 p[0] = pp[0];
128 p[1] = pp[1];
129
130 ar[0] = head;
131 while(p[0] != 1 || p[1] != 0) {
132 stepson = head - lp[pshift];
133 if((*cmp)(stepson, ar[0]) <= 0) {
134 break;
135 }
136 if(!trusty && pshift > 1) {
137 rt = head - width;
138 lf = head - width - lp[pshift - 2];
139 if((*cmp)(rt, stepson) >= 0 || (*cmp)(lf, stepson) >= 0) {
140 break;
141 }
142 }
143
144 ar[i++] = stepson;
145 head = stepson;
146 trail = pntz(p);
147 shr(p, trail);
148 pshift += trail;
149 trusty = 0;
150 }
151 if(!trusty) {
152 cycle(width, ar, i);
153 sift(head, width, cmp, pshift, lp);
154 }
155}
156
157void qsort(void *base, size_t nel, size_t width, cmpfun cmp)
158{
159 size_t lp[12*sizeof(size_t)];
160 size_t i, size = width * nel;
161 unsigned char *head, *high;
162 size_t p[2] = {1, 0};
163 int pshift = 1;
164 int trail;
165
166 if (!size) return;
167
168 head = base;
169 high = head + size - width;
170
171 /* Precompute Leonardo numbers, scaled by element width */
172 for(lp[0]=lp[1]=width, i=2; (lp[i]=lp[i-2]+lp[i-1]+width) < size; i++);
173
174 while(head < high) {
175 if((p[0] & 3) == 3) {
176 sift(head, width, cmp, pshift, lp);
177 shr(p, 2);
178 pshift += 2;
179 } else {
180 if(lp[pshift - 1] >= high - head) {
181 trinkle(head, width, cmp, p, pshift, 0, lp);
182 } else {
183 sift(head, width, cmp, pshift, lp);
184 }
185
186 if(pshift == 1) {
187 shl(p, 1);
188 pshift = 0;
189 } else {
190 shl(p, pshift - 1);
191 pshift = 1;
192 }
193 }
194
195 p[0] |= 1;
196 head += width;
197 }
198
199 trinkle(head, width, cmp, p, pshift, 0, lp);
200
201 while(pshift != 1 || p[0] != 1 || p[1] != 0) {
202 if(pshift <= 1) {
203 trail = pntz(p);
204 shr(p, trail);
205 pshift += trail;
206 } else {
207 shl(p, 2);
208 pshift -= 2;
209 p[0] ^= 7;
210 shr(p, 1);
211 trinkle(head - lp[pshift] - width, width, cmp, p, pshift + 1, 1, lp);
212 shl(p, 1);
213 p[0] |= 1;
214 trinkle(head - width, width, cmp, p, pshift, 1, lp);
215 }
216 head -= width;
217 }
218}
libc/musl/src/stdlib/strtod.c created+37
......@@ -0,0 +1,37 @@
1#include <stdlib.h>
2#include "shgetc.h"
3#include "floatscan.h"
4#include "stdio_impl.h"
5
6static long double strtox(const char *s, char **p, int prec)
7{
8 FILE f;
9 sh_fromstring(&f, s);
10 shlim(&f, 0);
11 long double y = __floatscan(&f, prec, 1);
12 off_t cnt = shcnt(&f);
13 if (p) *p = cnt ? (char *)s + cnt : (char *)s;
14 return y;
15}
16
17float strtof(const char *restrict s, char **restrict p)
18{
19 return strtox(s, p, 0);
20}
21
22double strtod(const char *restrict s, char **restrict p)
23{
24 return strtox(s, p, 1);
25}
26
27long double strtold(const char *restrict s, char **restrict p)
28{
29 return strtox(s, p, 2);
30}
31
32weak_alias(strtof, strtof_l);
33weak_alias(strtod, strtod_l);
34weak_alias(strtold, strtold_l);
35weak_alias(strtof, __strtof_l);
36weak_alias(strtod, __strtod_l);
37weak_alias(strtold, __strtold_l);
libc/musl/src/stdlib/strtol.c created+56
......@@ -0,0 +1,56 @@
1#include "stdio_impl.h"
2#include "intscan.h"
3#include "shgetc.h"
4#include <inttypes.h>
5#include <limits.h>
6#include <ctype.h>
7
8static unsigned long long strtox(const char *s, char **p, int base, unsigned long long lim)
9{
10 FILE f;
11 sh_fromstring(&f, s);
12 shlim(&f, 0);
13 unsigned long long y = __intscan(&f, base, 1, lim);
14 if (p) {
15 size_t cnt = shcnt(&f);
16 *p = (char *)s + cnt;
17 }
18 return y;
19}
20
21unsigned long long strtoull(const char *restrict s, char **restrict p, int base)
22{
23 return strtox(s, p, base, ULLONG_MAX);
24}
25
26long long strtoll(const char *restrict s, char **restrict p, int base)
27{
28 return strtox(s, p, base, LLONG_MIN);
29}
30
31unsigned long strtoul(const char *restrict s, char **restrict p, int base)
32{
33 return strtox(s, p, base, ULONG_MAX);
34}
35
36long strtol(const char *restrict s, char **restrict p, int base)
37{
38 return strtox(s, p, base, 0UL+LONG_MIN);
39}
40
41intmax_t strtoimax(const char *restrict s, char **restrict p, int base)
42{
43 return strtoll(s, p, base);
44}
45
46uintmax_t strtoumax(const char *restrict s, char **restrict p, int base)
47{
48 return strtoull(s, p, base);
49}
50
51weak_alias(strtol, __strtol_internal);
52weak_alias(strtoul, __strtoul_internal);
53weak_alias(strtoll, __strtoll_internal);
54weak_alias(strtoull, __strtoull_internal);
55weak_alias(strtoimax, __strtoimax_internal);
56weak_alias(strtoumax, __strtoumax_internal);
libc/musl/src/stdlib/wcstod.c created+65
......@@ -0,0 +1,65 @@
1#include "shgetc.h"
2#include "floatscan.h"
3#include "stdio_impl.h"
4#include <wchar.h>
5#include <wctype.h>
6
7/* This read function heavily cheats. It knows:
8 * (1) len will always be 1
9 * (2) non-ascii characters don't matter */
10
11static size_t do_read(FILE *f, unsigned char *buf, size_t len)
12{
13 size_t i;
14 const wchar_t *wcs = f->cookie;
15
16 if (!wcs[0]) wcs=L"@";
17 for (i=0; i<f->buf_size && wcs[i]; i++)
18 f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
19 f->rpos = f->buf;
20 f->rend = f->buf + i;
21 f->cookie = (void *)(wcs+i);
22
23 if (i && len) {
24 *buf = *f->rpos++;
25 return 1;
26 }
27 return 0;
28}
29
30static long double wcstox(const wchar_t *s, wchar_t **p, int prec)
31{
32 wchar_t *t = (wchar_t *)s;
33 unsigned char buf[64];
34 FILE f = {0};
35 f.flags = 0;
36 f.rpos = f.rend = 0;
37 f.buf = buf + 4;
38 f.buf_size = sizeof buf - 4;
39 f.lock = -1;
40 f.read = do_read;
41 while (iswspace(*t)) t++;
42 f.cookie = (void *)t;
43 shlim(&f, 0);
44 long double y = __floatscan(&f, prec, 1);
45 if (p) {
46 size_t cnt = shcnt(&f);
47 *p = cnt ? t + cnt : (wchar_t *)s;
48 }
49 return y;
50}
51
52float wcstof(const wchar_t *restrict s, wchar_t **restrict p)
53{
54 return wcstox(s, p, 0);
55}
56
57double wcstod(const wchar_t *restrict s, wchar_t **restrict p)
58{
59 return wcstox(s, p, 1);
60}
61
62long double wcstold(const wchar_t *restrict s, wchar_t **restrict p)
63{
64 return wcstox(s, p, 2);
65}
libc/musl/src/stdlib/wcstol.c created+82
......@@ -0,0 +1,82 @@
1#include "stdio_impl.h"
2#include "intscan.h"
3#include "shgetc.h"
4#include <inttypes.h>
5#include <limits.h>
6#include <wctype.h>
7#include <wchar.h>
8
9/* This read function heavily cheats. It knows:
10 * (1) len will always be 1
11 * (2) non-ascii characters don't matter */
12
13static size_t do_read(FILE *f, unsigned char *buf, size_t len)
14{
15 size_t i;
16 const wchar_t *wcs = f->cookie;
17
18 if (!wcs[0]) wcs=L"@";
19 for (i=0; i<f->buf_size && wcs[i]; i++)
20 f->buf[i] = wcs[i] < 128 ? wcs[i] : '@';
21 f->rpos = f->buf;
22 f->rend = f->buf + i;
23 f->cookie = (void *)(wcs+i);
24
25 if (i && len) {
26 *buf = *f->rpos++;
27 return 1;
28 }
29 return 0;
30}
31
32static unsigned long long wcstox(const wchar_t *s, wchar_t **p, int base, unsigned long long lim)
33{
34 wchar_t *t = (wchar_t *)s;
35 unsigned char buf[64];
36 FILE f = {0};
37 f.flags = 0;
38 f.rpos = f.rend = 0;
39 f.buf = buf + 4;
40 f.buf_size = sizeof buf - 4;
41 f.lock = -1;
42 f.read = do_read;
43 while (iswspace(*t)) t++;
44 f.cookie = (void *)t;
45 shlim(&f, 0);
46 unsigned long long y = __intscan(&f, base, 1, lim);
47 if (p) {
48 size_t cnt = shcnt(&f);
49 *p = cnt ? t + cnt : (wchar_t *)s;
50 }
51 return y;
52}
53
54unsigned long long wcstoull(const wchar_t *restrict s, wchar_t **restrict p, int base)
55{
56 return wcstox(s, p, base, ULLONG_MAX);
57}
58
59long long wcstoll(const wchar_t *restrict s, wchar_t **restrict p, int base)
60{
61 return wcstox(s, p, base, LLONG_MIN);
62}
63
64unsigned long wcstoul(const wchar_t *restrict s, wchar_t **restrict p, int base)
65{
66 return wcstox(s, p, base, ULONG_MAX);
67}
68
69long wcstol(const wchar_t *restrict s, wchar_t **restrict p, int base)
70{
71 return wcstox(s, p, base, 0UL+LONG_MIN);
72}
73
74intmax_t wcstoimax(const wchar_t *restrict s, wchar_t **restrict p, int base)
75{
76 return wcstoll(s, p, base);
77}
78
79uintmax_t wcstoumax(const wchar_t *restrict s, wchar_t **restrict p, int base)
80{
81 return wcstoull(s, p, base);
82}
libc/musl/src/string/arm/__aeabi_memcpy.s created+45
......@@ -0,0 +1,45 @@
1.syntax unified
2
3.global __aeabi_memcpy8
4.global __aeabi_memcpy4
5.global __aeabi_memcpy
6.global __aeabi_memmove8
7.global __aeabi_memmove4
8.global __aeabi_memmove
9
10.type __aeabi_memcpy8,%function
11.type __aeabi_memcpy4,%function
12.type __aeabi_memcpy,%function
13.type __aeabi_memmove8,%function
14.type __aeabi_memmove4,%function
15.type __aeabi_memmove,%function
16
17__aeabi_memmove8:
18__aeabi_memmove4:
19__aeabi_memmove:
20 cmp r0, r1
21 bls 3f
22 cmp r2, #0
23 beq 2f
24 adds r0, r0, r2
25 adds r2, r1, r2
261: subs r2, r2, #1
27 ldrb r3, [r2]
28 subs r0, r0, #1
29 strb r3, [r0]
30 cmp r1, r2
31 bne 1b
322: bx lr
33__aeabi_memcpy8:
34__aeabi_memcpy4:
35__aeabi_memcpy:
363: cmp r2, #0
37 beq 2f
38 adds r2, r1, r2
391: ldrb r3, [r1]
40 adds r1, r1, #1
41 strb r3, [r0]
42 adds r0, r0, #1
43 cmp r1, r2
44 bne 1b
452: bx lr
libc/musl/src/string/arm/__aeabi_memset.s created+31
......@@ -0,0 +1,31 @@
1.syntax unified
2
3.global __aeabi_memclr8
4.global __aeabi_memclr4
5.global __aeabi_memclr
6.global __aeabi_memset8
7.global __aeabi_memset4
8.global __aeabi_memset
9
10.type __aeabi_memclr8,%function
11.type __aeabi_memclr4,%function
12.type __aeabi_memclr,%function
13.type __aeabi_memset8,%function
14.type __aeabi_memset4,%function
15.type __aeabi_memset,%function
16
17__aeabi_memclr8:
18__aeabi_memclr4:
19__aeabi_memclr:
20 movs r2, #0
21__aeabi_memset8:
22__aeabi_memset4:
23__aeabi_memset:
24 cmp r1, #0
25 beq 2f
26 adds r1, r0, r1
271: strb r2, [r0]
28 adds r0, r0, #1
29 cmp r1, r0
30 bne 1b
312: bx lr
libc/musl/src/string/arm/memcpy.c created+3
......@@ -0,0 +1,3 @@
1#if __ARMEB__ || __thumb__
2#include "../memcpy.c"
3#endif
libc/musl/src/string/arm/memcpy_le.S created+383
......@@ -0,0 +1,383 @@
1#if !__ARMEB__ && !__thumb__
2
3/*
4 * Copyright (C) 2008 The Android Open Source Project
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31
32/*
33 * Optimized memcpy() for ARM.
34 *
35 * note that memcpy() always returns the destination pointer,
36 * so we have to preserve R0.
37 */
38
39/*
40 * This file has been modified from the original for use in musl libc.
41 * The main changes are: addition of .type memcpy,%function to make the
42 * code safely callable from thumb mode, adjusting the return
43 * instructions to be compatible with pre-thumb ARM cpus, and removal
44 * of prefetch code that is not compatible with older cpus.
45 */
46
47.syntax unified
48
49.global memcpy
50.type memcpy,%function
51memcpy:
52 /* The stack must always be 64-bits aligned to be compliant with the
53 * ARM ABI. Since we have to save R0, we might as well save R4
54 * which we can use for better pipelining of the reads below
55 */
56 .fnstart
57 .save {r0, r4, lr}
58 stmfd sp!, {r0, r4, lr}
59 /* Making room for r5-r11 which will be spilled later */
60 .pad #28
61 sub sp, sp, #28
62
63 /* it simplifies things to take care of len<4 early */
64 cmp r2, #4
65 blo copy_last_3_and_return
66
67 /* compute the offset to align the source
68 * offset = (4-(src&3))&3 = -src & 3
69 */
70 rsb r3, r1, #0
71 ands r3, r3, #3
72 beq src_aligned
73
74 /* align source to 32 bits. We need to insert 2 instructions between
75 * a ldr[b|h] and str[b|h] because byte and half-word instructions
76 * stall 2 cycles.
77 */
78 movs r12, r3, lsl #31
79 sub r2, r2, r3 /* we know that r3 <= r2 because r2 >= 4 */
80 ldrbmi r3, [r1], #1
81 ldrbcs r4, [r1], #1
82 ldrbcs r12,[r1], #1
83 strbmi r3, [r0], #1
84 strbcs r4, [r0], #1
85 strbcs r12,[r0], #1
86
87src_aligned:
88
89 /* see if src and dst are aligned together (congruent) */
90 eor r12, r0, r1
91 tst r12, #3
92 bne non_congruent
93
94 /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
95 * frame. Don't update sp.
96 */
97 stmea sp, {r5-r11}
98
99 /* align the destination to a cache-line */
100 rsb r3, r0, #0
101 ands r3, r3, #0x1C
102 beq congruent_aligned32
103 cmp r3, r2
104 andhi r3, r2, #0x1C
105
106 /* conditionnaly copies 0 to 7 words (length in r3) */
107 movs r12, r3, lsl #28
108 ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
109 ldmmi r1!, {r8, r9} /* 8 bytes */
110 stmcs r0!, {r4, r5, r6, r7}
111 stmmi r0!, {r8, r9}
112 tst r3, #0x4
113 ldrne r10,[r1], #4 /* 4 bytes */
114 strne r10,[r0], #4
115 sub r2, r2, r3
116
117congruent_aligned32:
118 /*
119 * here source is aligned to 32 bytes.
120 */
121
122cached_aligned32:
123 subs r2, r2, #32
124 blo less_than_32_left
125
126 /*
127 * We preload a cache-line up to 64 bytes ahead. On the 926, this will
128 * stall only until the requested world is fetched, but the linefill
129 * continues in the the background.
130 * While the linefill is going, we write our previous cache-line
131 * into the write-buffer (which should have some free space).
132 * When the linefill is done, the writebuffer will
133 * start dumping its content into memory
134 *
135 * While all this is going, we then load a full cache line into
136 * 8 registers, this cache line should be in the cache by now
137 * (or partly in the cache).
138 *
139 * This code should work well regardless of the source/dest alignment.
140 *
141 */
142
143 /* Align the preload register to a cache-line because the cpu does
144 * "critical word first" (the first word requested is loaded first).
145 */
146 @ bic r12, r1, #0x1F
147 @ add r12, r12, #64
148
1491: ldmia r1!, { r4-r11 }
150 subs r2, r2, #32
151
152 /*
153 * NOTE: if r12 is more than 64 ahead of r1, the following ldrhi
154 * for ARM9 preload will not be safely guarded by the preceding subs.
155 * When it is safely guarded the only possibility to have SIGSEGV here
156 * is because the caller overstates the length.
157 */
158 @ ldrhi r3, [r12], #32 /* cheap ARM9 preload */
159 stmia r0!, { r4-r11 }
160 bhs 1b
161
162 add r2, r2, #32
163
164less_than_32_left:
165 /*
166 * less than 32 bytes left at this point (length in r2)
167 */
168
169 /* skip all this if there is nothing to do, which should
170 * be a common case (if not executed the code below takes
171 * about 16 cycles)
172 */
173 tst r2, #0x1F
174 beq 1f
175
176 /* conditionnaly copies 0 to 31 bytes */
177 movs r12, r2, lsl #28
178 ldmcs r1!, {r4, r5, r6, r7} /* 16 bytes */
179 ldmmi r1!, {r8, r9} /* 8 bytes */
180 stmcs r0!, {r4, r5, r6, r7}
181 stmmi r0!, {r8, r9}
182 movs r12, r2, lsl #30
183 ldrcs r3, [r1], #4 /* 4 bytes */
184 ldrhmi r4, [r1], #2 /* 2 bytes */
185 strcs r3, [r0], #4
186 strhmi r4, [r0], #2
187 tst r2, #0x1
188 ldrbne r3, [r1] /* last byte */
189 strbne r3, [r0]
190
191 /* we're done! restore everything and return */
1921: ldmfd sp!, {r5-r11}
193 ldmfd sp!, {r0, r4, lr}
194 bx lr
195
196 /********************************************************************/
197
198non_congruent:
199 /*
200 * here source is aligned to 4 bytes
201 * but destination is not.
202 *
203 * in the code below r2 is the number of bytes read
204 * (the number of bytes written is always smaller, because we have
205 * partial words in the shift queue)
206 */
207 cmp r2, #4
208 blo copy_last_3_and_return
209
210 /* Use post-incriment mode for stm to spill r5-r11 to reserved stack
211 * frame. Don't update sp.
212 */
213 stmea sp, {r5-r11}
214
215 /* compute shifts needed to align src to dest */
216 rsb r5, r0, #0
217 and r5, r5, #3 /* r5 = # bytes in partial words */
218 mov r12, r5, lsl #3 /* r12 = right */
219 rsb lr, r12, #32 /* lr = left */
220
221 /* read the first word */
222 ldr r3, [r1], #4
223 sub r2, r2, #4
224
225 /* write a partial word (0 to 3 bytes), such that destination
226 * becomes aligned to 32 bits (r5 = nb of words to copy for alignment)
227 */
228 movs r5, r5, lsl #31
229 strbmi r3, [r0], #1
230 movmi r3, r3, lsr #8
231 strbcs r3, [r0], #1
232 movcs r3, r3, lsr #8
233 strbcs r3, [r0], #1
234 movcs r3, r3, lsr #8
235
236 cmp r2, #4
237 blo partial_word_tail
238
239 /* Align destination to 32 bytes (cache line boundary) */
2401: tst r0, #0x1c
241 beq 2f
242 ldr r5, [r1], #4
243 sub r2, r2, #4
244 orr r4, r3, r5, lsl lr
245 mov r3, r5, lsr r12
246 str r4, [r0], #4
247 cmp r2, #4
248 bhs 1b
249 blo partial_word_tail
250
251 /* copy 32 bytes at a time */
2522: subs r2, r2, #32
253 blo less_than_thirtytwo
254
255 /* Use immediate mode for the shifts, because there is an extra cycle
256 * for register shifts, which could account for up to 50% of
257 * performance hit.
258 */
259
260 cmp r12, #24
261 beq loop24
262 cmp r12, #8
263 beq loop8
264
265loop16:
266 ldr r12, [r1], #4
2671: mov r4, r12
268 ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
269 subs r2, r2, #32
270 ldrhs r12, [r1], #4
271 orr r3, r3, r4, lsl #16
272 mov r4, r4, lsr #16
273 orr r4, r4, r5, lsl #16
274 mov r5, r5, lsr #16
275 orr r5, r5, r6, lsl #16
276 mov r6, r6, lsr #16
277 orr r6, r6, r7, lsl #16
278 mov r7, r7, lsr #16
279 orr r7, r7, r8, lsl #16
280 mov r8, r8, lsr #16
281 orr r8, r8, r9, lsl #16
282 mov r9, r9, lsr #16
283 orr r9, r9, r10, lsl #16
284 mov r10, r10, lsr #16
285 orr r10, r10, r11, lsl #16
286 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
287 mov r3, r11, lsr #16
288 bhs 1b
289 b less_than_thirtytwo
290
291loop8:
292 ldr r12, [r1], #4
2931: mov r4, r12
294 ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
295 subs r2, r2, #32
296 ldrhs r12, [r1], #4
297 orr r3, r3, r4, lsl #24
298 mov r4, r4, lsr #8
299 orr r4, r4, r5, lsl #24
300 mov r5, r5, lsr #8
301 orr r5, r5, r6, lsl #24
302 mov r6, r6, lsr #8
303 orr r6, r6, r7, lsl #24
304 mov r7, r7, lsr #8
305 orr r7, r7, r8, lsl #24
306 mov r8, r8, lsr #8
307 orr r8, r8, r9, lsl #24
308 mov r9, r9, lsr #8
309 orr r9, r9, r10, lsl #24
310 mov r10, r10, lsr #8
311 orr r10, r10, r11, lsl #24
312 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
313 mov r3, r11, lsr #8
314 bhs 1b
315 b less_than_thirtytwo
316
317loop24:
318 ldr r12, [r1], #4
3191: mov r4, r12
320 ldmia r1!, { r5,r6,r7, r8,r9,r10,r11}
321 subs r2, r2, #32
322 ldrhs r12, [r1], #4
323 orr r3, r3, r4, lsl #8
324 mov r4, r4, lsr #24
325 orr r4, r4, r5, lsl #8
326 mov r5, r5, lsr #24
327 orr r5, r5, r6, lsl #8
328 mov r6, r6, lsr #24
329 orr r6, r6, r7, lsl #8
330 mov r7, r7, lsr #24
331 orr r7, r7, r8, lsl #8
332 mov r8, r8, lsr #24
333 orr r8, r8, r9, lsl #8
334 mov r9, r9, lsr #24
335 orr r9, r9, r10, lsl #8
336 mov r10, r10, lsr #24
337 orr r10, r10, r11, lsl #8
338 stmia r0!, {r3,r4,r5,r6, r7,r8,r9,r10}
339 mov r3, r11, lsr #24
340 bhs 1b
341
342less_than_thirtytwo:
343 /* copy the last 0 to 31 bytes of the source */
344 rsb r12, lr, #32 /* we corrupted r12, recompute it */
345 add r2, r2, #32
346 cmp r2, #4
347 blo partial_word_tail
348
3491: ldr r5, [r1], #4
350 sub r2, r2, #4
351 orr r4, r3, r5, lsl lr
352 mov r3, r5, lsr r12
353 str r4, [r0], #4
354 cmp r2, #4
355 bhs 1b
356
357partial_word_tail:
358 /* we have a partial word in the input buffer */
359 movs r5, lr, lsl #(31-3)
360 strbmi r3, [r0], #1
361 movmi r3, r3, lsr #8
362 strbcs r3, [r0], #1
363 movcs r3, r3, lsr #8
364 strbcs r3, [r0], #1
365
366 /* Refill spilled registers from the stack. Don't update sp. */
367 ldmfd sp, {r5-r11}
368
369copy_last_3_and_return:
370 movs r2, r2, lsl #31 /* copy remaining 0, 1, 2 or 3 bytes */
371 ldrbmi r2, [r1], #1
372 ldrbcs r3, [r1], #1
373 ldrbcs r12,[r1]
374 strbmi r2, [r0], #1
375 strbcs r3, [r0], #1
376 strbcs r12,[r0]
377
378 /* we're done! restore sp and spilled registers and return */
379 add sp, sp, #28
380 ldmfd sp!, {r0, r4, lr}
381 bx lr
382
383#endif
libc/musl/src/string/bcmp.c created+8
......@@ -0,0 +1,8 @@
1#define _BSD_SOURCE
2#include <string.h>
3#include <strings.h>
4
5int bcmp(const void *s1, const void *s2, size_t n)
6{
7 return memcmp(s1, s2, n);
8}
libc/musl/src/string/bcopy.c created+8
......@@ -0,0 +1,8 @@
1#define _BSD_SOURCE
2#include <string.h>
3#include <strings.h>
4
5void bcopy(const void *s1, void *s2, size_t n)
6{
7 memmove(s2, s1, n);
8}
libc/musl/src/string/bzero.c created+8
......@@ -0,0 +1,8 @@
1#define _BSD_SOURCE
2#include <string.h>
3#include <strings.h>
4
5void bzero(void *s, size_t n)
6{
7 memset(s, 0, n);
8}
libc/musl/src/string/explicit_bzero.c created+8
......@@ -0,0 +1,8 @@
1#define _BSD_SOURCE
2#include <string.h>
3
4void explicit_bzero(void *d, size_t n)
5{
6 d = memset(d, 0, n);
7 __asm__ __volatile__ ("" : : "r"(d) : "memory");
8}
libc/musl/src/string/i386/memcpy.s created+32
......@@ -0,0 +1,32 @@
1.global memcpy
2.global __memcpy_fwd
3.hidden __memcpy_fwd
4.type memcpy,@function
5memcpy:
6__memcpy_fwd:
7 push %esi
8 push %edi
9 mov 12(%esp),%edi
10 mov 16(%esp),%esi
11 mov 20(%esp),%ecx
12 mov %edi,%eax
13 cmp $4,%ecx
14 jc 1f
15 test $3,%edi
16 jz 1f
172: movsb
18 dec %ecx
19 test $3,%edi
20 jnz 2b
211: mov %ecx,%edx
22 shr $2,%ecx
23 rep
24 movsl
25 and $3,%edx
26 jz 1f
272: movsb
28 dec %edx
29 jnz 2b
301: pop %edi
31 pop %esi
32 ret
libc/musl/src/string/i386/memmove.s created+22
......@@ -0,0 +1,22 @@
1.global memmove
2.type memmove,@function
3memmove:
4 mov 4(%esp),%eax
5 sub 8(%esp),%eax
6 cmp 12(%esp),%eax
7.hidden __memcpy_fwd
8 jae __memcpy_fwd
9 push %esi
10 push %edi
11 mov 12(%esp),%edi
12 mov 16(%esp),%esi
13 mov 20(%esp),%ecx
14 lea -1(%edi,%ecx),%edi
15 lea -1(%esi,%ecx),%esi
16 std
17 rep movsb
18 cld
19 lea 1(%edi),%eax
20 pop %edi
21 pop %esi
22 ret
libc/musl/src/string/i386/memset.s created+76
......@@ -0,0 +1,76 @@
1.global memset
2.type memset,@function
3memset:
4 mov 12(%esp),%ecx
5 cmp $62,%ecx
6 ja 2f
7
8 mov 8(%esp),%dl
9 mov 4(%esp),%eax
10 test %ecx,%ecx
11 jz 1f
12
13 mov %dl,%dh
14
15 mov %dl,(%eax)
16 mov %dl,-1(%eax,%ecx)
17 cmp $2,%ecx
18 jbe 1f
19
20 mov %dx,1(%eax)
21 mov %dx,(-1-2)(%eax,%ecx)
22 cmp $6,%ecx
23 jbe 1f
24
25 shl $16,%edx
26 mov 8(%esp),%dl
27 mov 8(%esp),%dh
28
29 mov %edx,(1+2)(%eax)
30 mov %edx,(-1-2-4)(%eax,%ecx)
31 cmp $14,%ecx
32 jbe 1f
33
34 mov %edx,(1+2+4)(%eax)
35 mov %edx,(1+2+4+4)(%eax)
36 mov %edx,(-1-2-4-8)(%eax,%ecx)
37 mov %edx,(-1-2-4-4)(%eax,%ecx)
38 cmp $30,%ecx
39 jbe 1f
40
41 mov %edx,(1+2+4+8)(%eax)
42 mov %edx,(1+2+4+8+4)(%eax)
43 mov %edx,(1+2+4+8+8)(%eax)
44 mov %edx,(1+2+4+8+12)(%eax)
45 mov %edx,(-1-2-4-8-16)(%eax,%ecx)
46 mov %edx,(-1-2-4-8-12)(%eax,%ecx)
47 mov %edx,(-1-2-4-8-8)(%eax,%ecx)
48 mov %edx,(-1-2-4-8-4)(%eax,%ecx)
49
501: ret
51
522: movzbl 8(%esp),%eax
53 mov %edi,12(%esp)
54 imul $0x1010101,%eax
55 mov 4(%esp),%edi
56 test $15,%edi
57 mov %eax,-4(%edi,%ecx)
58 jnz 2f
59
601: shr $2, %ecx
61 rep
62 stosl
63 mov 4(%esp),%eax
64 mov 12(%esp),%edi
65 ret
66
672: xor %edx,%edx
68 sub %edi,%edx
69 and $15,%edx
70 mov %eax,(%edi)
71 mov %eax,4(%edi)
72 mov %eax,8(%edi)
73 mov %eax,12(%edi)
74 sub %edx,%ecx
75 add %edx,%edi
76 jmp 1b
libc/musl/src/string/index.c created+8
......@@ -0,0 +1,8 @@
1#define _BSD_SOURCE
2#include <string.h>
3#include <strings.h>
4
5char *index(const char *s, int c)
6{
7 return strchr(s, c);
8}
libc/musl/src/string/memccpy.c created+34
......@@ -0,0 +1,34 @@
1#include <string.h>
2#include <stdint.h>
3#include <limits.h>
4
5#define ALIGN (sizeof(size_t)-1)
6#define ONES ((size_t)-1/UCHAR_MAX)
7#define HIGHS (ONES * (UCHAR_MAX/2+1))
8#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
9
10void *memccpy(void *restrict dest, const void *restrict src, int c, size_t n)
11{
12 unsigned char *d = dest;
13 const unsigned char *s = src;
14
15 c = (unsigned char)c;
16#ifdef __GNUC__
17 typedef size_t __attribute__((__may_alias__)) word;
18 word *wd;
19 const word *ws;
20 if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
21 for (; ((uintptr_t)s & ALIGN) && n && (*d=*s)!=c; n--, s++, d++);
22 if ((uintptr_t)s & ALIGN) goto tail;
23 size_t k = ONES * c;
24 wd=(void *)d; ws=(const void *)s;
25 for (; n>=sizeof(size_t) && !HASZERO(*ws^k);
26 n-=sizeof(size_t), ws++, wd++) *wd = *ws;
27 d=(void *)wd; s=(const void *)ws;
28 }
29#endif
30 for (; n && (*d=*s)!=c; n--, s++, d++);
31tail:
32 if (n && *s==c) return d+1;
33 return 0;
34}
libc/musl/src/string/memchr.c created+27
......@@ -0,0 +1,27 @@
1#include <string.h>
2#include <stdint.h>
3#include <limits.h>
4
5#define SS (sizeof(size_t))
6#define ALIGN (sizeof(size_t)-1)
7#define ONES ((size_t)-1/UCHAR_MAX)
8#define HIGHS (ONES * (UCHAR_MAX/2+1))
9#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
10
11void *memchr(const void *src, int c, size_t n)
12{
13 const unsigned char *s = src;
14 c = (unsigned char)c;
15#ifdef __GNUC__
16 for (; ((uintptr_t)s & ALIGN) && n && *s != c; s++, n--);
17 if (n && *s != c) {
18 typedef size_t __attribute__((__may_alias__)) word;
19 const word *w;
20 size_t k = ONES * c;
21 for (w = (const void *)s; n>=SS && !HASZERO(*w^k); w++, n-=SS);
22 s = (const void *)w;
23 }
24#endif
25 for (; n && *s != c; s++, n--);
26 return n ? (void *)s : 0;
27}
libc/musl/src/string/memcmp.c created+8
......@@ -0,0 +1,8 @@
1#include <string.h>
2
3int memcmp(const void *vl, const void *vr, size_t n)
4{
5 const unsigned char *l=vl, *r=vr;
6 for (; n && *l == *r; n--, l++, r++);
7 return n ? *l-*r : 0;
8}
libc/musl/src/string/memcpy.c created+124
......@@ -0,0 +1,124 @@
1#include <string.h>
2#include <stdint.h>
3#include <endian.h>
4
5void *memcpy(void *restrict dest, const void *restrict src, size_t n)
6{
7 unsigned char *d = dest;
8 const unsigned char *s = src;
9
10#ifdef __GNUC__
11
12#if __BYTE_ORDER == __LITTLE_ENDIAN
13#define LS >>
14#define RS <<
15#else
16#define LS <<
17#define RS >>
18#endif
19
20 typedef uint32_t __attribute__((__may_alias__)) u32;
21 uint32_t w, x;
22
23 for (; (uintptr_t)s % 4 && n; n--) *d++ = *s++;
24
25 if ((uintptr_t)d % 4 == 0) {
26 for (; n>=16; s+=16, d+=16, n-=16) {
27 *(u32 *)(d+0) = *(u32 *)(s+0);
28 *(u32 *)(d+4) = *(u32 *)(s+4);
29 *(u32 *)(d+8) = *(u32 *)(s+8);
30 *(u32 *)(d+12) = *(u32 *)(s+12);
31 }
32 if (n&8) {
33 *(u32 *)(d+0) = *(u32 *)(s+0);
34 *(u32 *)(d+4) = *(u32 *)(s+4);
35 d += 8; s += 8;
36 }
37 if (n&4) {
38 *(u32 *)(d+0) = *(u32 *)(s+0);
39 d += 4; s += 4;
40 }
41 if (n&2) {
42 *d++ = *s++; *d++ = *s++;
43 }
44 if (n&1) {
45 *d = *s;
46 }
47 return dest;
48 }
49
50 if (n >= 32) switch ((uintptr_t)d % 4) {
51 case 1:
52 w = *(u32 *)s;
53 *d++ = *s++;
54 *d++ = *s++;
55 *d++ = *s++;
56 n -= 3;
57 for (; n>=17; s+=16, d+=16, n-=16) {
58 x = *(u32 *)(s+1);
59 *(u32 *)(d+0) = (w LS 24) | (x RS 8);
60 w = *(u32 *)(s+5);
61 *(u32 *)(d+4) = (x LS 24) | (w RS 8);
62 x = *(u32 *)(s+9);
63 *(u32 *)(d+8) = (w LS 24) | (x RS 8);
64 w = *(u32 *)(s+13);
65 *(u32 *)(d+12) = (x LS 24) | (w RS 8);
66 }
67 break;
68 case 2:
69 w = *(u32 *)s;
70 *d++ = *s++;
71 *d++ = *s++;
72 n -= 2;
73 for (; n>=18; s+=16, d+=16, n-=16) {
74 x = *(u32 *)(s+2);
75 *(u32 *)(d+0) = (w LS 16) | (x RS 16);
76 w = *(u32 *)(s+6);
77 *(u32 *)(d+4) = (x LS 16) | (w RS 16);
78 x = *(u32 *)(s+10);
79 *(u32 *)(d+8) = (w LS 16) | (x RS 16);
80 w = *(u32 *)(s+14);
81 *(u32 *)(d+12) = (x LS 16) | (w RS 16);
82 }
83 break;
84 case 3:
85 w = *(u32 *)s;
86 *d++ = *s++;
87 n -= 1;
88 for (; n>=19; s+=16, d+=16, n-=16) {
89 x = *(u32 *)(s+3);
90 *(u32 *)(d+0) = (w LS 8) | (x RS 24);
91 w = *(u32 *)(s+7);
92 *(u32 *)(d+4) = (x LS 8) | (w RS 24);
93 x = *(u32 *)(s+11);
94 *(u32 *)(d+8) = (w LS 8) | (x RS 24);
95 w = *(u32 *)(s+15);
96 *(u32 *)(d+12) = (x LS 8) | (w RS 24);
97 }
98 break;
99 }
100 if (n&16) {
101 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
102 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
103 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
104 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
105 }
106 if (n&8) {
107 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
108 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
109 }
110 if (n&4) {
111 *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++;
112 }
113 if (n&2) {
114 *d++ = *s++; *d++ = *s++;
115 }
116 if (n&1) {
117 *d = *s;
118 }
119 return dest;
120#endif
121
122 for (; n; n--) *d++ = *s++;
123 return dest;
124}
libc/musl/src/string/memmem.c created+149
......@@ -0,0 +1,149 @@
1#define _GNU_SOURCE
2#include <string.h>
3#include <stdint.h>
4
5static char *twobyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
6{
7 uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
8 for (h+=2, k-=2; k; k--, hw = hw<<8 | *h++)
9 if (hw == nw) return (char *)h-2;
10 return hw == nw ? (char *)h-2 : 0;
11}
12
13static char *threebyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
14{
15 uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
16 uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
17 for (h+=3, k-=3; k; k--, hw = (hw|*h++)<<8)
18 if (hw == nw) return (char *)h-3;
19 return hw == nw ? (char *)h-3 : 0;
20}
21
22static char *fourbyte_memmem(const unsigned char *h, size_t k, const unsigned char *n)
23{
24 uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
25 uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
26 for (h+=4, k-=4; k; k--, hw = hw<<8 | *h++)
27 if (hw == nw) return (char *)h-4;
28 return hw == nw ? (char *)h-4 : 0;
29}
30
31#define MAX(a,b) ((a)>(b)?(a):(b))
32#define MIN(a,b) ((a)<(b)?(a):(b))
33
34#define BITOP(a,b,op) \
35 ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
36
37static char *twoway_memmem(const unsigned char *h, const unsigned char *z, const unsigned char *n, size_t l)
38{
39 size_t i, ip, jp, k, p, ms, p0, mem, mem0;
40 size_t byteset[32 / sizeof(size_t)] = { 0 };
41 size_t shift[256];
42
43 /* Computing length of needle and fill shift table */
44 for (i=0; i<l; i++)
45 BITOP(byteset, n[i], |=), shift[n[i]] = i+1;
46
47 /* Compute maximal suffix */
48 ip = -1; jp = 0; k = p = 1;
49 while (jp+k<l) {
50 if (n[ip+k] == n[jp+k]) {
51 if (k == p) {
52 jp += p;
53 k = 1;
54 } else k++;
55 } else if (n[ip+k] > n[jp+k]) {
56 jp += k;
57 k = 1;
58 p = jp - ip;
59 } else {
60 ip = jp++;
61 k = p = 1;
62 }
63 }
64 ms = ip;
65 p0 = p;
66
67 /* And with the opposite comparison */
68 ip = -1; jp = 0; k = p = 1;
69 while (jp+k<l) {
70 if (n[ip+k] == n[jp+k]) {
71 if (k == p) {
72 jp += p;
73 k = 1;
74 } else k++;
75 } else if (n[ip+k] < n[jp+k]) {
76 jp += k;
77 k = 1;
78 p = jp - ip;
79 } else {
80 ip = jp++;
81 k = p = 1;
82 }
83 }
84 if (ip+1 > ms+1) ms = ip;
85 else p = p0;
86
87 /* Periodic needle? */
88 if (memcmp(n, n+p, ms+1)) {
89 mem0 = 0;
90 p = MAX(ms, l-ms-1) + 1;
91 } else mem0 = l-p;
92 mem = 0;
93
94 /* Search loop */
95 for (;;) {
96 /* If remainder of haystack is shorter than needle, done */
97 if (z-h < l) return 0;
98
99 /* Check last byte first; advance by shift on mismatch */
100 if (BITOP(byteset, h[l-1], &)) {
101 k = l-shift[h[l-1]];
102 if (k) {
103 if (k < mem) k = mem;
104 h += k;
105 mem = 0;
106 continue;
107 }
108 } else {
109 h += l;
110 mem = 0;
111 continue;
112 }
113
114 /* Compare right half */
115 for (k=MAX(ms+1,mem); k<l && n[k] == h[k]; k++);
116 if (k < l) {
117 h += k-ms;
118 mem = 0;
119 continue;
120 }
121 /* Compare left half */
122 for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
123 if (k <= mem) return (char *)h;
124 h += p;
125 mem = mem0;
126 }
127}
128
129void *memmem(const void *h0, size_t k, const void *n0, size_t l)
130{
131 const unsigned char *h = h0, *n = n0;
132
133 /* Return immediately on empty needle */
134 if (!l) return (void *)h;
135
136 /* Return immediately when needle is longer than haystack */
137 if (k<l) return 0;
138
139 /* Use faster algorithms for short needles */
140 h = memchr(h0, *n, k);
141 if (!h || l==1) return (void *)h;
142 k -= h - (const unsigned char *)h0;
143 if (k<l) return 0;
144 if (l==2) return twobyte_memmem(h, k, n);
145 if (l==3) return threebyte_memmem(h, k, n);
146 if (l==4) return fourbyte_memmem(h, k, n);
147
148 return twoway_memmem(h, h+k, n, l);
149}
libc/musl/src/string/memmove.c created+42
......@@ -0,0 +1,42 @@
1#include <string.h>
2#include <stdint.h>
3
4#ifdef __GNUC__
5typedef __attribute__((__may_alias__)) size_t WT;
6#define WS (sizeof(WT))
7#endif
8
9void *memmove(void *dest, const void *src, size_t n)
10{
11 char *d = dest;
12 const char *s = src;
13
14 if (d==s) return d;
15 if ((uintptr_t)s-(uintptr_t)d-n <= -2*n) return memcpy(d, s, n);
16
17 if (d<s) {
18#ifdef __GNUC__
19 if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
20 while ((uintptr_t)d % WS) {
21 if (!n--) return dest;
22 *d++ = *s++;
23 }
24 for (; n>=WS; n-=WS, d+=WS, s+=WS) *(WT *)d = *(WT *)s;
25 }
26#endif
27 for (; n; n--) *d++ = *s++;
28 } else {
29#ifdef __GNUC__
30 if ((uintptr_t)s % WS == (uintptr_t)d % WS) {
31 while ((uintptr_t)(d+n) % WS) {
32 if (!n--) return dest;
33 d[n] = s[n];
34 }
35 while (n>=WS) n-=WS, *(WT *)(d+n) = *(WT *)(s+n);
36 }
37#endif
38 while (n) n--, d[n] = s[n];
39 }
40
41 return dest;
42}
libc/musl/src/string/mempcpy.c created+7
......@@ -0,0 +1,7 @@
1#define _GNU_SOURCE
2#include <string.h>
3
4void *mempcpy(void *dest, const void *src, size_t n)
5{
6 return (char *)memcpy(dest, src, n) + n;
7}
libc/musl/src/string/memrchr.c created+11
......@@ -0,0 +1,11 @@
1#include <string.h>
2
3void *__memrchr(const void *m, int c, size_t n)
4{
5 const unsigned char *s = m;
6 c = (unsigned char)c;
7 while (n--) if (s[n]==c) return (void *)(s+n);
8 return 0;
9}
10
11weak_alias(__memrchr, memrchr);
libc/musl/src/string/memset.c created+90
......@@ -0,0 +1,90 @@
1#include <string.h>
2#include <stdint.h>
3
4void *memset(void *dest, int c, size_t n)
5{
6 unsigned char *s = dest;
7 size_t k;
8
9 /* Fill head and tail with minimal branching. Each
10 * conditional ensures that all the subsequently used
11 * offsets are well-defined and in the dest region. */
12
13 if (!n) return dest;
14 s[0] = c;
15 s[n-1] = c;
16 if (n <= 2) return dest;
17 s[1] = c;
18 s[2] = c;
19 s[n-2] = c;
20 s[n-3] = c;
21 if (n <= 6) return dest;
22 s[3] = c;
23 s[n-4] = c;
24 if (n <= 8) return dest;
25
26 /* Advance pointer to align it at a 4-byte boundary,
27 * and truncate n to a multiple of 4. The previous code
28 * already took care of any head/tail that get cut off
29 * by the alignment. */
30
31 k = -(uintptr_t)s & 3;
32 s += k;
33 n -= k;
34 n &= -4;
35
36#ifdef __GNUC__
37 typedef uint32_t __attribute__((__may_alias__)) u32;
38 typedef uint64_t __attribute__((__may_alias__)) u64;
39
40 u32 c32 = ((u32)-1)/255 * (unsigned char)c;
41
42 /* In preparation to copy 32 bytes at a time, aligned on
43 * an 8-byte bounary, fill head/tail up to 28 bytes each.
44 * As in the initial byte-based head/tail fill, each
45 * conditional below ensures that the subsequent offsets
46 * are valid (e.g. !(n<=24) implies n>=28). */
47
48 *(u32 *)(s+0) = c32;
49 *(u32 *)(s+n-4) = c32;
50 if (n <= 8) return dest;
51 *(u32 *)(s+4) = c32;
52 *(u32 *)(s+8) = c32;
53 *(u32 *)(s+n-12) = c32;
54 *(u32 *)(s+n-8) = c32;
55 if (n <= 24) return dest;
56 *(u32 *)(s+12) = c32;
57 *(u32 *)(s+16) = c32;
58 *(u32 *)(s+20) = c32;
59 *(u32 *)(s+24) = c32;
60 *(u32 *)(s+n-28) = c32;
61 *(u32 *)(s+n-24) = c32;
62 *(u32 *)(s+n-20) = c32;
63 *(u32 *)(s+n-16) = c32;
64
65 /* Align to a multiple of 8 so we can fill 64 bits at a time,
66 * and avoid writing the same bytes twice as much as is
67 * practical without introducing additional branching. */
68
69 k = 24 + ((uintptr_t)s & 4);
70 s += k;
71 n -= k;
72
73 /* If this loop is reached, 28 tail bytes have already been
74 * filled, so any remainder when n drops below 32 can be
75 * safely ignored. */
76
77 u64 c64 = c32 | ((u64)c32 << 32);
78 for (; n >= 32; n-=32, s+=32) {
79 *(u64 *)(s+0) = c64;
80 *(u64 *)(s+8) = c64;
81 *(u64 *)(s+16) = c64;
82 *(u64 *)(s+24) = c64;
83 }
84#else
85 /* Pure C fallback with no aliasing violations. */
86 for (; n; n--, s++) *s = c;
87#endif
88
89 return dest;
90}
libc/musl/src/string/rindex.c created+8
......@@ -0,0 +1,8 @@
1#define _BSD_SOURCE
2#include <string.h>
3#include <strings.h>
4
5char *rindex(const char *s, int c)
6{
7 return strrchr(s, c);
8}
libc/musl/src/string/stpcpy.c created+29
......@@ -0,0 +1,29 @@
1#include <string.h>
2#include <stdint.h>
3#include <limits.h>
4
5#define ALIGN (sizeof(size_t))
6#define ONES ((size_t)-1/UCHAR_MAX)
7#define HIGHS (ONES * (UCHAR_MAX/2+1))
8#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
9
10char *__stpcpy(char *restrict d, const char *restrict s)
11{
12#ifdef __GNUC__
13 typedef size_t __attribute__((__may_alias__)) word;
14 word *wd;
15 const word *ws;
16 if ((uintptr_t)s % ALIGN == (uintptr_t)d % ALIGN) {
17 for (; (uintptr_t)s % ALIGN; s++, d++)
18 if (!(*d=*s)) return d;
19 wd=(void *)d; ws=(const void *)s;
20 for (; !HASZERO(*ws); *wd++ = *ws++);
21 d=(void *)wd; s=(const void *)ws;
22 }
23#endif
24 for (; (*d=*s); s++, d++);
25
26 return d;
27}
28
29weak_alias(__stpcpy, stpcpy);
libc/musl/src/string/stpncpy.c created+32
......@@ -0,0 +1,32 @@
1#include <string.h>
2#include <stdint.h>
3#include <limits.h>
4
5#define ALIGN (sizeof(size_t)-1)
6#define ONES ((size_t)-1/UCHAR_MAX)
7#define HIGHS (ONES * (UCHAR_MAX/2+1))
8#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
9
10char *__stpncpy(char *restrict d, const char *restrict s, size_t n)
11{
12#ifdef __GNUC__
13 typedef size_t __attribute__((__may_alias__)) word;
14 word *wd;
15 const word *ws;
16 if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
17 for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
18 if (!n || !*s) goto tail;
19 wd=(void *)d; ws=(const void *)s;
20 for (; n>=sizeof(size_t) && !HASZERO(*ws);
21 n-=sizeof(size_t), ws++, wd++) *wd = *ws;
22 d=(void *)wd; s=(const void *)ws;
23 }
24#endif
25 for (; n && (*d=*s); n--, s++, d++);
26tail:
27 memset(d, 0, n);
28 return d;
29}
30
31weak_alias(__stpncpy, stpncpy);
32
libc/musl/src/string/strcasecmp.c created+16
......@@ -0,0 +1,16 @@
1#include <strings.h>
2#include <ctype.h>
3
4int strcasecmp(const char *_l, const char *_r)
5{
6 const unsigned char *l=(void *)_l, *r=(void *)_r;
7 for (; *l && *r && (*l == *r || tolower(*l) == tolower(*r)); l++, r++);
8 return tolower(*l) - tolower(*r);
9}
10
11int __strcasecmp_l(const char *l, const char *r, locale_t loc)
12{
13 return strcasecmp(l, r);
14}
15
16weak_alias(__strcasecmp_l, strcasecmp_l);
libc/musl/src/string/strcasestr.c created+9
......@@ -0,0 +1,9 @@
1#define _GNU_SOURCE
2#include <string.h>
3
4char *strcasestr(const char *h, const char *n)
5{
6 size_t l = strlen(n);
7 for (; *h; h++) if (!strncasecmp(h, n, l)) return (char *)h;
8 return 0;
9}
libc/musl/src/string/strcat.c created+7
......@@ -0,0 +1,7 @@
1#include <string.h>
2
3char *strcat(char *restrict dest, const char *restrict src)
4{
5 strcpy(dest + strlen(dest), src);
6 return dest;
7}
libc/musl/src/string/strchr.c created+7
......@@ -0,0 +1,7 @@
1#include <string.h>
2
3char *strchr(const char *s, int c)
4{
5 char *r = __strchrnul(s, c);
6 return *(unsigned char *)r == (unsigned char)c ? r : 0;
7}
libc/musl/src/string/strchrnul.c created+28
......@@ -0,0 +1,28 @@
1#include <string.h>
2#include <stdint.h>
3#include <limits.h>
4
5#define ALIGN (sizeof(size_t))
6#define ONES ((size_t)-1/UCHAR_MAX)
7#define HIGHS (ONES * (UCHAR_MAX/2+1))
8#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
9
10char *__strchrnul(const char *s, int c)
11{
12 c = (unsigned char)c;
13 if (!c) return (char *)s + strlen(s);
14
15#ifdef __GNUC__
16 typedef size_t __attribute__((__may_alias__)) word;
17 const word *w;
18 for (; (uintptr_t)s % ALIGN; s++)
19 if (!*s || *(unsigned char *)s == c) return (char *)s;
20 size_t k = ONES * c;
21 for (w = (void *)s; !HASZERO(*w) && !HASZERO(*w^k); w++);
22 s = (void *)w;
23#endif
24 for (; *s && *(unsigned char *)s != c; s++);
25 return (char *)s;
26}
27
28weak_alias(__strchrnul, strchrnul);
libc/musl/src/string/strcmp.c created+7
......@@ -0,0 +1,7 @@
1#include <string.h>
2
3int strcmp(const char *l, const char *r)
4{
5 for (; *l==*r && *l; l++, r++);
6 return *(unsigned char *)l - *(unsigned char *)r;
7}
libc/musl/src/string/strcpy.c created+7
......@@ -0,0 +1,7 @@
1#include <string.h>
2
3char *strcpy(char *restrict dest, const char *restrict src)
4{
5 __stpcpy(dest, src);
6 return dest;
7}
libc/musl/src/string/strcspn.c created+17
......@@ -0,0 +1,17 @@
1#include <string.h>
2
3#define BITOP(a,b,op) \
4 ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
5
6size_t strcspn(const char *s, const char *c)
7{
8 const char *a = s;
9 size_t byteset[32/sizeof(size_t)];
10
11 if (!c[0] || !c[1]) return __strchrnul(s, *c)-a;
12
13 memset(byteset, 0, sizeof byteset);
14 for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);
15 for (; *s && !BITOP(byteset, *(unsigned char *)s, &); s++);
16 return s-a;
17}
libc/musl/src/string/strdup.c created+10
......@@ -0,0 +1,10 @@
1#include <stdlib.h>
2#include <string.h>
3
4char *strdup(const char *s)
5{
6 size_t l = strlen(s);
7 char *d = malloc(l+1);
8 if (!d) return NULL;
9 return memcpy(d, s, l+1);
10}
libc/musl/src/string/strerror_r.c created+19
......@@ -0,0 +1,19 @@
1#include <string.h>
2#include <errno.h>
3
4int strerror_r(int err, char *buf, size_t buflen)
5{
6 char *msg = strerror(err);
7 size_t l = strlen(msg);
8 if (l >= buflen) {
9 if (buflen) {
10 memcpy(buf, msg, buflen-1);
11 buf[buflen-1] = 0;
12 }
13 return ERANGE;
14 }
15 memcpy(buf, msg, l+1);
16 return 0;
17}
18
19weak_alias(strerror_r, __xpg_strerror_r);
libc/musl/src/string/strlcat.c created+9
......@@ -0,0 +1,9 @@
1#define _BSD_SOURCE
2#include <string.h>
3
4size_t strlcat(char *d, const char *s, size_t n)
5{
6 size_t l = strnlen(d, n);
7 if (l == n) return l + strlen(s);
8 return l + strlcpy(d+l, s, n-l);
9}
libc/musl/src/string/strlcpy.c created+34
......@@ -0,0 +1,34 @@
1#define _BSD_SOURCE
2#include <string.h>
3#include <stdint.h>
4#include <limits.h>
5
6#define ALIGN (sizeof(size_t)-1)
7#define ONES ((size_t)-1/UCHAR_MAX)
8#define HIGHS (ONES * (UCHAR_MAX/2+1))
9#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
10
11size_t strlcpy(char *d, const char *s, size_t n)
12{
13 char *d0 = d;
14 size_t *wd;
15
16 if (!n--) goto finish;
17#ifdef __GNUC__
18 typedef size_t __attribute__((__may_alias__)) word;
19 const word *ws;
20 if (((uintptr_t)s & ALIGN) == ((uintptr_t)d & ALIGN)) {
21 for (; ((uintptr_t)s & ALIGN) && n && (*d=*s); n--, s++, d++);
22 if (n && *s) {
23 wd=(void *)d; ws=(const void *)s;
24 for (; n>=sizeof(size_t) && !HASZERO(*ws);
25 n-=sizeof(size_t), ws++, wd++) *wd = *ws;
26 d=(void *)wd; s=(const void *)ws;
27 }
28 }
29#endif
30 for (; n && (*d=*s); n--, s++, d++);
31 *d = 0;
32finish:
33 return d-d0 + strlen(s);
34}
libc/musl/src/string/strlen.c created+22
......@@ -0,0 +1,22 @@
1#include <string.h>
2#include <stdint.h>
3#include <limits.h>
4
5#define ALIGN (sizeof(size_t))
6#define ONES ((size_t)-1/UCHAR_MAX)
7#define HIGHS (ONES * (UCHAR_MAX/2+1))
8#define HASZERO(x) ((x)-ONES & ~(x) & HIGHS)
9
10size_t strlen(const char *s)
11{
12 const char *a = s;
13#ifdef __GNUC__
14 typedef size_t __attribute__((__may_alias__)) word;
15 const word *w;
16 for (; (uintptr_t)s % ALIGN; s++) if (!*s) return s-a;
17 for (w = (const void *)s; !HASZERO(*w); w++);
18 s = (const void *)w;
19#endif
20 for (; *s; s++);
21 return s-a;
22}
libc/musl/src/string/strncasecmp.c created+17
......@@ -0,0 +1,17 @@
1#include <strings.h>
2#include <ctype.h>
3
4int strncasecmp(const char *_l, const char *_r, size_t n)
5{
6 const unsigned char *l=(void *)_l, *r=(void *)_r;
7 if (!n--) return 0;
8 for (; *l && *r && n && (*l == *r || tolower(*l) == tolower(*r)); l++, r++, n--);
9 return tolower(*l) - tolower(*r);
10}
11
12int __strncasecmp_l(const char *l, const char *r, size_t n, locale_t loc)
13{
14 return strncasecmp(l, r, n);
15}
16
17weak_alias(__strncasecmp_l, strncasecmp_l);
libc/musl/src/string/strncat.c created+10
......@@ -0,0 +1,10 @@
1#include <string.h>
2
3char *strncat(char *restrict d, const char *restrict s, size_t n)
4{
5 char *a = d;
6 d += strlen(d);
7 while (n && *s) n--, *d++ = *s++;
8 *d++ = 0;
9 return a;
10}
libc/musl/src/string/strncmp.c created+9
......@@ -0,0 +1,9 @@
1#include <string.h>
2
3int strncmp(const char *_l, const char *_r, size_t n)
4{
5 const unsigned char *l=(void *)_l, *r=(void *)_r;
6 if (!n--) return 0;
7 for (; *l && *r && n && *l == *r ; l++, r++, n--);
8 return *l - *r;
9}
libc/musl/src/string/strncpy.c created+7
......@@ -0,0 +1,7 @@
1#include <string.h>
2
3char *strncpy(char *restrict d, const char *restrict s, size_t n)
4{
5 __stpncpy(d, s, n);
6 return d;
7}
libc/musl/src/string/strndup.c created+12
......@@ -0,0 +1,12 @@
1#include <stdlib.h>
2#include <string.h>
3
4char *strndup(const char *s, size_t n)
5{
6 size_t l = strnlen(s, n);
7 char *d = malloc(l+1);
8 if (!d) return NULL;
9 memcpy(d, s, l);
10 d[l] = 0;
11 return d;
12}
libc/musl/src/string/strnlen.c created+7
......@@ -0,0 +1,7 @@
1#include <string.h>
2
3size_t strnlen(const char *s, size_t n)
4{
5 const char *p = memchr(s, 0, n);
6 return p ? p-s : n;
7}
libc/musl/src/string/strpbrk.c created+7
......@@ -0,0 +1,7 @@
1#include <string.h>
2
3char *strpbrk(const char *s, const char *b)
4{
5 s += strcspn(s, b);
6 return *s ? (char *)s : 0;
7}
libc/musl/src/string/strrchr.c created+6
......@@ -0,0 +1,6 @@
1#include <string.h>
2
3char *strrchr(const char *s, int c)
4{
5 return __memrchr(s, c, strlen(s) + 1);
6}
libc/musl/src/string/strsep.c created+13
......@@ -0,0 +1,13 @@
1#define _GNU_SOURCE
2#include <string.h>
3
4char *strsep(char **str, const char *sep)
5{
6 char *s = *str, *end;
7 if (!s) return NULL;
8 end = s + strcspn(s, sep);
9 if (*end) *end++ = 0;
10 else end = 0;
11 *str = end;
12 return s;
13}
libc/musl/src/string/strsignal.c created+116
......@@ -0,0 +1,116 @@
1#include <signal.h>
2#include <string.h>
3#include "locale_impl.h"
4
5#if (SIGHUP == 1) && (SIGINT == 2) && (SIGQUIT == 3) && (SIGILL == 4) \
6 && (SIGTRAP == 5) && (SIGABRT == 6) && (SIGBUS == 7) && (SIGFPE == 8) \
7 && (SIGKILL == 9) && (SIGUSR1 == 10) && (SIGSEGV == 11) && (SIGUSR2 == 12) \
8 && (SIGPIPE == 13) && (SIGALRM == 14) && (SIGTERM == 15) && (SIGSTKFLT == 16) \
9 && (SIGCHLD == 17) && (SIGCONT == 18) && (SIGSTOP == 19) && (SIGTSTP == 20) \
10 && (SIGTTIN == 21) && (SIGTTOU == 22) && (SIGURG == 23) && (SIGXCPU == 24) \
11 && (SIGXFSZ == 25) && (SIGVTALRM == 26) && (SIGPROF == 27) && (SIGWINCH == 28) \
12 && (SIGPOLL == 29) && (SIGPWR == 30) && (SIGSYS == 31)
13
14#define sigmap(x) x
15
16#else
17
18static const char map[] = {
19 [SIGHUP] = 1,
20 [SIGINT] = 2,
21 [SIGQUIT] = 3,
22 [SIGILL] = 4,
23 [SIGTRAP] = 5,
24 [SIGABRT] = 6,
25 [SIGBUS] = 7,
26 [SIGFPE] = 8,
27 [SIGKILL] = 9,
28 [SIGUSR1] = 10,
29 [SIGSEGV] = 11,
30 [SIGUSR2] = 12,
31 [SIGPIPE] = 13,
32 [SIGALRM] = 14,
33 [SIGTERM] = 15,
34 [SIGSTKFLT] = 16,
35 [SIGCHLD] = 17,
36 [SIGCONT] = 18,
37 [SIGSTOP] = 19,
38 [SIGTSTP] = 20,
39 [SIGTTIN] = 21,
40 [SIGTTOU] = 22,
41 [SIGURG] = 23,
42 [SIGXCPU] = 24,
43 [SIGXFSZ] = 25,
44 [SIGVTALRM] = 26,
45 [SIGPROF] = 27,
46 [SIGWINCH] = 28,
47 [SIGPOLL] = 29,
48 [SIGPWR] = 30,
49 [SIGSYS] = 31
50};
51
52#define sigmap(x) ((x) >= sizeof map ? (x) : map[(x)])
53
54#endif
55
56static const char strings[] =
57 "Unknown signal\0"
58 "Hangup\0"
59 "Interrupt\0"
60 "Quit\0"
61 "Illegal instruction\0"
62 "Trace/breakpoint trap\0"
63 "Aborted\0"
64 "Bus error\0"
65 "Arithmetic exception\0"
66 "Killed\0"
67 "User defined signal 1\0"
68 "Segmentation fault\0"
69 "User defined signal 2\0"
70 "Broken pipe\0"
71 "Alarm clock\0"
72 "Terminated\0"
73 "Stack fault\0"
74 "Child process status\0"
75 "Continued\0"
76 "Stopped (signal)\0"
77 "Stopped\0"
78 "Stopped (tty input)\0"
79 "Stopped (tty output)\0"
80 "Urgent I/O condition\0"
81 "CPU time limit exceeded\0"
82 "File size limit exceeded\0"
83 "Virtual timer expired\0"
84 "Profiling timer expired\0"
85 "Window changed\0"
86 "I/O possible\0"
87 "Power failure\0"
88 "Bad system call\0"
89 "RT32"
90 "\0RT33\0RT34\0RT35\0RT36\0RT37\0RT38\0RT39\0RT40"
91 "\0RT41\0RT42\0RT43\0RT44\0RT45\0RT46\0RT47\0RT48"
92 "\0RT49\0RT50\0RT51\0RT52\0RT53\0RT54\0RT55\0RT56"
93 "\0RT57\0RT58\0RT59\0RT60\0RT61\0RT62\0RT63\0RT64"
94#if _NSIG > 65
95 "\0RT65\0RT66\0RT67\0RT68\0RT69\0RT70\0RT71\0RT72"
96 "\0RT73\0RT74\0RT75\0RT76\0RT77\0RT78\0RT79\0RT80"
97 "\0RT81\0RT82\0RT83\0RT84\0RT85\0RT86\0RT87\0RT88"
98 "\0RT89\0RT90\0RT91\0RT92\0RT93\0RT94\0RT95\0RT96"
99 "\0RT97\0RT98\0RT99\0RT100\0RT101\0RT102\0RT103\0RT104"
100 "\0RT105\0RT106\0RT107\0RT108\0RT109\0RT110\0RT111\0RT112"
101 "\0RT113\0RT114\0RT115\0RT116\0RT117\0RT118\0RT119\0RT120"
102 "\0RT121\0RT122\0RT123\0RT124\0RT125\0RT126\0RT127\0RT128"
103#endif
104 "";
105
106char *strsignal(int signum)
107{
108 const char *s = strings;
109
110 signum = sigmap(signum);
111 if (signum - 1U >= _NSIG-1) signum = 0;
112
113 for (; signum--; s++) for (; *s; s++);
114
115 return (char *)LCTRANS_CUR(s);
116}
libc/musl/src/string/strspn.c created+20
......@@ -0,0 +1,20 @@
1#include <string.h>
2
3#define BITOP(a,b,op) \
4 ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
5
6size_t strspn(const char *s, const char *c)
7{
8 const char *a = s;
9 size_t byteset[32/sizeof(size_t)] = { 0 };
10
11 if (!c[0]) return 0;
12 if (!c[1]) {
13 for (; *s == *c; s++);
14 return s-a;
15 }
16
17 for (; *c && BITOP(byteset, *(unsigned char *)c, |=); c++);
18 for (; *s && BITOP(byteset, *(unsigned char *)s, &); s++);
19 return s-a;
20}
libc/musl/src/string/strstr.c created+154
......@@ -0,0 +1,154 @@
1#include <string.h>
2#include <stdint.h>
3
4static char *twobyte_strstr(const unsigned char *h, const unsigned char *n)
5{
6 uint16_t nw = n[0]<<8 | n[1], hw = h[0]<<8 | h[1];
7 for (h++; *h && hw != nw; hw = hw<<8 | *++h);
8 return *h ? (char *)h-1 : 0;
9}
10
11static char *threebyte_strstr(const unsigned char *h, const unsigned char *n)
12{
13 uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8;
14 uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8;
15 for (h+=2; *h && hw != nw; hw = (hw|*++h)<<8);
16 return *h ? (char *)h-2 : 0;
17}
18
19static char *fourbyte_strstr(const unsigned char *h, const unsigned char *n)
20{
21 uint32_t nw = n[0]<<24 | n[1]<<16 | n[2]<<8 | n[3];
22 uint32_t hw = h[0]<<24 | h[1]<<16 | h[2]<<8 | h[3];
23 for (h+=3; *h && hw != nw; hw = hw<<8 | *++h);
24 return *h ? (char *)h-3 : 0;
25}
26
27#define MAX(a,b) ((a)>(b)?(a):(b))
28#define MIN(a,b) ((a)<(b)?(a):(b))
29
30#define BITOP(a,b,op) \
31 ((a)[(size_t)(b)/(8*sizeof *(a))] op (size_t)1<<((size_t)(b)%(8*sizeof *(a))))
32
33static char *twoway_strstr(const unsigned char *h, const unsigned char *n)
34{
35 const unsigned char *z;
36 size_t l, ip, jp, k, p, ms, p0, mem, mem0;
37 size_t byteset[32 / sizeof(size_t)] = { 0 };
38 size_t shift[256];
39
40 /* Computing length of needle and fill shift table */
41 for (l=0; n[l] && h[l]; l++)
42 BITOP(byteset, n[l], |=), shift[n[l]] = l+1;
43 if (n[l]) return 0; /* hit the end of h */
44
45 /* Compute maximal suffix */
46 ip = -1; jp = 0; k = p = 1;
47 while (jp+k<l) {
48 if (n[ip+k] == n[jp+k]) {
49 if (k == p) {
50 jp += p;
51 k = 1;
52 } else k++;
53 } else if (n[ip+k] > n[jp+k]) {
54 jp += k;
55 k = 1;
56 p = jp - ip;
57 } else {
58 ip = jp++;
59 k = p = 1;
60 }
61 }
62 ms = ip;
63 p0 = p;
64
65 /* And with the opposite comparison */
66 ip = -1; jp = 0; k = p = 1;
67 while (jp+k<l) {
68 if (n[ip+k] == n[jp+k]) {
69 if (k == p) {
70 jp += p;
71 k = 1;
72 } else k++;
73 } else if (n[ip+k] < n[jp+k]) {
74 jp += k;
75 k = 1;
76 p = jp - ip;
77 } else {
78 ip = jp++;
79 k = p = 1;
80 }
81 }
82 if (ip+1 > ms+1) ms = ip;
83 else p = p0;
84
85 /* Periodic needle? */
86 if (memcmp(n, n+p, ms+1)) {
87 mem0 = 0;
88 p = MAX(ms, l-ms-1) + 1;
89 } else mem0 = l-p;
90 mem = 0;
91
92 /* Initialize incremental end-of-haystack pointer */
93 z = h;
94
95 /* Search loop */
96 for (;;) {
97 /* Update incremental end-of-haystack pointer */
98 if (z-h < l) {
99 /* Fast estimate for MIN(l,63) */
100 size_t grow = l | 63;
101 const unsigned char *z2 = memchr(z, 0, grow);
102 if (z2) {
103 z = z2;
104 if (z-h < l) return 0;
105 } else z += grow;
106 }
107
108 /* Check last byte first; advance by shift on mismatch */
109 if (BITOP(byteset, h[l-1], &)) {
110 k = l-shift[h[l-1]];
111 if (k) {
112 if (k < mem) k = mem;
113 h += k;
114 mem = 0;
115 continue;
116 }
117 } else {
118 h += l;
119 mem = 0;
120 continue;
121 }
122
123 /* Compare right half */
124 for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
125 if (n[k]) {
126 h += k-ms;
127 mem = 0;
128 continue;
129 }
130 /* Compare left half */
131 for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
132 if (k <= mem) return (char *)h;
133 h += p;
134 mem = mem0;
135 }
136}
137
138char *strstr(const char *h, const char *n)
139{
140 /* Return immediately on empty needle */
141 if (!n[0]) return (char *)h;
142
143 /* Use faster algorithms for short needles */
144 h = strchr(h, *n);
145 if (!h || !n[1]) return (char *)h;
146 if (!h[1]) return 0;
147 if (!n[2]) return twobyte_strstr((void *)h, (void *)n);
148 if (!h[2]) return 0;
149 if (!n[3]) return threebyte_strstr((void *)h, (void *)n);
150 if (!h[3]) return 0;
151 if (!n[4]) return fourbyte_strstr((void *)h, (void *)n);
152
153 return twoway_strstr((void *)h, (void *)n);
154}
libc/musl/src/string/strtok.c created+13
......@@ -0,0 +1,13 @@
1#include <string.h>
2
3char *strtok(char *restrict s, const char *restrict sep)
4{
5 static char *p;
6 if (!s && !(s = p)) return NULL;
7 s += strspn(s, sep);
8 if (!*s) return p = 0;
9 p = s + strcspn(s, sep);
10 if (*p) *p++ = 0;
11 else p = 0;
12 return s;
13}
libc/musl/src/string/strtok_r.c created+12
......@@ -0,0 +1,12 @@
1#include <string.h>
2
3char *strtok_r(char *restrict s, const char *restrict sep, char **restrict p)
4{
5 if (!s && !(s = *p)) return NULL;
6 s += strspn(s, sep);
7 if (!*s) return *p = 0;
8 *p = s + strcspn(s, sep);
9 if (**p) *(*p)++ = 0;
10 else *p = 0;
11 return s;
12}
libc/musl/src/string/strverscmp.c created+34
......@@ -0,0 +1,34 @@
1#define _GNU_SOURCE
2#include <ctype.h>
3#include <string.h>
4
5int strverscmp(const char *l0, const char *r0)
6{
7 const unsigned char *l = (const void *)l0;
8 const unsigned char *r = (const void *)r0;
9 size_t i, dp, j;
10 int z = 1;
11
12 /* Find maximal matching prefix and track its maximal digit
13 * suffix and whether those digits are all zeros. */
14 for (dp=i=0; l[i]==r[i]; i++) {
15 int c = l[i];
16 if (!c) return 0;
17 if (!isdigit(c)) dp=i+1, z=1;
18 else if (c!='0') z=0;
19 }
20
21 if (l[dp]!='0' && r[dp]!='0') {
22 /* If we're not looking at a digit sequence that began
23 * with a zero, longest digit string is greater. */
24 for (j=i; isdigit(l[j]); j++)
25 if (!isdigit(r[j])) return 1;
26 if (isdigit(r[j])) return -1;
27 } else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) {
28 /* Otherwise, if common prefix of digit sequence is
29 * all zeros, digits order less than non-digits. */
30 return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0');
31 }
32
33 return l[i] - r[i];
34}
libc/musl/src/string/swab.c created+13
......@@ -0,0 +1,13 @@
1#include <unistd.h>
2
3void swab(const void *restrict _src, void *restrict _dest, ssize_t n)
4{
5 const char *src = _src;
6 char *dest = _dest;
7 for (; n>1; n-=2) {
8 dest[0] = src[1];
9 dest[1] = src[0];
10 dest += 2;
11 src += 2;
12 }
13}
libc/musl/src/string/wcpcpy.c created+6
......@@ -0,0 +1,6 @@
1#include <wchar.h>
2
3wchar_t *wcpcpy(wchar_t *restrict d, const wchar_t *restrict s)
4{
5 return wcscpy(d, s) + wcslen(s);
6}
libc/musl/src/string/wcpncpy.c created+6
......@@ -0,0 +1,6 @@
1#include <wchar.h>
2
3wchar_t *wcpncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
4{
5 return wcsncpy(d, s, n) + wcsnlen(s, n);
6}
libc/musl/src/string/wcscasecmp.c created+7
......@@ -0,0 +1,7 @@
1#include <wchar.h>
2#include <wctype.h>
3
4int wcscasecmp(const wchar_t *l, const wchar_t *r)
5{
6 return wcsncasecmp(l, r, -1);
7}
libc/musl/src/string/wcscasecmp_l.c created+6
......@@ -0,0 +1,6 @@
1#include <wchar.h>
2
3int wcscasecmp_l(const wchar_t *l, const wchar_t *r, locale_t locale)
4{
5 return wcscasecmp(l, r);
6}
libc/musl/src/string/wcscat.c created+7
......@@ -0,0 +1,7 @@
1#include <wchar.h>
2
3wchar_t *wcscat(wchar_t *restrict dest, const wchar_t *restrict src)
4{
5 wcscpy(dest + wcslen(dest), src);
6 return dest;
7}
libc/musl/src/string/wcschr.c created+8
......@@ -0,0 +1,8 @@
1#include <wchar.h>
2
3wchar_t *wcschr(const wchar_t *s, wchar_t c)
4{
5 if (!c) return (wchar_t *)s + wcslen(s);
6 for (; *s && *s != c; s++);
7 return *s ? (wchar_t *)s : 0;
8}
libc/musl/src/string/wcscmp.c created+7
......@@ -0,0 +1,7 @@
1#include <wchar.h>
2
3int wcscmp(const wchar_t *l, const wchar_t *r)
4{
5 for (; *l==*r && *l && *r; l++, r++);
6 return *l - *r;
7}
libc/musl/src/string/wcscpy.c created+8
......@@ -0,0 +1,8 @@
1#include <wchar.h>
2
3wchar_t *wcscpy(wchar_t *restrict d, const wchar_t *restrict s)
4{
5 wchar_t *a = d;
6 while ((*d++ = *s++));
7 return a;
8}
libc/musl/src/string/wcscspn.c created+10
......@@ -0,0 +1,10 @@
1#include <wchar.h>
2
3size_t wcscspn(const wchar_t *s, const wchar_t *c)
4{
5 const wchar_t *a;
6 if (!c[0]) return wcslen(s);
7 if (!c[1]) return (s=wcschr(a=s, *c)) ? s-a : wcslen(a);
8 for (a=s; *s && !wcschr(c, *s); s++);
9 return s-a;
10}
libc/musl/src/string/wcsdup.c created+10
......@@ -0,0 +1,10 @@
1#include <stdlib.h>
2#include <wchar.h>
3
4wchar_t *wcsdup(const wchar_t *s)
5{
6 size_t l = wcslen(s);
7 wchar_t *d = malloc((l+1)*sizeof(wchar_t));
8 if (!d) return NULL;
9 return wmemcpy(d, s, l+1);
10}
libc/musl/src/string/wcslen.c created+8
......@@ -0,0 +1,8 @@
1#include <wchar.h>
2
3size_t wcslen(const wchar_t *s)
4{
5 const wchar_t *a;
6 for (a=s; *s; s++);
7 return s-a;
8}
libc/musl/src/string/wcsncasecmp.c created+9
......@@ -0,0 +1,9 @@
1#include <wchar.h>
2#include <wctype.h>
3
4int wcsncasecmp(const wchar_t *l, const wchar_t *r, size_t n)
5{
6 if (!n--) return 0;
7 for (; *l && *r && n && (*l == *r || towlower(*l) == towlower(*r)); l++, r++, n--);
8 return towlower(*l) - towlower(*r);
9}
libc/musl/src/string/wcsncasecmp_l.c created+6
......@@ -0,0 +1,6 @@
1#include <wchar.h>
2
3int wcsncasecmp_l(const wchar_t *l, const wchar_t *r, size_t n, locale_t locale)
4{
5 return wcsncasecmp(l, r, n);
6}
libc/musl/src/string/wcsncat.c created+10
......@@ -0,0 +1,10 @@
1#include <wchar.h>
2
3wchar_t *wcsncat(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
4{
5 wchar_t *a = d;
6 d += wcslen(d);
7 while (n && *s) n--, *d++ = *s++;
8 *d++ = 0;
9 return a;
10}
libc/musl/src/string/wcsncmp.c created+7
......@@ -0,0 +1,7 @@
1#include <wchar.h>
2
3int wcsncmp(const wchar_t *l, const wchar_t *r, size_t n)
4{
5 for (; n && *l==*r && *l && *r; n--, l++, r++);
6 return n ? *l - *r : 0;
7}
libc/musl/src/string/wcsncpy.c created+9
......@@ -0,0 +1,9 @@
1#include <wchar.h>
2
3wchar_t *wcsncpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
4{
5 wchar_t *a = d;
6 while (n && *s) n--, *d++ = *s++;
7 wmemset(d, 0, n);
8 return a;
9}
libc/musl/src/string/wcsnlen.c created+8
......@@ -0,0 +1,8 @@
1#include <wchar.h>
2
3size_t wcsnlen(const wchar_t *s, size_t n)
4{
5 const wchar_t *z = wmemchr(s, 0, n);
6 if (z) n = z-s;
7 return n;
8}
libc/musl/src/string/wcspbrk.c created+7
......@@ -0,0 +1,7 @@
1#include <wchar.h>
2
3wchar_t *wcspbrk(const wchar_t *s, const wchar_t *b)
4{
5 s += wcscspn(s, b);
6 return *s ? (wchar_t *)s : NULL;
7}
libc/musl/src/string/wcsrchr.c created+8
......@@ -0,0 +1,8 @@
1#include <wchar.h>
2
3wchar_t *wcsrchr(const wchar_t *s, wchar_t c)
4{
5 const wchar_t *p;
6 for (p=s+wcslen(s); p>=s && *p!=c; p--);
7 return p>=s ? (wchar_t *)p : 0;
8}
libc/musl/src/string/wcsspn.c created+8
......@@ -0,0 +1,8 @@
1#include <wchar.h>
2
3size_t wcsspn(const wchar_t *s, const wchar_t *c)
4{
5 const wchar_t *a;
6 for (a=s; *s && wcschr(c, *s); s++);
7 return s-a;
8}
libc/musl/src/string/wcsstr.c created+105
......@@ -0,0 +1,105 @@
1#include <wchar.h>
2
3#define MAX(a,b) ((a)>(b)?(a):(b))
4#define MIN(a,b) ((a)<(b)?(a):(b))
5
6static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n)
7{
8 const wchar_t *z;
9 size_t l, ip, jp, k, p, ms, p0, mem, mem0;
10
11 /* Computing length of needle */
12 for (l=0; n[l] && h[l]; l++);
13 if (n[l]) return 0; /* hit the end of h */
14
15 /* Compute maximal suffix */
16 ip = -1; jp = 0; k = p = 1;
17 while (jp+k<l) {
18 if (n[ip+k] == n[jp+k]) {
19 if (k == p) {
20 jp += p;
21 k = 1;
22 } else k++;
23 } else if (n[ip+k] > n[jp+k]) {
24 jp += k;
25 k = 1;
26 p = jp - ip;
27 } else {
28 ip = jp++;
29 k = p = 1;
30 }
31 }
32 ms = ip;
33 p0 = p;
34
35 /* And with the opposite comparison */
36 ip = -1; jp = 0; k = p = 1;
37 while (jp+k<l) {
38 if (n[ip+k] == n[jp+k]) {
39 if (k == p) {
40 jp += p;
41 k = 1;
42 } else k++;
43 } else if (n[ip+k] < n[jp+k]) {
44 jp += k;
45 k = 1;
46 p = jp - ip;
47 } else {
48 ip = jp++;
49 k = p = 1;
50 }
51 }
52 if (ip+1 > ms+1) ms = ip;
53 else p = p0;
54
55 /* Periodic needle? */
56 if (wmemcmp(n, n+p, ms+1)) {
57 mem0 = 0;
58 p = MAX(ms, l-ms-1) + 1;
59 } else mem0 = l-p;
60 mem = 0;
61
62 /* Initialize incremental end-of-haystack pointer */
63 z = h;
64
65 /* Search loop */
66 for (;;) {
67 /* Update incremental end-of-haystack pointer */
68 if (z-h < l) {
69 /* Fast estimate for MIN(l,63) */
70 size_t grow = l | 63;
71 const wchar_t *z2 = wmemchr(z, 0, grow);
72 if (z2) {
73 z = z2;
74 if (z-h < l) return 0;
75 } else z += grow;
76 }
77
78 /* Compare right half */
79 for (k=MAX(ms+1,mem); n[k] && n[k] == h[k]; k++);
80 if (n[k]) {
81 h += k-ms;
82 mem = 0;
83 continue;
84 }
85 /* Compare left half */
86 for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--);
87 if (k <= mem) return (wchar_t *)h;
88 h += p;
89 mem = mem0;
90 }
91}
92
93wchar_t *wcsstr(const wchar_t *restrict h, const wchar_t *restrict n)
94{
95 /* Return immediately on empty needle or haystack */
96 if (!n[0]) return (wchar_t *)h;
97 if (!h[0]) return 0;
98
99 /* Use faster algorithms for short needles */
100 h = wcschr(h, *n);
101 if (!h || !n[1]) return (wchar_t *)h;
102 if (!h[1]) return 0;
103
104 return twoway_wcsstr(h, n);
105}
libc/musl/src/string/wcstok.c created+12
......@@ -0,0 +1,12 @@
1#include <wchar.h>
2
3wchar_t *wcstok(wchar_t *restrict s, const wchar_t *restrict sep, wchar_t **restrict p)
4{
5 if (!s && !(s = *p)) return NULL;
6 s += wcsspn(s, sep);
7 if (!*s) return *p = 0;
8 *p = s + wcscspn(s, sep);
9 if (**p) *(*p)++ = 0;
10 else *p = 0;
11 return s;
12}
libc/musl/src/string/wcswcs.c created+6
......@@ -0,0 +1,6 @@
1#include <wchar.h>
2
3wchar_t *wcswcs(const wchar_t *haystack, const wchar_t *needle)
4{
5 return wcsstr(haystack, needle);
6}
libc/musl/src/string/wmemchr.c created+7
......@@ -0,0 +1,7 @@
1#include <wchar.h>
2
3wchar_t *wmemchr(const wchar_t *s, wchar_t c, size_t n)
4{
5 for (; n && *s != c; n--, s++);
6 return n ? (wchar_t *)s : 0;
7}
libc/musl/src/string/wmemcmp.c created+7
......@@ -0,0 +1,7 @@
1#include <wchar.h>
2
3int wmemcmp(const wchar_t *l, const wchar_t *r, size_t n)
4{
5 for (; n && *l==*r; n--, l++, r++);
6 return n ? *l-*r : 0;
7}
libc/musl/src/string/wmemcpy.c created+8
......@@ -0,0 +1,8 @@
1#include <wchar.h>
2
3wchar_t *wmemcpy(wchar_t *restrict d, const wchar_t *restrict s, size_t n)
4{
5 wchar_t *a = d;
6 while (n--) *d++ = *s++;
7 return a;
8}
libc/musl/src/string/wmemmove.c created+13
......@@ -0,0 +1,13 @@
1#include <wchar.h>
2#include <stdint.h>
3
4wchar_t *wmemmove(wchar_t *d, const wchar_t *s, size_t n)
5{
6 wchar_t *d0 = d;
7 if (d == s) return d;
8 if ((uintptr_t)d-(uintptr_t)s < n * sizeof *d)
9 while (n--) d[n] = s[n];
10 else
11 while (n--) *d++ = *s++;
12 return d0;
13}
libc/musl/src/string/wmemset.c created+8
......@@ -0,0 +1,8 @@
1#include <wchar.h>
2
3wchar_t *wmemset(wchar_t *d, wchar_t c, size_t n)
4{
5 wchar_t *ret = d;
6 while (n--) *d++ = c;
7 return ret;
8}
libc/musl/src/string/x86_64/memcpy.s created+25
......@@ -0,0 +1,25 @@
1.global memcpy
2.global __memcpy_fwd
3.hidden __memcpy_fwd
4.type memcpy,@function
5memcpy:
6__memcpy_fwd:
7 mov %rdi,%rax
8 cmp $8,%rdx
9 jc 1f
10 test $7,%edi
11 jz 1f
122: movsb
13 dec %rdx
14 test $7,%edi
15 jnz 2b
161: mov %rdx,%rcx
17 shr $3,%rcx
18 rep
19 movsq
20 and $7,%edx
21 jz 1f
222: movsb
23 dec %edx
24 jnz 2b
251: ret
libc/musl/src/string/x86_64/memmove.s created+16
......@@ -0,0 +1,16 @@
1.global memmove
2.type memmove,@function
3memmove:
4 mov %rdi,%rax
5 sub %rsi,%rax
6 cmp %rdx,%rax
7.hidden __memcpy_fwd
8 jae __memcpy_fwd
9 mov %rdx,%rcx
10 lea -1(%rdi,%rdx),%rdi
11 lea -1(%rsi,%rdx),%rsi
12 std
13 rep movsb
14 cld
15 lea 1(%rdi),%rax
16 ret
libc/musl/src/string/x86_64/memset.s created+72
......@@ -0,0 +1,72 @@
1.global memset
2.type memset,@function
3memset:
4 movzbq %sil,%rax
5 mov $0x101010101010101,%r8
6 imul %r8,%rax
7
8 cmp $126,%rdx
9 ja 2f
10
11 test %edx,%edx
12 jz 1f
13
14 mov %sil,(%rdi)
15 mov %sil,-1(%rdi,%rdx)
16 cmp $2,%edx
17 jbe 1f
18
19 mov %ax,1(%rdi)
20 mov %ax,(-1-2)(%rdi,%rdx)
21 cmp $6,%edx
22 jbe 1f
23
24 mov %eax,(1+2)(%rdi)
25 mov %eax,(-1-2-4)(%rdi,%rdx)
26 cmp $14,%edx
27 jbe 1f
28
29 mov %rax,(1+2+4)(%rdi)
30 mov %rax,(-1-2-4-8)(%rdi,%rdx)
31 cmp $30,%edx
32 jbe 1f
33
34 mov %rax,(1+2+4+8)(%rdi)
35 mov %rax,(1+2+4+8+8)(%rdi)
36 mov %rax,(-1-2-4-8-16)(%rdi,%rdx)
37 mov %rax,(-1-2-4-8-8)(%rdi,%rdx)
38 cmp $62,%edx
39 jbe 1f
40
41 mov %rax,(1+2+4+8+16)(%rdi)
42 mov %rax,(1+2+4+8+16+8)(%rdi)
43 mov %rax,(1+2+4+8+16+16)(%rdi)
44 mov %rax,(1+2+4+8+16+24)(%rdi)
45 mov %rax,(-1-2-4-8-16-32)(%rdi,%rdx)
46 mov %rax,(-1-2-4-8-16-24)(%rdi,%rdx)
47 mov %rax,(-1-2-4-8-16-16)(%rdi,%rdx)
48 mov %rax,(-1-2-4-8-16-8)(%rdi,%rdx)
49
501: mov %rdi,%rax
51 ret
52
532: test $15,%edi
54 mov %rdi,%r8
55 mov %rax,-8(%rdi,%rdx)
56 mov %rdx,%rcx
57 jnz 2f
58
591: shr $3,%rcx
60 rep
61 stosq
62 mov %r8,%rax
63 ret
64
652: xor %edx,%edx
66 sub %edi,%edx
67 and $15,%edx
68 mov %rax,(%rdi)
69 mov %rax,8(%rdi)
70 sub %rdx,%rcx
71 add %rdx,%rdi
72 jmp 1b
libc/musl/src/temp/__randname.c created+18
......@@ -0,0 +1,18 @@
1#include <time.h>
2#include <stdint.h>
3
4/* This assumes that a check for the
5 template size has already been made */
6char *__randname(char *template)
7{
8 int i;
9 struct timespec ts;
10 unsigned long r;
11
12 __clock_gettime(CLOCK_REALTIME, &ts);
13 r = ts.tv_nsec*65537 ^ (uintptr_t)&ts / 16 + (uintptr_t)template;
14 for (i=0; i<6; i++, r>>=5)
15 template[i] = 'A'+(r&15)+(r&16)*2;
16
17 return template;
18}
libc/musl/src/temp/mkdtemp.c created+23
......@@ -0,0 +1,23 @@
1#include <string.h>
2#include <stdlib.h>
3#include <errno.h>
4#include <sys/stat.h>
5
6char *mkdtemp(char *template)
7{
8 size_t l = strlen(template);
9 int retries = 100;
10
11 if (l<6 || memcmp(template+l-6, "XXXXXX", 6)) {
12 errno = EINVAL;
13 return 0;
14 }
15
16 do {
17 __randname(template+l-6);
18 if (!mkdir(template, 0700)) return template;
19 } while (--retries && errno == EEXIST);
20
21 memcpy(template+l-6, "XXXXXX", 6);
22 return 0;
23}
libc/musl/src/temp/mkostemp.c created+9
......@@ -0,0 +1,9 @@
1#define _BSD_SOURCE
2#include <stdlib.h>
3
4int mkostemp(char *template, int flags)
5{
6 return __mkostemps(template, 0, flags);
7}
8
9weak_alias(mkostemp, mkostemp64);
libc/musl/src/temp/mkostemps.c created+29
......@@ -0,0 +1,29 @@
1#define _BSD_SOURCE
2#include <stdlib.h>
3#include <string.h>
4#include <fcntl.h>
5#include <unistd.h>
6#include <errno.h>
7
8int __mkostemps(char *template, int len, int flags)
9{
10 size_t l = strlen(template);
11 if (l<6 || len>l-6 || memcmp(template+l-len-6, "XXXXXX", 6)) {
12 errno = EINVAL;
13 return -1;
14 }
15
16 flags -= flags & O_ACCMODE;
17 int fd, retries = 100;
18 do {
19 __randname(template+l-len-6);
20 if ((fd = open(template, flags | O_RDWR | O_CREAT | O_EXCL, 0600))>=0)
21 return fd;
22 } while (--retries && errno == EEXIST);
23
24 memcpy(template+l-len-6, "XXXXXX", 6);
25 return -1;
26}
27
28weak_alias(__mkostemps, mkostemps);
29weak_alias(__mkostemps, mkostemps64);
libc/musl/src/temp/mkstemp.c created+8
......@@ -0,0 +1,8 @@
1#include <stdlib.h>
2
3int mkstemp(char *template)
4{
5 return __mkostemps(template, 0, 0);
6}
7
8weak_alias(mkstemp, mkstemp64);
libc/musl/src/temp/mkstemps.c created+9
......@@ -0,0 +1,9 @@
1#define _BSD_SOURCE
2#include <stdlib.h>
3
4int mkstemps(char *template, int len)
5{
6 return __mkostemps(template, len, 0);
7}
8
9weak_alias(mkstemps, mkstemps64);
libc/musl/src/temp/mktemp.c created+30
......@@ -0,0 +1,30 @@
1#define _GNU_SOURCE
2#include <string.h>
3#include <stdlib.h>
4#include <errno.h>
5#include <sys/stat.h>
6
7char *mktemp(char *template)
8{
9 size_t l = strlen(template);
10 int retries = 100;
11 struct stat st;
12
13 if (l < 6 || memcmp(template+l-6, "XXXXXX", 6)) {
14 errno = EINVAL;
15 *template = 0;
16 return template;
17 }
18
19 do {
20 __randname(template+l-6);
21 if (stat(template, &st)) {
22 if (errno != ENOENT) *template = 0;
23 return template;
24 }
25 } while (--retries);
26
27 *template = 0;
28 errno = EEXIST;
29 return template;
30}
libc/musl/src/termios/cfgetospeed.c created+13
......@@ -0,0 +1,13 @@
1#define _BSD_SOURCE
2#include <termios.h>
3#include <sys/ioctl.h>
4
5speed_t cfgetospeed(const struct termios *tio)
6{
7 return tio->c_cflag & CBAUD;
8}
9
10speed_t cfgetispeed(const struct termios *tio)
11{
12 return cfgetospeed(tio);
13}
libc/musl/src/termios/cfmakeraw.c created+13
......@@ -0,0 +1,13 @@
1#define _GNU_SOURCE
2#include <termios.h>
3
4void cfmakeraw(struct termios *t)
5{
6 t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON);
7 t->c_oflag &= ~OPOST;
8 t->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
9 t->c_cflag &= ~(CSIZE|PARENB);
10 t->c_cflag |= CS8;
11 t->c_cc[VMIN] = 1;
12 t->c_cc[VTIME] = 0;
13}
libc/musl/src/termios/cfsetospeed.c created+22
......@@ -0,0 +1,22 @@
1#define _BSD_SOURCE
2#include <termios.h>
3#include <sys/ioctl.h>
4#include <errno.h>
5
6int cfsetospeed(struct termios *tio, speed_t speed)
7{
8 if (speed & ~CBAUD) {
9 errno = EINVAL;
10 return -1;
11 }
12 tio->c_cflag &= ~CBAUD;
13 tio->c_cflag |= speed;
14 return 0;
15}
16
17int cfsetispeed(struct termios *tio, speed_t speed)
18{
19 return speed ? cfsetospeed(tio, speed) : 0;
20}
21
22weak_alias(cfsetospeed, cfsetspeed);
libc/musl/src/termios/tcdrain.c created+8
......@@ -0,0 +1,8 @@
1#include <termios.h>
2#include <sys/ioctl.h>
3#include "syscall.h"
4
5int tcdrain(int fd)
6{
7 return syscall_cp(SYS_ioctl, fd, TCSBRK, 1);
8}
libc/musl/src/termios/tcflow.c created+7
......@@ -0,0 +1,7 @@
1#include <termios.h>
2#include <sys/ioctl.h>
3
4int tcflow(int fd, int action)
5{
6 return ioctl(fd, TCXONC, action);
7}
libc/musl/src/termios/tcflush.c created+7
......@@ -0,0 +1,7 @@
1#include <termios.h>
2#include <sys/ioctl.h>
3
4int tcflush(int fd, int queue)
5{
6 return ioctl(fd, TCFLSH, queue);
7}
libc/musl/src/termios/tcgetattr.c created+9
......@@ -0,0 +1,9 @@
1#include <termios.h>
2#include <sys/ioctl.h>
3
4int tcgetattr(int fd, struct termios *tio)
5{
6 if (ioctl(fd, TCGETS, tio))
7 return -1;
8 return 0;
9}
libc/musl/src/termios/tcgetsid.c created+10
......@@ -0,0 +1,10 @@
1#include <termios.h>
2#include <sys/ioctl.h>
3
4pid_t tcgetsid(int fd)
5{
6 int sid;
7 if (ioctl(fd, TIOCGSID, &sid) < 0)
8 return -1;
9 return sid;
10}
libc/musl/src/termios/tcsendbreak.c created+8
......@@ -0,0 +1,8 @@
1#include <termios.h>
2#include <sys/ioctl.h>
3
4int tcsendbreak(int fd, int dur)
5{
6 /* nonzero duration is implementation-defined, so ignore it */
7 return ioctl(fd, TCSBRK, 0);
8}
libc/musl/src/termios/tcsetattr.c created+12
......@@ -0,0 +1,12 @@
1#include <termios.h>
2#include <sys/ioctl.h>
3#include <errno.h>
4
5int tcsetattr(int fd, int act, const struct termios *tio)
6{
7 if (act < 0 || act > 2) {
8 errno = EINVAL;
9 return -1;
10 }
11 return ioctl(fd, TCSETS+act, tio);
12}
libc/musl/src/thread/__lock.c created+60
......@@ -0,0 +1,60 @@
1#include "pthread_impl.h"
2
3/* This lock primitive combines a flag (in the sign bit) and a
4 * congestion count (= threads inside the critical section, CS) in a
5 * single int that is accessed through atomic operations. The states
6 * of the int for value x are:
7 *
8 * x == 0: unlocked and no thread inside the critical section
9 *
10 * x < 0: locked with a congestion of x-INT_MIN, including the thread
11 * that holds the lock
12 *
13 * x > 0: unlocked with a congestion of x
14 *
15 * or in an equivalent formulation x is the congestion count or'ed
16 * with INT_MIN as a lock flag.
17 */
18
19void __lock(volatile int *l)
20{
21 if (!libc.threads_minus_1) return;
22 /* fast path: INT_MIN for the lock, +1 for the congestion */
23 int current = a_cas(l, 0, INT_MIN + 1);
24 if (!current) return;
25 /* A first spin loop, for medium congestion. */
26 for (unsigned i = 0; i < 10; ++i) {
27 if (current < 0) current -= INT_MIN + 1;
28 // assertion: current >= 0
29 int val = a_cas(l, current, INT_MIN + (current + 1));
30 if (val == current) return;
31 current = val;
32 }
33 // Spinning failed, so mark ourselves as being inside the CS.
34 current = a_fetch_add(l, 1) + 1;
35 /* The main lock acquisition loop for heavy congestion. The only
36 * change to the value performed inside that loop is a successful
37 * lock via the CAS that acquires the lock. */
38 for (;;) {
39 /* We can only go into wait, if we know that somebody holds the
40 * lock and will eventually wake us up, again. */
41 if (current < 0) {
42 __futexwait(l, current, 1);
43 current -= INT_MIN + 1;
44 }
45 /* assertion: current > 0, the count includes us already. */
46 int val = a_cas(l, current, INT_MIN + current);
47 if (val == current) return;
48 current = val;
49 }
50}
51
52void __unlock(volatile int *l)
53{
54 /* Check l[0] to see if we are multi-threaded. */
55 if (l[0] < 0) {
56 if (a_fetch_add(l, -(INT_MIN + 1)) != (INT_MIN + 1)) {
57 __wake(l, 1, 1);
58 }
59 }
60}
libc/musl/src/thread/__set_thread_area.c created+10
......@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2
3int __set_thread_area(void *p)
4{
5#ifdef SYS_set_thread_area
6 return __syscall(SYS_set_thread_area, p);
7#else
8 return -ENOSYS;
9#endif
10}
libc/musl/src/thread/__syscall_cp.c created+20
......@@ -0,0 +1,20 @@
1#include "pthread_impl.h"
2#include "syscall.h"
3
4hidden long __syscall_cp_c();
5
6static long sccp(syscall_arg_t nr,
7 syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
8 syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
9{
10 return (__syscall)(nr, u, v, w, x, y, z);
11}
12
13weak_alias(sccp, __syscall_cp_c);
14
15long (__syscall_cp)(syscall_arg_t nr,
16 syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
17 syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
18{
19 return __syscall_cp_c(nr, u, v, w, x, y, z);
20}
libc/musl/src/thread/__timedwait.c created+51
......@@ -0,0 +1,51 @@
1#include <pthread.h>
2#include <time.h>
3#include <errno.h>
4#include "futex.h"
5#include "syscall.h"
6#include "pthread_impl.h"
7
8static volatile int dummy = 0;
9weak_alias(dummy, __eintr_valid_flag);
10
11int __timedwait_cp(volatile int *addr, int val,
12 clockid_t clk, const struct timespec *at, int priv)
13{
14 int r;
15 struct timespec to, *top=0;
16
17 if (priv) priv = FUTEX_PRIVATE;
18
19 if (at) {
20 if (at->tv_nsec >= 1000000000UL) return EINVAL;
21 if (__clock_gettime(clk, &to)) return EINVAL;
22 to.tv_sec = at->tv_sec - to.tv_sec;
23 if ((to.tv_nsec = at->tv_nsec - to.tv_nsec) < 0) {
24 to.tv_sec--;
25 to.tv_nsec += 1000000000;
26 }
27 if (to.tv_sec < 0) return ETIMEDOUT;
28 top = &to;
29 }
30
31 r = -__syscall_cp(SYS_futex, addr, FUTEX_WAIT|priv, val, top);
32 if (r == ENOSYS) r = -__syscall_cp(SYS_futex, addr, FUTEX_WAIT, val, top);
33 if (r != EINTR && r != ETIMEDOUT && r != ECANCELED) r = 0;
34 /* Mitigate bug in old kernels wrongly reporting EINTR for non-
35 * interrupting (SA_RESTART) signal handlers. This is only practical
36 * when NO interrupting signal handlers have been installed, and
37 * works by sigaction tracking whether that's the case. */
38 if (r == EINTR && !__eintr_valid_flag) r = 0;
39
40 return r;
41}
42
43int __timedwait(volatile int *addr, int val,
44 clockid_t clk, const struct timespec *at, int priv)
45{
46 int cs, r;
47 __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
48 r = __timedwait_cp(addr, val, clk, at, priv);
49 __pthread_setcancelstate(cs, 0);
50 return r;
51}
libc/musl/src/thread/__tls_get_addr.c created+12
......@@ -0,0 +1,12 @@
1#include <stddef.h>
2#include "pthread_impl.h"
3
4void *__tls_get_addr(tls_mod_off_t *v)
5{
6 pthread_t self = __pthread_self();
7 if (v[0] <= self->dtv[0])
8 return (void *)(self->dtv[v[0]] + v[1]);
9 return __tls_get_new(v);
10}
11
12weak_alias(__tls_get_addr, __tls_get_new);
libc/musl/src/thread/__unmapself.c created+29
......@@ -0,0 +1,29 @@
1#include "pthread_impl.h"
2#include "atomic.h"
3#include "syscall.h"
4/* cheat and reuse CRTJMP macro from dynlink code */
5#include "dynlink.h"
6
7static volatile int lock;
8static void *unmap_base;
9static size_t unmap_size;
10static char shared_stack[256];
11
12static void do_unmap()
13{
14 __syscall(SYS_munmap, unmap_base, unmap_size);
15 __syscall(SYS_exit);
16}
17
18void __unmapself(void *base, size_t size)
19{
20 int tid=__pthread_self()->tid;
21 char *stack = shared_stack + sizeof shared_stack;
22 stack -= (uintptr_t)stack % 16;
23 while (lock || a_cas(&lock, 0, tid))
24 a_spin();
25 __syscall(SYS_set_tid_address, &lock);
26 unmap_base = base;
27 unmap_size = size;
28 CRTJMP(do_unmap, stack);
29}
libc/musl/src/thread/__wait.c created+17
......@@ -0,0 +1,17 @@
1#include "pthread_impl.h"
2
3void __wait(volatile int *addr, volatile int *waiters, int val, int priv)
4{
5 int spins=100;
6 if (priv) priv = FUTEX_PRIVATE;
7 while (spins-- && (!waiters || !*waiters)) {
8 if (*addr==val) a_spin();
9 else return;
10 }
11 if (waiters) a_inc(waiters);
12 while (*addr==val) {
13 __syscall(SYS_futex, addr, FUTEX_WAIT|priv, val, 0) != -ENOSYS
14 || __syscall(SYS_futex, addr, FUTEX_WAIT, val, 0);
15 }
16 if (waiters) a_dec(waiters);
17}
libc/musl/src/thread/aarch64/__set_thread_area.s created+7
......@@ -0,0 +1,7 @@
1.global __set_thread_area
2.hidden __set_thread_area
3.type __set_thread_area,@function
4__set_thread_area:
5 msr tpidr_el0,x0
6 mov w0,#0
7 ret
libc/musl/src/thread/aarch64/__unmapself.s created+7
......@@ -0,0 +1,7 @@
1.global __unmapself
2.type __unmapself,%function
3__unmapself:
4 mov x8,#215 // SYS_munmap
5 svc 0
6 mov x8,#93 // SYS_exit
7 svc 0
libc/musl/src/thread/aarch64/clone.s created+30
......@@ -0,0 +1,30 @@
1// __clone(func, stack, flags, arg, ptid, tls, ctid)
2// x0, x1, w2, x3, x4, x5, x6
3
4// syscall(SYS_clone, flags, stack, ptid, tls, ctid)
5// x8, x0, x1, x2, x3, x4
6
7.global __clone
8.hidden __clone
9.type __clone,%function
10__clone:
11 // align stack and save func,arg
12 and x1,x1,#-16
13 stp x0,x3,[x1,#-16]!
14
15 // syscall
16 uxtw x0,w2
17 mov x2,x4
18 mov x3,x5
19 mov x4,x6
20 mov x8,#220 // SYS_clone
21 svc #0
22
23 cbz x0,1f
24 // parent
25 ret
26 // child
271: ldp x1,x0,[sp],#16
28 blr x1
29 mov x8,#93 // SYS_exit
30 svc #0
libc/musl/src/thread/aarch64/syscall_cp.s created+32
......@@ -0,0 +1,32 @@
1// __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z)
2// x0 x1 x2 x3 x4 x5 x6 x7
3
4// syscall(nr, u, v, w, x, y, z)
5// x8 x0 x1 x2 x3 x4 x5
6
7.global __cp_begin
8.hidden __cp_begin
9.global __cp_end
10.hidden __cp_end
11.global __cp_cancel
12.hidden __cp_cancel
13.hidden __cancel
14.global __syscall_cp_asm
15.hidden __syscall_cp_asm
16.type __syscall_cp_asm,%function
17__syscall_cp_asm:
18__cp_begin:
19 ldr w0,[x0]
20 cbnz w0,__cp_cancel
21 mov x8,x1
22 mov x0,x2
23 mov x1,x3
24 mov x2,x4
25 mov x3,x5
26 mov x4,x6
27 mov x5,x7
28 svc 0
29__cp_end:
30 ret
31__cp_cancel:
32 b __cancel
libc/musl/src/thread/arm/__aeabi_read_tp.s created+10
......@@ -0,0 +1,10 @@
1.syntax unified
2.global __aeabi_read_tp
3.type __aeabi_read_tp,%function
4__aeabi_read_tp:
5 ldr r0,1f
6 add r0,r0,pc
7 ldr r0,[r0]
82: bx r0
9 .align 2
101: .word __a_gettp_ptr - 2b
libc/musl/src/thread/arm/__set_thread_area.c created+52
......@@ -0,0 +1,52 @@
1#include <stdint.h>
2#include <elf.h>
3#include "pthread_impl.h"
4#include "libc.h"
5
6#define HWCAP_TLS (1 << 15)
7
8extern hidden const unsigned char
9 __a_barrier_oldkuser[], __a_barrier_v6[], __a_barrier_v7[],
10 __a_cas_v6[], __a_cas_v7[],
11 __a_gettp_cp15[];
12
13#define __a_barrier_kuser 0xffff0fa0
14#define __a_barrier_oldkuser (uintptr_t)__a_barrier_oldkuser
15#define __a_barrier_v6 (uintptr_t)__a_barrier_v6
16#define __a_barrier_v7 (uintptr_t)__a_barrier_v7
17
18#define __a_cas_kuser 0xffff0fc0
19#define __a_cas_v6 (uintptr_t)__a_cas_v6
20#define __a_cas_v7 (uintptr_t)__a_cas_v7
21
22#define __a_gettp_kuser 0xffff0fe0
23#define __a_gettp_cp15 (uintptr_t)__a_gettp_cp15
24
25extern hidden uintptr_t __a_barrier_ptr, __a_cas_ptr, __a_gettp_ptr;
26
27int __set_thread_area(void *p)
28{
29#if !__ARM_ARCH_7A__ && !__ARM_ARCH_7R__ && __ARM_ARCH < 7
30 if (__hwcap & HWCAP_TLS) {
31 size_t *aux;
32 __a_cas_ptr = __a_cas_v7;
33 __a_barrier_ptr = __a_barrier_v7;
34 for (aux=libc.auxv; *aux; aux+=2) {
35 if (*aux != AT_PLATFORM) continue;
36 const char *s = (void *)aux[1];
37 if (s[0]!='v' || s[1]!='6' || s[2]-'0'<10u) break;
38 __a_cas_ptr = __a_cas_v6;
39 __a_barrier_ptr = __a_barrier_v6;
40 break;
41 }
42 } else {
43 int ver = *(int *)0xffff0ffc;
44 __a_gettp_ptr = __a_gettp_kuser;
45 __a_cas_ptr = __a_cas_kuser;
46 __a_barrier_ptr = __a_barrier_kuser;
47 if (ver < 2) a_crash();
48 if (ver < 3) __a_barrier_ptr = __a_barrier_oldkuser;
49 }
50#endif
51 return __syscall(0xf0005, p);
52}
libc/musl/src/thread/arm/__unmapself.s created+9
......@@ -0,0 +1,9 @@
1.syntax unified
2.text
3.global __unmapself
4.type __unmapself,%function
5__unmapself:
6 mov r7,#91
7 svc 0
8 mov r7,#1
9 svc 0
libc/musl/src/thread/arm/atomics.s created+106
......@@ -0,0 +1,106 @@
1.syntax unified
2.text
3
4.global __a_barrier_dummy
5.hidden __a_barrier_dummy
6.type __a_barrier_dummy,%function
7__a_barrier_dummy:
8 bx lr
9
10.global __a_barrier_oldkuser
11.hidden __a_barrier_oldkuser
12.type __a_barrier_oldkuser,%function
13__a_barrier_oldkuser:
14 push {r0,r1,r2,r3,ip,lr}
15 mov r1,r0
16 mov r2,sp
17 ldr ip,=0xffff0fc0
18 mov lr,pc
19 mov pc,ip
20 pop {r0,r1,r2,r3,ip,lr}
21 bx lr
22
23.global __a_barrier_v6
24.hidden __a_barrier_v6
25.type __a_barrier_v6,%function
26__a_barrier_v6:
27 .arch armv6t2
28 mcr p15,0,r0,c7,c10,5
29 bx lr
30
31.global __a_barrier_v7
32.hidden __a_barrier_v7
33.type __a_barrier_v7,%function
34__a_barrier_v7:
35 .arch armv7-a
36 dmb ish
37 bx lr
38
39.global __a_cas_dummy
40.hidden __a_cas_dummy
41.type __a_cas_dummy,%function
42__a_cas_dummy:
43 mov r3,r0
44 ldr r0,[r2]
45 subs r0,r3,r0
46 streq r1,[r2]
47 bx lr
48
49.global __a_cas_v6
50.hidden __a_cas_v6
51.type __a_cas_v6,%function
52__a_cas_v6:
53 .arch armv6t2
54 mov r3,r0
55 mcr p15,0,r0,c7,c10,5
561: ldrex r0,[r2]
57 subs r0,r3,r0
58 strexeq r0,r1,[r2]
59 teqeq r0,#1
60 beq 1b
61 mcr p15,0,r0,c7,c10,5
62 bx lr
63
64.global __a_cas_v7
65.hidden __a_cas_v7
66.type __a_cas_v7,%function
67__a_cas_v7:
68 .arch armv7-a
69 mov r3,r0
70 dmb ish
711: ldrex r0,[r2]
72 subs r0,r3,r0
73 strexeq r0,r1,[r2]
74 teqeq r0,#1
75 beq 1b
76 dmb ish
77 bx lr
78
79.global __a_gettp_cp15
80.hidden __a_gettp_cp15
81.type __a_gettp_cp15,%function
82__a_gettp_cp15:
83 mrc p15,0,r0,c13,c0,3
84 bx lr
85
86/* Tag this file with minimum ISA level so as not to affect linking. */
87.object_arch armv4t
88.eabi_attribute 6,2
89
90.data
91.align 2
92
93.global __a_barrier_ptr
94.hidden __a_barrier_ptr
95__a_barrier_ptr:
96 .word __a_barrier_dummy
97
98.global __a_cas_ptr
99.hidden __a_cas_ptr
100__a_cas_ptr:
101 .word __a_cas_dummy
102
103.global __a_gettp_ptr
104.hidden __a_gettp_ptr
105__a_gettp_ptr:
106 .word __a_gettp_cp15
libc/musl/src/thread/arm/clone.s created+32
......@@ -0,0 +1,32 @@
1.syntax unified
2.text
3.global __clone
4.hidden __clone
5.type __clone,%function
6__clone:
7 stmfd sp!,{r4,r5,r6,r7}
8 mov r7,#120
9 mov r6,r3
10 mov r5,r0
11 mov r0,r2
12 and r1,r1,#-16
13 ldr r2,[sp,#16]
14 ldr r3,[sp,#20]
15 ldr r4,[sp,#24]
16 svc 0
17 tst r0,r0
18 beq 1f
19 ldmfd sp!,{r4,r5,r6,r7}
20 bx lr
21
221: mov r0,r6
23 tst r5,#1
24 bne 1f
25 mov lr,pc
26 mov pc,r5
272: mov r7,#1
28 svc 0
29
301: mov lr,pc
31 bx r5
32 b 2b
libc/musl/src/thread/arm/syscall_cp.s created+29
......@@ -0,0 +1,29 @@
1.syntax unified
2.global __cp_begin
3.hidden __cp_begin
4.global __cp_end
5.hidden __cp_end
6.global __cp_cancel
7.hidden __cp_cancel
8.hidden __cancel
9.global __syscall_cp_asm
10.hidden __syscall_cp_asm
11.type __syscall_cp_asm,%function
12__syscall_cp_asm:
13 mov ip,sp
14 stmfd sp!,{r4,r5,r6,r7,lr}
15__cp_begin:
16 ldr r0,[r0]
17 cmp r0,#0
18 blne __cp_cancel
19 mov r7,r1
20 mov r0,r2
21 mov r1,r3
22 ldmfd ip,{r2,r3,r4,r5,r6}
23 svc 0
24__cp_end:
25 ldmfd sp!,{r4,r5,r6,r7,lr}
26 bx lr
27__cp_cancel:
28 ldmfd sp!,{r4,r5,r6,r7,lr}
29 b __cancel
libc/musl/src/thread/call_once.c created+7
......@@ -0,0 +1,7 @@
1#include <threads.h>
2#include <pthread.h>
3
4void call_once(once_flag *flag, void (*func)(void))
5{
6 __pthread_once(flag, func);
7}
libc/musl/src/thread/clone.c created+7
......@@ -0,0 +1,7 @@
1#include <errno.h>
2#include "pthread_impl.h"
3
4int __clone(int (*func)(void *), void *stack, int flags, void *arg, ...)
5{
6 return -ENOSYS;
7}
libc/musl/src/thread/cnd_broadcast.c created+9
......@@ -0,0 +1,9 @@
1#include <threads.h>
2#include <pthread.h>
3
4int cnd_broadcast(cnd_t *c)
5{
6 /* This internal function never fails, and always returns zero,
7 * which matches the value thrd_success is defined with. */
8 return __private_cond_signal((pthread_cond_t *)c, -1);
9}
libc/musl/src/thread/cnd_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include <threads.h>
2
3void cnd_destroy(cnd_t *c)
4{
5 /* For private cv this is a no-op */
6}
libc/musl/src/thread/cnd_init.c created+7
......@@ -0,0 +1,7 @@
1#include <threads.h>
2
3int cnd_init(cnd_t *c)
4{
5 *c = (cnd_t){ 0 };
6 return thrd_success;
7}
libc/musl/src/thread/cnd_signal.c created+9
......@@ -0,0 +1,9 @@
1#include <threads.h>
2#include <pthread.h>
3
4int cnd_signal(cnd_t *c)
5{
6 /* This internal function never fails, and always returns zero,
7 * which matches the value thrd_success is defined with. */
8 return __private_cond_signal((pthread_cond_t *)c, 1);
9}
libc/musl/src/thread/cnd_timedwait.c created+14
......@@ -0,0 +1,14 @@
1#include <threads.h>
2#include <pthread.h>
3#include <errno.h>
4
5int cnd_timedwait(cnd_t *restrict c, mtx_t *restrict m, const struct timespec *restrict ts)
6{
7 int ret = __pthread_cond_timedwait((pthread_cond_t *)c, (pthread_mutex_t *)m, ts);
8 switch (ret) {
9 /* May also return EINVAL or EPERM. */
10 default: return thrd_error;
11 case 0: return thrd_success;
12 case ETIMEDOUT: return thrd_timedout;
13 }
14}
libc/musl/src/thread/cnd_wait.c created+9
......@@ -0,0 +1,9 @@
1#include <threads.h>
2
3int cnd_wait(cnd_t *c, mtx_t *m)
4{
5 /* Calling cnd_timedwait with a null pointer is an extension.
6 * It is convenient here to avoid duplication of the logic
7 * for return values. */
8 return cnd_timedwait(c, m, 0);
9}
libc/musl/src/thread/default_attr.c created+4
......@@ -0,0 +1,4 @@
1#include "pthread_impl.h"
2
3unsigned __default_stacksize = DEFAULT_STACK_SIZE;
4unsigned __default_guardsize = DEFAULT_GUARD_SIZE;
libc/musl/src/thread/i386/__set_thread_area.s created+46
......@@ -0,0 +1,46 @@
1.text
2.global __set_thread_area
3.hidden __set_thread_area
4.type __set_thread_area,@function
5__set_thread_area:
6 push %ebx
7 push $0x51
8 push $0xfffff
9 push 16(%esp)
10 call 1f
111: addl $4f-1b,(%esp)
12 pop %ecx
13 mov (%ecx),%edx
14 push %edx
15 mov %esp,%ebx
16 xor %eax,%eax
17 mov $243,%al
18 int $128
19 testl %eax,%eax
20 jnz 2f
21 movl (%esp),%edx
22 movl %edx,(%ecx)
23 leal 3(,%edx,8),%edx
243: movw %dx,%gs
251:
26 addl $16,%esp
27 popl %ebx
28 ret
292:
30 mov %ebx,%ecx
31 xor %ebx,%ebx
32 xor %edx,%edx
33 mov %ebx,(%esp)
34 mov $1,%bl
35 mov $16,%dl
36 mov $123,%al
37 int $128
38 testl %eax,%eax
39 jnz 1b
40 mov $7,%dl
41 inc %al
42 jmp 3b
43
44.data
45 .align 4
464: .long -1
libc/musl/src/thread/i386/__unmapself.s created+11
......@@ -0,0 +1,11 @@
1.text
2.global __unmapself
3.type __unmapself,@function
4__unmapself:
5 movl $91,%eax
6 movl 4(%esp),%ebx
7 movl 8(%esp),%ecx
8 int $128
9 xorl %ebx,%ebx
10 movl $1,%eax
11 int $128
libc/musl/src/thread/i386/clone.s created+49
......@@ -0,0 +1,49 @@
1.text
2.global __clone
3.hidden __clone
4.type __clone,@function
5__clone:
6 push %ebp
7 mov %esp,%ebp
8 push %ebx
9 push %esi
10 push %edi
11
12 xor %eax,%eax
13 push $0x51
14 mov %gs,%ax
15 push $0xfffff
16 shr $3,%eax
17 push 28(%ebp)
18 push %eax
19 mov $120,%al
20
21 mov 12(%ebp),%ecx
22 mov 16(%ebp),%ebx
23 and $-16,%ecx
24 sub $16,%ecx
25 mov 20(%ebp),%edi
26 mov %edi,(%ecx)
27 mov 24(%ebp),%edx
28 mov %esp,%esi
29 mov 32(%ebp),%edi
30 mov 8(%ebp),%ebp
31 int $128
32 test %eax,%eax
33 jnz 1f
34
35 mov %ebp,%eax
36 xor %ebp,%ebp
37 call *%eax
38 mov %eax,%ebx
39 xor %eax,%eax
40 inc %eax
41 int $128
42 hlt
43
441: add $16,%esp
45 pop %edi
46 pop %esi
47 pop %ebx
48 pop %ebp
49 ret
libc/musl/src/thread/i386/syscall_cp.s created+41
......@@ -0,0 +1,41 @@
1.text
2.global __cp_begin
3.hidden __cp_begin
4.global __cp_end
5.hidden __cp_end
6.global __cp_cancel
7.hidden __cp_cancel
8.hidden __cancel
9.global __syscall_cp_asm
10.hidden __syscall_cp_asm
11.type __syscall_cp_asm,@function
12__syscall_cp_asm:
13 mov 4(%esp),%ecx
14 pushl %ebx
15 pushl %esi
16 pushl %edi
17 pushl %ebp
18__cp_begin:
19 movl (%ecx),%eax
20 testl %eax,%eax
21 jnz __cp_cancel
22 movl 24(%esp),%eax
23 movl 28(%esp),%ebx
24 movl 32(%esp),%ecx
25 movl 36(%esp),%edx
26 movl 40(%esp),%esi
27 movl 44(%esp),%edi
28 movl 48(%esp),%ebp
29 int $128
30__cp_end:
31 popl %ebp
32 popl %edi
33 popl %esi
34 popl %ebx
35 ret
36__cp_cancel:
37 popl %ebp
38 popl %edi
39 popl %esi
40 popl %ebx
41 jmp __cancel
libc/musl/src/thread/i386/tls.s created+17
......@@ -0,0 +1,17 @@
1.text
2.global ___tls_get_addr
3.type ___tls_get_addr,@function
4___tls_get_addr:
5 mov %gs:4,%edx
6 mov (%eax),%ecx
7 cmp %ecx,(%edx)
8 jc 1f
9 mov 4(%eax),%eax
10 add (%edx,%ecx,4),%eax
11 ret
121: push %eax
13.weak __tls_get_new
14.hidden __tls_get_new
15 call __tls_get_new
16 pop %edx
17 ret
libc/musl/src/thread/lock_ptc.c created+18
......@@ -0,0 +1,18 @@
1#include <pthread.h>
2
3static pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
4
5void __inhibit_ptc()
6{
7 pthread_rwlock_wrlock(&lock);
8}
9
10void __acquire_ptc()
11{
12 pthread_rwlock_rdlock(&lock);
13}
14
15void __release_ptc()
16{
17 pthread_rwlock_unlock(&lock);
18}
libc/musl/src/thread/m68k/__m68k_read_tp.s created+8
......@@ -0,0 +1,8 @@
1.text
2.global __m68k_read_tp
3.type __m68k_read_tp,@function
4__m68k_read_tp:
5 move.l #333,%d0
6 trap #0
7 move.l %d0,%a0
8 rts
libc/musl/src/thread/m68k/clone.s created+25
......@@ -0,0 +1,25 @@
1.text
2.global __clone
3.hidden __clone
4.type __clone,@function
5__clone:
6 movem.l %d2-%d5,-(%sp)
7 move.l #120,%d0
8 move.l 28(%sp),%d1
9 move.l 24(%sp),%d2
10 and.l #-16,%d2
11 move.l 36(%sp),%d3
12 move.l 44(%sp),%d4
13 move.l 40(%sp),%d5
14 move.l 20(%sp),%a0
15 move.l 32(%sp),%a1
16 trap #0
17 tst.l %d0
18 beq 1f
19 movem.l (%sp)+,%d2-%d5
20 rts
211: move.l %a1,-(%sp)
22 jsr (%a0)
23 move.l #1,%d0
24 trap #0
25 clr.b 0
libc/musl/src/thread/m68k/syscall_cp.s created+26
......@@ -0,0 +1,26 @@
1.text
2.global __cp_begin
3.hidden __cp_begin
4.global __cp_end
5.hidden __cp_end
6.global __cp_cancel
7.hidden __cp_cancel
8.hidden __cancel
9.global __syscall_cp_asm
10.hidden __syscall_cp_asm
11.type __syscall_cp_asm,@function
12__syscall_cp_asm:
13 movem.l %d2-%d5,-(%sp)
14 movea.l 20(%sp),%a0
15__cp_begin:
16 move.l (%a0),%d0
17 bne __cp_cancel
18 movem.l 24(%sp),%d0-%d5/%a0
19 trap #0
20__cp_end:
21 movem.l (%sp)+,%d2-%d5
22 rts
23__cp_cancel:
24 movem.l (%sp)+,%d2-%d5
25 move.l __cancel-.-8,%a1
26 jmp (%pc,%a1)
libc/musl/src/thread/microblaze/__set_thread_area.s created+7
......@@ -0,0 +1,7 @@
1.global __set_thread_area
2.hidden __set_thread_area
3.type __set_thread_area,@function
4__set_thread_area:
5 ori r21, r5, 0
6 rtsd r15, 8
7 ori r3, r0, 0
libc/musl/src/thread/microblaze/__unmapself.s created+8
......@@ -0,0 +1,8 @@
1.global __unmapself
2.type __unmapself,@function
3__unmapself:
4 ori r12, r0, 91
5 brki r14, 0x8
6 ori r12, r0, 1
7 brki r14, 0x8
8 nop
libc/musl/src/thread/microblaze/clone.s created+30
......@@ -0,0 +1,30 @@
1.global __clone
2.hidden __clone
3.type __clone,@function
4
5# r5, r6, r7, r8, r9, r10, stack
6# fn, st, fl, ar, pt, tl, ct
7# fl, st, __, pt, ct, tl
8
9__clone:
10 andi r6, r6, -16
11 addi r6, r6, -16
12 swi r5, r6, 0
13 swi r8, r6, 4
14
15 ori r5, r7, 0
16 ori r8, r9, 0
17 lwi r9, r1, 28
18 ori r12, r0, 120
19
20 brki r14, 8
21 beqi r3, 1f
22 rtsd r15, 8
23 nop
24
251: lwi r3, r1, 0
26 lwi r5, r1, 4
27 brald r15, r3
28 nop
29 ori r12, r0, 1
30 brki r14, 8
libc/musl/src/thread/microblaze/syscall_cp.s created+27
......@@ -0,0 +1,27 @@
1.global __cp_begin
2.hidden __cp_begin
3.global __cp_end
4.hidden __cp_end
5.global __cp_cancel
6.hidden __cp_cancel
7.hidden __cancel
8.global __syscall_cp_asm
9.hidden __syscall_cp_asm
10.type __syscall_cp_asm,@function
11__syscall_cp_asm:
12__cp_begin:
13 lwi r5, r5, 0
14 bnei r5, __cp_cancel
15 addi r12, r6, 0
16 add r5, r7, r0
17 add r6, r8, r0
18 add r7, r9, r0
19 add r8, r10, r0
20 lwi r9, r1, 28
21 lwi r10, r1, 32
22 brki r14, 0x8
23__cp_end:
24 rtsd r15, 8
25 nop
26__cp_cancel:
27 bri __cancel
libc/musl/src/thread/mips/__unmapself.s created+10
......@@ -0,0 +1,10 @@
1.set noreorder
2.global __unmapself
3.type __unmapself,@function
4__unmapself:
5 move $sp, $25
6 li $2, 4091
7 syscall
8 li $4, 0
9 li $2, 4001
10 syscall
libc/musl/src/thread/mips/clone.s created+36
......@@ -0,0 +1,36 @@
1.set noreorder
2.global __clone
3.hidden __clone
4.type __clone,@function
5__clone:
6 # Save function pointer and argument pointer on new thread stack
7 and $5, $5, -8
8 subu $5, $5, 16
9 sw $4, 0($5)
10 sw $7, 4($5)
11 # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
12 move $4, $6
13 lw $6, 16($sp)
14 lw $7, 20($sp)
15 lw $9, 24($sp)
16 subu $sp, $sp, 16
17 sw $9, 16($sp)
18 li $2, 4120
19 syscall
20 beq $7, $0, 1f
21 nop
22 addu $sp, $sp, 16
23 jr $ra
24 subu $2, $0, $2
251: beq $2, $0, 1f
26 nop
27 addu $sp, $sp, 16
28 jr $ra
29 nop
301: lw $25, 0($sp)
31 lw $4, 4($sp)
32 jalr $25
33 nop
34 move $4, $2
35 li $2, 4001
36 syscall
libc/musl/src/thread/mips/syscall_cp.s created+53
......@@ -0,0 +1,53 @@
1.set noreorder
2
3.global __cp_begin
4.hidden __cp_begin
5.type __cp_begin,@function
6.global __cp_end
7.hidden __cp_end
8.type __cp_end,@function
9.global __cp_cancel
10.hidden __cp_cancel
11.type __cp_cancel,@function
12.hidden __cancel
13.global __syscall_cp_asm
14.hidden __syscall_cp_asm
15.type __syscall_cp_asm,@function
16__syscall_cp_asm:
17 subu $sp, $sp, 32
18__cp_begin:
19 lw $4, 0($4)
20 bne $4, $0, __cp_cancel
21 move $2, $5
22 move $4, $6
23 move $5, $7
24 lw $6, 48($sp)
25 lw $7, 52($sp)
26 lw $8, 56($sp)
27 lw $9, 60($sp)
28 lw $10,64($sp)
29 sw $8, 16($sp)
30 sw $9, 20($sp)
31 sw $10,24($sp)
32 sw $2, 28($sp)
33 lw $2, 28($sp)
34 syscall
35__cp_end:
36 beq $7, $0, 1f
37 addu $sp, $sp, 32
38 subu $2, $0, $2
391: jr $ra
40 nop
41
42__cp_cancel:
43 move $2, $ra
44 bal 1f
45 addu $sp, $sp, 32
46 .gpword .
47 .gpword __cancel
481: lw $3, ($ra)
49 subu $3, $ra, $3
50 lw $25, 4($ra)
51 addu $25, $25, $3
52 jr $25
53 move $ra, $2
libc/musl/src/thread/mips64/__unmapself.s created+9
......@@ -0,0 +1,9 @@
1.set noreorder
2.global __unmapself
3.type __unmapself, @function
4__unmapself:
5 li $2, 5011
6 syscall
7 li $4, 0
8 li $2, 5058
9 syscall
libc/musl/src/thread/mips64/clone.s created+34
......@@ -0,0 +1,34 @@
1.set noreorder
2.global __clone
3.hidden __clone
4.type __clone,@function
5__clone:
6 # Save function pointer and argument pointer on new thread stack
7 and $5, $5, -16 # aligning stack to double word
8 dsubu $5, $5, 16
9 sd $4, 0($5) # save function pointer
10 sd $7, 8($5) # save argument pointer
11
12 # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
13 # sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls)
14 move $4, $6
15 move $6, $8
16 move $7, $9
17 move $8, $10
18 li $2, 5055
19 syscall
20 beq $7, $0, 1f
21 nop
22 jr $ra
23 dsubu $2, $0, $2
241: beq $2, $0, 1f
25 nop
26 jr $ra
27 nop
281: ld $25, 0($sp) # function pointer
29 ld $4, 8($sp) # argument pointer
30 jalr $25 # call the user's function
31 nop
32 move $4, $2
33 li $2, 5058
34 syscall
libc/musl/src/thread/mips64/syscall_cp.s created+52
......@@ -0,0 +1,52 @@
1.set noreorder
2.global __cp_begin
3.hidden __cp_begin
4.type __cp_begin,@function
5.global __cp_end
6.hidden __cp_end
7.type __cp_end,@function
8.global __cp_cancel
9.hidden __cp_cancel
10.type __cp_cancel,@function
11.global __cp_cancel_data
12.hidden __cp_cancel_data
13.type __cp_cancel_data,@function
14.hidden __cancel
15.global __syscall_cp_asm
16.hidden __syscall_cp_asm
17.type __syscall_cp_asm,@function
18__syscall_cp_asm:
19__cp_begin:
20 lw $4, 0($4)
21 bne $4, $0, __cp_cancel
22 move $2, $5
23 move $4, $6
24 move $5, $7
25 move $6, $8
26 move $7, $9
27 move $8, $10
28 move $9, $11
29 ld $10, 0($sp)
30 syscall
31__cp_end:
32 beq $7, $0, 1f
33 nop
34 dsubu $2, $0, $2
351: jr $ra
36 nop
37
38 # if cancellation flag is 1 then call __cancel
39__cp_cancel:
40 move $2, $ra
41.align 8
42 bal 1f
43 nop
44__cp_cancel_data:
45 .gpdword __cp_cancel_data
46 .gpdword __cancel
471: ld $3, ($ra)
48 dsubu $3, $ra, $3
49 ld $25, 8($ra)
50 daddu $25, $25, $3
51 jr $25
52 move $ra, $2
libc/musl/src/thread/mipsn32/__unmapself.s created+9
......@@ -0,0 +1,9 @@
1.set noreorder
2.global __unmapself
3.type __unmapself,@function
4__unmapself:
5 li $2, 6011
6 syscall
7 li $4, 0
8 li $2, 6058
9 syscall
libc/musl/src/thread/mipsn32/clone.s created+34
......@@ -0,0 +1,34 @@
1.set noreorder
2.global __clone
3.hidden __clone
4.type __clone,@function
5__clone:
6 # Save function pointer and argument pointer on new thread stack
7 and $5, $5, -16 # aligning stack to double word
8 subu $5, $5, 16
9 sw $4, 0($5) # save function pointer
10 sw $7, 4($5) # save argument pointer
11
12 # Shuffle (fn,sp,fl,arg,ptid,tls,ctid) to (fl,sp,ptid,tls,ctid)
13 # sys_clone(u64 flags, u64 ustack_base, u64 parent_tidptr, u64 child_tidptr, u64 tls)
14 move $4, $6
15 move $6, $8
16 move $7, $9
17 move $8, $10
18 li $2, 6055
19 syscall
20 beq $7, $0, 1f
21 nop
22 jr $ra
23 subu $2, $0, $2
241: beq $2, $0, 1f
25 nop
26 jr $ra
27 nop
281: lw $25, 0($sp) # function pointer
29 lw $4, 4($sp) # argument pointer
30 jalr $25 # call the user's function
31 nop
32 move $4, $2
33 li $2, 6058
34 syscall
libc/musl/src/thread/mipsn32/syscall_cp.s created+51
......@@ -0,0 +1,51 @@
1.set noreorder
2.global __cp_begin
3.hidden __cp_begin
4.type __cp_begin,@function
5.global __cp_end
6.hidden __cp_end
7.type __cp_end,@function
8.global __cp_cancel
9.hidden __cp_cancel
10.type __cp_cancel,@function
11.global __cp_cancel_data
12.hidden __cp_cancel_data
13.type __cp_cancel_data,@function
14.hidden __cancel
15.global __syscall_cp_asm
16.hidden __syscall_cp_asm
17.type __syscall_cp_asm,@function
18__syscall_cp_asm:
19__cp_begin:
20 lw $4, 0($4)
21 bne $4, $0, __cp_cancel
22 move $2, $5
23 move $4, $6
24 move $5, $7
25 move $6, $8
26 move $7, $9
27 move $8, $10
28 move $9, $11
29 lw $10, 0($sp)
30 syscall
31__cp_end:
32 beq $7, $0, 1f
33 nop
34 subu $2, $0, $2
351: jr $ra
36 nop
37
38 # if cancellation flag is 1 then call __cancel
39__cp_cancel:
40 move $2, $ra
41 bal 1f
42 nop
43__cp_cancel_data:
44 .gpword __cp_cancel_data
45 .gpword __cancel
461: lw $3, 0($ra)
47 subu $3, $ra, $3
48 lw $25, 4($ra)
49 addu $25, $25, $3
50 jr $25
51 move $ra, $2
libc/musl/src/thread/mtx_destroy.c created+5
......@@ -0,0 +1,5 @@
1#include <threads.h>
2
3void mtx_destroy(mtx_t *mtx)
4{
5}
libc/musl/src/thread/mtx_init.c created+10
......@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2#include <threads.h>
3
4int mtx_init(mtx_t *m, int type)
5{
6 *m = (mtx_t){
7 ._m_type = ((type&mtx_recursive) ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL),
8 };
9 return thrd_success;
10}
libc/musl/src/thread/mtx_lock.c created+12
......@@ -0,0 +1,12 @@
1#include "pthread_impl.h"
2#include <threads.h>
3
4int mtx_lock(mtx_t *m)
5{
6 if (m->_m_type == PTHREAD_MUTEX_NORMAL && !a_cas(&m->_m_lock, 0, EBUSY))
7 return thrd_success;
8 /* Calling mtx_timedlock with a null pointer is an extension.
9 * It is convenient, here to avoid duplication of the logic
10 * for return values. */
11 return mtx_timedlock(m, 0);
12}
libc/musl/src/thread/mtx_timedlock.c created+13
......@@ -0,0 +1,13 @@
1#include <threads.h>
2#include <pthread.h>
3#include <errno.h>
4
5int mtx_timedlock(mtx_t *restrict m, const struct timespec *restrict ts)
6{
7 int ret = __pthread_mutex_timedlock((pthread_mutex_t *)m, ts);
8 switch (ret) {
9 default: return thrd_error;
10 case 0: return thrd_success;
11 case ETIMEDOUT: return thrd_timedout;
12 }
13}
libc/musl/src/thread/mtx_trylock.c created+15
......@@ -0,0 +1,15 @@
1#include "pthread_impl.h"
2#include <threads.h>
3
4int mtx_trylock(mtx_t *m)
5{
6 if (m->_m_type == PTHREAD_MUTEX_NORMAL)
7 return (a_cas(&m->_m_lock, 0, EBUSY) & EBUSY) ? thrd_busy : thrd_success;
8
9 int ret = __pthread_mutex_trylock((pthread_mutex_t *)m);
10 switch (ret) {
11 default: return thrd_error;
12 case 0: return thrd_success;
13 case EBUSY: return thrd_busy;
14 }
15}
libc/musl/src/thread/mtx_unlock.c created+10
......@@ -0,0 +1,10 @@
1#include <threads.h>
2#include <pthread.h>
3
4int mtx_unlock(mtx_t *mtx)
5{
6 /* The only cases where pthread_mutex_unlock can return an
7 * error are undefined behavior for C11 mtx_unlock, so we can
8 * assume it does not return an error and simply tail call. */
9 return __pthread_mutex_unlock((pthread_mutex_t *)mtx);
10}
libc/musl/src/thread/or1k/__set_thread_area.s created+7
......@@ -0,0 +1,7 @@
1.global __set_thread_area
2.hidden __set_thread_area
3.type __set_thread_area,@function
4__set_thread_area:
5 l.ori r10, r3, 0
6 l.jr r9
7 l.ori r11, r0, 0
libc/musl/src/thread/or1k/__unmapself.s created+8
......@@ -0,0 +1,8 @@
1.global __unmapself
2.type __unmapself,@function
3__unmapself:
4 l.ori r11, r0, 215 /* __NR_munmap */
5 l.sys 1
6 l.ori r3, r0, 0
7 l.ori r11, r0, 93 /* __NR_exit */
8 l.sys 1
libc/musl/src/thread/or1k/clone.s created+31
......@@ -0,0 +1,31 @@
1/* int clone(fn, stack, flags, arg, ptid, tls, ctid)
2 * r3 r4 r5 r6 sp+0 sp+4 sp+8
3 * sys_clone(flags, stack, ptid, ctid, tls)
4 */
5.global __clone
6.hidden __clone
7.type __clone,@function
8__clone:
9 l.addi r4, r4, -8
10 l.sw 0(r4), r3
11 l.sw 4(r4), r6
12 /* (fn, st, fl, ar, pt, tl, ct) => (fl, st, pt, ct, tl) */
13 l.ori r3, r5, 0
14 l.lwz r5, 0(r1)
15 l.lwz r6, 8(r1)
16 l.lwz r7, 4(r1)
17 l.ori r11, r0, 220 /* __NR_clone */
18 l.sys 1
19
20 l.sfeqi r11, 0
21 l.bf 1f
22 l.nop
23 l.jr r9
24 l.nop
25
261: l.lwz r11, 0(r1)
27 l.jalr r11
28 l.lwz r3, 4(r1)
29
30 l.ori r11, r0, 93 /* __NR_exit */
31 l.sys 1
libc/musl/src/thread/or1k/syscall_cp.s created+29
......@@ -0,0 +1,29 @@
1.global __cp_begin
2.hidden __cp_begin
3.global __cp_end
4.hidden __cp_end
5.global __cp_cancel
6.hidden __cp_cancel
7.hidden __cancel
8.global __syscall_cp_asm
9.hidden __syscall_cp_asm
10.type __syscall_cp_asm,@function
11__syscall_cp_asm:
12__cp_begin:
13 l.lwz r3, 0(r3)
14 l.sfeqi r3, 0
15 l.bnf __cp_cancel
16 l.ori r11, r4, 0
17 l.ori r3, r5, 0
18 l.ori r4, r6, 0
19 l.ori r5, r7, 0
20 l.ori r6, r8, 0
21 l.lwz r7, 0(r1)
22 l.lwz r8, 4(r1)
23 l.sys 1
24__cp_end:
25 l.jr r9
26 l.nop
27__cp_cancel:
28 l.j __cancel
29 l.nop
libc/musl/src/thread/powerpc/__set_thread_area.s created+12
......@@ -0,0 +1,12 @@
1.text
2.global __set_thread_area
3.hidden __set_thread_area
4.type __set_thread_area, %function
5__set_thread_area:
6 # mov pointer in reg3 into r2
7 mr 2, 3
8 # put 0 into return reg
9 li 3, 0
10 # return
11 blr
12
libc/musl/src/thread/powerpc/__unmapself.s created+9
......@@ -0,0 +1,9 @@
1 .text
2 .global __unmapself
3 .type __unmapself,%function
4__unmapself:
5 li 0, 91 # __NR_munmap
6 sc
7 li 0, 1 #__NR_exit
8 sc
9 blr
libc/musl/src/thread/powerpc/clone.s created+73
......@@ -0,0 +1,73 @@
1.text
2.global __clone
3.hidden __clone
4.type __clone, %function
5__clone:
6# int clone(fn, stack, flags, arg, ptid, tls, ctid)
7# a b c d e f g
8# 3 4 5 6 7 8 9
9# pseudo C code:
10# tid = syscall(SYS_clone,c,b,e,f,g);
11# if (!tid) syscall(SYS_exit, a(d));
12# return tid;
13
14# SYS_clone = 120
15# SYS_exit = 1
16
17# store non-volatile regs r30, r31 on stack in order to put our
18# start func and its arg there
19stwu 30, -16(1)
20stw 31, 4(1)
21
22# save r3 (func) into r30, and r6(arg) into r31
23mr 30, 3
24mr 31, 6
25
26# create initial stack frame for new thread
27clrrwi 4, 4, 4
28li 0, 0
29stwu 0, -16(4)
30
31#move c into first arg
32mr 3, 5
33#mr 4, 4
34mr 5, 7
35mr 6, 8
36mr 7, 9
37
38# move syscall number into r0
39li 0, 120
40
41sc
42
43# check for syscall error
44bns+ 1f # jump to label 1 if no summary overflow.
45#else
46neg 3, 3 #negate the result (errno)
471:
48# compare sc result with 0
49cmpwi cr7, 3, 0
50
51# if not 0, jump to end
52bne cr7, 2f
53
54#else: we're the child
55#call funcptr: move arg (d) into r3
56mr 3, 31
57#move r30 (funcptr) into CTR reg
58mtctr 30
59# call CTR reg
60bctrl
61# mov SYS_exit into r0 (the exit param is already in r3)
62li 0, 1
63sc
64
652:
66
67# restore stack
68lwz 30, 0(1)
69lwz 31, 4(1)
70addi 1, 1, 16
71
72blr
73
libc/musl/src/thread/powerpc/syscall_cp.s created+59
......@@ -0,0 +1,59 @@
1.global __cp_begin
2.hidden __cp_begin
3.global __cp_end
4.hidden __cp_end
5.global __cp_cancel
6.hidden __cp_cancel
7.hidden __cancel
8.global __syscall_cp_asm
9.hidden __syscall_cp_asm
10
11#r0: volatile. may be modified during linkage.
12#r1: stack frame: 16 byte alignment.
13#r2: tls/thread pointer on pp32
14#r3,r4: return values, first args
15#r5-r10: args
16#r11-r12: volatile. may be modified during linkage
17#r13: "small data area" pointer
18#r14 - r30: local vars
19#r31: local or environment pointer
20
21#r1, r14-31: belong to the caller, must be saved and restored
22#r0, r3-r12, ctr, xer: volatile, not preserved
23#r0,r11,r12: may be altered by cross-module call,
24#"a func cannot depend on that these regs have the values placed by the caller"
25
26#the fields CR2,CR2,CR4 of the cond reg must be preserved
27#LR (link reg) shall contain the funcs return address
28 .text
29 .type __syscall_cp_asm,%function
30__syscall_cp_asm:
31 # at enter: r3 = pointer to self->cancel, r4: syscall no, r5: first arg, r6: 2nd, r7: 3rd, r8: 4th, r9: 5th, r10: 6th
32__cp_begin:
33 # r3 holds first argument, its a pointer to self->cancel.
34 # we must compare the dereferenced value with 0 and jump to __cancel if its not
35
36 lwz 0, 0(3) #deref pointer into r0
37
38 cmpwi cr7, 0, 0 #compare r0 with 0, store result in cr7.
39 beq+ cr7, 1f #jump to label 1 if r0 was 0
40
41 b __cp_cancel #else call cancel
421:
43 #ok, the cancel flag was not set
44 # syscall: number goes to r0, the rest 3-8
45 mr 0, 4 # put the system call number into r0
46 mr 3, 5 # Shift the arguments: arg1
47 mr 4, 6 # arg2
48 mr 5, 7 # arg3
49 mr 6, 8 # arg4
50 mr 7, 9 # arg5
51 mr 8, 10 # arg6
52 sc
53__cp_end:
54 bnslr+ # return if no summary overflow.
55 #else negate result.
56 neg 3, 3
57 blr
58__cp_cancel:
59 b __cancel
libc/musl/src/thread/powerpc64/__set_thread_area.s created+9
......@@ -0,0 +1,9 @@
1.text
2.global __set_thread_area
3.hidden __set_thread_area
4.type __set_thread_area, %function
5__set_thread_area:
6 mr 13, 3
7 li 3, 0
8 blr
9
libc/musl/src/thread/powerpc64/__unmapself.s created+9
......@@ -0,0 +1,9 @@
1 .text
2 .global __unmapself
3 .type __unmapself,%function
4__unmapself:
5 li 0, 91 # __NR_munmap
6 sc
7 li 0, 1 #__NR_exit
8 sc
9 blr
libc/musl/src/thread/powerpc64/clone.s created+48
......@@ -0,0 +1,48 @@
1.text
2.global __clone
3.hidden __clone
4.type __clone, %function
5__clone:
6 # int clone(fn, stack, flags, arg, ptid, tls, ctid)
7 # a b c d e f g
8 # 3 4 5 6 7 8 9
9 # pseudo C code:
10 # tid = syscall(SYS_clone,c,b,e,f,g);
11 # if (!tid) syscall(SYS_exit, a(d));
12 # return tid;
13
14 # create initial stack frame for new thread
15 clrrdi 4, 4, 4
16 li 0, 0
17 stdu 0,-32(4)
18
19 # save fn and arg to child stack
20 std 3, 8(4)
21 std 6, 16(4)
22
23 # shuffle args into correct registers and call SYS_clone
24 mr 3, 5
25 #mr 4, 4
26 mr 5, 7
27 mr 6, 8
28 mr 7, 9
29 li 0, 120 # SYS_clone = 120
30 sc
31
32 # if error, negate return (errno)
33 bns+ 1f
34 neg 3, 3
35
361: # if we're the parent, return
37 cmpwi cr7, 3, 0
38 bnelr cr7
39
40 # we're the child. call fn(arg)
41 ld 3, 16(1)
42 ld 12, 8(1)
43 mtctr 12
44 bctrl
45
46 # call SYS_exit. exit code is already in r3 from fn return value
47 li 0, 1 # SYS_exit = 1
48 sc
libc/musl/src/thread/powerpc64/syscall_cp.s created+44
......@@ -0,0 +1,44 @@
1 .global __cp_begin
2 .hidden __cp_begin
3 .global __cp_end
4 .hidden __cp_end
5 .global __cp_cancel
6 .hidden __cp_cancel
7 .hidden __cancel
8 .global __syscall_cp_asm
9 .hidden __syscall_cp_asm
10 .text
11 .type __syscall_cp_asm,%function
12__syscall_cp_asm:
13 # at enter: r3 = pointer to self->cancel, r4: syscall no, r5: first arg, r6: 2nd, r7: 3rd, r8: 4th, r9: 5th, r10: 6th
14__cp_begin:
15 # if (self->cancel) goto __cp_cancel
16 lwz 0, 0(3)
17 cmpwi cr7, 0, 0
18 bne- cr7, __cp_cancel
19
20 # make syscall
21 mr 0, 4
22 mr 3, 5
23 mr 4, 6
24 mr 5, 7
25 mr 6, 8
26 mr 7, 9
27 mr 8, 10
28 sc
29
30__cp_end:
31 # return error ? -r3 : r3
32 bnslr+
33 neg 3, 3
34 blr
35
36__cp_cancel:
37 mflr 0
38 bl 1f
39 .long .TOC.-.
401: mflr 3
41 lwa 2, 0(3)
42 add 2, 2, 3
43 mtlr 0
44 b __cancel
libc/musl/src/thread/pthread_atfork.c created+49
......@@ -0,0 +1,49 @@
1#include <pthread.h>
2#include "libc.h"
3#include "lock.h"
4
5static struct atfork_funcs {
6 void (*prepare)(void);
7 void (*parent)(void);
8 void (*child)(void);
9 struct atfork_funcs *prev, *next;
10} *funcs;
11
12static volatile int lock[1];
13
14void __fork_handler(int who)
15{
16 struct atfork_funcs *p;
17 if (!funcs) return;
18 if (who < 0) {
19 LOCK(lock);
20 for (p=funcs; p; p = p->next) {
21 if (p->prepare) p->prepare();
22 funcs = p;
23 }
24 } else {
25 for (p=funcs; p; p = p->prev) {
26 if (!who && p->parent) p->parent();
27 else if (who && p->child) p->child();
28 funcs = p;
29 }
30 UNLOCK(lock);
31 }
32}
33
34int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
35{
36 struct atfork_funcs *new = malloc(sizeof *new);
37 if (!new) return -1;
38
39 LOCK(lock);
40 new->next = funcs;
41 new->prev = 0;
42 new->prepare = prepare;
43 new->parent = parent;
44 new->child = child;
45 if (funcs) funcs->prev = new;
46 funcs = new;
47 UNLOCK(lock);
48 return 0;
49}
libc/musl/src/thread/pthread_attr_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_attr_destroy(pthread_attr_t *a)
4{
5 return 0;
6}
libc/musl/src/thread/pthread_attr_get.c created+98
......@@ -0,0 +1,98 @@
1#include "pthread_impl.h"
2
3int pthread_attr_getdetachstate(const pthread_attr_t *a, int *state)
4{
5 *state = a->_a_detach;
6 return 0;
7}
8int pthread_attr_getguardsize(const pthread_attr_t *restrict a, size_t *restrict size)
9{
10 *size = a->_a_guardsize;
11 return 0;
12}
13
14int pthread_attr_getinheritsched(const pthread_attr_t *restrict a, int *restrict inherit)
15{
16 *inherit = a->_a_sched;
17 return 0;
18}
19
20int pthread_attr_getschedparam(const pthread_attr_t *restrict a, struct sched_param *restrict param)
21{
22 param->sched_priority = a->_a_prio;
23 return 0;
24}
25
26int pthread_attr_getschedpolicy(const pthread_attr_t *restrict a, int *restrict policy)
27{
28 *policy = a->_a_policy;
29 return 0;
30}
31
32int pthread_attr_getscope(const pthread_attr_t *restrict a, int *restrict scope)
33{
34 *scope = PTHREAD_SCOPE_SYSTEM;
35 return 0;
36}
37
38int pthread_attr_getstack(const pthread_attr_t *restrict a, void **restrict addr, size_t *restrict size)
39{
40 if (!a->_a_stackaddr)
41 return EINVAL;
42 *size = a->_a_stacksize;
43 *addr = (void *)(a->_a_stackaddr - *size);
44 return 0;
45}
46
47int pthread_attr_getstacksize(const pthread_attr_t *restrict a, size_t *restrict size)
48{
49 *size = a->_a_stacksize;
50 return 0;
51}
52
53int pthread_barrierattr_getpshared(const pthread_barrierattr_t *restrict a, int *restrict pshared)
54{
55 *pshared = !!a->__attr;
56 return 0;
57}
58
59int pthread_condattr_getclock(const pthread_condattr_t *restrict a, clockid_t *restrict clk)
60{
61 *clk = a->__attr & 0x7fffffff;
62 return 0;
63}
64
65int pthread_condattr_getpshared(const pthread_condattr_t *restrict a, int *restrict pshared)
66{
67 *pshared = a->__attr>>31;
68 return 0;
69}
70
71int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict a, int *restrict protocol)
72{
73 *protocol = PTHREAD_PRIO_NONE;
74 return 0;
75}
76int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *restrict pshared)
77{
78 *pshared = a->__attr / 128U % 2;
79 return 0;
80}
81
82int pthread_mutexattr_getrobust(const pthread_mutexattr_t *restrict a, int *restrict robust)
83{
84 *robust = a->__attr / 4U % 2;
85 return 0;
86}
87
88int pthread_mutexattr_gettype(const pthread_mutexattr_t *restrict a, int *restrict type)
89{
90 *type = a->__attr & 3;
91 return 0;
92}
93
94int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *restrict a, int *restrict pshared)
95{
96 *pshared = a->__attr[0];
97 return 0;
98}
libc/musl/src/thread/pthread_attr_init.c created+11
......@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2
3int pthread_attr_init(pthread_attr_t *a)
4{
5 *a = (pthread_attr_t){0};
6 __acquire_ptc();
7 a->_a_stacksize = __default_stacksize;
8 a->_a_guardsize = __default_guardsize;
9 __release_ptc();
10 return 0;
11}
libc/musl/src/thread/pthread_attr_setdetachstate.c created+8
......@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_attr_setdetachstate(pthread_attr_t *a, int state)
4{
5 if (state > 1U) return EINVAL;
6 a->_a_detach = state;
7 return 0;
8}
libc/musl/src/thread/pthread_attr_setguardsize.c created+8
......@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_attr_setguardsize(pthread_attr_t *a, size_t size)
4{
5 if (size > SIZE_MAX/8) return EINVAL;
6 a->_a_guardsize = size;
7 return 0;
8}
libc/musl/src/thread/pthread_attr_setinheritsched.c created+28
......@@ -0,0 +1,28 @@
1#include "pthread_impl.h"
2#include "syscall.h"
3
4hidden void *__start_sched(void *p)
5{
6 struct start_sched_args *ssa = p;
7 void *start_arg = ssa->start_arg;
8 void *(*start_fn)(void *) = ssa->start_fn;
9 pthread_t self = __pthread_self();
10
11 int ret = -__syscall(SYS_sched_setscheduler, self->tid,
12 ssa->attr->_a_policy, &ssa->attr->_a_prio);
13 if (!ret) __restore_sigs(&ssa->mask);
14 a_store(&ssa->futex, ret);
15 __wake(&ssa->futex, 1, 1);
16 if (ret) {
17 self->detach_state = DT_DYNAMIC;
18 return 0;
19 }
20 return start_fn(start_arg);
21}
22
23int pthread_attr_setinheritsched(pthread_attr_t *a, int inherit)
24{
25 if (inherit > 1U) return EINVAL;
26 a->_a_sched = inherit;
27 return 0;
28}
libc/musl/src/thread/pthread_attr_setschedparam.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_attr_setschedparam(pthread_attr_t *restrict a, const struct sched_param *restrict param)
4{
5 a->_a_prio = param->sched_priority;
6 return 0;
7}
libc/musl/src/thread/pthread_attr_setschedpolicy.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_attr_setschedpolicy(pthread_attr_t *a, int policy)
4{
5 a->_a_policy = policy;
6 return 0;
7}
libc/musl/src/thread/pthread_attr_setscope.c created+13
......@@ -0,0 +1,13 @@
1#include "pthread_impl.h"
2
3int pthread_attr_setscope(pthread_attr_t *a, int scope)
4{
5 switch (scope) {
6 case PTHREAD_SCOPE_SYSTEM:
7 return 0;
8 case PTHREAD_SCOPE_PROCESS:
9 return ENOTSUP;
10 default:
11 return EINVAL;
12 }
13}
libc/musl/src/thread/pthread_attr_setstack.c created+9
......@@ -0,0 +1,9 @@
1#include "pthread_impl.h"
2
3int pthread_attr_setstack(pthread_attr_t *a, void *addr, size_t size)
4{
5 if (size-PTHREAD_STACK_MIN > SIZE_MAX/4) return EINVAL;
6 a->_a_stackaddr = (size_t)addr + size;
7 a->_a_stacksize = size;
8 return 0;
9}
libc/musl/src/thread/pthread_attr_setstacksize.c created+9
......@@ -0,0 +1,9 @@
1#include "pthread_impl.h"
2
3int pthread_attr_setstacksize(pthread_attr_t *a, size_t size)
4{
5 if (size-PTHREAD_STACK_MIN > SIZE_MAX/4) return EINVAL;
6 a->_a_stackaddr = 0;
7 a->_a_stacksize = size;
8 return 0;
9}
libc/musl/src/thread/pthread_barrier_destroy.c created+15
......@@ -0,0 +1,15 @@
1#include "pthread_impl.h"
2
3int pthread_barrier_destroy(pthread_barrier_t *b)
4{
5 if (b->_b_limit < 0) {
6 if (b->_b_lock) {
7 int v;
8 a_or(&b->_b_lock, INT_MIN);
9 while ((v = b->_b_lock) & INT_MAX)
10 __wait(&b->_b_lock, 0, v, 0);
11 }
12 __vm_wait();
13 }
14 return 0;
15}
libc/musl/src/thread/pthread_barrier_init.c created+8
......@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_barrier_init(pthread_barrier_t *restrict b, const pthread_barrierattr_t *restrict a, unsigned count)
4{
5 if (count-1 > INT_MAX-1) return EINVAL;
6 *b = (pthread_barrier_t){ ._b_limit = count-1 | (a?a->__attr:0) };
7 return 0;
8}
libc/musl/src/thread/pthread_barrier_wait.c created+111
......@@ -0,0 +1,111 @@
1#include "pthread_impl.h"
2
3static int pshared_barrier_wait(pthread_barrier_t *b)
4{
5 int limit = (b->_b_limit & INT_MAX) + 1;
6 int ret = 0;
7 int v, w;
8
9 if (limit==1) return PTHREAD_BARRIER_SERIAL_THREAD;
10
11 while ((v=a_cas(&b->_b_lock, 0, limit)))
12 __wait(&b->_b_lock, &b->_b_waiters, v, 0);
13
14 /* Wait for <limit> threads to get to the barrier */
15 if (++b->_b_count == limit) {
16 a_store(&b->_b_count, 0);
17 ret = PTHREAD_BARRIER_SERIAL_THREAD;
18 if (b->_b_waiters2) __wake(&b->_b_count, -1, 0);
19 } else {
20 a_store(&b->_b_lock, 0);
21 if (b->_b_waiters) __wake(&b->_b_lock, 1, 0);
22 while ((v=b->_b_count)>0)
23 __wait(&b->_b_count, &b->_b_waiters2, v, 0);
24 }
25
26 __vm_lock();
27
28 /* Ensure all threads have a vm lock before proceeding */
29 if (a_fetch_add(&b->_b_count, -1)==1-limit) {
30 a_store(&b->_b_count, 0);
31 if (b->_b_waiters2) __wake(&b->_b_count, -1, 0);
32 } else {
33 while ((v=b->_b_count))
34 __wait(&b->_b_count, &b->_b_waiters2, v, 0);
35 }
36
37 /* Perform a recursive unlock suitable for self-sync'd destruction */
38 do {
39 v = b->_b_lock;
40 w = b->_b_waiters;
41 } while (a_cas(&b->_b_lock, v, v==INT_MIN+1 ? 0 : v-1) != v);
42
43 /* Wake a thread waiting to reuse or destroy the barrier */
44 if (v==INT_MIN+1 || (v==1 && w))
45 __wake(&b->_b_lock, 1, 0);
46
47 __vm_unlock();
48
49 return ret;
50}
51
52struct instance
53{
54 volatile int count;
55 volatile int last;
56 volatile int waiters;
57 volatile int finished;
58};
59
60int pthread_barrier_wait(pthread_barrier_t *b)
61{
62 int limit = b->_b_limit;
63 struct instance *inst;
64
65 /* Trivial case: count was set at 1 */
66 if (!limit) return PTHREAD_BARRIER_SERIAL_THREAD;
67
68 /* Process-shared barriers require a separate, inefficient wait */
69 if (limit < 0) return pshared_barrier_wait(b);
70
71 /* Otherwise we need a lock on the barrier object */
72 while (a_swap(&b->_b_lock, 1))
73 __wait(&b->_b_lock, &b->_b_waiters, 1, 1);
74 inst = b->_b_inst;
75
76 /* First thread to enter the barrier becomes the "instance owner" */
77 if (!inst) {
78 struct instance new_inst = { 0 };
79 int spins = 200;
80 b->_b_inst = inst = &new_inst;
81 a_store(&b->_b_lock, 0);
82 if (b->_b_waiters) __wake(&b->_b_lock, 1, 1);
83 while (spins-- && !inst->finished)
84 a_spin();
85 a_inc(&inst->finished);
86 while (inst->finished == 1)
87 __syscall(SYS_futex,&inst->finished,FUTEX_WAIT|FUTEX_PRIVATE,1,0) != -ENOSYS
88 || __syscall(SYS_futex,&inst->finished,FUTEX_WAIT,1,0);
89 return PTHREAD_BARRIER_SERIAL_THREAD;
90 }
91
92 /* Last thread to enter the barrier wakes all non-instance-owners */
93 if (++inst->count == limit) {
94 b->_b_inst = 0;
95 a_store(&b->_b_lock, 0);
96 if (b->_b_waiters) __wake(&b->_b_lock, 1, 1);
97 a_store(&inst->last, 1);
98 if (inst->waiters)
99 __wake(&inst->last, -1, 1);
100 } else {
101 a_store(&b->_b_lock, 0);
102 if (b->_b_waiters) __wake(&b->_b_lock, 1, 1);
103 __wait(&inst->last, &inst->waiters, 0, 1);
104 }
105
106 /* Last thread to exit the barrier wakes the instance owner */
107 if (a_fetch_add(&inst->count,-1)==1 && a_fetch_add(&inst->finished,1))
108 __wake(&inst->finished, 1, 1);
109
110 return 0;
111}
libc/musl/src/thread/pthread_barrierattr_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_barrierattr_destroy(pthread_barrierattr_t *a)
4{
5 return 0;
6}
libc/musl/src/thread/pthread_barrierattr_init.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_barrierattr_init(pthread_barrierattr_t *a)
4{
5 *a = (pthread_barrierattr_t){0};
6 return 0;
7}
libc/musl/src/thread/pthread_barrierattr_setpshared.c created+8
......@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_barrierattr_setpshared(pthread_barrierattr_t *a, int pshared)
4{
5 if (pshared > 1U) return EINVAL;
6 a->__attr = pshared ? INT_MIN : 0;
7 return 0;
8}
libc/musl/src/thread/pthread_cancel.c created+101
......@@ -0,0 +1,101 @@
1#define _GNU_SOURCE
2#include <string.h>
3#include "pthread_impl.h"
4#include "syscall.h"
5
6hidden long __cancel(), __syscall_cp_asm(), __syscall_cp_c();
7
8long __cancel()
9{
10 pthread_t self = __pthread_self();
11 if (self->canceldisable == PTHREAD_CANCEL_ENABLE || self->cancelasync)
12 pthread_exit(PTHREAD_CANCELED);
13 self->canceldisable = PTHREAD_CANCEL_DISABLE;
14 return -ECANCELED;
15}
16
17long __syscall_cp_asm(volatile void *, syscall_arg_t,
18 syscall_arg_t, syscall_arg_t, syscall_arg_t,
19 syscall_arg_t, syscall_arg_t, syscall_arg_t);
20
21long __syscall_cp_c(syscall_arg_t nr,
22 syscall_arg_t u, syscall_arg_t v, syscall_arg_t w,
23 syscall_arg_t x, syscall_arg_t y, syscall_arg_t z)
24{
25 pthread_t self;
26 long r;
27 int st;
28
29 if ((st=(self=__pthread_self())->canceldisable)
30 && (st==PTHREAD_CANCEL_DISABLE || nr==SYS_close))
31 return __syscall(nr, u, v, w, x, y, z);
32
33 r = __syscall_cp_asm(&self->cancel, nr, u, v, w, x, y, z);
34 if (r==-EINTR && nr!=SYS_close && self->cancel &&
35 self->canceldisable != PTHREAD_CANCEL_DISABLE)
36 r = __cancel();
37 return r;
38}
39
40static void _sigaddset(sigset_t *set, int sig)
41{
42 unsigned s = sig-1;
43 set->__bits[s/8/sizeof *set->__bits] |= 1UL<<(s&8*sizeof *set->__bits-1);
44}
45
46extern hidden const char __cp_begin[1], __cp_end[1], __cp_cancel[1];
47
48static void cancel_handler(int sig, siginfo_t *si, void *ctx)
49{
50 pthread_t self = __pthread_self();
51 ucontext_t *uc = ctx;
52 uintptr_t pc = uc->uc_mcontext.MC_PC;
53
54 a_barrier();
55 if (!self->cancel || self->canceldisable == PTHREAD_CANCEL_DISABLE) return;
56
57 _sigaddset(&uc->uc_sigmask, SIGCANCEL);
58
59 if (self->cancelasync || pc >= (uintptr_t)__cp_begin && pc < (uintptr_t)__cp_end) {
60 uc->uc_mcontext.MC_PC = (uintptr_t)__cp_cancel;
61#ifdef CANCEL_GOT
62 uc->uc_mcontext.MC_GOT = CANCEL_GOT;
63#endif
64 return;
65 }
66
67 __syscall(SYS_tkill, self->tid, SIGCANCEL);
68}
69
70void __testcancel()
71{
72 pthread_t self = __pthread_self();
73 if (self->cancel && !self->canceldisable)
74 __cancel();
75}
76
77static void init_cancellation()
78{
79 struct sigaction sa = {
80 .sa_flags = SA_SIGINFO | SA_RESTART,
81 .sa_sigaction = cancel_handler
82 };
83 memset(&sa.sa_mask, -1, _NSIG/8);
84 __libc_sigaction(SIGCANCEL, &sa, 0);
85}
86
87int pthread_cancel(pthread_t t)
88{
89 static int init;
90 if (!init) {
91 init_cancellation();
92 init = 1;
93 }
94 a_store(&t->cancel, 1);
95 if (t == pthread_self()) {
96 if (t->canceldisable == PTHREAD_CANCEL_ENABLE && t->cancelasync)
97 pthread_exit(PTHREAD_CANCELED);
98 return 0;
99 }
100 return pthread_kill(t, SIGCANCEL);
101}
libc/musl/src/thread/pthread_cleanup_push.c created+20
......@@ -0,0 +1,20 @@
1#include "pthread_impl.h"
2
3static void dummy(struct __ptcb *cb)
4{
5}
6weak_alias(dummy, __do_cleanup_push);
7weak_alias(dummy, __do_cleanup_pop);
8
9void _pthread_cleanup_push(struct __ptcb *cb, void (*f)(void *), void *x)
10{
11 cb->__f = f;
12 cb->__x = x;
13 __do_cleanup_push(cb);
14}
15
16void _pthread_cleanup_pop(struct __ptcb *cb, int run)
17{
18 __do_cleanup_pop(cb);
19 if (run) cb->__f(cb->__x);
20}
libc/musl/src/thread/pthread_cond_broadcast.c created+10
......@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2
3int pthread_cond_broadcast(pthread_cond_t *c)
4{
5 if (!c->_c_shared) return __private_cond_signal(c, -1);
6 if (!c->_c_waiters) return 0;
7 a_inc(&c->_c_seq);
8 __wake(&c->_c_seq, -1, 0);
9 return 0;
10}
libc/musl/src/thread/pthread_cond_destroy.c created+14
......@@ -0,0 +1,14 @@
1#include "pthread_impl.h"
2
3int pthread_cond_destroy(pthread_cond_t *c)
4{
5 if (c->_c_shared && c->_c_waiters) {
6 int cnt;
7 a_or(&c->_c_waiters, 0x80000000);
8 a_inc(&c->_c_seq);
9 __wake(&c->_c_seq, -1, 0);
10 while ((cnt = c->_c_waiters) & 0x7fffffff)
11 __wait(&c->_c_waiters, 0, cnt, 0);
12 }
13 return 0;
14}
libc/musl/src/thread/pthread_cond_init.c created+11
......@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2
3int pthread_cond_init(pthread_cond_t *restrict c, const pthread_condattr_t *restrict a)
4{
5 *c = (pthread_cond_t){0};
6 if (a) {
7 c->_c_clock = a->__attr & 0x7fffffff;
8 if (a->__attr>>31) c->_c_shared = (void *)-1;
9 }
10 return 0;
11}
libc/musl/src/thread/pthread_cond_signal.c created+10
......@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2
3int pthread_cond_signal(pthread_cond_t *c)
4{
5 if (!c->_c_shared) return __private_cond_signal(c, 1);
6 if (!c->_c_waiters) return 0;
7 a_inc(&c->_c_seq);
8 __wake(&c->_c_seq, 1, 0);
9 return 0;
10}
libc/musl/src/thread/pthread_cond_timedwait.c created+209
......@@ -0,0 +1,209 @@
1#include "pthread_impl.h"
2
3/*
4 * struct waiter
5 *
6 * Waiter objects have automatic storage on the waiting thread, and
7 * are used in building a linked list representing waiters currently
8 * waiting on the condition variable or a group of waiters woken
9 * together by a broadcast or signal; in the case of signal, this is a
10 * degenerate list of one member.
11 *
12 * Waiter lists attached to the condition variable itself are
13 * protected by the lock on the cv. Detached waiter lists are never
14 * modified again, but can only be traversed in reverse order, and are
15 * protected by the "barrier" locks in each node, which are unlocked
16 * in turn to control wake order.
17 *
18 * Since process-shared cond var semantics do not necessarily allow
19 * one thread to see another's automatic storage (they may be in
20 * different processes), the waiter list is not used for the
21 * process-shared case, but the structure is still used to store data
22 * needed by the cancellation cleanup handler.
23 */
24
25struct waiter {
26 struct waiter *prev, *next;
27 volatile int state, barrier;
28 volatile int *notify;
29};
30
31/* Self-synchronized-destruction-safe lock functions */
32
33static inline void lock(volatile int *l)
34{
35 if (a_cas(l, 0, 1)) {
36 a_cas(l, 1, 2);
37 do __wait(l, 0, 2, 1);
38 while (a_cas(l, 0, 2));
39 }
40}
41
42static inline void unlock(volatile int *l)
43{
44 if (a_swap(l, 0)==2)
45 __wake(l, 1, 1);
46}
47
48static inline void unlock_requeue(volatile int *l, volatile int *r, int w)
49{
50 a_store(l, 0);
51 if (w) __wake(l, 1, 1);
52 else __syscall(SYS_futex, l, FUTEX_REQUEUE|FUTEX_PRIVATE, 0, 1, r) != -ENOSYS
53 || __syscall(SYS_futex, l, FUTEX_REQUEUE, 0, 1, r);
54}
55
56enum {
57 WAITING,
58 SIGNALED,
59 LEAVING,
60};
61
62int __pthread_cond_timedwait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m, const struct timespec *restrict ts)
63{
64 struct waiter node = { 0 };
65 int e, seq, clock = c->_c_clock, cs, shared=0, oldstate, tmp;
66 volatile int *fut;
67
68 if ((m->_m_type&15) && (m->_m_lock&INT_MAX) != __pthread_self()->tid)
69 return EPERM;
70
71 if (ts && ts->tv_nsec >= 1000000000UL)
72 return EINVAL;
73
74 __pthread_testcancel();
75
76 if (c->_c_shared) {
77 shared = 1;
78 fut = &c->_c_seq;
79 seq = c->_c_seq;
80 a_inc(&c->_c_waiters);
81 } else {
82 lock(&c->_c_lock);
83
84 seq = node.barrier = 2;
85 fut = &node.barrier;
86 node.state = WAITING;
87 node.next = c->_c_head;
88 c->_c_head = &node;
89 if (!c->_c_tail) c->_c_tail = &node;
90 else node.next->prev = &node;
91
92 unlock(&c->_c_lock);
93 }
94
95 __pthread_mutex_unlock(m);
96
97 __pthread_setcancelstate(PTHREAD_CANCEL_MASKED, &cs);
98 if (cs == PTHREAD_CANCEL_DISABLE) __pthread_setcancelstate(cs, 0);
99
100 do e = __timedwait_cp(fut, seq, clock, ts, !shared);
101 while (*fut==seq && (!e || e==EINTR));
102 if (e == EINTR) e = 0;
103
104 if (shared) {
105 /* Suppress cancellation if a signal was potentially
106 * consumed; this is a legitimate form of spurious
107 * wake even if not. */
108 if (e == ECANCELED && c->_c_seq != seq) e = 0;
109 if (a_fetch_add(&c->_c_waiters, -1) == -0x7fffffff)
110 __wake(&c->_c_waiters, 1, 0);
111 oldstate = WAITING;
112 goto relock;
113 }
114
115 oldstate = a_cas(&node.state, WAITING, LEAVING);
116
117 if (oldstate == WAITING) {
118 /* Access to cv object is valid because this waiter was not
119 * yet signaled and a new signal/broadcast cannot return
120 * after seeing a LEAVING waiter without getting notified
121 * via the futex notify below. */
122
123 lock(&c->_c_lock);
124
125 if (c->_c_head == &node) c->_c_head = node.next;
126 else if (node.prev) node.prev->next = node.next;
127 if (c->_c_tail == &node) c->_c_tail = node.prev;
128 else if (node.next) node.next->prev = node.prev;
129
130 unlock(&c->_c_lock);
131
132 if (node.notify) {
133 if (a_fetch_add(node.notify, -1)==1)
134 __wake(node.notify, 1, 1);
135 }
136 } else {
137 /* Lock barrier first to control wake order. */
138 lock(&node.barrier);
139 }
140
141relock:
142 /* Errors locking the mutex override any existing error or
143 * cancellation, since the caller must see them to know the
144 * state of the mutex. */
145 if ((tmp = pthread_mutex_lock(m))) e = tmp;
146
147 if (oldstate == WAITING) goto done;
148
149 if (!node.next) a_inc(&m->_m_waiters);
150
151 /* Unlock the barrier that's holding back the next waiter, and
152 * either wake it or requeue it to the mutex. */
153 if (node.prev)
154 unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & 128);
155 else
156 a_dec(&m->_m_waiters);
157
158 /* Since a signal was consumed, cancellation is not permitted. */
159 if (e == ECANCELED) e = 0;
160
161done:
162 __pthread_setcancelstate(cs, 0);
163
164 if (e == ECANCELED) {
165 __pthread_testcancel();
166 __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
167 }
168
169 return e;
170}
171
172int __private_cond_signal(pthread_cond_t *c, int n)
173{
174 struct waiter *p, *first=0;
175 volatile int ref = 0;
176 int cur;
177
178 lock(&c->_c_lock);
179 for (p=c->_c_tail; n && p; p=p->prev) {
180 if (a_cas(&p->state, WAITING, SIGNALED) != WAITING) {
181 ref++;
182 p->notify = &ref;
183 } else {
184 n--;
185 if (!first) first=p;
186 }
187 }
188 /* Split the list, leaving any remainder on the cv. */
189 if (p) {
190 if (p->next) p->next->prev = 0;
191 p->next = 0;
192 } else {
193 c->_c_head = 0;
194 }
195 c->_c_tail = p;
196 unlock(&c->_c_lock);
197
198 /* Wait for any waiters in the LEAVING state to remove
199 * themselves from the list before returning or allowing
200 * signaled threads to proceed. */
201 while ((cur = ref)) __wait(&ref, 0, cur, 1);
202
203 /* Allow first signaled waiter, if any, to proceed. */
204 if (first) unlock(&first->barrier);
205
206 return 0;
207}
208
209weak_alias(__pthread_cond_timedwait, pthread_cond_timedwait);
libc/musl/src/thread/pthread_cond_wait.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_cond_wait(pthread_cond_t *restrict c, pthread_mutex_t *restrict m)
4{
5 return pthread_cond_timedwait(c, m, 0);
6}
libc/musl/src/thread/pthread_condattr_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_condattr_destroy(pthread_condattr_t *a)
4{
5 return 0;
6}
libc/musl/src/thread/pthread_condattr_init.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_condattr_init(pthread_condattr_t *a)
4{
5 *a = (pthread_condattr_t){0};
6 return 0;
7}
libc/musl/src/thread/pthread_condattr_setclock.c created+9
......@@ -0,0 +1,9 @@
1#include "pthread_impl.h"
2
3int pthread_condattr_setclock(pthread_condattr_t *a, clockid_t clk)
4{
5 if (clk < 0 || clk-2U < 2) return EINVAL;
6 a->__attr &= 0x80000000;
7 a->__attr |= clk;
8 return 0;
9}
libc/musl/src/thread/pthread_condattr_setpshared.c created+9
......@@ -0,0 +1,9 @@
1#include "pthread_impl.h"
2
3int pthread_condattr_setpshared(pthread_condattr_t *a, int pshared)
4{
5 if (pshared > 1U) return EINVAL;
6 a->__attr &= 0x7fffffff;
7 a->__attr |= (unsigned)pshared<<31;
8 return 0;
9}
libc/musl/src/thread/pthread_create.c created+314
......@@ -0,0 +1,314 @@
1#define _GNU_SOURCE
2#include "pthread_impl.h"
3#include "stdio_impl.h"
4#include "libc.h"
5#include "lock.h"
6#include <sys/mman.h>
7#include <string.h>
8#include <stddef.h>
9
10static void dummy_0()
11{
12}
13weak_alias(dummy_0, __acquire_ptc);
14weak_alias(dummy_0, __release_ptc);
15weak_alias(dummy_0, __pthread_tsd_run_dtors);
16weak_alias(dummy_0, __do_orphaned_stdio_locks);
17weak_alias(dummy_0, __dl_thread_cleanup);
18
19static void *dummy_1(void *p)
20{
21 return 0;
22}
23weak_alias(dummy_1, __start_sched);
24
25_Noreturn void __pthread_exit(void *result)
26{
27 pthread_t self = __pthread_self();
28 sigset_t set;
29
30 self->canceldisable = 1;
31 self->cancelasync = 0;
32 self->result = result;
33
34 while (self->cancelbuf) {
35 void (*f)(void *) = self->cancelbuf->__f;
36 void *x = self->cancelbuf->__x;
37 self->cancelbuf = self->cancelbuf->__next;
38 f(x);
39 }
40
41 __pthread_tsd_run_dtors();
42
43 /* Access to target the exiting thread with syscalls that use
44 * its kernel tid is controlled by killlock. For detached threads,
45 * any use past this point would have undefined behavior, but for
46 * joinable threads it's a valid usage that must be handled. */
47 LOCK(self->killlock);
48
49 /* Block all signals before decrementing the live thread count.
50 * This is important to ensure that dynamically allocated TLS
51 * is not under-allocated/over-committed, and possibly for other
52 * reasons as well. */
53 __block_all_sigs(&set);
54
55 /* It's impossible to determine whether this is "the last thread"
56 * until performing the atomic decrement, since multiple threads
57 * could exit at the same time. For the last thread, revert the
58 * decrement, restore the tid, and unblock signals to give the
59 * atexit handlers and stdio cleanup code a consistent state. */
60 if (a_fetch_add(&libc.threads_minus_1, -1)==0) {
61 libc.threads_minus_1 = 0;
62 UNLOCK(self->killlock);
63 __restore_sigs(&set);
64 exit(0);
65 }
66
67 /* Process robust list in userspace to handle non-pshared mutexes
68 * and the detached thread case where the robust list head will
69 * be invalid when the kernel would process it. */
70 __vm_lock();
71 volatile void *volatile *rp;
72 while ((rp=self->robust_list.head) && rp != &self->robust_list.head) {
73 pthread_mutex_t *m = (void *)((char *)rp
74 - offsetof(pthread_mutex_t, _m_next));
75 int waiters = m->_m_waiters;
76 int priv = (m->_m_type & 128) ^ 128;
77 self->robust_list.pending = rp;
78 self->robust_list.head = *rp;
79 int cont = a_swap(&m->_m_lock, 0x40000000);
80 self->robust_list.pending = 0;
81 if (cont < 0 || waiters)
82 __wake(&m->_m_lock, 1, priv);
83 }
84 __vm_unlock();
85
86 __do_orphaned_stdio_locks();
87 __dl_thread_cleanup();
88
89 /* This atomic potentially competes with a concurrent pthread_detach
90 * call; the loser is responsible for freeing thread resources. */
91 int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING);
92
93 if (state>=DT_DETACHED && self->map_base) {
94 /* Detached threads must avoid the kernel clear_child_tid
95 * feature, since the virtual address will have been
96 * unmapped and possibly already reused by a new mapping
97 * at the time the kernel would perform the write. In
98 * the case of threads that started out detached, the
99 * initial clone flags are correct, but if the thread was
100 * detached later, we need to clear it here. */
101 if (state == DT_DYNAMIC) __syscall(SYS_set_tid_address, 0);
102
103 /* Robust list will no longer be valid, and was already
104 * processed above, so unregister it with the kernel. */
105 if (self->robust_list.off)
106 __syscall(SYS_set_robust_list, 0, 3*sizeof(long));
107
108 /* Since __unmapself bypasses the normal munmap code path,
109 * explicitly wait for vmlock holders first. */
110 __vm_wait();
111
112 /* The following call unmaps the thread's stack mapping
113 * and then exits without touching the stack. */
114 __unmapself(self->map_base, self->map_size);
115 }
116
117 /* After the kernel thread exits, its tid may be reused. Clear it
118 * to prevent inadvertent use and inform functions that would use
119 * it that it's no longer available. */
120 self->tid = 0;
121 UNLOCK(self->killlock);
122
123 for (;;) __syscall(SYS_exit, 0);
124}
125
126void __do_cleanup_push(struct __ptcb *cb)
127{
128 struct pthread *self = __pthread_self();
129 cb->__next = self->cancelbuf;
130 self->cancelbuf = cb;
131}
132
133void __do_cleanup_pop(struct __ptcb *cb)
134{
135 __pthread_self()->cancelbuf = cb->__next;
136}
137
138static int start(void *p)
139{
140 pthread_t self = p;
141 if (self->unblock_cancel)
142 __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
143 SIGPT_SET, 0, _NSIG/8);
144 __pthread_exit(self->start(self->start_arg));
145 return 0;
146}
147
148static int start_c11(void *p)
149{
150 pthread_t self = p;
151 int (*start)(void*) = (int(*)(void*)) self->start;
152 __pthread_exit((void *)(uintptr_t)start(self->start_arg));
153 return 0;
154}
155
156#define ROUND(x) (((x)+PAGE_SIZE-1)&-PAGE_SIZE)
157
158/* pthread_key_create.c overrides this */
159static volatile size_t dummy = 0;
160weak_alias(dummy, __pthread_tsd_size);
161static void *dummy_tsd[1] = { 0 };
162weak_alias(dummy_tsd, __pthread_tsd_main);
163
164volatile int __block_new_threads = 0;
165
166static FILE *volatile dummy_file = 0;
167weak_alias(dummy_file, __stdin_used);
168weak_alias(dummy_file, __stdout_used);
169weak_alias(dummy_file, __stderr_used);
170
171static void init_file_lock(FILE *f)
172{
173 if (f && f->lock<0) f->lock = 0;
174}
175
176int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attrp, void *(*entry)(void *), void *restrict arg)
177{
178 int ret, c11 = (attrp == __ATTRP_C11_THREAD);
179 size_t size, guard;
180 struct pthread *self, *new;
181 unsigned char *map = 0, *stack = 0, *tsd = 0, *stack_limit;
182 unsigned flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND
183 | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS
184 | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID | CLONE_DETACHED;
185 int do_sched = 0;
186 pthread_attr_t attr = { 0 };
187 struct start_sched_args ssa;
188
189 if (!libc.can_do_threads) return ENOSYS;
190 self = __pthread_self();
191 if (!libc.threaded) {
192 for (FILE *f=*__ofl_lock(); f; f=f->next)
193 init_file_lock(f);
194 __ofl_unlock();
195 init_file_lock(__stdin_used);
196 init_file_lock(__stdout_used);
197 init_file_lock(__stderr_used);
198 __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK, SIGPT_SET, 0, _NSIG/8);
199 self->tsd = (void **)__pthread_tsd_main;
200 libc.threaded = 1;
201 }
202 if (attrp && !c11) attr = *attrp;
203
204 __acquire_ptc();
205 if (!attrp || c11) {
206 attr._a_stacksize = __default_stacksize;
207 attr._a_guardsize = __default_guardsize;
208 }
209
210 if (__block_new_threads) __wait(&__block_new_threads, 0, 1, 1);
211
212 if (attr._a_stackaddr) {
213 size_t need = libc.tls_size + __pthread_tsd_size;
214 size = attr._a_stacksize;
215 stack = (void *)(attr._a_stackaddr & -16);
216 stack_limit = (void *)(attr._a_stackaddr - size);
217 /* Use application-provided stack for TLS only when
218 * it does not take more than ~12% or 2k of the
219 * application's stack space. */
220 if (need < size/8 && need < 2048) {
221 tsd = stack - __pthread_tsd_size;
222 stack = tsd - libc.tls_size;
223 memset(stack, 0, need);
224 } else {
225 size = ROUND(need);
226 }
227 guard = 0;
228 } else {
229 guard = ROUND(attr._a_guardsize);
230 size = guard + ROUND(attr._a_stacksize
231 + libc.tls_size + __pthread_tsd_size);
232 }
233
234 if (!tsd) {
235 if (guard) {
236 map = __mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0);
237 if (map == MAP_FAILED) goto fail;
238 if (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE)
239 && errno != ENOSYS) {
240 __munmap(map, size);
241 goto fail;
242 }
243 } else {
244 map = __mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
245 if (map == MAP_FAILED) goto fail;
246 }
247 tsd = map + size - __pthread_tsd_size;
248 if (!stack) {
249 stack = tsd - libc.tls_size;
250 stack_limit = map + guard;
251 }
252 }
253
254 new = __copy_tls(tsd - libc.tls_size);
255 new->map_base = map;
256 new->map_size = size;
257 new->stack = stack;
258 new->stack_size = stack - stack_limit;
259 new->guard_size = guard;
260 new->start = entry;
261 new->start_arg = arg;
262 new->self = new;
263 new->tsd = (void *)tsd;
264 new->locale = &libc.global_locale;
265 if (attr._a_detach) {
266 new->detach_state = DT_DETACHED;
267 flags -= CLONE_CHILD_CLEARTID;
268 } else {
269 new->detach_state = DT_JOINABLE;
270 }
271 if (attr._a_sched) {
272 do_sched = 1;
273 ssa.futex = -1;
274 ssa.start_fn = new->start;
275 ssa.start_arg = new->start_arg;
276 ssa.attr = &attr;
277 new->start = __start_sched;
278 new->start_arg = &ssa;
279 __block_app_sigs(&ssa.mask);
280 }
281 new->robust_list.head = &new->robust_list.head;
282 new->unblock_cancel = self->cancel;
283 new->CANARY = self->CANARY;
284
285 a_inc(&libc.threads_minus_1);
286 ret = __clone((c11 ? start_c11 : start), stack, flags, new, &new->tid, TP_ADJ(new), &new->detach_state);
287
288 __release_ptc();
289
290 if (do_sched) {
291 __restore_sigs(&ssa.mask);
292 }
293
294 if (ret < 0) {
295 a_dec(&libc.threads_minus_1);
296 if (map) __munmap(map, size);
297 return EAGAIN;
298 }
299
300 if (do_sched) {
301 __futexwait(&ssa.futex, -1, 1);
302 ret = ssa.futex;
303 if (ret) return ret;
304 }
305
306 *res = new;
307 return 0;
308fail:
309 __release_ptc();
310 return EAGAIN;
311}
312
313weak_alias(__pthread_exit, pthread_exit);
314weak_alias(__pthread_create, pthread_create);
libc/musl/src/thread/pthread_detach.c created+14
......@@ -0,0 +1,14 @@
1#include "pthread_impl.h"
2#include <threads.h>
3
4static int __pthread_detach(pthread_t t)
5{
6 /* If the cas fails, detach state is either already-detached
7 * or exiting/exited, and pthread_join will trap or cleanup. */
8 if (a_cas(&t->detach_state, DT_JOINABLE, DT_DYNAMIC) != DT_JOINABLE)
9 return __pthread_join(t, 0);
10 return 0;
11}
12
13weak_alias(__pthread_detach, pthread_detach);
14weak_alias(__pthread_detach, thrd_detach);
libc/musl/src/thread/pthread_equal.c created+10
......@@ -0,0 +1,10 @@
1#include <pthread.h>
2#include <threads.h>
3
4static int __pthread_equal(pthread_t a, pthread_t b)
5{
6 return a==b;
7}
8
9weak_alias(__pthread_equal, pthread_equal);
10weak_alias(__pthread_equal, thrd_equal);
libc/musl/src/thread/pthread_getattr_np.c created+24
......@@ -0,0 +1,24 @@
1#define _GNU_SOURCE
2#include "pthread_impl.h"
3#include "libc.h"
4#include <sys/mman.h>
5
6int pthread_getattr_np(pthread_t t, pthread_attr_t *a)
7{
8 *a = (pthread_attr_t){0};
9 a->_a_detach = t->detach_state>=DT_DETACHED;
10 a->_a_guardsize = t->guard_size;
11 if (t->stack) {
12 a->_a_stackaddr = (uintptr_t)t->stack;
13 a->_a_stacksize = t->stack_size;
14 } else {
15 char *p = (void *)libc.auxv;
16 size_t l = PAGE_SIZE;
17 p += -(uintptr_t)p & PAGE_SIZE-1;
18 a->_a_stackaddr = (uintptr_t)p;
19 while (mremap(p-l-PAGE_SIZE, PAGE_SIZE, 2*PAGE_SIZE, 0)==MAP_FAILED && errno==ENOMEM)
20 l += PAGE_SIZE;
21 a->_a_stacksize = l;
22 }
23 return 0;
24}
libc/musl/src/thread/pthread_getconcurrency.c created+6
......@@ -0,0 +1,6 @@
1#include <pthread.h>
2
3int pthread_getconcurrency()
4{
5 return 0;
6}
libc/musl/src/thread/pthread_getcpuclockid.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_getcpuclockid(pthread_t t, clockid_t *clockid)
4{
5 *clockid = (-t->tid-1)*8U + 6;
6 return 0;
7}
libc/musl/src/thread/pthread_getschedparam.c created+18
......@@ -0,0 +1,18 @@
1#include "pthread_impl.h"
2#include "lock.h"
3
4int pthread_getschedparam(pthread_t t, int *restrict policy, struct sched_param *restrict param)
5{
6 int r;
7 LOCK(t->killlock);
8 if (!t->tid) {
9 r = ESRCH;
10 } else {
11 r = -__syscall(SYS_sched_getparam, t->tid, param);
12 if (!r) {
13 *policy = __syscall(SYS_sched_getscheduler, t->tid);
14 }
15 }
16 UNLOCK(t->killlock);
17 return r;
18}
libc/musl/src/thread/pthread_getspecific.c created+11
......@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2#include <threads.h>
3
4static void *__pthread_getspecific(pthread_key_t k)
5{
6 struct pthread *self = __pthread_self();
7 return self->tsd[k];
8}
9
10weak_alias(__pthread_getspecific, pthread_getspecific);
11weak_alias(__pthread_getspecific, tss_get);
libc/musl/src/thread/pthread_join.c created+34
......@@ -0,0 +1,34 @@
1#include "pthread_impl.h"
2#include <sys/mman.h>
3
4static int __pthread_timedjoin_np(pthread_t t, void **res, const struct timespec *at)
5{
6 int state, cs, r = 0;
7 __pthread_testcancel();
8 __pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
9 if (cs == PTHREAD_CANCEL_ENABLE) __pthread_setcancelstate(cs, 0);
10 while ((state = t->detach_state) && r != ETIMEDOUT && r != EINVAL) {
11 if (state >= DT_DETACHED) a_crash();
12 r = __timedwait_cp(&t->detach_state, state, CLOCK_REALTIME, at, 0);
13 }
14 __pthread_setcancelstate(cs, 0);
15 if (r == ETIMEDOUT || r == EINVAL) return r;
16 a_barrier();
17 if (res) *res = t->result;
18 if (t->map_base) __munmap(t->map_base, t->map_size);
19 return 0;
20}
21
22int __pthread_join(pthread_t t, void **res)
23{
24 return __pthread_timedjoin_np(t, res, 0);
25}
26
27static int __pthread_tryjoin_np(pthread_t t, void **res)
28{
29 return t->detach_state==DT_JOINABLE ? EBUSY : __pthread_join(t, res);
30}
31
32weak_alias(__pthread_tryjoin_np, pthread_tryjoin_np);
33weak_alias(__pthread_timedjoin_np, pthread_timedjoin_np);
34weak_alias(__pthread_join, pthread_join);
libc/musl/src/thread/pthread_key_create.c created+131
......@@ -0,0 +1,131 @@
1#include "pthread_impl.h"
2
3volatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX;
4void *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 };
5
6static void (*keys[PTHREAD_KEYS_MAX])(void *);
7
8static pthread_rwlock_t key_lock = PTHREAD_RWLOCK_INITIALIZER;
9
10static pthread_key_t next_key;
11
12static void nodtor(void *dummy)
13{
14}
15
16static void dirty(void *dummy)
17{
18}
19
20struct cleanup_args {
21 pthread_t caller;
22 int ret;
23};
24
25static void clean_dirty_tsd_callback(void *p)
26{
27 struct cleanup_args *args = p;
28 pthread_t self = __pthread_self();
29 pthread_key_t i;
30 for (i=0; i<PTHREAD_KEYS_MAX; i++) {
31 if (keys[i] == dirty && self->tsd[i])
32 self->tsd[i] = 0;
33 }
34 /* Arbitrary choice to avoid data race. */
35 if (args->caller == self) args->ret = 0;
36}
37
38static void dummy2(void (*f)(void *), void *p)
39{
40}
41
42weak_alias(dummy2, __pthread_key_delete_synccall);
43
44static int clean_dirty_tsd(void)
45{
46 struct cleanup_args args = {
47 .caller = __pthread_self(),
48 .ret = EAGAIN
49 };
50 __pthread_key_delete_synccall(clean_dirty_tsd_callback, &args);
51 return args.ret;
52}
53
54int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
55{
56 pthread_key_t j = next_key;
57 pthread_t self = __pthread_self();
58 int found_dirty = 0;
59
60 /* This can only happen in the main thread before
61 * pthread_create has been called. */
62 if (!self->tsd) self->tsd = __pthread_tsd_main;
63
64 /* Purely a sentinel value since null means slot is free. */
65 if (!dtor) dtor = nodtor;
66
67 pthread_rwlock_wrlock(&key_lock);
68 do {
69 if (!keys[j]) {
70 keys[next_key = *k = j] = dtor;
71 pthread_rwlock_unlock(&key_lock);
72 return 0;
73 } else if (keys[j] == dirty) {
74 found_dirty = 1;
75 }
76 } while ((j=(j+1)%PTHREAD_KEYS_MAX) != next_key);
77
78 /* It's possible that all slots are in use or __synccall fails. */
79 if (!found_dirty || clean_dirty_tsd()) {
80 pthread_rwlock_unlock(&key_lock);
81 return EAGAIN;
82 }
83
84 /* If this point is reached there is necessarily a newly-cleaned
85 * slot to allocate to satisfy the caller's request. Find it and
86 * mark any additional previously-dirty slots clean. */
87 for (j=0; j<PTHREAD_KEYS_MAX; j++) {
88 if (keys[j] == dirty) {
89 if (dtor) {
90 keys[next_key = *k = j] = dtor;
91 dtor = 0;
92 } else {
93 keys[j] = 0;
94 }
95 }
96 }
97
98 pthread_rwlock_unlock(&key_lock);
99 return 0;
100}
101
102int __pthread_key_delete_impl(pthread_key_t k)
103{
104 pthread_rwlock_wrlock(&key_lock);
105 keys[k] = dirty;
106 pthread_rwlock_unlock(&key_lock);
107 return 0;
108}
109
110void __pthread_tsd_run_dtors()
111{
112 pthread_t self = __pthread_self();
113 int i, j;
114 for (j=0; self->tsd_used && j<PTHREAD_DESTRUCTOR_ITERATIONS; j++) {
115 pthread_rwlock_rdlock(&key_lock);
116 self->tsd_used = 0;
117 for (i=0; i<PTHREAD_KEYS_MAX; i++) {
118 void *val = self->tsd[i];
119 void (*dtor)(void *) = keys[i];
120 self->tsd[i] = 0;
121 if (val && dtor && dtor != nodtor && dtor != dirty) {
122 pthread_rwlock_unlock(&key_lock);
123 dtor(val);
124 pthread_rwlock_rdlock(&key_lock);
125 }
126 }
127 pthread_rwlock_unlock(&key_lock);
128 }
129}
130
131weak_alias(__pthread_key_create, pthread_key_create);
libc/musl/src/thread/pthread_key_delete.c created+14
......@@ -0,0 +1,14 @@
1#include "pthread_impl.h"
2#include "libc.h"
3
4void __pthread_key_delete_synccall(void (*f)(void *), void *p)
5{
6 __synccall(f, p);
7}
8
9int __pthread_key_delete(pthread_key_t k)
10{
11 return __pthread_key_delete_impl(k);
12}
13
14weak_alias(__pthread_key_delete, pthread_key_delete);
libc/musl/src/thread/pthread_kill.c created+12
......@@ -0,0 +1,12 @@
1#include "pthread_impl.h"
2#include "lock.h"
3
4int pthread_kill(pthread_t t, int sig)
5{
6 int r;
7 LOCK(t->killlock);
8 r = t->tid ? -__syscall(SYS_tkill, t->tid, sig)
9 : (sig+0U >= _NSIG ? EINVAL : 0);
10 UNLOCK(t->killlock);
11 return r;
12}
libc/musl/src/thread/pthread_mutex_consistent.c created+10
......@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2
3int pthread_mutex_consistent(pthread_mutex_t *m)
4{
5 if (!(m->_m_type & 8)) return EINVAL;
6 if ((m->_m_lock & 0x7fffffff) != __pthread_self()->tid)
7 return EPERM;
8 m->_m_type &= ~8U;
9 return 0;
10}
libc/musl/src/thread/pthread_mutex_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include <pthread.h>
2
3int pthread_mutex_destroy(pthread_mutex_t *mutex)
4{
5 return 0;
6}
libc/musl/src/thread/pthread_mutex_getprioceiling.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_mutex_getprioceiling(const pthread_mutex_t *restrict m, int *restrict ceiling)
4{
5 return EINVAL;
6}
libc/musl/src/thread/pthread_mutex_init.c created+8
......@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_mutex_init(pthread_mutex_t *restrict m, const pthread_mutexattr_t *restrict a)
4{
5 *m = (pthread_mutex_t){0};
6 if (a) m->_m_type = a->__attr;
7 return 0;
8}
libc/musl/src/thread/pthread_mutex_lock.c created+12
......@@ -0,0 +1,12 @@
1#include "pthread_impl.h"
2
3int __pthread_mutex_lock(pthread_mutex_t *m)
4{
5 if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL
6 && !a_cas(&m->_m_lock, 0, EBUSY))
7 return 0;
8
9 return __pthread_mutex_timedlock(m, 0);
10}
11
12weak_alias(__pthread_mutex_lock, pthread_mutex_lock);
libc/musl/src/thread/pthread_mutex_setprioceiling.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_mutex_setprioceiling(pthread_mutex_t *restrict m, int ceiling, int *restrict old)
4{
5 return EINVAL;
6}
libc/musl/src/thread/pthread_mutex_timedlock.c created+35
......@@ -0,0 +1,35 @@
1#include "pthread_impl.h"
2
3int __pthread_mutex_timedlock(pthread_mutex_t *restrict m, const struct timespec *restrict at)
4{
5 if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL
6 && !a_cas(&m->_m_lock, 0, EBUSY))
7 return 0;
8
9 int type = m->_m_type;
10 int r, t, priv = (type & 128) ^ 128;
11
12 r = pthread_mutex_trylock(m);
13 if (r != EBUSY) return r;
14
15 int spins = 100;
16 while (spins-- && m->_m_lock && !m->_m_waiters) a_spin();
17
18 while ((r=__pthread_mutex_trylock(m)) == EBUSY) {
19 if (!(r=m->_m_lock) || ((r&0x40000000) && (type&4)))
20 continue;
21 if ((type&3) == PTHREAD_MUTEX_ERRORCHECK
22 && (r&0x7fffffff) == __pthread_self()->tid)
23 return EDEADLK;
24
25 a_inc(&m->_m_waiters);
26 t = r | 0x80000000;
27 a_cas(&m->_m_lock, r, t);
28 r = __timedwait(&m->_m_lock, t, CLOCK_REALTIME, at, priv);
29 a_dec(&m->_m_waiters);
30 if (r && r != EINTR) break;
31 }
32 return r;
33}
34
35weak_alias(__pthread_mutex_timedlock, pthread_mutex_timedlock);
libc/musl/src/thread/pthread_mutex_trylock.c created+58
......@@ -0,0 +1,58 @@
1#include "pthread_impl.h"
2
3int __pthread_mutex_trylock_owner(pthread_mutex_t *m)
4{
5 int old, own;
6 int type = m->_m_type & 15;
7 pthread_t self = __pthread_self();
8 int tid = self->tid;
9
10 old = m->_m_lock;
11 own = old & 0x7fffffff;
12 if (own == tid && (type&3) == PTHREAD_MUTEX_RECURSIVE) {
13 if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN;
14 m->_m_count++;
15 return 0;
16 }
17 if (own == 0x7fffffff) return ENOTRECOVERABLE;
18 if (own && (!(own & 0x40000000) || !(type & 4))) return EBUSY;
19
20 if (m->_m_type & 128) {
21 if (!self->robust_list.off) {
22 self->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next;
23 __syscall(SYS_set_robust_list, &self->robust_list, 3*sizeof(long));
24 }
25 if (m->_m_waiters) tid |= 0x80000000;
26 self->robust_list.pending = &m->_m_next;
27 }
28
29 if (a_cas(&m->_m_lock, old, tid) != old) {
30 self->robust_list.pending = 0;
31 return EBUSY;
32 }
33
34 volatile void *next = self->robust_list.head;
35 m->_m_next = next;
36 m->_m_prev = &self->robust_list.head;
37 if (next != &self->robust_list.head) *(volatile void *volatile *)
38 ((char *)next - sizeof(void *)) = &m->_m_next;
39 self->robust_list.head = &m->_m_next;
40 self->robust_list.pending = 0;
41
42 if (own) {
43 m->_m_count = 0;
44 m->_m_type |= 8;
45 return EOWNERDEAD;
46 }
47
48 return 0;
49}
50
51int __pthread_mutex_trylock(pthread_mutex_t *m)
52{
53 if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL)
54 return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY;
55 return __pthread_mutex_trylock_owner(m);
56}
57
58weak_alias(__pthread_mutex_trylock, pthread_mutex_trylock);
libc/musl/src/thread/pthread_mutex_unlock.c created+37
......@@ -0,0 +1,37 @@
1#include "pthread_impl.h"
2
3int __pthread_mutex_unlock(pthread_mutex_t *m)
4{
5 pthread_t self;
6 int waiters = m->_m_waiters;
7 int cont;
8 int type = m->_m_type & 15;
9 int priv = (m->_m_type & 128) ^ 128;
10
11 if (type != PTHREAD_MUTEX_NORMAL) {
12 self = __pthread_self();
13 if ((m->_m_lock&0x7fffffff) != self->tid)
14 return EPERM;
15 if ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)
16 return m->_m_count--, 0;
17 if (!priv) {
18 self->robust_list.pending = &m->_m_next;
19 __vm_lock();
20 }
21 volatile void *prev = m->_m_prev;
22 volatile void *next = m->_m_next;
23 *(volatile void *volatile *)prev = next;
24 if (next != &self->robust_list.head) *(volatile void *volatile *)
25 ((char *)next - sizeof(void *)) = prev;
26 }
27 cont = a_swap(&m->_m_lock, (type & 8) ? 0x7fffffff : 0);
28 if (type != PTHREAD_MUTEX_NORMAL && !priv) {
29 self->robust_list.pending = 0;
30 __vm_unlock();
31 }
32 if (waiters || cont<0)
33 __wake(&m->_m_lock, 1, priv);
34 return 0;
35}
36
37weak_alias(__pthread_mutex_unlock, pthread_mutex_unlock);
libc/musl/src/thread/pthread_mutexattr_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
4{
5 return 0;
6}
libc/musl/src/thread/pthread_mutexattr_init.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_mutexattr_init(pthread_mutexattr_t *a)
4{
5 *a = (pthread_mutexattr_t){0};
6 return 0;
7}
libc/musl/src/thread/pthread_mutexattr_setprotocol.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol)
4{
5 if (protocol) return ENOTSUP;
6 return 0;
7}
libc/musl/src/thread/pthread_mutexattr_setpshared.c created+9
......@@ -0,0 +1,9 @@
1#include "pthread_impl.h"
2
3int pthread_mutexattr_setpshared(pthread_mutexattr_t *a, int pshared)
4{
5 if (pshared > 1U) return EINVAL;
6 a->__attr &= ~128U;
7 a->__attr |= pshared<<7;
8 return 0;
9}
libc/musl/src/thread/pthread_mutexattr_setrobust.c created+25
......@@ -0,0 +1,25 @@
1#include "pthread_impl.h"
2#include "syscall.h"
3
4static pthread_once_t check_robust_once;
5static int check_robust_result;
6
7static void check_robust()
8{
9 void *p;
10 size_t l;
11 check_robust_result = -__syscall(SYS_get_robust_list, 0, &p, &l);
12}
13
14int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust)
15{
16 if (robust > 1U) return EINVAL;
17 if (robust) {
18 pthread_once(&check_robust_once, check_robust);
19 if (check_robust_result) return check_robust_result;
20 a->__attr |= 4;
21 return 0;
22 }
23 a->__attr &= ~4;
24 return 0;
25}
libc/musl/src/thread/pthread_mutexattr_settype.c created+8
......@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)
4{
5 if ((unsigned)type > 2) return EINVAL;
6 a->__attr = (a->__attr & ~3) | type;
7 return 0;
8}
libc/musl/src/thread/pthread_once.c created+50
......@@ -0,0 +1,50 @@
1#include "pthread_impl.h"
2
3static void undo(void *control)
4{
5 /* Wake all waiters, since the waiter status is lost when
6 * resetting control to the initial state. */
7 if (a_swap(control, 0) == 3)
8 __wake(control, -1, 1);
9}
10
11hidden int __pthread_once_full(pthread_once_t *control, void (*init)(void))
12{
13 /* Try to enter initializing state. Four possibilities:
14 * 0 - we're the first or the other cancelled; run init
15 * 1 - another thread is running init; wait
16 * 2 - another thread finished running init; just return
17 * 3 - another thread is running init, waiters present; wait */
18
19 for (;;) switch (a_cas(control, 0, 1)) {
20 case 0:
21 pthread_cleanup_push(undo, control);
22 init();
23 pthread_cleanup_pop(0);
24
25 if (a_swap(control, 2) == 3)
26 __wake(control, -1, 1);
27 return 0;
28 case 1:
29 /* If this fails, so will __wait. */
30 a_cas(control, 1, 3);
31 case 3:
32 __wait(control, 0, 3, 1);
33 continue;
34 case 2:
35 return 0;
36 }
37}
38
39int __pthread_once(pthread_once_t *control, void (*init)(void))
40{
41 /* Return immediately if init finished before, but ensure that
42 * effects of the init routine are visible to the caller. */
43 if (*(volatile int *)control == 2) {
44 a_barrier();
45 return 0;
46 }
47 return __pthread_once_full(control, init);
48}
49
50weak_alias(__pthread_once, pthread_once);
libc/musl/src/thread/pthread_rwlock_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_rwlock_destroy(pthread_rwlock_t *rw)
4{
5 return 0;
6}
libc/musl/src/thread/pthread_rwlock_init.c created+8
......@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_rwlock_init(pthread_rwlock_t *restrict rw, const pthread_rwlockattr_t *restrict a)
4{
5 *rw = (pthread_rwlock_t){0};
6 if (a) rw->_rw_shared = a->__attr[0]*128;
7 return 0;
8}
libc/musl/src/thread/pthread_rwlock_rdlock.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_rwlock_rdlock(pthread_rwlock_t *rw)
4{
5 return pthread_rwlock_timedrdlock(rw, 0);
6}
libc/musl/src/thread/pthread_rwlock_timedrdlock.c created+23
......@@ -0,0 +1,23 @@
1#include "pthread_impl.h"
2
3int pthread_rwlock_timedrdlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)
4{
5 int r, t;
6
7 r = pthread_rwlock_tryrdlock(rw);
8 if (r != EBUSY) return r;
9
10 int spins = 100;
11 while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();
12
13 while ((r=pthread_rwlock_tryrdlock(rw))==EBUSY) {
14 if (!(r=rw->_rw_lock) || (r&0x7fffffff)!=0x7fffffff) continue;
15 t = r | 0x80000000;
16 a_inc(&rw->_rw_waiters);
17 a_cas(&rw->_rw_lock, r, t);
18 r = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at, rw->_rw_shared^128);
19 a_dec(&rw->_rw_waiters);
20 if (r && r != EINTR) return r;
21 }
22 return r;
23}
libc/musl/src/thread/pthread_rwlock_timedwrlock.c created+23
......@@ -0,0 +1,23 @@
1#include "pthread_impl.h"
2
3int pthread_rwlock_timedwrlock(pthread_rwlock_t *restrict rw, const struct timespec *restrict at)
4{
5 int r, t;
6
7 r = pthread_rwlock_trywrlock(rw);
8 if (r != EBUSY) return r;
9
10 int spins = 100;
11 while (spins-- && rw->_rw_lock && !rw->_rw_waiters) a_spin();
12
13 while ((r=pthread_rwlock_trywrlock(rw))==EBUSY) {
14 if (!(r=rw->_rw_lock)) continue;
15 t = r | 0x80000000;
16 a_inc(&rw->_rw_waiters);
17 a_cas(&rw->_rw_lock, r, t);
18 r = __timedwait(&rw->_rw_lock, t, CLOCK_REALTIME, at, rw->_rw_shared^128);
19 a_dec(&rw->_rw_waiters);
20 if (r && r != EINTR) return r;
21 }
22 return r;
23}
libc/musl/src/thread/pthread_rwlock_tryrdlock.c created+13
......@@ -0,0 +1,13 @@
1#include "pthread_impl.h"
2
3int pthread_rwlock_tryrdlock(pthread_rwlock_t *rw)
4{
5 int val, cnt;
6 do {
7 val = rw->_rw_lock;
8 cnt = val & 0x7fffffff;
9 if (cnt == 0x7fffffff) return EBUSY;
10 if (cnt == 0x7ffffffe) return EAGAIN;
11 } while (a_cas(&rw->_rw_lock, val, val+1) != val);
12 return 0;
13}
libc/musl/src/thread/pthread_rwlock_trywrlock.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_rwlock_trywrlock(pthread_rwlock_t *rw)
4{
5 if (a_cas(&rw->_rw_lock, 0, 0x7fffffff)) return EBUSY;
6 return 0;
7}
libc/musl/src/thread/pthread_rwlock_unlock.c created+18
......@@ -0,0 +1,18 @@
1#include "pthread_impl.h"
2
3int pthread_rwlock_unlock(pthread_rwlock_t *rw)
4{
5 int val, cnt, waiters, new, priv = rw->_rw_shared^128;
6
7 do {
8 val = rw->_rw_lock;
9 cnt = val & 0x7fffffff;
10 waiters = rw->_rw_waiters;
11 new = (cnt == 0x7fffffff || cnt == 1) ? 0 : val-1;
12 } while (a_cas(&rw->_rw_lock, val, new) != val);
13
14 if (!new && (waiters || val<0))
15 __wake(&rw->_rw_lock, cnt, priv);
16
17 return 0;
18}
libc/musl/src/thread/pthread_rwlock_wrlock.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_rwlock_wrlock(pthread_rwlock_t *rw)
4{
5 return pthread_rwlock_timedwrlock(rw, 0);
6}
libc/musl/src/thread/pthread_rwlockattr_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
4{
5 return 0;
6}
libc/musl/src/thread/pthread_rwlockattr_init.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_rwlockattr_init(pthread_rwlockattr_t *a)
4{
5 *a = (pthread_rwlockattr_t){0};
6 return 0;
7}
libc/musl/src/thread/pthread_rwlockattr_setpshared.c created+8
......@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2
3int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int pshared)
4{
5 if (pshared > 1U) return EINVAL;
6 a->__attr[0] = pshared;
7 return 0;
8}
libc/musl/src/thread/pthread_self.c created+10
......@@ -0,0 +1,10 @@
1#include "pthread_impl.h"
2#include <threads.h>
3
4static pthread_t __pthread_self_internal()
5{
6 return __pthread_self();
7}
8
9weak_alias(__pthread_self_internal, pthread_self);
10weak_alias(__pthread_self_internal, thrd_current);
libc/musl/src/thread/pthread_setattr_default_np.c created+37
......@@ -0,0 +1,37 @@
1#define _GNU_SOURCE
2#include "pthread_impl.h"
3#include <string.h>
4
5#define MIN(a,b) ((a)<(b) ? (a) : (b))
6#define MAX(a,b) ((a)>(b) ? (a) : (b))
7
8int pthread_setattr_default_np(const pthread_attr_t *attrp)
9{
10 /* Reject anything in the attr object other than stack/guard size. */
11 pthread_attr_t tmp = *attrp, zero = { 0 };
12 tmp._a_stacksize = 0;
13 tmp._a_guardsize = 0;
14 if (memcmp(&tmp, &zero, sizeof tmp))
15 return EINVAL;
16
17 unsigned stack = MIN(attrp->_a_stacksize, DEFAULT_STACK_MAX);
18 unsigned guard = MIN(attrp->_a_guardsize, DEFAULT_GUARD_MAX);
19
20 __inhibit_ptc();
21 __default_stacksize = MAX(__default_stacksize, stack);
22 __default_guardsize = MAX(__default_guardsize, guard);
23 __release_ptc();
24
25 return 0;
26}
27
28int pthread_getattr_default_np(pthread_attr_t *attrp)
29{
30 __acquire_ptc();
31 *attrp = (pthread_attr_t) {
32 ._a_stacksize = __default_stacksize,
33 ._a_guardsize = __default_guardsize,
34 };
35 __release_ptc();
36 return 0;
37}
libc/musl/src/thread/pthread_setcancelstate.c created+12
......@@ -0,0 +1,12 @@
1#include "pthread_impl.h"
2
3int __pthread_setcancelstate(int new, int *old)
4{
5 if (new > 2U) return EINVAL;
6 struct pthread *self = __pthread_self();
7 if (old) *old = self->canceldisable;
8 self->canceldisable = new;
9 return 0;
10}
11
12weak_alias(__pthread_setcancelstate, pthread_setcancelstate);
libc/musl/src/thread/pthread_setcanceltype.c created+11
......@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2
3int pthread_setcanceltype(int new, int *old)
4{
5 struct pthread *self = __pthread_self();
6 if (new > 1U) return EINVAL;
7 if (old) *old = self->cancelasync;
8 self->cancelasync = new;
9 if (new) pthread_testcancel();
10 return 0;
11}
libc/musl/src/thread/pthread_setconcurrency.c created+9
......@@ -0,0 +1,9 @@
1#include <pthread.h>
2#include <errno.h>
3
4int pthread_setconcurrency(int val)
5{
6 if (val < 0) return EINVAL;
7 if (val > 0) return EAGAIN;
8 return 0;
9}
libc/musl/src/thread/pthread_setname_np.c created+26
......@@ -0,0 +1,26 @@
1#define _GNU_SOURCE
2#include <fcntl.h>
3#include <string.h>
4#include <unistd.h>
5#include <sys/prctl.h>
6
7#include "pthread_impl.h"
8
9int pthread_setname_np(pthread_t thread, const char *name)
10{
11 int fd, cs, status = 0;
12 char f[sizeof "/proc/self/task//comm" + 3*sizeof(int)];
13 size_t len;
14
15 if ((len = strnlen(name, 16)) > 15) return ERANGE;
16
17 if (thread == pthread_self())
18 return prctl(PR_SET_NAME, (unsigned long)name, 0UL, 0UL, 0UL) ? errno : 0;
19
20 snprintf(f, sizeof f, "/proc/self/task/%d/comm", thread->tid);
21 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
22 if ((fd = open(f, O_WRONLY)) < 0 || write(fd, name, len) < 0) status = errno;
23 if (fd >= 0) close(fd);
24 pthread_setcancelstate(cs, 0);
25 return status;
26}
libc/musl/src/thread/pthread_setschedparam.c created+11
......@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2#include "lock.h"
3
4int pthread_setschedparam(pthread_t t, int policy, const struct sched_param *param)
5{
6 int r;
7 LOCK(t->killlock);
8 r = !t->tid ? ESRCH : -__syscall(SYS_sched_setscheduler, t->tid, policy, param);
9 UNLOCK(t->killlock);
10 return r;
11}
libc/musl/src/thread/pthread_setschedprio.c created+11
......@@ -0,0 +1,11 @@
1#include "pthread_impl.h"
2#include "lock.h"
3
4int pthread_setschedprio(pthread_t t, int prio)
5{
6 int r;
7 LOCK(t->killlock);
8 r = !t->tid ? ESRCH : -__syscall(SYS_sched_setparam, t->tid, &prio);
9 UNLOCK(t->killlock);
10 return r;
11}
libc/musl/src/thread/pthread_setspecific.c created+12
......@@ -0,0 +1,12 @@
1#include "pthread_impl.h"
2
3int pthread_setspecific(pthread_key_t k, const void *x)
4{
5 struct pthread *self = __pthread_self();
6 /* Avoid unnecessary COW */
7 if (self->tsd[k] != x) {
8 self->tsd[k] = (void *)x;
9 self->tsd_used = 1;
10 }
11 return 0;
12}
libc/musl/src/thread/pthread_sigmask.c created+19
......@@ -0,0 +1,19 @@
1#include <signal.h>
2#include <errno.h>
3#include "syscall.h"
4
5int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict old)
6{
7 int ret;
8 if (set && (unsigned)how - SIG_BLOCK > 2U) return EINVAL;
9 ret = -__syscall(SYS_rt_sigprocmask, how, set, old, _NSIG/8);
10 if (!ret && old) {
11 if (sizeof old->__bits[0] == 8) {
12 old->__bits[0] &= ~0x380000000ULL;
13 } else {
14 old->__bits[0] &= ~0x80000000UL;
15 old->__bits[1] &= ~0x3UL;
16 }
17 }
18 return ret;
19}
libc/musl/src/thread/pthread_spin_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_spin_destroy(pthread_spinlock_t *s)
4{
5 return 0;
6}
libc/musl/src/thread/pthread_spin_init.c created+6
......@@ -0,0 +1,6 @@
1#include "pthread_impl.h"
2
3int pthread_spin_init(pthread_spinlock_t *s, int shared)
4{
5 return *s = 0;
6}
libc/musl/src/thread/pthread_spin_lock.c created+8
......@@ -0,0 +1,8 @@
1#include "pthread_impl.h"
2#include <errno.h>
3
4int pthread_spin_lock(pthread_spinlock_t *s)
5{
6 while (*(volatile int *)s || a_cas(s, 0, EBUSY)) a_spin();
7 return 0;
8}
libc/musl/src/thread/pthread_spin_trylock.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2#include <errno.h>
3
4int pthread_spin_trylock(pthread_spinlock_t *s)
5{
6 return a_cas(s, 0, EBUSY);
7}
libc/musl/src/thread/pthread_spin_unlock.c created+7
......@@ -0,0 +1,7 @@
1#include "pthread_impl.h"
2
3int pthread_spin_unlock(pthread_spinlock_t *s)
4{
5 a_store(s, 0);
6 return 0;
7}
libc/musl/src/thread/pthread_testcancel.c created+14
......@@ -0,0 +1,14 @@
1#include "pthread_impl.h"
2
3static void dummy()
4{
5}
6
7weak_alias(dummy, __testcancel);
8
9void __pthread_testcancel()
10{
11 __testcancel();
12}
13
14weak_alias(__pthread_testcancel, pthread_testcancel);
libc/musl/src/thread/s390x/__set_thread_area.s created+10
......@@ -0,0 +1,10 @@
1.text
2.global __set_thread_area
3.hidden __set_thread_area
4.type __set_thread_area, %function
5__set_thread_area:
6 sar %a1, %r2
7 srlg %r2, %r2, 32
8 sar %a0, %r2
9 lghi %r2, 0
10 br %r14
libc/musl/src/thread/s390x/__tls_get_offset.s created+17
......@@ -0,0 +1,17 @@
1 .global __tls_get_offset
2 .type __tls_get_offset,%function
3__tls_get_offset:
4 stmg %r14, %r15, 112(%r15)
5 aghi %r15, -160
6
7 la %r2, 0(%r2, %r12)
8 brasl %r14, __tls_get_addr
9
10 ear %r1, %a0
11 sllg %r1, %r1, 32
12 ear %r1, %a1
13
14 sgr %r2, %r1
15
16 lmg %r14, %r15, 272(%r15)
17 br %r14
libc/musl/src/thread/s390x/__unmapself.s created+6
......@@ -0,0 +1,6 @@
1.text
2.global __unmapself
3.type __unmapself, @function
4__unmapself:
5 svc 91 # SYS_munmap
6 svc 1 # SYS_exit
libc/musl/src/thread/s390x/clone.s created+48
......@@ -0,0 +1,48 @@
1.text
2.global __clone
3.hidden __clone
4.type __clone, %function
5__clone:
6 # int clone(
7 # fn, a = r2
8 # stack, b = r3
9 # flags, c = r4
10 # arg, d = r5
11 # ptid, e = r6
12 # tls, f = *(r15+160)
13 # ctid) g = *(r15+168)
14 #
15 # pseudo C code:
16 # tid = syscall(SYS_clone,b,c,e,g,f);
17 # if (!tid) syscall(SYS_exit, a(d));
18 # return tid;
19
20 # create initial stack frame for new thread
21 nill %r3, 0xfff8
22 aghi %r3, -160
23 lghi %r0, 0
24 stg %r0, 0(%r3)
25
26 # save fn and arg to child stack
27 stg %r2, 8(%r3)
28 stg %r5, 16(%r3)
29
30 # shuffle args into correct registers and call SYS_clone
31 lgr %r2, %r3
32 lgr %r3, %r4
33 lgr %r4, %r6
34 lg %r5, 168(%r15)
35 lg %r6, 160(%r15)
36 svc 120
37
38 # if error or if we're the parent, return
39 ltgr %r2, %r2
40 bnzr %r14
41
42 # we're the child. call fn(arg)
43 lg %r1, 8(%r15)
44 lg %r2, 16(%r15)
45 basr %r14, %r1
46
47 # call SYS_exit. exit code is already in r2 from fn return value
48 svc 1
libc/musl/src/thread/s390x/syscall_cp.s created+32
......@@ -0,0 +1,32 @@
1 .global __cp_begin
2 .hidden __cp_begin
3 .global __cp_end
4 .hidden __cp_end
5 .global __cp_cancel
6 .hidden __cp_cancel
7 .hidden __cancel
8 .global __syscall_cp_asm
9 .hidden __syscall_cp_asm
10 .text
11 .type __syscall_cp_asm,%function
12__syscall_cp_asm:
13__cp_begin:
14 icm %r2, 15, 0(%r2)
15 jne __cp_cancel
16
17 stg %r7, 56(%r15)
18 lgr %r1, %r3
19 lgr %r2, %r4
20 lgr %r3, %r5
21 lgr %r4, %r6
22 lg %r5, 160(%r15)
23 lg %r6, 168(%r15)
24 lg %r7, 176(%r15)
25 svc 0
26
27__cp_end:
28 lg %r7, 56(%r15)
29 br %r14
30
31__cp_cancel:
32 jg __cancel
libc/musl/src/thread/sem_destroy.c created+6
......@@ -0,0 +1,6 @@
1#include <semaphore.h>
2
3int sem_destroy(sem_t *sem)
4{
5 return 0;
6}
libc/musl/src/thread/sem_getvalue.c created+8
......@@ -0,0 +1,8 @@
1#include <semaphore.h>
2
3int sem_getvalue(sem_t *restrict sem, int *restrict valp)
4{
5 int val = sem->__val[0];
6 *valp = val < 0 ? 0 : val;
7 return 0;
8}
libc/musl/src/thread/sem_init.c created+15
......@@ -0,0 +1,15 @@
1#include <semaphore.h>
2#include <limits.h>
3#include <errno.h>
4
5int sem_init(sem_t *sem, int pshared, unsigned value)
6{
7 if (value > SEM_VALUE_MAX) {
8 errno = EINVAL;
9 return -1;
10 }
11 sem->__val[0] = value;
12 sem->__val[1] = 0;
13 sem->__val[2] = pshared ? 0 : 128;
14 return 0;
15}
libc/musl/src/thread/sem_open.c created+173
......@@ -0,0 +1,173 @@
1#include <semaphore.h>
2#include <sys/mman.h>
3#include <limits.h>
4#include <fcntl.h>
5#include <unistd.h>
6#include <string.h>
7#include <stdarg.h>
8#include <errno.h>
9#include <time.h>
10#include <stdio.h>
11#include <sys/stat.h>
12#include <stdlib.h>
13#include <pthread.h>
14#include "lock.h"
15
16static struct {
17 ino_t ino;
18 sem_t *sem;
19 int refcnt;
20} *semtab;
21static volatile int lock[1];
22
23#define FLAGS (O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK)
24
25sem_t *sem_open(const char *name, int flags, ...)
26{
27 va_list ap;
28 mode_t mode;
29 unsigned value;
30 int fd, i, e, slot, first=1, cnt, cs;
31 sem_t newsem;
32 void *map;
33 char tmp[64];
34 struct timespec ts;
35 struct stat st;
36 char buf[NAME_MAX+10];
37
38 if (!(name = __shm_mapname(name, buf)))
39 return SEM_FAILED;
40
41 LOCK(lock);
42 /* Allocate table if we don't have one yet */
43 if (!semtab && !(semtab = calloc(sizeof *semtab, SEM_NSEMS_MAX))) {
44 UNLOCK(lock);
45 return SEM_FAILED;
46 }
47
48 /* Reserve a slot in case this semaphore is not mapped yet;
49 * this is necessary because there is no way to handle
50 * failures after creation of the file. */
51 slot = -1;
52 for (cnt=i=0; i<SEM_NSEMS_MAX; i++) {
53 cnt += semtab[i].refcnt;
54 if (!semtab[i].sem && slot < 0) slot = i;
55 }
56 /* Avoid possibility of overflow later */
57 if (cnt == INT_MAX || slot < 0) {
58 errno = EMFILE;
59 UNLOCK(lock);
60 return SEM_FAILED;
61 }
62 /* Dummy pointer to make a reservation */
63 semtab[slot].sem = (sem_t *)-1;
64 UNLOCK(lock);
65
66 flags &= (O_CREAT|O_EXCL);
67
68 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
69
70 /* Early failure check for exclusive open; otherwise the case
71 * where the semaphore already exists is expensive. */
72 if (flags == (O_CREAT|O_EXCL) && access(name, F_OK) == 0) {
73 errno = EEXIST;
74 goto fail;
75 }
76
77 for (;;) {
78 /* If exclusive mode is not requested, try opening an
79 * existing file first and fall back to creation. */
80 if (flags != (O_CREAT|O_EXCL)) {
81 fd = open(name, FLAGS);
82 if (fd >= 0) {
83 if (fstat(fd, &st) < 0 ||
84 (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
85 close(fd);
86 goto fail;
87 }
88 close(fd);
89 break;
90 }
91 if (errno != ENOENT)
92 goto fail;
93 }
94 if (!(flags & O_CREAT))
95 goto fail;
96 if (first) {
97 first = 0;
98 va_start(ap, flags);
99 mode = va_arg(ap, mode_t) & 0666;
100 value = va_arg(ap, unsigned);
101 va_end(ap);
102 if (value > SEM_VALUE_MAX) {
103 errno = EINVAL;
104 goto fail;
105 }
106 sem_init(&newsem, 1, value);
107 }
108 /* Create a temp file with the new semaphore contents
109 * and attempt to atomically link it as the new name */
110 clock_gettime(CLOCK_REALTIME, &ts);
111 snprintf(tmp, sizeof(tmp), "/dev/shm/tmp-%d", (int)ts.tv_nsec);
112 fd = open(tmp, O_CREAT|O_EXCL|FLAGS, mode);
113 if (fd < 0) {
114 if (errno == EEXIST) continue;
115 goto fail;
116 }
117 if (write(fd, &newsem, sizeof newsem) != sizeof newsem || fstat(fd, &st) < 0 ||
118 (map = mmap(0, sizeof(sem_t), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
119 close(fd);
120 unlink(tmp);
121 goto fail;
122 }
123 close(fd);
124 e = link(tmp, name) ? errno : 0;
125 unlink(tmp);
126 if (!e) break;
127 munmap(map, sizeof(sem_t));
128 /* Failure is only fatal when doing an exclusive open;
129 * otherwise, next iteration will try to open the
130 * existing file. */
131 if (e != EEXIST || flags == (O_CREAT|O_EXCL))
132 goto fail;
133 }
134
135 /* See if the newly mapped semaphore is already mapped. If
136 * so, unmap the new mapping and use the existing one. Otherwise,
137 * add it to the table of mapped semaphores. */
138 LOCK(lock);
139 for (i=0; i<SEM_NSEMS_MAX && semtab[i].ino != st.st_ino; i++);
140 if (i<SEM_NSEMS_MAX) {
141 munmap(map, sizeof(sem_t));
142 semtab[slot].sem = 0;
143 slot = i;
144 map = semtab[i].sem;
145 }
146 semtab[slot].refcnt++;
147 semtab[slot].sem = map;
148 semtab[slot].ino = st.st_ino;
149 UNLOCK(lock);
150 pthread_setcancelstate(cs, 0);
151 return map;
152
153fail:
154 pthread_setcancelstate(cs, 0);
155 LOCK(lock);
156 semtab[slot].sem = 0;
157 UNLOCK(lock);
158 return SEM_FAILED;
159}
160
161int sem_close(sem_t *sem)
162{
163 int i;
164 LOCK(lock);
165 for (i=0; i<SEM_NSEMS_MAX && semtab[i].sem != sem; i++);
166 if (!--semtab[i].refcnt) {
167 semtab[i].sem = 0;
168 semtab[i].ino = 0;
169 }
170 UNLOCK(lock);
171 munmap(sem, sizeof *sem);
172 return 0;
173}
libc/musl/src/thread/sem_post.c created+17
......@@ -0,0 +1,17 @@
1#include <semaphore.h>
2#include "pthread_impl.h"
3
4int sem_post(sem_t *sem)
5{
6 int val, waiters, priv = sem->__val[2];
7 do {
8 val = sem->__val[0];
9 waiters = sem->__val[1];
10 if (val == SEM_VALUE_MAX) {
11 errno = EOVERFLOW;
12 return -1;
13 }
14 } while (a_cas(sem->__val, val, val+1+(val<0)) != val);
15 if (val<0 || waiters) __wake(sem->__val, 1, priv);
16 return 0;
17}
libc/musl/src/thread/sem_timedwait.c created+31
......@@ -0,0 +1,31 @@
1#include <semaphore.h>
2#include "pthread_impl.h"
3
4static void cleanup(void *p)
5{
6 a_dec(p);
7}
8
9int sem_timedwait(sem_t *restrict sem, const struct timespec *restrict at)
10{
11 pthread_testcancel();
12
13 if (!sem_trywait(sem)) return 0;
14
15 int spins = 100;
16 while (spins-- && sem->__val[0] <= 0 && !sem->__val[1]) a_spin();
17
18 while (sem_trywait(sem)) {
19 int r;
20 a_inc(sem->__val+1);
21 a_cas(sem->__val, 0, -1);
22 pthread_cleanup_push(cleanup, (void *)(sem->__val+1));
23 r = __timedwait_cp(sem->__val, -1, CLOCK_REALTIME, at, sem->__val[2]);
24 pthread_cleanup_pop(1);
25 if (r) {
26 errno = r;
27 return -1;
28 }
29 }
30 return 0;
31}
libc/musl/src/thread/sem_trywait.c created+13
......@@ -0,0 +1,13 @@
1#include <semaphore.h>
2#include "pthread_impl.h"
3
4int sem_trywait(sem_t *sem)
5{
6 int val;
7 while ((val=sem->__val[0]) > 0) {
8 int new = val-1-(val==1 && sem->__val[1]);
9 if (a_cas(sem->__val, val, new)==val) return 0;
10 }
11 errno = EAGAIN;
12 return -1;
13}
libc/musl/src/thread/sem_unlink.c created+7
......@@ -0,0 +1,7 @@
1#include <semaphore.h>
2#include <sys/mman.h>
3
4int sem_unlink(const char *name)
5{
6 return shm_unlink(name);
7}
libc/musl/src/thread/sem_wait.c created+6
......@@ -0,0 +1,6 @@
1#include <semaphore.h>
2
3int sem_wait(sem_t *sem)
4{
5 return sem_timedwait(sem, 0);
6}
libc/musl/src/thread/sh/__set_thread_area.c created+37
......@@ -0,0 +1,37 @@
1#include "pthread_impl.h"
2#include "libc.h"
3#include <elf.h>
4
5/* Also perform sh-specific init */
6
7#define CPU_HAS_LLSC 0x0040
8#define CPU_HAS_CAS_L 0x0400
9
10extern hidden const char __sh_cas_gusa[], __sh_cas_llsc[], __sh_cas_imask[], __sh_cas_cas_l[];
11
12hidden const void *__sh_cas_ptr;
13
14hidden unsigned __sh_nommu;
15
16int __set_thread_area(void *p)
17{
18 size_t *aux;
19 __asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
20#ifndef __SH4A__
21 __sh_cas_ptr = __sh_cas_gusa;
22#if !defined(__SH3__) && !defined(__SH4__)
23 for (aux=libc.auxv; *aux; aux+=2) {
24 if (*aux != AT_PLATFORM) continue;
25 const char *s = (void *)aux[1];
26 if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
27 __sh_cas_ptr = __sh_cas_imask;
28 __sh_nommu = 1;
29 }
30#endif
31 if (__hwcap & CPU_HAS_CAS_L)
32 __sh_cas_ptr = __sh_cas_cas_l;
33 else if (__hwcap & CPU_HAS_LLSC)
34 __sh_cas_ptr = __sh_cas_llsc;
35#endif
36 return 0;
37}
libc/musl/src/thread/sh/__unmapself.c created+24
......@@ -0,0 +1,24 @@
1#include "pthread_impl.h"
2
3hidden void __unmapself_sh_mmu(void *, size_t);
4hidden void __unmapself_sh_nommu(void *, size_t);
5
6#if !defined(__SH3__) && !defined(__SH4__)
7#define __unmapself __unmapself_sh_nommu
8#include "dynlink.h"
9#undef CRTJMP
10#define CRTJMP(pc,sp) __asm__ __volatile__( \
11 "mov.l @%0+,r0 ; mov.l @%0,r12 ; jmp @r0 ; mov %1,r15" \
12 : : "r"(pc), "r"(sp) : "r0", "memory" )
13#include "../__unmapself.c"
14#undef __unmapself
15extern hidden unsigned __sh_nommu;
16#else
17#define __sh_nommu 0
18#endif
19
20void __unmapself(void *base, size_t size)
21{
22 if (__sh_nommu) __unmapself_sh_nommu(base, size);
23 else __unmapself_sh_mmu(base, size);
24}
libc/musl/src/thread/sh/__unmapself_mmu.s created+23
......@@ -0,0 +1,23 @@
1.text
2.global __unmapself_sh_mmu
3.hidden __unmapself_sh_mmu
4.type __unmapself_sh_mmu, @function
5__unmapself_sh_mmu:
6 mov #91, r3 ! SYS_munmap
7 trapa #31
8
9 or r0, r0
10 or r0, r0
11 or r0, r0
12 or r0, r0
13 or r0, r0
14
15 mov #1, r3 ! SYS_exit
16 mov #0, r4
17 trapa #31
18
19 or r0, r0
20 or r0, r0
21 or r0, r0
22 or r0, r0
23 or r0, r0
libc/musl/src/thread/sh/atomics.s created+65
......@@ -0,0 +1,65 @@
1/* Contract for all versions is same as cas.l r2,r3,@r0
2 * pr and r1 are also clobbered (by jsr & r1 as temp).
3 * r0,r2,r4-r15 must be preserved.
4 * r3 contains result (==r2 iff cas succeeded). */
5
6 .align 2
7.global __sh_cas_gusa
8.hidden __sh_cas_gusa
9__sh_cas_gusa:
10 mov.l r5,@-r15
11 mov.l r4,@-r15
12 mov r0,r4
13 mova 1f,r0
14 mov r15,r1
15 mov #(0f-1f),r15
160: mov.l @r4,r5
17 cmp/eq r5,r2
18 bf 1f
19 mov.l r3,@r4
201: mov r1,r15
21 mov r5,r3
22 mov r4,r0
23 mov.l @r15+,r4
24 rts
25 mov.l @r15+,r5
26
27.global __sh_cas_llsc
28.hidden __sh_cas_llsc
29__sh_cas_llsc:
30 mov r0,r1
31 .word 0x00ab /* synco */
320: .word 0x0163 /* movli.l @r1,r0 */
33 cmp/eq r0,r2
34 bf 1f
35 mov r3,r0
36 .word 0x0173 /* movco.l r0,@r1 */
37 bf 0b
38 mov r2,r0
391: .word 0x00ab /* synco */
40 mov r0,r3
41 rts
42 mov r1,r0
43
44.global __sh_cas_imask
45.hidden __sh_cas_imask
46__sh_cas_imask:
47 mov r0,r1
48 stc sr,r0
49 mov.l r0,@-r15
50 or #0xf0,r0
51 ldc r0,sr
52 mov.l @r1,r0
53 cmp/eq r0,r2
54 bf 1f
55 mov.l r3,@r1
561: ldc.l @r15+,sr
57 mov r0,r3
58 rts
59 mov r1,r0
60
61.global __sh_cas_cas_l
62.hidden __sh_cas_cas_l
63__sh_cas_cas_l:
64 rts
65 .word 0x2323 /* cas.l r2,r3,@r0 */
libc/musl/src/thread/sh/clone.s created+54
......@@ -0,0 +1,54 @@
1.text
2.global __clone
3.hidden __clone
4.type __clone, @function
5__clone:
6! incoming: fn stack flags arg ptid tls ctid
7! r4 r5 r6 r7 @r15 @(4,r15) @(8,r15)
8
9 mov #-16, r0
10 and r0, r5
11
12 mov r4, r1 ! r1 = fn
13 mov r7, r2 ! r2 = arg
14
15 mov #120, r3 ! r3 = __NR_clone
16 mov r6, r4 ! r4 = flags
17 !mov r5, r5 ! r5 = stack
18 mov.l @r15, r6 ! r6 = ptid
19 mov.l @(8,r15), r7 ! r7 = ctid
20 mov.l @(4,r15), r0 ! r0 = tls
21 trapa #31
22
23 or r0, r0
24 or r0, r0
25 or r0, r0
26 or r0, r0
27 or r0, r0
28
29 cmp/eq #0, r0
30 bt 1f
31
32 ! we are the parent, return
33 rts
34 nop
35
361: ! we are the child, call fn(arg)
37 mov.l 1f, r0
38 mov r1, r5
39 bsrf r0
40 mov r2, r4
41
422: mov #1, r3 ! __NR_exit
43 mov r0, r4
44 trapa #31
45
46 or r0, r0
47 or r0, r0
48 or r0, r0
49 or r0, r0
50 or r0, r0
51
52.align 2
53.hidden __shcall
541: .long __shcall@PCREL+(.-2b)
libc/musl/src/thread/sh/syscall_cp.s created+45
......@@ -0,0 +1,45 @@
1.text
2.global __cp_begin
3.hidden __cp_begin
4.global __cp_end
5.hidden __cp_end
6.global __cp_cancel
7.hidden __cp_cancel
8.hidden __cancel
9.global __syscall_cp_asm
10.hidden __syscall_cp_asm
11.type __syscall_cp_asm, @function
12__syscall_cp_asm:
13
14__cp_begin:
15 mov.l @r4, r4
16 tst r4, r4
17 bf __cp_cancel
18 mov r5, r3
19 mov r6, r4
20 mov r7, r5
21 mov.l @r15, r6
22 mov.l @(4,r15), r7
23 mov.l @(8,r15), r0
24 mov.l @(12,r15), r1
25 trapa #31
26
27__cp_end:
28 ! work around hardware bug
29 or r0, r0
30 or r0, r0
31 or r0, r0
32 or r0, r0
33 or r0, r0
34
35 rts
36 nop
37
38__cp_cancel:
39 mov.l 2f, r0
40 braf r0
41 nop
421:
43
44.align 2
452: .long __cancel@PCREL-(1b-.)
libc/musl/src/thread/synccall.c created+179
......@@ -0,0 +1,179 @@
1#include "pthread_impl.h"
2#include <semaphore.h>
3#include <unistd.h>
4#include <dirent.h>
5#include <string.h>
6#include <ctype.h>
7#include "futex.h"
8#include "atomic.h"
9#include "../dirent/__dirent.h"
10#include "lock.h"
11
12static struct chain {
13 struct chain *next;
14 int tid;
15 sem_t target_sem, caller_sem;
16} *volatile head;
17
18static volatile int synccall_lock[1];
19static volatile int target_tid;
20static void (*callback)(void *), *context;
21static volatile int dummy = 0;
22weak_alias(dummy, __block_new_threads);
23
24static void handler(int sig)
25{
26 struct chain ch;
27 int old_errno = errno;
28
29 sem_init(&ch.target_sem, 0, 0);
30 sem_init(&ch.caller_sem, 0, 0);
31
32 ch.tid = __syscall(SYS_gettid);
33
34 do ch.next = head;
35 while (a_cas_p(&head, ch.next, &ch) != ch.next);
36
37 if (a_cas(&target_tid, ch.tid, 0) == (ch.tid | 0x80000000))
38 __syscall(SYS_futex, &target_tid, FUTEX_UNLOCK_PI|FUTEX_PRIVATE);
39
40 sem_wait(&ch.target_sem);
41 callback(context);
42 sem_post(&ch.caller_sem);
43 sem_wait(&ch.target_sem);
44
45 errno = old_errno;
46}
47
48void __synccall(void (*func)(void *), void *ctx)
49{
50 sigset_t oldmask;
51 int cs, i, r, pid, self;;
52 DIR dir = {0};
53 struct dirent *de;
54 struct sigaction sa = { .sa_flags = SA_RESTART, .sa_handler = handler };
55 struct chain *cp, *next;
56 struct timespec ts;
57
58 /* Blocking signals in two steps, first only app-level signals
59 * before taking the lock, then all signals after taking the lock,
60 * is necessary to achieve AS-safety. Blocking them all first would
61 * deadlock if multiple threads called __synccall. Waiting to block
62 * any until after the lock would allow re-entry in the same thread
63 * with the lock already held. */
64 __block_app_sigs(&oldmask);
65 LOCK(synccall_lock);
66 __block_all_sigs(0);
67 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
68
69 head = 0;
70
71 if (!libc.threaded) goto single_threaded;
72
73 callback = func;
74 context = ctx;
75
76 /* This atomic store ensures that any signaled threads will see the
77 * above stores, and prevents more than a bounded number of threads,
78 * those already in pthread_create, from creating new threads until
79 * the value is cleared to zero again. */
80 a_store(&__block_new_threads, 1);
81
82 /* Block even implementation-internal signals, so that nothing
83 * interrupts the SIGSYNCCALL handlers. The main possible source
84 * of trouble is asynchronous cancellation. */
85 memset(&sa.sa_mask, -1, sizeof sa.sa_mask);
86 __libc_sigaction(SIGSYNCCALL, &sa, 0);
87
88 pid = __syscall(SYS_getpid);
89 self = __syscall(SYS_gettid);
90
91 /* Since opendir is not AS-safe, the DIR needs to be setup manually
92 * in automatic storage. Thankfully this is easy. */
93 dir.fd = open("/proc/self/task", O_RDONLY|O_DIRECTORY|O_CLOEXEC);
94 if (dir.fd < 0) goto out;
95
96 /* Initially send one signal per counted thread. But since we can't
97 * synchronize with thread creation/exit here, there could be too
98 * few signals. This initial signaling is just an optimization, not
99 * part of the logic. */
100 for (i=libc.threads_minus_1; i; i--)
101 __syscall(SYS_kill, pid, SIGSYNCCALL);
102
103 /* Loop scanning the kernel-provided thread list until it shows no
104 * threads that have not already replied to the signal. */
105 for (;;) {
106 int miss_cnt = 0;
107 while ((de = readdir(&dir))) {
108 if (!isdigit(de->d_name[0])) continue;
109 int tid = atoi(de->d_name);
110 if (tid == self || !tid) continue;
111
112 /* Set the target thread as the PI futex owner before
113 * checking if it's in the list of caught threads. If it
114 * adds itself to the list after we check for it, then
115 * it will see its own tid in the PI futex and perform
116 * the unlock operation. */
117 a_store(&target_tid, tid);
118
119 /* Thread-already-caught is a success condition. */
120 for (cp = head; cp && cp->tid != tid; cp=cp->next);
121 if (cp) continue;
122
123 r = -__syscall(SYS_tgkill, pid, tid, SIGSYNCCALL);
124
125 /* Target thread exit is a success condition. */
126 if (r == ESRCH) continue;
127
128 /* The FUTEX_LOCK_PI operation is used to loan priority
129 * to the target thread, which otherwise may be unable
130 * to run. Timeout is necessary because there is a race
131 * condition where the tid may be reused by a different
132 * process. */
133 clock_gettime(CLOCK_REALTIME, &ts);
134 ts.tv_nsec += 10000000;
135 if (ts.tv_nsec >= 1000000000) {
136 ts.tv_sec++;
137 ts.tv_nsec -= 1000000000;
138 }
139 r = -__syscall(SYS_futex, &target_tid,
140 FUTEX_LOCK_PI|FUTEX_PRIVATE, 0, &ts);
141
142 /* Obtaining the lock means the thread responded. ESRCH
143 * means the target thread exited, which is okay too. */
144 if (!r || r == ESRCH) continue;
145
146 miss_cnt++;
147 }
148 if (!miss_cnt) break;
149 rewinddir(&dir);
150 }
151 close(dir.fd);
152
153 /* Serialize execution of callback in caught threads. */
154 for (cp=head; cp; cp=cp->next) {
155 sem_post(&cp->target_sem);
156 sem_wait(&cp->caller_sem);
157 }
158
159 sa.sa_handler = SIG_IGN;
160 __libc_sigaction(SIGSYNCCALL, &sa, 0);
161
162single_threaded:
163 func(ctx);
164
165 /* Only release the caught threads once all threads, including the
166 * caller, have returned from the callback function. */
167 for (cp=head; cp; cp=next) {
168 next = cp->next;
169 sem_post(&cp->target_sem);
170 }
171
172out:
173 a_store(&__block_new_threads, 0);
174 __wake(&__block_new_threads, -1, 1);
175
176 pthread_setcancelstate(cs, 0);
177 UNLOCK(synccall_lock);
178 __restore_sigs(&oldmask);
179}
libc/musl/src/thread/syscall_cp.c created
libc/musl/src/thread/thrd_create.c created+12
......@@ -0,0 +1,12 @@
1#include "pthread_impl.h"
2#include <threads.h>
3
4int thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
5{
6 int ret = __pthread_create(thr, __ATTRP_C11_THREAD, (void *(*)(void *))func, arg);
7 switch (ret) {
8 case 0: return thrd_success;
9 case EAGAIN: return thrd_nomem;
10 default: return thrd_error;
11 }
12}
libc/musl/src/thread/thrd_exit.c created+8
......@@ -0,0 +1,8 @@
1#include <threads.h>
2#include <pthread.h>
3#include <stdint.h>
4
5_Noreturn void thrd_exit(int result)
6{
7 __pthread_exit((void*)(intptr_t)result);
8}
libc/musl/src/thread/thrd_join.c created+11
......@@ -0,0 +1,11 @@
1#include <stdint.h>
2#include <threads.h>
3#include <pthread.h>
4
5int thrd_join(thrd_t t, int *res)
6{
7 void *pthread_res;
8 __pthread_join(t, &pthread_res);
9 if (res) *res = (int)(intptr_t)pthread_res;
10 return thrd_success;
11}
libc/musl/src/thread/thrd_sleep.c created+13
......@@ -0,0 +1,13 @@
1#include <threads.h>
2#include <errno.h>
3#include "syscall.h"
4
5int thrd_sleep(const struct timespec *req, struct timespec *rem)
6{
7 int ret = __syscall(SYS_nanosleep, req, rem);
8 switch (ret) {
9 case 0: return 0;
10 case -EINTR: return -1; /* value specified by C11 */
11 default: return -2;
12 }
13}
libc/musl/src/thread/thrd_yield.c created+7
......@@ -0,0 +1,7 @@
1#include <threads.h>
2#include "syscall.h"
3
4void thrd_yield()
5{
6 __syscall(SYS_sched_yield);
7}
libc/musl/src/thread/tls.c created
libc/musl/src/thread/tss_create.c created+10
......@@ -0,0 +1,10 @@
1#include <threads.h>
2#include <pthread.h>
3
4int tss_create(tss_t *tss, tss_dtor_t dtor)
5{
6 /* Different error returns are possible. C glues them together into
7 * just failure notification. Can't be optimized to a tail call,
8 * unless thrd_error equals EAGAIN. */
9 return __pthread_key_create(tss, dtor) ? thrd_error : thrd_success;
10}
libc/musl/src/thread/tss_delete.c created+7
......@@ -0,0 +1,7 @@
1#include <threads.h>
2#include <pthread.h>
3
4void tss_delete(tss_t key)
5{
6 __pthread_key_delete(key);
7}
libc/musl/src/thread/tss_set.c created+13
......@@ -0,0 +1,13 @@
1#include "pthread_impl.h"
2#include <threads.h>
3
4int tss_set(tss_t k, void *x)
5{
6 struct pthread *self = __pthread_self();
7 /* Avoid unnecessary COW */
8 if (self->tsd[k] != x) {
9 self->tsd[k] = x;
10 self->tsd_used = 1;
11 }
12 return thrd_success;
13}
libc/musl/src/thread/vmlock.c created+21
......@@ -0,0 +1,21 @@
1#include "pthread_impl.h"
2
3static volatile int vmlock[2];
4
5void __vm_wait()
6{
7 int tmp;
8 while ((tmp=vmlock[0]))
9 __wait(vmlock, vmlock+1, tmp, 1);
10}
11
12void __vm_lock()
13{
14 a_inc(vmlock);
15}
16
17void __vm_unlock()
18{
19 if (a_fetch_add(vmlock, -1)==1 && vmlock[1])
20 __wake(vmlock, -1, 1);
21}
libc/musl/src/thread/x32/__set_thread_area.s created+11
......@@ -0,0 +1,11 @@
1/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
2.text
3.global __set_thread_area
4.hidden __set_thread_area
5.type __set_thread_area,@function
6__set_thread_area:
7 mov %edi,%esi /* shift for syscall */
8 movl $0x1002,%edi /* SET_FS register */
9 movl $0x4000009e,%eax /* set fs segment to */
10 syscall /* arch_prctl(SET_FS, arg)*/
11 ret
libc/musl/src/thread/x32/__unmapself.s created+10
......@@ -0,0 +1,10 @@
1/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
2.text
3.global __unmapself
4.type __unmapself,@function
5__unmapself:
6 movl $0x4000000b,%eax /* SYS_munmap */
7 syscall /* munmap(arg2,arg3) */
8 xor %rdi,%rdi /* exit() args: always return success */
9 movl $0x4000003c,%eax /* SYS_exit */
10 syscall /* exit(0) */
libc/musl/src/thread/x32/clone.s created+26
......@@ -0,0 +1,26 @@
1.text
2.global __clone
3.hidden __clone
4.type __clone,@function
5__clone:
6 movl $0x40000038,%eax /* SYS_clone */
7 mov %rdi,%r11
8 mov %rdx,%rdi
9 mov %r8,%rdx
10 mov %r9,%r8
11 mov 8(%rsp),%r10
12 mov %r11,%r9
13 and $-16,%rsi
14 sub $8,%rsi
15 mov %rcx,(%rsi)
16 syscall
17 test %eax,%eax
18 jnz 1f
19 xor %ebp,%ebp
20 pop %rdi
21 call *%r9
22 mov %eax,%edi
23 movl $0x4000003c,%eax /* SYS_exit */
24 syscall
25 hlt
261: ret
libc/musl/src/thread/x32/syscall_cp.s created+31
......@@ -0,0 +1,31 @@
1.text
2.global __cp_begin
3.hidden __cp_begin
4.global __cp_end
5.hidden __cp_end
6.global __cp_cancel
7.hidden __cp_cancel
8.hidden __cancel
9.global __syscall_cp_internal
10.hidden __syscall_cp_internal
11.type __syscall_cp_internal,@function
12__syscall_cp_internal:
13
14__cp_begin:
15 mov (%rdi),%eax
16 test %eax,%eax
17 jnz __cp_cancel
18 mov %rdi,%r11
19 mov %rsi,%rax
20 mov %rdx,%rdi
21 mov %rcx,%rsi
22 mov %r8,%rdx
23 mov %r9,%r10
24 mov 8(%rsp),%r8
25 mov 16(%rsp),%r9
26 mov %r11,8(%rsp)
27 syscall
28__cp_end:
29 ret
30__cp_cancel:
31 jmp __cancel
libc/musl/src/thread/x32/syscall_cp_fixup.c created+39
......@@ -0,0 +1,39 @@
1#include <sys/syscall.h>
2#include <features.h>
3
4hidden long __syscall_cp_internal(volatile void*, long long, long long,
5 long long, long long, long long,
6 long long, long long);
7
8struct __timespec { long long tv_sec; long tv_nsec; };
9struct __timespec_kernel { long long tv_sec; long long tv_nsec; };
10#define __tsc(X) ((struct __timespec*)(unsigned long)(X))
11#define __fixup(X) do { if(X) { \
12 ts->tv_sec = __tsc(X)->tv_sec; \
13 ts->tv_nsec = __tsc(X)->tv_nsec; \
14 (X) = (unsigned long)ts; } } while(0)
15
16hidden long __syscall_cp_asm (volatile void * foo, long long n, long long a1,
17 long long a2, long long a3, long long a4,
18 long long a5, long long a6)
19{
20 struct __timespec_kernel ts[1];
21 switch (n) {
22 case SYS_mq_timedsend: case SYS_mq_timedreceive: case SYS_pselect6:
23 __fixup(a5);
24 break;
25 case SYS_futex:
26 if((a2 & (~128 /* FUTEX_PRIVATE_FLAG */)) == 0 /* FUTEX_WAIT */)
27 __fixup(a4);
28 break;
29 case SYS_clock_nanosleep:
30 case SYS_rt_sigtimedwait: case SYS_ppoll:
31 __fixup(a3);
32 break;
33 case SYS_nanosleep:
34 __fixup(a1);
35 break;
36 }
37 return __syscall_cp_internal(foo, n, a1, a2, a3, a4, a5, a6);
38}
39
libc/musl/src/thread/x86_64/__set_thread_area.s created+11
......@@ -0,0 +1,11 @@
1/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
2.text
3.global __set_thread_area
4.hidden __set_thread_area
5.type __set_thread_area,@function
6__set_thread_area:
7 mov %rdi,%rsi /* shift for syscall */
8 movl $0x1002,%edi /* SET_FS register */
9 movl $158,%eax /* set fs segment to */
10 syscall /* arch_prctl(SET_FS, arg)*/
11 ret
libc/musl/src/thread/x86_64/__unmapself.s created+10
......@@ -0,0 +1,10 @@
1/* Copyright 2011-2012 Nicholas J. Kain, licensed under standard MIT license */
2.text
3.global __unmapself
4.type __unmapself,@function
5__unmapself:
6 movl $11,%eax /* SYS_munmap */
7 syscall /* munmap(arg2,arg3) */
8 xor %rdi,%rdi /* exit() args: always return success */
9 movl $60,%eax /* SYS_exit */
10 syscall /* exit(0) */
libc/musl/src/thread/x86_64/clone.s created+28
......@@ -0,0 +1,28 @@
1.text
2.global __clone
3.hidden __clone
4.type __clone,@function
5__clone:
6 xor %eax,%eax
7 mov $56,%al
8 mov %rdi,%r11
9 mov %rdx,%rdi
10 mov %r8,%rdx
11 mov %r9,%r8
12 mov 8(%rsp),%r10
13 mov %r11,%r9
14 and $-16,%rsi
15 sub $8,%rsi
16 mov %rcx,(%rsi)
17 syscall
18 test %eax,%eax
19 jnz 1f
20 xor %ebp,%ebp
21 pop %rdi
22 call *%r9
23 mov %eax,%edi
24 xor %eax,%eax
25 mov $60,%al
26 syscall
27 hlt
281: ret
libc/musl/src/thread/x86_64/syscall_cp.s created+31
......@@ -0,0 +1,31 @@
1.text
2.global __cp_begin
3.hidden __cp_begin
4.global __cp_end
5.hidden __cp_end
6.global __cp_cancel
7.hidden __cp_cancel
8.hidden __cancel
9.global __syscall_cp_asm
10.hidden __syscall_cp_asm
11.type __syscall_cp_asm,@function
12__syscall_cp_asm:
13
14__cp_begin:
15 mov (%rdi),%eax
16 test %eax,%eax
17 jnz __cp_cancel
18 mov %rdi,%r11
19 mov %rsi,%rax
20 mov %rdx,%rdi
21 mov %rcx,%rsi
22 mov %r8,%rdx
23 mov %r9,%r10
24 mov 8(%rsp),%r8
25 mov 16(%rsp),%r9
26 mov %r11,8(%rsp)
27 syscall
28__cp_end:
29 ret
30__cp_cancel:
31 jmp __cancel
libc/musl/src/time/__map_file.c created+18
......@@ -0,0 +1,18 @@
1#include <sys/mman.h>
2#include <fcntl.h>
3#include <sys/stat.h>
4#include "syscall.h"
5
6const char unsigned *__map_file(const char *pathname, size_t *size)
7{
8 struct stat st;
9 const unsigned char *map = MAP_FAILED;
10 int fd = sys_open(pathname, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
11 if (fd < 0) return 0;
12 if (!syscall(SYS_fstat, fd, &st)) {
13 map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
14 *size = st.st_size;
15 }
16 __syscall(SYS_close, fd);
17 return map == MAP_FAILED ? 0 : map;
18}
libc/musl/src/time/__month_to_secs.c created+10
......@@ -0,0 +1,10 @@
1int __month_to_secs(int month, int is_leap)
2{
3 static const int secs_through_month[] = {
4 0, 31*86400, 59*86400, 90*86400,
5 120*86400, 151*86400, 181*86400, 212*86400,
6 243*86400, 273*86400, 304*86400, 334*86400 };
7 int t = secs_through_month[month];
8 if (is_leap && month >= 2) t+=86400;
9 return t;
10}
libc/musl/src/time/__secs_to_tm.c created+82
......@@ -0,0 +1,82 @@
1#include "time_impl.h"
2#include <limits.h>
3
4/* 2000-03-01 (mod 400 year, immediately after feb29 */
5#define LEAPOCH (946684800LL + 86400*(31+29))
6
7#define DAYS_PER_400Y (365*400 + 97)
8#define DAYS_PER_100Y (365*100 + 24)
9#define DAYS_PER_4Y (365*4 + 1)
10
11int __secs_to_tm(long long t, struct tm *tm)
12{
13 long long days, secs, years;
14 int remdays, remsecs, remyears;
15 int qc_cycles, c_cycles, q_cycles;
16 int months;
17 int wday, yday, leap;
18 static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
19
20 /* Reject time_t values whose year would overflow int */
21 if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
22 return -1;
23
24 secs = t - LEAPOCH;
25 days = secs / 86400;
26 remsecs = secs % 86400;
27 if (remsecs < 0) {
28 remsecs += 86400;
29 days--;
30 }
31
32 wday = (3+days)%7;
33 if (wday < 0) wday += 7;
34
35 qc_cycles = days / DAYS_PER_400Y;
36 remdays = days % DAYS_PER_400Y;
37 if (remdays < 0) {
38 remdays += DAYS_PER_400Y;
39 qc_cycles--;
40 }
41
42 c_cycles = remdays / DAYS_PER_100Y;
43 if (c_cycles == 4) c_cycles--;
44 remdays -= c_cycles * DAYS_PER_100Y;
45
46 q_cycles = remdays / DAYS_PER_4Y;
47 if (q_cycles == 25) q_cycles--;
48 remdays -= q_cycles * DAYS_PER_4Y;
49
50 remyears = remdays / 365;
51 if (remyears == 4) remyears--;
52 remdays -= remyears * 365;
53
54 leap = !remyears && (q_cycles || !c_cycles);
55 yday = remdays + 31 + 28 + leap;
56 if (yday >= 365+leap) yday -= 365+leap;
57
58 years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles;
59
60 for (months=0; days_in_month[months] <= remdays; months++)
61 remdays -= days_in_month[months];
62
63 if (months >= 10) {
64 months -= 12;
65 years++;
66 }
67
68 if (years+100 > INT_MAX || years+100 < INT_MIN)
69 return -1;
70
71 tm->tm_year = years + 100;
72 tm->tm_mon = months + 2;
73 tm->tm_mday = remdays + 1;
74 tm->tm_wday = wday;
75 tm->tm_yday = yday;
76
77 tm->tm_hour = remsecs / 3600;
78 tm->tm_min = remsecs / 60 % 60;
79 tm->tm_sec = remsecs % 60;
80
81 return 0;
82}
libc/musl/src/time/__tm_to_secs.c created+24
......@@ -0,0 +1,24 @@
1#include "time_impl.h"
2
3long long __tm_to_secs(const struct tm *tm)
4{
5 int is_leap;
6 long long year = tm->tm_year;
7 int month = tm->tm_mon;
8 if (month >= 12 || month < 0) {
9 int adj = month / 12;
10 month %= 12;
11 if (month < 0) {
12 adj--;
13 month += 12;
14 }
15 year += adj;
16 }
17 long long t = __year_to_secs(year, &is_leap);
18 t += __month_to_secs(month, is_leap);
19 t += 86400LL * (tm->tm_mday-1);
20 t += 3600LL * tm->tm_hour;
21 t += 60LL * tm->tm_min;
22 t += tm->tm_sec;
23 return t;
24}
libc/musl/src/time/__tz.c created+422
......@@ -0,0 +1,422 @@
1#include "time_impl.h"
2#include <stdint.h>
3#include <limits.h>
4#include <stdlib.h>
5#include <string.h>
6#include <sys/mman.h>
7#include "libc.h"
8#include "lock.h"
9
10long __timezone = 0;
11int __daylight = 0;
12char *__tzname[2] = { 0, 0 };
13
14weak_alias(__timezone, timezone);
15weak_alias(__daylight, daylight);
16weak_alias(__tzname, tzname);
17
18static char std_name[TZNAME_MAX+1];
19static char dst_name[TZNAME_MAX+1];
20const char __utc[] = "UTC";
21
22static int dst_off;
23static int r0[5], r1[5];
24
25static const unsigned char *zi, *trans, *index, *types, *abbrevs, *abbrevs_end;
26static size_t map_size;
27
28static char old_tz_buf[32];
29static char *old_tz = old_tz_buf;
30static size_t old_tz_size = sizeof old_tz_buf;
31
32static volatile int lock[1];
33
34static int getint(const char **p)
35{
36 unsigned x;
37 for (x=0; **p-'0'<10U; (*p)++) x = **p-'0' + 10*x;
38 return x;
39}
40
41static int getoff(const char **p)
42{
43 int neg = 0;
44 if (**p == '-') {
45 ++*p;
46 neg = 1;
47 } else if (**p == '+') {
48 ++*p;
49 }
50 int off = 3600*getint(p);
51 if (**p == ':') {
52 ++*p;
53 off += 60*getint(p);
54 if (**p == ':') {
55 ++*p;
56 off += getint(p);
57 }
58 }
59 return neg ? -off : off;
60}
61
62static void getrule(const char **p, int rule[5])
63{
64 int r = rule[0] = **p;
65
66 if (r!='M') {
67 if (r=='J') ++*p;
68 else rule[0] = 0;
69 rule[1] = getint(p);
70 } else {
71 ++*p; rule[1] = getint(p);
72 ++*p; rule[2] = getint(p);
73 ++*p; rule[3] = getint(p);
74 }
75
76 if (**p=='/') {
77 ++*p;
78 rule[4] = getoff(p);
79 } else {
80 rule[4] = 7200;
81 }
82}
83
84static void getname(char *d, const char **p)
85{
86 int i;
87 if (**p == '<') {
88 ++*p;
89 for (i=0; (*p)[i]!='>' && i<TZNAME_MAX; i++)
90 d[i] = (*p)[i];
91 ++*p;
92 } else {
93 for (i=0; ((*p)[i]|32)-'a'<26U && i<TZNAME_MAX; i++)
94 d[i] = (*p)[i];
95 }
96 *p += i;
97 d[i] = 0;
98}
99
100#define VEC(...) ((const unsigned char[]){__VA_ARGS__})
101
102static uint32_t zi_read32(const unsigned char *z)
103{
104 return (unsigned)z[0]<<24 | z[1]<<16 | z[2]<<8 | z[3];
105}
106
107static size_t zi_dotprod(const unsigned char *z, const unsigned char *v, size_t n)
108{
109 size_t y;
110 uint32_t x;
111 for (y=0; n; n--, z+=4, v++) {
112 x = zi_read32(z);
113 y += x * *v;
114 }
115 return y;
116}
117
118static void do_tzset()
119{
120 char buf[NAME_MAX+25], *pathname=buf+24;
121 const char *try, *s, *p;
122 const unsigned char *map = 0;
123 size_t i;
124 static const char search[] =
125 "/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
126
127 s = getenv("TZ");
128 if (!s) s = "/etc/localtime";
129 if (!*s) s = __utc;
130
131 if (old_tz && !strcmp(s, old_tz)) return;
132
133 for (i=0; i<5; i++) r0[i] = r1[i] = 0;
134
135 if (zi) __munmap((void *)zi, map_size);
136
137 /* Cache the old value of TZ to check if it has changed. Avoid
138 * free so as not to pull it into static programs. Growth
139 * strategy makes it so free would have minimal benefit anyway. */
140 i = strlen(s);
141 if (i > PATH_MAX+1) s = __utc, i = 3;
142 if (i >= old_tz_size) {
143 old_tz_size *= 2;
144 if (i >= old_tz_size) old_tz_size = i+1;
145 if (old_tz_size > PATH_MAX+2) old_tz_size = PATH_MAX+2;
146 old_tz = malloc(old_tz_size);
147 }
148 if (old_tz) memcpy(old_tz, s, i+1);
149
150 /* Non-suid can use an absolute tzfile pathname or a relative
151 * pathame beginning with "."; in secure mode, only the
152 * standard path will be searched. */
153 if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) {
154 if (*s == ':') s++;
155 if (*s == '/' || *s == '.') {
156 if (!libc.secure || !strcmp(s, "/etc/localtime"))
157 map = __map_file(s, &map_size);
158 } else {
159 size_t l = strlen(s);
160 if (l <= NAME_MAX && !strchr(s, '.')) {
161 memcpy(pathname, s, l+1);
162 pathname[l] = 0;
163 for (try=search; !map && *try; try+=l+1) {
164 l = strlen(try);
165 memcpy(pathname-l, try, l);
166 map = __map_file(pathname-l, &map_size);
167 }
168 }
169 }
170 if (!map) s = __utc;
171 }
172 if (map && (map_size < 44 || memcmp(map, "TZif", 4))) {
173 __munmap((void *)map, map_size);
174 map = 0;
175 s = __utc;
176 }
177
178 zi = map;
179 if (map) {
180 int scale = 2;
181 if (sizeof(time_t) > 4 && map[4]=='2') {
182 size_t skip = zi_dotprod(zi+20, VEC(1,1,8,5,6,1), 6);
183 trans = zi+skip+44+44;
184 scale++;
185 } else {
186 trans = zi+44;
187 }
188 index = trans + (zi_read32(trans-12) << scale);
189 types = index + zi_read32(trans-12);
190 abbrevs = types + 6*zi_read32(trans-8);
191 abbrevs_end = abbrevs + zi_read32(trans-4);
192 if (zi[map_size-1] == '\n') {
193 for (s = (const char *)zi+map_size-2; *s!='\n'; s--);
194 s++;
195 } else {
196 const unsigned char *p;
197 __tzname[0] = __tzname[1] = 0;
198 __daylight = __timezone = dst_off = 0;
199 for (p=types; p<abbrevs; p+=6) {
200 if (!p[4] && !__tzname[0]) {
201 __tzname[0] = (char *)abbrevs + p[5];
202 __timezone = -zi_read32(p);
203 }
204 if (p[4] && !__tzname[1]) {
205 __tzname[1] = (char *)abbrevs + p[5];
206 dst_off = -zi_read32(p);
207 __daylight = 1;
208 }
209 }
210 if (!__tzname[0]) __tzname[0] = __tzname[1];
211 if (!__tzname[0]) __tzname[0] = (char *)__utc;
212 if (!__daylight) {
213 __tzname[1] = __tzname[0];
214 dst_off = __timezone;
215 }
216 return;
217 }
218 }
219
220 if (!s) s = __utc;
221 getname(std_name, &s);
222 __tzname[0] = std_name;
223 __timezone = getoff(&s);
224 getname(dst_name, &s);
225 __tzname[1] = dst_name;
226 if (dst_name[0]) {
227 __daylight = 1;
228 if (*s == '+' || *s=='-' || *s-'0'<10U)
229 dst_off = getoff(&s);
230 else
231 dst_off = __timezone - 3600;
232 } else {
233 __daylight = 0;
234 dst_off = __timezone;
235 }
236
237 if (*s == ',') s++, getrule(&s, r0);
238 if (*s == ',') s++, getrule(&s, r1);
239}
240
241/* Search zoneinfo rules to find the one that applies to the given time,
242 * and determine alternate opposite-DST-status rule that may be needed. */
243
244static size_t scan_trans(long long t, int local, size_t *alt)
245{
246 int scale = 3 - (trans == zi+44);
247 uint64_t x;
248 int off = 0;
249
250 size_t a = 0, n = (index-trans)>>scale, m;
251
252 if (!n) {
253 if (alt) *alt = 0;
254 return 0;
255 }
256
257 /* Binary search for 'most-recent rule before t'. */
258 while (n > 1) {
259 m = a + n/2;
260 x = zi_read32(trans + (m<<scale));
261 if (scale == 3) x = x<<32 | zi_read32(trans + (m<<scale) + 4);
262 else x = (int32_t)x;
263 if (local) off = (int32_t)zi_read32(types + 6 * index[m-1]);
264 if (t - off < (int64_t)x) {
265 n /= 2;
266 } else {
267 a = m;
268 n -= n/2;
269 }
270 }
271
272 /* First and last entry are special. First means to use lowest-index
273 * non-DST type. Last means to apply POSIX-style rule if available. */
274 n = (index-trans)>>scale;
275 if (a == n-1) return -1;
276 if (a == 0) {
277 x = zi_read32(trans + (a<<scale));
278 if (scale == 3) x = x<<32 | zi_read32(trans + (a<<scale) + 4);
279 else x = (int32_t)x;
280 if (local) off = (int32_t)zi_read32(types + 6 * index[a-1]);
281 if (t - off < (int64_t)x) {
282 for (a=0; a<(abbrevs-types)/6; a++) {
283 if (types[6*a+4] != types[4]) break;
284 }
285 if (a == (abbrevs-types)/6) a = 0;
286 if (types[6*a+4]) {
287 *alt = a;
288 return 0;
289 } else {
290 *alt = 0;
291 return a;
292 }
293 }
294 }
295
296 /* Try to find a neighboring opposite-DST-status rule. */
297 if (alt) {
298 if (a && types[6*index[a-1]+4] != types[6*index[a]+4])
299 *alt = index[a-1];
300 else if (a+1<n && types[6*index[a+1]+4] != types[6*index[a]+4])
301 *alt = index[a+1];
302 else
303 *alt = index[a];
304 }
305
306 return index[a];
307}
308
309static int days_in_month(int m, int is_leap)
310{
311 if (m==2) return 28+is_leap;
312 else return 30+((0xad5>>(m-1))&1);
313}
314
315/* Convert a POSIX DST rule plus year to seconds since epoch. */
316
317static long long rule_to_secs(const int *rule, int year)
318{
319 int is_leap;
320 long long t = __year_to_secs(year, &is_leap);
321 int x, m, n, d;
322 if (rule[0]!='M') {
323 x = rule[1];
324 if (rule[0]=='J' && (x < 60 || !is_leap)) x--;
325 t += 86400 * x;
326 } else {
327 m = rule[1];
328 n = rule[2];
329 d = rule[3];
330 t += __month_to_secs(m-1, is_leap);
331 int wday = (int)((t + 4*86400) % (7*86400)) / 86400;
332 int days = d - wday;
333 if (days < 0) days += 7;
334 if (n == 5 && days+28 >= days_in_month(m, is_leap)) n = 4;
335 t += 86400 * (days + 7*(n-1));
336 }
337 t += rule[4];
338 return t;
339}
340
341/* Determine the time zone in effect for a given time in seconds since the
342 * epoch. It can be given in local or universal time. The results will
343 * indicate whether DST is in effect at the queried time, and will give both
344 * the GMT offset for the active zone/DST rule and the opposite DST. This
345 * enables a caller to efficiently adjust for the case where an explicit
346 * DST specification mismatches what would be in effect at the time. */
347
348void __secs_to_zone(long long t, int local, int *isdst, long *offset, long *oppoff, const char **zonename)
349{
350 LOCK(lock);
351
352 do_tzset();
353
354 if (zi) {
355 size_t alt, i = scan_trans(t, local, &alt);
356 if (i != -1) {
357 *isdst = types[6*i+4];
358 *offset = (int32_t)zi_read32(types+6*i);
359 *zonename = (const char *)abbrevs + types[6*i+5];
360 if (oppoff) *oppoff = (int32_t)zi_read32(types+6*alt);
361 UNLOCK(lock);
362 return;
363 }
364 }
365
366 if (!__daylight) goto std;
367
368 /* FIXME: may be broken if DST changes right at year boundary?
369 * Also, this could be more efficient.*/
370 long long y = t / 31556952 + 70;
371 while (__year_to_secs(y, 0) > t) y--;
372 while (__year_to_secs(y+1, 0) < t) y++;
373
374 long long t0 = rule_to_secs(r0, y);
375 long long t1 = rule_to_secs(r1, y);
376
377 if (!local) {
378 t0 += __timezone;
379 t1 += dst_off;
380 }
381 if (t0 < t1) {
382 if (t >= t0 && t < t1) goto dst;
383 goto std;
384 } else {
385 if (t >= t1 && t < t0) goto std;
386 goto dst;
387 }
388std:
389 *isdst = 0;
390 *offset = -__timezone;
391 if (oppoff) *oppoff = -dst_off;
392 *zonename = __tzname[0];
393 UNLOCK(lock);
394 return;
395dst:
396 *isdst = 1;
397 *offset = -dst_off;
398 if (oppoff) *oppoff = -__timezone;
399 *zonename = __tzname[1];
400 UNLOCK(lock);
401}
402
403static void __tzset()
404{
405 LOCK(lock);
406 do_tzset();
407 UNLOCK(lock);
408}
409
410weak_alias(__tzset, tzset);
411
412const char *__tm_to_tzname(const struct tm *tm)
413{
414 const void *p = tm->__tm_zone;
415 LOCK(lock);
416 do_tzset();
417 if (p != __utc && p != __tzname[0] && p != __tzname[1] &&
418 (!zi || (uintptr_t)p-(uintptr_t)abbrevs >= abbrevs_end - abbrevs))
419 p = "";
420 UNLOCK(lock);
421 return p;
422}
libc/musl/src/time/__year_to_secs.c created+47
......@@ -0,0 +1,47 @@
1long long __year_to_secs(long long year, int *is_leap)
2{
3 if (year-2ULL <= 136) {
4 int y = year;
5 int leaps = (y-68)>>2;
6 if (!((y-68)&3)) {
7 leaps--;
8 if (is_leap) *is_leap = 1;
9 } else if (is_leap) *is_leap = 0;
10 return 31536000*(y-70) + 86400*leaps;
11 }
12
13 int cycles, centuries, leaps, rem;
14
15 if (!is_leap) is_leap = &(int){0};
16 cycles = (year-100) / 400;
17 rem = (year-100) % 400;
18 if (rem < 0) {
19 cycles--;
20 rem += 400;
21 }
22 if (!rem) {
23 *is_leap = 1;
24 centuries = 0;
25 leaps = 0;
26 } else {
27 if (rem >= 200) {
28 if (rem >= 300) centuries = 3, rem -= 300;
29 else centuries = 2, rem -= 200;
30 } else {
31 if (rem >= 100) centuries = 1, rem -= 100;
32 else centuries = 0;
33 }
34 if (!rem) {
35 *is_leap = 0;
36 leaps = 0;
37 } else {
38 leaps = rem / 4U;
39 rem %= 4U;
40 *is_leap = !rem;
41 }
42 }
43
44 leaps += 97*cycles + 24*centuries - *is_leap;
45
46 return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
47}
libc/musl/src/time/asctime.c created+7
......@@ -0,0 +1,7 @@
1#include <time.h>
2
3char *asctime(const struct tm *tm)
4{
5 static char buf[26];
6 return __asctime_r(tm, buf);
7}
libc/musl/src/time/asctime_r.c created+28
......@@ -0,0 +1,28 @@
1#include <time.h>
2#include <stdio.h>
3#include <langinfo.h>
4#include "locale_impl.h"
5#include "atomic.h"
6
7char *__asctime_r(const struct tm *restrict tm, char *restrict buf)
8{
9 if (snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
10 __nl_langinfo_l(ABDAY_1+tm->tm_wday, C_LOCALE),
11 __nl_langinfo_l(ABMON_1+tm->tm_mon, C_LOCALE),
12 tm->tm_mday, tm->tm_hour,
13 tm->tm_min, tm->tm_sec,
14 1900 + tm->tm_year) >= 26)
15 {
16 /* ISO C requires us to use the above format string,
17 * even if it will not fit in the buffer. Thus asctime_r
18 * is _supposed_ to crash if the fields in tm are too large.
19 * We follow this behavior and crash "gracefully" to warn
20 * application developers that they may not be so lucky
21 * on other implementations (e.g. stack smashing..).
22 */
23 a_crash();
24 }
25 return buf;
26}
27
28weak_alias(__asctime_r, asctime_r);
libc/musl/src/time/clock.c created+16
......@@ -0,0 +1,16 @@
1#include <time.h>
2#include <limits.h>
3
4clock_t clock()
5{
6 struct timespec ts;
7
8 if (__clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts))
9 return -1;
10
11 if (ts.tv_sec > LONG_MAX/1000000
12 || ts.tv_nsec/1000 > LONG_MAX-1000000*ts.tv_sec)
13 return -1;
14
15 return ts.tv_sec*1000000 + ts.tv_nsec/1000;
16}
libc/musl/src/time/clock_getcpuclockid.c created+14
......@@ -0,0 +1,14 @@
1#include <time.h>
2#include <errno.h>
3#include <unistd.h>
4#include "syscall.h"
5
6int clock_getcpuclockid(pid_t pid, clockid_t *clk)
7{
8 struct timespec ts;
9 clockid_t id = (-pid-1)*8U + 2;
10 int ret = __syscall(SYS_clock_getres, id, &ts);
11 if (ret) return -ret;
12 *clk = id;
13 return 0;
14}
libc/musl/src/time/clock_getres.c created+7
......@@ -0,0 +1,7 @@
1#include <time.h>
2#include "syscall.h"
3
4int clock_getres(clockid_t clk, struct timespec *ts)
5{
6 return syscall(SYS_clock_getres, clk, ts);
7}
libc/musl/src/time/clock_gettime.c created+55
......@@ -0,0 +1,55 @@
1#include <time.h>
2#include <errno.h>
3#include <stdint.h>
4#include "syscall.h"
5#include "atomic.h"
6
7#ifdef VDSO_CGT_SYM
8
9static void *volatile vdso_func;
10
11static int cgt_init(clockid_t clk, struct timespec *ts)
12{
13 void *p = __vdsosym(VDSO_CGT_VER, VDSO_CGT_SYM);
14 int (*f)(clockid_t, struct timespec *) =
15 (int (*)(clockid_t, struct timespec *))p;
16 a_cas_p(&vdso_func, (void *)cgt_init, p);
17 return f ? f(clk, ts) : -ENOSYS;
18}
19
20static void *volatile vdso_func = (void *)cgt_init;
21
22#endif
23
24int __clock_gettime(clockid_t clk, struct timespec *ts)
25{
26 int r;
27
28#ifdef VDSO_CGT_SYM
29 int (*f)(clockid_t, struct timespec *) =
30 (int (*)(clockid_t, struct timespec *))vdso_func;
31 if (f) {
32 r = f(clk, ts);
33 if (!r) return r;
34 if (r == -EINVAL) return __syscall_ret(r);
35 /* Fall through on errors other than EINVAL. Some buggy
36 * vdso implementations return ENOSYS for clocks they
37 * can't handle, rather than making the syscall. This
38 * also handles the case where cgt_init fails to find
39 * a vdso function to use. */
40 }
41#endif
42
43 r = __syscall(SYS_clock_gettime, clk, ts);
44 if (r == -ENOSYS) {
45 if (clk == CLOCK_REALTIME) {
46 __syscall(SYS_gettimeofday, ts, 0);
47 ts->tv_nsec = (int)ts->tv_nsec * 1000;
48 return 0;
49 }
50 r = -EINVAL;
51 }
52 return __syscall_ret(r);
53}
54
55weak_alias(__clock_gettime, clock_gettime);
libc/musl/src/time/clock_nanosleep.c created+9
......@@ -0,0 +1,9 @@
1#include <time.h>
2#include <errno.h>
3#include "syscall.h"
4
5int clock_nanosleep(clockid_t clk, int flags, const struct timespec *req, struct timespec *rem)
6{
7 int r = -__syscall_cp(SYS_clock_nanosleep, clk, flags, req, rem);
8 return clk == CLOCK_THREAD_CPUTIME_ID ? EINVAL : r;
9}
libc/musl/src/time/clock_settime.c created+7
......@@ -0,0 +1,7 @@
1#include <time.h>
2#include "syscall.h"
3
4int clock_settime(clockid_t clk, const struct timespec *ts)
5{
6 return syscall(SYS_clock_settime, clk, ts);
7}
libc/musl/src/time/ctime.c created+8
......@@ -0,0 +1,8 @@
1#include <time.h>
2
3char *ctime(const time_t *t)
4{
5 struct tm *tm = localtime(t);
6 if (!tm) return 0;
7 return asctime(tm);
8}
libc/musl/src/time/ctime_r.c created+7
......@@ -0,0 +1,7 @@
1#include <time.h>
2
3char *ctime_r(const time_t *t, char *buf)
4{
5 struct tm tm, *tm_p = localtime_r(t, &tm);
6 return tm_p ? asctime_r(tm_p, buf) : 0;
7}
libc/musl/src/time/difftime.c created+6
......@@ -0,0 +1,6 @@
1#include <time.h>
2
3double difftime(time_t t1, time_t t0)
4{
5 return t1-t0;
6}
libc/musl/src/time/ftime.c created+12
......@@ -0,0 +1,12 @@
1#include <sys/timeb.h>
2#include <time.h>
3
4int ftime(struct timeb *tp)
5{
6 struct timespec ts;
7 clock_gettime(CLOCK_REALTIME, &ts);
8 tp->time = ts.tv_sec;
9 tp->millitm = ts.tv_nsec / 1000000;
10 tp->timezone = tp->dstflag = 0;
11 return 0;
12}
libc/musl/src/time/getdate.c created+46
......@@ -0,0 +1,46 @@
1#include <time.h>
2#include <pthread.h>
3#include <errno.h>
4#include <stdio.h>
5#include <stdlib.h>
6
7int getdate_err;
8
9struct tm *getdate(const char *s)
10{
11 static struct tm tmbuf;
12 struct tm *ret = 0;
13 char *datemsk = getenv("DATEMSK");
14 FILE *f = 0;
15 char fmt[100], *p;
16 int cs;
17
18 pthread_setcancelstate(PTHREAD_CANCEL_DEFERRED, &cs);
19
20 if (!datemsk) {
21 getdate_err = 1;
22 goto out;
23 }
24
25 f = fopen(datemsk, "rbe");
26 if (!f) {
27 if (errno == ENOMEM) getdate_err = 6;
28 else getdate_err = 2;
29 goto out;
30 }
31
32 while (fgets(fmt, sizeof fmt, f)) {
33 p = strptime(s, fmt, &tmbuf);
34 if (p && !*p) {
35 ret = &tmbuf;
36 goto out;
37 }
38 }
39
40 if (ferror(f)) getdate_err = 5;
41 else getdate_err = 7;
42out:
43 if (f) fclose(f);
44 pthread_setcancelstate(cs, 0);
45 return ret;
46}
libc/musl/src/time/gettimeofday.c created+13
......@@ -0,0 +1,13 @@
1#include <time.h>
2#include <sys/time.h>
3#include "syscall.h"
4
5int gettimeofday(struct timeval *restrict tv, void *restrict tz)
6{
7 struct timespec ts;
8 if (!tv) return 0;
9 clock_gettime(CLOCK_REALTIME, &ts);
10 tv->tv_sec = ts.tv_sec;
11 tv->tv_usec = (int)ts.tv_nsec / 1000;
12 return 0;
13}
libc/musl/src/time/gmtime.c created+8
......@@ -0,0 +1,8 @@
1#include "time_impl.h"
2#include <errno.h>
3
4struct tm *gmtime(const time_t *t)
5{
6 static struct tm tm;
7 return __gmtime_r(t, &tm);
8}
libc/musl/src/time/gmtime_r.c created+16
......@@ -0,0 +1,16 @@
1#include "time_impl.h"
2#include <errno.h>
3
4struct tm *__gmtime_r(const time_t *restrict t, struct tm *restrict tm)
5{
6 if (__secs_to_tm(*t, tm) < 0) {
7 errno = EOVERFLOW;
8 return 0;
9 }
10 tm->tm_isdst = 0;
11 tm->__tm_gmtoff = 0;
12 tm->__tm_zone = __utc;
13 return tm;
14}
15
16weak_alias(__gmtime_r, gmtime_r);
libc/musl/src/time/localtime.c created+7
......@@ -0,0 +1,7 @@
1#include "time_impl.h"
2
3struct tm *localtime(const time_t *t)
4{
5 static struct tm tm;
6 return __localtime_r(t, &tm);
7}
libc/musl/src/time/localtime_r.c created+21
......@@ -0,0 +1,21 @@
1#include "time_impl.h"
2#include <errno.h>
3#include <limits.h>
4
5struct tm *__localtime_r(const time_t *restrict t, struct tm *restrict tm)
6{
7 /* Reject time_t values whose year would overflow int because
8 * __secs_to_zone cannot safely handle them. */
9 if (*t < INT_MIN * 31622400LL || *t > INT_MAX * 31622400LL) {
10 errno = EOVERFLOW;
11 return 0;
12 }
13 __secs_to_zone(*t, 0, &tm->tm_isdst, &tm->__tm_gmtoff, 0, &tm->__tm_zone);
14 if (__secs_to_tm((long long)*t + tm->__tm_gmtoff, tm) < 0) {
15 errno = EOVERFLOW;
16 return 0;
17 }
18 return tm;
19}
20
21weak_alias(__localtime_r, localtime_r);
libc/musl/src/time/mktime.c created+28
......@@ -0,0 +1,28 @@
1#include "time_impl.h"
2#include <errno.h>
3
4time_t mktime(struct tm *tm)
5{
6 struct tm new;
7 long opp;
8 long long t = __tm_to_secs(tm);
9
10 __secs_to_zone(t, 1, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
11
12 if (tm->tm_isdst>=0 && new.tm_isdst!=tm->tm_isdst)
13 t -= opp - new.__tm_gmtoff;
14
15 t -= new.__tm_gmtoff;
16 if ((time_t)t != t) goto error;
17
18 __secs_to_zone(t, 0, &new.tm_isdst, &new.__tm_gmtoff, &opp, &new.__tm_zone);
19
20 if (__secs_to_tm(t + new.__tm_gmtoff, &new) < 0) goto error;
21
22 *tm = new;
23 return t;
24
25error:
26 errno = EOVERFLOW;
27 return -1;
28}
libc/musl/src/time/nanosleep.c created+7
......@@ -0,0 +1,7 @@
1#include <time.h>
2#include "syscall.h"
3
4int nanosleep(const struct timespec *req, struct timespec *rem)
5{
6 return syscall_cp(SYS_nanosleep, req, rem);
7}
libc/musl/src/time/strftime.c created+281
......@@ -0,0 +1,281 @@
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <langinfo.h>
5#include <locale.h>
6#include <time.h>
7#include <limits.h>
8#include "locale_impl.h"
9#include "time_impl.h"
10
11static int is_leap(int y)
12{
13 /* Avoid overflow */
14 if (y>INT_MAX-1900) y -= 2000;
15 y += 1900;
16 return !(y%4) && ((y%100) || !(y%400));
17}
18
19static int week_num(const struct tm *tm)
20{
21 int val = (tm->tm_yday + 7U - (tm->tm_wday+6U)%7) / 7;
22 /* If 1 Jan is just 1-3 days past Monday,
23 * the previous week is also in this year. */
24 if ((tm->tm_wday + 371U - tm->tm_yday - 2) % 7 <= 2)
25 val++;
26 if (!val) {
27 val = 52;
28 /* If 31 December of prev year a Thursday,
29 * or Friday of a leap year, then the
30 * prev year has 53 weeks. */
31 int dec31 = (tm->tm_wday + 7U - tm->tm_yday - 1) % 7;
32 if (dec31 == 4 || (dec31 == 5 && is_leap(tm->tm_year%400-1)))
33 val++;
34 } else if (val == 53) {
35 /* If 1 January is not a Thursday, and not
36 * a Wednesday of a leap year, then this
37 * year has only 52 weeks. */
38 int jan1 = (tm->tm_wday + 371U - tm->tm_yday) % 7;
39 if (jan1 != 4 && (jan1 != 3 || !is_leap(tm->tm_year)))
40 val = 1;
41 }
42 return val;
43}
44
45const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc, int pad)
46{
47 nl_item item;
48 long long val;
49 const char *fmt = "-";
50 int width = 2, def_pad = '0';
51
52 switch (f) {
53 case 'a':
54 if (tm->tm_wday > 6U) goto string;
55 item = ABDAY_1 + tm->tm_wday;
56 goto nl_strcat;
57 case 'A':
58 if (tm->tm_wday > 6U) goto string;
59 item = DAY_1 + tm->tm_wday;
60 goto nl_strcat;
61 case 'h':
62 case 'b':
63 if (tm->tm_mon > 11U) goto string;
64 item = ABMON_1 + tm->tm_mon;
65 goto nl_strcat;
66 case 'B':
67 if (tm->tm_mon > 11U) goto string;
68 item = MON_1 + tm->tm_mon;
69 goto nl_strcat;
70 case 'c':
71 item = D_T_FMT;
72 goto nl_strftime;
73 case 'C':
74 val = (1900LL+tm->tm_year) / 100;
75 goto number;
76 case 'e':
77 def_pad = '_';
78 case 'd':
79 val = tm->tm_mday;
80 goto number;
81 case 'D':
82 fmt = "%m/%d/%y";
83 goto recu_strftime;
84 case 'F':
85 fmt = "%Y-%m-%d";
86 goto recu_strftime;
87 case 'g':
88 case 'G':
89 val = tm->tm_year + 1900LL;
90 if (tm->tm_yday < 3 && week_num(tm) != 1) val--;
91 else if (tm->tm_yday > 360 && week_num(tm) == 1) val++;
92 if (f=='g') val %= 100;
93 else width = 4;
94 goto number;
95 case 'H':
96 val = tm->tm_hour;
97 goto number;
98 case 'I':
99 val = tm->tm_hour;
100 if (!val) val = 12;
101 else if (val > 12) val -= 12;
102 goto number;
103 case 'j':
104 val = tm->tm_yday+1;
105 width = 3;
106 goto number;
107 case 'm':
108 val = tm->tm_mon+1;
109 goto number;
110 case 'M':
111 val = tm->tm_min;
112 goto number;
113 case 'n':
114 *l = 1;
115 return "\n";
116 case 'p':
117 item = tm->tm_hour >= 12 ? PM_STR : AM_STR;
118 goto nl_strcat;
119 case 'r':
120 item = T_FMT_AMPM;
121 goto nl_strftime;
122 case 'R':
123 fmt = "%H:%M";
124 goto recu_strftime;
125 case 's':
126 val = __tm_to_secs(tm) - tm->__tm_gmtoff;
127 width = 1;
128 goto number;
129 case 'S':
130 val = tm->tm_sec;
131 goto number;
132 case 't':
133 *l = 1;
134 return "\t";
135 case 'T':
136 fmt = "%H:%M:%S";
137 goto recu_strftime;
138 case 'u':
139 val = tm->tm_wday ? tm->tm_wday : 7;
140 width = 1;
141 goto number;
142 case 'U':
143 val = (tm->tm_yday + 7U - tm->tm_wday) / 7;
144 goto number;
145 case 'W':
146 val = (tm->tm_yday + 7U - (tm->tm_wday+6U)%7) / 7;
147 goto number;
148 case 'V':
149 val = week_num(tm);
150 goto number;
151 case 'w':
152 val = tm->tm_wday;
153 width = 1;
154 goto number;
155 case 'x':
156 item = D_FMT;
157 goto nl_strftime;
158 case 'X':
159 item = T_FMT;
160 goto nl_strftime;
161 case 'y':
162 val = (tm->tm_year + 1900LL) % 100;
163 if (val < 0) val = -val;
164 goto number;
165 case 'Y':
166 val = tm->tm_year + 1900LL;
167 if (val >= 10000) {
168 *l = snprintf(*s, sizeof *s, "+%lld", val);
169 return *s;
170 }
171 width = 4;
172 goto number;
173 case 'z':
174 if (tm->tm_isdst < 0) {
175 *l = 0;
176 return "";
177 }
178 *l = snprintf(*s, sizeof *s, "%+.4ld",
179 tm->__tm_gmtoff/3600*100 + tm->__tm_gmtoff%3600/60);
180 return *s;
181 case 'Z':
182 if (tm->tm_isdst < 0) {
183 *l = 0;
184 return "";
185 }
186 fmt = __tm_to_tzname(tm);
187 goto string;
188 case '%':
189 *l = 1;
190 return "%";
191 default:
192 return 0;
193 }
194number:
195 switch (pad ? pad : def_pad) {
196 case '-': *l = snprintf(*s, sizeof *s, "%lld", val); break;
197 case '_': *l = snprintf(*s, sizeof *s, "%*lld", width, val); break;
198 case '0':
199 default: *l = snprintf(*s, sizeof *s, "%0*lld", width, val); break;
200 }
201 return *s;
202nl_strcat:
203 fmt = __nl_langinfo_l(item, loc);
204string:
205 *l = strlen(fmt);
206 return fmt;
207nl_strftime:
208 fmt = __nl_langinfo_l(item, loc);
209recu_strftime:
210 *l = __strftime_l(*s, sizeof *s, fmt, tm, loc);
211 if (!*l) return 0;
212 return *s;
213}
214
215size_t __strftime_l(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm, locale_t loc)
216{
217 size_t l, k;
218 char buf[100];
219 char *p;
220 const char *t;
221 int pad, plus;
222 unsigned long width;
223 for (l=0; l<n; f++) {
224 if (!*f) {
225 s[l] = 0;
226 return l;
227 }
228 if (*f != '%') {
229 s[l++] = *f;
230 continue;
231 }
232 f++;
233 pad = 0;
234 if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
235 if ((plus = (*f == '+'))) f++;
236 width = strtoul(f, &p, 10);
237 if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
238 if (!width && p!=f) width = 1;
239 } else {
240 width = 0;
241 }
242 f = p;
243 if (*f == 'E' || *f == 'O') f++;
244 t = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad);
245 if (!t) break;
246 if (width) {
247 /* Trim off any sign and leading zeros, then
248 * count remaining digits to determine behavior
249 * for the + flag. */
250 if (*t=='+' || *t=='-') t++, k--;
251 for (; *t=='0' && t[1]-'0'<10U; t++, k--);
252 if (width < k) width = k;
253 size_t d;
254 for (d=0; t[d]-'0'<10U; d++);
255 if (tm->tm_year < -1900) {
256 s[l++] = '-';
257 width--;
258 } else if (plus && d+(width-k) >= (*p=='C'?3:5)) {
259 s[l++] = '+';
260 width--;
261 }
262 for (; width > k && l < n; width--)
263 s[l++] = '0';
264 }
265 if (k > n-l) k = n-l;
266 memcpy(s+l, t, k);
267 l += k;
268 }
269 if (n) {
270 if (l==n) l=n-1;
271 s[l] = 0;
272 }
273 return 0;
274}
275
276size_t strftime(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm)
277{
278 return __strftime_l(s, n, f, tm, CURRENT_LOCALE);
279}
280
281weak_alias(__strftime_l, strftime_l);
libc/musl/src/time/strptime.c created+206
......@@ -0,0 +1,206 @@
1#include <stdlib.h>
2#include <langinfo.h>
3#include <time.h>
4#include <ctype.h>
5#include <stddef.h>
6#include <string.h>
7#include <strings.h>
8
9char *strptime(const char *restrict s, const char *restrict f, struct tm *restrict tm)
10{
11 int i, w, neg, adj, min, range, *dest, dummy;
12 const char *ex;
13 size_t len;
14 int want_century = 0, century = 0, relyear = 0;
15 while (*f) {
16 if (*f != '%') {
17 if (isspace(*f)) for (; *s && isspace(*s); s++);
18 else if (*s != *f) return 0;
19 else s++;
20 f++;
21 continue;
22 }
23 f++;
24 if (*f == '+') f++;
25 if (isdigit(*f)) {
26 char *new_f;
27 w=strtoul(f, &new_f, 10);
28 f = new_f;
29 } else {
30 w=-1;
31 }
32 adj=0;
33 switch (*f++) {
34 case 'a': case 'A':
35 dest = &tm->tm_wday;
36 min = ABDAY_1;
37 range = 7;
38 goto symbolic_range;
39 case 'b': case 'B': case 'h':
40 dest = &tm->tm_mon;
41 min = ABMON_1;
42 range = 12;
43 goto symbolic_range;
44 case 'c':
45 s = strptime(s, nl_langinfo(D_T_FMT), tm);
46 if (!s) return 0;
47 break;
48 case 'C':
49 dest = &century;
50 if (w<0) w=2;
51 want_century |= 2;
52 goto numeric_digits;
53 case 'd': case 'e':
54 dest = &tm->tm_mday;
55 min = 1;
56 range = 31;
57 goto numeric_range;
58 case 'D':
59 s = strptime(s, "%m/%d/%y", tm);
60 if (!s) return 0;
61 break;
62 case 'H':
63 dest = &tm->tm_hour;
64 min = 0;
65 range = 24;
66 goto numeric_range;
67 case 'I':
68 dest = &tm->tm_hour;
69 min = 1;
70 range = 12;
71 goto numeric_range;
72 case 'j':
73 dest = &tm->tm_yday;
74 min = 1;
75 range = 366;
76 adj = 1;
77 goto numeric_range;
78 case 'm':
79 dest = &tm->tm_mon;
80 min = 1;
81 range = 12;
82 adj = 1;
83 goto numeric_range;
84 case 'M':
85 dest = &tm->tm_min;
86 min = 0;
87 range = 60;
88 goto numeric_range;
89 case 'n': case 't':
90 for (; *s && isspace(*s); s++);
91 break;
92 case 'p':
93 ex = nl_langinfo(AM_STR);
94 len = strlen(ex);
95 if (!strncasecmp(s, ex, len)) {
96 tm->tm_hour %= 12;
97 s += len;
98 break;
99 }
100 ex = nl_langinfo(PM_STR);
101 len = strlen(ex);
102 if (!strncasecmp(s, ex, len)) {
103 tm->tm_hour %= 12;
104 tm->tm_hour += 12;
105 s += len;
106 break;
107 }
108 return 0;
109 case 'r':
110 s = strptime(s, nl_langinfo(T_FMT_AMPM), tm);
111 if (!s) return 0;
112 break;
113 case 'R':
114 s = strptime(s, "%H:%M", tm);
115 if (!s) return 0;
116 break;
117 case 'S':
118 dest = &tm->tm_sec;
119 min = 0;
120 range = 61;
121 goto numeric_range;
122 case 'T':
123 s = strptime(s, "%H:%M:%S", tm);
124 if (!s) return 0;
125 break;
126 case 'U':
127 case 'W':
128 /* Throw away result, for now. (FIXME?) */
129 dest = &dummy;
130 min = 0;
131 range = 54;
132 goto numeric_range;
133 case 'w':
134 dest = &tm->tm_wday;
135 min = 0;
136 range = 7;
137 goto numeric_range;
138 case 'x':
139 s = strptime(s, nl_langinfo(D_FMT), tm);
140 if (!s) return 0;
141 break;
142 case 'X':
143 s = strptime(s, nl_langinfo(T_FMT), tm);
144 if (!s) return 0;
145 break;
146 case 'y':
147 dest = &relyear;
148 w = 2;
149 want_century |= 1;
150 goto numeric_digits;
151 case 'Y':
152 dest = &tm->tm_year;
153 if (w<0) w=4;
154 adj = 1900;
155 want_century = 0;
156 goto numeric_digits;
157 case '%':
158 if (*s++ != '%') return 0;
159 break;
160 default:
161 return 0;
162 numeric_range:
163 if (!isdigit(*s)) return 0;
164 *dest = 0;
165 for (i=1; i<=min+range && isdigit(*s); i*=10)
166 *dest = *dest * 10 + *s++ - '0';
167 if (*dest - min >= (unsigned)range) return 0;
168 *dest -= adj;
169 switch((char *)dest - (char *)tm) {
170 case offsetof(struct tm, tm_yday):
171 ;
172 }
173 goto update;
174 numeric_digits:
175 neg = 0;
176 if (*s == '+') s++;
177 else if (*s == '-') neg=1, s++;
178 if (!isdigit(*s)) return 0;
179 for (*dest=i=0; i<w && isdigit(*s); i++)
180 *dest = *dest * 10 + *s++ - '0';
181 if (neg) *dest = -*dest;
182 *dest -= adj;
183 goto update;
184 symbolic_range:
185 for (i=2*range-1; i>=0; i--) {
186 ex = nl_langinfo(min+i);
187 len = strlen(ex);
188 if (strncasecmp(s, ex, len)) continue;
189 s += len;
190 *dest = i % range;
191 break;
192 }
193 if (i<0) return 0;
194 goto update;
195 update:
196 //FIXME
197 ;
198 }
199 }
200 if (want_century) {
201 tm->tm_year = relyear;
202 if (want_century & 2) tm->tm_year += century * 100 - 1900;
203 else if (tm->tm_year <= 68) tm->tm_year += 100;
204 }
205 return (char *)s;
206}
libc/musl/src/time/time.c created+10
......@@ -0,0 +1,10 @@
1#include <time.h>
2#include "syscall.h"
3
4time_t time(time_t *t)
5{
6 struct timespec ts;
7 __clock_gettime(CLOCK_REALTIME, &ts);
8 if (t) *t = ts.tv_sec;
9 return ts.tv_sec;
10}
libc/musl/src/time/time_impl.h created+11
......@@ -0,0 +1,11 @@
1#include <time.h>
2
3hidden int __days_in_month(int, int);
4hidden int __month_to_secs(int, int);
5hidden long long __year_to_secs(long long, int *);
6hidden long long __tm_to_secs(const struct tm *);
7hidden const char *__tm_to_tzname(const struct tm *);
8hidden int __secs_to_tm(long long, struct tm *);
9hidden void __secs_to_zone(long long, int, int *, long *, long *, const char **);
10hidden const char *__strftime_fmt_1(char (*)[100], size_t *, int, const struct tm *, locale_t, int);
11extern hidden const char __utc[];
libc/musl/src/time/timegm.c created+18
......@@ -0,0 +1,18 @@
1#define _GNU_SOURCE
2#include "time_impl.h"
3#include <errno.h>
4
5time_t timegm(struct tm *tm)
6{
7 struct tm new;
8 long long t = __tm_to_secs(tm);
9 if (__secs_to_tm(t, &new) < 0) {
10 errno = EOVERFLOW;
11 return -1;
12 }
13 *tm = new;
14 tm->tm_isdst = 0;
15 tm->__tm_gmtoff = 0;
16 tm->__tm_zone = __utc;
17 return t;
18}
libc/musl/src/time/timer_create.c created+139
......@@ -0,0 +1,139 @@
1#include <time.h>
2#include <setjmp.h>
3#include "pthread_impl.h"
4
5struct ksigevent {
6 union sigval sigev_value;
7 int sigev_signo;
8 int sigev_notify;
9 int sigev_tid;
10};
11
12struct start_args {
13 pthread_barrier_t b;
14 struct sigevent *sev;
15};
16
17static void dummy_0()
18{
19}
20weak_alias(dummy_0, __pthread_tsd_run_dtors);
21
22static void cleanup_fromsig(void *p)
23{
24 pthread_t self = __pthread_self();
25 __pthread_tsd_run_dtors();
26 self->cancel = 0;
27 self->cancelbuf = 0;
28 self->canceldisable = 0;
29 self->cancelasync = 0;
30 self->unblock_cancel = 0;
31 __reset_tls();
32 longjmp(p, 1);
33}
34
35static void timer_handler(int sig, siginfo_t *si, void *ctx)
36{
37 pthread_t self = __pthread_self();
38 jmp_buf jb;
39 void (*notify)(union sigval) = (void (*)(union sigval))self->start;
40 union sigval val = { .sival_ptr = self->start_arg };
41
42 if (!setjmp(jb) && si->si_code == SI_TIMER) {
43 pthread_cleanup_push(cleanup_fromsig, jb);
44 notify(val);
45 pthread_cleanup_pop(1);
46 }
47}
48
49static void install_handler()
50{
51 struct sigaction sa = {
52 .sa_sigaction = timer_handler,
53 .sa_flags = SA_SIGINFO | SA_RESTART
54 };
55 __libc_sigaction(SIGTIMER, &sa, 0);
56}
57
58static void *start(void *arg)
59{
60 pthread_t self = __pthread_self();
61 struct start_args *args = arg;
62 int id;
63
64 /* Reuse no-longer-needed thread structure fields to avoid
65 * needing the timer address in the signal handler. */
66 self->start = (void *(*)(void *))args->sev->sigev_notify_function;
67 self->start_arg = args->sev->sigev_value.sival_ptr;
68
69 pthread_barrier_wait(&args->b);
70 if ((id = self->timer_id) >= 0) {
71 __syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
72 SIGTIMER_SET, 0, _NSIG/8);
73 __wait(&self->timer_id, 0, id, 1);
74 __syscall(SYS_timer_delete, id);
75 }
76 return 0;
77}
78
79int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict res)
80{
81 static pthread_once_t once = PTHREAD_ONCE_INIT;
82 pthread_t td;
83 pthread_attr_t attr;
84 int r;
85 struct start_args args;
86 struct ksigevent ksev, *ksevp=0;
87 int timerid;
88 sigset_t set;
89
90 switch (evp ? evp->sigev_notify : SIGEV_SIGNAL) {
91 case SIGEV_NONE:
92 case SIGEV_SIGNAL:
93 if (evp) {
94 ksev.sigev_value = evp->sigev_value;
95 ksev.sigev_signo = evp->sigev_signo;
96 ksev.sigev_notify = evp->sigev_notify;
97 ksev.sigev_tid = 0;
98 ksevp = &ksev;
99 }
100 if (syscall(SYS_timer_create, clk, ksevp, &timerid) < 0)
101 return -1;
102 *res = (void *)(intptr_t)timerid;
103 break;
104 case SIGEV_THREAD:
105 pthread_once(&once, install_handler);
106 if (evp->sigev_notify_attributes)
107 attr = *evp->sigev_notify_attributes;
108 else
109 pthread_attr_init(&attr);
110 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
111 pthread_barrier_init(&args.b, 0, 2);
112 args.sev = evp;
113
114 __block_app_sigs(&set);
115 r = pthread_create(&td, &attr, start, &args);
116 __restore_sigs(&set);
117 if (r) {
118 errno = r;
119 return -1;
120 }
121
122 ksev.sigev_value.sival_ptr = 0;
123 ksev.sigev_signo = SIGTIMER;
124 ksev.sigev_notify = 4; /* SIGEV_THREAD_ID */
125 ksev.sigev_tid = td->tid;
126 if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0)
127 timerid = -1;
128 td->timer_id = timerid;
129 pthread_barrier_wait(&args.b);
130 if (timerid < 0) return -1;
131 *res = (void *)(INTPTR_MIN | (uintptr_t)td>>1);
132 break;
133 default:
134 errno = EINVAL;
135 return -1;
136 }
137
138 return 0;
139}
libc/musl/src/time/timer_delete.c created+14
......@@ -0,0 +1,14 @@
1#include <time.h>
2#include <limits.h>
3#include "pthread_impl.h"
4
5int timer_delete(timer_t t)
6{
7 if ((intptr_t)t < 0) {
8 pthread_t td = (void *)((uintptr_t)t << 1);
9 a_store(&td->timer_id, td->timer_id | INT_MIN);
10 __wake(&td->timer_id, 1, 1);
11 return 0;
12 }
13 return __syscall(SYS_timer_delete, t);
14}
libc/musl/src/time/timer_getoverrun.c created+12
......@@ -0,0 +1,12 @@
1#include <time.h>
2#include <limits.h>
3#include "pthread_impl.h"
4
5int timer_getoverrun(timer_t t)
6{
7 if ((intptr_t)t < 0) {
8 pthread_t td = (void *)((uintptr_t)t << 1);
9 t = (void *)(uintptr_t)(td->timer_id & INT_MAX);
10 }
11 return syscall(SYS_timer_getoverrun, t);
12}
libc/musl/src/time/timer_gettime.c created+12
......@@ -0,0 +1,12 @@
1#include <time.h>
2#include <limits.h>
3#include "pthread_impl.h"
4
5int timer_gettime(timer_t t, struct itimerspec *val)
6{
7 if ((intptr_t)t < 0) {
8 pthread_t td = (void *)((uintptr_t)t << 1);
9 t = (void *)(uintptr_t)(td->timer_id & INT_MAX);
10 }
11 return syscall(SYS_timer_gettime, t, val);
12}
libc/musl/src/time/timer_settime.c created+12
......@@ -0,0 +1,12 @@
1#include <time.h>
2#include <limits.h>
3#include "pthread_impl.h"
4
5int timer_settime(timer_t t, int flags, const struct itimerspec *restrict val, struct itimerspec *restrict old)
6{
7 if ((intptr_t)t < 0) {
8 pthread_t td = (void *)((uintptr_t)t << 1);
9 t = (void *)(uintptr_t)(td->timer_id & INT_MAX);
10 }
11 return syscall(SYS_timer_settime, t, flags, val, old);
12}
libc/musl/src/time/times.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/times.h>
2#include "syscall.h"
3
4clock_t times(struct tms *tms)
5{
6 return __syscall(SYS_times, tms);
7}
libc/musl/src/time/timespec_get.c created+10
......@@ -0,0 +1,10 @@
1#include <time.h>
2
3/* There is no other implemented value than TIME_UTC; all other values
4 * are considered erroneous. */
5int timespec_get(struct timespec * ts, int base)
6{
7 if (base != TIME_UTC) return 0;
8 int ret = __clock_gettime(CLOCK_REALTIME, ts);
9 return ret < 0 ? 0 : base;
10}
libc/musl/src/time/utime.c created+11
......@@ -0,0 +1,11 @@
1#include <utime.h>
2#include <sys/stat.h>
3#include <time.h>
4#include <fcntl.h>
5
6int utime(const char *path, const struct utimbuf *times)
7{
8 return utimensat(AT_FDCWD, path, times ? ((struct timespec [2]){
9 { .tv_sec = times->actime }, { .tv_sec = times->modtime }})
10 : 0, 0);
11}
libc/musl/src/time/wcsftime.c created+71
......@@ -0,0 +1,71 @@
1#include <wchar.h>
2#include <time.h>
3#include <locale.h>
4#include "locale_impl.h"
5#include "time_impl.h"
6
7size_t __wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, const struct tm *restrict tm, locale_t loc)
8{
9 size_t l, k;
10 char buf[100];
11 wchar_t wbuf[100];
12 wchar_t *p;
13 const char *t_mb;
14 const wchar_t *t;
15 int pad, plus;
16 unsigned long width;
17 for (l=0; l<n; f++) {
18 if (!*f) {
19 s[l] = 0;
20 return l;
21 }
22 if (*f != '%') {
23 s[l++] = *f;
24 continue;
25 }
26 f++;
27 pad = 0;
28 if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
29 if ((plus = (*f == '+'))) f++;
30 width = wcstoul(f, &p, 10);
31 if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
32 if (!width && p!=f) width = 1;
33 } else {
34 width = 0;
35 }
36 f = p;
37 if (*f == 'E' || *f == 'O') f++;
38 t_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad);
39 if (!t_mb) break;
40 k = mbstowcs(wbuf, t_mb, sizeof wbuf / sizeof *wbuf);
41 if (k == (size_t)-1) return 0;
42 t = wbuf;
43 if (width) {
44 for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--);
45 width--;
46 if (plus && tm->tm_year >= 10000-1900)
47 s[l++] = '+';
48 else if (tm->tm_year < -1900)
49 s[l++] = '-';
50 else
51 width++;
52 for (; width > k && l < n; width--)
53 s[l++] = '0';
54 }
55 if (k >= n-l) k = n-l;
56 wmemcpy(s+l, t, k);
57 l += k;
58 }
59 if (n) {
60 if (l==n) l=n-1;
61 s[l] = 0;
62 }
63 return 0;
64}
65
66size_t wcsftime(wchar_t *restrict wcs, size_t n, const wchar_t *restrict f, const struct tm *restrict tm)
67{
68 return __wcsftime_l(wcs, n, f, tm, CURRENT_LOCALE);
69}
70
71weak_alias(__wcsftime_l, wcsftime_l);
libc/musl/src/unistd/_exit.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include <stdlib.h>
3
4_Noreturn void _exit(int status)
5{
6 _Exit(status);
7}
libc/musl/src/unistd/access.c created+12
......@@ -0,0 +1,12 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int access(const char *filename, int amode)
6{
7#ifdef SYS_access
8 return syscall(SYS_access, filename, amode);
9#else
10 return syscall(SYS_faccessat, AT_FDCWD, filename, amode, 0);
11#endif
12}
libc/musl/src/unistd/acct.c created+8
......@@ -0,0 +1,8 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4
5int acct(const char *filename)
6{
7 return syscall(SYS_acct, filename);
8}
libc/musl/src/unistd/alarm.c created+10
......@@ -0,0 +1,10 @@
1#include <unistd.h>
2#include <sys/time.h>
3#include "syscall.h"
4
5unsigned alarm(unsigned seconds)
6{
7 struct itimerval it = { .it_value.tv_sec = seconds };
8 __syscall(SYS_setitimer, ITIMER_REAL, &it, &it);
9 return it.it_value.tv_sec + !!it.it_value.tv_usec;
10}
libc/musl/src/unistd/chdir.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int chdir(const char *path)
5{
6 return syscall(SYS_chdir, path);
7}
libc/musl/src/unistd/chown.c created+12
......@@ -0,0 +1,12 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int chown(const char *path, uid_t uid, gid_t gid)
6{
7#ifdef SYS_chown
8 return syscall(SYS_chown, path, uid, gid);
9#else
10 return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, 0);
11#endif
12}
libc/musl/src/unistd/close.c created+18
......@@ -0,0 +1,18 @@
1#include <unistd.h>
2#include <errno.h>
3#include "syscall.h"
4
5static int dummy(int fd)
6{
7 return fd;
8}
9
10weak_alias(dummy, __aio_close);
11
12int close(int fd)
13{
14 fd = __aio_close(fd);
15 int r = __syscall_cp(SYS_close, fd);
16 if (r == -EINTR) r = 0;
17 return __syscall_ret(r);
18}
libc/musl/src/unistd/ctermid.c created+7
......@@ -0,0 +1,7 @@
1#include <stdio.h>
2#include <string.h>
3
4char *ctermid(char *s)
5{
6 return s ? strcpy(s, "/dev/tty") : "/dev/tty";
7}
libc/musl/src/unistd/dup.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int dup(int fd)
5{
6 return syscall(SYS_dup, fd);
7}
libc/musl/src/unistd/dup2.c created+20
......@@ -0,0 +1,20 @@
1#include <unistd.h>
2#include <errno.h>
3#include <fcntl.h>
4#include "syscall.h"
5
6int dup2(int old, int new)
7{
8 int r;
9#ifdef SYS_dup2
10 while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
11#else
12 if (old==new) {
13 r = __syscall(SYS_fcntl, old, F_GETFD);
14 if (r >= 0) return old;
15 } else {
16 while ((r=__syscall(SYS_dup3, old, new, 0))==-EBUSY);
17 }
18#endif
19 return __syscall_ret(r);
20}
libc/musl/src/unistd/dup3.c created+24
......@@ -0,0 +1,24 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include <errno.h>
4#include <fcntl.h>
5#include "syscall.h"
6
7int __dup3(int old, int new, int flags)
8{
9 int r;
10#ifdef SYS_dup2
11 if (old==new) return __syscall_ret(-EINVAL);
12 if (flags & O_CLOEXEC) {
13 while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
14 if (r!=-ENOSYS) return __syscall_ret(r);
15 }
16 while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
17 if (flags & O_CLOEXEC) __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);
18#else
19 while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
20#endif
21 return __syscall_ret(r);
22}
23
24weak_alias(__dup3, dup3);
libc/musl/src/unistd/faccessat.c created+56
......@@ -0,0 +1,56 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include <sys/wait.h>
4#include "syscall.h"
5#include "pthread_impl.h"
6
7struct ctx {
8 int fd;
9 const char *filename;
10 int amode;
11 int p;
12};
13
14static int checker(void *p)
15{
16 struct ctx *c = p;
17 int ret;
18 if (__syscall(SYS_setregid, __syscall(SYS_getegid), -1)
19 || __syscall(SYS_setreuid, __syscall(SYS_geteuid), -1))
20 __syscall(SYS_exit, 1);
21 ret = __syscall(SYS_faccessat, c->fd, c->filename, c->amode, 0);
22 __syscall(SYS_write, c->p, &ret, sizeof ret);
23 return 0;
24}
25
26int faccessat(int fd, const char *filename, int amode, int flag)
27{
28 if (!flag || (flag==AT_EACCESS && getuid()==geteuid() && getgid()==getegid()))
29 return syscall(SYS_faccessat, fd, filename, amode, flag);
30
31 if (flag != AT_EACCESS)
32 return __syscall_ret(-EINVAL);
33
34 char stack[1024];
35 sigset_t set;
36 pid_t pid;
37 int status;
38 int ret, p[2];
39
40 if (pipe2(p, O_CLOEXEC)) return __syscall_ret(-EBUSY);
41 struct ctx c = { .fd = fd, .filename = filename, .amode = amode, .p = p[1] };
42
43 __block_all_sigs(&set);
44
45 pid = __clone(checker, stack+sizeof stack, 0, &c);
46 __syscall(SYS_close, p[1]);
47
48 if (pid<0 || __syscall(SYS_read, p[0], &ret, sizeof ret) != sizeof(ret))
49 ret = -EBUSY;
50 __syscall(SYS_close, p[0]);
51 __syscall(SYS_wait4, pid, &status, __WCLONE, 0);
52
53 __restore_sigs(&set);
54
55 return __syscall_ret(ret);
56}
libc/musl/src/unistd/fchdir.c created+15
......@@ -0,0 +1,15 @@
1#include <unistd.h>
2#include <errno.h>
3#include <fcntl.h>
4#include "syscall.h"
5
6int fchdir(int fd)
7{
8 int ret = __syscall(SYS_fchdir, fd);
9 if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
10 return __syscall_ret(ret);
11
12 char buf[15+3*sizeof(int)];
13 __procfdname(buf, fd);
14 return syscall(SYS_chdir, buf);
15}
libc/musl/src/unistd/fchown.c created+20
......@@ -0,0 +1,20 @@
1#include <unistd.h>
2#include <errno.h>
3#include <fcntl.h>
4#include "syscall.h"
5
6int fchown(int fd, uid_t uid, gid_t gid)
7{
8 int ret = __syscall(SYS_fchown, fd, uid, gid);
9 if (ret != -EBADF || __syscall(SYS_fcntl, fd, F_GETFD) < 0)
10 return __syscall_ret(ret);
11
12 char buf[15+3*sizeof(int)];
13 __procfdname(buf, fd);
14#ifdef SYS_chown
15 return syscall(SYS_chown, buf, uid, gid);
16#else
17 return syscall(SYS_fchownat, AT_FDCWD, buf, uid, gid, 0);
18#endif
19
20}
libc/musl/src/unistd/fchownat.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int fchownat(int fd, const char *path, uid_t uid, gid_t gid, int flag)
5{
6 return syscall(SYS_fchownat, fd, path, uid, gid, flag);
7}
libc/musl/src/unistd/fdatasync.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int fdatasync(int fd)
5{
6 return syscall_cp(SYS_fdatasync, fd);
7}
libc/musl/src/unistd/fsync.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int fsync(int fd)
5{
6 return syscall_cp(SYS_fsync, fd);
7}
libc/musl/src/unistd/ftruncate.c created+9
......@@ -0,0 +1,9 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int ftruncate(int fd, off_t length)
5{
6 return syscall(SYS_ftruncate, fd, __SYSCALL_LL_O(length));
7}
8
9weak_alias(ftruncate, ftruncate64);
libc/musl/src/unistd/getcwd.c created+25
......@@ -0,0 +1,25 @@
1#include <unistd.h>
2#include <errno.h>
3#include <limits.h>
4#include <string.h>
5#include "syscall.h"
6
7char *getcwd(char *buf, size_t size)
8{
9 char tmp[buf ? 1 : PATH_MAX];
10 if (!buf) {
11 buf = tmp;
12 size = sizeof tmp;
13 } else if (!size) {
14 errno = EINVAL;
15 return 0;
16 }
17 long ret = syscall(SYS_getcwd, buf, size);
18 if (ret < 0)
19 return 0;
20 if (ret == 0 || buf[0] != '/') {
21 errno = ENOENT;
22 return 0;
23 }
24 return buf == tmp ? strdup(buf) : buf;
25}
libc/musl/src/unistd/getegid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4gid_t getegid(void)
5{
6 return __syscall(SYS_getegid);
7}
libc/musl/src/unistd/geteuid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4uid_t geteuid(void)
5{
6 return __syscall(SYS_geteuid);
7}
libc/musl/src/unistd/getgid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4gid_t getgid(void)
5{
6 return __syscall(SYS_getgid);
7}
libc/musl/src/unistd/getgroups.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int getgroups(int count, gid_t list[])
5{
6 return syscall(SYS_getgroups, count, list);
7}
libc/musl/src/unistd/gethostname.c created+13
......@@ -0,0 +1,13 @@
1#include <unistd.h>
2#include <sys/utsname.h>
3
4int gethostname(char *name, size_t len)
5{
6 size_t i;
7 struct utsname uts;
8 if (uname(&uts)) return -1;
9 if (len > sizeof uts.nodename) len = sizeof uts.nodename;
10 for (i=0; i<len && (name[i] = uts.nodename[i]); i++);
11 if (i && i==len) name[i-1] = 0;
12 return 0;
13}
libc/musl/src/unistd/getlogin.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include <stdlib.h>
3
4char *getlogin(void)
5{
6 return getenv("LOGNAME");
7}
libc/musl/src/unistd/getlogin_r.c created+12
......@@ -0,0 +1,12 @@
1#include <unistd.h>
2#include <string.h>
3#include <errno.h>
4
5int getlogin_r(char *name, size_t size)
6{
7 char *logname = getlogin();
8 if (!logname) return ENXIO; /* or...? */
9 if (strlen(logname) >= size) return ERANGE;
10 strcpy(name, logname);
11 return 0;
12}
libc/musl/src/unistd/getpgid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4pid_t getpgid(pid_t pid)
5{
6 return syscall(SYS_getpgid, pid);
7}
libc/musl/src/unistd/getpgrp.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4pid_t getpgrp(void)
5{
6 return __syscall(SYS_getpgid, 0);
7}
libc/musl/src/unistd/getpid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4pid_t getpid(void)
5{
6 return __syscall(SYS_getpid);
7}
libc/musl/src/unistd/getppid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4pid_t getppid(void)
5{
6 return __syscall(SYS_getppid);
7}
libc/musl/src/unistd/getsid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4pid_t getsid(pid_t pid)
5{
6 return syscall(SYS_getsid, pid);
7}
libc/musl/src/unistd/getuid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4uid_t getuid(void)
5{
6 return __syscall(SYS_getuid);
7}
libc/musl/src/unistd/isatty.c created+13
......@@ -0,0 +1,13 @@
1#include <unistd.h>
2#include <errno.h>
3#include <sys/ioctl.h>
4#include "syscall.h"
5
6int isatty(int fd)
7{
8 struct winsize wsz;
9 unsigned long r = syscall(SYS_ioctl, fd, TIOCGWINSZ, &wsz);
10 if (r == 0) return 1;
11 if (errno != EBADF) errno = ENOTTY;
12 return 0;
13}
libc/musl/src/unistd/lchown.c created+12
......@@ -0,0 +1,12 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int lchown(const char *path, uid_t uid, gid_t gid)
6{
7#ifdef SYS_lchown
8 return syscall(SYS_lchown, path, uid, gid);
9#else
10 return syscall(SYS_fchownat, AT_FDCWD, path, uid, gid, AT_SYMLINK_NOFOLLOW);
11#endif
12}
libc/musl/src/unistd/link.c created+12
......@@ -0,0 +1,12 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int link(const char *existing, const char *new)
6{
7#ifdef SYS_link
8 return syscall(SYS_link, existing, new);
9#else
10 return syscall(SYS_linkat, AT_FDCWD, existing, AT_FDCWD, new, 0);
11#endif
12}
libc/musl/src/unistd/linkat.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int linkat(int fd1, const char *existing, int fd2, const char *new, int flag)
5{
6 return syscall(SYS_linkat, fd1, existing, fd2, new, flag);
7}
libc/musl/src/unistd/lseek.c created+14
......@@ -0,0 +1,14 @@
1#include <unistd.h>
2#include "syscall.h"
3
4off_t lseek(int fd, off_t offset, int whence)
5{
6#ifdef SYS__llseek
7 off_t result;
8 return syscall(SYS__llseek, fd, offset>>32, offset, &result, whence) ? -1 : result;
9#else
10 return syscall(SYS_lseek, fd, offset, whence);
11#endif
12}
13
14weak_alias(lseek, lseek64);
libc/musl/src/unistd/mips/pipe.s created+20
......@@ -0,0 +1,20 @@
1.set noreorder
2
3.global pipe
4.type pipe,@function
5pipe:
6 lui $gp, %hi(_gp_disp)
7 addiu $gp, %lo(_gp_disp)
8 addu $gp, $gp, $25
9 li $2, 4042
10 syscall
11 beq $7, $0, 1f
12 nop
13 lw $25, %call16(__syscall_ret)($gp)
14 jr $25
15 subu $4, $0, $2
161: sw $2, 0($4)
17 sw $3, 4($4)
18 move $2, $0
19 jr $ra
20 nop
libc/musl/src/unistd/mips64/pipe.s created+19
......@@ -0,0 +1,19 @@
1.set noreorder
2.global pipe
3.type pipe,@function
4pipe:
5 lui $3, %hi(%neg(%gp_rel(pipe)))
6 daddiu $3, $3, %lo(%neg(%gp_rel(pipe)))
7 daddu $3, $3, $25
8 li $2, 5021
9 syscall
10 beq $7, $0, 1f
11 nop
12 ld $25, %got_disp(__syscall_ret)($3)
13 jr $25
14 dsubu $4, $0, $2
151: sw $2, 0($4)
16 sw $3, 4($4)
17 move $2, $0
18 jr $ra
19 nop
libc/musl/src/unistd/mipsn32/pipe.s created+19
......@@ -0,0 +1,19 @@
1.set noreorder
2.global pipe
3.type pipe,@function
4pipe:
5 lui $3, %hi(%neg(%gp_rel(pipe)))
6 addiu $3, $3, %lo(%neg(%gp_rel(pipe)))
7 addu $3, $3, $25
8 li $2, 6021
9 syscall
10 beq $7, $0, 1f
11 nop
12 lw $25, %got_disp(__syscall_ret)($3)
13 jr $25
14 subu $4, $0, $2
151: sw $2, 0($4)
16 sw $3, 4($4)
17 move $2, $0
18 jr $ra
19 nop
libc/musl/src/unistd/nice.c created+16
......@@ -0,0 +1,16 @@
1#include <unistd.h>
2#include <sys/resource.h>
3#include <limits.h>
4#include "syscall.h"
5
6int nice(int inc)
7{
8 int prio = inc;
9 // Only query old priority if it can affect the result.
10 // This also avoids issues with integer overflow.
11 if (inc > -2*NZERO && inc < 2*NZERO)
12 prio += getpriority(PRIO_PROCESS, 0);
13 if (prio > NZERO-1) prio = NZERO-1;
14 if (prio < -NZERO) prio = -NZERO;
15 return setpriority(PRIO_PROCESS, 0, prio) ? -1 : prio;
16}
libc/musl/src/unistd/pause.c created+11
......@@ -0,0 +1,11 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int pause(void)
5{
6#ifdef SYS_pause
7 return syscall_cp(SYS_pause);
8#else
9 return syscall_cp(SYS_ppoll, 0, 0, 0, 0);
10#endif
11}
libc/musl/src/unistd/pipe.c created+11
......@@ -0,0 +1,11 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int pipe(int fd[2])
5{
6#ifdef SYS_pipe
7 return syscall(SYS_pipe, fd);
8#else
9 return syscall(SYS_pipe2, fd, 0);
10#endif
11}
libc/musl/src/unistd/pipe2.c created+22
......@@ -0,0 +1,22 @@
1#include <unistd.h>
2#include <errno.h>
3#include <fcntl.h>
4#include "syscall.h"
5
6int pipe2(int fd[2], int flag)
7{
8 if (!flag) return pipe(fd);
9 int ret = __syscall(SYS_pipe2, fd, flag);
10 if (ret != -ENOSYS) return __syscall_ret(ret);
11 ret = pipe(fd);
12 if (ret) return ret;
13 if (flag & O_CLOEXEC) {
14 __syscall(SYS_fcntl, fd[0], F_SETFD, FD_CLOEXEC);
15 __syscall(SYS_fcntl, fd[1], F_SETFD, FD_CLOEXEC);
16 }
17 if (flag & O_NONBLOCK) {
18 __syscall(SYS_fcntl, fd[0], F_SETFL, O_NONBLOCK);
19 __syscall(SYS_fcntl, fd[1], F_SETFL, O_NONBLOCK);
20 }
21 return 0;
22}
libc/musl/src/unistd/posix_close.c created+6
......@@ -0,0 +1,6 @@
1#include <unistd.h>
2
3int posix_close(int fd, int flags)
4{
5 return close(fd);
6}
libc/musl/src/unistd/pread.c created+9
......@@ -0,0 +1,9 @@
1#include <unistd.h>
2#include "syscall.h"
3
4ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
5{
6 return syscall_cp(SYS_pread, fd, buf, size, __SYSCALL_LL_PRW(ofs));
7}
8
9weak_alias(pread, pread64);
libc/musl/src/unistd/preadv.c created+12
......@@ -0,0 +1,12 @@
1#define _BSD_SOURCE
2#include <sys/uio.h>
3#include <unistd.h>
4#include "syscall.h"
5
6ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs)
7{
8 return syscall_cp(SYS_preadv, fd, iov, count,
9 (long)(ofs), (long)(ofs>>32));
10}
11
12weak_alias(preadv, preadv64);
libc/musl/src/unistd/pwrite.c created+9
......@@ -0,0 +1,9 @@
1#include <unistd.h>
2#include "syscall.h"
3
4ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs)
5{
6 return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs));
7}
8
9weak_alias(pwrite, pwrite64);
libc/musl/src/unistd/pwritev.c created+12
......@@ -0,0 +1,12 @@
1#define _BSD_SOURCE
2#include <sys/uio.h>
3#include <unistd.h>
4#include "syscall.h"
5
6ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs)
7{
8 return syscall_cp(SYS_pwritev, fd, iov, count,
9 (long)(ofs), (long)(ofs>>32));
10}
11
12weak_alias(pwritev, pwritev64);
libc/musl/src/unistd/read.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4ssize_t read(int fd, void *buf, size_t count)
5{
6 return syscall_cp(SYS_read, fd, buf, count);
7}
libc/musl/src/unistd/readlink.c created+12
......@@ -0,0 +1,12 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
6{
7#ifdef SYS_readlink
8 return syscall(SYS_readlink, path, buf, bufsize);
9#else
10 return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
11#endif
12}
libc/musl/src/unistd/readlinkat.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize)
5{
6 return syscall(SYS_readlinkat, fd, path, buf, bufsize);
7}
libc/musl/src/unistd/readv.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/uio.h>
2#include "syscall.h"
3
4ssize_t readv(int fd, const struct iovec *iov, int count)
5{
6 return syscall_cp(SYS_readv, fd, iov, count);
7}
libc/musl/src/unistd/renameat.c created+7
......@@ -0,0 +1,7 @@
1#include <stdio.h>
2#include "syscall.h"
3
4int renameat(int oldfd, const char *old, int newfd, const char *new)
5{
6 return syscall(SYS_renameat, oldfd, old, newfd, new);
7}
libc/musl/src/unistd/rmdir.c created+12
......@@ -0,0 +1,12 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int rmdir(const char *path)
6{
7#ifdef SYS_rmdir
8 return syscall(SYS_rmdir, path);
9#else
10 return syscall(SYS_unlinkat, AT_FDCWD, path, AT_REMOVEDIR);
11#endif
12}
libc/musl/src/unistd/setegid.c created+8
......@@ -0,0 +1,8 @@
1#include <unistd.h>
2#include "libc.h"
3#include "syscall.h"
4
5int setegid(gid_t egid)
6{
7 return __setxid(SYS_setresgid, -1, egid, -1);
8}
libc/musl/src/unistd/seteuid.c created+8
......@@ -0,0 +1,8 @@
1#include <unistd.h>
2#include "syscall.h"
3#include "libc.h"
4
5int seteuid(uid_t euid)
6{
7 return __setxid(SYS_setresuid, -1, euid, -1);
8}
libc/musl/src/unistd/setgid.c created+8
......@@ -0,0 +1,8 @@
1#include <unistd.h>
2#include "syscall.h"
3#include "libc.h"
4
5int setgid(gid_t gid)
6{
7 return __setxid(SYS_setgid, gid, 0, 0);
8}
libc/musl/src/unistd/setpgid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int setpgid(pid_t pid, pid_t pgid)
5{
6 return syscall(SYS_setpgid, pid, pgid);
7}
libc/musl/src/unistd/setpgrp.c created+6
......@@ -0,0 +1,6 @@
1#include <unistd.h>
2
3pid_t setpgrp(void)
4{
5 return setpgid(0, 0);
6}
libc/musl/src/unistd/setregid.c created+8
......@@ -0,0 +1,8 @@
1#include <unistd.h>
2#include "syscall.h"
3#include "libc.h"
4
5int setregid(gid_t rgid, gid_t egid)
6{
7 return __setxid(SYS_setregid, rgid, egid, 0);
8}
libc/musl/src/unistd/setresgid.c created+9
......@@ -0,0 +1,9 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4#include "libc.h"
5
6int setresgid(gid_t rgid, gid_t egid, gid_t sgid)
7{
8 return __setxid(SYS_setresgid, rgid, egid, sgid);
9}
libc/musl/src/unistd/setresuid.c created+9
......@@ -0,0 +1,9 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include "syscall.h"
4#include "libc.h"
5
6int setresuid(uid_t ruid, uid_t euid, uid_t suid)
7{
8 return __setxid(SYS_setresuid, ruid, euid, suid);
9}
libc/musl/src/unistd/setreuid.c created+8
......@@ -0,0 +1,8 @@
1#include <unistd.h>
2#include "syscall.h"
3#include "libc.h"
4
5int setreuid(uid_t ruid, uid_t euid)
6{
7 return __setxid(SYS_setreuid, ruid, euid, 0);
8}
libc/musl/src/unistd/setsid.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4pid_t setsid(void)
5{
6 return syscall(SYS_setsid);
7}
libc/musl/src/unistd/setuid.c created+8
......@@ -0,0 +1,8 @@
1#include <unistd.h>
2#include "syscall.h"
3#include "libc.h"
4
5int setuid(uid_t uid)
6{
7 return __setxid(SYS_setuid, uid, 0, 0);
8}
libc/musl/src/unistd/setxid.c created+39
......@@ -0,0 +1,39 @@
1#include <unistd.h>
2#include <errno.h>
3#include "syscall.h"
4#include "libc.h"
5#include "pthread_impl.h"
6
7struct ctx {
8 int id, eid, sid;
9 int nr, err;
10};
11
12static void do_setxid(void *p)
13{
14 struct ctx *c = p;
15 if (c->err>0) return;
16 int ret = -__syscall(c->nr, c->id, c->eid, c->sid);
17 if (ret && !c->err) {
18 /* If one thread fails to set ids after another has already
19 * succeeded, forcibly killing the process is the only safe
20 * thing to do. State is inconsistent and dangerous. Use
21 * SIGKILL because it is uncatchable. */
22 __block_all_sigs(0);
23 __syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL);
24 }
25 c->err = ret;
26}
27
28int __setxid(int nr, int id, int eid, int sid)
29{
30 /* err is initially nonzero so that failure of the first thread does not
31 * trigger the safety kill above. */
32 struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .err = -1 };
33 __synccall(do_setxid, &c);
34 if (c.err) {
35 if (c.err>0) errno = c.err;
36 return -1;
37 }
38 return 0;
39}
libc/musl/src/unistd/sh/pipe.s created+27
......@@ -0,0 +1,27 @@
1.global pipe
2.type pipe, @function
3pipe:
4 mov #42, r3
5 trapa #31
6
7 ! work around hardware bug
8 or r0, r0
9 or r0, r0
10 or r0, r0
11 or r0, r0
12 or r0, r0
13
14 cmp/pz r0
15 bt 1f
16
17 mov.l L1, r1
18 braf r1
19 mov r0, r4
20
211: mov.l r0, @(0,r4)
22 mov.l r1, @(4,r4)
23 rts
24 mov #0, r0
25
26.align 2
27L1: .long __syscall_ret@PLT-(1b-.)
libc/musl/src/unistd/sleep.c created+10
......@@ -0,0 +1,10 @@
1#include <unistd.h>
2#include <time.h>
3
4unsigned sleep(unsigned seconds)
5{
6 struct timespec tv = { .tv_sec = seconds, .tv_nsec = 0 };
7 if (nanosleep(&tv, &tv))
8 return tv.tv_sec;
9 return 0;
10}
libc/musl/src/unistd/symlink.c created+12
......@@ -0,0 +1,12 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int symlink(const char *existing, const char *new)
6{
7#ifdef SYS_symlink
8 return syscall(SYS_symlink, existing, new);
9#else
10 return syscall(SYS_symlinkat, existing, AT_FDCWD, new);
11#endif
12}
libc/musl/src/unistd/symlinkat.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int symlinkat(const char *existing, int fd, const char *new)
5{
6 return syscall(SYS_symlinkat, existing, fd, new);
7}
libc/musl/src/unistd/sync.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4void sync(void)
5{
6 __syscall(SYS_sync);
7}
libc/musl/src/unistd/tcgetpgrp.c created+11
......@@ -0,0 +1,11 @@
1#include <unistd.h>
2#include <termios.h>
3#include <sys/ioctl.h>
4
5pid_t tcgetpgrp(int fd)
6{
7 int pgrp;
8 if (ioctl(fd, TIOCGPGRP, &pgrp) < 0)
9 return -1;
10 return pgrp;
11}
libc/musl/src/unistd/tcsetpgrp.c created+9
......@@ -0,0 +1,9 @@
1#include <unistd.h>
2#include <termios.h>
3#include <sys/ioctl.h>
4
5int tcsetpgrp(int fd, pid_t pgrp)
6{
7 int pgrp_int = pgrp;
8 return ioctl(fd, TIOCSPGRP, &pgrp_int);
9}
libc/musl/src/unistd/truncate.c created+9
......@@ -0,0 +1,9 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int truncate(const char *path, off_t length)
5{
6 return syscall(SYS_truncate, path, __SYSCALL_LL_O(length));
7}
8
9weak_alias(truncate, truncate64);
libc/musl/src/unistd/ttyname.c created+14
......@@ -0,0 +1,14 @@
1#include <unistd.h>
2#include <errno.h>
3#include <limits.h>
4
5char *ttyname(int fd)
6{
7 static char buf[TTY_NAME_MAX];
8 int result;
9 if ((result = ttyname_r(fd, buf, sizeof buf))) {
10 errno = result;
11 return NULL;
12 }
13 return buf;
14}
libc/musl/src/unistd/ttyname_r.c created+28
......@@ -0,0 +1,28 @@
1#include <unistd.h>
2#include <errno.h>
3#include <sys/stat.h>
4#include "syscall.h"
5
6int ttyname_r(int fd, char *name, size_t size)
7{
8 struct stat st1, st2;
9 char procname[sizeof "/proc/self/fd/" + 3*sizeof(int) + 2];
10 ssize_t l;
11
12 if (!isatty(fd)) return errno;
13
14 __procfdname(procname, fd);
15 l = readlink(procname, name, size);
16
17 if (l < 0) return errno;
18 else if (l == size) return ERANGE;
19
20 name[l] = 0;
21
22 if (stat(name, &st1) || fstat(fd, &st2))
23 return errno;
24 if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
25 return ENODEV;
26
27 return 0;
28}
libc/musl/src/unistd/ualarm.c created+13
......@@ -0,0 +1,13 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include <sys/time.h>
4
5unsigned ualarm(unsigned value, unsigned interval)
6{
7 struct itimerval it = {
8 .it_interval.tv_usec = interval,
9 .it_value.tv_usec = value
10 };
11 setitimer(ITIMER_REAL, &it, &it);
12 return it.it_value.tv_sec*1000000 + it.it_value.tv_usec;
13}
libc/musl/src/unistd/unlink.c created+12
......@@ -0,0 +1,12 @@
1#include <unistd.h>
2#include <fcntl.h>
3#include "syscall.h"
4
5int unlink(const char *path)
6{
7#ifdef SYS_unlink
8 return syscall(SYS_unlink, path);
9#else
10 return syscall(SYS_unlinkat, AT_FDCWD, path, 0);
11#endif
12}
libc/musl/src/unistd/unlinkat.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4int unlinkat(int fd, const char *path, int flag)
5{
6 return syscall(SYS_unlinkat, fd, path, flag);
7}
libc/musl/src/unistd/usleep.c created+12
......@@ -0,0 +1,12 @@
1#define _GNU_SOURCE
2#include <unistd.h>
3#include <time.h>
4
5int usleep(unsigned useconds)
6{
7 struct timespec tv = {
8 .tv_sec = useconds/1000000,
9 .tv_nsec = (useconds%1000000)*1000
10 };
11 return nanosleep(&tv, &tv);
12}
libc/musl/src/unistd/write.c created+7
......@@ -0,0 +1,7 @@
1#include <unistd.h>
2#include "syscall.h"
3
4ssize_t write(int fd, const void *buf, size_t count)
5{
6 return syscall_cp(SYS_write, fd, buf, count);
7}
libc/musl/src/unistd/writev.c created+7
......@@ -0,0 +1,7 @@
1#include <sys/uio.h>
2#include "syscall.h"
3
4ssize_t writev(int fd, const struct iovec *iov, int count)
5{
6 return syscall_cp(SYS_writev, fd, iov, count);
7}
src/codegen.cpp+7-4
......@@ -8014,11 +8014,14 @@ static void detect_libc(CodeGen *g) {
80148014 } else if ((g->out_type == OutTypeExe || (g->out_type == OutTypeLib && !g->is_static)) &&
80158015 !target_is_darwin(g->zig_target))
80168016 {
8017 // Currently darwin is the only platform that we can link libc on when not compiling natively,
8018 // without a cross compiling libc kit.
80198017 fprintf(stderr,
8020 "Cannot link against libc for non-native OS '%s' without providing a libc installation file.\n"
8021 "See `zig libc --help` for more details.\n", target_os_name(g->zig_target->os));
8018 "Zig is unable to provide a libc for the chosen target '%s-%s-%s'.\n"
8019 "The target is non-native, so Zig also cannot use the native libc installation.\n"
8020 "Choose a target which has a libc available, or provide a libc installation text file.\n"
8021 "See `zig libc --help` for more details.\n",
8022 target_arch_name(g->zig_target->arch),
8023 target_os_name(g->zig_target->os),
8024 target_abi_name(g->zig_target->abi));
80228025 exit(1);
80238026 }
80248027}
src/config.h.in-2
......@@ -22,8 +22,6 @@
2222#define ZIG_LLD_INCLUDE_PATH "@LLD_INCLUDE_DIRS@"
2323#define ZIG_LLD_LIBRARIES "@LLD_LIBRARIES@"
2424#define ZIG_LLVM_CONFIG_EXE "@LLVM_CONFIG_EXE@"
25#define ZIG_STD_FILES "@ZIG_STD_FILES@"
26#define ZIG_C_HEADER_FILES "@ZIG_C_HEADER_FILES@"
2725#define ZIG_DIA_GUIDS_LIB "@ZIG_DIA_GUIDS_LIB_ESCAPED@"
2826
2927#endif
src/install_files.h.in created+15
......@@ -0,0 +1,15 @@
1/*
2 * Copyright (c) 2019 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_INSTALL_FILES_H
9#define ZIG_INSTALL_FILES_H
10
11#define ZIG_MUSL_SRC_FILES "@ZIG_MUSL_SRC_FILES@"
12#define ZIG_STD_FILES "@ZIG_STD_FILES@"
13#define ZIG_C_HEADER_FILES "@ZIG_C_HEADER_FILES@"
14
15#endif
src/link.cpp+155-4
......@@ -10,7 +10,7 @@
1010#include "codegen.hpp"
1111#include "analyze.hpp"
1212#include "compiler.hpp"
13
13#include "install_files.h"
1414
1515struct LinkJob {
1616 CodeGen *codegen;
......@@ -458,11 +458,157 @@ static void musl_add_cc_args(CodeGen *parent, CFile *c_file) {
458458 c_file->args.append("-fno-asynchronous-unwind-tables");
459459 c_file->args.append("-ffunction-sections");
460460 c_file->args.append("-fdata-sections");
461}
461462
462 c_file->args.append("-fno-stack-protector");
463 c_file->args.append("-DCRT");
463static const char *musl_arch_names[] = {
464 "aarch64",
465 "arm",
466 "generic",
467 "i386",
468 "m68k",
469 "microblaze",
470 "mips",
471 "mips64",
472 "mipsn32",
473 "or1k",
474 "powerpc",
475 "powerpc64",
476 "s390x",
477 "sh",
478 "x32",
479 "x86_64",
480};
481
482static bool is_musl_arch_name(const char *name) {
483 for (size_t i = 0; i < array_length(musl_arch_names); i += 1) {
484 if (strcmp(name, musl_arch_names[i]) == 0)
485 return true;
486 }
487 return false;
464488}
465489
490static const char *build_musl(CodeGen *parent) {
491 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr);
492 codegen_set_out_name(child_gen, buf_create_from_str("c"));
493 child_gen->is_static = true;
494
495 // When there is a src/<arch>/foo.* then it should substitute for src/foo.*
496 // Even a .s file can substitute for a .c file.
497
498 enum MuslSrc {
499 MuslSrcAsm,
500 MuslSrcNormal,
501 MuslSrcO3,
502 };
503
504 HashMap<Buf *, MuslSrc, buf_hash, buf_eql_buf> source_table = {};
505 source_table.init(1800);
506
507 SplitIterator install_h_it = memSplit(str(ZIG_MUSL_SRC_FILES), str(";"));
508 const char *target_musl_arch_name = musl_arch_name(parent->zig_target);
509 for (;;) {
510 Optional<Slice<uint8_t>> opt_item = SplitIterator_next(&install_h_it);
511 if (!opt_item.is_some) break;
512 Buf *src_file = buf_create_from_slice(opt_item.value);
513
514 MuslSrc src_kind;
515 if (buf_ends_with_str(src_file, ".c")) {
516 assert(buf_starts_with_str(src_file, "musl/src/"));
517 bool want_O3 = buf_starts_with_str(src_file, "musl/src/malloc/") ||
518 buf_starts_with_str(src_file, "musl/src/string/") ||
519 buf_starts_with_str(src_file, "musl/src/internal/");
520 src_kind = want_O3 ? MuslSrcO3 : MuslSrcNormal;
521 } else if (buf_ends_with_str(src_file, ".s") || buf_ends_with_str(src_file, ".S")) {
522 src_kind = MuslSrcAsm;
523 } else {
524 continue;
525 }
526 if (ZIG_OS_SEP_CHAR != '/') {
527 buf_replace(src_file, '/', ZIG_OS_SEP_CHAR);
528 }
529 source_table.put_unique(src_file, src_kind);
530 }
531
532 ZigList<CFile *> c_source_files = {0};
533
534 Buf dirname = BUF_INIT;
535 Buf basename = BUF_INIT;
536 Buf noextbasename = BUF_INIT;
537 Buf dirbasename = BUF_INIT;
538 Buf before_arch_dir = BUF_INIT;
539 Buf override_c = BUF_INIT;
540 Buf override_s = BUF_INIT;
541 Buf override_S = BUF_INIT;
542
543 auto source_it = source_table.entry_iterator();
544 for (;;) {
545 auto *entry = source_it.next();
546 if (!entry) break;
547
548 Buf *src_file = entry->key;
549 MuslSrc src_kind = entry->value;
550
551 os_path_split(src_file, &dirname, &basename);
552 os_path_extname(&basename, &noextbasename, nullptr);
553 os_path_split(&dirname, &before_arch_dir, &dirbasename);
554 if (is_musl_arch_name(buf_ptr(&dirbasename))) {
555 // We find these by explicitly looking for overrides.
556 continue;
557 }
558 // Look for an arch specific override.
559 buf_resize(&override_c, 0);
560 buf_resize(&override_s, 0);
561 buf_resize(&override_S, 0);
562
563 buf_appendf(&override_c, "%s" OS_SEP "%s" OS_SEP "%s.c",
564 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
565 buf_appendf(&override_s, "%s" OS_SEP "%s" OS_SEP "%s.s",
566 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
567 buf_appendf(&override_S, "%s" OS_SEP "%s" OS_SEP "%s.S",
568 buf_ptr(&dirname), target_musl_arch_name, buf_ptr(&noextbasename));
569
570 if (source_table.maybe_get(&override_c) != nullptr) {
571 src_file = &override_c;
572 src_kind = (src_kind == MuslSrcAsm) ? MuslSrcNormal : src_kind;
573 } else if (source_table.maybe_get(&override_s) != nullptr) {
574 src_file = &override_s;
575 src_kind = MuslSrcAsm;
576 } else if (source_table.maybe_get(&override_S) != nullptr) {
577 src_file = &override_S;
578 src_kind = MuslSrcAsm;
579 }
580
581 Buf *full_path = buf_sprintf("%s" OS_SEP "libc" OS_SEP "%s",
582 buf_ptr(parent->zig_lib_dir), buf_ptr(src_file));
583
584 if (src_kind == MuslSrcAsm) {
585 codegen_add_assembly(child_gen, full_path);
586 } else {
587 CFile *c_file = allocate<CFile>(1);
588 c_file->source_path = buf_ptr(full_path);
589 musl_add_cc_args(parent, c_file);
590 c_file->args.append("-Wno-ignored-attributes");
591 c_file->args.append("-Wno-bitwise-op-parentheses");
592 c_file->args.append("-Wno-logical-op-parentheses");
593 c_file->args.append("-Wno-dangling-else");
594 c_file->args.append("-Wno-shift-op-parentheses");
595 c_file->args.append("-Qunused-arguments");
596 c_file->args.append("-Wno-unknown-pragmas");
597 c_file->args.append("-Wno-string-plus-int");
598 c_file->args.append("-Wno-parentheses");
599 if (src_kind == MuslSrcO3) {
600 c_file->args.append("-O3");
601 }
602 c_source_files.append(c_file);
603 }
604 }
605
606 child_gen->c_source_files = c_source_files;
607 codegen_build_and_link(child_gen);
608 return buf_ptr(&child_gen->output_file_path);
609}
610
611
466612static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
467613 if (parent->libc == nullptr && target_is_glibc(parent)) {
468614 if (strcmp(file, "crti.o") == 0) {
......@@ -620,12 +766,16 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
620766 CFile *c_file = allocate<CFile>(1);
621767 c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "crt1.c");
622768 musl_add_cc_args(parent, c_file);
769 c_file->args.append("-fno-stack-protector");
770 c_file->args.append("-DCRT");
623771 return build_libc_object(parent, "crt1", c_file);
624772 } else if (strcmp(file, "Scrt1.o") == 0) {
625773 CFile *c_file = allocate<CFile>(1);
626774 c_file->source_path = path_from_libc(parent, "musl" OS_SEP "crt" OS_SEP "Scrt1.c");
627775 musl_add_cc_args(parent, c_file);
628776 c_file->args.append("-fPIC");
777 c_file->args.append("-fno-stack-protector");
778 c_file->args.append("-DCRT");
629779 return build_libc_object(parent, "Scrt1", c_file);
630780 } else {
631781 zig_unreachable();
......@@ -937,7 +1087,8 @@ static void construct_linker_job_elf(LinkJob *lj) {
9371087 lj->args.append(build_dummy_so(g, "rt", 1));
9381088 lj->args.append(get_libc_crt_file(g, "libc_nonshared.a"));
9391089 } else if (target_is_musl(g)) {
940 //lj->args.append(build_musl(g)); TODO
1090 lj->args.append(build_libunwind(g));
1091 lj->args.append(build_musl(g));
9411092 } else {
9421093 zig_unreachable();
9431094 }
src/main.cpp+1
......@@ -10,6 +10,7 @@
1010#include "codegen.hpp"
1111#include "compiler.hpp"
1212#include "config.h"
13#include "install_files.h"
1314#include "error.hpp"
1415#include "os.hpp"
1516#include "target.hpp"