objects = {
/* Begin PBXBuildFile section */
- 3F2208E814358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; };
- 3F2208E914358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; };
- 3F2208EA14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; };
- 3F2208EB14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; };
- 3F2208EC14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; };
- 3F2208ED14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; };
- 3F2208EE14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; };
- 3F2208EF14358B4A00386F5B /* asl_fd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F2208E714358B4A00386F5B /* asl_fd.c */; };
+ 2B9D61B8157D667600AF25B8 /* trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9D61B5157D667000AF25B8 /* trace.c */; };
+ 2B9D61B9157D667600AF25B8 /* trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9D61B5157D667000AF25B8 /* trace.c */; };
+ 2B9D61BA157D667800AF25B8 /* trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9D61B5157D667000AF25B8 /* trace.c */; };
+ 2B9D61BB157D667900AF25B8 /* trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9D61B5157D667000AF25B8 /* trace.c */; };
+ 2B9D61BC157D667A00AF25B8 /* trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9D61B5157D667000AF25B8 /* trace.c */; };
+ 2B9D61BD157D667A00AF25B8 /* trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9D61B5157D667000AF25B8 /* trace.c */; };
+ 2B9D61BE157D667B00AF25B8 /* trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9D61B5157D667000AF25B8 /* trace.c */; };
+ 2B9D61BF157D667B00AF25B8 /* trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9D61B5157D667000AF25B8 /* trace.c */; };
+ 2B9D61C0157D667C00AF25B8 /* trace.c in Sources */ = {isa = PBXBuildFile; fileRef = 2B9D61B5157D667000AF25B8 /* trace.c */; };
+ 3F169A3E1643B7BA0029E851 /* memccpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F169A3C1643B7BA0029E851 /* memccpy_chk.c */; };
+ 3F18DE21162A732C008B15AC /* memset_s.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F18DE20162A732C008B15AC /* memset_s.c */; };
+ 3F267F38163FC8880089A0A6 /* rb.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F267F36163FC8880089A0A6 /* rb.c */; };
+ 3F51210416C317FD00AFB431 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
+ 3F51210516C317FD00AFB431 /* memccpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F169A3C1643B7BA0029E851 /* memccpy_chk.c */; };
+ 3F51210616C317FD00AFB431 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
+ 3F51210716C317FD00AFB431 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
+ 3F51210816C317FD00AFB431 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
+ 3F51210916C317FD00AFB431 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
+ 3F51210A16C317FD00AFB431 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
+ 3F51210B16C317FD00AFB431 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
+ 3F51210C16C317FD00AFB431 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
+ 3F51210D16C317FD00AFB431 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
+ 3F51210E16C317FD00AFB431 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
+ 3F51210F16C317FD00AFB431 /* strlcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3081643AB4300D37078 /* strlcat_chk.c */; };
+ 3F51211016C317FD00AFB431 /* strlcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3091643AB4300D37078 /* strlcpy_chk.c */; };
+ 3F51211116C317FD00AFB431 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
+ 3F51211216C317FD00AFB431 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
+ 3F51211316C317FD00AFB431 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
+ 3F51211416C317FD00AFB431 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
3F76864713E91CBC00C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; };
3F76864913E91CE800C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; };
3F76864A13E91D3700C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; };
3F76864D13E91D5500C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; };
3F76864E13E91D5D00C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; };
3F76864F13E91D6700C94D25 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; };
+ 3FA8F3251643AB8100D37078 /* strlcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3081643AB4300D37078 /* strlcat_chk.c */; };
+ 3FA8F3261643AB8100D37078 /* strlcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FA8F3091643AB4300D37078 /* strlcpy_chk.c */; };
3FB7E1B5146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; };
3FB7E1B6146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; };
3FB7E1B7146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; };
3FB7E1B9146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; };
3FB7E1BA146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; };
3FB7E1BB146EF2E000843438 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; };
+ 3FD14574171D42B300B7BAF5 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FD14572171D42B300B7BAF5 /* bcopy.c */; settings = {COMPILER_FLAGS = "-momit-leaf-frame-pointer"; }; };
+ 3FD14575171D42B300B7BAF5 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FD14572171D42B300B7BAF5 /* bcopy.c */; settings = {COMPILER_FLAGS = "-momit-leaf-frame-pointer"; }; };
+ 3FD14576171D42B300B7BAF5 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FD14572171D42B300B7BAF5 /* bcopy.c */; settings = {COMPILER_FLAGS = "-momit-leaf-frame-pointer"; }; };
3FD4D48E1472F4B200075CCE /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; };
+ 4B2C64A315519BC300342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
+ 4B2C64A415519BC400342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
+ 4B2C64A515519BC600342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
+ 4B2C64A615519BC600342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
+ 4B2C64A715519BC700342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
+ 4B2C64A815519BC700342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
+ 4B2C64A915519BC800342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
+ 4B2C64AA15519BCB00342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
+ 4B2C64BA1551B03700342BFA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = 4B2C64A215519BAF00342BFA /* assumes.c */; };
6310518713D4D966004F7BA8 /* strcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518613D4D966004F7BA8 /* strcpy.c */; };
6310518A13D4D9E9004F7BA8 /* strcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518613D4D966004F7BA8 /* strcpy.c */; };
6310518C13D4DABD004F7BA8 /* strlcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518B13D4DABD004F7BA8 /* strlcpy.c */; };
6310518D13D4DABD004F7BA8 /* strlcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518B13D4DABD004F7BA8 /* strlcpy.c */; };
6310518F13D4DAEA004F7BA8 /* strncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518E13D4DAEA004F7BA8 /* strncpy.c */; };
6310519013D4DAEA004F7BA8 /* strncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518E13D4DAEA004F7BA8 /* strncpy.c */; };
- 634C4C3813BCEADC008CA66D /* memset_pattern_Swift.s in Sources */ = {isa = PBXBuildFile; fileRef = 634C4C3713BCEADC008CA66D /* memset_pattern_Swift.s */; };
- 6358199113B53DD800CDF61C /* bzero_Swift.s in Sources */ = {isa = PBXBuildFile; fileRef = 6358199013B53DD800CDF61C /* bzero_Swift.s */; };
- 6358199313B53ECC00CDF61C /* bcopy_Swift.s in Sources */ = {isa = PBXBuildFile; fileRef = 6358199213B53ECB00CDF61C /* bcopy_Swift.s */; };
+ 63505E3B1548525D00B637D7 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 63505E3A1548525D00B637D7 /* strnlen.s */; };
+ 63505E3C1548525D00B637D7 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 63505E3A1548525D00B637D7 /* strnlen.s */; };
+ 63505E3D1548525D00B637D7 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 63505E3A1548525D00B637D7 /* strnlen.s */; };
+ 639D126A15595DDE00D0403A /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 639D126615595DDE00D0403A /* strnlen.s */; };
+ 639D126C15595DDE00D0403A /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = 639D126615595DDE00D0403A /* strnlen.s */; };
63D4060613DDEDF10094DD56 /* stpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060513DDEDF10094DD56 /* stpcpy.c */; };
63D4060813DDEDFF0094DD56 /* stpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060513DDEDF10094DD56 /* stpcpy.c */; };
63D4060A13DDEEA20094DD56 /* stpncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060913DDEEA10094DD56 /* stpncpy.c */; };
B122F2D31432B95B00AF95D0 /* tre-mem.c in Sources */ = {isa = PBXBuildFile; fileRef = B122F2BB1432B95B00AF95D0 /* tre-mem.c */; };
B122F2D51432B95B00AF95D0 /* tre-parse.c in Sources */ = {isa = PBXBuildFile; fileRef = B122F2BD1432B95B00AF95D0 /* tre-parse.c */; };
B122F2D71432B95B00AF95D0 /* tre-stack.c in Sources */ = {isa = PBXBuildFile; fileRef = B122F2BF1432B95B00AF95D0 /* tre-stack.c */; };
+ B12613F8158818EC0077E3CC /* xprintf_errno.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613EE158818EC0077E3CC /* xprintf_errno.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; };
+ B12613F9158818EC0077E3CC /* xprintf_float.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613EF158818EC0077E3CC /* xprintf_float.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; };
+ B12613FA158818EC0077E3CC /* xprintf_hexdump.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F0158818EC0077E3CC /* xprintf_hexdump.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; };
+ B12613FB158818EC0077E3CC /* xprintf_int.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F1158818EC0077E3CC /* xprintf_int.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; };
+ B12613FC158818EC0077E3CC /* xprintf_quote.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F3158818EC0077E3CC /* xprintf_quote.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; };
+ B12613FD158818EC0077E3CC /* xprintf_str.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F4158818EC0077E3CC /* xprintf_str.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; };
+ B12613FE158818EC0077E3CC /* xprintf_time.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F5158818EC0077E3CC /* xprintf_time.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; };
+ B12613FF158818EC0077E3CC /* xprintf_vis.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F6158818EC0077E3CC /* xprintf_vis.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; };
+ B1261400158818EC0077E3CC /* xprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = B12613F7158818EC0077E3CC /* xprintf.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio"; }; };
+ B126140515881A000077E3CC /* xprintf_comp.c in Sources */ = {isa = PBXBuildFile; fileRef = B126140215881A000077E3CC /* xprintf_comp.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio/FreeBSD"; }; };
+ B126140615881A000077E3CC /* xprintf_domain.c in Sources */ = {isa = PBXBuildFile; fileRef = B126140315881A000077E3CC /* xprintf_domain.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio/FreeBSD"; }; };
+ B1795373158B0E35008990E8 /* xprintf_all_in_one.c in Sources */ = {isa = PBXBuildFile; fileRef = B1795371158B0E35008990E8 /* xprintf_all_in_one.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio/FreeBSD"; }; };
+ B1795374158B0E35008990E8 /* xprintf_exec.c in Sources */ = {isa = PBXBuildFile; fileRef = B1795372158B0E35008990E8 /* xprintf_exec.c */; settings = {COMPILER_FLAGS = "-I$(SRCROOT)/stdio/FreeBSD"; }; };
B19C645C1450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; };
B19C645D1450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; };
B19C645E1450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; };
B19C64611450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; };
B19C64621450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; };
B19C64631450F90200032373 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; };
- B1E96442157E722200FCCEE7 /* printf-pos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA3138D9E990028D27C /* printf-pos.c */; };
- B1E9645F157E722200FCCEE7 /* vfprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEA138D9E990028D27C /* vfprintf.c */; };
- B1E96461157E722200FCCEE7 /* vfwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEE138D9E9A0028D27C /* vfwprintf.c */; };
+ C921D3891395B7DD001CE070 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C921D3831395B7DD001CE070 /* init_cpu_capabilities.c */; };
+ C921D38A1395B7DD001CE070 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3841395B7DD001CE070 /* pthread_getspecific.s */; };
+ C921D38B1395B7DD001CE070 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3851395B7DD001CE070 /* pthread_self.s */; };
+ C921D38C1395B7DD001CE070 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3861395B7DD001CE070 /* pthread_set_self.s */; };
+ C921D38D1395B7DD001CE070 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3871395B7DD001CE070 /* start_wqthread.s */; };
+ C921D38E1395B7DD001CE070 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3881395B7DD001CE070 /* thread_start.s */; };
C9257ED5138E1C2E00B3107C /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; };
C9257ED6138E1C2E00B3107C /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; };
C9257ED7138E1C2E00B3107C /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; };
C9257FD4138E1CC000B3107C /* makebuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B9C138D9E990028D27C /* makebuf.c */; };
C9257FD5138E1CC000B3107C /* mktemp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA0138D9E990028D27C /* mktemp.c */; };
C9257FD6138E1CC000B3107C /* perror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA2138D9E990028D27C /* perror.c */; };
+ C9257FD7138E1CC000B3107C /* printf-pos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA3138D9E990028D27C /* printf-pos.c */; };
C9257FD8138E1CC000B3107C /* printf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA7138D9E990028D27C /* printf.c */; };
C9257FD9138E1CC000B3107C /* putc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BAF138D9E990028D27C /* putc.c */; };
C9257FDA138E1CC000B3107C /* putchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB0138D9E990028D27C /* putchar.c */; };
C9257FF1138E1CC000B3107C /* ungetwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE4138D9E990028D27C /* ungetwc.c */; };
C9257FF2138E1CC000B3107C /* vasprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE6138D9E990028D27C /* vasprintf.c */; };
C9257FF3138E1CC000B3107C /* vdprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE8138D9E990028D27C /* vdprintf.c */; };
+ C9257FF4138E1CC000B3107C /* vfprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEA138D9E990028D27C /* vfprintf.c */; };
C9257FF5138E1CC000B3107C /* vfscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEC138D9E990028D27C /* vfscanf.c */; };
+ C9257FF6138E1CC000B3107C /* vfwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEE138D9E9A0028D27C /* vfwprintf.c */; };
C9257FF7138E1CC000B3107C /* vfwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF0138D9E9A0028D27C /* vfwscanf.c */; };
C9257FF8138E1CC000B3107C /* vprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF2138D9E9A0028D27C /* vprintf.c */; };
C9257FF9138E1CC000B3107C /* vscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF4138D9E9A0028D27C /* vscanf.c */; };
C925800A138E1CC000B3107C /* strptime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD3138D9E9A0028D27C /* strptime.c */; };
C925800B138E1CC000B3107C /* time32.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD6138D9E9A0028D27C /* time32.c */; };
C925800C138E1CC000B3107C /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; };
- C925800D138E1CD200B3107C /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; };
- C925800E138E1CD200B3107C /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; };
- C925800F138E1CD200B3107C /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; };
C9258010138E1CD200B3107C /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; };
- C9258011138E1CD200B3107C /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; };
- C9258012138E1CD200B3107C /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; };
- C9258013138E1CD200B3107C /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; };
- C9258014138E1CD200B3107C /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; };
C9258015138E1CD200B3107C /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; };
- C9258016138E1CD200B3107C /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; };
- C9258017138E1CD200B3107C /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; settings = {COMPILER_FLAGS = "-fno-builtin"; }; };
C9258018138E1CD200B3107C /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; };
C925801B138E1CD200B3107C /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; };
C925801C138E1CD200B3107C /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; };
- C925801E138E1CD200B3107C /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; };
- C925801F138E1CD200B3107C /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; };
C9258020138E1CD200B3107C /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; };
C9258022138E1CD200B3107C /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; };
C9258023138E1CD200B3107C /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; };
C9258024138E1CD200B3107C /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; };
C9258027138E1CD200B3107C /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; };
C9258028138E1CD200B3107C /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; };
- C925802A138E1CD200B3107C /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; };
C925802C138E1CD200B3107C /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; };
C925802D138E1CD200B3107C /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; };
C925802E138E1CD200B3107C /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; };
C9258055138E1CD200B3107C /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; };
C9258058138E1CDD00B3107C /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; };
C92580CC138E2D3100B3107C /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; };
- C9258122138E3CA100B3107C /* magmallocProvider.d in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D5138D9E990028D27C /* magmallocProvider.d */; };
- C932C2D013AB1C73004EDA12 /* SpinlocksWFE.c in Sources */ = {isa = PBXBuildFile; fileRef = C932C2CF13AB1C73004EDA12 /* SpinlocksWFE.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
- C932C2D313AB20C8004EDA12 /* OSAtomicUP.c in Sources */ = {isa = PBXBuildFile; fileRef = C995462713AAA25000A531B4 /* OSAtomicUP.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
- C932C2D413AB20C8004EDA12 /* Spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C97C344013AB0E1B00713550 /* Spinlocks.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
- C932C2D513AB20C8004EDA12 /* SpinlocksUP.c in Sources */ = {isa = PBXBuildFile; fileRef = C980F8EB13AB168D0069AB06 /* SpinlocksUP.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
- C932C2D613AB20C8004EDA12 /* SpinlocksWFE.c in Sources */ = {isa = PBXBuildFile; fileRef = C932C2CF13AB1C73004EDA12 /* SpinlocksWFE.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
+ C925D1FD1518F4A2003D315B /* eos_stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C925D1FB151805C6003D315B /* eos_stubs.c */; };
C9421014138F23CA004BA536 /* frune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E3138D9E990028D27C /* frune.c */; settings = {COMPILER_FLAGS = "-D__FBSDID=__RCSID"; }; };
C9421015138F23CA004BA536 /* mbrune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EB138D9E990028D27C /* mbrune.c */; settings = {COMPILER_FLAGS = "-D__FBSDID=__RCSID"; }; };
C9421016138F23CA004BA536 /* runedepreciated.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EF138D9E990028D27C /* runedepreciated.c */; settings = {COMPILER_FLAGS = "-D__FBSDID=__RCSID"; }; };
C9421024138F2661004BA536 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; };
C9421025138F2661004BA536 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; };
C942103213900C8A004BA536 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; };
- C942103313900C8A004BA536 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; };
- C942103413900C8A004BA536 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; };
- C942103513900C8A004BA536 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; };
- C942103613900C8A004BA536 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; };
- C942103713900C8A004BA536 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; };
C942103913900C8A004BA536 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; };
C942103A13900C8A004BA536 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; };
C942103B13900C8A004BA536 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; };
C942104413900C8A004BA536 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; };
C942104513900C8A004BA536 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; };
C942104613900C8A004BA536 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; };
- C942104713900C8A004BA536 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; };
- C942104813900C8A004BA536 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; };
- C942104913900C8A004BA536 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; };
C942104A13900C8A004BA536 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; };
C942104B13900C8A004BA536 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; };
C942104C13900C8A004BA536 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; };
C942108713900C8A004BA536 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; };
C942108813900C8A004BA536 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; };
C942108913900C8A004BA536 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; };
- C942108A13900C8A004BA536 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; };
- C942108B13900C8A004BA536 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; };
- C942108C13900C8A004BA536 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; };
- C942108D13900C8A004BA536 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; };
- C942108E13900C8A004BA536 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; };
- C942108F13900C8A004BA536 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; };
- C942109013900C8A004BA536 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; };
- C942109113900C8A004BA536 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; };
- C942109213900C8A004BA536 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; };
C942109313900C8A004BA536 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; };
C942109413900C8A004BA536 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; };
- C942109513900C8A004BA536 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; };
C942109613900C8A004BA536 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_CONFSTR"; }; };
C942109713900C8A004BA536 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY"; }; };
C942109813900C8A004BA536 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; };
C94210EC13900C8A004BA536 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; };
C94210ED13900C8A004BA536 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; };
C94210EE13900C8A004BA536 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; };
- C94210EF13900C8A004BA536 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; };
- C94210F013900C8A004BA536 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; };
- C94210F113900C8A004BA536 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; };
- C94210F213900C8A004BA536 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; };
C94210F313900C8A004BA536 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; };
C94210F413900C8A004BA536 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; };
C94210F513900C8A004BA536 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW"; }; };
C94210F613900C8A004BA536 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; };
C94210F713900C8A004BA536 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; };
C94210F813900C8A004BA536 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; };
- C94210F913900C8A004BA536 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; };
- C94210FA13900C8A004BA536 /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; };
C94210FB13900C8A004BA536 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; };
C94210FC13900C8A004BA536 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; };
- C94210FD13900C8A004BA536 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; };
- C94210FE13900C8A004BA536 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; };
C94210FF13900C8A004BA536 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; };
- C942110013900C8A004BA536 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; };
C942110113900C8A004BA536 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; };
C942110213900C8A004BA536 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; };
C942110313900C8A004BA536 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; };
C942110413900C8A004BA536 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; };
C942110613900C8A004BA536 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; };
- C942110713900C8A004BA536 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; };
- C942110813900C8A004BA536 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; };
- C942110913900C8A004BA536 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; };
- C942110A13900C8A004BA536 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; };
- C942110B13900C8A004BA536 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; };
- C942110C13900C8A004BA536 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; };
- C942110D13900C8A004BA536 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; };
- C942110E13900C8A004BA536 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; };
- C942110F13900C8A004BA536 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; };
- C942111013900C8A004BA536 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; };
- C942111113900C8A004BA536 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; };
- C942111313900C8A004BA536 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; };
C942112613900C8A004BA536 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; };
C942112713900C8A004BA536 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; };
C942112813900C8A004BA536 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; };
C942117B13900C8A004BA536 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; };
C942117C13900C8A004BA536 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; };
C942117D13900C8A004BA536 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; };
- C942118613900C8A004BA536 /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; };
- C942118713900C8A004BA536 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_CANCEL -DLIBC_ALIAS_PTHREAD_SETCANCELSTATE -DLIBC_ALIAS_PTHREAD_SETCANCELTYPE -DLIBC_ALIAS_PTHREAD_SIGMASK -DLIBC_ALIAS_PTHREAD_TESTCANCEL"; }; };
- C942118813900C8A004BA536 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; };
- C942118913900C8A004BA536 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_INIT"; }; };
- C942118A13900C8A004BA536 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY"; }; };
- C942118B13900C8A004BA536 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_RWLOCK_DESTROY -DLIBC_ALIAS_PTHREAD_RWLOCK_INIT -DLIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK"; }; };
- C942118C13900C8A004BA536 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; };
- C942118D13900C8A004BA536 /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; };
- C942118E13900C8A004BA536 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; };
C942119113900C8A004BA536 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; };
- C942119413900C8A004BA536 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
- C942119513900C8A004BA536 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
- C942119613900C8A004BA536 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
- C942119713900C8A004BA536 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
- C942119813900C8A004BA536 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
- C942119913900C8A004BA536 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
- C942119A13900C8A004BA536 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
- C942119B13900C8A004BA536 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
- C942119C13900C8A004BA536 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
- C942119D13900C8A004BA536 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
- C942119E13900C8A004BA536 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
- C942119F13900C8A004BA536 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
- C94211A013900C8A004BA536 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
- C94211A113900C8A004BA536 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
C94211A213900C8A004BA536 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; };
C94211A313900C8A004BA536 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; };
C94211A413900C8A004BA536 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; };
C942124413900C8A004BA536 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; };
C942124513900C8A004BA536 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; settings = {COMPILER_FLAGS = "-D_DARWIN_UNLIMITED_STREAMS"; }; };
C942124613900C8A004BA536 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; };
- C942124713900C8A004BA536 /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; };
- C942124813900C8A004BA536 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; };
- C942124913900C8A004BA536 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; };
C942124A13900C8A004BA536 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; };
- C942124B13900C8A004BA536 /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; };
- C942124C13900C8A004BA536 /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; };
- C942124D13900C8A004BA536 /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; };
- C942124E13900C8A004BA536 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; };
C942124F13900C8A004BA536 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; };
- C942125013900C8A004BA536 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; };
- C942125113900C8A004BA536 /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; settings = {COMPILER_FLAGS = "-fno-builtin"; }; };
C942125213900C8A004BA536 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; };
C942125513900C8A004BA536 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; };
C942125613900C8A004BA536 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; };
- C942125813900C8A004BA536 /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
- C942125913900C8A004BA536 /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; };
C942125A13900C8A004BA536 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; };
C942125C13900C8A004BA536 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; };
C942125D13900C8A004BA536 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
C942125E13900C8A004BA536 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRERROR"; }; };
C942126113900C8A004BA536 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; };
C942126213900C8A004BA536 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; };
- C942126413900C8A004BA536 /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
C942126613900C8A004BA536 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; };
C942126713900C8A004BA536 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; };
C942126813900C8A004BA536 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; };
C942129013900C8A004BA536 /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; };
C942129113900C8A004BA536 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; };
C942129213900C8A004BA536 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; };
- C942129313900C8A004BA536 /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; };
C942129413900C8A004BA536 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; };
- C942129513900C8A004BA536 /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; };
C942129613900C8A004BA536 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; };
C942129713900C8A004BA536 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; };
- C942129813900C8A004BA536 /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; };
C942129913900C8A004BA536 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; };
C942129A13900C8A004BA536 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_MSGCTL -DKERNEL"; }; };
C942129B13900C8A004BA536 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; };
C94212A113900C8A004BA536 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; };
C94212A213900C8A004BA536 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SHMCTL -DKERNEL"; }; };
C94212A313900C8A004BA536 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; };
- C94212A413900C8A004BA536 /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; };
- C94212A513900C8A004BA536 /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; };
- C94212A613900C8A004BA536 /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; };
C94212A713900C8A004BA536 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; };
C94212A813900C8A004BA536 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; };
- C94212A913900C8A004BA536 /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; };
- C94212AA13900C8A004BA536 /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; };
- C94212AB13900C8A004BA536 /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; };
C94212AC13900C8A004BA536 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; };
C94212AD13900C8A004BA536 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; };
C94212AE13900C8A004BA536 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; };
C94212B913900C8A004BA536 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; };
C94212BA13900C8A004BA536 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; };
C94212BB13900C8A004BA536 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; };
- C94212BC13900C8A004BA536 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; };
- C94212BD13900C8A004BA536 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; };
- C94212BE13900C8A004BA536 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; };
- C94212BF13900C8A004BA536 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; };
- C94212C013900C8A004BA536 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; };
- C94212C113900C8A004BA536 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; };
- C94212C213900C8A004BA536 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; };
- C94212C313900C8A004BA536 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; };
- C94212C413900C8A004BA536 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; };
- C94212C513900C8A004BA536 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; };
C94212C613900C8A004BA536 /* scandir_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB350E138F769B0075BB52 /* scandir_b.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; };
C94212D113900ED1004BA536 /* dirhelper.defs in Sources */ = {isa = PBXBuildFile; fileRef = C9B53614138D9E980028D27C /* dirhelper.defs */; };
- C94212D213900ED1004BA536 /* asl_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CA138D9E990028D27C /* asl_ipc.defs */; };
- C94212DE13901595004BA536 /* _ctx_start.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF1138D9E9A0028D27C /* _ctx_start.S */; };
- C94212DF13901595004BA536 /* _setcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF2138D9E9A0028D27C /* _setcontext.S */; };
- C94212E013901595004BA536 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF3138D9E9A0028D27C /* cpu_number.s */; };
- C94212E113901595004BA536 /* getcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF4138D9E9A0028D27C /* getcontext.S */; };
- C94212E213901595004BA536 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF6138D9E9A0028D27C /* icacheinval.s */; };
C94212E413901595004BA536 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF9138D9E9A0028D27C /* mcount.s */; };
- C94212E513901595004BA536 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB3555138F7F6A0075BB52 /* setjmperr.c */; };
- C94212E713901595004BA536 /* preempt.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFE138D9E9A0028D27C /* preempt.s */; };
- C94212E813901595004BA536 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFF138D9E9A0028D27C /* pthread_getspecific.s */; };
- C94212E913901595004BA536 /* pthread_mutex_lock.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E00138D9E9A0028D27C /* pthread_mutex_lock.s */; };
- C94212EA13901595004BA536 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E01138D9E9A0028D27C /* pthread_self.s */; };
- C94212EB13901595004BA536 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E02138D9E9A0028D27C /* pthread_set_self.s */; };
- C94212EC13901595004BA536 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E03138D9E9A0028D27C /* start_wqthread.s */; };
- C94212ED13901595004BA536 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E04138D9E9A0028D27C /* thread_start.s */; };
- C94212EF13901595004BA536 /* __bzero.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E08138D9E9A0028D27C /* __bzero.s */; };
- C94212F013901595004BA536 /* bcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0A138D9E9A0028D27C /* bcopy_sse3x.s */; };
- C94212F113901595004BA536 /* bcopy_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0B138D9E9A0028D27C /* bcopy_sse42.s */; };
- C94212F213901595004BA536 /* bzero_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0D138D9E9A0028D27C /* bzero_sse2.s */; };
- C94212F313901595004BA536 /* bzero_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0E138D9E9A0028D27C /* bzero_sse42.s */; };
- C94212F413901595004BA536 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0F138D9E9A0028D27C /* ffs.s */; };
- C94212F513901595004BA536 /* longcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E10138D9E9A0028D27C /* longcopy_sse3x.s */; };
- C94212F713901595004BA536 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E12138D9E9A0028D27C /* memcmp.s */; };
- C94212F813901595004BA536 /* memset.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E15138D9E9A0028D27C /* memset.s */; };
- C94212F913901595004BA536 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E16138D9E9A0028D27C /* strcmp.s */; };
C94212FA13901595004BA536 /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E17138D9E9A0028D27C /* strcpy.s */; };
- C94212FB13901595004BA536 /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E18138D9E9A0028D27C /* strlcat.s */; };
- C94212FC13901595004BA536 /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E19138D9E9A0028D27C /* strlcpy.s */; };
C94212FD13901595004BA536 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1A138D9E9A0028D27C /* strlen.s */; };
- C94212FE13901595004BA536 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1B138D9E9A0028D27C /* strncmp.s */; };
C94212FF13901595004BA536 /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1C138D9E9A0028D27C /* strncpy.s */; };
- C942130013901595004BA536 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1E138D9E9A0028D27C /* _setjmp.s */; };
- C942130113901595004BA536 /* _sigtramp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1F138D9E9A0028D27C /* _sigtramp.s */; };
- C942130213901595004BA536 /* i386_gettimeofday_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E21138D9E9A0028D27C /* i386_gettimeofday_asm.s */; };
- C942130413901595004BA536 /* nanotime.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E23138D9E9A0028D27C /* nanotime.s */; };
- C942130513901595004BA536 /* OSAtomic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E24138D9E9A0028D27C /* OSAtomic.s */; };
- C942130613901595004BA536 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E25138D9E9A0028D27C /* setjmp.s */; };
- C942130713901595004BA536 /* spinlocks_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E27138D9E9A0028D27C /* spinlocks_asm.s */; };
- C942130A13903959004BA536 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B1138D9E980028D27C /* cpu_number.s */; };
- C942130B13903959004BA536 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B2138D9E980028D27C /* icacheinval.s */; };
- C942130C13903959004BA536 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B8138D9E980028D27C /* pthread_getspecific.s */; };
- C942130D13903959004BA536 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B9138D9E980028D27C /* pthread_self.s */; };
- C942130E13903959004BA536 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BA138D9E980028D27C /* pthread_set_self.s */; };
- C942130F13903959004BA536 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BB138D9E980028D27C /* start_wqthread.s */; };
- C942131013903959004BA536 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BC138D9E980028D27C /* thread_start.s */; };
- C942131313903959004BA536 /* bcopy_Generic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C2138D9E980028D27C /* bcopy_Generic.s */; };
- C942131613903959004BA536 /* bzero_Generic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C5138D9E980028D27C /* bzero_Generic.s */; };
- C942131713903959004BA536 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C7138D9E980028D27C /* ffs.s */; };
- C942131813903959004BA536 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C9138D9E980028D27C /* memcmp.s */; };
- C942131913903959004BA536 /* memset_pattern.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CA138D9E980028D27C /* memset_pattern.s */; };
- C942131A13903959004BA536 /* strchr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CB138D9E980028D27C /* strchr.s */; };
- C942131B13903959004BA536 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CC138D9E980028D27C /* strcmp.s */; };
C942131E13903959004BA536 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CF138D9E980028D27C /* strlen.s */; };
- C942131F13903959004BA536 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D0138D9E980028D27C /* strncmp.s */; };
C942132113903959004BA536 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D2138D9E980028D27C /* strnlen.s */; };
C942132213903959004BA536 /* strstr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D3138D9E980028D27C /* strstr.s */; };
- C942132313903959004BA536 /* _longjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D5138D9E980028D27C /* _longjmp.s */; };
- C942132413903959004BA536 /* _setjmp.h in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D6138D9E980028D27C /* _setjmp.h */; };
- C942132513903959004BA536 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D7138D9E980028D27C /* _setjmp.s */; };
- C942132613903959004BA536 /* longjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DA138D9E980028D27C /* longjmp.s */; };
- C942132713903959004BA536 /* mach_absolute_time.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DB138D9E980028D27C /* mach_absolute_time.s */; };
- C942132913903959004BA536 /* OSAtomic_resolvers.h in Sources */ = {isa = PBXBuildFile; fileRef = C9B535E0138D9E980028D27C /* OSAtomic_resolvers.h */; };
- C942132A13903959004BA536 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535E1138D9E980028D27C /* setjmp.s */; };
- C94213311390396E004BA536 /* _ctx_start.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53811138D9E990028D27C /* _ctx_start.S */; };
- C94213321390396E004BA536 /* _setcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53812138D9E990028D27C /* _setcontext.S */; };
- C94213331390396E004BA536 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53813138D9E990028D27C /* cpu_number.s */; };
- C94213341390396E004BA536 /* getcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53814138D9E990028D27C /* getcontext.S */; };
- C94213351390396E004BA536 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53816138D9E990028D27C /* icacheinval.s */; };
C94213361390396E004BA536 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53819138D9E990028D27C /* mcount.s */; };
- C94213371390396E004BA536 /* preempt.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53820138D9E990028D27C /* preempt.s */; };
- C94213381390396E004BA536 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53821138D9E990028D27C /* pthread_getspecific.s */; };
- C94213391390396E004BA536 /* pthread_mutex_lock.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53822138D9E990028D27C /* pthread_mutex_lock.s */; };
- C942133A1390396E004BA536 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53823138D9E990028D27C /* pthread_self.s */; };
- C942133B1390396E004BA536 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53824138D9E990028D27C /* pthread_set_self.s */; };
- C942133C1390396E004BA536 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53825138D9E990028D27C /* start_wqthread.s */; };
- C942133D1390396E004BA536 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53826138D9E990028D27C /* thread_start.s */; };
- C942133E1390396E004BA536 /* __bzero.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382A138D9E990028D27C /* __bzero.s */; };
- C942133F1390396E004BA536 /* bcopy_scalar.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382C138D9E990028D27C /* bcopy_scalar.s */; };
- C94213401390396E004BA536 /* bcopy_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382D138D9E990028D27C /* bcopy_sse2.s */; };
- C94213411390396E004BA536 /* bcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382E138D9E990028D27C /* bcopy_sse3x.s */; };
- C94213421390396E004BA536 /* bcopy_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382F138D9E990028D27C /* bcopy_sse42.s */; };
- C94213431390396E004BA536 /* bzero_scalar.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53831138D9E990028D27C /* bzero_scalar.s */; };
- C94213441390396E004BA536 /* bzero_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53832138D9E990028D27C /* bzero_sse2.s */; };
- C94213451390396E004BA536 /* bzero_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53833138D9E990028D27C /* bzero_sse42.s */; };
- C94213461390396E004BA536 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53834138D9E990028D27C /* ffs.s */; };
- C94213471390396E004BA536 /* longcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53835138D9E990028D27C /* longcopy_sse3x.s */; };
- C94213481390396E004BA536 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53837138D9E990028D27C /* memcmp.s */; };
- C94213491390396E004BA536 /* memset.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383A138D9E990028D27C /* memset.s */; };
- C942134A1390396E004BA536 /* memset_pattern_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383B138D9E990028D27C /* memset_pattern_sse2.s */; };
- C942134B1390396E004BA536 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383C138D9E990028D27C /* strcmp.s */; };
C942134C1390396E004BA536 /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383D138D9E990028D27C /* strcpy.s */; };
C942134D1390396E004BA536 /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383E138D9E990028D27C /* strlcat.s */; };
C942134E1390396E004BA536 /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383F138D9E990028D27C /* strlcpy.s */; };
C942134F1390396E004BA536 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53840138D9E990028D27C /* strlen.s */; };
- C94213501390396E004BA536 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53841138D9E990028D27C /* strncmp.s */; };
C94213511390396E004BA536 /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53842138D9E990028D27C /* strncpy.s */; };
- C94213521390396E004BA536 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53844138D9E990028D27C /* _setjmp.s */; };
- C94213531390396E004BA536 /* _sigtramp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53845138D9E990028D27C /* _sigtramp.s */; };
- C94213541390396E004BA536 /* i386_gettimeofday_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53847138D9E990028D27C /* i386_gettimeofday_asm.s */; };
- C94213551390396E004BA536 /* mach_absolute_time_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53849138D9E990028D27C /* mach_absolute_time_asm.s */; };
- C94213561390396E004BA536 /* OSAtomic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384B138D9E990028D27C /* OSAtomic.s */; };
- C94213571390396E004BA536 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384C138D9E990028D27C /* setjmp.s */; };
- C94213581390396E004BA536 /* spinlocks_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384E138D9E990028D27C /* spinlocks_asm.s */; };
C95B7ED7138F3BEA004311DA /* rune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53989138D9E990028D27C /* rune.c */; };
C95B7EDD138F3C55004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; };
- C95B7EDE138F3C55004311DA /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; };
- C95B7EDF138F3C55004311DA /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; };
- C95B7EE0138F3C55004311DA /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; };
- C95B7EE1138F3C55004311DA /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; };
- C95B7EE2138F3C55004311DA /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; };
C95B7EE4138F3C55004311DA /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; };
C95B7EE5138F3C55004311DA /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; };
C95B7EE6138F3C55004311DA /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; };
C95B7EEF138F3C55004311DA /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; };
C95B7EF0138F3C55004311DA /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; };
C95B7EF1138F3C55004311DA /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; };
- C95B7EF2138F3C55004311DA /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; };
- C95B7EF3138F3C55004311DA /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; };
- C95B7EF4138F3C55004311DA /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; };
C95B7EF5138F3C55004311DA /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; };
C95B7EF6138F3C55004311DA /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; };
C95B7EF7138F3C55004311DA /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; };
C95B7F32138F3C55004311DA /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; };
C95B7F33138F3C55004311DA /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; };
C95B7F34138F3C55004311DA /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; };
- C95B7F35138F3C55004311DA /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; };
- C95B7F36138F3C55004311DA /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; };
- C95B7F37138F3C55004311DA /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; };
- C95B7F38138F3C55004311DA /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; };
- C95B7F39138F3C55004311DA /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; };
- C95B7F3A138F3C55004311DA /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; };
- C95B7F3B138F3C55004311DA /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; };
- C95B7F3C138F3C55004311DA /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; };
- C95B7F3D138F3C55004311DA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; };
C95B7F3E138F3C55004311DA /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; };
C95B7F3F138F3C55004311DA /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; };
- C95B7F40138F3C55004311DA /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; };
C95B7F41138F3C55004311DA /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; };
C95B7F42138F3C55004311DA /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; };
C95B7F43138F3C55004311DA /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; };
C95B7F97138F3C55004311DA /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; };
C95B7F98138F3C55004311DA /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; };
C95B7F99138F3C55004311DA /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; };
- C95B7F9A138F3C55004311DA /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; };
- C95B7F9B138F3C55004311DA /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; };
- C95B7F9C138F3C55004311DA /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; };
- C95B7F9D138F3C55004311DA /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; };
C95B7F9E138F3C55004311DA /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; };
C95B7F9F138F3C55004311DA /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; };
C95B7FA0138F3C55004311DA /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; };
C95B7FA1138F3C55004311DA /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; };
C95B7FA2138F3C55004311DA /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; };
C95B7FA3138F3C55004311DA /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; };
- C95B7FA4138F3C55004311DA /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; };
- C95B7FA5138F3C55004311DA /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; };
C95B7FA6138F3C55004311DA /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; };
C95B7FA7138F3C55004311DA /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; };
- C95B7FA8138F3C55004311DA /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; };
- C95B7FA9138F3C55004311DA /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; };
C95B7FAA138F3C55004311DA /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; };
- C95B7FAB138F3C55004311DA /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; };
C95B7FAC138F3C55004311DA /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; };
C95B7FAD138F3C55004311DA /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; };
C95B7FAE138F3C55004311DA /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; };
C95B7FAF138F3C55004311DA /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; };
C95B7FB1138F3C55004311DA /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; };
- C95B7FB2138F3C55004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; };
- C95B7FB3138F3C55004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; };
- C95B7FB4138F3C55004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; };
- C95B7FB5138F3C55004311DA /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; };
- C95B7FB6138F3C55004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; };
- C95B7FB7138F3C55004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; };
- C95B7FB8138F3C55004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; };
- C95B7FB9138F3C55004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; };
- C95B7FBA138F3C55004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; };
- C95B7FBB138F3C55004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; };
- C95B7FBC138F3C55004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; };
- C95B7FBE138F3C55004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; };
C95B7FD1138F3C55004311DA /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; };
C95B7FD2138F3C55004311DA /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; };
C95B7FD3138F3C55004311DA /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; };
C95B8026138F3C55004311DA /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; };
C95B8027138F3C55004311DA /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; };
C95B8028138F3C55004311DA /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; };
- C95B8031138F3C55004311DA /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; };
- C95B8032138F3C55004311DA /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; };
- C95B8033138F3C55004311DA /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; };
- C95B8034138F3C55004311DA /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; };
- C95B8035138F3C55004311DA /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; };
- C95B8036138F3C55004311DA /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; };
- C95B8037138F3C55004311DA /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; };
- C95B8038138F3C55004311DA /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; };
- C95B8039138F3C55004311DA /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; };
C95B803C138F3C55004311DA /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; };
- C95B803F138F3C55004311DA /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
- C95B8040138F3C55004311DA /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
- C95B8041138F3C55004311DA /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
- C95B8042138F3C55004311DA /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
- C95B8043138F3C55004311DA /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
- C95B8044138F3C55004311DA /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
- C95B8045138F3C55004311DA /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
- C95B8046138F3C55004311DA /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
- C95B8047138F3C55004311DA /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
- C95B8048138F3C55004311DA /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
- C95B8049138F3C55004311DA /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
- C95B804A138F3C55004311DA /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
- C95B804B138F3C55004311DA /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
- C95B804C138F3C55004311DA /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
C95B804D138F3C55004311DA /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; };
C95B804E138F3C55004311DA /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; };
C95B804F138F3C55004311DA /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; };
C95B80EF138F3C55004311DA /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; };
C95B80F0138F3C55004311DA /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; };
C95B80F1138F3C55004311DA /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; };
- C95B80F2138F3C55004311DA /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; };
- C95B80F3138F3C55004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; };
- C95B80F4138F3C55004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; };
C95B80F5138F3C55004311DA /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; };
- C95B80F6138F3C55004311DA /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; };
- C95B80F7138F3C55004311DA /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; };
- C95B80F8138F3C55004311DA /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; };
- C95B80F9138F3C55004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; };
C95B80FA138F3C55004311DA /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; };
- C95B80FB138F3C55004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; };
- C95B80FC138F3C55004311DA /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; };
C95B80FD138F3C55004311DA /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; };
C95B8100138F3C55004311DA /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; };
C95B8101138F3C55004311DA /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; };
- C95B8103138F3C55004311DA /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; };
- C95B8104138F3C55004311DA /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; };
C95B8105138F3C55004311DA /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; };
C95B8107138F3C55004311DA /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; };
C95B8108138F3C55004311DA /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; };
C95B8109138F3C55004311DA /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; };
C95B810C138F3C55004311DA /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; };
C95B810D138F3C55004311DA /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; };
- C95B810F138F3C55004311DA /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; };
C95B8111138F3C55004311DA /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; };
C95B8112138F3C55004311DA /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; };
C95B8113138F3C55004311DA /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; };
C95B813B138F3C55004311DA /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; };
C95B813C138F3C55004311DA /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; };
C95B813D138F3C55004311DA /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; };
- C95B813E138F3C55004311DA /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; };
C95B813F138F3C55004311DA /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; };
- C95B8140138F3C55004311DA /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; };
C95B8141138F3C55004311DA /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; };
C95B8142138F3C55004311DA /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; };
- C95B8143138F3C55004311DA /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; };
C95B8144138F3C55004311DA /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; };
C95B8145138F3C55004311DA /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; };
C95B8146138F3C55004311DA /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; };
C95B814C138F3C55004311DA /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; };
C95B814D138F3C55004311DA /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; };
C95B814E138F3C55004311DA /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; };
- C95B814F138F3C55004311DA /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; };
- C95B8150138F3C55004311DA /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; };
- C95B8151138F3C55004311DA /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; };
C95B8152138F3C55004311DA /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; };
C95B8153138F3C55004311DA /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; };
- C95B8154138F3C55004311DA /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; };
- C95B8155138F3C55004311DA /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; };
- C95B8156138F3C55004311DA /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; };
C95B8157138F3C55004311DA /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; };
C95B8158138F3C55004311DA /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; };
C95B8159138F3C55004311DA /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; };
C95B8164138F3C55004311DA /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; };
C95B8165138F3C55004311DA /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; };
C95B8166138F3C55004311DA /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; };
- C95B8167138F3C55004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; };
- C95B8168138F3C55004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; };
- C95B8169138F3C55004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; };
- C95B816A138F3C55004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; };
- C95B816B138F3C55004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; };
- C95B816C138F3C55004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; };
- C95B816D138F3C55004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; };
- C95B816E138F3C55004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; };
- C95B816F138F3C55004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; };
- C95B8170138F3C55004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; };
C95B8188138F52B0004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; };
- C95B8189138F52B0004311DA /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; };
- C95B818A138F52B0004311DA /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; };
- C95B818B138F52B0004311DA /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; };
- C95B818C138F52B0004311DA /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; };
- C95B818D138F52B0004311DA /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; };
C95B818F138F52B0004311DA /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; };
C95B8190138F52B0004311DA /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; };
C95B8191138F52B0004311DA /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; };
C95B819A138F52B0004311DA /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; };
C95B819B138F52B0004311DA /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; };
C95B819C138F52B0004311DA /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; };
- C95B819D138F52B0004311DA /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; };
- C95B819E138F52B0004311DA /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; };
- C95B819F138F52B0004311DA /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; };
C95B81A0138F52B0004311DA /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; };
C95B81A1138F52B0004311DA /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; };
C95B81A2138F52B0004311DA /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; };
C95B81DD138F52B0004311DA /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; };
C95B81DE138F52B0004311DA /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; };
C95B81DF138F52B0004311DA /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; };
- C95B81E0138F52B0004311DA /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; };
- C95B81E1138F52B0004311DA /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; };
- C95B81E2138F52B0004311DA /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; };
- C95B81E3138F52B0004311DA /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; };
- C95B81E4138F52B0004311DA /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; };
- C95B81E5138F52B0004311DA /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; };
- C95B81E6138F52B0004311DA /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; };
- C95B81E7138F52B0004311DA /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; };
- C95B81E8138F52B0004311DA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; };
C95B81E9138F52B0004311DA /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; };
C95B81EA138F52B0004311DA /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; };
- C95B81EB138F52B0004311DA /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; };
C95B81EC138F52B0004311DA /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; };
C95B81ED138F52B0004311DA /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; };
C95B81EE138F52B0004311DA /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; };
C95B8216138F52B0004311DA /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; };
C95B8217138F52B0004311DA /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; };
C95B8218138F52B0004311DA /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; };
- C95B8219138F52B0004311DA /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PSELECT"; }; };
+ C95B8219138F52B0004311DA /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PSELECT -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; };
C95B821A138F52B0004311DA /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; };
C95B821B138F52B0004311DA /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; };
C95B821C138F52B0004311DA /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; };
C95B8242138F52B0004311DA /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; };
C95B8243138F52B0004311DA /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; };
C95B8244138F52B0004311DA /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; };
- C95B8245138F52B0004311DA /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; };
- C95B8246138F52B0004311DA /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; };
- C95B8247138F52B0004311DA /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; };
- C95B8248138F52B0004311DA /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; };
C95B8249138F52B0004311DA /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; };
C95B824A138F52B0004311DA /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; };
C95B824B138F52B0004311DA /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; };
C95B824C138F52B0004311DA /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; };
C95B824D138F52B0004311DA /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; };
C95B824E138F52B0004311DA /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; };
- C95B824F138F52B0004311DA /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; };
- C95B8250138F52B0004311DA /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; };
C95B8251138F52B0004311DA /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; };
C95B8252138F52B0004311DA /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; };
- C95B8253138F52B0004311DA /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; };
- C95B8254138F52B0004311DA /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; };
C95B8255138F52B0004311DA /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; };
- C95B8256138F52B0004311DA /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; };
C95B8257138F52B0004311DA /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; };
C95B8258138F52B0004311DA /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; };
C95B8259138F52B0004311DA /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; };
C95B825A138F52B0004311DA /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; };
C95B825C138F52B0004311DA /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; };
- C95B825D138F52B0004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; };
- C95B825E138F52B0004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; };
- C95B825F138F52B0004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; };
- C95B8260138F52B0004311DA /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; };
- C95B8261138F52B0004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; };
- C95B8262138F52B0004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; };
- C95B8263138F52B0004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; };
- C95B8264138F52B0004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; };
- C95B8265138F52B0004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; };
- C95B8266138F52B0004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; };
- C95B8267138F52B0004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; };
- C95B8269138F52B0004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; };
C95B827C138F52B0004311DA /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; };
C95B827D138F52B0004311DA /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; };
C95B827E138F52B0004311DA /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; };
C95B82D1138F52B0004311DA /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; };
C95B82D2138F52B0004311DA /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; };
C95B82D3138F52B0004311DA /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; };
- C95B82DC138F52B0004311DA /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; };
- C95B82DD138F52B0004311DA /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; };
- C95B82DE138F52B0004311DA /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; };
- C95B82DF138F52B0004311DA /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; };
- C95B82E0138F52B0004311DA /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; };
- C95B82E1138F52B0004311DA /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; };
- C95B82E2138F52B0004311DA /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; };
- C95B82E3138F52B0004311DA /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; };
- C95B82E4138F52B0004311DA /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; };
C95B82E7138F52B0004311DA /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; };
- C95B82EA138F52B0004311DA /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
- C95B82EB138F52B0004311DA /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
- C95B82EC138F52B0004311DA /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
- C95B82ED138F52B0004311DA /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
- C95B82EE138F52B0004311DA /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
- C95B82EF138F52B0004311DA /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
- C95B82F0138F52B0004311DA /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
- C95B82F1138F52B0004311DA /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
- C95B82F2138F52B0004311DA /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
- C95B82F3138F52B0004311DA /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
- C95B82F4138F52B0004311DA /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
- C95B82F5138F52B0004311DA /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
- C95B82F6138F52B0004311DA /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
- C95B82F7138F52B0004311DA /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
C95B82F8138F52B0004311DA /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; };
C95B82F9138F52B0004311DA /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; };
C95B82FA138F52B0004311DA /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; };
C95B839A138F52B0004311DA /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; };
C95B839B138F52B0004311DA /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; };
C95B839C138F52B0004311DA /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; };
- C95B839D138F52B0004311DA /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; };
- C95B839E138F52B0004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; };
- C95B839F138F52B0004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; };
C95B83A0138F52B0004311DA /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; };
- C95B83A1138F52B0004311DA /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; };
- C95B83A2138F52B0004311DA /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; };
- C95B83A3138F52B0004311DA /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; };
- C95B83A4138F52B0004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; };
C95B83A5138F52B0004311DA /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; };
- C95B83A6138F52B0004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; };
- C95B83A7138F52B0004311DA /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; };
C95B83A8138F52B0004311DA /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; };
C95B83AB138F52B0004311DA /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; };
C95B83AC138F52B0004311DA /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; };
- C95B83AE138F52B0004311DA /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; };
- C95B83AF138F52B0004311DA /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; };
C95B83B0138F52B0004311DA /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; };
C95B83B2138F52B0004311DA /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; };
C95B83B3138F52B0004311DA /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; };
C95B83B4138F52B0004311DA /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; };
C95B83B7138F52B0004311DA /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; };
C95B83B8138F52B0004311DA /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; };
- C95B83BA138F52B0004311DA /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; };
C95B83BC138F52B0004311DA /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; };
C95B83BD138F52B0004311DA /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; };
C95B83BE138F52B0004311DA /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; };
C95B83E6138F52B0004311DA /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; };
C95B83E7138F52B0004311DA /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; };
C95B83E8138F52B0004311DA /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; };
- C95B83E9138F52B0004311DA /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; };
C95B83EA138F52B0004311DA /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; };
- C95B83EB138F52B0004311DA /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; };
C95B83EC138F52B0004311DA /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; };
C95B83ED138F52B0004311DA /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; };
- C95B83EE138F52B0004311DA /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; };
C95B83EF138F52B0004311DA /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; };
C95B83F0138F52B0004311DA /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; };
C95B83F1138F52B0004311DA /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; };
C95B83F7138F52B0004311DA /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; };
C95B83F8138F52B0004311DA /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; };
C95B83F9138F52B0004311DA /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; };
- C95B83FA138F52B0004311DA /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; };
- C95B83FB138F52B0004311DA /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; };
- C95B83FC138F52B0004311DA /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; };
C95B83FD138F52B0004311DA /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; };
C95B83FE138F52B0004311DA /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; };
- C95B83FF138F52B0004311DA /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; };
- C95B8400138F52B0004311DA /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; };
- C95B8401138F52B0004311DA /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; };
C95B8402138F52B0004311DA /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; };
C95B8403138F52B0004311DA /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; };
C95B8404138F52B0004311DA /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; };
C95B840F138F52B0004311DA /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; };
C95B8410138F52B0004311DA /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; };
C95B8411138F52B0004311DA /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; };
- C95B8412138F52B0004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; };
- C95B8413138F52B0004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; };
- C95B8414138F52B0004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; };
- C95B8415138F52B0004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; };
- C95B8416138F52B0004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; };
- C95B8417138F52B0004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; };
- C95B8418138F52B0004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; };
- C95B8419138F52B0004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; };
- C95B841A138F52B0004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; };
- C95B841B138F52B0004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; };
C95B842E138F53DB004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; };
- C95B842F138F53DB004311DA /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; };
- C95B8430138F53DB004311DA /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; };
- C95B8431138F53DB004311DA /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; };
- C95B8432138F53DB004311DA /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; };
- C95B8433138F53DB004311DA /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; };
C95B8435138F53DB004311DA /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; };
C95B8436138F53DB004311DA /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; };
C95B8437138F53DB004311DA /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; };
C95B8440138F53DB004311DA /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; };
C95B8441138F53DB004311DA /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; };
C95B8442138F53DB004311DA /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; };
- C95B8443138F53DB004311DA /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; };
- C95B8444138F53DB004311DA /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; };
- C95B8445138F53DB004311DA /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; };
C95B8446138F53DB004311DA /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; };
C95B8447138F53DB004311DA /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; };
C95B8448138F53DB004311DA /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; };
C95B8483138F53DB004311DA /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; };
C95B8484138F53DB004311DA /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; };
C95B8485138F53DB004311DA /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; };
- C95B8486138F53DB004311DA /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; };
- C95B8487138F53DB004311DA /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; };
- C95B8488138F53DB004311DA /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; };
- C95B8489138F53DB004311DA /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; };
- C95B848A138F53DB004311DA /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; };
- C95B848B138F53DB004311DA /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; };
- C95B848C138F53DB004311DA /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; };
- C95B848D138F53DB004311DA /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; };
- C95B848E138F53DB004311DA /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; };
C95B848F138F53DB004311DA /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; };
C95B8490138F53DB004311DA /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; };
- C95B8491138F53DB004311DA /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; };
C95B8492138F53DB004311DA /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; };
C95B8493138F53DB004311DA /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; };
C95B8494138F53DB004311DA /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; };
C95B84BC138F53DB004311DA /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; };
C95B84BD138F53DB004311DA /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; };
C95B84BE138F53DB004311DA /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; };
- C95B84BF138F53DB004311DA /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PSELECT $(FreeBSD_CFLAGS)"; }; };
+ C95B84BF138F53DB004311DA /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PSELECT $(FreeBSD_CFLAGS) -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; };
C95B84C0138F53DB004311DA /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; };
C95B84C1138F53DB004311DA /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; };
C95B84C2138F53DB004311DA /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; };
C95B84E8138F53DB004311DA /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; };
C95B84E9138F53DB004311DA /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; };
C95B84EA138F53DB004311DA /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; };
- C95B84EB138F53DB004311DA /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; };
- C95B84EC138F53DB004311DA /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; };
- C95B84ED138F53DB004311DA /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; };
- C95B84EE138F53DB004311DA /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; };
C95B84EF138F53DB004311DA /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; };
C95B84F0138F53DB004311DA /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; };
C95B84F1138F53DB004311DA /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; };
C95B84F2138F53DB004311DA /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; };
C95B84F3138F53DB004311DA /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; };
C95B84F4138F53DB004311DA /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; };
- C95B84F5138F53DB004311DA /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; };
- C95B84F6138F53DB004311DA /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; };
C95B84F7138F53DB004311DA /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; };
C95B84F8138F53DB004311DA /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; };
- C95B84F9138F53DB004311DA /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; };
- C95B84FA138F53DB004311DA /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; };
C95B84FB138F53DB004311DA /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; };
- C95B84FC138F53DB004311DA /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; };
C95B84FD138F53DB004311DA /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; };
C95B84FE138F53DB004311DA /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; };
C95B84FF138F53DB004311DA /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; };
C95B8500138F53DB004311DA /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; };
C95B8502138F53DB004311DA /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; };
- C95B8503138F53DB004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; };
- C95B8504138F53DB004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; };
- C95B8505138F53DB004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; };
- C95B8506138F53DB004311DA /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; };
- C95B8507138F53DB004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; };
- C95B8508138F53DB004311DA /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; };
- C95B8509138F53DB004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; };
- C95B850A138F53DB004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; };
- C95B850B138F53DB004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; };
- C95B850C138F53DB004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; };
- C95B850D138F53DB004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; };
- C95B850F138F53DB004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; };
C95B8522138F53DB004311DA /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; };
C95B8523138F53DB004311DA /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; };
C95B8524138F53DB004311DA /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; };
C95B8577138F53DB004311DA /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; };
C95B8578138F53DB004311DA /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; };
C95B8579138F53DB004311DA /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; };
- C95B8582138F53DB004311DA /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; };
- C95B8583138F53DB004311DA /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; };
- C95B8584138F53DB004311DA /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; };
- C95B8585138F53DB004311DA /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; };
- C95B8586138F53DB004311DA /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; };
- C95B8587138F53DB004311DA /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; };
- C95B8588138F53DB004311DA /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; };
- C95B8589138F53DB004311DA /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; };
- C95B858A138F53DB004311DA /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; };
C95B858D138F53DB004311DA /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; };
- C95B8590138F53DB004311DA /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
- C95B8591138F53DB004311DA /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
- C95B8592138F53DB004311DA /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
- C95B8593138F53DB004311DA /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
- C95B8594138F53DB004311DA /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
- C95B8595138F53DB004311DA /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
- C95B8596138F53DB004311DA /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
- C95B8597138F53DB004311DA /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
- C95B8598138F53DB004311DA /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
- C95B8599138F53DB004311DA /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
- C95B859A138F53DB004311DA /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
- C95B859B138F53DB004311DA /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
- C95B859C138F53DB004311DA /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
- C95B859D138F53DB004311DA /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
C95B859E138F53DB004311DA /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; };
C95B859F138F53DB004311DA /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; };
C95B85A0138F53DB004311DA /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; };
C95B8640138F53DB004311DA /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; };
C95B8641138F53DB004311DA /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; };
C95B8642138F53DB004311DA /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; };
- C95B8643138F53DB004311DA /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; };
- C95B8644138F53DB004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; };
- C95B8645138F53DB004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; };
C95B8646138F53DB004311DA /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; };
- C95B8647138F53DB004311DA /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; };
- C95B8648138F53DB004311DA /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; };
- C95B8649138F53DB004311DA /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; };
- C95B864A138F53DB004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; };
C95B864B138F53DB004311DA /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; };
- C95B864C138F53DB004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; };
- C95B864D138F53DB004311DA /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; };
C95B864E138F53DB004311DA /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; };
C95B8651138F53DB004311DA /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; };
C95B8652138F53DB004311DA /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; };
- C95B8654138F53DB004311DA /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; };
- C95B8655138F53DB004311DA /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; };
C95B8656138F53DB004311DA /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; };
C95B8658138F53DB004311DA /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; };
C95B8659138F53DB004311DA /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; };
C95B865A138F53DB004311DA /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; };
C95B865D138F53DB004311DA /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; };
C95B865E138F53DB004311DA /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; };
- C95B8660138F53DB004311DA /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; };
C95B8662138F53DB004311DA /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; };
C95B8663138F53DB004311DA /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; };
C95B8664138F53DB004311DA /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; };
C95B868C138F53DB004311DA /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; };
C95B868D138F53DB004311DA /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; };
C95B868E138F53DB004311DA /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; };
- C95B868F138F53DB004311DA /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; };
C95B8690138F53DB004311DA /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; };
- C95B8691138F53DB004311DA /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; };
C95B8692138F53DB004311DA /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; };
C95B8693138F53DB004311DA /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; };
- C95B8694138F53DB004311DA /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; };
C95B8695138F53DB004311DA /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; };
C95B8696138F53DB004311DA /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; };
C95B8697138F53DB004311DA /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; };
C95B869D138F53DB004311DA /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; };
C95B869E138F53DB004311DA /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; };
C95B869F138F53DB004311DA /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; };
- C95B86A0138F53DB004311DA /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; };
- C95B86A1138F53DB004311DA /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; };
- C95B86A2138F53DB004311DA /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; };
C95B86A3138F53DB004311DA /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; };
C95B86A4138F53DB004311DA /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; };
- C95B86A5138F53DB004311DA /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; };
- C95B86A6138F53DB004311DA /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; };
- C95B86A7138F53DB004311DA /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; };
C95B86A8138F53DB004311DA /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; };
C95B86A9138F53DB004311DA /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; };
C95B86AA138F53DB004311DA /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; };
C95B86B5138F53DB004311DA /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; };
C95B86B6138F53DB004311DA /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; };
C95B86B7138F53DB004311DA /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; };
- C95B86B8138F53DB004311DA /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; };
- C95B86B9138F53DB004311DA /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; };
- C95B86BA138F53DB004311DA /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; };
- C95B86BB138F53DB004311DA /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; };
- C95B86BC138F53DB004311DA /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; };
- C95B86BD138F53DB004311DA /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; };
- C95B86BE138F53DB004311DA /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; };
- C95B86BF138F53DB004311DA /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; };
- C95B86C0138F53DB004311DA /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; };
- C95B86C1138F53DB004311DA /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; };
C965CBF2143BBEC7003912CE /* deps.c in Sources */ = {isa = PBXBuildFile; fileRef = C965CBF1143BBEC7003912CE /* deps.c */; };
C9765EB2138EC61900741512 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; };
- C9765EB3138EC61900741512 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; };
- C9765EB4138EC61900741512 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; };
- C9765EB5138EC61900741512 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; };
- C9765EB6138EC61900741512 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; };
- C9765EB7138EC61900741512 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; };
C9765EB9138EC61900741512 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; };
C9765EBA138EC61900741512 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; };
C9765EBB138EC61900741512 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; };
C9765EC4138EC61900741512 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; };
C9765EC5138EC61900741512 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; };
C9765EC6138EC61900741512 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; };
- C9765EC7138EC61900741512 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; };
- C9765EC8138EC61900741512 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; };
- C9765EC9138EC61900741512 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; };
C9765ECA138EC61900741512 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; };
C9765ECB138EC61900741512 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; };
C9765ECC138EC61900741512 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; };
C9765F07138EC61900741512 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; };
C9765F08138EC61900741512 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; };
C9765F09138EC61900741512 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; };
- C9765F0A138EC61900741512 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; };
- C9765F0B138EC61900741512 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; };
- C9765F0C138EC61900741512 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; };
- C9765F0D138EC61900741512 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; };
- C9765F0E138EC61900741512 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; };
- C9765F0F138EC61900741512 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; };
- C9765F10138EC61900741512 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; };
- C9765F11138EC61900741512 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; };
- C9765F12138EC61900741512 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; };
C9765F13138EC61900741512 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; };
C9765F14138EC61900741512 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; };
- C9765F15138EC61900741512 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; };
C9765F16138EC61900741512 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; };
C9765F17138EC61900741512 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; };
C9765F18138EC61900741512 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; };
C9765F3E138EC61900741512 /* nice.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374C138D9E990028D27C /* nice.c */; };
C9765F3F138EC61900741512 /* nrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374E138D9E990028D27C /* nrand48.c */; };
C9765F40138EC61900741512 /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; };
- C9765F41138EC61900741512 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; };
+ C9765F41138EC61900741512 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; };
C9765F42138EC61900741512 /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; };
- C9765F43138EC61900741512 /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PSELECT"; }; };
+ C9765F43138EC61900741512 /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PSELECT -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; };
C9765F44138EC61900741512 /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; };
C9765F45138EC61900741512 /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; };
C9765F46138EC61900741512 /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; };
C9765F4F138EC61900741512 /* siginterrupt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377C138D9E990028D27C /* siginterrupt.c */; };
C9765F50138EC61900741512 /* siglist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377D138D9E990028D27C /* siglist.c */; };
C9765F51138EC61900741512 /* signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53781138D9E990028D27C /* signal.c */; };
- C9765F52138EC61900741512 /* sleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53787138D9E990028D27C /* sleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SLEEP"; }; };
+ C9765F52138EC61900741512 /* sleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53787138D9E990028D27C /* sleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SLEEP -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; };
C9765F53138EC61900741512 /* srand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53789138D9E990028D27C /* srand48.c */; };
C9765F54138EC61900741512 /* stringlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378C138D9E990028D27C /* stringlist.c */; };
C9765F55138EC61900741512 /* sysconf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378E138D9E990028D27C /* sysconf.c */; };
C9765F60138EC61900741512 /* ualarm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537AC138D9E990028D27C /* ualarm.c */; };
C9765F61138EC61900741512 /* ulimit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B0138D9E990028D27C /* ulimit.c */; };
C9765F62138EC61900741512 /* unvis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B2138D9E990028D27C /* unvis.c */; };
- C9765F63138EC61900741512 /* usleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B6138D9E990028D27C /* usleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_USLEEP"; }; };
+ C9765F63138EC61900741512 /* usleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B6138D9E990028D27C /* usleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_USLEEP -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0"; }; };
C9765F64138EC61900741512 /* utime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BA138D9E990028D27C /* utime.c */; };
C9765F65138EC61900741512 /* vis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BC138D9E990028D27C /* vis.c */; };
C9765F66138EC61900741512 /* wait.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BE138D9E990028D27C /* wait.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAIT"; }; };
C9765F6C138EC61900741512 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; };
C9765F6D138EC61900741512 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; };
C9765F6E138EC61900741512 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; };
- C9765F6F138EC61900741512 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; };
- C9765F70138EC61900741512 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; };
- C9765F71138EC61900741512 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; };
- C9765F72138EC61900741512 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; };
C9765F73138EC61900741512 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; };
C9765F74138EC61900741512 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; };
C9765F75138EC61900741512 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; };
C9765F76138EC61900741512 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; };
C9765F77138EC61900741512 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; };
C9765F78138EC61900741512 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; };
- C9765F79138EC61900741512 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; };
- C9765F7A138EC61900741512 /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; };
C9765F7B138EC61900741512 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; };
C9765F7C138EC61900741512 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; };
- C9765F7D138EC61900741512 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; };
- C9765F7E138EC61900741512 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; };
C9765F7F138EC61900741512 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; };
- C9765F80138EC61900741512 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; };
C9765F81138EC61900741512 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; };
C9765F82138EC61900741512 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; };
C9765F83138EC61900741512 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; };
C9765F84138EC61900741512 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; };
C9765F86138EC61900741512 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; };
- C9765F87138EC61900741512 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; };
- C9765F88138EC61900741512 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; };
- C9765F89138EC61900741512 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; };
- C9765F8A138EC61900741512 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; };
- C9765F8B138EC61900741512 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; };
- C9765F8C138EC61900741512 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; };
- C9765F8D138EC61900741512 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; };
- C9765F8E138EC61900741512 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; };
- C9765F8F138EC61900741512 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; };
- C9765F90138EC61900741512 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; };
- C9765F91138EC61900741512 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; };
- C9765F93138EC61900741512 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; };
C9765FA6138EC61900741512 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; };
C9765FA7138EC61900741512 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; };
C9765FA8138EC61900741512 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; };
C9765FFB138EC61900741512 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; };
C9765FFC138EC61900741512 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; };
C9765FFD138EC61900741512 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; };
- C9766006138EC61900741512 /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; };
- C9766007138EC61900741512 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; };
- C9766008138EC61900741512 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; };
- C9766009138EC61900741512 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; };
- C976600A138EC61900741512 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; };
- C976600B138EC61900741512 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; };
- C976600C138EC61900741512 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; };
- C976600D138EC61900741512 /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; };
- C976600E138EC61900741512 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; };
C9766011138EC61900741512 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; };
- C9766014138EC61900741512 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
- C9766015138EC61900741512 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
- C9766016138EC61900741512 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
- C9766017138EC61900741512 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
- C9766018138EC61900741512 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
- C9766019138EC61900741512 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
- C976601A138EC61A00741512 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
- C976601B138EC61A00741512 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
- C976601C138EC61A00741512 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
- C976601D138EC61A00741512 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
- C976601E138EC61A00741512 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
- C976601F138EC61A00741512 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
- C9766020138EC61A00741512 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
- C9766021138EC61A00741512 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
C9766022138EC61A00741512 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; };
C9766023138EC61A00741512 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; };
C9766024138EC61A00741512 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; };
C97660C4138EC61A00741512 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; };
C97660C5138EC61A00741512 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; };
C97660C6138EC61A00741512 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; };
- C97660C7138EC61A00741512 /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; };
- C97660C8138EC61A00741512 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; };
- C97660C9138EC61A00741512 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; };
C97660CA138EC61A00741512 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; };
- C97660CB138EC61A00741512 /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; };
- C97660CC138EC61A00741512 /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; };
- C97660CD138EC61A00741512 /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; };
- C97660CE138EC61A00741512 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; };
C97660CF138EC61A00741512 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; };
- C97660D0138EC61A00741512 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; };
- C97660D1138EC61A00741512 /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; };
C97660D2138EC61A00741512 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; };
C97660D5138EC61A00741512 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; };
C97660D6138EC61A00741512 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; };
- C97660D8138EC61A00741512 /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; };
- C97660D9138EC61A00741512 /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; };
C97660DA138EC61A00741512 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; };
C97660DC138EC61A00741512 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; };
C97660DD138EC61A00741512 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; };
C97660DE138EC61A00741512 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; };
C97660E1138EC61A00741512 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; };
C97660E2138EC61A00741512 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; };
- C97660E4138EC61A00741512 /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; };
C97660E6138EC61A00741512 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; };
C97660E7138EC61A00741512 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; };
C97660E8138EC61A00741512 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; };
C9766110138EC61A00741512 /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; };
C9766111138EC61A00741512 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; };
C9766112138EC61A00741512 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; };
- C9766113138EC61A00741512 /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; };
C9766114138EC61A00741512 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; };
- C9766115138EC61A00741512 /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; };
C9766116138EC61A00741512 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; };
C9766117138EC61A00741512 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; };
- C9766118138EC61A00741512 /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; };
C9766119138EC61A00741512 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; };
C976611A138EC61A00741512 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; };
C976611B138EC61A00741512 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; };
C9766121138EC61A00741512 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; };
C9766122138EC61A00741512 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; };
C9766123138EC61A00741512 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; };
- C9766124138EC61A00741512 /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; };
- C9766125138EC61A00741512 /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; };
- C9766126138EC61A00741512 /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; };
C9766127138EC61A00741512 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; };
C9766128138EC61A00741512 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; };
- C9766129138EC61A00741512 /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; };
- C976612A138EC61A00741512 /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; };
- C976612B138EC61A00741512 /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; };
C976612C138EC61A00741512 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; };
C976612D138EC61A00741512 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; };
C976612E138EC61A00741512 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; };
C9766139138EC61A00741512 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; };
C976613A138EC61A00741512 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; };
C976613B138EC61A00741512 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; };
- C976613C138EC61A00741512 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; };
- C976613D138EC61A00741512 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; };
- C976613E138EC61A00741512 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; };
- C976613F138EC61A00741512 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; };
- C9766140138EC61A00741512 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; };
- C9766141138EC61A00741512 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; };
- C9766142138EC61A00741512 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; };
- C9766143138EC61A00741512 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; };
- C9766144138EC61A00741512 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; };
- C9766145138EC61A00741512 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; };
- C97C344113AB0E1B00713550 /* Spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C97C344013AB0E1B00713550 /* Spinlocks.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
- C980F8EC13AB168D0069AB06 /* SpinlocksUP.c in Sources */ = {isa = PBXBuildFile; fileRef = C980F8EB13AB168D0069AB06 /* SpinlocksUP.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
+ C97A6F291517AF53005E1998 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53819138D9E990028D27C /* mcount.s */; };
+ C97A6F3F1517AF53005E1998 /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383D138D9E990028D27C /* strcpy.s */; };
+ C97A6F401517AF53005E1998 /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383E138D9E990028D27C /* strlcat.s */; };
+ C97A6F411517AF53005E1998 /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383F138D9E990028D27C /* strlcpy.s */; };
+ C97A6F421517AF53005E1998 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53840138D9E990028D27C /* strlen.s */; };
+ C97A6F441517AF53005E1998 /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53842138D9E990028D27C /* strncpy.s */; };
+ C97A6F5A1517AF53005E1998 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CF138D9E980028D27C /* strlen.s */; };
+ C97A6F5C1517AF53005E1998 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D2138D9E980028D27C /* strnlen.s */; };
+ C97A6F5D1517AF53005E1998 /* strstr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D3138D9E980028D27C /* strstr.s */; };
+ C97A6F6D1517AF53005E1998 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF9138D9E9A0028D27C /* mcount.s */; };
+ C97A6F761517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; };
+ C97A6F791517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; };
+ C97A6F7A1517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; };
+ C97A6F7E1517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; };
+ C97A6F8D1517AF53005E1998 /* dirhelper.defs in Sources */ = {isa = PBXBuildFile; fileRef = C9B53614138D9E980028D27C /* dirhelper.defs */; };
+ C97A6F8F1517AF53005E1998 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; };
+ C97A6F961517AF53005E1998 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; };
+ C97A6F971517AF53005E1998 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; };
+ C97A6F981517AF53005E1998 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; };
+ C97A6F991517AF53005E1998 /* killpg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53601138D9E980028D27C /* killpg.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_KILLPG"; }; };
+ C97A6F9A1517AF53005E1998 /* sethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53603138D9E980028D27C /* sethostid.c */; };
+ C97A6F9B1517AF53005E1998 /* setpgrp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53604138D9E980028D27C /* setpgrp.c */; };
+ C97A6F9C1517AF53005E1998 /* setrgid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53606138D9E980028D27C /* setrgid.c */; };
+ C97A6F9D1517AF53005E1998 /* setruid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53608138D9E980028D27C /* setruid.c */; };
+ C97A6F9E1517AF53005E1998 /* setregid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360A138D9E980028D27C /* setregid.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SETREGID"; }; };
+ C97A6F9F1517AF53005E1998 /* setreuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360B138D9E980028D27C /* setreuid.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SETREUID"; }; };
+ C97A6FA01517AF53005E1998 /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; };
+ C97A6FA11517AF53005E1998 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; };
+ C97A6FA21517AF53005E1998 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; };
+ C97A6FA31517AF53005E1998 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; };
+ C97A6FA71517AF53005E1998 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; };
+ C97A6FA81517AF53005E1998 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; };
+ C97A6FA91517AF53005E1998 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; };
+ C97A6FAA1517AF53005E1998 /* bt_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53622138D9E980028D27C /* bt_debug.c */; };
+ C97A6FAB1517AF53005E1998 /* bt_delete.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53623138D9E980028D27C /* bt_delete.c */; };
+ C97A6FAC1517AF53005E1998 /* bt_get.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53624138D9E980028D27C /* bt_get.c */; };
+ C97A6FAD1517AF53005E1998 /* bt_open.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53625138D9E980028D27C /* bt_open.c */; };
+ C97A6FAE1517AF53005E1998 /* bt_overflow.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53626138D9E980028D27C /* bt_overflow.c */; };
+ C97A6FAF1517AF53005E1998 /* bt_page.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53628138D9E980028D27C /* bt_page.c */; };
+ C97A6FB01517AF53005E1998 /* bt_put.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53629138D9E980028D27C /* bt_put.c */; };
+ C97A6FB11517AF53005E1998 /* bt_search.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362A138D9E980028D27C /* bt_search.c */; };
+ C97A6FB21517AF53005E1998 /* bt_seq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362B138D9E980028D27C /* bt_seq.c */; };
+ C97A6FB31517AF53005E1998 /* bt_split.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362D138D9E980028D27C /* bt_split.c */; };
+ C97A6FB41517AF53005E1998 /* bt_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5362F138D9E980028D27C /* bt_utils.c */; };
+ C97A6FB51517AF53005E1998 /* db.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53636138D9E980028D27C /* db.c */; };
+ C97A6FB61517AF53005E1998 /* hash.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5363B138D9E980028D27C /* hash.c */; };
+ C97A6FB71517AF53005E1998 /* hash_bigkey.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5363F138D9E980028D27C /* hash_bigkey.c */; };
+ C97A6FB81517AF53005E1998 /* hash_buf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53641138D9E980028D27C /* hash_buf.c */; };
+ C97A6FB91517AF53005E1998 /* hash_func.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53643138D9E980028D27C /* hash_func.c */; };
+ C97A6FBA1517AF53005E1998 /* hash_log2.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53645138D9E980028D27C /* hash_log2.c */; };
+ C97A6FBB1517AF53005E1998 /* hash_page.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53647138D9E980028D27C /* hash_page.c */; };
+ C97A6FBC1517AF53005E1998 /* ndbm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53649138D9E980028D27C /* ndbm.c */; };
+ C97A6FBD1517AF53005E1998 /* mpool.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5365A138D9E980028D27C /* mpool.c */; };
+ C97A6FBE1517AF53005E1998 /* rec_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53661138D9E980028D27C /* rec_close.c */; };
+ C97A6FBF1517AF53005E1998 /* rec_delete.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53662138D9E980028D27C /* rec_delete.c */; };
+ C97A6FC01517AF53005E1998 /* rec_get.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53663138D9E980028D27C /* rec_get.c */; };
+ C97A6FC11517AF53005E1998 /* rec_open.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53664138D9E980028D27C /* rec_open.c */; };
+ C97A6FC21517AF53005E1998 /* rec_put.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53665138D9E980028D27C /* rec_put.c */; };
+ C97A6FC31517AF53005E1998 /* rec_search.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53666138D9E980028D27C /* rec_search.c */; };
+ C97A6FC41517AF53005E1998 /* rec_seq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53667138D9E980028D27C /* rec_seq.c */; };
+ C97A6FC51517AF53005E1998 /* rec_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53668138D9E980028D27C /* rec_utils.c */; };
+ C97A6FC61517AF53005E1998 /* brk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5366E138D9E980028D27C /* brk.c */; };
+ C97A6FC71517AF53005E1998 /* bsd_signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53670138D9E980028D27C /* bsd_signal.c */; };
+ C97A6FC81517AF53005E1998 /* lchflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53672138D9E980028D27C /* lchflags.c */; };
+ C97A6FC91517AF53005E1998 /* lchmod.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53674138D9E980028D27C /* lchmod.c */; };
+ C97A6FCA1517AF53005E1998 /* lutimes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53676138D9E980028D27C /* lutimes.c */; };
+ C97A6FCB1517AF53005E1998 /* statvfs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53679138D9E980028D27C /* statvfs.c */; };
+ C97A6FCC1517AF53005E1998 /* tcgetsid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5367B138D9E980028D27C /* tcgetsid.c */; };
+ C97A6FCD1517AF53005E1998 /* _ldbl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5368E138D9E980028D27C /* _ldbl_util.c */; };
+ C97A6FCE1517AF53005E1998 /* _hdtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53691138D9E980028D27C /* _hdtoa.c */; };
+ C97A6FCF1517AF53005E1998 /* _ldtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53693138D9E980028D27C /* _ldtoa.c */; };
+ C97A6FD01517AF53005E1998 /* gdtoa-dmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53695138D9E980028D27C /* gdtoa-dmisc.c */; };
+ C97A6FD11517AF53005E1998 /* gdtoa-dtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53696138D9E980028D27C /* gdtoa-dtoa.c */; };
+ C97A6FD21517AF53005E1998 /* gdtoa-gdtoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53697138D9E980028D27C /* gdtoa-gdtoa.c */; };
+ C97A6FD31517AF53005E1998 /* gdtoa-gethex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53698138D9E980028D27C /* gdtoa-gethex.c */; };
+ C97A6FD41517AF53005E1998 /* gdtoa-gmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369A138D9E980028D27C /* gdtoa-gmisc.c */; };
+ C97A6FD51517AF53005E1998 /* gdtoa-hd_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369B138D9E980028D27C /* gdtoa-hd_init.c */; };
+ C97A6FD61517AF53005E1998 /* gdtoa-hexnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369C138D9E980028D27C /* gdtoa-hexnan.c */; };
+ C97A6FD71517AF53005E1998 /* gdtoa-misc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5369E138D9E980028D27C /* gdtoa-misc.c */; };
+ C97A6FD81517AF53005E1998 /* gdtoa-smisc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A0138D9E980028D27C /* gdtoa-smisc.c */; };
+ C97A6FD91517AF53005E1998 /* gdtoa-strtod.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A1138D9E980028D27C /* gdtoa-strtod.c */; };
+ C97A6FDA1517AF53005E1998 /* gdtoa-strtodg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A3138D9E980028D27C /* gdtoa-strtodg.c */; };
+ C97A6FDB1517AF53005E1998 /* gdtoa-strtof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A5138D9E980028D27C /* gdtoa-strtof.c */; };
+ C97A6FDC1517AF53005E1998 /* gdtoa-strtoIg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A7138D9E980028D27C /* gdtoa-strtoIg.c */; };
+ C97A6FDD1517AF53005E1998 /* gdtoa-strtopdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536A8138D9E980028D27C /* gdtoa-strtopdd.c */; };
+ C97A6FDE1517AF53005E1998 /* gdtoa-strtopx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AA138D9E980028D27C /* gdtoa-strtopx.c */; };
+ C97A6FDF1517AF53005E1998 /* gdtoa-strtord.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AC138D9E980028D27C /* gdtoa-strtord.c */; };
+ C97A6FE01517AF53005E1998 /* gdtoa-sum.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AE138D9E980028D27C /* gdtoa-sum.c */; };
+ C97A6FE11517AF53005E1998 /* gdtoa-ulp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536AF138D9E980028D27C /* gdtoa-ulp.c */; };
+ C97A6FE21517AF53005E1998 /* glue.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B5138D9E980028D27C /* glue.c */; };
+ C97A6FE31517AF53005E1998 /* machdep_ldisd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B6138D9E980028D27C /* machdep_ldisd.c */; };
+ C97A6FE41517AF53005E1998 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; };
+ C97A6FE51517AF53005E1998 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; };
+ C97A6FE61517AF53005E1998 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; };
+ C97A6FF01517AF53005E1998 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; };
+ C97A6FF11517AF53005E1998 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; };
+ C97A6FF31517AF53005E1998 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_CONFSTR"; }; };
+ C97A6FF41517AF53005E1998 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY"; }; };
+ C97A6FF51517AF53005E1998 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; };
+ C97A6FF61517AF53005E1998 /* disklabel.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E1138D9E990028D27C /* disklabel.c */; };
+ C97A6FF71517AF53005E1998 /* errlst.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E2138D9E990028D27C /* errlst.c */; };
+ C97A6FF81517AF53005E1998 /* filesec.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E4138D9E990028D27C /* filesec.c */; };
+ C97A6FF91517AF53005E1998 /* _rand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536E6138D9E990028D27C /* _rand48.c */; };
+ C97A6FFA1517AF53005E1998 /* alarm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536EA138D9E990028D27C /* alarm.c */; };
+ C97A6FFB1517AF53005E1998 /* arc4random.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536EC138D9E990028D27C /* arc4random.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A6FFC1517AF53005E1998 /* assert.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536EE138D9E990028D27C /* assert.c */; };
+ C97A6FFD1517AF53005E1998 /* basename.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536F2138D9E990028D27C /* basename.c */; };
+ C97A6FFE1517AF53005E1998 /* clock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536F5138D9E990028D27C /* clock.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CLOCK"; }; };
+ C97A6FFF1517AF53005E1998 /* closedir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536F6138D9E990028D27C /* closedir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CLOSEDIR -include gen/__dirent.h"; }; };
+ C97A70001517AF53005E1998 /* ctermid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536FA138D9E990028D27C /* ctermid.c */; };
+ C97A70011517AF53005E1998 /* daemon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536FD138D9E990028D27C /* daemon.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A70021517AF53005E1998 /* dirname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53701138D9E990028D27C /* dirname.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A70031517AF53005E1998 /* drand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53703138D9E990028D27C /* drand48.c */; };
+ C97A70041517AF53005E1998 /* erand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53705138D9E990028D27C /* erand48.c */; };
+ C97A70051517AF53005E1998 /* err.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53709138D9E990028D27C /* err.c */; };
+ C97A70061517AF53005E1998 /* exec.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5370D138D9E990028D27C /* exec.c */; };
+ C97A70071517AF53005E1998 /* fmtcheck.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53710138D9E990028D27C /* fmtcheck.c */; };
+ C97A70081517AF53005E1998 /* fmtmsg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53712138D9E990028D27C /* fmtmsg.c */; };
+ C97A70091517AF53005E1998 /* fnmatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53716138D9E990028D27C /* fnmatch.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FNMATCH"; }; };
+ C97A700A1517AF53005E1998 /* ftok.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5371A138D9E990028D27C /* ftok.c */; };
+ C97A700B1517AF53005E1998 /* getbsize.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5371C138D9E990028D27C /* getbsize.c */; };
+ C97A700C1517AF53005E1998 /* getcap.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5371E138D9E990028D27C /* getcap.c */; };
+ C97A700D1517AF53005E1998 /* getcwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53722138D9E990028D27C /* getcwd.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A700E1517AF53005E1998 /* gethostname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53726138D9E990028D27C /* gethostname.c */; };
+ C97A700F1517AF53005E1998 /* getlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53728138D9E990028D27C /* getlogin.c */; };
+ C97A70101517AF53005E1998 /* getmntinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5372C138D9E990028D27C /* getmntinfo.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A70111517AF53005E1998 /* getpagesize.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5372F138D9E990028D27C /* getpagesize.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A70121517AF53005E1998 /* getpeereid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53732138D9E990028D27C /* getpeereid.c */; };
+ C97A70131517AF53005E1998 /* getprogname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53735138D9E990028D27C /* getprogname.c */; };
+ C97A70141517AF53005E1998 /* glob.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53739138D9E990028D27C /* glob.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_GLOB"; }; };
+ C97A70151517AF53005E1998 /* isatty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5373B138D9E990028D27C /* isatty.c */; };
+ C97A70161517AF53005E1998 /* jrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5373D138D9E990028D27C /* jrand48.c */; };
+ C97A70171517AF53005E1998 /* lcong48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5373F138D9E990028D27C /* lcong48.c */; };
+ C97A70181517AF53005E1998 /* lockf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53743138D9E990028D27C /* lockf.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_LOCKF"; }; };
+ C97A70191517AF53005E1998 /* lrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53745138D9E990028D27C /* lrand48.c */; };
+ C97A701A1517AF53005E1998 /* mrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53749138D9E990028D27C /* mrand48.c */; };
+ C97A701B1517AF53005E1998 /* nice.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374C138D9E990028D27C /* nice.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_NICE"; }; };
+ C97A701C1517AF53005E1998 /* nrand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5374E138D9E990028D27C /* nrand48.c */; };
+ C97A701D1517AF53005E1998 /* opendir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53750138D9E990028D27C /* opendir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS___OPENDIR2 -DLIBC_ALIAS_OPENDIR -include gen/__dirent.h"; }; };
+ C97A701E1517AF53005E1998 /* pause.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53753138D9E990028D27C /* pause.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PAUSE"; }; };
+ C97A701F1517AF53005E1998 /* popen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53757138D9E990028D27C /* popen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_POPEN"; }; };
+ C97A70201517AF53005E1998 /* pselect.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375B138D9E990028D27C /* pselect.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PSELECT $(FreeBSD_CFLAGS)"; }; };
+ C97A70211517AF53005E1998 /* psignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5375F138D9E990028D27C /* psignal.c */; };
+ C97A70221517AF53005E1998 /* raise.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53761138D9E990028D27C /* raise.c */; };
+ C97A70231517AF53005E1998 /* readdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53766138D9E990028D27C /* readdir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; };
+ C97A70241517AF53005E1998 /* readpassphrase.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53769138D9E990028D27C /* readpassphrase.c */; };
+ C97A70251517AF53005E1998 /* rewinddir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5376B138D9E990028D27C /* rewinddir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_REWINDDIR -include gen/__dirent.h"; }; };
+ C97A70261517AF53005E1998 /* scandir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5376E138D9E990028D27C /* scandir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; };
+ C97A70271517AF53005E1998 /* seed48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53771138D9E990028D27C /* seed48.c */; };
+ C97A70281517AF53005E1998 /* seekdir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53773138D9E990028D27C /* seekdir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SEEKDIR -include gen/__dirent.h"; }; };
+ C97A70291517AF53005E1998 /* sethostname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53774138D9E990028D27C /* sethostname.c */; };
+ C97A702A1517AF53005E1998 /* setmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53776138D9E990028D27C /* setmode.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SETMODE"; }; };
+ C97A702B1517AF53005E1998 /* setprogname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53778138D9E990028D27C /* setprogname.c */; };
+ C97A702C1517AF53005E1998 /* siginterrupt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377C138D9E990028D27C /* siginterrupt.c */; };
+ C97A702D1517AF53005E1998 /* siglist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5377D138D9E990028D27C /* siglist.c */; };
+ C97A702E1517AF53005E1998 /* signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53781138D9E990028D27C /* signal.c */; };
+ C97A702F1517AF53005E1998 /* sleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53787138D9E990028D27C /* sleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SLEEP"; }; };
+ C97A70301517AF53005E1998 /* srand48.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53789138D9E990028D27C /* srand48.c */; };
+ C97A70311517AF53005E1998 /* stringlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378C138D9E990028D27C /* stringlist.c */; };
+ C97A70321517AF53005E1998 /* sysconf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5378E138D9E990028D27C /* sysconf.c */; };
+ C97A70331517AF53005E1998 /* sysctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53792138D9E990028D27C /* sysctl.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A70341517AF53005E1998 /* sysctlbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53794138D9E990028D27C /* sysctlbyname.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A70351517AF53005E1998 /* sysctlnametomib.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53795138D9E990028D27C /* sysctlnametomib.c */; };
+ C97A70361517AF53005E1998 /* telldir.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53796138D9E990028D27C /* telldir.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS__SEEKDIR -DLIBC_ALIAS_TELLDIR -include gen/__dirent.h"; }; };
+ C97A70371517AF53005E1998 /* termios.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5379A138D9E990028D27C /* termios.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TCDRAIN"; }; };
+ C97A70381517AF53005E1998 /* time.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5379E138D9E990028D27C /* time.c */; };
+ C97A70391517AF53005E1998 /* times.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A2138D9E990028D27C /* times.c */; };
+ C97A703A1517AF53005E1998 /* timezone.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A4138D9E990028D27C /* timezone.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A703B1517AF53005E1998 /* ttyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A7138D9E990028D27C /* ttyname.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TTYNAME_R"; }; };
+ C97A703C1517AF53005E1998 /* ttyslot.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537A9138D9E990028D27C /* ttyslot.c */; };
+ C97A703D1517AF53005E1998 /* ualarm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537AC138D9E990028D27C /* ualarm.c */; };
+ C97A703E1517AF53005E1998 /* ulimit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B0138D9E990028D27C /* ulimit.c */; };
+ C97A703F1517AF53005E1998 /* unvis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B2138D9E990028D27C /* unvis.c */; };
+ C97A70401517AF53005E1998 /* usleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537B6138D9E990028D27C /* usleep.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_USLEEP"; }; };
+ C97A70411517AF53005E1998 /* utime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BA138D9E990028D27C /* utime.c */; };
+ C97A70421517AF53005E1998 /* vis.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BC138D9E990028D27C /* vis.c */; };
+ C97A70431517AF53005E1998 /* wait.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537BE138D9E990028D27C /* wait.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAIT"; }; };
+ C97A70441517AF53005E1998 /* wait3.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C0138D9E990028D27C /* wait3.c */; };
+ C97A70451517AF53005E1998 /* waitpid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C1138D9E990028D27C /* waitpid.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WAITPID"; }; };
+ C97A70461517AF53005E1998 /* fts.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C4138D9E990028D27C /* fts.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTS_CHILDREN -DLIBC_ALIAS_FTS_CLOSE -DLIBC_ALIAS_FTS_OPEN -DLIBC_ALIAS_FTS_OPEN_B -DLIBC_ALIAS_FTS_READ -DLIBC_ALIAS_FTS_SET"; }; };
+ C97A70471517AF53005E1998 /* get_compat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537C6138D9E990028D27C /* get_compat.c */; };
+ C97A70481517AF53005E1998 /* getloadavg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CA138D9E990028D27C /* getloadavg.c */; };
+ C97A70491517AF53005E1998 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; };
+ C97A704A1517AF53005E1998 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; };
+ C97A704B1517AF53005E1998 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; };
+ C97A70501517AF53005E1998 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; };
+ C97A70511517AF53005E1998 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; };
+ C97A70521517AF53005E1998 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW"; }; };
+ C97A70531517AF53005E1998 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; };
+ C97A70541517AF53005E1998 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; };
+ C97A70551517AF53005E1998 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; };
+ C97A70581517AF53005E1998 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; };
+ C97A70591517AF53005E1998 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; };
+ C97A705C1517AF53005E1998 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; };
+ C97A705E1517AF53005E1998 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; };
+ C97A705F1517AF53005E1998 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; };
+ C97A70601517AF53005E1998 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; };
+ C97A70611517AF53005E1998 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; };
+ C97A70621517AF53005E1998 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; };
+ C97A70701517AF53005E1998 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; };
+ C97A70711517AF53005E1998 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; };
+ C97A70721517AF53005E1998 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; };
+ C97A70731517AF53005E1998 /* collate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5390B138D9E990028D27C /* collate.c */; };
+ C97A70741517AF53005E1998 /* collcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5390F138D9E990028D27C /* collcmp.c */; };
+ C97A70751517AF53005E1998 /* euc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53916138D9E990028D27C /* euc.c */; };
+ C97A70761517AF53005E1998 /* fix_grouping.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53918138D9E990028D27C /* fix_grouping.c */; };
+ C97A70771517AF53005E1998 /* gb18030.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5391B138D9E990028D27C /* gb18030.c */; };
+ C97A70781517AF53005E1998 /* gb2312.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5391E138D9E990028D27C /* gb2312.c */; };
+ C97A70791517AF53005E1998 /* gbk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53921138D9E990028D27C /* gbk.c */; };
+ C97A707A1517AF53005E1998 /* ldpart.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53946138D9E990028D27C /* ldpart.c */; };
+ C97A707B1517AF53005E1998 /* lmessages.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5394A138D9E990028D27C /* lmessages.c */; };
+ C97A707C1517AF53005E1998 /* lmonetary.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5394E138D9E990028D27C /* lmonetary.c */; };
+ C97A707D1517AF53005E1998 /* lnumeric.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53952138D9E990028D27C /* lnumeric.c */; };
+ C97A707E1517AF53005E1998 /* localeconv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53958138D9E990028D27C /* localeconv.c */; };
+ C97A707F1517AF53005E1998 /* mblen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5395C138D9E990028D27C /* mblen.c */; };
+ C97A70801517AF53005E1998 /* mbrlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53962138D9E990028D27C /* mbrlen.c */; };
+ C97A70811517AF53005E1998 /* mbrtowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53966138D9E990028D27C /* mbrtowc.c */; };
+ C97A70821517AF53005E1998 /* mbsinit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5396A138D9E990028D27C /* mbsinit.c */; };
+ C97A70831517AF53005E1998 /* mbsnrtowcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5396C138D9E990028D27C /* mbsnrtowcs.c */; };
+ C97A70841517AF53005E1998 /* mbsrtowcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53970138D9E990028D27C /* mbsrtowcs.c */; };
+ C97A70851517AF53005E1998 /* mbstowcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53974138D9E990028D27C /* mbstowcs.c */; };
+ C97A70861517AF53005E1998 /* mbtowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53978138D9E990028D27C /* mbtowc.c */; };
+ C97A70871517AF53005E1998 /* mskanji.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5397B138D9E990028D27C /* mskanji.c */; };
+ C97A70881517AF53005E1998 /* nextwctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53980138D9E990028D27C /* nextwctype.c */; };
+ C97A70891517AF53005E1998 /* nl_langinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53984138D9E990028D27C /* nl_langinfo.c */; };
+ C97A708A1517AF53005E1998 /* nomacros.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53986138D9E990028D27C /* nomacros.c */; };
+ C97A708B1517AF53005E1998 /* none.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53987138D9E990028D27C /* none.c */; };
+ C97A708C1517AF53005E1998 /* rune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53989138D9E990028D27C /* rune.c */; };
+ C97A708D1517AF53005E1998 /* runetype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5398B138D9E990028D27C /* runetype.c */; };
+ C97A708E1517AF53005E1998 /* setlocale.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5398F138D9E990028D27C /* setlocale.c */; };
+ C97A708F1517AF53005E1998 /* setrunelocale.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53993138D9E990028D27C /* setrunelocale.c */; };
+ C97A70901517AF53005E1998 /* table.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53995138D9E990028D27C /* table.c */; };
+ C97A70911517AF53005E1998 /* tolower.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5399A138D9E990028D27C /* tolower.c */; };
+ C97A70921517AF53005E1998 /* toupper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5399E138D9E990028D27C /* toupper.c */; };
+ C97A70931517AF53005E1998 /* utf2.c in Sources */ = {isa = PBXBuildFile; fileRef = C9FA32F8138E4A5C0089A94B /* utf2.c */; };
+ C97A70941517AF53005E1998 /* utf8.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539A6138D9E990028D27C /* utf8.c */; };
+ C97A70951517AF53005E1998 /* wcrtomb.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539AA138D9E990028D27C /* wcrtomb.c */; };
+ C97A70961517AF53005E1998 /* wcsftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539AE138D9E990028D27C /* wcsftime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_WCSFTIME -DLIBC_ALIAS_WCSFTIME_L"; }; };
+ C97A70971517AF53005E1998 /* wcsnrtombs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539B0138D9E990028D27C /* wcsnrtombs.c */; };
+ C97A70981517AF53005E1998 /* wcsrtombs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539B4138D9E990028D27C /* wcsrtombs.c */; };
+ C97A70991517AF53005E1998 /* wcstod.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539B8138D9E990028D27C /* wcstod.c */; };
+ C97A709A1517AF53005E1998 /* wcstof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539BA138D9E990028D27C /* wcstof.c */; };
+ C97A709B1517AF53005E1998 /* wcstoimax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539BC138D9E990028D27C /* wcstoimax.c */; };
+ C97A709C1517AF53005E1998 /* wcstol.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C0138D9E990028D27C /* wcstol.c */; };
+ C97A709D1517AF53005E1998 /* wcstold.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C2138D9E990028D27C /* wcstold.c */; };
+ C97A709E1517AF53005E1998 /* wcstoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C4138D9E990028D27C /* wcstoll.c */; };
+ C97A709F1517AF53005E1998 /* wcstombs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539C8138D9E990028D27C /* wcstombs.c */; };
+ C97A70A01517AF53005E1998 /* wcstoul.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539CA138D9E990028D27C /* wcstoul.c */; };
+ C97A70A11517AF53005E1998 /* wcstoull.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539CC138D9E990028D27C /* wcstoull.c */; };
+ C97A70A21517AF53005E1998 /* wcstoumax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539CE138D9E990028D27C /* wcstoumax.c */; };
+ C97A70A31517AF53005E1998 /* wctob.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539D0138D9E990028D27C /* wctob.c */; };
+ C97A70A41517AF53005E1998 /* wctomb.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539D4138D9E990028D27C /* wctomb.c */; };
+ C97A70A51517AF53005E1998 /* wctrans.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539D8138D9E990028D27C /* wctrans.c */; };
+ C97A70A61517AF53005E1998 /* wctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539DC138D9E990028D27C /* wctype.c */; };
+ C97A70A71517AF53005E1998 /* wcwidth.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E0138D9E990028D27C /* wcwidth.c */; };
+ C97A70A81517AF53005E1998 /* frune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E3138D9E990028D27C /* frune.c */; };
+ C97A70A91517AF53005E1998 /* isctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E5138D9E990028D27C /* isctype.c */; };
+ C97A70AA1517AF53005E1998 /* iswctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E7138D9E990028D27C /* iswctype.c */; };
+ C97A70AB1517AF53005E1998 /* lconv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E8138D9E990028D27C /* lconv.c */; };
+ C97A70AC1517AF53005E1998 /* mbrune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EB138D9E990028D27C /* mbrune.c */; };
+ C97A70AD1517AF53005E1998 /* runedepreciated.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539EF138D9E990028D27C /* runedepreciated.c */; };
+ C97A70AE1517AF53005E1998 /* setinvalidrune.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539F1138D9E990028D27C /* setinvalidrune.c */; };
+ C97A70AF1517AF53005E1998 /* xlocale.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539F7138D9E990028D27C /* xlocale.c */; };
+ C97A70B01517AF53005E1998 /* addr2ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A16138D9E990028D27C /* addr2ascii.c */; };
+ C97A70B11517AF53005E1998 /* ascii2addr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A17138D9E990028D27C /* ascii2addr.c */; };
+ C97A70B21517AF53005E1998 /* inet_addr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A1A138D9E990028D27C /* inet_addr.c */; };
+ C97A70B31517AF53005E1998 /* inet_lnaof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A1C138D9E990028D27C /* inet_lnaof.c */; };
+ C97A70B41517AF53005E1998 /* inet_makeaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A1D138D9E990028D27C /* inet_makeaddr.c */; };
+ C97A70B51517AF53005E1998 /* inet_net_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A20138D9E990028D27C /* inet_net_ntop.c */; };
+ C97A70B61517AF53005E1998 /* inet_net_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A21138D9E990028D27C /* inet_net_pton.c */; };
+ C97A70B71517AF53005E1998 /* inet_neta.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A23138D9E990028D27C /* inet_neta.c */; };
+ C97A70B81517AF53005E1998 /* inet_netof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A24138D9E990028D27C /* inet_netof.c */; };
+ C97A70B91517AF53005E1998 /* inet_network.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A25138D9E990028D27C /* inet_network.c */; };
+ C97A70BA1517AF53005E1998 /* inet_ntoa.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A27138D9E990028D27C /* inet_ntoa.c */; };
+ C97A70BB1517AF53005E1998 /* linkaddr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2A138D9E990028D27C /* linkaddr.c */; };
+ C97A70BC1517AF53005E1998 /* nsap_addr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2B138D9E990028D27C /* nsap_addr.c */; };
+ C97A70BD1517AF53005E1998 /* recv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2D138D9E990028D27C /* recv.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_RECV"; }; };
+ C97A70BE1517AF53005E1998 /* send.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A2F138D9E990028D27C /* send.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SEND"; }; };
+ C97A70BF1517AF53005E1998 /* sockatmark.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A33138D9E990028D27C /* sockatmark.c */; };
+ C97A70C01517AF53005E1998 /* sourcefilter.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A36138D9E990028D27C /* sourcefilter.c */; };
+ C97A70C11517AF53005E1998 /* msgcat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A3F138D9E990028D27C /* msgcat.c */; };
+ C97A70C21517AF53005E1998 /* acl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A4C138D9E990028D27C /* acl.c */; };
+ C97A70C31517AF53005E1998 /* acl_entry.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A59138D9E990028D27C /* acl_entry.c */; };
+ C97A70C41517AF53005E1998 /* acl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5A138D9E990028D27C /* acl_file.c */; };
+ C97A70C51517AF53005E1998 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; };
+ C97A70C61517AF53005E1998 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; };
+ C97A70C71517AF53005E1998 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; };
+ C97A70D11517AF53005E1998 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; };
+ C97A70D21517AF53005E1998 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
+ C97A70D31517AF53005E1998 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
+ C97A70D41517AF53005E1998 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
+ C97A70D51517AF53005E1998 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
+ C97A70D61517AF53005E1998 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
+ C97A70D71517AF53005E1998 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
+ C97A70D81517AF53005E1998 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
+ C97A70D91517AF53005E1998 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
+ C97A70DA1517AF53005E1998 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
+ C97A70DB1517AF53005E1998 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
+ C97A70DC1517AF53005E1998 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
+ C97A70DD1517AF53005E1998 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
+ C97A70DE1517AF53005E1998 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
+ C97A70DF1517AF53005E1998 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
+ C97A70E01517AF53005E1998 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; };
+ C97A70E11517AF53005E1998 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; };
+ C97A70E21517AF53005E1998 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; };
+ C97A70E31517AF53005E1998 /* dprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B33138D9E990028D27C /* dprintf.c */; };
+ C97A70E41517AF53005E1998 /* fclose.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B36138D9E990028D27C /* fclose.c */; };
+ C97A70E51517AF53005E1998 /* fdopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B38138D9E990028D27C /* fdopen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FDOPEN"; }; };
+ C97A70E61517AF53005E1998 /* feof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B3A138D9E990028D27C /* feof.c */; };
+ C97A70E71517AF53005E1998 /* ferror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B3C138D9E990028D27C /* ferror.c */; };
+ C97A70E81517AF53005E1998 /* fflush.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B3E138D9E990028D27C /* fflush.c */; };
+ C97A70E91517AF53005E1998 /* fgetc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B40138D9E990028D27C /* fgetc.c */; };
+ C97A70EA1517AF53005E1998 /* fgetln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B43138D9E990028D27C /* fgetln.c */; };
+ C97A70EB1517AF53005E1998 /* fgetpos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B45138D9E990028D27C /* fgetpos.c */; };
+ C97A70EC1517AF53005E1998 /* fgets.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B47138D9E990028D27C /* fgets.c */; };
+ C97A70ED1517AF53005E1998 /* fgetwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B48138D9E990028D27C /* fgetwc.c */; };
+ C97A70EE1517AF53005E1998 /* fgetwln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B4C138D9E990028D27C /* fgetwln.c */; };
+ C97A70EF1517AF53005E1998 /* fgetws.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B50138D9E990028D27C /* fgetws.c */; };
+ C97A70F01517AF53005E1998 /* fileno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B52138D9E990028D27C /* fileno.c */; };
+ C97A70F11517AF53005E1998 /* findfp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B53138D9E990028D27C /* findfp.c */; };
+ C97A70F21517AF53005E1998 /* flags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B55138D9E990028D27C /* flags.c */; };
+ C97A70F31517AF53005E1998 /* fopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B5C138D9E990028D27C /* fopen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FOPEN"; }; };
+ C97A70F41517AF53005E1998 /* fprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B5E138D9E990028D27C /* fprintf.c */; };
+ C97A70F51517AF53005E1998 /* fpurge.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B60138D9E990028D27C /* fpurge.c */; };
+ C97A70F61517AF53005E1998 /* fputc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B61138D9E990028D27C /* fputc.c */; };
+ C97A70F71517AF53005E1998 /* fputs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B64138D9E990028D27C /* fputs.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FPUTS"; }; };
+ C97A70F81517AF53005E1998 /* fputwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B66138D9E990028D27C /* fputwc.c */; };
+ C97A70F91517AF53005E1998 /* fputws.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B6A138D9E990028D27C /* fputws.c */; };
+ C97A70FA1517AF53005E1998 /* fread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B6E138D9E990028D27C /* fread.c */; };
+ C97A70FB1517AF53005E1998 /* freopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B70138D9E990028D27C /* freopen.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FREOPEN"; }; };
+ C97A70FC1517AF53005E1998 /* fscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B72138D9E990028D27C /* fscanf.c */; };
+ C97A70FD1517AF53005E1998 /* fseek.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B76138D9E990028D27C /* fseek.c */; };
+ C97A70FE1517AF53005E1998 /* fsetpos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B77138D9E990028D27C /* fsetpos.c */; };
+ C97A70FF1517AF53005E1998 /* ftell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B78138D9E990028D27C /* ftell.c */; };
+ C97A71001517AF53005E1998 /* funopen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B7B138D9E990028D27C /* funopen.c */; };
+ C97A71011517AF53005E1998 /* fvwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B7D138D9E990028D27C /* fvwrite.c */; };
+ C97A71021517AF53005E1998 /* fwalk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B7F138D9E990028D27C /* fwalk.c */; };
+ C97A71031517AF53005E1998 /* fwide.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B82138D9E990028D27C /* fwide.c */; };
+ C97A71041517AF53005E1998 /* fwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B83138D9E990028D27C /* fwprintf.c */; };
+ C97A71051517AF53005E1998 /* fwrite.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B85138D9E990028D27C /* fwrite.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_FWRITE"; }; };
+ C97A71061517AF53005E1998 /* fwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B87138D9E990028D27C /* fwscanf.c */; };
+ C97A71071517AF53005E1998 /* getc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B8B138D9E990028D27C /* getc.c */; };
+ C97A71081517AF53005E1998 /* getchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B8C138D9E990028D27C /* getchar.c */; };
+ C97A71091517AF53005E1998 /* getdelim.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B8D138D9E990028D27C /* getdelim.c */; };
+ C97A710A1517AF53005E1998 /* getline.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B90138D9E990028D27C /* getline.c */; };
+ C97A710B1517AF53005E1998 /* gets.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B91138D9E990028D27C /* gets.c */; };
+ C97A710C1517AF53005E1998 /* getw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B92138D9E990028D27C /* getw.c */; };
+ C97A710D1517AF53005E1998 /* getwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B95138D9E990028D27C /* getwc.c */; };
+ C97A710E1517AF53005E1998 /* getwchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B97138D9E990028D27C /* getwchar.c */; };
+ C97A710F1517AF53005E1998 /* makebuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B9C138D9E990028D27C /* makebuf.c */; };
+ C97A71101517AF53005E1998 /* mktemp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA0138D9E990028D27C /* mktemp.c */; };
+ C97A71111517AF53005E1998 /* perror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA2138D9E990028D27C /* perror.c */; };
+ C97A71121517AF53005E1998 /* printf-pos.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA3138D9E990028D27C /* printf-pos.c */; };
+ C97A71131517AF53005E1998 /* printf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BA7138D9E990028D27C /* printf.c */; };
+ C97A71141517AF53005E1998 /* putc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BAF138D9E990028D27C /* putc.c */; };
+ C97A71151517AF53005E1998 /* putchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB0138D9E990028D27C /* putchar.c */; };
+ C97A71161517AF53005E1998 /* puts.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB1138D9E990028D27C /* puts.c */; };
+ C97A71171517AF53005E1998 /* putw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB3138D9E990028D27C /* putw.c */; };
+ C97A71181517AF53005E1998 /* putwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB6138D9E990028D27C /* putwc.c */; };
+ C97A71191517AF53005E1998 /* putwchar.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BB8138D9E990028D27C /* putwchar.c */; };
+ C97A711A1517AF53005E1998 /* refill.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BBA138D9E990028D27C /* refill.c */; };
+ C97A711B1517AF53005E1998 /* remove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BBE138D9E990028D27C /* remove.c */; };
+ C97A711C1517AF53005E1998 /* rewind.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BBF138D9E990028D27C /* rewind.c */; };
+ C97A711D1517AF53005E1998 /* rget.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC1138D9E990028D27C /* rget.c */; };
+ C97A711E1517AF53005E1998 /* scanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC4138D9E990028D27C /* scanf.c */; };
+ C97A711F1517AF53005E1998 /* setbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC8138D9E990028D27C /* setbuf.c */; };
+ C97A71201517AF53005E1998 /* setbuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BC9138D9E990028D27C /* setbuffer.c */; };
+ C97A71211517AF53005E1998 /* setvbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCA138D9E990028D27C /* setvbuf.c */; };
+ C97A71221517AF53005E1998 /* snprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCB138D9E990028D27C /* snprintf.c */; };
+ C97A71231517AF53005E1998 /* sprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCD138D9E990028D27C /* sprintf.c */; };
+ C97A71241517AF53005E1998 /* sscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BCF138D9E990028D27C /* sscanf.c */; };
+ C97A71251517AF53005E1998 /* stdio.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD3138D9E990028D27C /* stdio.c */; };
+ C97A71261517AF53005E1998 /* swprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD4138D9E990028D27C /* swprintf.c */; };
+ C97A71271517AF53005E1998 /* swscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD6138D9E990028D27C /* swscanf.c */; };
+ C97A71281517AF53005E1998 /* tempnam.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BD8138D9E990028D27C /* tempnam.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_TEMPNAM"; }; };
+ C97A71291517AF53005E1998 /* tmpfile.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BDA138D9E990028D27C /* tmpfile.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -D_DARWIN_UNLIMITED_STREAMS"; }; };
+ C97A712A1517AF53005E1998 /* tmpnam.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BDD138D9E990028D27C /* tmpnam.c */; };
+ C97A712B1517AF53005E1998 /* ungetc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE1138D9E990028D27C /* ungetc.c */; };
+ C97A712C1517AF53005E1998 /* ungetwc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE4138D9E990028D27C /* ungetwc.c */; };
+ C97A712D1517AF53005E1998 /* vasprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE6138D9E990028D27C /* vasprintf.c */; };
+ C97A712E1517AF53005E1998 /* vdprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BE8138D9E990028D27C /* vdprintf.c */; };
+ C97A712F1517AF53005E1998 /* vfprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEA138D9E990028D27C /* vfprintf.c */; };
+ C97A71301517AF53005E1998 /* vfscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEC138D9E990028D27C /* vfscanf.c */; };
+ C97A71311517AF53005E1998 /* vfwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BEE138D9E9A0028D27C /* vfwprintf.c */; };
+ C97A71321517AF53005E1998 /* vfwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF0138D9E9A0028D27C /* vfwscanf.c */; };
+ C97A71331517AF53005E1998 /* vprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF2138D9E9A0028D27C /* vprintf.c */; };
+ C97A71341517AF53005E1998 /* vscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF4138D9E9A0028D27C /* vscanf.c */; };
+ C97A71351517AF53005E1998 /* vsnprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF6138D9E9A0028D27C /* vsnprintf.c */; };
+ C97A71361517AF53005E1998 /* vsprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BF8138D9E9A0028D27C /* vsprintf.c */; };
+ C97A71371517AF53005E1998 /* vsscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BFA138D9E9A0028D27C /* vsscanf.c */; };
+ C97A71381517AF53005E1998 /* vswprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BFC138D9E9A0028D27C /* vswprintf.c */; };
+ C97A71391517AF53005E1998 /* vswscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53BFE138D9E9A0028D27C /* vswscanf.c */; };
+ C97A713A1517AF53005E1998 /* vwprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C00138D9E9A0028D27C /* vwprintf.c */; };
+ C97A713B1517AF53005E1998 /* vwscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C02138D9E9A0028D27C /* vwscanf.c */; };
+ C97A713C1517AF53005E1998 /* wbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C04138D9E9A0028D27C /* wbuf.c */; };
+ C97A713D1517AF53005E1998 /* wprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C08138D9E9A0028D27C /* wprintf.c */; };
+ C97A713E1517AF53005E1998 /* wscanf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C0C138D9E9A0028D27C /* wscanf.c */; };
+ C97A713F1517AF53005E1998 /* wsetup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C0E138D9E9A0028D27C /* wsetup.c */; };
+ C97A71401517AF53005E1998 /* a64l.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C18138D9E9A0028D27C /* a64l.c */; };
+ C97A71411517AF53005E1998 /* _Exit_.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C1A138D9E9A0028D27C /* _Exit_.c */; };
+ C97A71421517AF53005E1998 /* abort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C1D138D9E9A0028D27C /* abort.c */; };
+ C97A71431517AF53005E1998 /* abs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C21138D9E9A0028D27C /* abs.c */; };
+ C97A71441517AF53005E1998 /* atexit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C26138D9E9A0028D27C /* atexit.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A71451517AF53005E1998 /* atof.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C2C138D9E9A0028D27C /* atof.c */; };
+ C97A71461517AF53005E1998 /* atoi.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C30138D9E9A0028D27C /* atoi.c */; };
+ C97A71471517AF53005E1998 /* atol.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C34138D9E9A0028D27C /* atol.c */; };
+ C97A71481517AF53005E1998 /* atoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C36138D9E9A0028D27C /* atoll.c */; };
+ C97A71491517AF53005E1998 /* bsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C3A138D9E9A0028D27C /* bsearch.c */; };
+ C97A714A1517AF53005E1998 /* div.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C3E138D9E9A0028D27C /* div.c */; };
+ C97A714B1517AF53005E1998 /* exit.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C40138D9E9A0028D27C /* exit.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A714C1517AF53005E1998 /* getenv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C44138D9E9A0028D27C /* getenv.c */; };
+ C97A714D1517AF53005E1998 /* getopt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C47138D9E9A0028D27C /* getopt.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_GETOPT"; }; };
+ C97A714E1517AF53005E1998 /* getopt_long.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C4A138D9E9A0028D27C /* getopt_long.c */; };
+ C97A714F1517AF53005E1998 /* getsubopt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C4D138D9E9A0028D27C /* getsubopt.c */; };
+ C97A71501517AF53005E1998 /* hcreate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C4F138D9E9A0028D27C /* hcreate.c */; };
+ C97A71511517AF53005E1998 /* heapsort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C50138D9E9A0028D27C /* heapsort.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A71521517AF53005E1998 /* heapsort_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94357138EC0C600FB7ACC /* heapsort_b.c */; };
+ C97A71531517AF53005E1998 /* heapsort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94358138EC0C600FB7ACC /* heapsort_r.c */; };
+ C97A71541517AF53005E1998 /* imaxabs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C54138D9E9A0028D27C /* imaxabs.c */; };
+ C97A71551517AF53005E1998 /* imaxdiv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C57138D9E9A0028D27C /* imaxdiv.c */; };
+ C97A71561517AF53005E1998 /* insque.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C5A138D9E9A0028D27C /* insque.c */; };
+ C97A71571517AF53005E1998 /* labs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C5D138D9E9A0028D27C /* labs.c */; };
+ C97A71581517AF53005E1998 /* ldiv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C60138D9E9A0028D27C /* ldiv.c */; };
+ C97A71591517AF53005E1998 /* llabs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C63138D9E9A0028D27C /* llabs.c */; };
+ C97A715A1517AF53005E1998 /* lldiv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C66138D9E9A0028D27C /* lldiv.c */; };
+ C97A715B1517AF53005E1998 /* lsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C69138D9E9A0028D27C /* lsearch.c */; };
+ C97A715C1517AF53005E1998 /* merge.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C6C138D9E9A0028D27C /* merge.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A715D1517AF53005E1998 /* putenv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C6F138D9E9A0028D27C /* putenv.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_PUTENV"; }; };
+ C97A715E1517AF53005E1998 /* qsort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C73138D9E9A0028D27C /* qsort.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A715F1517AF53005E1998 /* qsort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C75138D9E9A0028D27C /* qsort_r.c */; };
+ C97A71601517AF53005E1998 /* radixsort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C78138D9E9A0028D27C /* radixsort.c */; };
+ C97A71611517AF53005E1998 /* rand.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C7C138D9E9A0028D27C /* rand.c */; };
+ C97A71621517AF53005E1998 /* random.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C7F138D9E9A0028D27C /* random.c */; };
+ C97A71631517AF53005E1998 /* reallocf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C81138D9E9A0028D27C /* reallocf.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A71641517AF53005E1998 /* realpath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C84138D9E9A0028D27C /* realpath.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_REALPATH"; }; };
+ C97A71651517AF53005E1998 /* remque.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C86138D9E9A0028D27C /* remque.c */; };
+ C97A71661517AF53005E1998 /* setenv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C87138D9E9A0028D27C /* setenv.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_REALPATH"; }; };
+ C97A71671517AF53005E1998 /* strhash.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C89138D9E9A0028D27C /* strhash.c */; };
+ C97A71681517AF53005E1998 /* strtoimax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C8D138D9E9A0028D27C /* strtoimax.c */; };
+ C97A71691517AF53005E1998 /* strtol.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C91138D9E9A0028D27C /* strtol.c */; };
+ C97A716A1517AF53005E1998 /* strtoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C93138D9E9A0028D27C /* strtoll.c */; };
+ C97A716B1517AF53005E1998 /* strtoq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C95138D9E9A0028D27C /* strtoq.c */; };
+ C97A716C1517AF53005E1998 /* strtoul.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C99138D9E9A0028D27C /* strtoul.c */; };
+ C97A716D1517AF53005E1998 /* strtoull.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C9B138D9E9A0028D27C /* strtoull.c */; };
+ C97A716E1517AF53005E1998 /* strtoumax.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C9D138D9E9A0028D27C /* strtoumax.c */; };
+ C97A716F1517AF53005E1998 /* strtouq.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C9F138D9E9A0028D27C /* strtouq.c */; };
+ C97A71701517AF53005E1998 /* system.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA3138D9E9A0028D27C /* system.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_SYSTEM"; }; };
+ C97A71711517AF53005E1998 /* tdelete.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA5138D9E9A0028D27C /* tdelete.c */; };
+ C97A71721517AF53005E1998 /* tfind.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA6138D9E9A0028D27C /* tfind.c */; };
+ C97A71731517AF53005E1998 /* tsearch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CA9138D9E9A0028D27C /* tsearch.c */; };
+ C97A71741517AF53005E1998 /* twalk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CAA138D9E9A0028D27C /* twalk.c */; };
+ C97A71751517AF53005E1998 /* grantpt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CAC138D9E9A0028D27C /* grantpt.c */; };
+ C97A71761517AF53005E1998 /* l64a.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CAD138D9E9A0028D27C /* l64a.c */; };
+ C97A71771517AF53005E1998 /* strfmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB2138D9E9A0028D27C /* strfmon.c */; };
+ C97A71781517AF53005E1998 /* ecvt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB7138D9E9A0028D27C /* ecvt.c */; };
+ C97A71791517AF53005E1998 /* gcvt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB9138D9E9A0028D27C /* gcvt.c */; };
+ C97A717A1517AF53005E1998 /* qsort_b-fbsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CBD138D9E9A0028D27C /* qsort_b-fbsd.c */; };
+ C97A717B1517AF53005E1998 /* asctime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CC2138D9E9A0028D27C /* asctime.c */; };
+ C97A717C1517AF53005E1998 /* difftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CC6138D9E9A0028D27C /* difftime.c */; };
+ C97A717D1517AF53005E1998 /* ftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CC9138D9E9A0028D27C /* ftime.c */; };
+ C97A717E1517AF53005E1998 /* localtime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CCA138D9E9A0028D27C /* localtime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_MKTIME"; }; };
+ C97A717F1517AF53005E1998 /* strftime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CCF138D9E9A0028D27C /* strftime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRFTIME -DLIBC_ALIAS_STRFTIME_L"; }; };
+ C97A71801517AF53005E1998 /* strptime.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD3138D9E9A0028D27C /* strptime.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRPTIME -DLIBC_ALIAS_STRPTIME_L"; }; };
+ C97A71811517AF53005E1998 /* time32.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD6138D9E9A0028D27C /* time32.c */; };
+ C97A71821517AF53005E1998 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; };
+ C97A71831517AF53005E1998 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; settings = {COMPILER_FLAGS = "-D_DARWIN_UNLIMITED_STREAMS"; }; };
+ C97A71841517AF53005E1998 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; };
+ C97A71881517AF53005E1998 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; };
+ C97A718D1517AF53005E1998 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; };
+ C97A71901517AF53005E1998 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; };
+ C97A71911517AF53005E1998 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; };
+ C97A71921517AF53005E1998 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; };
+ C97A71951517AF53005E1998 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; };
+ C97A71961517AF53005E1998 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; };
+ C97A71971517AF53005E1998 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A71981517AF53005E1998 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRERROR"; }; };
+ C97A71991517AF53005E1998 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; };
+ C97A719A1517AF53005E1998 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; };
+ C97A719C1517AF53005E1998 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; };
+ C97A719D1517AF53005E1998 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; };
+ C97A719E1517AF53005E1998 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; };
+ C97A719F1517AF53005E1998 /* strpbrk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D49138D9E9A0028D27C /* strpbrk.c */; };
+ C97A71A01517AF53005E1998 /* strrchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D4C138D9E9A0028D27C /* strrchr.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A71A11517AF53005E1998 /* strsep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D4F138D9E9A0028D27C /* strsep.c */; };
+ C97A71A21517AF53005E1998 /* strsignal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D50138D9E9A0028D27C /* strsignal.c */; };
+ C97A71A31517AF53005E1998 /* strspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D54138D9E9A0028D27C /* strspn.c */; };
+ C97A71A41517AF53005E1998 /* strstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D57138D9E9A0028D27C /* strstr.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS)"; }; };
+ C97A71A51517AF53005E1998 /* strtok.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D5A138D9E9A0028D27C /* strtok.c */; };
+ C97A71A61517AF53005E1998 /* strxfrm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D5D138D9E9A0028D27C /* strxfrm.c */; };
+ C97A71A71517AF53005E1998 /* swab.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D61138D9E9A0028D27C /* swab.c */; };
+ C97A71A81517AF53005E1998 /* wcpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D63138D9E9A0028D27C /* wcpcpy.c */; };
+ C97A71A91517AF53005E1998 /* wcpncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D64138D9E9A0028D27C /* wcpncpy.c */; };
+ C97A71AA1517AF53005E1998 /* wcscasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D65138D9E9A0028D27C /* wcscasecmp.c */; };
+ C97A71AB1517AF53005E1998 /* wcscat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D67138D9E9A0028D27C /* wcscat.c */; };
+ C97A71AC1517AF53005E1998 /* wcschr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D68138D9E9A0028D27C /* wcschr.c */; };
+ C97A71AD1517AF53005E1998 /* wcscmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D69138D9E9A0028D27C /* wcscmp.c */; };
+ C97A71AE1517AF53005E1998 /* wcscoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D6C138D9E9A0028D27C /* wcscoll.c */; };
+ C97A71AF1517AF53005E1998 /* wcscpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D6E138D9E9A0028D27C /* wcscpy.c */; };
+ C97A71B01517AF53005E1998 /* wcscspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D6F138D9E9A0028D27C /* wcscspn.c */; };
+ C97A71B11517AF53005E1998 /* wcsdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D70138D9E9A0028D27C /* wcsdup.c */; };
+ C97A71B21517AF53005E1998 /* wcslcat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D71138D9E9A0028D27C /* wcslcat.c */; };
+ C97A71B31517AF53005E1998 /* wcslcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D72138D9E9A0028D27C /* wcslcpy.c */; };
+ C97A71B41517AF53005E1998 /* wcslen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D73138D9E9A0028D27C /* wcslen.c */; };
+ C97A71B51517AF53005E1998 /* wcsncasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D74138D9E9A0028D27C /* wcsncasecmp.c */; };
+ C97A71B61517AF53005E1998 /* wcsncat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D76138D9E9A0028D27C /* wcsncat.c */; };
+ C97A71B71517AF53005E1998 /* wcsncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D77138D9E9A0028D27C /* wcsncmp.c */; };
+ C97A71B81517AF53005E1998 /* wcsncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D78138D9E9A0028D27C /* wcsncpy.c */; };
+ C97A71B91517AF53005E1998 /* wcsnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D79138D9E9A0028D27C /* wcsnlen.c */; };
+ C97A71BA1517AF53005E1998 /* wcspbrk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7A138D9E9A0028D27C /* wcspbrk.c */; };
+ C97A71BB1517AF53005E1998 /* wcsrchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7B138D9E9A0028D27C /* wcsrchr.c */; };
+ C97A71BC1517AF53005E1998 /* wcsspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7C138D9E9A0028D27C /* wcsspn.c */; };
+ C97A71BD1517AF53005E1998 /* wcsstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D7D138D9E9A0028D27C /* wcsstr.c */; };
+ C97A71BE1517AF53005E1998 /* wcstok.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D80138D9E9A0028D27C /* wcstok.c */; };
+ C97A71BF1517AF53005E1998 /* wcswidth.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D83138D9E9A0028D27C /* wcswidth.c */; };
+ C97A71C01517AF53005E1998 /* wcsxfrm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D87138D9E9A0028D27C /* wcsxfrm.c */; };
+ C97A71C11517AF53005E1998 /* wmemchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8B138D9E9A0028D27C /* wmemchr.c */; };
+ C97A71C21517AF53005E1998 /* wmemcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8C138D9E9A0028D27C /* wmemcmp.c */; };
+ C97A71C31517AF53005E1998 /* wmemcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8D138D9E9A0028D27C /* wmemcpy.c */; };
+ C97A71C41517AF53005E1998 /* wmemmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8E138D9E9A0028D27C /* wmemmove.c */; };
+ C97A71C51517AF53005E1998 /* wmemset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D8F138D9E9A0028D27C /* wmemset.c */; };
+ C97A71C61517AF53005E1998 /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; };
+ C97A71C71517AF53005E1998 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; };
+ C97A71C81517AF53005E1998 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; };
+ C97A71CA1517AF53005E1998 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; };
+ C97A71CC1517AF53005E1998 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; };
+ C97A71CD1517AF53005E1998 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; };
+ C97A71CF1517AF53005E1998 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; };
+ C97A71D01517AF53005E1998 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_MSGCTL -DKERNEL"; }; };
+ C97A71D11517AF53005E1998 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; };
+ C97A71D21517AF53005E1998 /* openx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAB138D9E9A0028D27C /* openx_np.c */; };
+ C97A71D31517AF53005E1998 /* OSMemoryNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAC138D9E9A0028D27C /* OSMemoryNotification.c */; };
+ C97A71D41517AF53005E1998 /* OSThermalNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAD138D9E9A0028D27C /* OSThermalNotification.c */; };
+ C97A71D51517AF53005E1998 /* posix_spawn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAE138D9E9A0028D27C /* posix_spawn.c */; };
+ C97A71D61517AF53005E1998 /* semctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB2138D9E9A0028D27C /* semctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SEMCTL -DKERNEL"; }; };
+ C97A71D71517AF53005E1998 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; };
+ C97A71D81517AF53005E1998 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SHMCTL -DKERNEL"; }; };
+ C97A71D91517AF53005E1998 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; };
+ C97A71DA1517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; };
+ C97A71DD1517AF53005E1998 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; };
+ C97A71DE1517AF53005E1998 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; };
+ C97A71E21517AF53005E1998 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; };
+ C97A71E31517AF53005E1998 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; };
+ C97A71E41517AF53005E1998 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; };
+ C97A71E51517AF53005E1998 /* logout.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCC138D9E9A0028D27C /* logout.c */; };
+ C97A71E61517AF53005E1998 /* logwtmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCD138D9E9A0028D27C /* logwtmp.c */; };
+ C97A71E71517AF53005E1998 /* mkpath_np.c in Sources */ = {isa = PBXBuildFile; fileRef = 3F89F3DD13E9194C00F6856C /* mkpath_np.c */; };
+ C97A71E81517AF53005E1998 /* opendev.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DD0138D9E9A0028D27C /* opendev.c */; };
+ C97A71E91517AF53005E1998 /* pty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DD2138D9E9A0028D27C /* pty.c */; };
+ C97A71EA1517AF53005E1998 /* clear.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DD9138D9E9A0028D27C /* clear.c */; };
+ C97A71EB1517AF53005E1998 /* compare.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDA138D9E9A0028D27C /* compare.c */; };
+ C97A71EC1517AF53005E1998 /* copy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDB138D9E9A0028D27C /* copy.c */; };
+ C97A71ED1517AF53005E1998 /* gen_uuid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDC138D9E9A0028D27C /* gen_uuid.c */; };
+ C97A71EE1517AF53005E1998 /* isnull.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DDE138D9E9A0028D27C /* isnull.c */; };
+ C97A71EF1517AF53005E1998 /* pack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE0138D9E9A0028D27C /* pack.c */; };
+ C97A71F01517AF53005E1998 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; };
+ C97A71F11517AF53005E1998 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; };
+ C97A71F21517AF53005E1998 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; };
+ C97A71F71517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; };
+ C97A71F81517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; };
+ C97A71F91517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; };
+ C97A71FA1517AF53005E1998 /* (null) in Sources */ = {isa = PBXBuildFile; };
+ C97A71FD1517AF53005E1998 /* scandir_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB350E138F769B0075BB52 /* scandir_b.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; };
+ C97A71FF1517AF53005E1998 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C921D3831395B7DD001CE070 /* init_cpu_capabilities.c */; };
+ C97A72001517AF53005E1998 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3841395B7DD001CE070 /* pthread_getspecific.s */; };
+ C97A72011517AF53005E1998 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3851395B7DD001CE070 /* pthread_self.s */; };
+ C97A72021517AF53005E1998 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3861395B7DD001CE070 /* pthread_set_self.s */; };
+ C97A72031517AF53005E1998 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3871395B7DD001CE070 /* start_wqthread.s */; };
+ C97A72041517AF53005E1998 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3881395B7DD001CE070 /* thread_start.s */; };
+ C97A720D1517AF53005E1998 /* strcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518613D4D966004F7BA8 /* strcpy.c */; };
+ C97A720E1517AF53005E1998 /* strlcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518B13D4DABD004F7BA8 /* strlcpy.c */; };
+ C97A720F1517AF53005E1998 /* strncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 6310518E13D4DAEA004F7BA8 /* strncpy.c */; };
+ C97A72101517AF53005E1998 /* stpcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060513DDEDF10094DD56 /* stpcpy.c */; };
+ C97A72111517AF53005E1998 /* stpncpy.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060913DDEEA10094DD56 /* stpncpy.c */; };
+ C97A72121517AF53005E1998 /* strcat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060C13DDF26A0094DD56 /* strcat.c */; };
+ C97A72131517AF53005E1998 /* strncat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4060F13DDF4340094DD56 /* strncat.c */; };
+ C97A72141517AF53005E1998 /* strlcat.c in Sources */ = {isa = PBXBuildFile; fileRef = 63D4061213DDF6A20094DD56 /* strlcat.c */; };
+ C97A72161517AF53005E1998 /* sync_volume_np.c in Sources */ = {isa = PBXBuildFile; fileRef = B19C645B1450F90200032373 /* sync_volume_np.c */; };
+ C97A72171517AF53005E1998 /* dirfd.c in Sources */ = {isa = PBXBuildFile; fileRef = 3FB7E1B4146EF2E000843438 /* dirfd.c */; };
C98373971395989E00E5C052 /* OSMemoryNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAC138D9E9A0028D27C /* OSMemoryNotification.c */; };
C98373981395989E00E5C052 /* OSThermalNotification.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAD138D9E9A0028D27C /* OSThermalNotification.c */; };
- C995462813AAA25000A531B4 /* OSAtomicUP.c in Sources */ = {isa = PBXBuildFile; fileRef = C995462713AAA25000A531B4 /* OSAtomicUP.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
+ C98E2B4C139851B7002A3ABB /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C921D3831395B7DD001CE070 /* init_cpu_capabilities.c */; };
+ C98E2B4D139851B7002A3ABB /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3841395B7DD001CE070 /* pthread_getspecific.s */; };
+ C98E2B4E139851B7002A3ABB /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3851395B7DD001CE070 /* pthread_self.s */; };
+ C98E2B4F139851B7002A3ABB /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3861395B7DD001CE070 /* pthread_set_self.s */; };
+ C98E2B50139851B7002A3ABB /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3871395B7DD001CE070 /* start_wqthread.s */; };
+ C98E2B51139851B7002A3ABB /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C921D3881395B7DD001CE070 /* thread_start.s */; };
C9A12853138E0BE00003880A /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; };
C9A12854138E0C1C0003880A /* isctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E5138D9E990028D27C /* isctype.c */; };
C9A12855138E0C1C0003880A /* iswctype.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B539E7138D9E990028D27C /* iswctype.c */; };
C9A128A3138E0CD10003880A /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; };
C9A128A4138E0CD10003880A /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; };
C9A128A5138E0CD10003880A /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; };
- C9A128A6138E0D0B0003880A /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; };
- C9A128A7138E0D0B0003880A /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; };
- C9A128A8138E0D0B0003880A /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; };
- C9A128A9138E0D0B0003880A /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; };
- C9A128AA138E0D0B0003880A /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; };
- C9A128AB138E0D0B0003880A /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; };
- C9A128AC138E0D0B0003880A /* stack.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFE138D9E990028D27C /* stack.s */; };
- C9A128AD138E0D0B0003880A /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; settings = {COMPILER_FLAGS = "-U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0"; }; };
- C9A128B3138E0D950003880A /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
- C9A128B4138E0D950003880A /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
- C9A128B5138E0D950003880A /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
- C9A128B6138E0D950003880A /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
- C9A128B7138E0D950003880A /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
- C9A128B8138E0D950003880A /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
- C9A128B9138E0D950003880A /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
- C9A128BA138E0D950003880A /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
- C9A128BB138E0D950003880A /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
- C9A128BC138E0D950003880A /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
- C9A128BD138E0D950003880A /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
- C9A128BE138E0D950003880A /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
- C9A128BF138E0D950003880A /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
- C9A128C0138E0D950003880A /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
C9A12929138E0EF00003880A /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; };
C9A1292A138E0EF00003880A /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; };
- C9A12974138E10AB0003880A /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; };
- C9A12975138E10AB0003880A /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; };
- C9A12976138E10AB0003880A /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; };
C9A12977138E10C40003880A /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; settings = {COMPILER_FLAGS = " -D__FBSDID=__RCSID"; }; };
C9A12978138E10C40003880A /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; };
C9A12979138E10C40003880A /* logwtmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCD138D9E9A0028D27C /* logwtmp.c */; };
C9A12982138E10FB0003880A /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; settings = {COMPILER_FLAGS = "-include $(SRCROOT)/uuid/uuid-config.h"; }; };
C9A12983138E10FB0003880A /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; settings = {COMPILER_FLAGS = "-include $(SRCROOT)/uuid/uuid-config.h"; }; };
C9A12984138E10FB0003880A /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; settings = {COMPILER_FLAGS = "-include $(SRCROOT)/uuid/uuid-config.h"; }; };
- C9B4E3D813BBBF2D0008A9BB /* OSAtomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B4E3D713BBBF2D0008A9BB /* OSAtomic.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
- C9B4E3DE13BBCE5F0008A9BB /* OSAtomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B4E3D713BBBF2D0008A9BB /* OSAtomic.c */; settings = {COMPILER_FLAGS = "$(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))"; }; };
- C9B53E57138DA5910028D27C /* _ctx_start.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF1138D9E9A0028D27C /* _ctx_start.S */; };
- C9B53E58138DA5910028D27C /* _setcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF2138D9E9A0028D27C /* _setcontext.S */; };
- C9B53E59138DA5910028D27C /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF3138D9E9A0028D27C /* cpu_number.s */; };
- C9B53E5A138DA5910028D27C /* getcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF4138D9E9A0028D27C /* getcontext.S */; };
- C9B53E5B138DA5910028D27C /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; };
- C9B53E5C138DA5910028D27C /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF6138D9E9A0028D27C /* icacheinval.s */; };
- C9B53E5D138DA5910028D27C /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; };
+ C9AE91B51517D31A00A2626C /* libBase.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9C2A94D138DFFD900287F00 /* libBase.a */; };
+ C9AE91B71517D31C00A2626C /* libFreeBSD.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9257ED0138E1B5000B3107C /* libFreeBSD.a */; };
+ C9AE91B81517D32200A2626C /* libvCancelable.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C9D94360138EC3E300FB7ACC /* libvCancelable.a */; };
+ C9AE91B91517D32900A2626C /* libTRE.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B122F2AD1432B8E600AF95D0 /* libTRE.a */; };
C9B53E5E138DA5910028D27C /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF9138D9E9A0028D27C /* mcount.s */; };
- C9B53E5F138DA5910028D27C /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; };
- C9B53E60138DA5910028D27C /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; };
- C9B53E62138DA5950028D27C /* preempt.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFE138D9E9A0028D27C /* preempt.s */; };
- C9B53E63138DA5950028D27C /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFF138D9E9A0028D27C /* pthread_getspecific.s */; };
- C9B53E64138DA5950028D27C /* pthread_mutex_lock.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E00138D9E9A0028D27C /* pthread_mutex_lock.s */; };
- C9B53E65138DA5950028D27C /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E01138D9E9A0028D27C /* pthread_self.s */; };
- C9B53E66138DA5950028D27C /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E02138D9E9A0028D27C /* pthread_set_self.s */; };
- C9B53E67138DA5950028D27C /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E03138D9E9A0028D27C /* start_wqthread.s */; };
- C9B53E68138DA5950028D27C /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E04138D9E9A0028D27C /* thread_start.s */; };
- C9B53E69138DA59F0028D27C /* __bzero.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E08138D9E9A0028D27C /* __bzero.s */; };
- C9B53E6A138DA59F0028D27C /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; };
- C9B53E6B138DA59F0028D27C /* bcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0A138D9E9A0028D27C /* bcopy_sse3x.s */; };
- C9B53E6C138DA59F0028D27C /* bcopy_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0B138D9E9A0028D27C /* bcopy_sse42.s */; };
- C9B53E6D138DA59F0028D27C /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; };
- C9B53E6E138DA59F0028D27C /* bzero_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0D138D9E9A0028D27C /* bzero_sse2.s */; };
- C9B53E6F138DA59F0028D27C /* bzero_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0E138D9E9A0028D27C /* bzero_sse42.s */; };
- C9B53E70138DA59F0028D27C /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0F138D9E9A0028D27C /* ffs.s */; };
- C9B53E71138DA59F0028D27C /* longcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E10138D9E9A0028D27C /* longcopy_sse3x.s */; };
- C9B53E72138DA59F0028D27C /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E12138D9E9A0028D27C /* memcmp.s */; };
- C9B53E73138DA59F0028D27C /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; };
- C9B53E74138DA59F0028D27C /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; };
- C9B53E75138DA59F0028D27C /* memset.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E15138D9E9A0028D27C /* memset.s */; };
- C9B53E76138DA59F0028D27C /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E16138D9E9A0028D27C /* strcmp.s */; };
C9B53E77138DA59F0028D27C /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E17138D9E9A0028D27C /* strcpy.s */; };
- C9B53E78138DA59F0028D27C /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E18138D9E9A0028D27C /* strlcat.s */; };
- C9B53E79138DA59F0028D27C /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E19138D9E9A0028D27C /* strlcpy.s */; };
C9B53E7A138DA59F0028D27C /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1A138D9E9A0028D27C /* strlen.s */; };
- C9B53E7B138DA59F0028D27C /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1B138D9E9A0028D27C /* strncmp.s */; };
C9B53E7C138DA59F0028D27C /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1C138D9E9A0028D27C /* strncpy.s */; };
- C9B53E7D138DA5A30028D27C /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1E138D9E9A0028D27C /* _setjmp.s */; };
- C9B53E7E138DA5A30028D27C /* _sigtramp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E1F138D9E9A0028D27C /* _sigtramp.s */; };
- C9B53E7F138DA5A30028D27C /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; };
- C9B53E80138DA5A30028D27C /* i386_gettimeofday_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E21138D9E9A0028D27C /* i386_gettimeofday_asm.s */; };
- C9B53E81138DA5A30028D27C /* nanotime.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E23138D9E9A0028D27C /* nanotime.s */; };
- C9B53E82138DA5A30028D27C /* OSAtomic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E24138D9E9A0028D27C /* OSAtomic.s */; };
- C9B53E83138DA5A30028D27C /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E25138D9E9A0028D27C /* setjmp.s */; };
- C9B53E84138DA5A30028D27C /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; };
- C9B53E85138DA5A30028D27C /* spinlocks_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E27138D9E9A0028D27C /* spinlocks_asm.s */; };
C9C2A959138E025700287F00 /* sigaltstk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360C138D9E980028D27C /* sigaltstk.c */; };
C9C2A95A138E025700287F00 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; };
C9C2A95B138E03C700287F00 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; };
C9C2A95C138E03C700287F00 /* dirhelper.defs in Sources */ = {isa = PBXBuildFile; fileRef = C9B53614138D9E980028D27C /* dirhelper.defs */; };
- C9C2A95D138E03C700287F00 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; };
- C9C2A95E138E03C700287F00 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; };
C9C2A97D138E058200287F00 /* brk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5366E138D9E980028D27C /* brk.c */; };
C9C2A97E138E058200287F00 /* bsd_signal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53670138D9E980028D27C /* bsd_signal.c */; };
C9C2A97F138E058200287F00 /* lchflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53672138D9E980028D27C /* lchflags.c */; };
C9C2A981138E058200287F00 /* lutimes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53676138D9E980028D27C /* lutimes.c */; };
C9C2A982138E058200287F00 /* statvfs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53679138D9E980028D27C /* statvfs.c */; };
C9C2A983138E058200287F00 /* tcgetsid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5367B138D9E980028D27C /* tcgetsid.c */; };
- C9C2A998138E06D900287F00 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; };
- C9C2A999138E06D900287F00 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; };
- C9C2A99A138E06D900287F00 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; };
- C9C2A99B138E06D900287F00 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; };
- C9C2A99C138E06D900287F00 /* asl_ipc.defs in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CA138D9E990028D27C /* asl_ipc.defs */; };
- C9C2A99D138E06D900287F00 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; };
- C9C2A99E138E06D900287F00 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; };
- C9C2A99F138E06D900287F00 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; };
- C9C2A9A0138E06D900287F00 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; };
- C9C2A9A1138E06D900287F00 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; };
C9C2A9A2138E06D900287F00 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; };
- C9C2A9A3138E06D900287F00 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; };
C9C2A9A4138E06D900287F00 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; };
C9C2A9A5138E06D900287F00 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; };
C9C2A9A6138E06D900287F00 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; };
C9C2A9AD138E072500287F00 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; };
C9C2A9AE138E072500287F00 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; };
C9C2A9AF138E072500287F00 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; };
- C9C2A9B0138E072500287F00 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; };
- C9C2A9B1138E072500287F00 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; };
- C9C2A9B2138E072500287F00 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; };
- C9C2A9B4138E072500287F00 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; };
C9C2A9B5138E072500287F00 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; };
C9C2A9B6138E072500287F00 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; };
- C9C2A9B7138E072500287F00 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; };
C9C2A9B8138E072500287F00 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; };
C9C2A9B9138E072600287F00 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; };
- C9C2A9BA138E072600287F00 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; };
- C9C2A9BB138E072600287F00 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; };
C9C2A9BC138E072600287F00 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; };
- C9C2A9BD138E072600287F00 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; };
C9C2A9BE138E072600287F00 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; };
C9C2A9BF138E072600287F00 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; };
C9C2A9C0138E072600287F00 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; };
C9C2A9C1138E072600287F00 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; };
- C9CF595A13CD0B9600674871 /* memset_pattern.c in Sources */ = {isa = PBXBuildFile; fileRef = C9CF595913CD0B9600674871 /* memset_pattern.c */; };
C9D94333138DB75B00FB7ACC /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; };
C9D94359138EC0C600FB7ACC /* heapsort_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94357138EC0C600FB7ACC /* heapsort_b.c */; };
C9D9435A138EC0C600FB7ACC /* heapsort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D94358138EC0C600FB7ACC /* heapsort_r.c */; };
- C9EB2F4C138F68A80075BB52 /* _ctx_start.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53811138D9E990028D27C /* _ctx_start.S */; };
- C9EB2F4D138F68A80075BB52 /* _setcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53812138D9E990028D27C /* _setcontext.S */; };
- C9EB2F4E138F68A80075BB52 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53813138D9E990028D27C /* cpu_number.s */; };
- C9EB2F4F138F68A80075BB52 /* getcontext.S in Sources */ = {isa = PBXBuildFile; fileRef = C9B53814138D9E990028D27C /* getcontext.S */; };
- C9EB2F50138F68A80075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; };
- C9EB2F51138F68A80075BB52 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53816138D9E990028D27C /* icacheinval.s */; };
- C9EB2F52138F68A80075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; };
C9EB2F53138F68A80075BB52 /* mcount.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53819138D9E990028D27C /* mcount.s */; };
- C9EB2F54138F68A80075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; };
- C9EB2F55138F68A80075BB52 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; };
- C9EB2F56138F68A80075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; };
- C9EB2F57138F68A80075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; };
- C9EB2F58138F68A80075BB52 /* preempt.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53820138D9E990028D27C /* preempt.s */; };
- C9EB2F59138F68A80075BB52 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53821138D9E990028D27C /* pthread_getspecific.s */; };
- C9EB2F5A138F68A80075BB52 /* pthread_mutex_lock.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53822138D9E990028D27C /* pthread_mutex_lock.s */; };
- C9EB2F5B138F68A80075BB52 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53823138D9E990028D27C /* pthread_self.s */; };
- C9EB2F5C138F68A80075BB52 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53824138D9E990028D27C /* pthread_set_self.s */; };
- C9EB2F5D138F68A80075BB52 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53825138D9E990028D27C /* start_wqthread.s */; };
- C9EB2F5E138F68A80075BB52 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53826138D9E990028D27C /* thread_start.s */; };
- C9EB2F60138F68A80075BB52 /* __bzero.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382A138D9E990028D27C /* __bzero.s */; };
- C9EB2F61138F68A80075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; };
- C9EB2F62138F68A80075BB52 /* bcopy_scalar.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382C138D9E990028D27C /* bcopy_scalar.s */; };
- C9EB2F63138F68A80075BB52 /* bcopy_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382D138D9E990028D27C /* bcopy_sse2.s */; };
- C9EB2F64138F68A80075BB52 /* bcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382E138D9E990028D27C /* bcopy_sse3x.s */; };
- C9EB2F65138F68A80075BB52 /* bcopy_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382F138D9E990028D27C /* bcopy_sse42.s */; };
- C9EB2F66138F68A80075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; };
- C9EB2F67138F68A80075BB52 /* bzero_scalar.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53831138D9E990028D27C /* bzero_scalar.s */; };
- C9EB2F68138F68A80075BB52 /* bzero_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53832138D9E990028D27C /* bzero_sse2.s */; };
- C9EB2F69138F68A80075BB52 /* bzero_sse42.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53833138D9E990028D27C /* bzero_sse42.s */; };
- C9EB2F6A138F68A80075BB52 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53834138D9E990028D27C /* ffs.s */; };
- C9EB2F6B138F68A80075BB52 /* longcopy_sse3x.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53835138D9E990028D27C /* longcopy_sse3x.s */; };
- C9EB2F6C138F68A80075BB52 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53837138D9E990028D27C /* memcmp.s */; };
- C9EB2F6D138F68A80075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; };
- C9EB2F6E138F68A80075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; };
- C9EB2F6F138F68A80075BB52 /* memset.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383A138D9E990028D27C /* memset.s */; };
- C9EB2F70138F68A80075BB52 /* memset_pattern_sse2.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383B138D9E990028D27C /* memset_pattern_sse2.s */; };
- C9EB2F71138F68A80075BB52 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383C138D9E990028D27C /* strcmp.s */; };
C9EB2F72138F68A80075BB52 /* strcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383D138D9E990028D27C /* strcpy.s */; };
C9EB2F73138F68A80075BB52 /* strlcat.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383E138D9E990028D27C /* strlcat.s */; };
C9EB2F74138F68A80075BB52 /* strlcpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5383F138D9E990028D27C /* strlcpy.s */; };
C9EB2F75138F68A80075BB52 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53840138D9E990028D27C /* strlen.s */; };
- C9EB2F76138F68A80075BB52 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53841138D9E990028D27C /* strncmp.s */; };
C9EB2F77138F68A80075BB52 /* strncpy.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53842138D9E990028D27C /* strncpy.s */; };
- C9EB2F78138F68A80075BB52 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53844138D9E990028D27C /* _setjmp.s */; };
- C9EB2F79138F68A80075BB52 /* _sigtramp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53845138D9E990028D27C /* _sigtramp.s */; };
- C9EB2F7A138F68A80075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; };
- C9EB2F7B138F68A80075BB52 /* i386_gettimeofday_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53847138D9E990028D27C /* i386_gettimeofday_asm.s */; };
- C9EB2F7D138F68A80075BB52 /* mach_absolute_time_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B53849138D9E990028D27C /* mach_absolute_time_asm.s */; };
- C9EB2F7E138F68A80075BB52 /* OSAtomic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384B138D9E990028D27C /* OSAtomic.s */; };
- C9EB2F7F138F68A80075BB52 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384C138D9E990028D27C /* setjmp.s */; };
- C9EB2F80138F68A80075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; };
- C9EB2F81138F68A80075BB52 /* spinlocks_asm.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384E138D9E990028D27C /* spinlocks_asm.s */; };
- C9EB2F82138F68CB0075BB52 /* cpu_number.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B1138D9E980028D27C /* cpu_number.s */; };
- C9EB2F83138F68CB0075BB52 /* icacheinval.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B2138D9E980028D27C /* icacheinval.s */; };
C9EB2F84138F68CB0075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; };
- C9EB2F85138F68CB0075BB52 /* pthread_getspecific.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B8138D9E980028D27C /* pthread_getspecific.s */; };
- C9EB2F86138F68CB0075BB52 /* pthread_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B9138D9E980028D27C /* pthread_self.s */; };
- C9EB2F87138F68CB0075BB52 /* pthread_set_self.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BA138D9E980028D27C /* pthread_set_self.s */; };
- C9EB2F88138F68CB0075BB52 /* start_wqthread.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BB138D9E980028D27C /* start_wqthread.s */; };
- C9EB2F89138F68CB0075BB52 /* thread_start.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535BC138D9E980028D27C /* thread_start.s */; };
- C9EB2F8B138F68CB0075BB52 /* bcopy_CortexA8.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C0138D9E980028D27C /* bcopy_CortexA8.s */; };
- C9EB2F8C138F68CB0075BB52 /* bcopy_CortexA9.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C1138D9E980028D27C /* bcopy_CortexA9.s */; };
- C9EB2F8D138F68CB0075BB52 /* bcopy_Generic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C2138D9E980028D27C /* bcopy_Generic.s */; };
- C9EB2F8E138F68CB0075BB52 /* bzero_CortexA8.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C3138D9E980028D27C /* bzero_CortexA8.s */; };
- C9EB2F8F138F68CB0075BB52 /* bzero_CortexA9.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C4138D9E980028D27C /* bzero_CortexA9.s */; };
- C9EB2F90138F68CB0075BB52 /* bzero_Generic.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C5138D9E980028D27C /* bzero_Generic.s */; };
- C9EB2F91138F68CB0075BB52 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; };
- C9EB2F92138F68CB0075BB52 /* ffs.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C7138D9E980028D27C /* ffs.s */; };
- C9EB2F93138F68CB0075BB52 /* memcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C9138D9E980028D27C /* memcmp.s */; };
- C9EB2F94138F68CB0075BB52 /* memset_pattern.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CA138D9E980028D27C /* memset_pattern.s */; };
- C9EB2F95138F68CB0075BB52 /* strchr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CB138D9E980028D27C /* strchr.s */; };
- C9EB2F96138F68CB0075BB52 /* strcmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CC138D9E980028D27C /* strcmp.s */; };
C9EB2F99138F68CB0075BB52 /* strlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535CF138D9E980028D27C /* strlen.s */; };
- C9EB2F9A138F68CB0075BB52 /* strncmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D0138D9E980028D27C /* strncmp.s */; };
C9EB2F9C138F68CB0075BB52 /* strnlen.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D2138D9E980028D27C /* strnlen.s */; };
C9EB2F9D138F68CB0075BB52 /* strstr.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D3138D9E980028D27C /* strstr.s */; };
- C9EB2F9E138F68CB0075BB52 /* _longjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D5138D9E980028D27C /* _longjmp.s */; };
- C9EB2FA0138F68CB0075BB52 /* _setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D7138D9E980028D27C /* _setjmp.s */; };
- C9EB2FA1138F68CB0075BB52 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; };
- C9EB2FA2138F68CB0075BB52 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; };
- C9EB2FA3138F68CB0075BB52 /* longjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DA138D9E980028D27C /* longjmp.s */; };
- C9EB2FA4138F68CB0075BB52 /* mach_absolute_time.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DB138D9E980028D27C /* mach_absolute_time.s */; };
- C9EB2FA5138F68CB0075BB52 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; };
- C9EB2FA7138F68CB0075BB52 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; };
- C9EB2FA9138F68CB0075BB52 /* setjmp.s in Sources */ = {isa = PBXBuildFile; fileRef = C9B535E1138D9E980028D27C /* setjmp.s */; };
C9EB2FBB138F6A920075BB52 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; };
C9EB2FC1138F6BB00075BB52 /* merge_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB2FC0138F6BB00075BB52 /* merge_b.c */; };
C9EB2FC4138F6C5C0075BB52 /* psort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB2FC3138F6C5C0075BB52 /* psort.c */; };
C9EB2FC7138F6CE10075BB52 /* psort_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB2FC5138F6CE10075BB52 /* psort_b.c */; settings = {COMPILER_FLAGS = "-DI_AM_PSORT_B"; }; };
C9EB2FC8138F6CE10075BB52 /* psort_r.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB2FC6138F6CE10075BB52 /* psort_r.c */; settings = {COMPILER_FLAGS = "-DI_AM_PSORT_R"; }; };
C9EB2FCD138F6D880075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; };
- C9EB2FCE138F6D880075BB52 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; };
- C9EB2FCF138F6D880075BB52 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; };
- C9EB2FD0138F6D880075BB52 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; };
- C9EB2FD1138F6D880075BB52 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; };
- C9EB2FD2138F6D880075BB52 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; };
C9EB2FD4138F6D880075BB52 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; };
C9EB2FD5138F6D880075BB52 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; };
C9EB2FD6138F6D880075BB52 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; };
C9EB2FDF138F6D880075BB52 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; };
C9EB2FE0138F6D880075BB52 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; };
C9EB2FE1138F6D880075BB52 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; };
- C9EB2FE2138F6D880075BB52 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; };
- C9EB2FE3138F6D880075BB52 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; };
- C9EB2FE4138F6D880075BB52 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; };
C9EB2FE5138F6D880075BB52 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; };
C9EB2FE6138F6D880075BB52 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; };
C9EB2FE7138F6D880075BB52 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; };
C9EB3022138F6D880075BB52 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; };
C9EB3023138F6D880075BB52 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; };
C9EB3024138F6D880075BB52 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; };
- C9EB3025138F6D880075BB52 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; };
- C9EB3026138F6D880075BB52 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; };
- C9EB3027138F6D880075BB52 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; };
- C9EB3028138F6D880075BB52 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; };
- C9EB3029138F6D880075BB52 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; };
- C9EB302A138F6D880075BB52 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; };
- C9EB302B138F6D880075BB52 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; };
- C9EB302C138F6D880075BB52 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; };
- C9EB302D138F6D880075BB52 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; };
C9EB302E138F6D880075BB52 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; };
C9EB302F138F6D880075BB52 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; };
- C9EB3030138F6D880075BB52 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; };
C9EB3031138F6D880075BB52 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_CONFSTR"; }; };
C9EB3032138F6D880075BB52 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY"; }; };
C9EB3033138F6D880075BB52 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; };
C9EB3087138F6D880075BB52 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; };
C9EB3088138F6D880075BB52 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; };
C9EB3089138F6D880075BB52 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; };
- C9EB308A138F6D880075BB52 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; };
- C9EB308B138F6D880075BB52 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; };
- C9EB308C138F6D880075BB52 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; };
- C9EB308D138F6D880075BB52 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; };
C9EB308E138F6D880075BB52 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; };
C9EB308F138F6D880075BB52 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; };
C9EB3090138F6D880075BB52 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW"; }; };
C9EB3091138F6D880075BB52 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; };
C9EB3092138F6D880075BB52 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; };
C9EB3093138F6D880075BB52 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; };
- C9EB3094138F6D880075BB52 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; };
- C9EB3095138F6D880075BB52 /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; };
C9EB3096138F6D880075BB52 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; };
C9EB3097138F6D880075BB52 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; };
- C9EB3098138F6D880075BB52 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; };
- C9EB3099138F6D880075BB52 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; };
C9EB309A138F6D880075BB52 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; };
- C9EB309B138F6D880075BB52 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; };
C9EB309C138F6D880075BB52 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; };
C9EB309D138F6D880075BB52 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; };
C9EB309E138F6D880075BB52 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; };
C9EB309F138F6D880075BB52 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; };
C9EB30A1138F6D880075BB52 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; };
- C9EB30A2138F6D880075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; };
- C9EB30A3138F6D880075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; };
- C9EB30A4138F6D880075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; };
- C9EB30A5138F6D880075BB52 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; };
- C9EB30A6138F6D880075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; };
- C9EB30A7138F6D880075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; };
- C9EB30A8138F6D880075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; };
- C9EB30A9138F6D880075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; };
- C9EB30AA138F6D880075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; };
- C9EB30AB138F6D880075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; };
- C9EB30AC138F6D880075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; };
- C9EB30AE138F6D880075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; };
C9EB30C1138F6D880075BB52 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; };
C9EB30C2138F6D880075BB52 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; };
C9EB30C3138F6D880075BB52 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; };
C9EB3116138F6D880075BB52 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; };
C9EB3117138F6D880075BB52 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; };
C9EB3118138F6D880075BB52 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; };
- C9EB3121138F6D880075BB52 /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; };
- C9EB3122138F6D880075BB52 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_CANCEL -DLIBC_ALIAS_PTHREAD_SETCANCELSTATE -DLIBC_ALIAS_PTHREAD_SETCANCELTYPE -DLIBC_ALIAS_PTHREAD_SIGMASK -DLIBC_ALIAS_PTHREAD_TESTCANCEL"; }; };
- C9EB3123138F6D880075BB52 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; };
- C9EB3124138F6D880075BB52 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_INIT"; }; };
- C9EB3125138F6D880075BB52 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY"; }; };
- C9EB3126138F6D880075BB52 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_RWLOCK_DESTROY -DLIBC_ALIAS_PTHREAD_RWLOCK_INIT -DLIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK"; }; };
- C9EB3127138F6D880075BB52 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; };
- C9EB3128138F6D880075BB52 /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; };
- C9EB3129138F6D880075BB52 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; };
C9EB312C138F6D880075BB52 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; };
- C9EB312F138F6D880075BB52 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
- C9EB3130138F6D880075BB52 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
- C9EB3131138F6D880075BB52 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
- C9EB3132138F6D880075BB52 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
- C9EB3133138F6D880075BB52 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
- C9EB3134138F6D880075BB52 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
- C9EB3135138F6D880075BB52 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
- C9EB3136138F6D880075BB52 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
- C9EB3137138F6D880075BB52 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
- C9EB3138138F6D880075BB52 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
- C9EB3139138F6D880075BB52 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
- C9EB313A138F6D880075BB52 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
- C9EB313B138F6D880075BB52 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
- C9EB313C138F6D880075BB52 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
C9EB313D138F6D880075BB52 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; };
C9EB313E138F6D880075BB52 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; };
C9EB313F138F6D880075BB52 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; };
C9EB31DF138F6D880075BB52 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; };
C9EB31E0138F6D880075BB52 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; settings = {COMPILER_FLAGS = "-D_DARWIN_UNLIMITED_STREAMS"; }; };
C9EB31E1138F6D880075BB52 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; };
- C9EB31E2138F6D880075BB52 /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; };
- C9EB31E3138F6D880075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; };
- C9EB31E4138F6D880075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; };
C9EB31E5138F6D880075BB52 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; };
- C9EB31E6138F6D880075BB52 /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; };
- C9EB31E7138F6D880075BB52 /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; };
- C9EB31E8138F6D880075BB52 /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; };
- C9EB31E9138F6D880075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; };
C9EB31EA138F6D880075BB52 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; };
- C9EB31EB138F6D880075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; };
- C9EB31EC138F6D880075BB52 /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; };
C9EB31ED138F6D880075BB52 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; };
C9EB31F0138F6D880075BB52 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; };
C9EB31F1138F6D880075BB52 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; };
- C9EB31F3138F6D880075BB52 /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; };
- C9EB31F4138F6D880075BB52 /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; };
C9EB31F5138F6D880075BB52 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; };
C9EB31F7138F6D880075BB52 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; };
C9EB31F8138F6D880075BB52 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; };
C9EB31F9138F6D880075BB52 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRERROR"; }; };
C9EB31FC138F6D880075BB52 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; };
C9EB31FD138F6D880075BB52 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; };
- C9EB31FF138F6D880075BB52 /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; };
C9EB3201138F6D880075BB52 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; };
C9EB3202138F6D880075BB52 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; };
C9EB3203138F6D880075BB52 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; };
C9EB322B138F6D880075BB52 /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; };
C9EB322C138F6D880075BB52 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; };
C9EB322D138F6D880075BB52 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; };
- C9EB322E138F6D880075BB52 /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; };
C9EB322F138F6D880075BB52 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; };
- C9EB3230138F6D880075BB52 /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; };
C9EB3231138F6D880075BB52 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; };
C9EB3232138F6D880075BB52 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; };
- C9EB3233138F6D880075BB52 /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; };
C9EB3234138F6D880075BB52 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; };
C9EB3235138F6D880075BB52 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_MSGCTL -DKERNEL"; }; };
C9EB3236138F6D880075BB52 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; };
C9EB323C138F6D880075BB52 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; };
C9EB323D138F6D880075BB52 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SHMCTL -DKERNEL"; }; };
C9EB323E138F6D880075BB52 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; };
- C9EB323F138F6D880075BB52 /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; };
- C9EB3240138F6D880075BB52 /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; };
- C9EB3241138F6D880075BB52 /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; };
C9EB3242138F6D880075BB52 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; };
C9EB3243138F6D880075BB52 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; };
- C9EB3244138F6D880075BB52 /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; };
- C9EB3245138F6D880075BB52 /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; };
- C9EB3246138F6D880075BB52 /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; };
C9EB3247138F6D880075BB52 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; };
C9EB3248138F6D880075BB52 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; };
C9EB3249138F6D880075BB52 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; };
C9EB3254138F6D880075BB52 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; };
C9EB3255138F6D880075BB52 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; };
C9EB3256138F6D880075BB52 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; };
- C9EB3257138F6D880075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; };
- C9EB3258138F6D880075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; };
- C9EB3259138F6D880075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; };
- C9EB325A138F6D880075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; };
- C9EB325B138F6D880075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; };
- C9EB325C138F6D880075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; };
- C9EB325D138F6D880075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; };
- C9EB325E138F6D880075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; };
- C9EB325F138F6D880075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; };
- C9EB3260138F6D880075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; };
C9EB3274138F75580075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */; };
- C9EB3275138F75580075BB52 /* dyld_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535C6138D9E980028D27C /* dyld_resolvers.c */; };
- C9EB3276138F75580075BB52 /* arm_commpage_gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */; };
- C9EB3277138F75580075BB52 /* gcc_atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535D9138D9E980028D27C /* gcc_atomic.c */; };
- C9EB3278138F75580075BB52 /* OSAtomic-v4.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DD138D9E980028D27C /* OSAtomic-v4.c */; };
- C9EB3279138F75580075BB52 /* OSAtomic_resolvers.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */; };
C9EB327B138F75580075BB52 /* creat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535F8138D9E980028D27C /* creat.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_CREAT"; }; };
C9EB327C138F75580075BB52 /* gethostid.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FC138D9E980028D27C /* gethostid.c */; };
C9EB327D138F75580075BB52 /* getwd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B535FE138D9E980028D27C /* getwd.c */; };
C9EB3286138F75580075BB52 /* sigcompat.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5360E138D9E980028D27C /* sigcompat.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SIGPAUSE"; }; };
C9EB3287138F75580075BB52 /* _dirhelper.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53613138D9E980028D27C /* _dirhelper.c */; };
C9EB3288138F75580075BB52 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; };
- C9EB3289138F75580075BB52 /* libproc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53617138D9E980028D27C /* libproc.c */; };
- C9EB328A138F75580075BB52 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; };
- C9EB328B138F75580075BB52 /* proc_listpidspath.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361C138D9E980028D27C /* proc_listpidspath.c */; };
C9EB328C138F75580075BB52 /* forceLibcToBuild.c in Sources */ = {isa = PBXBuildFile; fileRef = C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */; };
C9EB328D138F75580075BB52 /* bt_close.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53620138D9E980028D27C /* bt_close.c */; };
C9EB328E138F75580075BB52 /* bt_conv.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53621138D9E980028D27C /* bt_conv.c */; };
C9EB32C9138F75580075BB52 /* machdep_ldisdd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536B8138D9E980028D27C /* machdep_ldisdd.c */; };
C9EB32CA138F75580075BB52 /* machdep_ldisQ.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BA138D9E980028D27C /* machdep_ldisQ.c */; };
C9EB32CB138F75580075BB52 /* machdep_ldisx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536BB138D9E980028D27C /* machdep_ldisx.c */; };
- C9EB32CC138F75580075BB52 /* _simple.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C2138D9E990028D27C /* _simple.c */; };
- C9EB32CD138F75580075BB52 /* asl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C5138D9E990028D27C /* asl.c */; };
- C9EB32CE138F75580075BB52 /* asl_core.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C6138D9E990028D27C /* asl_core.c */; };
- C9EB32CF138F75580075BB52 /* asl_file.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536C8138D9E990028D27C /* asl_file.c */; };
- C9EB32D0138F75580075BB52 /* asl_legacy1.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CB138D9E990028D27C /* asl_legacy1.c */; };
- C9EB32D1138F75580075BB52 /* asl_msg.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536CD138D9E990028D27C /* asl_msg.c */; };
- C9EB32D2138F75580075BB52 /* asl_store.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D0138D9E990028D27C /* asl_store.c */; };
- C9EB32D3138F75580075BB52 /* asl_util.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D2138D9E990028D27C /* asl_util.c */; };
- C9EB32D4138F75580075BB52 /* assumes.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D3138D9E990028D27C /* assumes.c */; };
C9EB32D5138F75580075BB52 /* authentication.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D5138D9E990028D27C /* authentication.c */; };
C9EB32D6138F75580075BB52 /* backtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D7138D9E990028D27C /* backtrace.c */; };
- C9EB32D7138F75580075BB52 /* cache.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536D8138D9E990028D27C /* cache.c */; };
C9EB32D8138F75580075BB52 /* confstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DB138D9E990028D27C /* confstr.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_CONFSTR"; }; };
C9EB32D9138F75580075BB52 /* crypt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DD138D9E990028D27C /* crypt.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_ENCRYPT -DLIBC_ALIAS_SETKEY"; }; };
C9EB32DA138F75580075BB52 /* devname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B536DF138D9E990028D27C /* devname.c */; };
C9EB332E138F75580075BB52 /* getttyent.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CC138D9E990028D27C /* getttyent.c */; };
C9EB332F138F75580075BB52 /* getusershell.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537CE138D9E990028D27C /* getusershell.c */; };
C9EB3330138F75580075BB52 /* getvfsbyname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D0138D9E990028D27C /* getvfsbyname.c */; };
- C9EB3331138F75580075BB52 /* isinf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D2138D9E990028D27C /* isinf.c */; };
- C9EB3332138F75580075BB52 /* isnan.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D3138D9E990028D27C /* isnan.c */; };
- C9EB3333138F75580075BB52 /* magazine_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D4138D9E990028D27C /* magazine_malloc.c */; };
- C9EB3334138F75580075BB52 /* malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537D8138D9E990028D27C /* malloc.c */; };
C9EB3335138F75580075BB52 /* nanosleep.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537DC138D9E990028D27C /* nanosleep.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_NANOSLEEP"; }; };
C9EB3336138F75580075BB52 /* utmpx.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E4138D9E990028D27C /* utmpx.c */; };
C9EB3337138F75580075BB52 /* nftw.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E6138D9E990028D27C /* nftw.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_FTW -DLIBC_ALIAS_NFTW"; }; };
C9EB3338138F75580075BB52 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; };
C9EB3339138F75580075BB52 /* NSSystemDirectories.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E9138D9E990028D27C /* NSSystemDirectories.c */; };
C9EB333A138F75580075BB52 /* oldsyslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EA138D9E990028D27C /* oldsyslog.c */; };
- C9EB333B138F75580075BB52 /* platfunc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EB138D9E990028D27C /* platfunc.c */; };
- C9EB333C138F75580075BB52 /* scalable_malloc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537EF138D9E990028D27C /* scalable_malloc.c */; };
C9EB333D138F75580075BB52 /* setlogin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F2138D9E990028D27C /* setlogin.c */; };
C9EB333E138F75580075BB52 /* sigsetops.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F4138D9E990028D27C /* sigsetops.c */; };
- C9EB333F138F75580075BB52 /* stack_logging.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F5138D9E990028D27C /* stack_logging.c */; };
- C9EB3340138F75580075BB52 /* stack_logging_disk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F7138D9E990028D27C /* stack_logging_disk.c */; };
C9EB3341138F75580075BB52 /* strtofflags.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537F9138D9E990028D27C /* strtofflags.c */; };
- C9EB3342138F75580075BB52 /* syslog.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537FB138D9E990028D27C /* syslog.c */; };
C9EB3343138F75580075BB52 /* thread_stack_pcs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53800138D9E990028D27C /* thread_stack_pcs.c */; };
C9EB3344138F75580075BB52 /* uname.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53803138D9E990028D27C /* uname.c */; };
C9EB3345138F75580075BB52 /* utmpx-darwin.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53804138D9E990028D27C /* utmpx-darwin.c */; };
C9EB3346138F75580075BB52 /* wordexp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53808138D9E990028D27C /* wordexp.c */; };
C9EB3348138F75580075BB52 /* gmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5380B138D9E990028D27C /* gmon.c */; };
- C9EB3349138F75580075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53815138D9E990028D27C /* getmcontext.c */; };
- C9EB334A138F75580075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53817138D9E990028D27C /* makecontext.c */; };
- C9EB334B138F75580075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381A138D9E990028D27C /* setcontext.c */; };
- C9EB334C138F75580075BB52 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381B138D9E990028D27C /* setjmperr.c */; };
- C9EB334D138F75580075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381C138D9E990028D27C /* swapcontext.c */; };
- C9EB334E138F75580075BB52 /* init_cpu_capabilities.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */; };
- C9EB334F138F75580075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5382B138D9E990028D27C /* bcopy.c */; };
- C9EB3350138F75580075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53830138D9E990028D27C /* bzero.c */; };
- C9EB3351138F75580075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53838138D9E990028D27C /* memcpy.c */; };
- C9EB3352138F75580075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53839138D9E990028D27C /* memmove.c */; };
- C9EB3353138F75580075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53846138D9E990028D27C /* atomic.c */; };
- C9EB3355138F75580075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5384D138D9E990028D27C /* spinlocks.c */; };
C9EB3368138F75580075BB52 /* ascii.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53902138D9E990028D27C /* ascii.c */; };
C9EB3369138F75580075BB52 /* big5.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53905138D9E990028D27C /* big5.c */; };
C9EB336A138F75580075BB52 /* btowc.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53909138D9E990028D27C /* btowc.c */; };
C9EB33BD138F75580075BB52 /* acl_flag.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A5B138D9E990028D27C /* acl_flag.c */; };
C9EB33BE138F75580075BB52 /* acl_perm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A68138D9E990028D27C /* acl_perm.c */; };
C9EB33BF138F75580075BB52 /* acl_translate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53A6F138D9E990028D27C /* acl_translate.c */; };
- C9EB33C8138F75580075BB52 /* mk_pthread_impl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */; };
- C9EB33C9138F75580075BB52 /* pthread.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AC0138D9E990028D27C /* pthread.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_CANCEL -DLIBC_ALIAS_PTHREAD_SETCANCELSTATE -DLIBC_ALIAS_PTHREAD_SETCANCELTYPE -DLIBC_ALIAS_PTHREAD_SIGMASK -DLIBC_ALIAS_PTHREAD_TESTCANCEL"; }; };
- C9EB33CA138F75580075BB52 /* pthread_cancelable.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53ACD138D9E990028D27C /* pthread_cancelable.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_TIMEDWAIT -DLIBC_ALIAS_PTHREAD_COND_WAIT -DLIBC_ALIAS_PTHREAD_JOIN -DLIBC_ALIAS_SIGWAIT"; }; };
- C9EB33CB138F75580075BB52 /* pthread_cond.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AD0138D9E990028D27C /* pthread_cond.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_COND_INIT"; }; };
- C9EB33CC138F75580075BB52 /* pthread_mutex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AE4138D9E990028D27C /* pthread_mutex.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY"; }; };
- C9EB33CD138F75580075BB52 /* pthread_rwlock.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AEC138D9E990028D27C /* pthread_rwlock.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_PTHREAD_RWLOCK_DESTROY -DLIBC_ALIAS_PTHREAD_RWLOCK_INIT -DLIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK -DLIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK"; }; };
- C9EB33CE138F75580075BB52 /* pthread_tsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53AFB138D9E990028D27C /* pthread_tsd.c */; };
- C9EB33CF138F75580075BB52 /* pthread_atfork_test.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B01138D9E990028D27C /* pthread_atfork_test.c */; };
- C9EB33D0138F75580075BB52 /* thread_setup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B02138D9E990028D27C /* thread_setup.c */; };
C9EB33D3138F75580075BB52 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B0E138D9E990028D27C /* regerror.c */; };
- C9EB33D6138F75580075BB52 /* chk_fail.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B1E138D9E990028D27C /* chk_fail.c */; };
- C9EB33D7138F75580075BB52 /* memcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B20138D9E990028D27C /* memcpy_chk.c */; };
- C9EB33D8138F75580075BB52 /* memmove_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B21138D9E990028D27C /* memmove_chk.c */; };
- C9EB33D9138F75580075BB52 /* memset_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B22138D9E990028D27C /* memset_chk.c */; };
- C9EB33DA138F75580075BB52 /* snprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B23138D9E990028D27C /* snprintf_chk.c */; };
- C9EB33DB138F75580075BB52 /* sprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B24138D9E990028D27C /* sprintf_chk.c */; };
- C9EB33DC138F75580075BB52 /* stpcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B25138D9E990028D27C /* stpcpy_chk.c */; };
- C9EB33DD138F75580075BB52 /* stpncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B26138D9E990028D27C /* stpncpy_chk.c */; };
- C9EB33DE138F75580075BB52 /* strcat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B27138D9E990028D27C /* strcat_chk.c */; };
- C9EB33DF138F75580075BB52 /* strcpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B28138D9E990028D27C /* strcpy_chk.c */; };
- C9EB33E0138F75580075BB52 /* strncat_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B29138D9E990028D27C /* strncat_chk.c */; };
- C9EB33E1138F75580075BB52 /* strncpy_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2A138D9E990028D27C /* strncpy_chk.c */; };
- C9EB33E2138F75580075BB52 /* vsnprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */; };
- C9EB33E3138F75580075BB52 /* vsprintf_chk.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2C138D9E990028D27C /* vsprintf_chk.c */; };
C9EB33E4138F75580075BB52 /* _flock_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B2F138D9E990028D27C /* _flock_stub.c */; };
C9EB33E5138F75580075BB52 /* asprintf.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B30138D9E990028D27C /* asprintf.c */; };
C9EB33E6138F75580075BB52 /* clrerr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53B32138D9E990028D27C /* clrerr.c */; };
C9EB3486138F75580075BB52 /* timelocal.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CD7138D9E9A0028D27C /* timelocal.c */; };
C9EB3487138F75580075BB52 /* getdate.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE0138D9E9A0028D27C /* getdate.c */; settings = {COMPILER_FLAGS = "-D_DARWIN_UNLIMITED_STREAMS"; }; };
C9EB3488138F75580075BB52 /* timezone_unix03.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */; };
- C9EB3489138F75580075BB52 /* bcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CE8138D9E9A0028D27C /* bcmp.c */; };
- C9EB348A138F75580075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CEB138D9E9A0028D27C /* bcopy.c */; };
- C9EB348B138F75580075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF1138D9E9A0028D27C /* bzero.c */; };
C9EB348C138F75580075BB52 /* index.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CF7138D9E9A0028D27C /* index.c */; };
- C9EB348D138F75580075BB52 /* memccpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFA138D9E9A0028D27C /* memccpy.c */; };
- C9EB348E138F75580075BB52 /* memchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CFD138D9E9A0028D27C /* memchr.c */; };
- C9EB348F138F75580075BB52 /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D00138D9E9A0028D27C /* memcmp.c */; };
- C9EB3490138F75580075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D03138D9E9A0028D27C /* memcpy.c */; };
C9EB3491138F75580075BB52 /* memmem.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D06138D9E9A0028D27C /* memmem.c */; };
- C9EB3492138F75580075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D09138D9E9A0028D27C /* memmove.c */; };
- C9EB3493138F75580075BB52 /* memset.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D0D138D9E9A0028D27C /* memset.c */; };
C9EB3494138F75580075BB52 /* rindex.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D10138D9E9A0028D27C /* rindex.c */; };
C9EB3497138F75580075BB52 /* strcasecmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D15138D9E9A0028D27C /* strcasecmp.c */; };
C9EB3498138F75580075BB52 /* strcasestr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D17138D9E9A0028D27C /* strcasestr.c */; };
- C9EB349A138F75580075BB52 /* strchr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D1E138D9E9A0028D27C /* strchr.c */; };
- C9EB349B138F75580075BB52 /* strcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D22138D9E9A0028D27C /* strcmp.c */; };
C9EB349C138F75580075BB52 /* strcoll.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D26138D9E9A0028D27C /* strcoll.c */; };
C9EB349E138F75580075BB52 /* strcspn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D2D138D9E9A0028D27C /* strcspn.c */; };
C9EB349F138F75580075BB52 /* strdup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D30138D9E9A0028D27C /* strdup.c */; };
C9EB34A0138F75580075BB52 /* strerror.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D33138D9E9A0028D27C /* strerror.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -DLIBC_ALIAS_STRERROR"; }; };
C9EB34A3138F75580075BB52 /* strlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D3C138D9E9A0028D27C /* strlen.c */; };
C9EB34A4138F75580075BB52 /* strmode.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D40138D9E9A0028D27C /* strmode.c */; };
- C9EB34A6138F75580075BB52 /* strncmp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D42138D9E9A0028D27C /* strncmp.c */; };
C9EB34A8138F75580075BB52 /* strndup.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D44138D9E9A0028D27C /* strndup.c */; };
C9EB34A9138F75580075BB52 /* strnlen.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D45138D9E9A0028D27C /* strnlen.c */; };
C9EB34AA138F75580075BB52 /* strnstr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D46138D9E9A0028D27C /* strnstr.c */; };
C9EB34D2138F75580075BB52 /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; };
C9EB34D3138F75580075BB52 /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; };
C9EB34D4138F75580075BB52 /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; };
- C9EB34D5138F75580075BB52 /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; };
C9EB34D6138F75580075BB52 /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; };
- C9EB34D7138F75580075BB52 /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; };
C9EB34D8138F75580075BB52 /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; };
C9EB34D9138F75580075BB52 /* getgroups.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9F138D9E9A0028D27C /* getgroups.c */; };
- C9EB34DA138F75580075BB52 /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; };
C9EB34DB138F75580075BB52 /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; };
C9EB34DC138F75580075BB52 /* msgctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA6138D9E9A0028D27C /* msgctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_MSGCTL -DKERNEL"; }; };
C9EB34DD138F75580075BB52 /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; };
C9EB34E3138F75580075BB52 /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; };
C9EB34E4138F75580075BB52 /* shmctl.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB4138D9E9A0028D27C /* shmctl.c */; settings = {COMPILER_FLAGS = "-DLIBC_ALIAS_SHMCTL -DKERNEL"; }; };
C9EB34E5138F75580075BB52 /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; };
- C9EB34E6138F75580075BB52 /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; };
- C9EB34E7138F75580075BB52 /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; };
- C9EB34E8138F75580075BB52 /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; };
C9EB34E9138F75580075BB52 /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; };
C9EB34EA138F75580075BB52 /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; };
- C9EB34EB138F75580075BB52 /* cprocs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC0138D9E9A0028D27C /* cprocs.c */; };
- C9EB34EC138F75580075BB52 /* cthreads.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC2138D9E9A0028D27C /* cthreads.c */; };
- C9EB34ED138F75580075BB52 /* mig_support.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC5138D9E9A0028D27C /* mig_support.c */; };
C9EB34EE138F75580075BB52 /* fparseln.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DC8138D9E9A0028D27C /* fparseln.c */; };
C9EB34EF138F75580075BB52 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; };
C9EB34F0138F75580075BB52 /* login_tty.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCB138D9E9A0028D27C /* login_tty.c */; };
C9EB34FB138F75580075BB52 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE1138D9E9A0028D27C /* parse.c */; };
C9EB34FC138F75580075BB52 /* unpack.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE2138D9E9A0028D27C /* unpack.c */; };
C9EB34FD138F75580075BB52 /* unparse.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DE3138D9E9A0028D27C /* unparse.c */; };
- C9EB34FE138F75580075BB52 /* getmcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF5138D9E9A0028D27C /* getmcontext.c */; };
- C9EB34FF138F75580075BB52 /* makecontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DF7138D9E9A0028D27C /* makecontext.c */; };
- C9EB3500138F75580075BB52 /* setcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFA138D9E9A0028D27C /* setcontext.c */; };
- C9EB3501138F75580075BB52 /* swapcontext.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DFB138D9E9A0028D27C /* swapcontext.c */; };
- C9EB3502138F75580075BB52 /* bcopy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E09138D9E9A0028D27C /* bcopy.c */; };
- C9EB3503138F75580075BB52 /* bzero.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E0C138D9E9A0028D27C /* bzero.c */; };
- C9EB3504138F75580075BB52 /* memcpy.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E13138D9E9A0028D27C /* memcpy.c */; };
- C9EB3505138F75580075BB52 /* memmove.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E14138D9E9A0028D27C /* memmove.c */; };
- C9EB3506138F75580075BB52 /* atomic.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E20138D9E9A0028D27C /* atomic.c */; };
- C9EB3507138F75580075BB52 /* spinlocks.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53E26138D9E9A0028D27C /* spinlocks.c */; };
C9EB350F138F769B0075BB52 /* scandir_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB350E138F769B0075BB52 /* scandir_b.c */; };
C9EB3510138F76A10075BB52 /* scandir_b.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB350E138F769B0075BB52 /* scandir_b.c */; settings = {COMPILER_FLAGS = "$(FreeBSD_CFLAGS) -include gen/__dirent.h"; }; };
C9EB3542138F7D0A0075BB52 /* login.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCA138D9E9A0028D27C /* login.c */; };
C9EB3543138F7D0A0075BB52 /* logout.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DCC138D9E9A0028D27C /* logout.c */; };
C9EB3550138F7EA50075BB52 /* getmntinfo64.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB354F138F7EA50075BB52 /* getmntinfo64.c */; };
- C9EB3556138F7F6A0075BB52 /* setjmperr.c in Sources */ = {isa = PBXBuildFile; fileRef = C9EB3555138F7F6A0075BB52 /* setjmperr.c */; };
C9EB3558138F7FF40075BB52 /* nlist.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B537E8138D9E990028D27C /* nlist.c */; };
C9EB355C138F81A40075BB52 /* kvm.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53616138D9E980028D27C /* kvm.c */; };
- C9EB355E138F81AB0075BB52 /* MKGetTimeBaseInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */; };
C9FA32F4138E49550089A94B /* abort.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53C1D138D9E9A0028D27C /* abort.c */; };
C9FA32F9138E4A5C0089A94B /* utf2.c in Sources */ = {isa = PBXBuildFile; fileRef = C9FA32F8138E4A5C0089A94B /* utf2.c */; };
C9FA32FB138E4BD00089A94B /* __libc_init.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D94138D9E9A0028D27C /* __libc_init.c */; };
C9FA32FC138E4BD00089A94B /* _libc_fork_child.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */; };
C9FA32FD138E4BD00089A94B /* chmodx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D99138D9E9A0028D27C /* chmodx_np.c */; };
- C9FA32FE138E4BD00089A94B /* context-stubs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9B138D9E9A0028D27C /* context-stubs.c */; };
C9FA32FF138E4BD00089A94B /* crt_externs.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9C138D9E9A0028D27C /* crt_externs.c */; };
- C9FA3300138E4BD00089A94B /* errno.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9D138D9E9A0028D27C /* errno.c */; };
C9FA3301138E4BD00089A94B /* fork.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53D9E138D9E9A0028D27C /* fork.c */; };
- C9FA3302138E4BD00089A94B /* getiopolicy_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */; };
C9FA3303138E4BD00089A94B /* gettimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA2138D9E9A0028D27C /* gettimeofday.c */; };
C9FA3304138E4BD00089A94B /* openx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAB138D9E9A0028D27C /* openx_np.c */; };
C9FA3307138E4BD00089A94B /* posix_spawn.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DAE138D9E9A0028D27C /* posix_spawn.c */; };
C9FA3308138E4BD00089A94B /* settimeofday.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB3138D9E9A0028D27C /* settimeofday.c */; };
C9FA3309138E4BD00089A94B /* sigaction.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB5138D9E9A0028D27C /* sigaction.c */; };
- C9FA330A138E4BD00089A94B /* sigcatch.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB6138D9E9A0028D27C /* sigcatch.c */; };
- C9FA330B138E4BD00089A94B /* sigtramp.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DB8138D9E9A0028D27C /* sigtramp.c */; };
- C9FA330C138E4BD00089A94B /* slot_name.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBA138D9E9A0028D27C /* slot_name.c */; };
C9FA330D138E4BD00089A94B /* statx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBC138D9E9A0028D27C /* statx_np.c */; };
C9FA330E138E4BD00089A94B /* umaskx_np.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DBE138D9E9A0028D27C /* umaskx_np.c */; };
C9FA3312138E4C490089A94B /* stack_protector.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53DA9138D9E9A0028D27C /* stack_protector.c */; settings = {COMPILER_FLAGS = "-fno-stack-protector"; }; };
C9FA334B138E4D040089A94B /* gcvt.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB9138D9E9A0028D27C /* gcvt.c */; };
C9FA334C138E4D040089A94B /* qsort_b-fbsd.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CBD138D9E9A0028D27C /* qsort_b-fbsd.c */; };
C9FA334D138E4D0C0089A94B /* strfmon.c in Sources */ = {isa = PBXBuildFile; fileRef = C9B53CB2138D9E9A0028D27C /* strfmon.c */; };
+ FC2ED610157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; };
+ FC2ED611157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; };
+ FC2ED612157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; };
+ FC2ED613157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; };
+ FC2ED614157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; };
+ FC2ED615157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; };
+ FC2ED616157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; };
+ FC2ED617157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; };
+ FC2ED618157D4BE80098EC69 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60E157D4BE70098EC69 /* inet_ntop.c */; };
+ FC2ED619157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; };
+ FC2ED61A157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; };
+ FC2ED61B157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; };
+ FC2ED61C157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; };
+ FC2ED61D157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; };
+ FC2ED61E157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; };
+ FC2ED61F157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; };
+ FC2ED620157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; };
+ FC2ED621157D4BE80098EC69 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC2ED60F157D4BE70098EC69 /* inet_pton.c */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
+ 3F51211616C318EB00AFB431 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 3F51206A16C3174300AFB431;
+ remoteInfo = FortifySource;
+ };
B122F2D81432BA8700AF95D0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C9B53597138D9A690028D27C /* Project object */;
remoteGlobalIDString = B122F0E71432B8E600AF95D0;
remoteInfo = TRE;
};
- B1E96508157E749200FCCEE7 /* PBXContainerItemProxy */ = {
+ C925D2001518FA5D003D315B /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C95B7ED9138F3C55004311DA;
+ remoteInfo = Variant_DarwinExtsn;
+ };
+ C925D2021518FEBE003D315B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C9B53597138D9A690028D27C /* Project object */;
proxyType = 1;
- remoteGlobalIDString = B1E96340157E722200FCCEE7;
- remoteInfo = FreeBSD_gcc;
+ remoteGlobalIDString = C97A6F1E1517AF53005E1998;
+ remoteInfo = libc_eOS.a;
};
C942130813901709004BA536 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
remoteGlobalIDString = C95B842A138F53DB004311DA;
remoteInfo = Variant_Pre1050;
};
+ C9AE91BA1517D33100A2626C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C9C2A94C138DFFD900287F00;
+ remoteInfo = Base;
+ };
+ C9AE91BC1517D33100A2626C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C9257ECF138E1B5000B3107C;
+ remoteInfo = FreeBSD;
+ };
+ C9AE91BE1517D33100A2626C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = B122F0E71432B8E600AF95D0;
+ remoteInfo = TRE;
+ };
+ C9AE91C01517D33100A2626C /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = C9B53597138D9A690028D27C /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = C9D9435F138EC3E300FB7ACC;
+ remoteInfo = Variant_Cancelable;
+ };
C9BD3C38138F16EE00B389FD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = C9B53597138D9A690028D27C /* Project object */;
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
- 3F2208E714358B4A00386F5B /* asl_fd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = asl_fd.c; sourceTree = "<group>"; };
+ 2B350EC1158FDC7600A58CD2 /* base.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = base.h; path = os/base.h; sourceTree = "<group>"; };
+ 2B9D61B5157D667000AF25B8 /* trace.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = trace.c; path = os/trace.c; sourceTree = "<group>"; };
+ 2B9D61B6157D667000AF25B8 /* trace.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = trace.h; path = os/trace.h; sourceTree = "<group>"; };
+ 3F169A3C1643B7BA0029E851 /* memccpy_chk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memccpy_chk.c; sourceTree = "<group>"; };
+ 3F18DE1F162A732C008B15AC /* memset_s.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = memset_s.3; sourceTree = "<group>"; };
+ 3F18DE20162A732C008B15AC /* memset_s.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memset_s.c; sourceTree = "<group>"; };
+ 3F267F36163FC8880089A0A6 /* rb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rb.c; sourceTree = "<group>"; };
+ 3F267F37163FC8880089A0A6 /* rbtree.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rbtree.3; sourceTree = "<group>"; };
+ 3F267F39163FC8BD0089A0A6 /* rbtree.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rbtree.h; sourceTree = "<group>"; };
+ 3F5120F116C3174300AFB431 /* libFortifySource.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFortifySource.a; sourceTree = BUILT_PRODUCTS_DIR; };
3F89F3DC13E9194C00F6856C /* mkpath_np.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = mkpath_np.3; sourceTree = "<group>"; };
3F89F3DD13E9194C00F6856C /* mkpath_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mkpath_np.c; sourceTree = "<group>"; };
+ 3FA8F3081643AB4300D37078 /* strlcat_chk.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strlcat_chk.c; sourceTree = "<group>"; };
+ 3FA8F3091643AB4300D37078 /* strlcpy_chk.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strlcpy_chk.c; sourceTree = "<group>"; };
3FB7E1B4146EF2E000843438 /* dirfd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirfd.c; sourceTree = "<group>"; };
+ 3FD14572171D42B300B7BAF5 /* bcopy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bcopy.c; sourceTree = "<group>"; };
+ 4B2C64A215519BAF00342BFA /* assumes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = assumes.c; path = os/assumes.c; sourceTree = "<group>"; };
+ 4B2C64AB15519C3400342BFA /* assumes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = assumes.h; path = os/assumes.h; sourceTree = "<group>"; };
6310518613D4D966004F7BA8 /* strcpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strcpy.c; sourceTree = "<group>"; };
6310518B13D4DABD004F7BA8 /* strlcpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strlcpy.c; sourceTree = "<group>"; };
6310518E13D4DAEA004F7BA8 /* strncpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strncpy.c; sourceTree = "<group>"; };
- 634C4C3713BCEADC008CA66D /* memset_pattern_Swift.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = memset_pattern_Swift.s; sourceTree = "<group>"; };
- 6358199013B53DD800CDF61C /* bzero_Swift.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = bzero_Swift.s; sourceTree = "<group>"; };
- 6358199213B53ECB00CDF61C /* bcopy_Swift.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = bcopy_Swift.s; sourceTree = "<group>"; };
+ 63505E3A1548525D00B637D7 /* strnlen.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strnlen.s; sourceTree = "<group>"; };
+ 639D126615595DDE00D0403A /* strnlen.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = strnlen.s; sourceTree = "<group>"; };
63D4060513DDEDF10094DD56 /* stpcpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stpcpy.c; sourceTree = "<group>"; };
63D4060913DDEEA10094DD56 /* stpncpy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stpncpy.c; sourceTree = "<group>"; };
63D4060C13DDF26A0094DD56 /* strcat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = strcat.c; sourceTree = "<group>"; };
B122F2C31432B95B00AF95D0 /* tre-0.8.0.tar.bz2 */ = {isa = PBXFileReference; lastKnownFileType = file; path = "tre-0.8.0.tar.bz2"; sourceTree = "<group>"; };
B122F2C41432B95B00AF95D0 /* tre-config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "tre-config.h"; sourceTree = "<group>"; };
B122F2C51432B95B00AF95D0 /* tre-last-matched.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "tre-last-matched.h"; sourceTree = "<group>"; };
+ B12613EE158818EC0077E3CC /* xprintf_errno.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_errno.c; sourceTree = "<group>"; };
+ B12613EF158818EC0077E3CC /* xprintf_float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_float.c; sourceTree = "<group>"; };
+ B12613F0158818EC0077E3CC /* xprintf_hexdump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_hexdump.c; sourceTree = "<group>"; };
+ B12613F1158818EC0077E3CC /* xprintf_int.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_int.c; sourceTree = "<group>"; };
+ B12613F2158818EC0077E3CC /* xprintf_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xprintf_private.h; sourceTree = "<group>"; };
+ B12613F3158818EC0077E3CC /* xprintf_quote.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_quote.c; sourceTree = "<group>"; };
+ B12613F4158818EC0077E3CC /* xprintf_str.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_str.c; sourceTree = "<group>"; };
+ B12613F5158818EC0077E3CC /* xprintf_time.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_time.c; sourceTree = "<group>"; };
+ B12613F6158818EC0077E3CC /* xprintf_vis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_vis.c; sourceTree = "<group>"; };
+ B12613F7158818EC0077E3CC /* xprintf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf.c; sourceTree = "<group>"; };
+ B126140215881A000077E3CC /* xprintf_comp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_comp.c; sourceTree = "<group>"; };
+ B126140315881A000077E3CC /* xprintf_domain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_domain.c; sourceTree = "<group>"; };
+ B126140415881A000077E3CC /* xprintf_domain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xprintf_domain.h; sourceTree = "<group>"; };
+ B126140715881A420077E3CC /* printf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = printf.h; sourceTree = "<group>"; };
+ B1795371158B0E35008990E8 /* xprintf_all_in_one.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_all_in_one.c; sourceTree = "<group>"; };
+ B1795372158B0E35008990E8 /* xprintf_exec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xprintf_exec.c; sourceTree = "<group>"; };
B19C64591450F8B900032373 /* sync_volume_np.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sync_volume_np.3; sourceTree = "<group>"; };
B19C645B1450F90200032373 /* sync_volume_np.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sync_volume_np.c; sourceTree = "<group>"; };
- B1E96506157E722200FCCEE7 /* libFreeBSD_gcc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFreeBSD_gcc.a; sourceTree = BUILT_PRODUCTS_DIR; };
C9194B4C140E3BC700BE0C3A /* build_linklists.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = build_linklists.sh; sourceTree = "<group>"; };
+ C921D3831395B7DD001CE070 /* init_cpu_capabilities.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = init_cpu_capabilities.c; sourceTree = "<group>"; };
+ C921D3841395B7DD001CE070 /* pthread_getspecific.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = pthread_getspecific.s; sourceTree = "<group>"; };
+ C921D3851395B7DD001CE070 /* pthread_self.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = pthread_self.s; sourceTree = "<group>"; };
+ C921D3861395B7DD001CE070 /* pthread_set_self.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = pthread_set_self.s; sourceTree = "<group>"; };
+ C921D3871395B7DD001CE070 /* start_wqthread.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = start_wqthread.s; sourceTree = "<group>"; };
+ C921D3881395B7DD001CE070 /* thread_start.s */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = thread_start.s; sourceTree = "<group>"; };
C9257ED0138E1B5000B3107C /* libFreeBSD.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libFreeBSD.a; sourceTree = BUILT_PRODUCTS_DIR; };
C9258105138E2D3100B3107C /* libNetBSD.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libNetBSD.a; sourceTree = BUILT_PRODUCTS_DIR; };
+ C925D1FB151805C6003D315B /* eos_stubs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = eos_stubs.c; sourceTree = "<group>"; };
C9265D1113B1CF970090BA1C /* clean_simulator.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = clean_simulator.sh; sourceTree = "<group>"; };
- C932C2CF13AB1C73004EDA12 /* SpinlocksWFE.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SpinlocksWFE.c; sourceTree = "<group>"; };
C93D6150143D31E300EB9023 /* sanitise_headers.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = sanitise_headers.sh; sourceTree = "<group>"; };
C94212CC13900C8A004BA536 /* libc.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libc.a; sourceTree = BUILT_PRODUCTS_DIR; };
- C94212DD13900FC3004BA536 /* mig_headers.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = mig_headers.sh; sourceTree = "<group>"; };
C942135913904CBC004BA536 /* manpages.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = manpages.sh; sourceTree = "<group>"; };
C942135A13905D1C004BA536 /* manpages.lst */ = {isa = PBXFileReference; explicitFileType = text; path = manpages.lst; sourceTree = "<group>"; };
C95B7ED8138F3C11004311DA /* rune32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = rune32.h; sourceTree = "<group>"; };
C9766150138EC9D400741512 /* patch_headers_variants.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = patch_headers_variants.pl; sourceTree = "<group>"; };
C9766153138ECF0000741512 /* variants.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = variants.xcconfig; sourceTree = "<group>"; };
C976616B138EF14100741512 /* generate_features.pl */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = generate_features.pl; sourceTree = "<group>"; };
- C97C344013AB0E1B00713550 /* Spinlocks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Spinlocks.c; sourceTree = "<group>"; };
- C980F8EB13AB168D0069AB06 /* SpinlocksUP.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SpinlocksUP.c; sourceTree = "<group>"; };
+ C97A721C1517AF53005E1998 /* libc_eOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libc_eOS.a; sourceTree = BUILT_PRODUCTS_DIR; };
C9950E6A1390D2CA009863B6 /* headers.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = headers.sh; sourceTree = "<group>"; };
- C995462713AAA25000A531B4 /* OSAtomicUP.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = OSAtomicUP.c; sourceTree = "<group>"; };
- C9B4E3D513BBBF060008A9BB /* OSAtomicLoadStoreEx.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = OSAtomicLoadStoreEx.c; sourceTree = "<group>"; };
- C9B4E3D713BBBF2D0008A9BB /* OSAtomic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = OSAtomic.c; sourceTree = "<group>"; };
- C9B4E3D913BBC24E0008A9BB /* SpinlocksLoadStoreEx.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SpinlocksLoadStoreEx.c; sourceTree = "<group>"; };
+ C9AE91AE1517CDAC00A2626C /* eos.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = eos.xcconfig; sourceTree = "<group>"; };
C9B535AE138D9E980028D27C /* APPLE_LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = APPLE_LICENSE; sourceTree = "<group>"; };
- C9B535B1138D9E980028D27C /* cpu_number.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = cpu_number.s; sourceTree = "<group>"; };
- C9B535B2138D9E980028D27C /* icacheinval.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = icacheinval.s; sourceTree = "<group>"; };
C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = init_cpu_capabilities.c; sourceTree = "<group>"; };
- C9B535B8138D9E980028D27C /* pthread_getspecific.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_getspecific.s; sourceTree = "<group>"; };
- C9B535B9138D9E980028D27C /* pthread_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_self.s; sourceTree = "<group>"; };
- C9B535BA138D9E980028D27C /* pthread_set_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_set_self.s; sourceTree = "<group>"; };
- C9B535BB138D9E980028D27C /* start_wqthread.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = start_wqthread.s; sourceTree = "<group>"; };
- C9B535BC138D9E980028D27C /* thread_start.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = thread_start.s; sourceTree = "<group>"; };
- C9B535C0138D9E980028D27C /* bcopy_CortexA8.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_CortexA8.s; sourceTree = "<group>"; };
- C9B535C1138D9E980028D27C /* bcopy_CortexA9.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_CortexA9.s; sourceTree = "<group>"; };
- C9B535C2138D9E980028D27C /* bcopy_Generic.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_Generic.s; sourceTree = "<group>"; };
- C9B535C3138D9E980028D27C /* bzero_CortexA8.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_CortexA8.s; sourceTree = "<group>"; };
- C9B535C4138D9E980028D27C /* bzero_CortexA9.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_CortexA9.s; sourceTree = "<group>"; };
- C9B535C5138D9E980028D27C /* bzero_Generic.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_Generic.s; sourceTree = "<group>"; };
- C9B535C6138D9E980028D27C /* dyld_resolvers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = dyld_resolvers.c; sourceTree = "<group>"; };
- C9B535C7138D9E980028D27C /* ffs.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = ffs.s; sourceTree = "<group>"; };
- C9B535C9138D9E980028D27C /* memcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memcmp.s; sourceTree = "<group>"; };
- C9B535CA138D9E980028D27C /* memset_pattern.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memset_pattern.s; sourceTree = "<group>"; };
- C9B535CB138D9E980028D27C /* strchr.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strchr.s; sourceTree = "<group>"; };
- C9B535CC138D9E980028D27C /* strcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcmp.s; sourceTree = "<group>"; };
C9B535CF138D9E980028D27C /* strlen.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlen.s; sourceTree = "<group>"; };
- C9B535D0138D9E980028D27C /* strncmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncmp.s; sourceTree = "<group>"; };
C9B535D2138D9E980028D27C /* strnlen.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strnlen.s; sourceTree = "<group>"; };
C9B535D3138D9E980028D27C /* strstr.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strstr.s; sourceTree = "<group>"; };
- C9B535D5138D9E980028D27C /* _longjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _longjmp.s; sourceTree = "<group>"; };
- C9B535D6138D9E980028D27C /* _setjmp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _setjmp.h; sourceTree = "<group>"; };
- C9B535D7138D9E980028D27C /* _setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setjmp.s; sourceTree = "<group>"; };
- C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = arm_commpage_gettimeofday.c; sourceTree = "<group>"; };
- C9B535D9138D9E980028D27C /* gcc_atomic.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gcc_atomic.c; sourceTree = "<group>"; };
- C9B535DA138D9E980028D27C /* longjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = longjmp.s; sourceTree = "<group>"; };
- C9B535DB138D9E980028D27C /* mach_absolute_time.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = mach_absolute_time.s; sourceTree = "<group>"; };
- C9B535DD138D9E980028D27C /* OSAtomic-v4.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "OSAtomic-v4.c"; sourceTree = "<group>"; };
- C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = OSAtomic_resolvers.c; sourceTree = "<group>"; };
- C9B535E0138D9E980028D27C /* OSAtomic_resolvers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSAtomic_resolvers.h; sourceTree = "<group>"; };
- C9B535E1138D9E980028D27C /* setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = setjmp.s; sourceTree = "<group>"; };
C9B535F7138D9E980028D27C /* creat.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = creat.2; sourceTree = "<group>"; };
C9B535F8138D9E980028D27C /* creat.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = creat.c; sourceTree = "<group>"; };
C9B535FA138D9E980028D27C /* gethostid.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = gethostid.3; sourceTree = "<group>"; };
C9B53614138D9E980028D27C /* dirhelper.defs */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.mig; path = dirhelper.defs; sourceTree = "<group>"; };
C9B53615138D9E980028D27C /* dirhelper_priv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = dirhelper_priv.h; sourceTree = "<group>"; };
C9B53616138D9E980028D27C /* kvm.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = kvm.c; sourceTree = "<group>"; };
- C9B53617138D9E980028D27C /* libproc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = libproc.c; sourceTree = "<group>"; };
- C9B53618138D9E980028D27C /* libproc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libproc.h; sourceTree = "<group>"; };
- C9B53619138D9E980028D27C /* libproc_internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libproc_internal.h; sourceTree = "<group>"; };
- C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = MKGetTimeBaseInfo.c; sourceTree = "<group>"; };
- C9B5361C138D9E980028D27C /* proc_listpidspath.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = proc_listpidspath.c; sourceTree = "<group>"; };
C9B53620138D9E980028D27C /* bt_close.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bt_close.c; sourceTree = "<group>"; };
C9B53621138D9E980028D27C /* bt_conv.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bt_conv.c; sourceTree = "<group>"; };
C9B53622138D9E980028D27C /* bt_debug.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bt_debug.c; sourceTree = "<group>"; };
C9B536BD138D9E980028D27C /* gd_qnan.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = gd_qnan.h; sourceTree = "<group>"; };
C9B536BE138D9E980028D27C /* gdtoa.tgz */ = {isa = PBXFileReference; lastKnownFileType = file; path = gdtoa.tgz; sourceTree = "<group>"; };
C9B536C1138D9E990028D27C /* __dirent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = __dirent.h; sourceTree = "<group>"; };
- C9B536C2138D9E990028D27C /* _simple.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = _simple.c; sourceTree = "<group>"; };
- C9B536C3138D9E990028D27C /* _simple.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _simple.h; sourceTree = "<group>"; };
- C9B536C4138D9E990028D27C /* asl.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = asl.3; sourceTree = "<group>"; };
- C9B536C5138D9E990028D27C /* asl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl.c; sourceTree = "<group>"; };
- C9B536C6138D9E990028D27C /* asl_core.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_core.c; sourceTree = "<group>"; };
- C9B536C7138D9E990028D27C /* asl_core.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_core.h; sourceTree = "<group>"; };
- C9B536C8138D9E990028D27C /* asl_file.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_file.c; sourceTree = "<group>"; };
- C9B536C9138D9E990028D27C /* asl_file.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_file.h; sourceTree = "<group>"; };
- C9B536CA138D9E990028D27C /* asl_ipc.defs */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.mig; path = asl_ipc.defs; sourceTree = "<group>"; };
- C9B536CB138D9E990028D27C /* asl_legacy1.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_legacy1.c; sourceTree = "<group>"; };
- C9B536CC138D9E990028D27C /* asl_legacy1.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_legacy1.h; sourceTree = "<group>"; };
- C9B536CD138D9E990028D27C /* asl_msg.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_msg.c; sourceTree = "<group>"; };
- C9B536CE138D9E990028D27C /* asl_msg.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_msg.h; sourceTree = "<group>"; };
- C9B536CF138D9E990028D27C /* asl_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_private.h; sourceTree = "<group>"; };
- C9B536D0138D9E990028D27C /* asl_store.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_store.c; sourceTree = "<group>"; };
- C9B536D1138D9E990028D27C /* asl_store.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl_store.h; sourceTree = "<group>"; };
- C9B536D2138D9E990028D27C /* asl_util.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = asl_util.c; sourceTree = "<group>"; };
- C9B536D3138D9E990028D27C /* assumes.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = assumes.c; sourceTree = "<group>"; };
C9B536D4138D9E990028D27C /* assumes.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = assumes.h; sourceTree = "<group>"; };
C9B536D5138D9E990028D27C /* authentication.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = authentication.c; sourceTree = "<group>"; };
C9B536D6138D9E990028D27C /* backtrace.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = backtrace.3; sourceTree = "<group>"; };
C9B536D7138D9E990028D27C /* backtrace.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = backtrace.c; sourceTree = "<group>"; };
- C9B536D8138D9E990028D27C /* cache.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cache.c; sourceTree = "<group>"; };
C9B536D9138D9E990028D27C /* compat.5 */ = {isa = PBXFileReference; lastKnownFileType = text; path = compat.5; sourceTree = "<group>"; };
C9B536DA138D9E990028D27C /* confstr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = confstr.3; sourceTree = "<group>"; };
C9B536DB138D9E990028D27C /* confstr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = confstr.c; sourceTree = "<group>"; };
C9B5371C138D9E990028D27C /* getbsize.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getbsize.c; sourceTree = "<group>"; };
C9B5371D138D9E990028D27C /* getcap.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getcap.3; sourceTree = "<group>"; };
C9B5371E138D9E990028D27C /* getcap.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getcap.c; sourceTree = "<group>"; };
- C9B53720138D9E990028D27C /* getcontext.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getcontext.3; sourceTree = "<group>"; };
C9B53721138D9E990028D27C /* getcwd.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getcwd.3; sourceTree = "<group>"; };
C9B53722138D9E990028D27C /* getcwd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getcwd.c; sourceTree = "<group>"; };
C9B53724138D9E990028D27C /* gethostname.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = gethostname.3; sourceTree = "<group>"; };
C9B53741138D9E990028D27C /* lockf.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = lockf.3; sourceTree = "<group>"; };
C9B53743138D9E990028D27C /* lockf.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lockf.c; sourceTree = "<group>"; };
C9B53745138D9E990028D27C /* lrand48.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = lrand48.c; sourceTree = "<group>"; };
- C9B53747138D9E990028D27C /* makecontext.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = makecontext.3; sourceTree = "<group>"; };
C9B53749138D9E990028D27C /* mrand48.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mrand48.c; sourceTree = "<group>"; };
C9B5374B138D9E990028D27C /* nice.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = nice.3; sourceTree = "<group>"; };
C9B5374C138D9E990028D27C /* nice.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = nice.c; sourceTree = "<group>"; };
C9B537A9138D9E990028D27C /* ttyslot.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ttyslot.c; sourceTree = "<group>"; };
C9B537AA138D9E990028D27C /* ualarm.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = ualarm.3; sourceTree = "<group>"; };
C9B537AC138D9E990028D27C /* ualarm.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ualarm.c; sourceTree = "<group>"; };
- C9B537AD138D9E990028D27C /* ucontext.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = ucontext.3; sourceTree = "<group>"; };
C9B537AE138D9E990028D27C /* ulimit.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = ulimit.3; sourceTree = "<group>"; };
C9B537B0138D9E990028D27C /* ulimit.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ulimit.c; sourceTree = "<group>"; };
C9B537B1138D9E990028D27C /* unvis.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = unvis.3; sourceTree = "<group>"; };
C9B537CF138D9E990028D27C /* getvfsbyname.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getvfsbyname.3; sourceTree = "<group>"; };
C9B537D0138D9E990028D27C /* getvfsbyname.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getvfsbyname.c; sourceTree = "<group>"; };
C9B537D1138D9E990028D27C /* intro.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = intro.3; sourceTree = "<group>"; };
- C9B537D2138D9E990028D27C /* isinf.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = isinf.c; sourceTree = "<group>"; };
- C9B537D3138D9E990028D27C /* isnan.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = isnan.c; sourceTree = "<group>"; };
- C9B537D4138D9E990028D27C /* magazine_malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = magazine_malloc.c; sourceTree = "<group>"; };
- C9B537D5138D9E990028D27C /* magmallocProvider.d */ = {isa = PBXFileReference; explicitFileType = sourcecode.dtrace; path = magmallocProvider.d; sourceTree = "<group>"; };
- C9B537D7138D9E990028D27C /* malloc.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = malloc.3; sourceTree = "<group>"; };
- C9B537D8138D9E990028D27C /* malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = malloc.c; sourceTree = "<group>"; };
- C9B537D9138D9E990028D27C /* malloc_printf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = malloc_printf.h; sourceTree = "<group>"; };
- C9B537DA138D9E990028D27C /* malloc_size.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = malloc_size.3; sourceTree = "<group>"; };
- C9B537DB138D9E990028D27C /* malloc_zone_malloc.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = malloc_zone_malloc.3; sourceTree = "<group>"; };
C9B537DC138D9E990028D27C /* nanosleep.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = nanosleep.c; sourceTree = "<group>"; };
C9B537DE138D9E990028D27C /* endutxent.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = endutxent.3; sourceTree = "<group>"; };
C9B537E0138D9E990028D27C /* getlastlogx.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getlastlogx.3; sourceTree = "<group>"; };
C9B537E8138D9E990028D27C /* nlist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = nlist.c; sourceTree = "<group>"; };
C9B537E9138D9E990028D27C /* NSSystemDirectories.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = NSSystemDirectories.c; sourceTree = "<group>"; };
C9B537EA138D9E990028D27C /* oldsyslog.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = oldsyslog.c; sourceTree = "<group>"; };
- C9B537EB138D9E990028D27C /* platfunc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = platfunc.c; sourceTree = "<group>"; };
- C9B537EC138D9E990028D27C /* platfunc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = platfunc.h; sourceTree = "<group>"; };
C9B537ED138D9E990028D27C /* posix_memalign.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = posix_memalign.3; sourceTree = "<group>"; };
C9B537EE138D9E990028D27C /* pwcache.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pwcache.3; sourceTree = "<group>"; };
- C9B537EF138D9E990028D27C /* scalable_malloc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = scalable_malloc.c; sourceTree = "<group>"; };
- C9B537F0138D9E990028D27C /* scalable_malloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = scalable_malloc.h; sourceTree = "<group>"; };
- C9B537F1138D9E990028D27C /* setjmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = setjmp.3; sourceTree = "<group>"; };
C9B537F2138D9E990028D27C /* setlogin.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = setlogin.c; sourceTree = "<group>"; };
C9B537F3138D9E990028D27C /* sigsetops.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sigsetops.3; sourceTree = "<group>"; };
C9B537F4138D9E990028D27C /* sigsetops.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sigsetops.c; sourceTree = "<group>"; };
- C9B537F5138D9E990028D27C /* stack_logging.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stack_logging.c; sourceTree = "<group>"; };
- C9B537F6138D9E990028D27C /* stack_logging.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stack_logging.h; sourceTree = "<group>"; };
- C9B537F7138D9E990028D27C /* stack_logging_disk.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stack_logging_disk.c; sourceTree = "<group>"; };
C9B537F8138D9E990028D27C /* strtofflags.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strtofflags.3; sourceTree = "<group>"; };
C9B537F9138D9E990028D27C /* strtofflags.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strtofflags.c; sourceTree = "<group>"; };
- C9B537FA138D9E990028D27C /* syslog.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = syslog.3; sourceTree = "<group>"; };
- C9B537FB138D9E990028D27C /* syslog.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = syslog.c; sourceTree = "<group>"; };
C9B537FC138D9E990028D27C /* tcgetpgrp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = tcgetpgrp.3; sourceTree = "<group>"; };
C9B537FD138D9E990028D27C /* tcsendbreak.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = tcsendbreak.3; sourceTree = "<group>"; };
C9B537FE138D9E990028D27C /* tcsetattr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = tcsetattr.3; sourceTree = "<group>"; };
C9B53808138D9E990028D27C /* wordexp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = wordexp.c; sourceTree = "<group>"; };
C9B5380B138D9E990028D27C /* gmon.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gmon.c; sourceTree = "<group>"; };
C9B5380D138D9E990028D27C /* moncontrol.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = moncontrol.3; sourceTree = "<group>"; };
- C9B53811138D9E990028D27C /* _ctx_start.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _ctx_start.S; sourceTree = "<group>"; };
- C9B53812138D9E990028D27C /* _setcontext.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setcontext.S; sourceTree = "<group>"; };
- C9B53813138D9E990028D27C /* cpu_number.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = cpu_number.s; sourceTree = "<group>"; };
- C9B53814138D9E990028D27C /* getcontext.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = getcontext.S; sourceTree = "<group>"; };
- C9B53815138D9E990028D27C /* getmcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getmcontext.c; sourceTree = "<group>"; };
- C9B53816138D9E990028D27C /* icacheinval.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = icacheinval.s; sourceTree = "<group>"; };
- C9B53817138D9E990028D27C /* makecontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = makecontext.c; sourceTree = "<group>"; };
C9B53819138D9E990028D27C /* mcount.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = mcount.s; sourceTree = "<group>"; };
- C9B5381A138D9E990028D27C /* setcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = setcontext.c; sourceTree = "<group>"; };
- C9B5381B138D9E990028D27C /* setjmperr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = setjmperr.c; sourceTree = "<group>"; };
- C9B5381C138D9E990028D27C /* swapcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = swapcontext.c; sourceTree = "<group>"; };
- C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = init_cpu_capabilities.c; sourceTree = "<group>"; };
- C9B53820138D9E990028D27C /* preempt.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = preempt.s; sourceTree = "<group>"; };
- C9B53821138D9E990028D27C /* pthread_getspecific.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_getspecific.s; sourceTree = "<group>"; };
- C9B53822138D9E990028D27C /* pthread_mutex_lock.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_mutex_lock.s; sourceTree = "<group>"; };
- C9B53823138D9E990028D27C /* pthread_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_self.s; sourceTree = "<group>"; };
- C9B53824138D9E990028D27C /* pthread_set_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_set_self.s; sourceTree = "<group>"; };
- C9B53825138D9E990028D27C /* start_wqthread.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = start_wqthread.s; sourceTree = "<group>"; };
- C9B53826138D9E990028D27C /* thread_start.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = thread_start.s; sourceTree = "<group>"; };
- C9B5382A138D9E990028D27C /* __bzero.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = __bzero.s; sourceTree = "<group>"; };
- C9B5382B138D9E990028D27C /* bcopy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bcopy.c; sourceTree = "<group>"; };
- C9B5382C138D9E990028D27C /* bcopy_scalar.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_scalar.s; sourceTree = "<group>"; };
- C9B5382D138D9E990028D27C /* bcopy_sse2.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse2.s; sourceTree = "<group>"; };
- C9B5382E138D9E990028D27C /* bcopy_sse3x.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse3x.s; sourceTree = "<group>"; };
- C9B5382F138D9E990028D27C /* bcopy_sse42.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse42.s; sourceTree = "<group>"; };
- C9B53830138D9E990028D27C /* bzero.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bzero.c; sourceTree = "<group>"; };
- C9B53831138D9E990028D27C /* bzero_scalar.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_scalar.s; sourceTree = "<group>"; };
- C9B53832138D9E990028D27C /* bzero_sse2.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_sse2.s; sourceTree = "<group>"; };
- C9B53833138D9E990028D27C /* bzero_sse42.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_sse42.s; sourceTree = "<group>"; };
- C9B53834138D9E990028D27C /* ffs.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = ffs.s; sourceTree = "<group>"; };
- C9B53835138D9E990028D27C /* longcopy_sse3x.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = longcopy_sse3x.s; sourceTree = "<group>"; };
- C9B53837138D9E990028D27C /* memcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memcmp.s; sourceTree = "<group>"; };
- C9B53838138D9E990028D27C /* memcpy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memcpy.c; sourceTree = "<group>"; };
- C9B53839138D9E990028D27C /* memmove.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memmove.c; sourceTree = "<group>"; };
- C9B5383A138D9E990028D27C /* memset.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memset.s; sourceTree = "<group>"; };
- C9B5383B138D9E990028D27C /* memset_pattern_sse2.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memset_pattern_sse2.s; sourceTree = "<group>"; };
- C9B5383C138D9E990028D27C /* strcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcmp.s; sourceTree = "<group>"; };
C9B5383D138D9E990028D27C /* strcpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcpy.s; sourceTree = "<group>"; };
C9B5383E138D9E990028D27C /* strlcat.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlcat.s; sourceTree = "<group>"; };
C9B5383F138D9E990028D27C /* strlcpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlcpy.s; sourceTree = "<group>"; };
C9B53840138D9E990028D27C /* strlen.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlen.s; sourceTree = "<group>"; };
- C9B53841138D9E990028D27C /* strncmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncmp.s; sourceTree = "<group>"; };
C9B53842138D9E990028D27C /* strncpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncpy.s; sourceTree = "<group>"; };
- C9B53844138D9E990028D27C /* _setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setjmp.s; sourceTree = "<group>"; };
- C9B53845138D9E990028D27C /* _sigtramp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _sigtramp.s; sourceTree = "<group>"; };
- C9B53846138D9E990028D27C /* atomic.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = atomic.c; sourceTree = "<group>"; };
- C9B53847138D9E990028D27C /* i386_gettimeofday_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = i386_gettimeofday_asm.s; sourceTree = "<group>"; };
- C9B53849138D9E990028D27C /* mach_absolute_time_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = mach_absolute_time_asm.s; sourceTree = "<group>"; };
- C9B5384B138D9E990028D27C /* OSAtomic.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = OSAtomic.s; sourceTree = "<group>"; };
- C9B5384C138D9E990028D27C /* setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = setjmp.s; sourceTree = "<group>"; };
- C9B5384D138D9E990028D27C /* spinlocks.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = spinlocks.c; sourceTree = "<group>"; };
- C9B5384E138D9E990028D27C /* spinlocks_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = spinlocks_asm.s; sourceTree = "<group>"; };
C9B53850138D9E990028D27C /* _locale.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _locale.h; sourceTree = "<group>"; };
C9B53851138D9E990028D27C /* _structs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _structs.h; sourceTree = "<group>"; };
C9B53852138D9E990028D27C /* _types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _types.h; sourceTree = "<group>"; };
C9B5385B138D9E990028D27C /* nameser_compat.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = nameser_compat.h; sourceTree = "<group>"; };
C9B5385C138D9E990028D27C /* telnet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = telnet.h; sourceTree = "<group>"; };
C9B5385D138D9E990028D27C /* tftp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tftp.h; sourceTree = "<group>"; };
- C9B5385E138D9E990028D27C /* asl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asl.h; sourceTree = "<group>"; };
C9B5385F138D9E990028D27C /* asm.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = asm.h; sourceTree = "<group>"; };
C9B53860138D9E990028D27C /* assert.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = assert.h; sourceTree = "<group>"; };
C9B53861138D9E990028D27C /* authentication.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = authentication.h; sourceTree = "<group>"; };
C9B5387C138D9E990028D27C /* langinfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = langinfo.h; sourceTree = "<group>"; };
C9B5387D138D9E990028D27C /* libc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libc.h; sourceTree = "<group>"; };
C9B5387E138D9E990028D27C /* libgen.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = libgen.h; sourceTree = "<group>"; };
- C9B53881138D9E990028D27C /* OSAtomic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSAtomic.h; sourceTree = "<group>"; };
- C9B53882138D9E990028D27C /* OSCacheControl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSCacheControl.h; sourceTree = "<group>"; };
C9B53883138D9E990028D27C /* OSMemoryNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSMemoryNotification.h; sourceTree = "<group>"; };
C9B53884138D9E990028D27C /* OSThermalNotification.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSThermalNotification.h; sourceTree = "<group>"; };
C9B53885138D9E990028D27C /* limits.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = limits.h; sourceTree = "<group>"; };
C9B53886138D9E990028D27C /* locale.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = locale.h; sourceTree = "<group>"; };
- C9B5388A138D9E990028D27C /* malloc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = malloc.h; sourceTree = "<group>"; };
C9B5388B138D9E990028D27C /* memory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = "<group>"; };
C9B5388C138D9E990028D27C /* monetary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = monetary.h; sourceTree = "<group>"; };
C9B5388D138D9E990028D27C /* monitor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = monitor.h; sourceTree = "<group>"; };
C9B538AA138D9E990028D27C /* _stdio.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _stdio.h; sourceTree = "<group>"; };
C9B538AB138D9E990028D27C /* _string.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _string.h; sourceTree = "<group>"; };
C9B538AD138D9E990028D27C /* semaphore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = semaphore.h; sourceTree = "<group>"; };
- C9B538AE138D9E990028D27C /* setjmp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = setjmp.h; sourceTree = "<group>"; };
C9B538AF138D9E990028D27C /* sgtty.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sgtty.h; sourceTree = "<group>"; };
C9B538B0138D9E990028D27C /* signal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = signal.h; sourceTree = "<group>"; };
- C9B538B1138D9E990028D27C /* spawn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = spawn.h; sourceTree = "<group>"; };
- C9B538B2138D9E990028D27C /* spawn_private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = spawn_private.h; sourceTree = "<group>"; };
C9B538B3138D9E990028D27C /* stab.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stab.h; sourceTree = "<group>"; };
C9B538B4138D9E990028D27C /* standards.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = standards.h; sourceTree = "<group>"; };
C9B538B5138D9E990028D27C /* stdbool.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = stdbool.h; sourceTree = "<group>"; };
C9B538C9138D9E990028D27C /* time.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = time.h; sourceTree = "<group>"; };
C9B538CA138D9E990028D27C /* timeconv.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = timeconv.h; sourceTree = "<group>"; };
C9B538CB138D9E990028D27C /* ttyent.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ttyent.h; sourceTree = "<group>"; };
- C9B538CC138D9E990028D27C /* ucontext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ucontext.h; sourceTree = "<group>"; };
C9B538CD138D9E990028D27C /* ulimit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ulimit.h; sourceTree = "<group>"; };
C9B538CE138D9E990028D27C /* unistd.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unistd.h; sourceTree = "<group>"; };
C9B538CF138D9E990028D27C /* util.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = "<group>"; };
C9B53A6F138D9E990028D27C /* acl_translate.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = acl_translate.c; sourceTree = "<group>"; };
C9B53A70138D9E990028D27C /* acl_valid.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = acl_valid.3; sourceTree = "<group>"; };
C9B53A71138D9E990028D27C /* aclvar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = aclvar.h; sourceTree = "<group>"; };
- C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mk_pthread_impl.c; sourceTree = "<group>"; };
- C9B53ABD138D9E990028D27C /* plockstat.d */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.dtrace; path = plockstat.d; sourceTree = "<group>"; };
- C9B53ABE138D9E990028D27C /* posix_sched.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = posix_sched.h; sourceTree = "<group>"; };
- C9B53ABF138D9E990028D27C /* pthread.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread.3; sourceTree = "<group>"; };
- C9B53AC0138D9E990028D27C /* pthread.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread.c; sourceTree = "<group>"; };
- C9B53AC1138D9E990028D27C /* pthread.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread.h; sourceTree = "<group>"; };
- C9B53AC2138D9E990028D27C /* pthread_atfork.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_atfork.3; sourceTree = "<group>"; };
- C9B53AC3138D9E990028D27C /* pthread_attr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr.3; sourceTree = "<group>"; };
- C9B53AC4138D9E990028D27C /* pthread_attr_init_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_init_destroy.3; sourceTree = "<group>"; };
- C9B53AC5138D9E990028D27C /* pthread_attr_set_getdetachstate.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getdetachstate.3; sourceTree = "<group>"; };
- C9B53AC6138D9E990028D27C /* pthread_attr_set_getinheritsched.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getinheritsched.3; sourceTree = "<group>"; };
- C9B53AC7138D9E990028D27C /* pthread_attr_set_getschedparam.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getschedparam.3; sourceTree = "<group>"; };
- C9B53AC8138D9E990028D27C /* pthread_attr_set_getschedpolicy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getschedpolicy.3; sourceTree = "<group>"; };
- C9B53AC9138D9E990028D27C /* pthread_attr_set_getscope.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getscope.3; sourceTree = "<group>"; };
- C9B53ACA138D9E990028D27C /* pthread_attr_set_getstackaddr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getstackaddr.3; sourceTree = "<group>"; };
- C9B53ACB138D9E990028D27C /* pthread_attr_set_getstacksize.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_attr_set_getstacksize.3; sourceTree = "<group>"; };
- C9B53ACC138D9E990028D27C /* pthread_cancel.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cancel.3; sourceTree = "<group>"; };
- C9B53ACD138D9E990028D27C /* pthread_cancelable.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_cancelable.c; sourceTree = "<group>"; };
- C9B53ACE138D9E990028D27C /* pthread_cleanup_pop.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cleanup_pop.3; sourceTree = "<group>"; };
- C9B53ACF138D9E990028D27C /* pthread_cleanup_push.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cleanup_push.3; sourceTree = "<group>"; };
- C9B53AD0138D9E990028D27C /* pthread_cond.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_cond.c; sourceTree = "<group>"; };
- C9B53AD1138D9E990028D27C /* pthread_cond_broadcast.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_broadcast.3; sourceTree = "<group>"; };
- C9B53AD2138D9E990028D27C /* pthread_cond_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_destroy.3; sourceTree = "<group>"; };
- C9B53AD3138D9E990028D27C /* pthread_cond_init.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_init.3; sourceTree = "<group>"; };
- C9B53AD4138D9E990028D27C /* pthread_cond_signal.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_signal.3; sourceTree = "<group>"; };
- C9B53AD5138D9E990028D27C /* pthread_cond_timedwait.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_timedwait.3; sourceTree = "<group>"; };
- C9B53AD6138D9E990028D27C /* pthread_cond_wait.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_cond_wait.3; sourceTree = "<group>"; };
- C9B53AD7138D9E990028D27C /* pthread_condattr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_condattr.3; sourceTree = "<group>"; };
- C9B53AD8138D9E990028D27C /* pthread_create.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_create.3; sourceTree = "<group>"; };
- C9B53AD9138D9E990028D27C /* pthread_detach.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_detach.3; sourceTree = "<group>"; };
- C9B53ADA138D9E990028D27C /* pthread_equal.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_equal.3; sourceTree = "<group>"; };
- C9B53ADB138D9E990028D27C /* pthread_exit.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_exit.3; sourceTree = "<group>"; };
- C9B53ADC138D9E990028D27C /* pthread_getschedparam.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_getschedparam.3; sourceTree = "<group>"; };
- C9B53ADD138D9E990028D27C /* pthread_getspecific.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_getspecific.3; sourceTree = "<group>"; };
- C9B53ADE138D9E990028D27C /* pthread_impl.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_impl.h; sourceTree = "<group>"; };
- C9B53ADF138D9E990028D27C /* pthread_internals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_internals.h; sourceTree = "<group>"; };
- C9B53AE0138D9E990028D27C /* pthread_join.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_join.3; sourceTree = "<group>"; };
- C9B53AE1138D9E990028D27C /* pthread_key_create.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_key_create.3; sourceTree = "<group>"; };
- C9B53AE2138D9E990028D27C /* pthread_key_delete.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_key_delete.3; sourceTree = "<group>"; };
- C9B53AE3138D9E990028D27C /* pthread_machdep.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_machdep.h; sourceTree = "<group>"; };
- C9B53AE4138D9E990028D27C /* pthread_mutex.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_mutex.c; sourceTree = "<group>"; };
- C9B53AE5138D9E990028D27C /* pthread_mutex_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_destroy.3; sourceTree = "<group>"; };
- C9B53AE6138D9E990028D27C /* pthread_mutex_init.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_init.3; sourceTree = "<group>"; };
- C9B53AE7138D9E990028D27C /* pthread_mutex_lock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_lock.3; sourceTree = "<group>"; };
- C9B53AE8138D9E990028D27C /* pthread_mutex_trylock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_trylock.3; sourceTree = "<group>"; };
- C9B53AE9138D9E990028D27C /* pthread_mutex_unlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutex_unlock.3; sourceTree = "<group>"; };
- C9B53AEA138D9E990028D27C /* pthread_mutexattr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_mutexattr.3; sourceTree = "<group>"; };
- C9B53AEB138D9E990028D27C /* pthread_once.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_once.3; sourceTree = "<group>"; };
- C9B53AEC138D9E990028D27C /* pthread_rwlock.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_rwlock.c; sourceTree = "<group>"; };
- C9B53AED138D9E990028D27C /* pthread_rwlock_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_destroy.3; sourceTree = "<group>"; };
- C9B53AEE138D9E990028D27C /* pthread_rwlock_init.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_init.3; sourceTree = "<group>"; };
- C9B53AEF138D9E990028D27C /* pthread_rwlock_rdlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_rdlock.3; sourceTree = "<group>"; };
- C9B53AF0138D9E990028D27C /* pthread_rwlock_unlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_unlock.3; sourceTree = "<group>"; };
- C9B53AF1138D9E990028D27C /* pthread_rwlock_wrlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlock_wrlock.3; sourceTree = "<group>"; };
- C9B53AF2138D9E990028D27C /* pthread_rwlockattr_destroy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlockattr_destroy.3; sourceTree = "<group>"; };
- C9B53AF3138D9E990028D27C /* pthread_rwlockattr_getpshared.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlockattr_getpshared.3; sourceTree = "<group>"; };
- C9B53AF4138D9E990028D27C /* pthread_rwlockattr_init.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlockattr_init.3; sourceTree = "<group>"; };
- C9B53AF5138D9E990028D27C /* pthread_rwlockattr_setpshared.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_rwlockattr_setpshared.3; sourceTree = "<group>"; };
- C9B53AF6138D9E990028D27C /* pthread_self.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_self.3; sourceTree = "<group>"; };
- C9B53AF7138D9E990028D27C /* pthread_setcancelstate.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_setcancelstate.3; sourceTree = "<group>"; };
- C9B53AF8138D9E990028D27C /* pthread_setspecific.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_setspecific.3; sourceTree = "<group>"; };
- C9B53AF9138D9E990028D27C /* pthread_spinlock.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_spinlock.h; sourceTree = "<group>"; };
- C9B53AFA138D9E990028D27C /* pthread_spis.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_spis.h; sourceTree = "<group>"; };
- C9B53AFB138D9E990028D27C /* pthread_tsd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_tsd.c; sourceTree = "<group>"; };
- C9B53AFC138D9E990028D27C /* pthread_workqueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pthread_workqueue.h; sourceTree = "<group>"; };
- C9B53AFD138D9E990028D27C /* sched.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sched.h; sourceTree = "<group>"; };
- C9B53AFE138D9E990028D27C /* stack.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = stack.s; sourceTree = "<group>"; };
- C9B53B00138D9E990028D27C /* Makefile */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
- C9B53B01138D9E990028D27C /* pthread_atfork_test.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = pthread_atfork_test.c; sourceTree = "<group>"; };
- C9B53B02138D9E990028D27C /* thread_setup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = thread_setup.c; sourceTree = "<group>"; };
C9B53B06138D9E990028D27C /* cname.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cname.h; sourceTree = "<group>"; };
C9B53B08138D9E990028D27C /* COPYRIGHT */ = {isa = PBXFileReference; lastKnownFileType = text; path = COPYRIGHT; sourceTree = "<group>"; };
C9B53B0B138D9E990028D27C /* re_format.7 */ = {isa = PBXFileReference; lastKnownFileType = text; path = re_format.7; sourceTree = "<group>"; };
C9B53CE2138D9E9A0028D27C /* timegm.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = timegm.3; sourceTree = "<group>"; };
C9B53CE3138D9E9A0028D27C /* timezone_unix03.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = timezone_unix03.c; sourceTree = "<group>"; };
C9B53CE6138D9E9A0028D27C /* bcmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = bcmp.3; sourceTree = "<group>"; };
- C9B53CE8138D9E9A0028D27C /* bcmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bcmp.c; sourceTree = "<group>"; };
C9B53CE9138D9E9A0028D27C /* bcopy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = bcopy.3; sourceTree = "<group>"; };
- C9B53CEB138D9E9A0028D27C /* bcopy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bcopy.c; sourceTree = "<group>"; };
C9B53CED138D9E9A0028D27C /* bstring.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = bstring.3; sourceTree = "<group>"; };
C9B53CEF138D9E9A0028D27C /* bzero.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = bzero.3; sourceTree = "<group>"; };
- C9B53CF1138D9E9A0028D27C /* bzero.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bzero.c; sourceTree = "<group>"; };
- C9B53CF3138D9E9A0028D27C /* ffs.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = ffs.3; sourceTree = "<group>"; };
C9B53CF5138D9E9A0028D27C /* index.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = index.3; sourceTree = "<group>"; };
C9B53CF7138D9E9A0028D27C /* index.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = index.c; sourceTree = "<group>"; };
C9B53CF8138D9E9A0028D27C /* memccpy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memccpy.3; sourceTree = "<group>"; };
- C9B53CFA138D9E9A0028D27C /* memccpy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memccpy.c; sourceTree = "<group>"; };
C9B53CFB138D9E9A0028D27C /* memchr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memchr.3; sourceTree = "<group>"; };
- C9B53CFD138D9E9A0028D27C /* memchr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memchr.c; sourceTree = "<group>"; };
C9B53CFE138D9E9A0028D27C /* memcmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memcmp.3; sourceTree = "<group>"; };
- C9B53D00138D9E9A0028D27C /* memcmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memcmp.c; sourceTree = "<group>"; };
C9B53D01138D9E9A0028D27C /* memcpy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memcpy.3; sourceTree = "<group>"; };
- C9B53D03138D9E9A0028D27C /* memcpy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memcpy.c; sourceTree = "<group>"; };
C9B53D05138D9E9A0028D27C /* memmem.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memmem.3; sourceTree = "<group>"; };
C9B53D06138D9E9A0028D27C /* memmem.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memmem.c; sourceTree = "<group>"; };
C9B53D07138D9E9A0028D27C /* memmove.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memmove.3; sourceTree = "<group>"; };
- C9B53D09138D9E9A0028D27C /* memmove.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memmove.c; sourceTree = "<group>"; };
C9B53D0B138D9E9A0028D27C /* memset.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = memset.3; sourceTree = "<group>"; };
- C9B53D0D138D9E9A0028D27C /* memset.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memset.c; sourceTree = "<group>"; };
C9B53D0E138D9E9A0028D27C /* rindex.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = rindex.3; sourceTree = "<group>"; };
C9B53D10138D9E9A0028D27C /* rindex.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rindex.c; sourceTree = "<group>"; };
C9B53D13138D9E9A0028D27C /* strcasecmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcasecmp.3; sourceTree = "<group>"; };
C9B53D17138D9E9A0028D27C /* strcasestr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strcasestr.c; sourceTree = "<group>"; };
C9B53D19138D9E9A0028D27C /* strcat.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcat.3; sourceTree = "<group>"; };
C9B53D1C138D9E9A0028D27C /* strchr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strchr.3; sourceTree = "<group>"; };
- C9B53D1E138D9E9A0028D27C /* strchr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strchr.c; sourceTree = "<group>"; };
C9B53D20138D9E9A0028D27C /* strcmp.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcmp.3; sourceTree = "<group>"; };
- C9B53D22138D9E9A0028D27C /* strcmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strcmp.c; sourceTree = "<group>"; };
C9B53D24138D9E9A0028D27C /* strcoll.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcoll.3; sourceTree = "<group>"; };
C9B53D26138D9E9A0028D27C /* strcoll.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strcoll.c; sourceTree = "<group>"; };
C9B53D28138D9E9A0028D27C /* strcpy.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strcpy.3; sourceTree = "<group>"; };
C9B53D3C138D9E9A0028D27C /* strlen.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strlen.c; sourceTree = "<group>"; };
C9B53D3E138D9E9A0028D27C /* strmode.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strmode.3; sourceTree = "<group>"; };
C9B53D40138D9E9A0028D27C /* strmode.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strmode.c; sourceTree = "<group>"; };
- C9B53D42138D9E9A0028D27C /* strncmp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strncmp.c; sourceTree = "<group>"; };
C9B53D44138D9E9A0028D27C /* strndup.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strndup.c; sourceTree = "<group>"; };
C9B53D45138D9E9A0028D27C /* strnlen.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strnlen.c; sourceTree = "<group>"; };
C9B53D46138D9E9A0028D27C /* strnstr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strnstr.c; sourceTree = "<group>"; };
C9B53D47138D9E9A0028D27C /* strpbrk.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strpbrk.3; sourceTree = "<group>"; };
C9B53D49138D9E9A0028D27C /* strpbrk.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strpbrk.c; sourceTree = "<group>"; };
- C9B53D4A138D9E9A0028D27C /* strrchr.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strrchr.3; sourceTree = "<group>"; };
C9B53D4C138D9E9A0028D27C /* strrchr.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strrchr.c; sourceTree = "<group>"; };
C9B53D4E138D9E9A0028D27C /* strsep.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = strsep.3; sourceTree = "<group>"; };
C9B53D4F138D9E9A0028D27C /* strsep.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = strsep.c; sourceTree = "<group>"; };
C9B53D92138D9E9A0028D27C /* strip-header.ed */ = {isa = PBXFileReference; lastKnownFileType = text; path = "strip-header.ed"; sourceTree = "<group>"; };
C9B53D94138D9E9A0028D27C /* __libc_init.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = __libc_init.c; sourceTree = "<group>"; };
C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = _libc_fork_child.c; sourceTree = "<group>"; };
- C9B53D96138D9E9A0028D27C /* atomic.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = atomic.3; sourceTree = "<group>"; };
- C9B53D97138D9E9A0028D27C /* barrier.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = barrier.3; sourceTree = "<group>"; };
- C9B53D98138D9E9A0028D27C /* cache.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = cache.3; sourceTree = "<group>"; };
C9B53D99138D9E9A0028D27C /* chmodx_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = chmodx_np.c; sourceTree = "<group>"; };
- C9B53D9A138D9E9A0028D27C /* CLIB-LIST */ = {isa = PBXFileReference; lastKnownFileType = text; path = "CLIB-LIST"; sourceTree = "<group>"; };
- C9B53D9B138D9E9A0028D27C /* context-stubs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "context-stubs.c"; sourceTree = "<group>"; };
C9B53D9C138D9E9A0028D27C /* crt_externs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = crt_externs.c; sourceTree = "<group>"; };
- C9B53D9D138D9E9A0028D27C /* errno.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = errno.c; sourceTree = "<group>"; };
C9B53D9E138D9E9A0028D27C /* fork.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fork.c; sourceTree = "<group>"; };
C9B53D9F138D9E9A0028D27C /* getgroups.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getgroups.c; sourceTree = "<group>"; };
- C9B53DA0138D9E9A0028D27C /* getiopolicy_np.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = getiopolicy_np.3; sourceTree = "<group>"; };
- C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getiopolicy_np.c; sourceTree = "<group>"; };
C9B53DA2138D9E9A0028D27C /* gettimeofday.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = gettimeofday.c; sourceTree = "<group>"; };
- C9B53DA4138D9E9A0028D27C /* MISSING-MANPAGE */ = {isa = PBXFileReference; lastKnownFileType = text; path = "MISSING-MANPAGE"; sourceTree = "<group>"; };
- C9B53DA5138D9E9A0028D27C /* MISSING_SYSCALLS */ = {isa = PBXFileReference; lastKnownFileType = text; path = MISSING_SYSCALLS; sourceTree = "<group>"; };
C9B53DA6138D9E9A0028D27C /* msgctl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = msgctl.c; sourceTree = "<group>"; };
C9B53DA7138D9E9A0028D27C /* nanosleep.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = nanosleep.2; sourceTree = "<group>"; };
C9B53DA9138D9E9A0028D27C /* stack_protector.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = stack_protector.c; sourceTree = "<group>"; };
C9B53DAC138D9E9A0028D27C /* OSMemoryNotification.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = OSMemoryNotification.c; sourceTree = "<group>"; };
C9B53DAD138D9E9A0028D27C /* OSThermalNotification.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = OSThermalNotification.c; sourceTree = "<group>"; };
C9B53DAE138D9E9A0028D27C /* posix_spawn.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = posix_spawn.c; sourceTree = "<group>"; };
- C9B53DAF138D9E9A0028D27C /* pthread_kill.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_kill.2; sourceTree = "<group>"; };
- C9B53DB0138D9E9A0028D27C /* pthread_sigmask.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = pthread_sigmask.2; sourceTree = "<group>"; };
- C9B53DB1138D9E9A0028D27C /* REQUIRED-MACROS */ = {isa = PBXFileReference; lastKnownFileType = text; path = "REQUIRED-MACROS"; sourceTree = "<group>"; };
C9B53DB2138D9E9A0028D27C /* semctl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = semctl.c; sourceTree = "<group>"; };
C9B53DB3138D9E9A0028D27C /* settimeofday.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = settimeofday.c; sourceTree = "<group>"; };
C9B53DB4138D9E9A0028D27C /* shmctl.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = shmctl.c; sourceTree = "<group>"; };
C9B53DB5138D9E9A0028D27C /* sigaction.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sigaction.c; sourceTree = "<group>"; };
- C9B53DB6138D9E9A0028D27C /* sigcatch.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sigcatch.c; sourceTree = "<group>"; };
- C9B53DB7138D9E9A0028D27C /* sigcatch.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = sigcatch.h; sourceTree = "<group>"; };
- C9B53DB8138D9E9A0028D27C /* sigtramp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = sigtramp.c; sourceTree = "<group>"; };
C9B53DB9138D9E9A0028D27C /* sigwait.2 */ = {isa = PBXFileReference; lastKnownFileType = text; path = sigwait.2; sourceTree = "<group>"; };
- C9B53DBA138D9E9A0028D27C /* slot_name.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = slot_name.c; sourceTree = "<group>"; };
- C9B53DBB138D9E9A0028D27C /* spinlock.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = spinlock.3; sourceTree = "<group>"; };
C9B53DBC138D9E9A0028D27C /* statx_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = statx_np.c; sourceTree = "<group>"; };
- C9B53DBD138D9E9A0028D27C /* SYSCALL-LIST */ = {isa = PBXFileReference; lastKnownFileType = text; path = "SYSCALL-LIST"; sourceTree = "<group>"; };
C9B53DBE138D9E9A0028D27C /* umaskx_np.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = umaskx_np.c; sourceTree = "<group>"; };
- C9B53DC0138D9E9A0028D27C /* cprocs.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cprocs.c; sourceTree = "<group>"; };
- C9B53DC1138D9E9A0028D27C /* cthread_internals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cthread_internals.h; sourceTree = "<group>"; };
- C9B53DC2138D9E9A0028D27C /* cthreads.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = cthreads.c; sourceTree = "<group>"; };
- C9B53DC3138D9E9A0028D27C /* cthreads.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cthreads.h; sourceTree = "<group>"; };
- C9B53DC5138D9E9A0028D27C /* mig_support.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mig_support.c; sourceTree = "<group>"; };
C9B53DC7138D9E9A0028D27C /* fparseln.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = fparseln.3; sourceTree = "<group>"; };
C9B53DC8138D9E9A0028D27C /* fparseln.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = fparseln.c; sourceTree = "<group>"; };
C9B53DC9138D9E9A0028D27C /* login.3 */ = {isa = PBXFileReference; lastKnownFileType = text; path = login.3; sourceTree = "<group>"; };
C9B53DEA138D9E9A0028D27C /* uuid_parse.3.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = uuid_parse.3.in; sourceTree = "<group>"; };
C9B53DEB138D9E9A0028D27C /* uuid_unparse.3.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = uuid_unparse.3.in; sourceTree = "<group>"; };
C9B53DED138D9E9A0028D27C /* uuidP.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = uuidP.h; sourceTree = "<group>"; };
- C9B53DF1138D9E9A0028D27C /* _ctx_start.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _ctx_start.S; sourceTree = "<group>"; };
- C9B53DF2138D9E9A0028D27C /* _setcontext.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setcontext.S; sourceTree = "<group>"; };
- C9B53DF3138D9E9A0028D27C /* cpu_number.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = cpu_number.s; sourceTree = "<group>"; };
- C9B53DF4138D9E9A0028D27C /* getcontext.S */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = getcontext.S; sourceTree = "<group>"; };
- C9B53DF5138D9E9A0028D27C /* getmcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = getmcontext.c; sourceTree = "<group>"; };
- C9B53DF6138D9E9A0028D27C /* icacheinval.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = icacheinval.s; sourceTree = "<group>"; };
- C9B53DF7138D9E9A0028D27C /* makecontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = makecontext.c; sourceTree = "<group>"; };
C9B53DF9138D9E9A0028D27C /* mcount.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = mcount.s; sourceTree = "<group>"; };
- C9B53DFA138D9E9A0028D27C /* setcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = setcontext.c; sourceTree = "<group>"; };
- C9B53DFB138D9E9A0028D27C /* swapcontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = swapcontext.c; sourceTree = "<group>"; };
- C9B53DFE138D9E9A0028D27C /* preempt.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = preempt.s; sourceTree = "<group>"; };
- C9B53DFF138D9E9A0028D27C /* pthread_getspecific.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_getspecific.s; sourceTree = "<group>"; };
- C9B53E00138D9E9A0028D27C /* pthread_mutex_lock.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_mutex_lock.s; sourceTree = "<group>"; };
- C9B53E01138D9E9A0028D27C /* pthread_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_self.s; sourceTree = "<group>"; };
- C9B53E02138D9E9A0028D27C /* pthread_set_self.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = pthread_set_self.s; sourceTree = "<group>"; };
- C9B53E03138D9E9A0028D27C /* start_wqthread.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = start_wqthread.s; sourceTree = "<group>"; };
- C9B53E04138D9E9A0028D27C /* thread_start.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = thread_start.s; sourceTree = "<group>"; };
- C9B53E08138D9E9A0028D27C /* __bzero.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = __bzero.s; sourceTree = "<group>"; };
- C9B53E09138D9E9A0028D27C /* bcopy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bcopy.c; sourceTree = "<group>"; };
- C9B53E0A138D9E9A0028D27C /* bcopy_sse3x.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse3x.s; sourceTree = "<group>"; };
- C9B53E0B138D9E9A0028D27C /* bcopy_sse42.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bcopy_sse42.s; sourceTree = "<group>"; };
- C9B53E0C138D9E9A0028D27C /* bzero.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = bzero.c; sourceTree = "<group>"; };
- C9B53E0D138D9E9A0028D27C /* bzero_sse2.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_sse2.s; sourceTree = "<group>"; };
- C9B53E0E138D9E9A0028D27C /* bzero_sse42.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = bzero_sse42.s; sourceTree = "<group>"; };
- C9B53E0F138D9E9A0028D27C /* ffs.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = ffs.s; sourceTree = "<group>"; };
- C9B53E10138D9E9A0028D27C /* longcopy_sse3x.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = longcopy_sse3x.s; sourceTree = "<group>"; };
- C9B53E12138D9E9A0028D27C /* memcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memcmp.s; sourceTree = "<group>"; };
- C9B53E13138D9E9A0028D27C /* memcpy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memcpy.c; sourceTree = "<group>"; };
- C9B53E14138D9E9A0028D27C /* memmove.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = memmove.c; sourceTree = "<group>"; };
- C9B53E15138D9E9A0028D27C /* memset.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = memset.s; sourceTree = "<group>"; };
- C9B53E16138D9E9A0028D27C /* strcmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcmp.s; sourceTree = "<group>"; };
C9B53E17138D9E9A0028D27C /* strcpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strcpy.s; sourceTree = "<group>"; };
- C9B53E18138D9E9A0028D27C /* strlcat.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlcat.s; sourceTree = "<group>"; };
- C9B53E19138D9E9A0028D27C /* strlcpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlcpy.s; sourceTree = "<group>"; };
C9B53E1A138D9E9A0028D27C /* strlen.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strlen.s; sourceTree = "<group>"; };
- C9B53E1B138D9E9A0028D27C /* strncmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncmp.s; sourceTree = "<group>"; };
C9B53E1C138D9E9A0028D27C /* strncpy.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = strncpy.s; sourceTree = "<group>"; };
- C9B53E1E138D9E9A0028D27C /* _setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _setjmp.s; sourceTree = "<group>"; };
- C9B53E1F138D9E9A0028D27C /* _sigtramp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = _sigtramp.s; sourceTree = "<group>"; };
- C9B53E20138D9E9A0028D27C /* atomic.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = atomic.c; sourceTree = "<group>"; };
- C9B53E21138D9E9A0028D27C /* i386_gettimeofday_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = i386_gettimeofday_asm.s; sourceTree = "<group>"; };
- C9B53E23138D9E9A0028D27C /* nanotime.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = nanotime.s; sourceTree = "<group>"; };
- C9B53E24138D9E9A0028D27C /* OSAtomic.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = OSAtomic.s; sourceTree = "<group>"; };
- C9B53E25138D9E9A0028D27C /* setjmp.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = setjmp.s; sourceTree = "<group>"; };
- C9B53E26138D9E9A0028D27C /* spinlocks.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = spinlocks.c; sourceTree = "<group>"; };
- C9B53E27138D9E9A0028D27C /* spinlocks_asm.s */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.asm; path = spinlocks_asm.s; sourceTree = "<group>"; };
C9B53E2C138DA0610028D27C /* libPlatform.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPlatform.a; sourceTree = BUILT_PRODUCTS_DIR; };
C9C2A948138DF7DD00287F00 /* libc.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = libc.xcconfig; sourceTree = "<group>"; };
C9C2A94D138DFFD900287F00 /* libBase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBase.a; sourceTree = BUILT_PRODUCTS_DIR; };
- C9C62BDF13AA7F6A001FD88D /* OSAtomic.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSAtomic.h; sourceTree = "<group>"; };
- C9CF595913CD0B9600674871 /* memset_pattern.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = memset_pattern.c; sourceTree = "<group>"; };
C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = forceLibcToBuild.c; sourceTree = "<group>"; };
C9D9432F138DB73300FB7ACC /* libsystem_c.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_c.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
C9D94357138EC0C600FB7ACC /* heapsort_b.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = heapsort_b.c; sourceTree = "<group>"; };
C9EB350D138F75580075BB52 /* libvInode32.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libvInode32.a; sourceTree = BUILT_PRODUCTS_DIR; };
C9EB350E138F769B0075BB52 /* scandir_b.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = scandir_b.c; sourceTree = "<group>"; };
C9EB354F138F7EA50075BB52 /* getmntinfo64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getmntinfo64.c; sourceTree = "<group>"; };
- C9EB3555138F7F6A0075BB52 /* setjmperr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = setjmperr.c; sourceTree = "<group>"; };
C9FA32F8138E4A5C0089A94B /* utf2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = utf2.c; sourceTree = "<group>"; };
+ E4A877A6174D82FB000DBB55 /* alias.list */ = {isa = PBXFileReference; lastKnownFileType = text; path = alias.list; sourceTree = "<group>"; };
+ FC2ED60E157D4BE70098EC69 /* inet_ntop.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet_ntop.c; sourceTree = "<group>"; };
+ FC2ED60F157D4BE70098EC69 /* inet_pton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet_pton.c; sourceTree = "<group>"; };
+ FC2ED623157D4DA90098EC69 /* inet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inet.h; sourceTree = "<group>"; };
+ FC60BAD116555A4A00033196 /* _intmax_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _intmax_t.h; sourceTree = "<group>"; };
+ FC60BAD216555A4A00033196 /* _nl_item.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _nl_item.h; sourceTree = "<group>"; };
+ FC60BAD316555A4A00033196 /* _uint16_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uint16_t.h; sourceTree = "<group>"; };
+ FC60BAD416555A4A00033196 /* _uint32_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uint32_t.h; sourceTree = "<group>"; };
+ FC60BAD516555A4A00033196 /* _uint64_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uint64_t.h; sourceTree = "<group>"; };
+ FC60BAD616555A4A00033196 /* _uint8_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uint8_t.h; sourceTree = "<group>"; };
+ FC60BAD716555A4A00033196 /* _uintmax_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _uintmax_t.h; sourceTree = "<group>"; };
+ FC60BAD816555A4A00033196 /* _wctrans_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _wctrans_t.h; sourceTree = "<group>"; };
+ FC60BAD916555A4A00033196 /* _wctype_t.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _wctype_t.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
- B122F2A91432B8E600AF95D0 /* Frameworks */ = {
+ 3F5120ED16C3174300AFB431 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
- B1E96502157E722200FCCEE7 /* Frameworks */ = {
+ B122F2A91432B8E600AF95D0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
+ C97A72181517AF53005E1998 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C9AE91B51517D31A00A2626C /* libBase.a in Frameworks */,
+ C9AE91B71517D31C00A2626C /* libFreeBSD.a in Frameworks */,
+ C9AE91B81517D32200A2626C /* libvCancelable.a in Frameworks */,
+ C9AE91B91517D32900A2626C /* libTRE.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
C9B53E29138DA0610028D27C /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 3F18DE1E162A732C008B15AC /* NetBSD */ = {
+ isa = PBXGroup;
+ children = (
+ 3F18DE1F162A732C008B15AC /* memset_s.3 */,
+ 3F18DE20162A732C008B15AC /* memset_s.c */,
+ );
+ path = NetBSD;
+ sourceTree = "<group>";
+ };
+ 4B2C64A015519B0500342BFA /* os */ = {
+ isa = PBXGroup;
+ children = (
+ 2B9D61B5157D667000AF25B8 /* trace.c */,
+ 2B9D61B6157D667000AF25B8 /* trace.h */,
+ 2B350EC1158FDC7600A58CD2 /* base.h */,
+ 4B2C64AB15519C3400342BFA /* assumes.h */,
+ 4B2C64A215519BAF00342BFA /* assumes.c */,
+ );
+ name = os;
+ sourceTree = "<group>";
+ };
B122F2AE1432B95B00AF95D0 /* TRE */ = {
isa = PBXGroup;
children = (
children = (
C9B535AE138D9E980028D27C /* APPLE_LICENSE */,
C9B535AF138D9E980028D27C /* arm */,
+ C9B535E2138D9E980028D27C /* arm */,
C9B535F5138D9E980028D27C /* compat-43 */,
C9B53612138D9E980028D27C /* darwin */,
C9B5361D138D9E980028D27C /* db */,
C9B53A0E138D9E990028D27C /* nbsdcompat */,
C9B53A11138D9E990028D27C /* net */,
C9B53A3A138D9E990028D27C /* nls */,
+ 4B2C64A015519B0500342BFA /* os */,
C9B53A45138D9E990028D27C /* Platforms */,
C9B53A4A138D9E990028D27C /* posix1e */,
- C9B53ABA138D9E990028D27C /* pthreads */,
C9B53B03138D9E990028D27C /* regex */,
- C9B53B1B138D9E990028D27C /* rpc */,
C9B53B1D138D9E990028D27C /* secure */,
C9B53B2D138D9E990028D27C /* stdio */,
C9B53C16138D9E9A0028D27C /* stdlib */,
C9B53CC0138D9E9A0028D27C /* stdtime */,
C9B53CE4138D9E9A0028D27C /* string */,
C9B53D93138D9E9A0028D27C /* sys */,
- C9B53DBF138D9E9A0028D27C /* threads */,
C9B53DC6138D9E9A0028D27C /* util */,
C9B53DD3138D9E9A0028D27C /* uuid */,
C9B53DEF138D9E9A0028D27C /* x86_64 */,
C9EB350D138F75580075BB52 /* libvInode32.a */,
C94212CC13900C8A004BA536 /* libc.a */,
B122F2AD1432B8E600AF95D0 /* libTRE.a */,
- B1E96506157E722200FCCEE7 /* libFreeBSD_gcc.a */,
+ C97A721C1517AF53005E1998 /* libc_eOS.a */,
+ 3F5120F116C3174300AFB431 /* libFortifySource.a */,
);
name = Products;
sourceTree = "<group>";
isa = PBXGroup;
children = (
C9B535B0138D9E980028D27C /* gen */,
- C9B535B5138D9E980028D27C /* pthreads */,
C9B535BF138D9E980028D27C /* string */,
- C9B535D4138D9E980028D27C /* sys */,
);
path = arm;
sourceTree = "<group>";
C9B535B0138D9E980028D27C /* gen */ = {
isa = PBXGroup;
children = (
- C9B535B1138D9E980028D27C /* cpu_number.s */,
- C9B535B2138D9E980028D27C /* icacheinval.s */,
+ C925D1FB151805C6003D315B /* eos_stubs.c */,
);
path = gen;
sourceTree = "<group>";
};
- C9B535B5138D9E980028D27C /* pthreads */ = {
- isa = PBXGroup;
- children = (
- C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */,
- C9B535B8138D9E980028D27C /* pthread_getspecific.s */,
- C9B535B9138D9E980028D27C /* pthread_self.s */,
- C9B535BA138D9E980028D27C /* pthread_set_self.s */,
- C9B535BB138D9E980028D27C /* start_wqthread.s */,
- C9B535BC138D9E980028D27C /* thread_start.s */,
- );
- path = pthreads;
- sourceTree = "<group>";
- };
C9B535BF138D9E980028D27C /* string */ = {
isa = PBXGroup;
children = (
- C9B535C0138D9E980028D27C /* bcopy_CortexA8.s */,
- C9B535C1138D9E980028D27C /* bcopy_CortexA9.s */,
- 6358199213B53ECB00CDF61C /* bcopy_Swift.s */,
- C9B535C2138D9E980028D27C /* bcopy_Generic.s */,
- C9B535C3138D9E980028D27C /* bzero_CortexA8.s */,
- C9B535C4138D9E980028D27C /* bzero_CortexA9.s */,
- 6358199013B53DD800CDF61C /* bzero_Swift.s */,
- C9B535C5138D9E980028D27C /* bzero_Generic.s */,
- C9B535C6138D9E980028D27C /* dyld_resolvers.c */,
- C9B535C7138D9E980028D27C /* ffs.s */,
- C9B535C9138D9E980028D27C /* memcmp.s */,
- C9B535CA138D9E980028D27C /* memset_pattern.s */,
- 634C4C3713BCEADC008CA66D /* memset_pattern_Swift.s */,
- C9B535CB138D9E980028D27C /* strchr.s */,
- C9B535CC138D9E980028D27C /* strcmp.s */,
C9B535CF138D9E980028D27C /* strlen.s */,
- C9B535D0138D9E980028D27C /* strncmp.s */,
C9B535D2138D9E980028D27C /* strnlen.s */,
C9B535D3138D9E980028D27C /* strstr.s */,
);
path = string;
sourceTree = "<group>";
};
- C9B535D4138D9E980028D27C /* sys */ = {
+ C9B535E2138D9E980028D27C /* arm */ = {
isa = PBXGroup;
children = (
- C9B535D5138D9E980028D27C /* _longjmp.s */,
- C9B535D6138D9E980028D27C /* _setjmp.h */,
- C9B535D7138D9E980028D27C /* _setjmp.s */,
- C9B535D8138D9E980028D27C /* arm_commpage_gettimeofday.c */,
- C9B535D9138D9E980028D27C /* gcc_atomic.c */,
- C9B535DA138D9E980028D27C /* longjmp.s */,
- C9B535DB138D9E980028D27C /* mach_absolute_time.s */,
- C9B535DD138D9E980028D27C /* OSAtomic-v4.c */,
- C9C62BDF13AA7F6A001FD88D /* OSAtomic.h */,
- C9B4E3D713BBBF2D0008A9BB /* OSAtomic.c */,
- C995462713AAA25000A531B4 /* OSAtomicUP.c */,
- C97C344013AB0E1B00713550 /* Spinlocks.c */,
- C980F8EB13AB168D0069AB06 /* SpinlocksUP.c */,
- C932C2CF13AB1C73004EDA12 /* SpinlocksWFE.c */,
- C9B535DF138D9E980028D27C /* OSAtomic_resolvers.c */,
- C9B535E0138D9E980028D27C /* OSAtomic_resolvers.h */,
- C9B535E1138D9E980028D27C /* setjmp.s */,
+ C9B535EB138D9E980028D27C /* string */,
);
- path = sys;
+ path = arm;
+ sourceTree = "<group>";
+ };
+ C9B535EB138D9E980028D27C /* string */ = {
+ isa = PBXGroup;
+ children = (
+ 63505E3A1548525D00B637D7 /* strnlen.s */,
+ );
+ path = string;
sourceTree = "<group>";
};
C9B535F5138D9E980028D27C /* compat-43 */ = {
C9B53614138D9E980028D27C /* dirhelper.defs */,
C9B53615138D9E980028D27C /* dirhelper_priv.h */,
C9D9432A138DB72000FB7ACC /* forceLibcToBuild.c */,
+ C9B535B6138D9E980028D27C /* init_cpu_capabilities.c */,
C9B53616138D9E980028D27C /* kvm.c */,
- C9B53617138D9E980028D27C /* libproc.c */,
- C9B53618138D9E980028D27C /* libproc.h */,
- C9B53619138D9E980028D27C /* libproc_internal.h */,
- C9B5361C138D9E980028D27C /* proc_listpidspath.c */,
- C9B5361B138D9E980028D27C /* MKGetTimeBaseInfo.c */,
- C9B4E3D513BBBF060008A9BB /* OSAtomicLoadStoreEx.c */,
- C9B4E3D913BBC24E0008A9BB /* SpinlocksLoadStoreEx.c */,
);
path = darwin;
sourceTree = "<group>";
isa = PBXGroup;
children = (
C9B536C1138D9E990028D27C /* __dirent.h */,
- C9B536C2138D9E990028D27C /* _simple.c */,
- C9B536C3138D9E990028D27C /* _simple.h */,
- C9B536C4138D9E990028D27C /* asl.3 */,
- C9B536C5138D9E990028D27C /* asl.c */,
- C9B536C6138D9E990028D27C /* asl_core.c */,
- C9B536C7138D9E990028D27C /* asl_core.h */,
- 3F2208E714358B4A00386F5B /* asl_fd.c */,
- C9B536C8138D9E990028D27C /* asl_file.c */,
- C9B536C9138D9E990028D27C /* asl_file.h */,
- C9B536CA138D9E990028D27C /* asl_ipc.defs */,
- C9B536CB138D9E990028D27C /* asl_legacy1.c */,
- C9B536CC138D9E990028D27C /* asl_legacy1.h */,
- C9B536CD138D9E990028D27C /* asl_msg.c */,
- C9B536CE138D9E990028D27C /* asl_msg.h */,
- C9B536CF138D9E990028D27C /* asl_private.h */,
- C9B536D0138D9E990028D27C /* asl_store.c */,
- C9B536D1138D9E990028D27C /* asl_store.h */,
- C9B536D2138D9E990028D27C /* asl_util.c */,
- C9B536D3138D9E990028D27C /* assumes.c */,
C9B536D4138D9E990028D27C /* assumes.h */,
C9B536D5138D9E990028D27C /* authentication.c */,
C9B536D6138D9E990028D27C /* backtrace.3 */,
C9B536D7138D9E990028D27C /* backtrace.c */,
- C9B536D8138D9E990028D27C /* cache.c */,
C9B536D9138D9E990028D27C /* compat.5 */,
C9B536DA138D9E990028D27C /* confstr.3 */,
C9B536DB138D9E990028D27C /* confstr.c */,
C9B537CF138D9E990028D27C /* getvfsbyname.3 */,
C9B537D0138D9E990028D27C /* getvfsbyname.c */,
C9B537D1138D9E990028D27C /* intro.3 */,
- C9B537D2138D9E990028D27C /* isinf.c */,
- C9B537D3138D9E990028D27C /* isnan.c */,
- C9B537D4138D9E990028D27C /* magazine_malloc.c */,
- C9B537D5138D9E990028D27C /* magmallocProvider.d */,
- C9B537D7138D9E990028D27C /* malloc.3 */,
- C9B537D8138D9E990028D27C /* malloc.c */,
- C9B537D9138D9E990028D27C /* malloc_printf.h */,
- C9B537DA138D9E990028D27C /* malloc_size.3 */,
- C9B537DB138D9E990028D27C /* malloc_zone_malloc.3 */,
C9B537DC138D9E990028D27C /* nanosleep.c */,
C9B537DD138D9E990028D27C /* NetBSD */,
C9B537E6138D9E990028D27C /* nftw.c */,
C9B537E8138D9E990028D27C /* nlist.c */,
C9B537E9138D9E990028D27C /* NSSystemDirectories.c */,
C9B537EA138D9E990028D27C /* oldsyslog.c */,
- C9B537EB138D9E990028D27C /* platfunc.c */,
- C9B537EC138D9E990028D27C /* platfunc.h */,
C9B537ED138D9E990028D27C /* posix_memalign.3 */,
C9B537EE138D9E990028D27C /* pwcache.3 */,
- C9B537EF138D9E990028D27C /* scalable_malloc.c */,
- C9B537F0138D9E990028D27C /* scalable_malloc.h */,
- C9B537F1138D9E990028D27C /* setjmp.3 */,
C9B537F2138D9E990028D27C /* setlogin.c */,
C9B537F3138D9E990028D27C /* sigsetops.3 */,
C9B537F4138D9E990028D27C /* sigsetops.c */,
- C9B537F5138D9E990028D27C /* stack_logging.c */,
- C9B537F6138D9E990028D27C /* stack_logging.h */,
- C9B537F7138D9E990028D27C /* stack_logging_disk.c */,
C9B537F8138D9E990028D27C /* strtofflags.3 */,
C9B537F9138D9E990028D27C /* strtofflags.c */,
B19C64591450F8B900032373 /* sync_volume_np.3 */,
B19C645B1450F90200032373 /* sync_volume_np.c */,
- C9B537FA138D9E990028D27C /* syslog.3 */,
- C9B537FB138D9E990028D27C /* syslog.c */,
C9B537FC138D9E990028D27C /* tcgetpgrp.3 */,
C9B537FD138D9E990028D27C /* tcsendbreak.3 */,
C9B537FE138D9E990028D27C /* tcsetattr.3 */,
C9B5371A138D9E990028D27C /* ftok.c */,
C9B5371C138D9E990028D27C /* getbsize.c */,
C9B5371E138D9E990028D27C /* getcap.c */,
- C9B53720138D9E990028D27C /* getcontext.3 */,
C9B53721138D9E990028D27C /* getcwd.3 */,
C9B53722138D9E990028D27C /* getcwd.c */,
C9B53724138D9E990028D27C /* gethostname.3 */,
C9B53741138D9E990028D27C /* lockf.3 */,
C9B53743138D9E990028D27C /* lockf.c */,
C9B53745138D9E990028D27C /* lrand48.c */,
- C9B53747138D9E990028D27C /* makecontext.3 */,
C9B53749138D9E990028D27C /* mrand48.c */,
C9B5374B138D9E990028D27C /* nice.3 */,
C9B5374C138D9E990028D27C /* nice.c */,
C9B537A9138D9E990028D27C /* ttyslot.c */,
C9B537AA138D9E990028D27C /* ualarm.3 */,
C9B537AC138D9E990028D27C /* ualarm.c */,
- C9B537AD138D9E990028D27C /* ucontext.3 */,
C9B537AE138D9E990028D27C /* ulimit.3 */,
C9B537B0138D9E990028D27C /* ulimit.c */,
C9B537B1138D9E990028D27C /* unvis.3 */,
C9B537DD138D9E990028D27C /* NetBSD */ = {
isa = PBXGroup;
children = (
+ 3F267F36163FC8880089A0A6 /* rb.c */,
+ 3F267F37163FC8880089A0A6 /* rbtree.3 */,
C9B537DE138D9E990028D27C /* endutxent.3 */,
C9B537E0138D9E990028D27C /* getlastlogx.3 */,
C9B537E2138D9E990028D27C /* utmpx.5 */,
isa = PBXGroup;
children = (
C9B53810138D9E990028D27C /* gen */,
- C9B5381D138D9E990028D27C /* pthreads */,
C9B53829138D9E990028D27C /* string */,
- C9B53843138D9E990028D27C /* sys */,
);
path = i386;
sourceTree = "<group>";
C9B53810138D9E990028D27C /* gen */ = {
isa = PBXGroup;
children = (
- C9B53811138D9E990028D27C /* _ctx_start.S */,
- C9B53812138D9E990028D27C /* _setcontext.S */,
- C9B53813138D9E990028D27C /* cpu_number.s */,
- C9B53814138D9E990028D27C /* getcontext.S */,
- C9B53815138D9E990028D27C /* getmcontext.c */,
- C9B53816138D9E990028D27C /* icacheinval.s */,
- C9B53817138D9E990028D27C /* makecontext.c */,
C9B53819138D9E990028D27C /* mcount.s */,
- C9B5381A138D9E990028D27C /* setcontext.c */,
- C9B5381B138D9E990028D27C /* setjmperr.c */,
- C9B5381C138D9E990028D27C /* swapcontext.c */,
);
path = gen;
sourceTree = "<group>";
};
- C9B5381D138D9E990028D27C /* pthreads */ = {
- isa = PBXGroup;
- children = (
- C9B5381E138D9E990028D27C /* init_cpu_capabilities.c */,
- C9B53820138D9E990028D27C /* preempt.s */,
- C9B53821138D9E990028D27C /* pthread_getspecific.s */,
- C9B53822138D9E990028D27C /* pthread_mutex_lock.s */,
- C9B53823138D9E990028D27C /* pthread_self.s */,
- C9B53824138D9E990028D27C /* pthread_set_self.s */,
- C9B53825138D9E990028D27C /* start_wqthread.s */,
- C9B53826138D9E990028D27C /* thread_start.s */,
- );
- path = pthreads;
- sourceTree = "<group>";
- };
C9B53829138D9E990028D27C /* string */ = {
isa = PBXGroup;
children = (
- C9B5382A138D9E990028D27C /* __bzero.s */,
- C9B5382B138D9E990028D27C /* bcopy.c */,
- C9B5382C138D9E990028D27C /* bcopy_scalar.s */,
- C9B5382D138D9E990028D27C /* bcopy_sse2.s */,
- C9B5382E138D9E990028D27C /* bcopy_sse3x.s */,
- C9B5382F138D9E990028D27C /* bcopy_sse42.s */,
- C9B53830138D9E990028D27C /* bzero.c */,
- C9B53831138D9E990028D27C /* bzero_scalar.s */,
- C9B53832138D9E990028D27C /* bzero_sse2.s */,
- C9B53833138D9E990028D27C /* bzero_sse42.s */,
- C9B53834138D9E990028D27C /* ffs.s */,
- C9B53835138D9E990028D27C /* longcopy_sse3x.s */,
- C9B53837138D9E990028D27C /* memcmp.s */,
- C9B53838138D9E990028D27C /* memcpy.c */,
- C9B53839138D9E990028D27C /* memmove.c */,
- C9B5383A138D9E990028D27C /* memset.s */,
- C9B5383B138D9E990028D27C /* memset_pattern_sse2.s */,
- C9B5383C138D9E990028D27C /* strcmp.s */,
C9B5383D138D9E990028D27C /* strcpy.s */,
C9B5383E138D9E990028D27C /* strlcat.s */,
C9B5383F138D9E990028D27C /* strlcpy.s */,
C9B53840138D9E990028D27C /* strlen.s */,
- C9B53841138D9E990028D27C /* strncmp.s */,
C9B53842138D9E990028D27C /* strncpy.s */,
);
path = string;
sourceTree = "<group>";
};
- C9B53843138D9E990028D27C /* sys */ = {
- isa = PBXGroup;
- children = (
- C9B53844138D9E990028D27C /* _setjmp.s */,
- C9B53845138D9E990028D27C /* _sigtramp.s */,
- C9B53846138D9E990028D27C /* atomic.c */,
- C9B53847138D9E990028D27C /* i386_gettimeofday_asm.s */,
- C9B53849138D9E990028D27C /* mach_absolute_time_asm.s */,
- C9B5384B138D9E990028D27C /* OSAtomic.s */,
- C9B5384C138D9E990028D27C /* setjmp.s */,
- C9B5384D138D9E990028D27C /* spinlocks.c */,
- C9B5384E138D9E990028D27C /* spinlocks_asm.s */,
- );
- path = sys;
- sourceTree = "<group>";
- };
C9B5384F138D9E990028D27C /* include */ = {
isa = PBXGroup;
children = (
C9B53850138D9E990028D27C /* _locale.h */,
C9B53851138D9E990028D27C /* _structs.h */,
+ FC60BAD016555A4A00033196 /* _types */,
C9B53852138D9E990028D27C /* _types.h */,
C9B53853138D9E990028D27C /* _wctype.h */,
C9B53854138D9E990028D27C /* _xlocale.h */,
C9B53856138D9E990028D27C /* alloca.h */,
C9B53857138D9E990028D27C /* ar.h */,
C9B53858138D9E990028D27C /* arpa */,
- C9B5385E138D9E990028D27C /* asl.h */,
C9B5385F138D9E990028D27C /* asm.h */,
C9B53860138D9E990028D27C /* assert.h */,
C9B53861138D9E990028D27C /* authentication.h */,
C9B5387F138D9E990028D27C /* libkern */,
C9B53885138D9E990028D27C /* limits.h */,
C9B53886138D9E990028D27C /* locale.h */,
- C9B53888138D9E990028D27C /* malloc */,
C9B5388B138D9E990028D27C /* memory.h */,
C9B5388C138D9E990028D27C /* monetary.h */,
C9B5388D138D9E990028D27C /* monitor.h */,
C9B53894138D9E990028D27C /* NSSystemDirectories.h */,
C9B53899138D9E990028D27C /* paths.h */,
C9B5389A138D9E990028D27C /* poll.h */,
+ B126140715881A420077E3CC /* printf.h */,
C9B5389B138D9E990028D27C /* protocols */,
C9B538A2138D9E990028D27C /* ranlib.h */,
C9B538A3138D9E990028D27C /* readpassphrase.h */,
C9B538A7138D9E990028D27C /* search.h */,
C9B538A8138D9E990028D27C /* secure */,
C9B538AD138D9E990028D27C /* semaphore.h */,
- C9B538AE138D9E990028D27C /* setjmp.h */,
C9B538AF138D9E990028D27C /* sgtty.h */,
C9B538B0138D9E990028D27C /* signal.h */,
- C9B538B1138D9E990028D27C /* spawn.h */,
- C9B538B2138D9E990028D27C /* spawn_private.h */,
C9B538B3138D9E990028D27C /* stab.h */,
C9B538B4138D9E990028D27C /* standards.h */,
C9B538B5138D9E990028D27C /* stdbool.h */,
C9B538C9138D9E990028D27C /* time.h */,
C9B538CA138D9E990028D27C /* timeconv.h */,
C9B538CB138D9E990028D27C /* ttyent.h */,
- C9B538CC138D9E990028D27C /* ucontext.h */,
C9B538CD138D9E990028D27C /* ulimit.h */,
C9B538CE138D9E990028D27C /* unistd.h */,
C9B538CF138D9E990028D27C /* util.h */,
isa = PBXGroup;
children = (
C9B53859138D9E990028D27C /* ftp.h */,
+ FC2ED623157D4DA90098EC69 /* inet.h */,
C9B5385B138D9E990028D27C /* nameser_compat.h */,
C9B5385C138D9E990028D27C /* telnet.h */,
C9B5385D138D9E990028D27C /* tftp.h */,
C9B5387F138D9E990028D27C /* libkern */ = {
isa = PBXGroup;
children = (
- C9B53881138D9E990028D27C /* OSAtomic.h */,
- C9B53882138D9E990028D27C /* OSCacheControl.h */,
C9B53883138D9E990028D27C /* OSMemoryNotification.h */,
C9B53884138D9E990028D27C /* OSThermalNotification.h */,
);
path = libkern;
sourceTree = "<group>";
};
- C9B53888138D9E990028D27C /* malloc */ = {
- isa = PBXGroup;
- children = (
- C9B5388A138D9E990028D27C /* malloc.h */,
- );
- path = malloc;
- sourceTree = "<group>";
- };
C9B53890138D9E990028D27C /* NetBSD */ = {
isa = PBXGroup;
children = (
children = (
C9B538C0138D9E990028D27C /* acl.h */,
C9B538C1138D9E990028D27C /* cdefs.h */,
+ 3F267F39163FC8BD0089A0A6 /* rbtree.h */,
C9B538C3138D9E990028D27C /* statvfs.h */,
);
path = sys;
C9B53A11138D9E990028D27C /* net */ = {
isa = PBXGroup;
children = (
+ FC2ED60E157D4BE70098EC69 /* inet_ntop.c */,
+ FC2ED60F157D4BE70098EC69 /* inet_pton.c */,
C9B53A12138D9E990028D27C /* byteorder.3 */,
C9B53A13138D9E990028D27C /* ethers.3 */,
C9B53A14138D9E990028D27C /* FreeBSD */,
path = posix1e;
sourceTree = "<group>";
};
- C9B53ABA138D9E990028D27C /* pthreads */ = {
- isa = PBXGroup;
- children = (
- C9B53ABC138D9E990028D27C /* mk_pthread_impl.c */,
- C9B53ABD138D9E990028D27C /* plockstat.d */,
- C9B53ABE138D9E990028D27C /* posix_sched.h */,
- C9B53ABF138D9E990028D27C /* pthread.3 */,
- C9B53AC0138D9E990028D27C /* pthread.c */,
- C9B53AC1138D9E990028D27C /* pthread.h */,
- C9B53AC2138D9E990028D27C /* pthread_atfork.3 */,
- C9B53AC3138D9E990028D27C /* pthread_attr.3 */,
- C9B53AC4138D9E990028D27C /* pthread_attr_init_destroy.3 */,
- C9B53AC5138D9E990028D27C /* pthread_attr_set_getdetachstate.3 */,
- C9B53AC6138D9E990028D27C /* pthread_attr_set_getinheritsched.3 */,
- C9B53AC7138D9E990028D27C /* pthread_attr_set_getschedparam.3 */,
- C9B53AC8138D9E990028D27C /* pthread_attr_set_getschedpolicy.3 */,
- C9B53AC9138D9E990028D27C /* pthread_attr_set_getscope.3 */,
- C9B53ACA138D9E990028D27C /* pthread_attr_set_getstackaddr.3 */,
- C9B53ACB138D9E990028D27C /* pthread_attr_set_getstacksize.3 */,
- C9B53ACC138D9E990028D27C /* pthread_cancel.3 */,
- C9B53ACD138D9E990028D27C /* pthread_cancelable.c */,
- C9B53ACE138D9E990028D27C /* pthread_cleanup_pop.3 */,
- C9B53ACF138D9E990028D27C /* pthread_cleanup_push.3 */,
- C9B53AD0138D9E990028D27C /* pthread_cond.c */,
- C9B53AD1138D9E990028D27C /* pthread_cond_broadcast.3 */,
- C9B53AD2138D9E990028D27C /* pthread_cond_destroy.3 */,
- C9B53AD3138D9E990028D27C /* pthread_cond_init.3 */,
- C9B53AD4138D9E990028D27C /* pthread_cond_signal.3 */,
- C9B53AD5138D9E990028D27C /* pthread_cond_timedwait.3 */,
- C9B53AD6138D9E990028D27C /* pthread_cond_wait.3 */,
- C9B53AD7138D9E990028D27C /* pthread_condattr.3 */,
- C9B53AD8138D9E990028D27C /* pthread_create.3 */,
- C9B53AD9138D9E990028D27C /* pthread_detach.3 */,
- C9B53ADA138D9E990028D27C /* pthread_equal.3 */,
- C9B53ADB138D9E990028D27C /* pthread_exit.3 */,
- C9B53ADC138D9E990028D27C /* pthread_getschedparam.3 */,
- C9B53ADD138D9E990028D27C /* pthread_getspecific.3 */,
- C9B53ADE138D9E990028D27C /* pthread_impl.h */,
- C9B53ADF138D9E990028D27C /* pthread_internals.h */,
- C9B53AE0138D9E990028D27C /* pthread_join.3 */,
- C9B53AE1138D9E990028D27C /* pthread_key_create.3 */,
- C9B53AE2138D9E990028D27C /* pthread_key_delete.3 */,
- C9B53AE3138D9E990028D27C /* pthread_machdep.h */,
- C9B53AE4138D9E990028D27C /* pthread_mutex.c */,
- C9B53AE5138D9E990028D27C /* pthread_mutex_destroy.3 */,
- C9B53AE6138D9E990028D27C /* pthread_mutex_init.3 */,
- C9B53AE7138D9E990028D27C /* pthread_mutex_lock.3 */,
- C9B53AE8138D9E990028D27C /* pthread_mutex_trylock.3 */,
- C9B53AE9138D9E990028D27C /* pthread_mutex_unlock.3 */,
- C9B53AEA138D9E990028D27C /* pthread_mutexattr.3 */,
- C9B53AEB138D9E990028D27C /* pthread_once.3 */,
- C9B53AEC138D9E990028D27C /* pthread_rwlock.c */,
- C9B53AED138D9E990028D27C /* pthread_rwlock_destroy.3 */,
- C9B53AEE138D9E990028D27C /* pthread_rwlock_init.3 */,
- C9B53AEF138D9E990028D27C /* pthread_rwlock_rdlock.3 */,
- C9B53AF0138D9E990028D27C /* pthread_rwlock_unlock.3 */,
- C9B53AF1138D9E990028D27C /* pthread_rwlock_wrlock.3 */,
- C9B53AF2138D9E990028D27C /* pthread_rwlockattr_destroy.3 */,
- C9B53AF3138D9E990028D27C /* pthread_rwlockattr_getpshared.3 */,
- C9B53AF4138D9E990028D27C /* pthread_rwlockattr_init.3 */,
- C9B53AF5138D9E990028D27C /* pthread_rwlockattr_setpshared.3 */,
- C9B53AF6138D9E990028D27C /* pthread_self.3 */,
- C9B53AF7138D9E990028D27C /* pthread_setcancelstate.3 */,
- C9B53AF8138D9E990028D27C /* pthread_setspecific.3 */,
- C9B53AF9138D9E990028D27C /* pthread_spinlock.h */,
- C9B53AFA138D9E990028D27C /* pthread_spis.h */,
- C9B53AFB138D9E990028D27C /* pthread_tsd.c */,
- C9B53AFC138D9E990028D27C /* pthread_workqueue.h */,
- C9B53AFD138D9E990028D27C /* sched.h */,
- C9B53AFE138D9E990028D27C /* stack.s */,
- C9B53AFF138D9E990028D27C /* tests */,
- C9B53B02138D9E990028D27C /* thread_setup.c */,
- );
- path = pthreads;
- sourceTree = "<group>";
- };
- C9B53AFF138D9E990028D27C /* tests */ = {
- isa = PBXGroup;
- children = (
- C9B53B00138D9E990028D27C /* Makefile */,
- C9B53B01138D9E990028D27C /* pthread_atfork_test.c */,
- );
- path = tests;
- sourceTree = "<group>";
- };
C9B53B03138D9E990028D27C /* regex */ = {
isa = PBXGroup;
children = (
path = FreeBSD;
sourceTree = "<group>";
};
- C9B53B1B138D9E990028D27C /* rpc */ = {
- isa = PBXGroup;
- children = (
- );
- path = rpc;
- sourceTree = "<group>";
- };
C9B53B1D138D9E990028D27C /* secure */ = {
isa = PBXGroup;
children = (
C9B53B1E138D9E990028D27C /* chk_fail.c */,
+ 3F169A3C1643B7BA0029E851 /* memccpy_chk.c */,
C9B53B20138D9E990028D27C /* memcpy_chk.c */,
C9B53B21138D9E990028D27C /* memmove_chk.c */,
C9B53B22138D9E990028D27C /* memset_chk.c */,
C9B53B26138D9E990028D27C /* stpncpy_chk.c */,
C9B53B27138D9E990028D27C /* strcat_chk.c */,
C9B53B28138D9E990028D27C /* strcpy_chk.c */,
+ 3FA8F3081643AB4300D37078 /* strlcat_chk.c */,
+ 3FA8F3091643AB4300D37078 /* strlcpy_chk.c */,
C9B53B29138D9E990028D27C /* strncat_chk.c */,
C9B53B2A138D9E990028D27C /* strncpy_chk.c */,
C9B53B2B138D9E990028D27C /* vsnprintf_chk.c */,
C9B53C13138D9E9A0028D27C /* scanf_l.3 */,
C9B53C14138D9E9A0028D27C /* wprintf_l.3 */,
C9B53C15138D9E9A0028D27C /* wscanf_l.3 */,
+ B1795371158B0E35008990E8 /* xprintf_all_in_one.c */,
+ B126140215881A000077E3CC /* xprintf_comp.c */,
+ B126140315881A000077E3CC /* xprintf_domain.c */,
+ B126140415881A000077E3CC /* xprintf_domain.h */,
+ B1795372158B0E35008990E8 /* xprintf_exec.c */,
);
path = stdio;
sourceTree = "<group>";
C9B53C0A138D9E9A0028D27C /* wscanf.3 */,
C9B53C0C138D9E9A0028D27C /* wscanf.c */,
C9B53C0E138D9E9A0028D27C /* wsetup.c */,
+ B12613EE158818EC0077E3CC /* xprintf_errno.c */,
+ B12613EF158818EC0077E3CC /* xprintf_float.c */,
+ B12613F0158818EC0077E3CC /* xprintf_hexdump.c */,
+ B12613F1158818EC0077E3CC /* xprintf_int.c */,
+ B12613F2158818EC0077E3CC /* xprintf_private.h */,
+ B12613F3158818EC0077E3CC /* xprintf_quote.c */,
+ B12613F4158818EC0077E3CC /* xprintf_str.c */,
+ B12613F5158818EC0077E3CC /* xprintf_time.c */,
+ B12613F6158818EC0077E3CC /* xprintf_vis.c */,
+ B12613F7158818EC0077E3CC /* xprintf.c */,
);
path = FreeBSD;
sourceTree = "<group>";
C9B53CE4138D9E9A0028D27C /* string */ = {
isa = PBXGroup;
children = (
+ 3F18DE1E162A732C008B15AC /* NetBSD */,
C9B53CE5138D9E9A0028D27C /* FreeBSD */,
C9B53D91138D9E9A0028D27C /* memset_pattern.3 */,
- C9CF595913CD0B9600674871 /* memset_pattern.c */,
+ 3FD14572171D42B300B7BAF5 /* bcopy.c */,
63D4060513DDEDF10094DD56 /* stpcpy.c */,
63D4060913DDEEA10094DD56 /* stpncpy.c */,
63D4060C13DDF26A0094DD56 /* strcat.c */,
6310518613D4D966004F7BA8 /* strcpy.c */,
+ E4A877A6174D82FB000DBB55 /* alias.list */,
63D4061213DDF6A20094DD56 /* strlcat.c */,
6310518B13D4DABD004F7BA8 /* strlcpy.c */,
63D4060F13DDF4340094DD56 /* strncat.c */,
isa = PBXGroup;
children = (
C9B53CE6138D9E9A0028D27C /* bcmp.3 */,
- C9B53CE8138D9E9A0028D27C /* bcmp.c */,
C9B53CE9138D9E9A0028D27C /* bcopy.3 */,
- C9B53CEB138D9E9A0028D27C /* bcopy.c */,
C9B53CED138D9E9A0028D27C /* bstring.3 */,
C9B53CEF138D9E9A0028D27C /* bzero.3 */,
- C9B53CF1138D9E9A0028D27C /* bzero.c */,
- C9B53CF3138D9E9A0028D27C /* ffs.3 */,
C9B53CF5138D9E9A0028D27C /* index.3 */,
C9B53CF7138D9E9A0028D27C /* index.c */,
C9B53CF8138D9E9A0028D27C /* memccpy.3 */,
- C9B53CFA138D9E9A0028D27C /* memccpy.c */,
C9B53CFB138D9E9A0028D27C /* memchr.3 */,
- C9B53CFD138D9E9A0028D27C /* memchr.c */,
C9B53CFE138D9E9A0028D27C /* memcmp.3 */,
- C9B53D00138D9E9A0028D27C /* memcmp.c */,
C9B53D01138D9E9A0028D27C /* memcpy.3 */,
- C9B53D03138D9E9A0028D27C /* memcpy.c */,
C9B53D05138D9E9A0028D27C /* memmem.3 */,
C9B53D06138D9E9A0028D27C /* memmem.c */,
C9B53D07138D9E9A0028D27C /* memmove.3 */,
- C9B53D09138D9E9A0028D27C /* memmove.c */,
C9B53D0B138D9E9A0028D27C /* memset.3 */,
- C9B53D0D138D9E9A0028D27C /* memset.c */,
C9B53D0E138D9E9A0028D27C /* rindex.3 */,
C9B53D10138D9E9A0028D27C /* rindex.c */,
C9B53D13138D9E9A0028D27C /* strcasecmp.3 */,
C9B53D17138D9E9A0028D27C /* strcasestr.c */,
C9B53D19138D9E9A0028D27C /* strcat.3 */,
C9B53D1C138D9E9A0028D27C /* strchr.3 */,
- C9B53D1E138D9E9A0028D27C /* strchr.c */,
C9B53D20138D9E9A0028D27C /* strcmp.3 */,
- C9B53D22138D9E9A0028D27C /* strcmp.c */,
C9B53D24138D9E9A0028D27C /* strcoll.3 */,
C9B53D26138D9E9A0028D27C /* strcoll.c */,
C9B53D28138D9E9A0028D27C /* strcpy.3 */,
C9B53D3C138D9E9A0028D27C /* strlen.c */,
C9B53D3E138D9E9A0028D27C /* strmode.3 */,
C9B53D40138D9E9A0028D27C /* strmode.c */,
- C9B53D42138D9E9A0028D27C /* strncmp.c */,
C9B53D44138D9E9A0028D27C /* strndup.c */,
C9B53D45138D9E9A0028D27C /* strnlen.c */,
C9B53D46138D9E9A0028D27C /* strnstr.c */,
C9B53D47138D9E9A0028D27C /* strpbrk.3 */,
C9B53D49138D9E9A0028D27C /* strpbrk.c */,
- C9B53D4A138D9E9A0028D27C /* strrchr.3 */,
C9B53D4C138D9E9A0028D27C /* strrchr.c */,
C9B53D4E138D9E9A0028D27C /* strsep.3 */,
C9B53D4F138D9E9A0028D27C /* strsep.c */,
children = (
C9B53D94138D9E9A0028D27C /* __libc_init.c */,
C9B53D95138D9E9A0028D27C /* _libc_fork_child.c */,
- C9B53D96138D9E9A0028D27C /* atomic.3 */,
- C9B53D97138D9E9A0028D27C /* barrier.3 */,
- C9B53D98138D9E9A0028D27C /* cache.3 */,
C9B53D99138D9E9A0028D27C /* chmodx_np.c */,
- C9B53D9A138D9E9A0028D27C /* CLIB-LIST */,
- C9B53D9B138D9E9A0028D27C /* context-stubs.c */,
C9B53D9C138D9E9A0028D27C /* crt_externs.c */,
- C9B53D9D138D9E9A0028D27C /* errno.c */,
C9B53D9E138D9E9A0028D27C /* fork.c */,
C9B53D9F138D9E9A0028D27C /* getgroups.c */,
- C9B53DA0138D9E9A0028D27C /* getiopolicy_np.3 */,
- C9B53DA1138D9E9A0028D27C /* getiopolicy_np.c */,
C9B53DA2138D9E9A0028D27C /* gettimeofday.c */,
- C9B53DA4138D9E9A0028D27C /* MISSING-MANPAGE */,
- C9B53DA5138D9E9A0028D27C /* MISSING_SYSCALLS */,
C9B53DA6138D9E9A0028D27C /* msgctl.c */,
C9B53DA7138D9E9A0028D27C /* nanosleep.2 */,
C9B53DA8138D9E9A0028D27C /* OpenBSD */,
C9B53DAC138D9E9A0028D27C /* OSMemoryNotification.c */,
C9B53DAD138D9E9A0028D27C /* OSThermalNotification.c */,
C9B53DAE138D9E9A0028D27C /* posix_spawn.c */,
- C9B53DAF138D9E9A0028D27C /* pthread_kill.2 */,
- C9B53DB0138D9E9A0028D27C /* pthread_sigmask.2 */,
- C9B53DB1138D9E9A0028D27C /* REQUIRED-MACROS */,
C9B53DB2138D9E9A0028D27C /* semctl.c */,
C9B53DB3138D9E9A0028D27C /* settimeofday.c */,
C9B53DB4138D9E9A0028D27C /* shmctl.c */,
C9B53DB5138D9E9A0028D27C /* sigaction.c */,
- C9B53DB6138D9E9A0028D27C /* sigcatch.c */,
- C9B53DB7138D9E9A0028D27C /* sigcatch.h */,
- C9B53DB8138D9E9A0028D27C /* sigtramp.c */,
C9B53DB9138D9E9A0028D27C /* sigwait.2 */,
- C9B53DBA138D9E9A0028D27C /* slot_name.c */,
- C9B53DBB138D9E9A0028D27C /* spinlock.3 */,
C9B53DBC138D9E9A0028D27C /* statx_np.c */,
- C9B53DBD138D9E9A0028D27C /* SYSCALL-LIST */,
C9B53DBE138D9E9A0028D27C /* umaskx_np.c */,
);
path = sys;
path = OpenBSD;
sourceTree = "<group>";
};
- C9B53DBF138D9E9A0028D27C /* threads */ = {
- isa = PBXGroup;
- children = (
- C9B53DC0138D9E9A0028D27C /* cprocs.c */,
- C9B53DC1138D9E9A0028D27C /* cthread_internals.h */,
- C9B53DC2138D9E9A0028D27C /* cthreads.c */,
- C9B53DC3138D9E9A0028D27C /* cthreads.h */,
- C9B53DC5138D9E9A0028D27C /* mig_support.c */,
- );
- path = threads;
- sourceTree = "<group>";
- };
C9B53DC6138D9E9A0028D27C /* util */ = {
isa = PBXGroup;
children = (
isa = PBXGroup;
children = (
C9B53DF0138D9E9A0028D27C /* gen */,
- C9B53DFC138D9E9A0028D27C /* pthreads */,
C9B53E07138D9E9A0028D27C /* string */,
- C9B53E1D138D9E9A0028D27C /* sys */,
);
path = x86_64;
sourceTree = "<group>";
C9B53DF0138D9E9A0028D27C /* gen */ = {
isa = PBXGroup;
children = (
- C9B53DF1138D9E9A0028D27C /* _ctx_start.S */,
- C9B53DF2138D9E9A0028D27C /* _setcontext.S */,
- C9B53DF3138D9E9A0028D27C /* cpu_number.s */,
- C9B53DF4138D9E9A0028D27C /* getcontext.S */,
- C9B53DF5138D9E9A0028D27C /* getmcontext.c */,
- C9B53DF6138D9E9A0028D27C /* icacheinval.s */,
- C9B53DF7138D9E9A0028D27C /* makecontext.c */,
C9B53DF9138D9E9A0028D27C /* mcount.s */,
- C9B53DFA138D9E9A0028D27C /* setcontext.c */,
- C9EB3555138F7F6A0075BB52 /* setjmperr.c */,
- C9B53DFB138D9E9A0028D27C /* swapcontext.c */,
);
path = gen;
sourceTree = "<group>";
};
- C9B53DFC138D9E9A0028D27C /* pthreads */ = {
- isa = PBXGroup;
- children = (
- C9B53DFE138D9E9A0028D27C /* preempt.s */,
- C9B53DFF138D9E9A0028D27C /* pthread_getspecific.s */,
- C9B53E00138D9E9A0028D27C /* pthread_mutex_lock.s */,
- C9B53E01138D9E9A0028D27C /* pthread_self.s */,
- C9B53E02138D9E9A0028D27C /* pthread_set_self.s */,
- C9B53E03138D9E9A0028D27C /* start_wqthread.s */,
- C9B53E04138D9E9A0028D27C /* thread_start.s */,
- );
- path = pthreads;
- sourceTree = "<group>";
- };
C9B53E07138D9E9A0028D27C /* string */ = {
isa = PBXGroup;
children = (
- C9B53E08138D9E9A0028D27C /* __bzero.s */,
- C9B53E09138D9E9A0028D27C /* bcopy.c */,
- C9B53E0A138D9E9A0028D27C /* bcopy_sse3x.s */,
- C9B53E0B138D9E9A0028D27C /* bcopy_sse42.s */,
- C9B53E0C138D9E9A0028D27C /* bzero.c */,
- C9B53E0D138D9E9A0028D27C /* bzero_sse2.s */,
- C9B53E0E138D9E9A0028D27C /* bzero_sse42.s */,
- C9B53E0F138D9E9A0028D27C /* ffs.s */,
- C9B53E10138D9E9A0028D27C /* longcopy_sse3x.s */,
- C9B53E12138D9E9A0028D27C /* memcmp.s */,
- C9B53E13138D9E9A0028D27C /* memcpy.c */,
- C9B53E14138D9E9A0028D27C /* memmove.c */,
- C9B53E15138D9E9A0028D27C /* memset.s */,
- C9B53E16138D9E9A0028D27C /* strcmp.s */,
C9B53E17138D9E9A0028D27C /* strcpy.s */,
- C9B53E18138D9E9A0028D27C /* strlcat.s */,
- C9B53E19138D9E9A0028D27C /* strlcpy.s */,
C9B53E1A138D9E9A0028D27C /* strlen.s */,
- C9B53E1B138D9E9A0028D27C /* strncmp.s */,
C9B53E1C138D9E9A0028D27C /* strncpy.s */,
+ 639D126615595DDE00D0403A /* strnlen.s */,
);
path = string;
sourceTree = "<group>";
};
- C9B53E1D138D9E9A0028D27C /* sys */ = {
- isa = PBXGroup;
- children = (
- C9B53E1E138D9E9A0028D27C /* _setjmp.s */,
- C9B53E1F138D9E9A0028D27C /* _sigtramp.s */,
- C9B53E20138D9E9A0028D27C /* atomic.c */,
- C9B53E21138D9E9A0028D27C /* i386_gettimeofday_asm.s */,
- C9B53E23138D9E9A0028D27C /* nanotime.s */,
- C9B53E24138D9E9A0028D27C /* OSAtomic.s */,
- C9B53E25138D9E9A0028D27C /* setjmp.s */,
- C9B53E26138D9E9A0028D27C /* spinlocks.c */,
- C9B53E27138D9E9A0028D27C /* spinlocks_asm.s */,
- );
- path = sys;
- sourceTree = "<group>";
- };
C9C2A946138DF66900287F00 /* xcodescripts */ = {
isa = PBXGroup;
children = (
C9C2A948138DF7DD00287F00 /* libc.xcconfig */,
C9766153138ECF0000741512 /* variants.xcconfig */,
+ C9AE91AE1517CDAC00A2626C /* eos.xcconfig */,
C9194B4C140E3BC700BE0C3A /* build_linklists.sh */,
C9766150138EC9D400741512 /* patch_headers_variants.pl */,
C976616B138EF14100741512 /* generate_features.pl */,
- C94212DD13900FC3004BA536 /* mig_headers.sh */,
C942135913904CBC004BA536 /* manpages.sh */,
C9950E6A1390D2CA009863B6 /* headers.sh */,
C9B53D92138D9E9A0028D27C /* strip-header.ed */,
path = xcodescripts;
sourceTree = "<group>";
};
+ FC60BAD016555A4A00033196 /* _types */ = {
+ isa = PBXGroup;
+ children = (
+ FC60BAD116555A4A00033196 /* _intmax_t.h */,
+ FC60BAD216555A4A00033196 /* _nl_item.h */,
+ FC60BAD316555A4A00033196 /* _uint16_t.h */,
+ FC60BAD416555A4A00033196 /* _uint32_t.h */,
+ FC60BAD516555A4A00033196 /* _uint64_t.h */,
+ FC60BAD616555A4A00033196 /* _uint8_t.h */,
+ FC60BAD716555A4A00033196 /* _uintmax_t.h */,
+ FC60BAD816555A4A00033196 /* _wctrans_t.h */,
+ FC60BAD916555A4A00033196 /* _wctype_t.h */,
+ );
+ path = _types;
+ sourceTree = "<group>";
+ };
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
- B122F0E71432B8E600AF95D0 /* TRE */ = {
+ 3F51206A16C3174300AFB431 /* FortifySource */ = {
isa = PBXNativeTarget;
- buildConfigurationList = B122F2AA1432B8E600AF95D0 /* Build configuration list for PBXNativeTarget "TRE" */;
+ buildConfigurationList = 3F5120EE16C3174300AFB431 /* Build configuration list for PBXNativeTarget "FortifySource" */;
buildPhases = (
- B122F0E81432B8E600AF95D0 /* Generate libc-features.h */,
- B122F0E91432B8E600AF95D0 /* Sources */,
- B122F2A91432B8E600AF95D0 /* Frameworks */,
+ 3F51206B16C3174300AFB431 /* Generate libc-features.h */,
+ 3F51206C16C3174300AFB431 /* Sources */,
+ 3F5120ED16C3174300AFB431 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
- name = TRE;
- productName = FreeBSD;
- productReference = B122F2AD1432B8E600AF95D0 /* libTRE.a */;
+ name = FortifySource;
+ productName = Base;
+ productReference = 3F5120F116C3174300AFB431 /* libFortifySource.a */;
productType = "com.apple.product-type.library.static";
};
- B1E96340157E722200FCCEE7 /* FreeBSD_gcc */ = {
+ B122F0E71432B8E600AF95D0 /* TRE */ = {
isa = PBXNativeTarget;
- buildConfigurationList = B1E96503157E722200FCCEE7 /* Build configuration list for PBXNativeTarget "FreeBSD_gcc" */;
+ buildConfigurationList = B122F2AA1432B8E600AF95D0 /* Build configuration list for PBXNativeTarget "TRE" */;
buildPhases = (
- B1E96341157E722200FCCEE7 /* Generate libc-features.h */,
- B1E96342157E722200FCCEE7 /* Sources */,
- B1E96502157E722200FCCEE7 /* Frameworks */,
+ B122F0E81432B8E600AF95D0 /* Generate libc-features.h */,
+ B122F0E91432B8E600AF95D0 /* Sources */,
+ B122F2A91432B8E600AF95D0 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
- name = FreeBSD_gcc;
+ name = TRE;
productName = FreeBSD;
- productReference = B1E96506157E722200FCCEE7 /* libFreeBSD_gcc.a */;
+ productReference = B122F2AD1432B8E600AF95D0 /* libTRE.a */;
productType = "com.apple.product-type.library.static";
};
C9257ECF138E1B5000B3107C /* FreeBSD */ = {
buildConfigurationList = C94212C913900C8A004BA536 /* Build configuration list for PBXNativeTarget "libc.a" */;
buildPhases = (
C942102E13900C8A004BA536 /* Generate libc-features.h */,
- C94212DC13900FAA004BA536 /* Compile MIG Headers */,
- C942102F13900C8A004BA536 /* Generate dtrace headers */,
C942103013900C8A004BA536 /* Patch Headers */,
C942103113900C8A004BA536 /* Sources */,
C94212C713900C8A004BA536 /* Frameworks */,
productReference = C95B86C7138F53DB004311DA /* libvPre1050.a */;
productType = "com.apple.product-type.library.static";
};
+ C97A6F1E1517AF53005E1998 /* libc_eOS.a */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = C97A72191517AF53005E1998 /* Build configuration list for PBXNativeTarget "libc_eOS.a" */;
+ buildPhases = (
+ C9AE91C21517E17600A2626C /* Build Link List */,
+ C97A6F1F1517AF53005E1998 /* Generate libc-features.h */,
+ C97A6F221517AF53005E1998 /* Patch Headers */,
+ C97A6F231517AF53005E1998 /* Sources */,
+ C97A72181517AF53005E1998 /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ C9AE91BB1517D33100A2626C /* PBXTargetDependency */,
+ C9AE91BD1517D33100A2626C /* PBXTargetDependency */,
+ C9AE91BF1517D33100A2626C /* PBXTargetDependency */,
+ C9AE91C11517D33100A2626C /* PBXTargetDependency */,
+ C925D2011518FA5D003D315B /* PBXTargetDependency */,
+ );
+ name = libc_eOS.a;
+ productName = "Variant Cancelable";
+ productReference = C97A721C1517AF53005E1998 /* libc_eOS.a */;
+ productType = "com.apple.product-type.library.static";
+ };
C9B53E2B138DA0610028D27C /* Platform */ = {
isa = PBXNativeTarget;
buildConfigurationList = C9B53E2D138DA0610028D27C /* Build configuration list for PBXNativeTarget "Platform" */;
buildConfigurationList = C9C2A94E138DFFDA00287F00 /* Build configuration list for PBXNativeTarget "Base" */;
buildPhases = (
C9BD3C3E138F18B200B389FD /* Generate libc-features.h */,
- C91875E313FC6433001F2604 /* Compile MIG Headers */,
- C9258127138E3EC800B3107C /* Generate dtrace headers */,
C9C2A949138DFFD900287F00 /* Sources */,
C9C2A94A138DFFD900287F00 /* Frameworks */,
);
dependencies = (
C9FA32C8138E41800089A94B /* PBXTargetDependency */,
C9FA32CA138E41800089A94B /* PBXTargetDependency */,
- B1E96509157E749200FCCEE7 /* PBXTargetDependency */,
C9FA32CC138E41800089A94B /* PBXTargetDependency */,
B122F2D91432BA8700AF95D0 /* PBXTargetDependency */,
C9D94335138DB75F00FB7ACC /* PBXTargetDependency */,
C95B86CC138F546E004311DA /* PBXTargetDependency */,
C9EB326D138F74D20075BB52 /* PBXTargetDependency */,
C9EB3515138F771F0075BB52 /* PBXTargetDependency */,
+ 3F51211716C318EB00AFB431 /* PBXTargetDependency */,
C942130913901709004BA536 /* PBXTargetDependency */,
+ C925D2031518FEBE003D315B /* PBXTargetDependency */,
);
name = libsystem_c.dylib;
productName = Libc;
buildConfigurationList = C9EB3263138F6D880075BB52 /* Build configuration list for PBXNativeTarget "Variant_Legacy" */;
buildPhases = (
C9EB2FCA138F6D880075BB52 /* Generate libc-features.h */,
- C9EB326B138F74600075BB52 /* Generate dtrace headers */,
C9EB2FCB138F6D880075BB52 /* Patch Headers */,
C9EB2FCC138F6D880075BB52 /* Sources */,
C9EB3261138F6D880075BB52 /* Frameworks */,
buildConfigurationList = C9EB350A138F75580075BB52 /* Build configuration list for PBXNativeTarget "Variant_Inode32" */;
buildPhases = (
C9EB3270138F75580075BB52 /* Generate libc-features.h */,
- C9EB3271138F75580075BB52 /* Generate dtrace headers */,
C9EB3272138F75580075BB52 /* Patch Headers */,
C9EB3273138F75580075BB52 /* Sources */,
C9EB3508138F75580075BB52 /* Frameworks */,
C9B53597138D9A690028D27C /* Project object */ = {
isa = PBXProject;
attributes = {
- LastUpgradeCheck = 0430;
+ LastUpgradeCheck = 0460;
};
buildConfigurationList = C9B5359A138D9A690028D27C /* Build configuration list for PBXProject "Libc" */;
compatibilityVersion = "Xcode 3.2";
targets = (
C9D9432E138DB73300FB7ACC /* libsystem_c.dylib */,
C942102D13900C8A004BA536 /* libc.a */,
+ C97A6F1E1517AF53005E1998 /* libc_eOS.a */,
C9B53E2B138DA0610028D27C /* Platform */,
C9C2A94C138DFFD900287F00 /* Base */,
C9257ECF138E1B5000B3107C /* FreeBSD */,
- B1E96340157E722200FCCEE7 /* FreeBSD_gcc */,
C9258093138E2D3100B3107C /* NetBSD */,
B122F0E71432B8E600AF95D0 /* TRE */,
C9D9435F138EC3E300FB7ACC /* Variant_Cancelable */,
C95B842A138F53DB004311DA /* Variant_Pre1050 */,
C9EB2FC9138F6D880075BB52 /* Variant_Legacy */,
C9EB326F138F75580075BB52 /* Variant_Inode32 */,
+ 3F51206A16C3174300AFB431 /* FortifySource */,
);
};
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
- B122F0E81432B8E600AF95D0 /* Generate libc-features.h */ = {
+ 3F51206B16C3174300AFB431 /* Generate libc-features.h */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl";
showEnvVarsInLog = 0;
};
- B1E96341157E722200FCCEE7 /* Generate libc-features.h */ = {
+ B122F0E81432B8E600AF95D0 /* Generate libc-features.h */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl";
showEnvVarsInLog = 0;
};
- C91875E313FC6433001F2604 /* Compile MIG Headers */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "$(SRCROOT)/gen/asl_ipc.defs",
- "$(SRCROOT)/xcodescripts/mig_headers.sh",
- );
- name = "Compile MIG Headers";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = "/bin/bash -e";
- shellScript = ". \"${SCRIPT_INPUT_FILE_1}\"";
- showEnvVarsInLog = 0;
- };
C9194B4B140E3A7100BE0C3A /* Build Link Lists */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
shellPath = /bin/bash;
shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"";
};
- C9258127138E3EC800B3107C /* Generate dtrace headers */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "$(SRCROOT)/gen/magmallocProvider.d",
- "$(SRCROOT)/pthreads/plockstat.d",
- );
- name = "Generate dtrace headers";
- outputPaths = (
- "$(DERIVED_FILE_DIR)/dtrace/magmallocProvider.h",
- "$(DERIVED_FILE_DIR)/dtrace/plockstat.h",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/bash;
- shellScript = "dtrace -h -C -s ${SCRIPT_INPUT_FILE_0} -o ${SCRIPT_OUTPUT_FILE_0}\ndtrace -h -C -s ${SCRIPT_INPUT_FILE_1} -o ${SCRIPT_OUTPUT_FILE_1}";
- showEnvVarsInLog = 0;
- };
C9265D1313B1CFD10090BA1C /* Clean Simulator Binaries */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl";
showEnvVarsInLog = 0;
};
- C942102F13900C8A004BA536 /* Generate dtrace headers */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "$(SRCROOT)/pthreads/plockstat.d",
- );
- name = "Generate dtrace headers";
- outputPaths = (
- "$(DERIVED_FILE_DIR)/dtrace/plockstat.h",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/bash;
- shellScript = "dtrace -h -C -s ${SCRIPT_INPUT_FILE_0} -o ${SCRIPT_OUTPUT_FILE_0}\n";
- showEnvVarsInLog = 0;
- };
C942103013900C8A004BA536 /* Patch Headers */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
showEnvVarsInLog = 0;
};
- C94212DC13900FAA004BA536 /* Compile MIG Headers */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "$(SRCROOT)/gen/asl_ipc.defs",
- "$(SRCROOT)/xcodescripts/mig_headers.sh",
- );
- name = "Compile MIG Headers";
- outputPaths = (
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = "/bin/bash -e";
- shellScript = ". \"${SCRIPT_INPUT_FILE_1}\"";
- showEnvVarsInLog = 0;
- };
C942135B13905EB9004BA536 /* Install Manpages */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl";
showEnvVarsInLog = 0;
};
+ C97A6F1F1517AF53005E1998 /* Generate libc-features.h */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Generate libc-features.h";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl";
+ showEnvVarsInLog = 0;
+ };
+ C97A6F221517AF53005E1998 /* Patch Headers */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Patch Headers";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
+ showEnvVarsInLog = 0;
+ };
C9950E6B1390D2DC009863B6 /* Install Headers */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"";
showEnvVarsInLog = 0;
};
+ C9AE91C21517E17600A2626C /* Build Link List */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "$(SRCROOT)/xcodescripts/build_linklists.sh",
+ );
+ name = "Build Link List";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = ". \"${SCRIPT_INPUT_FILE_0}\"";
+ };
C9BD3C3C138F189200B389FD /* Generate libc-features.h */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
shellScript = "perl ${SRCROOT}/xcodescripts/patch_headers_variants.pl \\\n \"${SDKROOT}/System/Library/Frameworks/System.framework/Versions/B/PrivateHeaders\" \\\n \"${DERIVED_FILES_DIR}/System.framework/Versions/B\"";
showEnvVarsInLog = 0;
};
- C9EB326B138F74600075BB52 /* Generate dtrace headers */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "$(SRCROOT)/pthreads/plockstat.d",
- );
- name = "Generate dtrace headers";
- outputPaths = (
- "$(DERIVED_FILE_DIR)/dtrace/plockstat.h",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/bash;
- shellScript = "dtrace -h -C -s ${SCRIPT_INPUT_FILE_0} -o ${SCRIPT_OUTPUT_FILE_0}\n";
- showEnvVarsInLog = 0;
- };
C9EB3270138F75580075BB52 /* Generate libc-features.h */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
shellScript = "perl $SRCROOT/xcodescripts/generate_features.pl";
showEnvVarsInLog = 0;
};
- C9EB3271138F75580075BB52 /* Generate dtrace headers */ = {
- isa = PBXShellScriptBuildPhase;
- buildActionMask = 2147483647;
- files = (
- );
- inputPaths = (
- "$(SRCROOT)/pthreads/plockstat.d",
- );
- name = "Generate dtrace headers";
- outputPaths = (
- "$(DERIVED_FILE_DIR)/dtrace/plockstat.h",
- );
- runOnlyForDeploymentPostprocessing = 0;
- shellPath = /bin/bash;
- shellScript = "dtrace -h -C -s ${SCRIPT_INPUT_FILE_0} -o ${SCRIPT_OUTPUT_FILE_0}\n";
- showEnvVarsInLog = 0;
- };
C9EB3272138F75580075BB52 /* Patch Headers */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
+ 3F51206C16C3174300AFB431 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 3F51210F16C317FD00AFB431 /* strlcat_chk.c in Sources */,
+ 3F51210416C317FD00AFB431 /* chk_fail.c in Sources */,
+ 3F51210816C317FD00AFB431 /* memset_chk.c in Sources */,
+ 3F51211016C317FD00AFB431 /* strlcpy_chk.c in Sources */,
+ 3F51211116C317FD00AFB431 /* strncat_chk.c in Sources */,
+ 3F51211216C317FD00AFB431 /* strncpy_chk.c in Sources */,
+ 3F51210716C317FD00AFB431 /* memmove_chk.c in Sources */,
+ 3F51210E16C317FD00AFB431 /* strcpy_chk.c in Sources */,
+ 3F51210516C317FD00AFB431 /* memccpy_chk.c in Sources */,
+ 3F51210916C317FD00AFB431 /* snprintf_chk.c in Sources */,
+ 3F51210D16C317FD00AFB431 /* strcat_chk.c in Sources */,
+ 3F51211416C317FD00AFB431 /* vsprintf_chk.c in Sources */,
+ 3F51210B16C317FD00AFB431 /* stpcpy_chk.c in Sources */,
+ 3F51210A16C317FD00AFB431 /* sprintf_chk.c in Sources */,
+ 3F51210616C317FD00AFB431 /* memcpy_chk.c in Sources */,
+ 3F51210C16C317FD00AFB431 /* stpncpy_chk.c in Sources */,
+ 3F51211316C317FD00AFB431 /* vsnprintf_chk.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
B122F0E91432B8E600AF95D0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
);
runOnlyForDeploymentPostprocessing = 0;
};
- B1E96342157E722200FCCEE7 /* Sources */ = {
- isa = PBXSourcesBuildPhase;
- buildActionMask = 2147483647;
- files = (
- B1E96442157E722200FCCEE7 /* printf-pos.c in Sources */,
- B1E9645F157E722200FCCEE7 /* vfprintf.c in Sources */,
- B1E96461157E722200FCCEE7 /* vfwprintf.c in Sources */,
- );
- runOnlyForDeploymentPostprocessing = 0;
- };
C9257ECC138E1B5000B3107C /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
C9257FD4138E1CC000B3107C /* makebuf.c in Sources */,
C9257FD5138E1CC000B3107C /* mktemp.c in Sources */,
C9257FD6138E1CC000B3107C /* perror.c in Sources */,
+ C9257FD7138E1CC000B3107C /* printf-pos.c in Sources */,
C9257FD8138E1CC000B3107C /* printf.c in Sources */,
C9257FD9138E1CC000B3107C /* putc.c in Sources */,
C9257FDA138E1CC000B3107C /* putchar.c in Sources */,
C9257FF1138E1CC000B3107C /* ungetwc.c in Sources */,
C9257FF2138E1CC000B3107C /* vasprintf.c in Sources */,
C9257FF3138E1CC000B3107C /* vdprintf.c in Sources */,
+ C9257FF4138E1CC000B3107C /* vfprintf.c in Sources */,
C9257FF5138E1CC000B3107C /* vfscanf.c in Sources */,
+ C9257FF6138E1CC000B3107C /* vfwprintf.c in Sources */,
C9257FF7138E1CC000B3107C /* vfwscanf.c in Sources */,
C9257FF8138E1CC000B3107C /* vprintf.c in Sources */,
C9257FF9138E1CC000B3107C /* vscanf.c in Sources */,
C925800A138E1CC000B3107C /* strptime.c in Sources */,
C925800B138E1CC000B3107C /* time32.c in Sources */,
C925800C138E1CC000B3107C /* timelocal.c in Sources */,
- C925800D138E1CD200B3107C /* bcmp.c in Sources */,
- C925800E138E1CD200B3107C /* bcopy.c in Sources */,
- C925800F138E1CD200B3107C /* bzero.c in Sources */,
C9258010138E1CD200B3107C /* index.c in Sources */,
- C9258011138E1CD200B3107C /* memccpy.c in Sources */,
- C9258012138E1CD200B3107C /* memchr.c in Sources */,
- C9258013138E1CD200B3107C /* memcmp.c in Sources */,
- C9258014138E1CD200B3107C /* memcpy.c in Sources */,
C9258015138E1CD200B3107C /* memmem.c in Sources */,
- C9258016138E1CD200B3107C /* memmove.c in Sources */,
- C9258017138E1CD200B3107C /* memset.c in Sources */,
C9258018138E1CD200B3107C /* rindex.c in Sources */,
C925801B138E1CD200B3107C /* strcasecmp.c in Sources */,
C925801C138E1CD200B3107C /* strcasestr.c in Sources */,
- C925801E138E1CD200B3107C /* strchr.c in Sources */,
- C925801F138E1CD200B3107C /* strcmp.c in Sources */,
C9258020138E1CD200B3107C /* strcoll.c in Sources */,
C9258022138E1CD200B3107C /* strcspn.c in Sources */,
C9258023138E1CD200B3107C /* strdup.c in Sources */,
C9258024138E1CD200B3107C /* strerror.c in Sources */,
C9258027138E1CD200B3107C /* strlen.c in Sources */,
C9258028138E1CD200B3107C /* strmode.c in Sources */,
- C925802A138E1CD200B3107C /* strncmp.c in Sources */,
C925802C138E1CD200B3107C /* strndup.c in Sources */,
C925802D138E1CD200B3107C /* strnlen.c in Sources */,
C925802E138E1CD200B3107C /* strnstr.c in Sources */,
C9EB2FC8138F6CE10075BB52 /* psort_r.c in Sources */,
C9EB350F138F769B0075BB52 /* scandir_b.c in Sources */,
C9EB3550138F7EA50075BB52 /* getmntinfo64.c in Sources */,
+ FC2ED612157D4BE80098EC69 /* inet_ntop.c in Sources */,
+ FC2ED61B157D4BE80098EC69 /* inet_pton.c in Sources */,
+ B12613F8158818EC0077E3CC /* xprintf_errno.c in Sources */,
+ B12613F9158818EC0077E3CC /* xprintf_float.c in Sources */,
+ B12613FA158818EC0077E3CC /* xprintf_hexdump.c in Sources */,
+ B12613FB158818EC0077E3CC /* xprintf_int.c in Sources */,
+ B12613FC158818EC0077E3CC /* xprintf_quote.c in Sources */,
+ B12613FD158818EC0077E3CC /* xprintf_str.c in Sources */,
+ B12613FE158818EC0077E3CC /* xprintf_time.c in Sources */,
+ B12613FF158818EC0077E3CC /* xprintf_vis.c in Sources */,
+ B1261400158818EC0077E3CC /* xprintf.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
files = (
C92580CC138E2D3100B3107C /* utmpx.c in Sources */,
C9FA334D138E4D0C0089A94B /* strfmon.c in Sources */,
+ 3F18DE21162A732C008B15AC /* memset_s.c in Sources */,
+ 3F267F38163FC8880089A0A6 /* rb.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- C94213311390396E004BA536 /* _ctx_start.S in Sources */,
- C94213321390396E004BA536 /* _setcontext.S in Sources */,
- C94213331390396E004BA536 /* cpu_number.s in Sources */,
- C94213341390396E004BA536 /* getcontext.S in Sources */,
- C94213351390396E004BA536 /* icacheinval.s in Sources */,
C94213361390396E004BA536 /* mcount.s in Sources */,
- C94213371390396E004BA536 /* preempt.s in Sources */,
- C94213381390396E004BA536 /* pthread_getspecific.s in Sources */,
- C94213391390396E004BA536 /* pthread_mutex_lock.s in Sources */,
- C942133A1390396E004BA536 /* pthread_self.s in Sources */,
- C942133B1390396E004BA536 /* pthread_set_self.s in Sources */,
- C942133C1390396E004BA536 /* start_wqthread.s in Sources */,
- C942133D1390396E004BA536 /* thread_start.s in Sources */,
- C942133E1390396E004BA536 /* __bzero.s in Sources */,
- C942133F1390396E004BA536 /* bcopy_scalar.s in Sources */,
- C94213401390396E004BA536 /* bcopy_sse2.s in Sources */,
- C94213411390396E004BA536 /* bcopy_sse3x.s in Sources */,
- C94213421390396E004BA536 /* bcopy_sse42.s in Sources */,
- C94213431390396E004BA536 /* bzero_scalar.s in Sources */,
- C94213441390396E004BA536 /* bzero_sse2.s in Sources */,
- C94213451390396E004BA536 /* bzero_sse42.s in Sources */,
- C94213461390396E004BA536 /* ffs.s in Sources */,
- C94213471390396E004BA536 /* longcopy_sse3x.s in Sources */,
- C94213481390396E004BA536 /* memcmp.s in Sources */,
- C94213491390396E004BA536 /* memset.s in Sources */,
- C942134A1390396E004BA536 /* memset_pattern_sse2.s in Sources */,
- C942134B1390396E004BA536 /* strcmp.s in Sources */,
C942134C1390396E004BA536 /* strcpy.s in Sources */,
C942134D1390396E004BA536 /* strlcat.s in Sources */,
C942134E1390396E004BA536 /* strlcpy.s in Sources */,
C942134F1390396E004BA536 /* strlen.s in Sources */,
- C94213501390396E004BA536 /* strncmp.s in Sources */,
C94213511390396E004BA536 /* strncpy.s in Sources */,
- C94213521390396E004BA536 /* _setjmp.s in Sources */,
- C94213531390396E004BA536 /* _sigtramp.s in Sources */,
- C94213541390396E004BA536 /* i386_gettimeofday_asm.s in Sources */,
- C94213551390396E004BA536 /* mach_absolute_time_asm.s in Sources */,
- C94213561390396E004BA536 /* OSAtomic.s in Sources */,
- C94213571390396E004BA536 /* setjmp.s in Sources */,
- C94213581390396E004BA536 /* spinlocks_asm.s in Sources */,
- C942130A13903959004BA536 /* cpu_number.s in Sources */,
- C942130B13903959004BA536 /* icacheinval.s in Sources */,
- C942130C13903959004BA536 /* pthread_getspecific.s in Sources */,
- C942130D13903959004BA536 /* pthread_self.s in Sources */,
- C942130E13903959004BA536 /* pthread_set_self.s in Sources */,
- C942130F13903959004BA536 /* start_wqthread.s in Sources */,
- C942131013903959004BA536 /* thread_start.s in Sources */,
- C942131313903959004BA536 /* bcopy_Generic.s in Sources */,
- C942131613903959004BA536 /* bzero_Generic.s in Sources */,
- C942131713903959004BA536 /* ffs.s in Sources */,
- C942131813903959004BA536 /* memcmp.s in Sources */,
- C942131913903959004BA536 /* memset_pattern.s in Sources */,
- C942131A13903959004BA536 /* strchr.s in Sources */,
- C942131B13903959004BA536 /* strcmp.s in Sources */,
C942131E13903959004BA536 /* strlen.s in Sources */,
- C942131F13903959004BA536 /* strncmp.s in Sources */,
C942132113903959004BA536 /* strnlen.s in Sources */,
C942132213903959004BA536 /* strstr.s in Sources */,
- C942132313903959004BA536 /* _longjmp.s in Sources */,
- C942132413903959004BA536 /* _setjmp.h in Sources */,
- C942132513903959004BA536 /* _setjmp.s in Sources */,
- C942132613903959004BA536 /* longjmp.s in Sources */,
- C942132713903959004BA536 /* mach_absolute_time.s in Sources */,
- C942132913903959004BA536 /* OSAtomic_resolvers.h in Sources */,
- C942132A13903959004BA536 /* setjmp.s in Sources */,
- C94212DE13901595004BA536 /* _ctx_start.S in Sources */,
- C94212DF13901595004BA536 /* _setcontext.S in Sources */,
- C94212E013901595004BA536 /* cpu_number.s in Sources */,
- C94212E113901595004BA536 /* getcontext.S in Sources */,
- C94212E213901595004BA536 /* icacheinval.s in Sources */,
C94212E413901595004BA536 /* mcount.s in Sources */,
- C94212E513901595004BA536 /* setjmperr.c in Sources */,
- C94212E713901595004BA536 /* preempt.s in Sources */,
- C94212E813901595004BA536 /* pthread_getspecific.s in Sources */,
- C94212E913901595004BA536 /* pthread_mutex_lock.s in Sources */,
- C94212EA13901595004BA536 /* pthread_self.s in Sources */,
- C94212EB13901595004BA536 /* pthread_set_self.s in Sources */,
- C94212EC13901595004BA536 /* start_wqthread.s in Sources */,
- C94212ED13901595004BA536 /* thread_start.s in Sources */,
- C94212EF13901595004BA536 /* __bzero.s in Sources */,
- C94212F013901595004BA536 /* bcopy_sse3x.s in Sources */,
- C94212F113901595004BA536 /* bcopy_sse42.s in Sources */,
- C94212F213901595004BA536 /* bzero_sse2.s in Sources */,
- C94212F313901595004BA536 /* bzero_sse42.s in Sources */,
- C94212F413901595004BA536 /* ffs.s in Sources */,
- C94212F513901595004BA536 /* longcopy_sse3x.s in Sources */,
- C94212F713901595004BA536 /* memcmp.s in Sources */,
- C94212F813901595004BA536 /* memset.s in Sources */,
- C94212F913901595004BA536 /* strcmp.s in Sources */,
C94212FA13901595004BA536 /* strcpy.s in Sources */,
- C94212FB13901595004BA536 /* strlcat.s in Sources */,
- C94212FC13901595004BA536 /* strlcpy.s in Sources */,
C94212FD13901595004BA536 /* strlen.s in Sources */,
- C94212FE13901595004BA536 /* strncmp.s in Sources */,
C94212FF13901595004BA536 /* strncpy.s in Sources */,
- C942130013901595004BA536 /* _setjmp.s in Sources */,
- C942130113901595004BA536 /* _sigtramp.s in Sources */,
- C942130213901595004BA536 /* i386_gettimeofday_asm.s in Sources */,
- C942130413901595004BA536 /* nanotime.s in Sources */,
- C942130513901595004BA536 /* OSAtomic.s in Sources */,
- C942130613901595004BA536 /* setjmp.s in Sources */,
- C942130713901595004BA536 /* spinlocks_asm.s in Sources */,
C94212D113900ED1004BA536 /* dirhelper.defs in Sources */,
- C94212D213900ED1004BA536 /* asl_ipc.defs in Sources */,
C942103213900C8A004BA536 /* init_cpu_capabilities.c in Sources */,
- C942103313900C8A004BA536 /* dyld_resolvers.c in Sources */,
- C942103413900C8A004BA536 /* arm_commpage_gettimeofday.c in Sources */,
- C942103513900C8A004BA536 /* gcc_atomic.c in Sources */,
- C942103613900C8A004BA536 /* OSAtomic-v4.c in Sources */,
- C942103713900C8A004BA536 /* OSAtomic_resolvers.c in Sources */,
C942103913900C8A004BA536 /* creat.c in Sources */,
C942103A13900C8A004BA536 /* gethostid.c in Sources */,
C942103B13900C8A004BA536 /* getwd.c in Sources */,
C942104413900C8A004BA536 /* sigcompat.c in Sources */,
C942104513900C8A004BA536 /* _dirhelper.c in Sources */,
C942104613900C8A004BA536 /* kvm.c in Sources */,
- C942104713900C8A004BA536 /* libproc.c in Sources */,
- C942104813900C8A004BA536 /* MKGetTimeBaseInfo.c in Sources */,
- C942104913900C8A004BA536 /* proc_listpidspath.c in Sources */,
C942104A13900C8A004BA536 /* forceLibcToBuild.c in Sources */,
C942104B13900C8A004BA536 /* bt_close.c in Sources */,
C942104C13900C8A004BA536 /* bt_conv.c in Sources */,
C942108713900C8A004BA536 /* machdep_ldisdd.c in Sources */,
C942108813900C8A004BA536 /* machdep_ldisQ.c in Sources */,
C942108913900C8A004BA536 /* machdep_ldisx.c in Sources */,
- C942108A13900C8A004BA536 /* _simple.c in Sources */,
- C942108B13900C8A004BA536 /* asl.c in Sources */,
- C942108C13900C8A004BA536 /* asl_core.c in Sources */,
- C942108D13900C8A004BA536 /* asl_file.c in Sources */,
- C942108E13900C8A004BA536 /* asl_legacy1.c in Sources */,
- C942108F13900C8A004BA536 /* asl_msg.c in Sources */,
- C942109013900C8A004BA536 /* asl_store.c in Sources */,
- C942109113900C8A004BA536 /* asl_util.c in Sources */,
- C942109213900C8A004BA536 /* assumes.c in Sources */,
C942109313900C8A004BA536 /* authentication.c in Sources */,
C942109413900C8A004BA536 /* backtrace.c in Sources */,
- C942109513900C8A004BA536 /* cache.c in Sources */,
C942109613900C8A004BA536 /* confstr.c in Sources */,
C942109713900C8A004BA536 /* crypt.c in Sources */,
C942109813900C8A004BA536 /* devname.c in Sources */,
C94210A313900C8A004BA536 /* ctermid.c in Sources */,
C94210A413900C8A004BA536 /* daemon.c in Sources */,
C94210A513900C8A004BA536 /* dirname.c in Sources */,
+ 3FD14574171D42B300B7BAF5 /* bcopy.c in Sources */,
C94210A613900C8A004BA536 /* drand48.c in Sources */,
C94210A713900C8A004BA536 /* erand48.c in Sources */,
C94210A813900C8A004BA536 /* err.c in Sources */,
C94210EC13900C8A004BA536 /* getttyent.c in Sources */,
C94210ED13900C8A004BA536 /* getusershell.c in Sources */,
C94210EE13900C8A004BA536 /* getvfsbyname.c in Sources */,
- C94210EF13900C8A004BA536 /* isinf.c in Sources */,
- C94210F013900C8A004BA536 /* isnan.c in Sources */,
- C94210F113900C8A004BA536 /* magazine_malloc.c in Sources */,
- C94210F213900C8A004BA536 /* malloc.c in Sources */,
C94210F313900C8A004BA536 /* nanosleep.c in Sources */,
C94210F413900C8A004BA536 /* utmpx.c in Sources */,
C94210F513900C8A004BA536 /* nftw.c in Sources */,
C94210F613900C8A004BA536 /* nlist.c in Sources */,
C94210F713900C8A004BA536 /* NSSystemDirectories.c in Sources */,
C94210F813900C8A004BA536 /* oldsyslog.c in Sources */,
- C94210F913900C8A004BA536 /* platfunc.c in Sources */,
- C94210FA13900C8A004BA536 /* scalable_malloc.c in Sources */,
C94210FB13900C8A004BA536 /* setlogin.c in Sources */,
C94210FC13900C8A004BA536 /* sigsetops.c in Sources */,
- C94210FD13900C8A004BA536 /* stack_logging.c in Sources */,
- C94210FE13900C8A004BA536 /* stack_logging_disk.c in Sources */,
C94210FF13900C8A004BA536 /* strtofflags.c in Sources */,
- C942110013900C8A004BA536 /* syslog.c in Sources */,
C942110113900C8A004BA536 /* thread_stack_pcs.c in Sources */,
C942110213900C8A004BA536 /* uname.c in Sources */,
C942110313900C8A004BA536 /* utmpx-darwin.c in Sources */,
C942110413900C8A004BA536 /* wordexp.c in Sources */,
C942110613900C8A004BA536 /* gmon.c in Sources */,
- C942110713900C8A004BA536 /* getmcontext.c in Sources */,
- C942110813900C8A004BA536 /* makecontext.c in Sources */,
- C942110913900C8A004BA536 /* setcontext.c in Sources */,
- C942110A13900C8A004BA536 /* setjmperr.c in Sources */,
- C942110B13900C8A004BA536 /* swapcontext.c in Sources */,
- C942110C13900C8A004BA536 /* init_cpu_capabilities.c in Sources */,
- C942110D13900C8A004BA536 /* bcopy.c in Sources */,
- C942110E13900C8A004BA536 /* bzero.c in Sources */,
- C942110F13900C8A004BA536 /* memcpy.c in Sources */,
- C942111013900C8A004BA536 /* memmove.c in Sources */,
- C942111113900C8A004BA536 /* atomic.c in Sources */,
- C942111313900C8A004BA536 /* spinlocks.c in Sources */,
C942112613900C8A004BA536 /* ascii.c in Sources */,
C942112713900C8A004BA536 /* big5.c in Sources */,
C942112813900C8A004BA536 /* btowc.c in Sources */,
C942117B13900C8A004BA536 /* acl_flag.c in Sources */,
C942117C13900C8A004BA536 /* acl_perm.c in Sources */,
C942117D13900C8A004BA536 /* acl_translate.c in Sources */,
- C942118613900C8A004BA536 /* mk_pthread_impl.c in Sources */,
- C942118713900C8A004BA536 /* pthread.c in Sources */,
- C942118813900C8A004BA536 /* pthread_cancelable.c in Sources */,
- C942118913900C8A004BA536 /* pthread_cond.c in Sources */,
- C942118A13900C8A004BA536 /* pthread_mutex.c in Sources */,
- C942118B13900C8A004BA536 /* pthread_rwlock.c in Sources */,
- C942118C13900C8A004BA536 /* pthread_tsd.c in Sources */,
- C942118D13900C8A004BA536 /* pthread_atfork_test.c in Sources */,
- C942118E13900C8A004BA536 /* thread_setup.c in Sources */,
C942119113900C8A004BA536 /* regerror.c in Sources */,
- C942119413900C8A004BA536 /* chk_fail.c in Sources */,
- C942119513900C8A004BA536 /* memcpy_chk.c in Sources */,
- C942119613900C8A004BA536 /* memmove_chk.c in Sources */,
- C942119713900C8A004BA536 /* memset_chk.c in Sources */,
- C942119813900C8A004BA536 /* snprintf_chk.c in Sources */,
- C942119913900C8A004BA536 /* sprintf_chk.c in Sources */,
- C942119A13900C8A004BA536 /* stpcpy_chk.c in Sources */,
- C942119B13900C8A004BA536 /* stpncpy_chk.c in Sources */,
- C942119C13900C8A004BA536 /* strcat_chk.c in Sources */,
- C942119D13900C8A004BA536 /* strcpy_chk.c in Sources */,
- C942119E13900C8A004BA536 /* strncat_chk.c in Sources */,
- C942119F13900C8A004BA536 /* strncpy_chk.c in Sources */,
- C94211A013900C8A004BA536 /* vsnprintf_chk.c in Sources */,
- C94211A113900C8A004BA536 /* vsprintf_chk.c in Sources */,
C94211A213900C8A004BA536 /* _flock_stub.c in Sources */,
C94211A313900C8A004BA536 /* asprintf.c in Sources */,
C94211A413900C8A004BA536 /* clrerr.c in Sources */,
C942124413900C8A004BA536 /* timelocal.c in Sources */,
C942124513900C8A004BA536 /* getdate.c in Sources */,
C942124613900C8A004BA536 /* timezone_unix03.c in Sources */,
- C942124713900C8A004BA536 /* bcmp.c in Sources */,
- C942124813900C8A004BA536 /* bcopy.c in Sources */,
- C942124913900C8A004BA536 /* bzero.c in Sources */,
C942124A13900C8A004BA536 /* index.c in Sources */,
- C942124B13900C8A004BA536 /* memccpy.c in Sources */,
- C942124C13900C8A004BA536 /* memchr.c in Sources */,
- C942124D13900C8A004BA536 /* memcmp.c in Sources */,
- C942124E13900C8A004BA536 /* memcpy.c in Sources */,
C942124F13900C8A004BA536 /* memmem.c in Sources */,
- C942125013900C8A004BA536 /* memmove.c in Sources */,
- C942125113900C8A004BA536 /* memset.c in Sources */,
C942125213900C8A004BA536 /* rindex.c in Sources */,
C942125513900C8A004BA536 /* strcasecmp.c in Sources */,
C942125613900C8A004BA536 /* strcasestr.c in Sources */,
- C942125813900C8A004BA536 /* strchr.c in Sources */,
- C942125913900C8A004BA536 /* strcmp.c in Sources */,
C942125A13900C8A004BA536 /* strcoll.c in Sources */,
C942125C13900C8A004BA536 /* strcspn.c in Sources */,
C942125D13900C8A004BA536 /* strdup.c in Sources */,
C942125E13900C8A004BA536 /* strerror.c in Sources */,
C942126113900C8A004BA536 /* strlen.c in Sources */,
C942126213900C8A004BA536 /* strmode.c in Sources */,
- C942126413900C8A004BA536 /* strncmp.c in Sources */,
C942126613900C8A004BA536 /* strndup.c in Sources */,
C942126713900C8A004BA536 /* strnlen.c in Sources */,
C942126813900C8A004BA536 /* strnstr.c in Sources */,
C942129013900C8A004BA536 /* __libc_init.c in Sources */,
C942129113900C8A004BA536 /* _libc_fork_child.c in Sources */,
C942129213900C8A004BA536 /* chmodx_np.c in Sources */,
- C942129313900C8A004BA536 /* context-stubs.c in Sources */,
C942129413900C8A004BA536 /* crt_externs.c in Sources */,
- C942129513900C8A004BA536 /* errno.c in Sources */,
C942129613900C8A004BA536 /* fork.c in Sources */,
C942129713900C8A004BA536 /* getgroups.c in Sources */,
- C942129813900C8A004BA536 /* getiopolicy_np.c in Sources */,
C942129913900C8A004BA536 /* gettimeofday.c in Sources */,
C942129A13900C8A004BA536 /* msgctl.c in Sources */,
C942129B13900C8A004BA536 /* stack_protector.c in Sources */,
C94212A113900C8A004BA536 /* settimeofday.c in Sources */,
C94212A213900C8A004BA536 /* shmctl.c in Sources */,
C94212A313900C8A004BA536 /* sigaction.c in Sources */,
- C94212A413900C8A004BA536 /* sigcatch.c in Sources */,
- C94212A513900C8A004BA536 /* sigtramp.c in Sources */,
- C94212A613900C8A004BA536 /* slot_name.c in Sources */,
C94212A713900C8A004BA536 /* statx_np.c in Sources */,
C94212A813900C8A004BA536 /* umaskx_np.c in Sources */,
- C94212A913900C8A004BA536 /* cprocs.c in Sources */,
- C94212AA13900C8A004BA536 /* cthreads.c in Sources */,
- C94212AB13900C8A004BA536 /* mig_support.c in Sources */,
C94212AC13900C8A004BA536 /* fparseln.c in Sources */,
C94212AD13900C8A004BA536 /* login.c in Sources */,
C94212AE13900C8A004BA536 /* login_tty.c in Sources */,
C94212B913900C8A004BA536 /* parse.c in Sources */,
C94212BA13900C8A004BA536 /* unpack.c in Sources */,
C94212BB13900C8A004BA536 /* unparse.c in Sources */,
- C94212BC13900C8A004BA536 /* getmcontext.c in Sources */,
- C94212BD13900C8A004BA536 /* makecontext.c in Sources */,
- C94212BE13900C8A004BA536 /* setcontext.c in Sources */,
- C94212BF13900C8A004BA536 /* swapcontext.c in Sources */,
- C94212C013900C8A004BA536 /* bcopy.c in Sources */,
- C94212C113900C8A004BA536 /* bzero.c in Sources */,
- C94212C213900C8A004BA536 /* memcpy.c in Sources */,
- C94212C313900C8A004BA536 /* memmove.c in Sources */,
- C94212C413900C8A004BA536 /* atomic.c in Sources */,
- C94212C513900C8A004BA536 /* spinlocks.c in Sources */,
C94212C613900C8A004BA536 /* scandir_b.c in Sources */,
- C932C2D313AB20C8004EDA12 /* OSAtomicUP.c in Sources */,
- C932C2D413AB20C8004EDA12 /* Spinlocks.c in Sources */,
- C932C2D513AB20C8004EDA12 /* SpinlocksUP.c in Sources */,
- C932C2D613AB20C8004EDA12 /* SpinlocksWFE.c in Sources */,
- C9B4E3DE13BBCE5F0008A9BB /* OSAtomic.c in Sources */,
+ C98E2B4C139851B7002A3ABB /* init_cpu_capabilities.c in Sources */,
+ C98E2B4D139851B7002A3ABB /* pthread_getspecific.s in Sources */,
+ C98E2B4E139851B7002A3ABB /* pthread_self.s in Sources */,
+ C98E2B4F139851B7002A3ABB /* pthread_set_self.s in Sources */,
+ C98E2B50139851B7002A3ABB /* start_wqthread.s in Sources */,
+ C98E2B51139851B7002A3ABB /* thread_start.s in Sources */,
6310518713D4D966004F7BA8 /* strcpy.c in Sources */,
6310518C13D4DABD004F7BA8 /* strlcpy.c in Sources */,
6310518F13D4DAEA004F7BA8 /* strncpy.c in Sources */,
63D4060D13DDF26A0094DD56 /* strcat.c in Sources */,
63D4061013DDF4340094DD56 /* strncat.c in Sources */,
63D4061313DDF6A30094DD56 /* strlcat.c in Sources */,
- 3F2208E814358B4A00386F5B /* asl_fd.c in Sources */,
B19C645C1450F90200032373 /* sync_volume_np.c in Sources */,
3FD4D48E1472F4B200075CCE /* dirfd.c in Sources */,
+ 63505E3B1548525D00B637D7 /* strnlen.s in Sources */,
+ 4B2C64A315519BC300342BFA /* assumes.c in Sources */,
+ FC2ED610157D4BE80098EC69 /* inet_ntop.c in Sources */,
+ FC2ED619157D4BE80098EC69 /* inet_pton.c in Sources */,
+ 639D126A15595DDE00D0403A /* strnlen.s in Sources */,
+ 2B9D61B8157D667600AF25B8 /* trace.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
buildActionMask = 2147483647;
files = (
C95B7EDD138F3C55004311DA /* init_cpu_capabilities.c in Sources */,
- C95B7EDE138F3C55004311DA /* dyld_resolvers.c in Sources */,
- C95B7EDF138F3C55004311DA /* arm_commpage_gettimeofday.c in Sources */,
- C95B7EE0138F3C55004311DA /* gcc_atomic.c in Sources */,
- C95B7EE1138F3C55004311DA /* OSAtomic-v4.c in Sources */,
- C95B7EE2138F3C55004311DA /* OSAtomic_resolvers.c in Sources */,
C95B7EE4138F3C55004311DA /* creat.c in Sources */,
C95B7EE5138F3C55004311DA /* gethostid.c in Sources */,
C95B7EE6138F3C55004311DA /* getwd.c in Sources */,
C95B7EEF138F3C55004311DA /* sigcompat.c in Sources */,
C95B7EF0138F3C55004311DA /* _dirhelper.c in Sources */,
C95B7EF1138F3C55004311DA /* kvm.c in Sources */,
- C95B7EF2138F3C55004311DA /* libproc.c in Sources */,
- C95B7EF3138F3C55004311DA /* MKGetTimeBaseInfo.c in Sources */,
- C95B7EF4138F3C55004311DA /* proc_listpidspath.c in Sources */,
C95B7EF5138F3C55004311DA /* forceLibcToBuild.c in Sources */,
C95B7EF6138F3C55004311DA /* bt_close.c in Sources */,
C95B7EF7138F3C55004311DA /* bt_conv.c in Sources */,
C95B7F32138F3C55004311DA /* machdep_ldisdd.c in Sources */,
C95B7F33138F3C55004311DA /* machdep_ldisQ.c in Sources */,
C95B7F34138F3C55004311DA /* machdep_ldisx.c in Sources */,
- C95B7F35138F3C55004311DA /* _simple.c in Sources */,
- C95B7F36138F3C55004311DA /* asl.c in Sources */,
- C95B7F37138F3C55004311DA /* asl_core.c in Sources */,
- C95B7F38138F3C55004311DA /* asl_file.c in Sources */,
- C95B7F39138F3C55004311DA /* asl_legacy1.c in Sources */,
- C95B7F3A138F3C55004311DA /* asl_msg.c in Sources */,
- C95B7F3B138F3C55004311DA /* asl_store.c in Sources */,
- C95B7F3C138F3C55004311DA /* asl_util.c in Sources */,
- C95B7F3D138F3C55004311DA /* assumes.c in Sources */,
C95B7F3E138F3C55004311DA /* authentication.c in Sources */,
C95B7F3F138F3C55004311DA /* backtrace.c in Sources */,
- C95B7F40138F3C55004311DA /* cache.c in Sources */,
C95B7F41138F3C55004311DA /* confstr.c in Sources */,
C95B7F42138F3C55004311DA /* crypt.c in Sources */,
C95B7F43138F3C55004311DA /* devname.c in Sources */,
C95B7F97138F3C55004311DA /* getttyent.c in Sources */,
C95B7F98138F3C55004311DA /* getusershell.c in Sources */,
C95B7F99138F3C55004311DA /* getvfsbyname.c in Sources */,
- C95B7F9A138F3C55004311DA /* isinf.c in Sources */,
- C95B7F9B138F3C55004311DA /* isnan.c in Sources */,
- C95B7F9C138F3C55004311DA /* magazine_malloc.c in Sources */,
- C95B7F9D138F3C55004311DA /* malloc.c in Sources */,
C95B7F9E138F3C55004311DA /* nanosleep.c in Sources */,
C95B7F9F138F3C55004311DA /* utmpx.c in Sources */,
C95B7FA0138F3C55004311DA /* nftw.c in Sources */,
C95B7FA1138F3C55004311DA /* nlist.c in Sources */,
C95B7FA2138F3C55004311DA /* NSSystemDirectories.c in Sources */,
C95B7FA3138F3C55004311DA /* oldsyslog.c in Sources */,
- C95B7FA4138F3C55004311DA /* platfunc.c in Sources */,
- C95B7FA5138F3C55004311DA /* scalable_malloc.c in Sources */,
C95B7FA6138F3C55004311DA /* setlogin.c in Sources */,
C95B7FA7138F3C55004311DA /* sigsetops.c in Sources */,
- C95B7FA8138F3C55004311DA /* stack_logging.c in Sources */,
- C95B7FA9138F3C55004311DA /* stack_logging_disk.c in Sources */,
C95B7FAA138F3C55004311DA /* strtofflags.c in Sources */,
- C95B7FAB138F3C55004311DA /* syslog.c in Sources */,
C95B7FAC138F3C55004311DA /* thread_stack_pcs.c in Sources */,
C95B7FAD138F3C55004311DA /* uname.c in Sources */,
C95B7FAE138F3C55004311DA /* utmpx-darwin.c in Sources */,
C95B7FAF138F3C55004311DA /* wordexp.c in Sources */,
C95B7FB1138F3C55004311DA /* gmon.c in Sources */,
- C95B7FB2138F3C55004311DA /* getmcontext.c in Sources */,
- C95B7FB3138F3C55004311DA /* makecontext.c in Sources */,
- C95B7FB4138F3C55004311DA /* setcontext.c in Sources */,
- C95B7FB5138F3C55004311DA /* setjmperr.c in Sources */,
- C95B7FB6138F3C55004311DA /* swapcontext.c in Sources */,
- C95B7FB7138F3C55004311DA /* init_cpu_capabilities.c in Sources */,
- C95B7FB8138F3C55004311DA /* bcopy.c in Sources */,
- C95B7FB9138F3C55004311DA /* bzero.c in Sources */,
- C95B7FBA138F3C55004311DA /* memcpy.c in Sources */,
- C95B7FBB138F3C55004311DA /* memmove.c in Sources */,
- C95B7FBC138F3C55004311DA /* atomic.c in Sources */,
- C95B7FBE138F3C55004311DA /* spinlocks.c in Sources */,
C95B7FD1138F3C55004311DA /* ascii.c in Sources */,
C95B7FD2138F3C55004311DA /* big5.c in Sources */,
C95B7FD3138F3C55004311DA /* btowc.c in Sources */,
C95B8026138F3C55004311DA /* acl_flag.c in Sources */,
C95B8027138F3C55004311DA /* acl_perm.c in Sources */,
C95B8028138F3C55004311DA /* acl_translate.c in Sources */,
- C95B8031138F3C55004311DA /* mk_pthread_impl.c in Sources */,
- C95B8032138F3C55004311DA /* pthread.c in Sources */,
- C95B8033138F3C55004311DA /* pthread_cancelable.c in Sources */,
- C95B8034138F3C55004311DA /* pthread_cond.c in Sources */,
- C95B8035138F3C55004311DA /* pthread_mutex.c in Sources */,
- C95B8036138F3C55004311DA /* pthread_rwlock.c in Sources */,
- C95B8037138F3C55004311DA /* pthread_tsd.c in Sources */,
- C95B8038138F3C55004311DA /* pthread_atfork_test.c in Sources */,
- C95B8039138F3C55004311DA /* thread_setup.c in Sources */,
C95B803C138F3C55004311DA /* regerror.c in Sources */,
- C95B803F138F3C55004311DA /* chk_fail.c in Sources */,
- C95B8040138F3C55004311DA /* memcpy_chk.c in Sources */,
- C95B8041138F3C55004311DA /* memmove_chk.c in Sources */,
- C95B8042138F3C55004311DA /* memset_chk.c in Sources */,
- C95B8043138F3C55004311DA /* snprintf_chk.c in Sources */,
- C95B8044138F3C55004311DA /* sprintf_chk.c in Sources */,
- C95B8045138F3C55004311DA /* stpcpy_chk.c in Sources */,
- C95B8046138F3C55004311DA /* stpncpy_chk.c in Sources */,
- C95B8047138F3C55004311DA /* strcat_chk.c in Sources */,
- C95B8048138F3C55004311DA /* strcpy_chk.c in Sources */,
- C95B8049138F3C55004311DA /* strncat_chk.c in Sources */,
- C95B804A138F3C55004311DA /* strncpy_chk.c in Sources */,
- C95B804B138F3C55004311DA /* vsnprintf_chk.c in Sources */,
- C95B804C138F3C55004311DA /* vsprintf_chk.c in Sources */,
C95B804D138F3C55004311DA /* _flock_stub.c in Sources */,
C95B804E138F3C55004311DA /* asprintf.c in Sources */,
C95B804F138F3C55004311DA /* clrerr.c in Sources */,
C95B80EF138F3C55004311DA /* timelocal.c in Sources */,
C95B80F0138F3C55004311DA /* getdate.c in Sources */,
C95B80F1138F3C55004311DA /* timezone_unix03.c in Sources */,
- C95B80F2138F3C55004311DA /* bcmp.c in Sources */,
- C95B80F3138F3C55004311DA /* bcopy.c in Sources */,
- C95B80F4138F3C55004311DA /* bzero.c in Sources */,
C95B80F5138F3C55004311DA /* index.c in Sources */,
- C95B80F6138F3C55004311DA /* memccpy.c in Sources */,
- C95B80F7138F3C55004311DA /* memchr.c in Sources */,
- C95B80F8138F3C55004311DA /* memcmp.c in Sources */,
- C95B80F9138F3C55004311DA /* memcpy.c in Sources */,
C95B80FA138F3C55004311DA /* memmem.c in Sources */,
- C95B80FB138F3C55004311DA /* memmove.c in Sources */,
- C95B80FC138F3C55004311DA /* memset.c in Sources */,
C95B80FD138F3C55004311DA /* rindex.c in Sources */,
C95B8100138F3C55004311DA /* strcasecmp.c in Sources */,
C95B8101138F3C55004311DA /* strcasestr.c in Sources */,
- C95B8103138F3C55004311DA /* strchr.c in Sources */,
- C95B8104138F3C55004311DA /* strcmp.c in Sources */,
C95B8105138F3C55004311DA /* strcoll.c in Sources */,
C95B8107138F3C55004311DA /* strcspn.c in Sources */,
C95B8108138F3C55004311DA /* strdup.c in Sources */,
C95B8109138F3C55004311DA /* strerror.c in Sources */,
C95B810C138F3C55004311DA /* strlen.c in Sources */,
C95B810D138F3C55004311DA /* strmode.c in Sources */,
- C95B810F138F3C55004311DA /* strncmp.c in Sources */,
C95B8111138F3C55004311DA /* strndup.c in Sources */,
C95B8112138F3C55004311DA /* strnlen.c in Sources */,
C95B8113138F3C55004311DA /* strnstr.c in Sources */,
C95B813B138F3C55004311DA /* __libc_init.c in Sources */,
C95B813C138F3C55004311DA /* _libc_fork_child.c in Sources */,
C95B813D138F3C55004311DA /* chmodx_np.c in Sources */,
- C95B813E138F3C55004311DA /* context-stubs.c in Sources */,
C95B813F138F3C55004311DA /* crt_externs.c in Sources */,
- C95B8140138F3C55004311DA /* errno.c in Sources */,
C95B8141138F3C55004311DA /* fork.c in Sources */,
C95B8142138F3C55004311DA /* getgroups.c in Sources */,
- C95B8143138F3C55004311DA /* getiopolicy_np.c in Sources */,
C95B8144138F3C55004311DA /* gettimeofday.c in Sources */,
C95B8145138F3C55004311DA /* msgctl.c in Sources */,
C95B8146138F3C55004311DA /* stack_protector.c in Sources */,
C95B814C138F3C55004311DA /* settimeofday.c in Sources */,
C95B814D138F3C55004311DA /* shmctl.c in Sources */,
C95B814E138F3C55004311DA /* sigaction.c in Sources */,
- C95B814F138F3C55004311DA /* sigcatch.c in Sources */,
- C95B8150138F3C55004311DA /* sigtramp.c in Sources */,
- C95B8151138F3C55004311DA /* slot_name.c in Sources */,
C95B8152138F3C55004311DA /* statx_np.c in Sources */,
C95B8153138F3C55004311DA /* umaskx_np.c in Sources */,
- C95B8154138F3C55004311DA /* cprocs.c in Sources */,
- C95B8155138F3C55004311DA /* cthreads.c in Sources */,
- C95B8156138F3C55004311DA /* mig_support.c in Sources */,
C95B8157138F3C55004311DA /* fparseln.c in Sources */,
C95B8158138F3C55004311DA /* login.c in Sources */,
C95B8159138F3C55004311DA /* login_tty.c in Sources */,
C95B8164138F3C55004311DA /* parse.c in Sources */,
C95B8165138F3C55004311DA /* unpack.c in Sources */,
C95B8166138F3C55004311DA /* unparse.c in Sources */,
- C95B8167138F3C55004311DA /* getmcontext.c in Sources */,
- C95B8168138F3C55004311DA /* makecontext.c in Sources */,
- C95B8169138F3C55004311DA /* setcontext.c in Sources */,
- C95B816A138F3C55004311DA /* swapcontext.c in Sources */,
- C95B816B138F3C55004311DA /* bcopy.c in Sources */,
- C95B816C138F3C55004311DA /* bzero.c in Sources */,
- C95B816D138F3C55004311DA /* memcpy.c in Sources */,
- C95B816E138F3C55004311DA /* memmove.c in Sources */,
- C95B816F138F3C55004311DA /* atomic.c in Sources */,
- C95B8170138F3C55004311DA /* spinlocks.c in Sources */,
- 3F2208EB14358B4A00386F5B /* asl_fd.c in Sources */,
B19C645F1450F90200032373 /* sync_volume_np.c in Sources */,
3FB7E1B7146EF2E000843438 /* dirfd.c in Sources */,
+ 4B2C64A615519BC600342BFA /* assumes.c in Sources */,
+ FC2ED614157D4BE80098EC69 /* inet_ntop.c in Sources */,
+ FC2ED61D157D4BE80098EC69 /* inet_pton.c in Sources */,
+ 2B9D61BB157D667900AF25B8 /* trace.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
buildActionMask = 2147483647;
files = (
C95B8188138F52B0004311DA /* init_cpu_capabilities.c in Sources */,
- C95B8189138F52B0004311DA /* dyld_resolvers.c in Sources */,
- C95B818A138F52B0004311DA /* arm_commpage_gettimeofday.c in Sources */,
- C95B818B138F52B0004311DA /* gcc_atomic.c in Sources */,
- C95B818C138F52B0004311DA /* OSAtomic-v4.c in Sources */,
- C95B818D138F52B0004311DA /* OSAtomic_resolvers.c in Sources */,
C95B818F138F52B0004311DA /* creat.c in Sources */,
C95B8190138F52B0004311DA /* gethostid.c in Sources */,
C95B8191138F52B0004311DA /* getwd.c in Sources */,
C95B819A138F52B0004311DA /* sigcompat.c in Sources */,
C95B819B138F52B0004311DA /* _dirhelper.c in Sources */,
C95B819C138F52B0004311DA /* kvm.c in Sources */,
- C95B819D138F52B0004311DA /* libproc.c in Sources */,
- C95B819E138F52B0004311DA /* MKGetTimeBaseInfo.c in Sources */,
- C95B819F138F52B0004311DA /* proc_listpidspath.c in Sources */,
C95B81A0138F52B0004311DA /* forceLibcToBuild.c in Sources */,
C95B81A1138F52B0004311DA /* bt_close.c in Sources */,
C95B81A2138F52B0004311DA /* bt_conv.c in Sources */,
C95B81DD138F52B0004311DA /* machdep_ldisdd.c in Sources */,
C95B81DE138F52B0004311DA /* machdep_ldisQ.c in Sources */,
C95B81DF138F52B0004311DA /* machdep_ldisx.c in Sources */,
- C95B81E0138F52B0004311DA /* _simple.c in Sources */,
- C95B81E1138F52B0004311DA /* asl.c in Sources */,
- C95B81E2138F52B0004311DA /* asl_core.c in Sources */,
- C95B81E3138F52B0004311DA /* asl_file.c in Sources */,
- C95B81E4138F52B0004311DA /* asl_legacy1.c in Sources */,
- C95B81E5138F52B0004311DA /* asl_msg.c in Sources */,
- C95B81E6138F52B0004311DA /* asl_store.c in Sources */,
- C95B81E7138F52B0004311DA /* asl_util.c in Sources */,
- C95B81E8138F52B0004311DA /* assumes.c in Sources */,
C95B81E9138F52B0004311DA /* authentication.c in Sources */,
C95B81EA138F52B0004311DA /* backtrace.c in Sources */,
- C95B81EB138F52B0004311DA /* cache.c in Sources */,
C95B81EC138F52B0004311DA /* confstr.c in Sources */,
C95B81ED138F52B0004311DA /* crypt.c in Sources */,
C95B81EE138F52B0004311DA /* devname.c in Sources */,
C95B8242138F52B0004311DA /* getttyent.c in Sources */,
C95B8243138F52B0004311DA /* getusershell.c in Sources */,
C95B8244138F52B0004311DA /* getvfsbyname.c in Sources */,
- C95B8245138F52B0004311DA /* isinf.c in Sources */,
- C95B8246138F52B0004311DA /* isnan.c in Sources */,
- C95B8247138F52B0004311DA /* magazine_malloc.c in Sources */,
- C95B8248138F52B0004311DA /* malloc.c in Sources */,
C95B8249138F52B0004311DA /* nanosleep.c in Sources */,
C95B824A138F52B0004311DA /* utmpx.c in Sources */,
C95B824B138F52B0004311DA /* nftw.c in Sources */,
C95B824C138F52B0004311DA /* nlist.c in Sources */,
C95B824D138F52B0004311DA /* NSSystemDirectories.c in Sources */,
C95B824E138F52B0004311DA /* oldsyslog.c in Sources */,
- C95B824F138F52B0004311DA /* platfunc.c in Sources */,
- C95B8250138F52B0004311DA /* scalable_malloc.c in Sources */,
C95B8251138F52B0004311DA /* setlogin.c in Sources */,
C95B8252138F52B0004311DA /* sigsetops.c in Sources */,
- C95B8253138F52B0004311DA /* stack_logging.c in Sources */,
- C95B8254138F52B0004311DA /* stack_logging_disk.c in Sources */,
C95B8255138F52B0004311DA /* strtofflags.c in Sources */,
- C95B8256138F52B0004311DA /* syslog.c in Sources */,
C95B8257138F52B0004311DA /* thread_stack_pcs.c in Sources */,
C95B8258138F52B0004311DA /* uname.c in Sources */,
C95B8259138F52B0004311DA /* utmpx-darwin.c in Sources */,
C95B825A138F52B0004311DA /* wordexp.c in Sources */,
C95B825C138F52B0004311DA /* gmon.c in Sources */,
- C95B825D138F52B0004311DA /* getmcontext.c in Sources */,
- C95B825E138F52B0004311DA /* makecontext.c in Sources */,
- C95B825F138F52B0004311DA /* setcontext.c in Sources */,
- C95B8260138F52B0004311DA /* setjmperr.c in Sources */,
- C95B8261138F52B0004311DA /* swapcontext.c in Sources */,
- C95B8262138F52B0004311DA /* init_cpu_capabilities.c in Sources */,
- C95B8263138F52B0004311DA /* bcopy.c in Sources */,
- C95B8264138F52B0004311DA /* bzero.c in Sources */,
- C95B8265138F52B0004311DA /* memcpy.c in Sources */,
- C95B8266138F52B0004311DA /* memmove.c in Sources */,
- C95B8267138F52B0004311DA /* atomic.c in Sources */,
- C95B8269138F52B0004311DA /* spinlocks.c in Sources */,
C95B827C138F52B0004311DA /* ascii.c in Sources */,
C95B827D138F52B0004311DA /* big5.c in Sources */,
C95B827E138F52B0004311DA /* btowc.c in Sources */,
C95B82D1138F52B0004311DA /* acl_flag.c in Sources */,
C95B82D2138F52B0004311DA /* acl_perm.c in Sources */,
C95B82D3138F52B0004311DA /* acl_translate.c in Sources */,
- C95B82DC138F52B0004311DA /* mk_pthread_impl.c in Sources */,
- C95B82DD138F52B0004311DA /* pthread.c in Sources */,
- C95B82DE138F52B0004311DA /* pthread_cancelable.c in Sources */,
- C95B82DF138F52B0004311DA /* pthread_cond.c in Sources */,
- C95B82E0138F52B0004311DA /* pthread_mutex.c in Sources */,
- C95B82E1138F52B0004311DA /* pthread_rwlock.c in Sources */,
- C95B82E2138F52B0004311DA /* pthread_tsd.c in Sources */,
- C95B82E3138F52B0004311DA /* pthread_atfork_test.c in Sources */,
- C95B82E4138F52B0004311DA /* thread_setup.c in Sources */,
C95B82E7138F52B0004311DA /* regerror.c in Sources */,
- C95B82EA138F52B0004311DA /* chk_fail.c in Sources */,
- C95B82EB138F52B0004311DA /* memcpy_chk.c in Sources */,
- C95B82EC138F52B0004311DA /* memmove_chk.c in Sources */,
- C95B82ED138F52B0004311DA /* memset_chk.c in Sources */,
- C95B82EE138F52B0004311DA /* snprintf_chk.c in Sources */,
- C95B82EF138F52B0004311DA /* sprintf_chk.c in Sources */,
- C95B82F0138F52B0004311DA /* stpcpy_chk.c in Sources */,
- C95B82F1138F52B0004311DA /* stpncpy_chk.c in Sources */,
- C95B82F2138F52B0004311DA /* strcat_chk.c in Sources */,
- C95B82F3138F52B0004311DA /* strcpy_chk.c in Sources */,
- C95B82F4138F52B0004311DA /* strncat_chk.c in Sources */,
- C95B82F5138F52B0004311DA /* strncpy_chk.c in Sources */,
- C95B82F6138F52B0004311DA /* vsnprintf_chk.c in Sources */,
- C95B82F7138F52B0004311DA /* vsprintf_chk.c in Sources */,
C95B82F8138F52B0004311DA /* _flock_stub.c in Sources */,
C95B82F9138F52B0004311DA /* asprintf.c in Sources */,
C95B82FA138F52B0004311DA /* clrerr.c in Sources */,
C95B839A138F52B0004311DA /* timelocal.c in Sources */,
C95B839B138F52B0004311DA /* getdate.c in Sources */,
C95B839C138F52B0004311DA /* timezone_unix03.c in Sources */,
- C95B839D138F52B0004311DA /* bcmp.c in Sources */,
- C95B839E138F52B0004311DA /* bcopy.c in Sources */,
- C95B839F138F52B0004311DA /* bzero.c in Sources */,
C95B83A0138F52B0004311DA /* index.c in Sources */,
- C95B83A1138F52B0004311DA /* memccpy.c in Sources */,
- C95B83A2138F52B0004311DA /* memchr.c in Sources */,
- C95B83A3138F52B0004311DA /* memcmp.c in Sources */,
- C95B83A4138F52B0004311DA /* memcpy.c in Sources */,
C95B83A5138F52B0004311DA /* memmem.c in Sources */,
- C95B83A6138F52B0004311DA /* memmove.c in Sources */,
- C95B83A7138F52B0004311DA /* memset.c in Sources */,
C95B83A8138F52B0004311DA /* rindex.c in Sources */,
C95B83AB138F52B0004311DA /* strcasecmp.c in Sources */,
C95B83AC138F52B0004311DA /* strcasestr.c in Sources */,
- C95B83AE138F52B0004311DA /* strchr.c in Sources */,
- C95B83AF138F52B0004311DA /* strcmp.c in Sources */,
C95B83B0138F52B0004311DA /* strcoll.c in Sources */,
C95B83B2138F52B0004311DA /* strcspn.c in Sources */,
C95B83B3138F52B0004311DA /* strdup.c in Sources */,
C95B83B4138F52B0004311DA /* strerror.c in Sources */,
C95B83B7138F52B0004311DA /* strlen.c in Sources */,
C95B83B8138F52B0004311DA /* strmode.c in Sources */,
- C95B83BA138F52B0004311DA /* strncmp.c in Sources */,
C95B83BC138F52B0004311DA /* strndup.c in Sources */,
C95B83BD138F52B0004311DA /* strnlen.c in Sources */,
C95B83BE138F52B0004311DA /* strnstr.c in Sources */,
C95B83E6138F52B0004311DA /* __libc_init.c in Sources */,
C95B83E7138F52B0004311DA /* _libc_fork_child.c in Sources */,
C95B83E8138F52B0004311DA /* chmodx_np.c in Sources */,
- C95B83E9138F52B0004311DA /* context-stubs.c in Sources */,
C95B83EA138F52B0004311DA /* crt_externs.c in Sources */,
- C95B83EB138F52B0004311DA /* errno.c in Sources */,
C95B83EC138F52B0004311DA /* fork.c in Sources */,
C95B83ED138F52B0004311DA /* getgroups.c in Sources */,
- C95B83EE138F52B0004311DA /* getiopolicy_np.c in Sources */,
C95B83EF138F52B0004311DA /* gettimeofday.c in Sources */,
C95B83F0138F52B0004311DA /* msgctl.c in Sources */,
C95B83F1138F52B0004311DA /* stack_protector.c in Sources */,
C95B83F7138F52B0004311DA /* settimeofday.c in Sources */,
C95B83F8138F52B0004311DA /* shmctl.c in Sources */,
C95B83F9138F52B0004311DA /* sigaction.c in Sources */,
- C95B83FA138F52B0004311DA /* sigcatch.c in Sources */,
- C95B83FB138F52B0004311DA /* sigtramp.c in Sources */,
- C95B83FC138F52B0004311DA /* slot_name.c in Sources */,
C95B83FD138F52B0004311DA /* statx_np.c in Sources */,
C95B83FE138F52B0004311DA /* umaskx_np.c in Sources */,
- C95B83FF138F52B0004311DA /* cprocs.c in Sources */,
- C95B8400138F52B0004311DA /* cthreads.c in Sources */,
- C95B8401138F52B0004311DA /* mig_support.c in Sources */,
C95B8402138F52B0004311DA /* fparseln.c in Sources */,
C95B8403138F52B0004311DA /* login.c in Sources */,
C95B8404138F52B0004311DA /* login_tty.c in Sources */,
C95B840F138F52B0004311DA /* parse.c in Sources */,
C95B8410138F52B0004311DA /* unpack.c in Sources */,
C95B8411138F52B0004311DA /* unparse.c in Sources */,
- C95B8412138F52B0004311DA /* getmcontext.c in Sources */,
- C95B8413138F52B0004311DA /* makecontext.c in Sources */,
- C95B8414138F52B0004311DA /* setcontext.c in Sources */,
- C95B8415138F52B0004311DA /* swapcontext.c in Sources */,
- C95B8416138F52B0004311DA /* bcopy.c in Sources */,
- C95B8417138F52B0004311DA /* bzero.c in Sources */,
- C95B8418138F52B0004311DA /* memcpy.c in Sources */,
- C95B8419138F52B0004311DA /* memmove.c in Sources */,
- C95B841A138F52B0004311DA /* atomic.c in Sources */,
- C95B841B138F52B0004311DA /* spinlocks.c in Sources */,
- 3F2208EC14358B4A00386F5B /* asl_fd.c in Sources */,
B19C64601450F90200032373 /* sync_volume_np.c in Sources */,
3FB7E1B8146EF2E000843438 /* dirfd.c in Sources */,
+ 4B2C64A715519BC700342BFA /* assumes.c in Sources */,
+ FC2ED615157D4BE80098EC69 /* inet_ntop.c in Sources */,
+ FC2ED61E157D4BE80098EC69 /* inet_pton.c in Sources */,
+ 2B9D61BC157D667A00AF25B8 /* trace.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
buildActionMask = 2147483647;
files = (
C95B842E138F53DB004311DA /* init_cpu_capabilities.c in Sources */,
- C95B842F138F53DB004311DA /* dyld_resolvers.c in Sources */,
- C95B8430138F53DB004311DA /* arm_commpage_gettimeofday.c in Sources */,
- C95B8431138F53DB004311DA /* gcc_atomic.c in Sources */,
- C95B8432138F53DB004311DA /* OSAtomic-v4.c in Sources */,
- C95B8433138F53DB004311DA /* OSAtomic_resolvers.c in Sources */,
C95B8435138F53DB004311DA /* creat.c in Sources */,
C95B8436138F53DB004311DA /* gethostid.c in Sources */,
C95B8437138F53DB004311DA /* getwd.c in Sources */,
C95B8440138F53DB004311DA /* sigcompat.c in Sources */,
C95B8441138F53DB004311DA /* _dirhelper.c in Sources */,
C95B8442138F53DB004311DA /* kvm.c in Sources */,
- C95B8443138F53DB004311DA /* libproc.c in Sources */,
- C95B8444138F53DB004311DA /* MKGetTimeBaseInfo.c in Sources */,
- C95B8445138F53DB004311DA /* proc_listpidspath.c in Sources */,
C95B8446138F53DB004311DA /* forceLibcToBuild.c in Sources */,
C95B8447138F53DB004311DA /* bt_close.c in Sources */,
C95B8448138F53DB004311DA /* bt_conv.c in Sources */,
C95B8483138F53DB004311DA /* machdep_ldisdd.c in Sources */,
C95B8484138F53DB004311DA /* machdep_ldisQ.c in Sources */,
C95B8485138F53DB004311DA /* machdep_ldisx.c in Sources */,
- C95B8486138F53DB004311DA /* _simple.c in Sources */,
- C95B8487138F53DB004311DA /* asl.c in Sources */,
- C95B8488138F53DB004311DA /* asl_core.c in Sources */,
- C95B8489138F53DB004311DA /* asl_file.c in Sources */,
- C95B848A138F53DB004311DA /* asl_legacy1.c in Sources */,
- C95B848B138F53DB004311DA /* asl_msg.c in Sources */,
- C95B848C138F53DB004311DA /* asl_store.c in Sources */,
- C95B848D138F53DB004311DA /* asl_util.c in Sources */,
- C95B848E138F53DB004311DA /* assumes.c in Sources */,
C95B848F138F53DB004311DA /* authentication.c in Sources */,
C95B8490138F53DB004311DA /* backtrace.c in Sources */,
- C95B8491138F53DB004311DA /* cache.c in Sources */,
C95B8492138F53DB004311DA /* confstr.c in Sources */,
C95B8493138F53DB004311DA /* crypt.c in Sources */,
C95B8494138F53DB004311DA /* devname.c in Sources */,
C95B84E8138F53DB004311DA /* getttyent.c in Sources */,
C95B84E9138F53DB004311DA /* getusershell.c in Sources */,
C95B84EA138F53DB004311DA /* getvfsbyname.c in Sources */,
- C95B84EB138F53DB004311DA /* isinf.c in Sources */,
- C95B84EC138F53DB004311DA /* isnan.c in Sources */,
- C95B84ED138F53DB004311DA /* magazine_malloc.c in Sources */,
- C95B84EE138F53DB004311DA /* malloc.c in Sources */,
C95B84EF138F53DB004311DA /* nanosleep.c in Sources */,
C95B84F0138F53DB004311DA /* utmpx.c in Sources */,
C95B84F1138F53DB004311DA /* nftw.c in Sources */,
C95B84F2138F53DB004311DA /* nlist.c in Sources */,
C95B84F3138F53DB004311DA /* NSSystemDirectories.c in Sources */,
C95B84F4138F53DB004311DA /* oldsyslog.c in Sources */,
- C95B84F5138F53DB004311DA /* platfunc.c in Sources */,
- C95B84F6138F53DB004311DA /* scalable_malloc.c in Sources */,
C95B84F7138F53DB004311DA /* setlogin.c in Sources */,
C95B84F8138F53DB004311DA /* sigsetops.c in Sources */,
- C95B84F9138F53DB004311DA /* stack_logging.c in Sources */,
- C95B84FA138F53DB004311DA /* stack_logging_disk.c in Sources */,
C95B84FB138F53DB004311DA /* strtofflags.c in Sources */,
- C95B84FC138F53DB004311DA /* syslog.c in Sources */,
C95B84FD138F53DB004311DA /* thread_stack_pcs.c in Sources */,
C95B84FE138F53DB004311DA /* uname.c in Sources */,
C95B84FF138F53DB004311DA /* utmpx-darwin.c in Sources */,
C95B8500138F53DB004311DA /* wordexp.c in Sources */,
C95B8502138F53DB004311DA /* gmon.c in Sources */,
- C95B8503138F53DB004311DA /* getmcontext.c in Sources */,
- C95B8504138F53DB004311DA /* makecontext.c in Sources */,
- C95B8505138F53DB004311DA /* setcontext.c in Sources */,
- C95B8506138F53DB004311DA /* setjmperr.c in Sources */,
- C95B8507138F53DB004311DA /* swapcontext.c in Sources */,
- C95B8508138F53DB004311DA /* init_cpu_capabilities.c in Sources */,
- C95B8509138F53DB004311DA /* bcopy.c in Sources */,
- C95B850A138F53DB004311DA /* bzero.c in Sources */,
- C95B850B138F53DB004311DA /* memcpy.c in Sources */,
- C95B850C138F53DB004311DA /* memmove.c in Sources */,
- C95B850D138F53DB004311DA /* atomic.c in Sources */,
- C95B850F138F53DB004311DA /* spinlocks.c in Sources */,
C95B8522138F53DB004311DA /* ascii.c in Sources */,
C95B8523138F53DB004311DA /* big5.c in Sources */,
C95B8524138F53DB004311DA /* btowc.c in Sources */,
C95B8577138F53DB004311DA /* acl_flag.c in Sources */,
C95B8578138F53DB004311DA /* acl_perm.c in Sources */,
C95B8579138F53DB004311DA /* acl_translate.c in Sources */,
- C95B8582138F53DB004311DA /* mk_pthread_impl.c in Sources */,
- C95B8583138F53DB004311DA /* pthread.c in Sources */,
- C95B8584138F53DB004311DA /* pthread_cancelable.c in Sources */,
- C95B8585138F53DB004311DA /* pthread_cond.c in Sources */,
- C95B8586138F53DB004311DA /* pthread_mutex.c in Sources */,
- C95B8587138F53DB004311DA /* pthread_rwlock.c in Sources */,
- C95B8588138F53DB004311DA /* pthread_tsd.c in Sources */,
- C95B8589138F53DB004311DA /* pthread_atfork_test.c in Sources */,
- C95B858A138F53DB004311DA /* thread_setup.c in Sources */,
C95B858D138F53DB004311DA /* regerror.c in Sources */,
- C95B8590138F53DB004311DA /* chk_fail.c in Sources */,
- C95B8591138F53DB004311DA /* memcpy_chk.c in Sources */,
- C95B8592138F53DB004311DA /* memmove_chk.c in Sources */,
- C95B8593138F53DB004311DA /* memset_chk.c in Sources */,
- C95B8594138F53DB004311DA /* snprintf_chk.c in Sources */,
- C95B8595138F53DB004311DA /* sprintf_chk.c in Sources */,
- C95B8596138F53DB004311DA /* stpcpy_chk.c in Sources */,
- C95B8597138F53DB004311DA /* stpncpy_chk.c in Sources */,
- C95B8598138F53DB004311DA /* strcat_chk.c in Sources */,
- C95B8599138F53DB004311DA /* strcpy_chk.c in Sources */,
- C95B859A138F53DB004311DA /* strncat_chk.c in Sources */,
- C95B859B138F53DB004311DA /* strncpy_chk.c in Sources */,
- C95B859C138F53DB004311DA /* vsnprintf_chk.c in Sources */,
- C95B859D138F53DB004311DA /* vsprintf_chk.c in Sources */,
C95B859E138F53DB004311DA /* _flock_stub.c in Sources */,
C95B859F138F53DB004311DA /* asprintf.c in Sources */,
C95B85A0138F53DB004311DA /* clrerr.c in Sources */,
C95B8640138F53DB004311DA /* timelocal.c in Sources */,
C95B8641138F53DB004311DA /* getdate.c in Sources */,
C95B8642138F53DB004311DA /* timezone_unix03.c in Sources */,
- C95B8643138F53DB004311DA /* bcmp.c in Sources */,
- C95B8644138F53DB004311DA /* bcopy.c in Sources */,
- C95B8645138F53DB004311DA /* bzero.c in Sources */,
C95B8646138F53DB004311DA /* index.c in Sources */,
- C95B8647138F53DB004311DA /* memccpy.c in Sources */,
- C95B8648138F53DB004311DA /* memchr.c in Sources */,
- C95B8649138F53DB004311DA /* memcmp.c in Sources */,
- C95B864A138F53DB004311DA /* memcpy.c in Sources */,
C95B864B138F53DB004311DA /* memmem.c in Sources */,
- C95B864C138F53DB004311DA /* memmove.c in Sources */,
- C95B864D138F53DB004311DA /* memset.c in Sources */,
C95B864E138F53DB004311DA /* rindex.c in Sources */,
C95B8651138F53DB004311DA /* strcasecmp.c in Sources */,
C95B8652138F53DB004311DA /* strcasestr.c in Sources */,
- C95B8654138F53DB004311DA /* strchr.c in Sources */,
- C95B8655138F53DB004311DA /* strcmp.c in Sources */,
C95B8656138F53DB004311DA /* strcoll.c in Sources */,
C95B8658138F53DB004311DA /* strcspn.c in Sources */,
C95B8659138F53DB004311DA /* strdup.c in Sources */,
C95B865A138F53DB004311DA /* strerror.c in Sources */,
C95B865D138F53DB004311DA /* strlen.c in Sources */,
C95B865E138F53DB004311DA /* strmode.c in Sources */,
- C95B8660138F53DB004311DA /* strncmp.c in Sources */,
C95B8662138F53DB004311DA /* strndup.c in Sources */,
C95B8663138F53DB004311DA /* strnlen.c in Sources */,
C95B8664138F53DB004311DA /* strnstr.c in Sources */,
C95B868C138F53DB004311DA /* __libc_init.c in Sources */,
C95B868D138F53DB004311DA /* _libc_fork_child.c in Sources */,
C95B868E138F53DB004311DA /* chmodx_np.c in Sources */,
- C95B868F138F53DB004311DA /* context-stubs.c in Sources */,
C95B8690138F53DB004311DA /* crt_externs.c in Sources */,
- C95B8691138F53DB004311DA /* errno.c in Sources */,
C95B8692138F53DB004311DA /* fork.c in Sources */,
C95B8693138F53DB004311DA /* getgroups.c in Sources */,
- C95B8694138F53DB004311DA /* getiopolicy_np.c in Sources */,
C95B8695138F53DB004311DA /* gettimeofday.c in Sources */,
C95B8696138F53DB004311DA /* msgctl.c in Sources */,
C95B8697138F53DB004311DA /* stack_protector.c in Sources */,
C95B869D138F53DB004311DA /* settimeofday.c in Sources */,
C95B869E138F53DB004311DA /* shmctl.c in Sources */,
C95B869F138F53DB004311DA /* sigaction.c in Sources */,
- C95B86A0138F53DB004311DA /* sigcatch.c in Sources */,
- C95B86A1138F53DB004311DA /* sigtramp.c in Sources */,
- C95B86A2138F53DB004311DA /* slot_name.c in Sources */,
C95B86A3138F53DB004311DA /* statx_np.c in Sources */,
C95B86A4138F53DB004311DA /* umaskx_np.c in Sources */,
- C95B86A5138F53DB004311DA /* cprocs.c in Sources */,
- C95B86A6138F53DB004311DA /* cthreads.c in Sources */,
- C95B86A7138F53DB004311DA /* mig_support.c in Sources */,
C95B86A8138F53DB004311DA /* fparseln.c in Sources */,
C95B86A9138F53DB004311DA /* login.c in Sources */,
C95B86AA138F53DB004311DA /* login_tty.c in Sources */,
C95B86B5138F53DB004311DA /* parse.c in Sources */,
C95B86B6138F53DB004311DA /* unpack.c in Sources */,
C95B86B7138F53DB004311DA /* unparse.c in Sources */,
- C95B86B8138F53DB004311DA /* getmcontext.c in Sources */,
- C95B86B9138F53DB004311DA /* makecontext.c in Sources */,
- C95B86BA138F53DB004311DA /* setcontext.c in Sources */,
- C95B86BB138F53DB004311DA /* swapcontext.c in Sources */,
- C95B86BC138F53DB004311DA /* bcopy.c in Sources */,
- C95B86BD138F53DB004311DA /* bzero.c in Sources */,
- C95B86BE138F53DB004311DA /* memcpy.c in Sources */,
- C95B86BF138F53DB004311DA /* memmove.c in Sources */,
- C95B86C0138F53DB004311DA /* atomic.c in Sources */,
- C95B86C1138F53DB004311DA /* spinlocks.c in Sources */,
- 3F2208ED14358B4A00386F5B /* asl_fd.c in Sources */,
B19C64611450F90200032373 /* sync_volume_np.c in Sources */,
3FB7E1B9146EF2E000843438 /* dirfd.c in Sources */,
+ 4B2C64A815519BC700342BFA /* assumes.c in Sources */,
+ FC2ED616157D4BE80098EC69 /* inet_ntop.c in Sources */,
+ FC2ED61F157D4BE80098EC69 /* inet_pton.c in Sources */,
+ 2B9D61BD157D667A00AF25B8 /* trace.c in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ C97A6F231517AF53005E1998 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ C97A6F291517AF53005E1998 /* mcount.s in Sources */,
+ C97A6F3F1517AF53005E1998 /* strcpy.s in Sources */,
+ C97A6F401517AF53005E1998 /* strlcat.s in Sources */,
+ C97A6F411517AF53005E1998 /* strlcpy.s in Sources */,
+ C97A6F421517AF53005E1998 /* strlen.s in Sources */,
+ C97A6F441517AF53005E1998 /* strncpy.s in Sources */,
+ C97A6F5A1517AF53005E1998 /* strlen.s in Sources */,
+ C97A6F5C1517AF53005E1998 /* strnlen.s in Sources */,
+ C97A6F5D1517AF53005E1998 /* strstr.s in Sources */,
+ C97A6F6D1517AF53005E1998 /* mcount.s in Sources */,
+ C97A6F761517AF53005E1998 /* (null) in Sources */,
+ C97A6F791517AF53005E1998 /* (null) in Sources */,
+ C97A6F7A1517AF53005E1998 /* (null) in Sources */,
+ C97A6F7E1517AF53005E1998 /* (null) in Sources */,
+ C97A6F8D1517AF53005E1998 /* dirhelper.defs in Sources */,
+ C97A6F8F1517AF53005E1998 /* init_cpu_capabilities.c in Sources */,
+ C97A6F961517AF53005E1998 /* creat.c in Sources */,
+ C97A6F971517AF53005E1998 /* gethostid.c in Sources */,
+ C97A6F981517AF53005E1998 /* getwd.c in Sources */,
+ C97A6F991517AF53005E1998 /* killpg.c in Sources */,
+ C97A6F9A1517AF53005E1998 /* sethostid.c in Sources */,
+ C97A6F9B1517AF53005E1998 /* setpgrp.c in Sources */,
+ C97A6F9C1517AF53005E1998 /* setrgid.c in Sources */,
+ C97A6F9D1517AF53005E1998 /* setruid.c in Sources */,
+ C97A6F9E1517AF53005E1998 /* setregid.c in Sources */,
+ C97A6F9F1517AF53005E1998 /* setreuid.c in Sources */,
+ C97A6FA01517AF53005E1998 /* sigaltstk.c in Sources */,
+ C97A6FA11517AF53005E1998 /* sigcompat.c in Sources */,
+ C97A6FA21517AF53005E1998 /* _dirhelper.c in Sources */,
+ C97A6FA31517AF53005E1998 /* kvm.c in Sources */,
+ C97A6FA71517AF53005E1998 /* forceLibcToBuild.c in Sources */,
+ C97A6FA81517AF53005E1998 /* bt_close.c in Sources */,
+ C97A6FA91517AF53005E1998 /* bt_conv.c in Sources */,
+ C97A6FAA1517AF53005E1998 /* bt_debug.c in Sources */,
+ C97A6FAB1517AF53005E1998 /* bt_delete.c in Sources */,
+ C97A6FAC1517AF53005E1998 /* bt_get.c in Sources */,
+ C97A6FAD1517AF53005E1998 /* bt_open.c in Sources */,
+ C97A6FAE1517AF53005E1998 /* bt_overflow.c in Sources */,
+ C97A6FAF1517AF53005E1998 /* bt_page.c in Sources */,
+ C97A6FB01517AF53005E1998 /* bt_put.c in Sources */,
+ C97A6FB11517AF53005E1998 /* bt_search.c in Sources */,
+ C97A6FB21517AF53005E1998 /* bt_seq.c in Sources */,
+ C97A6FB31517AF53005E1998 /* bt_split.c in Sources */,
+ C97A6FB41517AF53005E1998 /* bt_utils.c in Sources */,
+ C97A6FB51517AF53005E1998 /* db.c in Sources */,
+ C97A6FB61517AF53005E1998 /* hash.c in Sources */,
+ C97A6FB71517AF53005E1998 /* hash_bigkey.c in Sources */,
+ C97A6FB81517AF53005E1998 /* hash_buf.c in Sources */,
+ C97A6FB91517AF53005E1998 /* hash_func.c in Sources */,
+ C97A6FBA1517AF53005E1998 /* hash_log2.c in Sources */,
+ C97A6FBB1517AF53005E1998 /* hash_page.c in Sources */,
+ C97A6FBC1517AF53005E1998 /* ndbm.c in Sources */,
+ C97A6FBD1517AF53005E1998 /* mpool.c in Sources */,
+ C97A6FBE1517AF53005E1998 /* rec_close.c in Sources */,
+ C97A6FBF1517AF53005E1998 /* rec_delete.c in Sources */,
+ C97A6FC01517AF53005E1998 /* rec_get.c in Sources */,
+ C97A6FC11517AF53005E1998 /* rec_open.c in Sources */,
+ C97A6FC21517AF53005E1998 /* rec_put.c in Sources */,
+ C97A6FC31517AF53005E1998 /* rec_search.c in Sources */,
+ C97A6FC41517AF53005E1998 /* rec_seq.c in Sources */,
+ C97A6FC51517AF53005E1998 /* rec_utils.c in Sources */,
+ C97A6FC61517AF53005E1998 /* brk.c in Sources */,
+ C97A6FC71517AF53005E1998 /* bsd_signal.c in Sources */,
+ C97A6FC81517AF53005E1998 /* lchflags.c in Sources */,
+ C97A6FC91517AF53005E1998 /* lchmod.c in Sources */,
+ C97A6FCA1517AF53005E1998 /* lutimes.c in Sources */,
+ C97A6FCB1517AF53005E1998 /* statvfs.c in Sources */,
+ C97A6FCC1517AF53005E1998 /* tcgetsid.c in Sources */,
+ C97A6FCD1517AF53005E1998 /* _ldbl_util.c in Sources */,
+ C97A6FCE1517AF53005E1998 /* _hdtoa.c in Sources */,
+ C97A6FCF1517AF53005E1998 /* _ldtoa.c in Sources */,
+ C97A6FD01517AF53005E1998 /* gdtoa-dmisc.c in Sources */,
+ C97A6FD11517AF53005E1998 /* gdtoa-dtoa.c in Sources */,
+ C97A6FD21517AF53005E1998 /* gdtoa-gdtoa.c in Sources */,
+ C97A6FD31517AF53005E1998 /* gdtoa-gethex.c in Sources */,
+ C97A6FD41517AF53005E1998 /* gdtoa-gmisc.c in Sources */,
+ C97A6FD51517AF53005E1998 /* gdtoa-hd_init.c in Sources */,
+ C97A6FD61517AF53005E1998 /* gdtoa-hexnan.c in Sources */,
+ C97A6FD71517AF53005E1998 /* gdtoa-misc.c in Sources */,
+ C97A6FD81517AF53005E1998 /* gdtoa-smisc.c in Sources */,
+ C97A6FD91517AF53005E1998 /* gdtoa-strtod.c in Sources */,
+ C97A6FDA1517AF53005E1998 /* gdtoa-strtodg.c in Sources */,
+ C97A6FDB1517AF53005E1998 /* gdtoa-strtof.c in Sources */,
+ C97A6FDC1517AF53005E1998 /* gdtoa-strtoIg.c in Sources */,
+ C97A6FDD1517AF53005E1998 /* gdtoa-strtopdd.c in Sources */,
+ C97A6FDE1517AF53005E1998 /* gdtoa-strtopx.c in Sources */,
+ C97A6FDF1517AF53005E1998 /* gdtoa-strtord.c in Sources */,
+ C97A6FE01517AF53005E1998 /* gdtoa-sum.c in Sources */,
+ C97A6FE11517AF53005E1998 /* gdtoa-ulp.c in Sources */,
+ C97A6FE21517AF53005E1998 /* glue.c in Sources */,
+ C97A6FE31517AF53005E1998 /* machdep_ldisd.c in Sources */,
+ C97A6FE41517AF53005E1998 /* machdep_ldisdd.c in Sources */,
+ C97A6FE51517AF53005E1998 /* machdep_ldisQ.c in Sources */,
+ C97A6FE61517AF53005E1998 /* machdep_ldisx.c in Sources */,
+ C97A6FF01517AF53005E1998 /* authentication.c in Sources */,
+ C97A6FF11517AF53005E1998 /* backtrace.c in Sources */,
+ C97A6FF31517AF53005E1998 /* confstr.c in Sources */,
+ C97A6FF41517AF53005E1998 /* crypt.c in Sources */,
+ C97A6FF51517AF53005E1998 /* devname.c in Sources */,
+ C97A6FF61517AF53005E1998 /* disklabel.c in Sources */,
+ C97A6FF71517AF53005E1998 /* errlst.c in Sources */,
+ C97A6FF81517AF53005E1998 /* filesec.c in Sources */,
+ C97A6FF91517AF53005E1998 /* _rand48.c in Sources */,
+ C97A6FFA1517AF53005E1998 /* alarm.c in Sources */,
+ C97A6FFB1517AF53005E1998 /* arc4random.c in Sources */,
+ C97A6FFC1517AF53005E1998 /* assert.c in Sources */,
+ C97A6FFD1517AF53005E1998 /* basename.c in Sources */,
+ C97A6FFE1517AF53005E1998 /* clock.c in Sources */,
+ C97A6FFF1517AF53005E1998 /* closedir.c in Sources */,
+ C97A70001517AF53005E1998 /* ctermid.c in Sources */,
+ C97A70011517AF53005E1998 /* daemon.c in Sources */,
+ C97A70021517AF53005E1998 /* dirname.c in Sources */,
+ C97A70031517AF53005E1998 /* drand48.c in Sources */,
+ C97A70041517AF53005E1998 /* erand48.c in Sources */,
+ C97A70051517AF53005E1998 /* err.c in Sources */,
+ C97A70061517AF53005E1998 /* exec.c in Sources */,
+ C97A70071517AF53005E1998 /* fmtcheck.c in Sources */,
+ C97A70081517AF53005E1998 /* fmtmsg.c in Sources */,
+ C97A70091517AF53005E1998 /* fnmatch.c in Sources */,
+ C97A700A1517AF53005E1998 /* ftok.c in Sources */,
+ C97A700B1517AF53005E1998 /* getbsize.c in Sources */,
+ C97A700C1517AF53005E1998 /* getcap.c in Sources */,
+ C97A700D1517AF53005E1998 /* getcwd.c in Sources */,
+ C97A700E1517AF53005E1998 /* gethostname.c in Sources */,
+ C97A700F1517AF53005E1998 /* getlogin.c in Sources */,
+ C97A70101517AF53005E1998 /* getmntinfo.c in Sources */,
+ C97A70111517AF53005E1998 /* getpagesize.c in Sources */,
+ C97A70121517AF53005E1998 /* getpeereid.c in Sources */,
+ C97A70131517AF53005E1998 /* getprogname.c in Sources */,
+ C97A70141517AF53005E1998 /* glob.c in Sources */,
+ C97A70151517AF53005E1998 /* isatty.c in Sources */,
+ C97A70161517AF53005E1998 /* jrand48.c in Sources */,
+ C97A70171517AF53005E1998 /* lcong48.c in Sources */,
+ C97A70181517AF53005E1998 /* lockf.c in Sources */,
+ C97A70191517AF53005E1998 /* lrand48.c in Sources */,
+ C97A701A1517AF53005E1998 /* mrand48.c in Sources */,
+ C97A701B1517AF53005E1998 /* nice.c in Sources */,
+ C97A701C1517AF53005E1998 /* nrand48.c in Sources */,
+ C97A701D1517AF53005E1998 /* opendir.c in Sources */,
+ C97A701E1517AF53005E1998 /* pause.c in Sources */,
+ C97A701F1517AF53005E1998 /* popen.c in Sources */,
+ C97A70201517AF53005E1998 /* pselect.c in Sources */,
+ C97A70211517AF53005E1998 /* psignal.c in Sources */,
+ C97A70221517AF53005E1998 /* raise.c in Sources */,
+ C97A70231517AF53005E1998 /* readdir.c in Sources */,
+ C97A70241517AF53005E1998 /* readpassphrase.c in Sources */,
+ C97A70251517AF53005E1998 /* rewinddir.c in Sources */,
+ C97A70261517AF53005E1998 /* scandir.c in Sources */,
+ C97A70271517AF53005E1998 /* seed48.c in Sources */,
+ C97A70281517AF53005E1998 /* seekdir.c in Sources */,
+ C97A70291517AF53005E1998 /* sethostname.c in Sources */,
+ C97A702A1517AF53005E1998 /* setmode.c in Sources */,
+ C97A702B1517AF53005E1998 /* setprogname.c in Sources */,
+ C97A702C1517AF53005E1998 /* siginterrupt.c in Sources */,
+ C97A702D1517AF53005E1998 /* siglist.c in Sources */,
+ C97A702E1517AF53005E1998 /* signal.c in Sources */,
+ C97A702F1517AF53005E1998 /* sleep.c in Sources */,
+ C97A70301517AF53005E1998 /* srand48.c in Sources */,
+ C97A70311517AF53005E1998 /* stringlist.c in Sources */,
+ C97A70321517AF53005E1998 /* sysconf.c in Sources */,
+ C97A70331517AF53005E1998 /* sysctl.c in Sources */,
+ C97A70341517AF53005E1998 /* sysctlbyname.c in Sources */,
+ C97A70351517AF53005E1998 /* sysctlnametomib.c in Sources */,
+ C97A70361517AF53005E1998 /* telldir.c in Sources */,
+ C97A70371517AF53005E1998 /* termios.c in Sources */,
+ C97A70381517AF53005E1998 /* time.c in Sources */,
+ C97A70391517AF53005E1998 /* times.c in Sources */,
+ C97A703A1517AF53005E1998 /* timezone.c in Sources */,
+ C97A703B1517AF53005E1998 /* ttyname.c in Sources */,
+ C97A703C1517AF53005E1998 /* ttyslot.c in Sources */,
+ C97A703D1517AF53005E1998 /* ualarm.c in Sources */,
+ C97A703E1517AF53005E1998 /* ulimit.c in Sources */,
+ C97A703F1517AF53005E1998 /* unvis.c in Sources */,
+ C97A70401517AF53005E1998 /* usleep.c in Sources */,
+ C97A70411517AF53005E1998 /* utime.c in Sources */,
+ C97A70421517AF53005E1998 /* vis.c in Sources */,
+ C97A70431517AF53005E1998 /* wait.c in Sources */,
+ C97A70441517AF53005E1998 /* wait3.c in Sources */,
+ C97A70451517AF53005E1998 /* waitpid.c in Sources */,
+ C97A70461517AF53005E1998 /* fts.c in Sources */,
+ C97A70471517AF53005E1998 /* get_compat.c in Sources */,
+ C97A70481517AF53005E1998 /* getloadavg.c in Sources */,
+ C97A70491517AF53005E1998 /* getttyent.c in Sources */,
+ C97A704A1517AF53005E1998 /* getusershell.c in Sources */,
+ C97A704B1517AF53005E1998 /* getvfsbyname.c in Sources */,
+ C97A70501517AF53005E1998 /* nanosleep.c in Sources */,
+ C97A70511517AF53005E1998 /* utmpx.c in Sources */,
+ C97A70521517AF53005E1998 /* nftw.c in Sources */,
+ C97A70531517AF53005E1998 /* nlist.c in Sources */,
+ C97A70541517AF53005E1998 /* NSSystemDirectories.c in Sources */,
+ C97A70551517AF53005E1998 /* oldsyslog.c in Sources */,
+ C97A70581517AF53005E1998 /* setlogin.c in Sources */,
+ C97A70591517AF53005E1998 /* sigsetops.c in Sources */,
+ C97A705C1517AF53005E1998 /* strtofflags.c in Sources */,
+ C97A705E1517AF53005E1998 /* thread_stack_pcs.c in Sources */,
+ C97A705F1517AF53005E1998 /* uname.c in Sources */,
+ C97A70601517AF53005E1998 /* utmpx-darwin.c in Sources */,
+ C97A70611517AF53005E1998 /* wordexp.c in Sources */,
+ C97A70621517AF53005E1998 /* gmon.c in Sources */,
+ C97A70701517AF53005E1998 /* ascii.c in Sources */,
+ C97A70711517AF53005E1998 /* big5.c in Sources */,
+ C97A70721517AF53005E1998 /* btowc.c in Sources */,
+ C97A70731517AF53005E1998 /* collate.c in Sources */,
+ C97A70741517AF53005E1998 /* collcmp.c in Sources */,
+ C97A70751517AF53005E1998 /* euc.c in Sources */,
+ C97A70761517AF53005E1998 /* fix_grouping.c in Sources */,
+ C97A70771517AF53005E1998 /* gb18030.c in Sources */,
+ C97A70781517AF53005E1998 /* gb2312.c in Sources */,
+ C97A70791517AF53005E1998 /* gbk.c in Sources */,
+ C97A707A1517AF53005E1998 /* ldpart.c in Sources */,
+ C97A707B1517AF53005E1998 /* lmessages.c in Sources */,
+ C97A707C1517AF53005E1998 /* lmonetary.c in Sources */,
+ C97A707D1517AF53005E1998 /* lnumeric.c in Sources */,
+ C97A707E1517AF53005E1998 /* localeconv.c in Sources */,
+ C97A707F1517AF53005E1998 /* mblen.c in Sources */,
+ C97A70801517AF53005E1998 /* mbrlen.c in Sources */,
+ C97A70811517AF53005E1998 /* mbrtowc.c in Sources */,
+ C97A70821517AF53005E1998 /* mbsinit.c in Sources */,
+ C97A70831517AF53005E1998 /* mbsnrtowcs.c in Sources */,
+ C97A70841517AF53005E1998 /* mbsrtowcs.c in Sources */,
+ C97A70851517AF53005E1998 /* mbstowcs.c in Sources */,
+ C97A70861517AF53005E1998 /* mbtowc.c in Sources */,
+ C97A70871517AF53005E1998 /* mskanji.c in Sources */,
+ C97A70881517AF53005E1998 /* nextwctype.c in Sources */,
+ C97A70891517AF53005E1998 /* nl_langinfo.c in Sources */,
+ C97A708A1517AF53005E1998 /* nomacros.c in Sources */,
+ C97A708B1517AF53005E1998 /* none.c in Sources */,
+ C97A708C1517AF53005E1998 /* rune.c in Sources */,
+ C97A708D1517AF53005E1998 /* runetype.c in Sources */,
+ C97A708E1517AF53005E1998 /* setlocale.c in Sources */,
+ C97A708F1517AF53005E1998 /* setrunelocale.c in Sources */,
+ C97A70901517AF53005E1998 /* table.c in Sources */,
+ C97A70911517AF53005E1998 /* tolower.c in Sources */,
+ C97A70921517AF53005E1998 /* toupper.c in Sources */,
+ C97A70931517AF53005E1998 /* utf2.c in Sources */,
+ C97A70941517AF53005E1998 /* utf8.c in Sources */,
+ C97A70951517AF53005E1998 /* wcrtomb.c in Sources */,
+ C97A70961517AF53005E1998 /* wcsftime.c in Sources */,
+ C97A70971517AF53005E1998 /* wcsnrtombs.c in Sources */,
+ C97A70981517AF53005E1998 /* wcsrtombs.c in Sources */,
+ C97A70991517AF53005E1998 /* wcstod.c in Sources */,
+ C97A709A1517AF53005E1998 /* wcstof.c in Sources */,
+ C97A709B1517AF53005E1998 /* wcstoimax.c in Sources */,
+ C97A709C1517AF53005E1998 /* wcstol.c in Sources */,
+ C97A709D1517AF53005E1998 /* wcstold.c in Sources */,
+ C97A709E1517AF53005E1998 /* wcstoll.c in Sources */,
+ C97A709F1517AF53005E1998 /* wcstombs.c in Sources */,
+ C97A70A01517AF53005E1998 /* wcstoul.c in Sources */,
+ C97A70A11517AF53005E1998 /* wcstoull.c in Sources */,
+ C97A70A21517AF53005E1998 /* wcstoumax.c in Sources */,
+ C97A70A31517AF53005E1998 /* wctob.c in Sources */,
+ C97A70A41517AF53005E1998 /* wctomb.c in Sources */,
+ C97A70A51517AF53005E1998 /* wctrans.c in Sources */,
+ C97A70A61517AF53005E1998 /* wctype.c in Sources */,
+ C97A70A71517AF53005E1998 /* wcwidth.c in Sources */,
+ C97A70A81517AF53005E1998 /* frune.c in Sources */,
+ C97A70A91517AF53005E1998 /* isctype.c in Sources */,
+ C97A70AA1517AF53005E1998 /* iswctype.c in Sources */,
+ C97A70AB1517AF53005E1998 /* lconv.c in Sources */,
+ C97A70AC1517AF53005E1998 /* mbrune.c in Sources */,
+ C97A70AD1517AF53005E1998 /* runedepreciated.c in Sources */,
+ C97A70AE1517AF53005E1998 /* setinvalidrune.c in Sources */,
+ C97A70AF1517AF53005E1998 /* xlocale.c in Sources */,
+ C97A70B01517AF53005E1998 /* addr2ascii.c in Sources */,
+ C97A70B11517AF53005E1998 /* ascii2addr.c in Sources */,
+ C97A70B21517AF53005E1998 /* inet_addr.c in Sources */,
+ C97A70B31517AF53005E1998 /* inet_lnaof.c in Sources */,
+ C97A70B41517AF53005E1998 /* inet_makeaddr.c in Sources */,
+ C97A70B51517AF53005E1998 /* inet_net_ntop.c in Sources */,
+ C97A70B61517AF53005E1998 /* inet_net_pton.c in Sources */,
+ C97A70B71517AF53005E1998 /* inet_neta.c in Sources */,
+ C97A70B81517AF53005E1998 /* inet_netof.c in Sources */,
+ C97A70B91517AF53005E1998 /* inet_network.c in Sources */,
+ C97A70BA1517AF53005E1998 /* inet_ntoa.c in Sources */,
+ C97A70BB1517AF53005E1998 /* linkaddr.c in Sources */,
+ C97A70BC1517AF53005E1998 /* nsap_addr.c in Sources */,
+ C97A70BD1517AF53005E1998 /* recv.c in Sources */,
+ C97A70BE1517AF53005E1998 /* send.c in Sources */,
+ C97A70BF1517AF53005E1998 /* sockatmark.c in Sources */,
+ C97A70C01517AF53005E1998 /* sourcefilter.c in Sources */,
+ C97A70C11517AF53005E1998 /* msgcat.c in Sources */,
+ C97A70C21517AF53005E1998 /* acl.c in Sources */,
+ C97A70C31517AF53005E1998 /* acl_entry.c in Sources */,
+ C97A70C41517AF53005E1998 /* acl_file.c in Sources */,
+ C97A70C51517AF53005E1998 /* acl_flag.c in Sources */,
+ C97A70C61517AF53005E1998 /* acl_perm.c in Sources */,
+ C97A70C71517AF53005E1998 /* acl_translate.c in Sources */,
+ C97A70D11517AF53005E1998 /* regerror.c in Sources */,
+ C97A70D21517AF53005E1998 /* chk_fail.c in Sources */,
+ C97A70D31517AF53005E1998 /* memcpy_chk.c in Sources */,
+ C97A70D41517AF53005E1998 /* memmove_chk.c in Sources */,
+ C97A70D51517AF53005E1998 /* memset_chk.c in Sources */,
+ C97A70D61517AF53005E1998 /* snprintf_chk.c in Sources */,
+ C97A70D71517AF53005E1998 /* sprintf_chk.c in Sources */,
+ C97A70D81517AF53005E1998 /* stpcpy_chk.c in Sources */,
+ C97A70D91517AF53005E1998 /* stpncpy_chk.c in Sources */,
+ C97A70DA1517AF53005E1998 /* strcat_chk.c in Sources */,
+ C97A70DB1517AF53005E1998 /* strcpy_chk.c in Sources */,
+ 3FA8F3251643AB8100D37078 /* strlcat_chk.c in Sources */,
+ 3FA8F3261643AB8100D37078 /* strlcpy_chk.c in Sources */,
+ C97A70DC1517AF53005E1998 /* strncat_chk.c in Sources */,
+ C97A70DD1517AF53005E1998 /* strncpy_chk.c in Sources */,
+ C97A70DE1517AF53005E1998 /* vsnprintf_chk.c in Sources */,
+ C97A70DF1517AF53005E1998 /* vsprintf_chk.c in Sources */,
+ C97A70E01517AF53005E1998 /* _flock_stub.c in Sources */,
+ C97A70E11517AF53005E1998 /* asprintf.c in Sources */,
+ C97A70E21517AF53005E1998 /* clrerr.c in Sources */,
+ C97A70E31517AF53005E1998 /* dprintf.c in Sources */,
+ C97A70E41517AF53005E1998 /* fclose.c in Sources */,
+ C97A70E51517AF53005E1998 /* fdopen.c in Sources */,
+ C97A70E61517AF53005E1998 /* feof.c in Sources */,
+ C97A70E71517AF53005E1998 /* ferror.c in Sources */,
+ C97A70E81517AF53005E1998 /* fflush.c in Sources */,
+ C97A70E91517AF53005E1998 /* fgetc.c in Sources */,
+ C97A70EA1517AF53005E1998 /* fgetln.c in Sources */,
+ C97A70EB1517AF53005E1998 /* fgetpos.c in Sources */,
+ C97A70EC1517AF53005E1998 /* fgets.c in Sources */,
+ C97A70ED1517AF53005E1998 /* fgetwc.c in Sources */,
+ C97A70EE1517AF53005E1998 /* fgetwln.c in Sources */,
+ C97A70EF1517AF53005E1998 /* fgetws.c in Sources */,
+ C97A70F01517AF53005E1998 /* fileno.c in Sources */,
+ C97A70F11517AF53005E1998 /* findfp.c in Sources */,
+ C97A70F21517AF53005E1998 /* flags.c in Sources */,
+ 3FD14575171D42B300B7BAF5 /* bcopy.c in Sources */,
+ C97A70F31517AF53005E1998 /* fopen.c in Sources */,
+ C97A70F41517AF53005E1998 /* fprintf.c in Sources */,
+ C97A70F51517AF53005E1998 /* fpurge.c in Sources */,
+ C97A70F61517AF53005E1998 /* fputc.c in Sources */,
+ C97A70F71517AF53005E1998 /* fputs.c in Sources */,
+ C97A70F81517AF53005E1998 /* fputwc.c in Sources */,
+ C97A70F91517AF53005E1998 /* fputws.c in Sources */,
+ C97A70FA1517AF53005E1998 /* fread.c in Sources */,
+ C97A70FB1517AF53005E1998 /* freopen.c in Sources */,
+ C97A70FC1517AF53005E1998 /* fscanf.c in Sources */,
+ C97A70FD1517AF53005E1998 /* fseek.c in Sources */,
+ C97A70FE1517AF53005E1998 /* fsetpos.c in Sources */,
+ C97A70FF1517AF53005E1998 /* ftell.c in Sources */,
+ C97A71001517AF53005E1998 /* funopen.c in Sources */,
+ C97A71011517AF53005E1998 /* fvwrite.c in Sources */,
+ C97A71021517AF53005E1998 /* fwalk.c in Sources */,
+ C97A71031517AF53005E1998 /* fwide.c in Sources */,
+ C97A71041517AF53005E1998 /* fwprintf.c in Sources */,
+ C97A71051517AF53005E1998 /* fwrite.c in Sources */,
+ C97A71061517AF53005E1998 /* fwscanf.c in Sources */,
+ C97A71071517AF53005E1998 /* getc.c in Sources */,
+ C97A71081517AF53005E1998 /* getchar.c in Sources */,
+ C97A71091517AF53005E1998 /* getdelim.c in Sources */,
+ C97A710A1517AF53005E1998 /* getline.c in Sources */,
+ C97A710B1517AF53005E1998 /* gets.c in Sources */,
+ C97A710C1517AF53005E1998 /* getw.c in Sources */,
+ C97A710D1517AF53005E1998 /* getwc.c in Sources */,
+ C97A710E1517AF53005E1998 /* getwchar.c in Sources */,
+ C97A710F1517AF53005E1998 /* makebuf.c in Sources */,
+ C97A71101517AF53005E1998 /* mktemp.c in Sources */,
+ C97A71111517AF53005E1998 /* perror.c in Sources */,
+ C97A71121517AF53005E1998 /* printf-pos.c in Sources */,
+ C97A71131517AF53005E1998 /* printf.c in Sources */,
+ C97A71141517AF53005E1998 /* putc.c in Sources */,
+ C97A71151517AF53005E1998 /* putchar.c in Sources */,
+ C97A71161517AF53005E1998 /* puts.c in Sources */,
+ C97A71171517AF53005E1998 /* putw.c in Sources */,
+ C97A71181517AF53005E1998 /* putwc.c in Sources */,
+ C97A71191517AF53005E1998 /* putwchar.c in Sources */,
+ C97A711A1517AF53005E1998 /* refill.c in Sources */,
+ C97A711B1517AF53005E1998 /* remove.c in Sources */,
+ C97A711C1517AF53005E1998 /* rewind.c in Sources */,
+ C97A711D1517AF53005E1998 /* rget.c in Sources */,
+ C97A711E1517AF53005E1998 /* scanf.c in Sources */,
+ C97A711F1517AF53005E1998 /* setbuf.c in Sources */,
+ C97A71201517AF53005E1998 /* setbuffer.c in Sources */,
+ C97A71211517AF53005E1998 /* setvbuf.c in Sources */,
+ C97A71221517AF53005E1998 /* snprintf.c in Sources */,
+ C97A71231517AF53005E1998 /* sprintf.c in Sources */,
+ C97A71241517AF53005E1998 /* sscanf.c in Sources */,
+ C97A71251517AF53005E1998 /* stdio.c in Sources */,
+ C97A71261517AF53005E1998 /* swprintf.c in Sources */,
+ C97A71271517AF53005E1998 /* swscanf.c in Sources */,
+ C97A71281517AF53005E1998 /* tempnam.c in Sources */,
+ C97A71291517AF53005E1998 /* tmpfile.c in Sources */,
+ C97A712A1517AF53005E1998 /* tmpnam.c in Sources */,
+ C97A712B1517AF53005E1998 /* ungetc.c in Sources */,
+ C97A712C1517AF53005E1998 /* ungetwc.c in Sources */,
+ C97A712D1517AF53005E1998 /* vasprintf.c in Sources */,
+ C97A712E1517AF53005E1998 /* vdprintf.c in Sources */,
+ C97A712F1517AF53005E1998 /* vfprintf.c in Sources */,
+ C97A71301517AF53005E1998 /* vfscanf.c in Sources */,
+ C97A71311517AF53005E1998 /* vfwprintf.c in Sources */,
+ C97A71321517AF53005E1998 /* vfwscanf.c in Sources */,
+ C97A71331517AF53005E1998 /* vprintf.c in Sources */,
+ C97A71341517AF53005E1998 /* vscanf.c in Sources */,
+ C97A71351517AF53005E1998 /* vsnprintf.c in Sources */,
+ C97A71361517AF53005E1998 /* vsprintf.c in Sources */,
+ C97A71371517AF53005E1998 /* vsscanf.c in Sources */,
+ C97A71381517AF53005E1998 /* vswprintf.c in Sources */,
+ C97A71391517AF53005E1998 /* vswscanf.c in Sources */,
+ C97A713A1517AF53005E1998 /* vwprintf.c in Sources */,
+ C97A713B1517AF53005E1998 /* vwscanf.c in Sources */,
+ C97A713C1517AF53005E1998 /* wbuf.c in Sources */,
+ C97A713D1517AF53005E1998 /* wprintf.c in Sources */,
+ C97A713E1517AF53005E1998 /* wscanf.c in Sources */,
+ C97A713F1517AF53005E1998 /* wsetup.c in Sources */,
+ C97A71401517AF53005E1998 /* a64l.c in Sources */,
+ C97A71411517AF53005E1998 /* _Exit_.c in Sources */,
+ C97A71421517AF53005E1998 /* abort.c in Sources */,
+ C97A71431517AF53005E1998 /* abs.c in Sources */,
+ C97A71441517AF53005E1998 /* atexit.c in Sources */,
+ C97A71451517AF53005E1998 /* atof.c in Sources */,
+ C97A71461517AF53005E1998 /* atoi.c in Sources */,
+ C97A71471517AF53005E1998 /* atol.c in Sources */,
+ C97A71481517AF53005E1998 /* atoll.c in Sources */,
+ C97A71491517AF53005E1998 /* bsearch.c in Sources */,
+ C97A714A1517AF53005E1998 /* div.c in Sources */,
+ C97A714B1517AF53005E1998 /* exit.c in Sources */,
+ C97A714C1517AF53005E1998 /* getenv.c in Sources */,
+ C97A714D1517AF53005E1998 /* getopt.c in Sources */,
+ C97A714E1517AF53005E1998 /* getopt_long.c in Sources */,
+ C97A714F1517AF53005E1998 /* getsubopt.c in Sources */,
+ C97A71501517AF53005E1998 /* hcreate.c in Sources */,
+ C97A71511517AF53005E1998 /* heapsort.c in Sources */,
+ C97A71521517AF53005E1998 /* heapsort_b.c in Sources */,
+ C97A71531517AF53005E1998 /* heapsort_r.c in Sources */,
+ C97A71541517AF53005E1998 /* imaxabs.c in Sources */,
+ C97A71551517AF53005E1998 /* imaxdiv.c in Sources */,
+ C97A71561517AF53005E1998 /* insque.c in Sources */,
+ C97A71571517AF53005E1998 /* labs.c in Sources */,
+ C97A71581517AF53005E1998 /* ldiv.c in Sources */,
+ C97A71591517AF53005E1998 /* llabs.c in Sources */,
+ C97A715A1517AF53005E1998 /* lldiv.c in Sources */,
+ C97A715B1517AF53005E1998 /* lsearch.c in Sources */,
+ C97A715C1517AF53005E1998 /* merge.c in Sources */,
+ C97A715D1517AF53005E1998 /* putenv.c in Sources */,
+ C97A715E1517AF53005E1998 /* qsort.c in Sources */,
+ C97A715F1517AF53005E1998 /* qsort_r.c in Sources */,
+ C97A71601517AF53005E1998 /* radixsort.c in Sources */,
+ C97A71611517AF53005E1998 /* rand.c in Sources */,
+ C97A71621517AF53005E1998 /* random.c in Sources */,
+ C97A71631517AF53005E1998 /* reallocf.c in Sources */,
+ C97A71641517AF53005E1998 /* realpath.c in Sources */,
+ C97A71651517AF53005E1998 /* remque.c in Sources */,
+ C97A71661517AF53005E1998 /* setenv.c in Sources */,
+ C97A71671517AF53005E1998 /* strhash.c in Sources */,
+ C97A71681517AF53005E1998 /* strtoimax.c in Sources */,
+ C97A71691517AF53005E1998 /* strtol.c in Sources */,
+ C97A716A1517AF53005E1998 /* strtoll.c in Sources */,
+ C97A716B1517AF53005E1998 /* strtoq.c in Sources */,
+ C97A716C1517AF53005E1998 /* strtoul.c in Sources */,
+ C97A716D1517AF53005E1998 /* strtoull.c in Sources */,
+ C97A716E1517AF53005E1998 /* strtoumax.c in Sources */,
+ C97A716F1517AF53005E1998 /* strtouq.c in Sources */,
+ C97A71701517AF53005E1998 /* system.c in Sources */,
+ C97A71711517AF53005E1998 /* tdelete.c in Sources */,
+ C97A71721517AF53005E1998 /* tfind.c in Sources */,
+ C97A71731517AF53005E1998 /* tsearch.c in Sources */,
+ C97A71741517AF53005E1998 /* twalk.c in Sources */,
+ C97A71751517AF53005E1998 /* grantpt.c in Sources */,
+ C97A71761517AF53005E1998 /* l64a.c in Sources */,
+ C97A71771517AF53005E1998 /* strfmon.c in Sources */,
+ C97A71781517AF53005E1998 /* ecvt.c in Sources */,
+ C97A71791517AF53005E1998 /* gcvt.c in Sources */,
+ C97A717A1517AF53005E1998 /* qsort_b-fbsd.c in Sources */,
+ C97A717B1517AF53005E1998 /* asctime.c in Sources */,
+ C97A717C1517AF53005E1998 /* difftime.c in Sources */,
+ C97A717D1517AF53005E1998 /* ftime.c in Sources */,
+ C97A717E1517AF53005E1998 /* localtime.c in Sources */,
+ C97A717F1517AF53005E1998 /* strftime.c in Sources */,
+ C97A71801517AF53005E1998 /* strptime.c in Sources */,
+ C97A71811517AF53005E1998 /* time32.c in Sources */,
+ C97A71821517AF53005E1998 /* timelocal.c in Sources */,
+ C97A71831517AF53005E1998 /* getdate.c in Sources */,
+ C97A71841517AF53005E1998 /* timezone_unix03.c in Sources */,
+ C97A71881517AF53005E1998 /* index.c in Sources */,
+ C97A718D1517AF53005E1998 /* memmem.c in Sources */,
+ C97A71901517AF53005E1998 /* rindex.c in Sources */,
+ C97A71911517AF53005E1998 /* strcasecmp.c in Sources */,
+ C97A71921517AF53005E1998 /* strcasestr.c in Sources */,
+ C97A71951517AF53005E1998 /* strcoll.c in Sources */,
+ C97A71961517AF53005E1998 /* strcspn.c in Sources */,
+ C97A71971517AF53005E1998 /* strdup.c in Sources */,
+ C97A71981517AF53005E1998 /* strerror.c in Sources */,
+ C97A71991517AF53005E1998 /* strlen.c in Sources */,
+ C97A719A1517AF53005E1998 /* strmode.c in Sources */,
+ C97A719C1517AF53005E1998 /* strndup.c in Sources */,
+ C97A719D1517AF53005E1998 /* strnlen.c in Sources */,
+ C97A719E1517AF53005E1998 /* strnstr.c in Sources */,
+ C97A719F1517AF53005E1998 /* strpbrk.c in Sources */,
+ C97A71A01517AF53005E1998 /* strrchr.c in Sources */,
+ C97A71A11517AF53005E1998 /* strsep.c in Sources */,
+ C97A71A21517AF53005E1998 /* strsignal.c in Sources */,
+ C97A71A31517AF53005E1998 /* strspn.c in Sources */,
+ C97A71A41517AF53005E1998 /* strstr.c in Sources */,
+ C97A71A51517AF53005E1998 /* strtok.c in Sources */,
+ C97A71A61517AF53005E1998 /* strxfrm.c in Sources */,
+ C97A71A71517AF53005E1998 /* swab.c in Sources */,
+ C97A71A81517AF53005E1998 /* wcpcpy.c in Sources */,
+ C97A71A91517AF53005E1998 /* wcpncpy.c in Sources */,
+ C97A71AA1517AF53005E1998 /* wcscasecmp.c in Sources */,
+ C97A71AB1517AF53005E1998 /* wcscat.c in Sources */,
+ C97A71AC1517AF53005E1998 /* wcschr.c in Sources */,
+ C97A71AD1517AF53005E1998 /* wcscmp.c in Sources */,
+ C97A71AE1517AF53005E1998 /* wcscoll.c in Sources */,
+ C97A71AF1517AF53005E1998 /* wcscpy.c in Sources */,
+ C97A71B01517AF53005E1998 /* wcscspn.c in Sources */,
+ C97A71B11517AF53005E1998 /* wcsdup.c in Sources */,
+ C97A71B21517AF53005E1998 /* wcslcat.c in Sources */,
+ C97A71B31517AF53005E1998 /* wcslcpy.c in Sources */,
+ C97A71B41517AF53005E1998 /* wcslen.c in Sources */,
+ C97A71B51517AF53005E1998 /* wcsncasecmp.c in Sources */,
+ C97A71B61517AF53005E1998 /* wcsncat.c in Sources */,
+ C97A71B71517AF53005E1998 /* wcsncmp.c in Sources */,
+ C97A71B81517AF53005E1998 /* wcsncpy.c in Sources */,
+ C97A71B91517AF53005E1998 /* wcsnlen.c in Sources */,
+ C97A71BA1517AF53005E1998 /* wcspbrk.c in Sources */,
+ C97A71BB1517AF53005E1998 /* wcsrchr.c in Sources */,
+ C97A71BC1517AF53005E1998 /* wcsspn.c in Sources */,
+ C97A71BD1517AF53005E1998 /* wcsstr.c in Sources */,
+ C97A71BE1517AF53005E1998 /* wcstok.c in Sources */,
+ C97A71BF1517AF53005E1998 /* wcswidth.c in Sources */,
+ C97A71C01517AF53005E1998 /* wcsxfrm.c in Sources */,
+ C97A71C11517AF53005E1998 /* wmemchr.c in Sources */,
+ C97A71C21517AF53005E1998 /* wmemcmp.c in Sources */,
+ C97A71C31517AF53005E1998 /* wmemcpy.c in Sources */,
+ C97A71C41517AF53005E1998 /* wmemmove.c in Sources */,
+ C97A71C51517AF53005E1998 /* wmemset.c in Sources */,
+ C97A71C61517AF53005E1998 /* __libc_init.c in Sources */,
+ C97A71C71517AF53005E1998 /* _libc_fork_child.c in Sources */,
+ C97A71C81517AF53005E1998 /* chmodx_np.c in Sources */,
+ C97A71CA1517AF53005E1998 /* crt_externs.c in Sources */,
+ C97A71CC1517AF53005E1998 /* fork.c in Sources */,
+ C97A71CD1517AF53005E1998 /* getgroups.c in Sources */,
+ C97A71CF1517AF53005E1998 /* gettimeofday.c in Sources */,
+ C97A71D01517AF53005E1998 /* msgctl.c in Sources */,
+ C97A71D11517AF53005E1998 /* stack_protector.c in Sources */,
+ C97A71D21517AF53005E1998 /* openx_np.c in Sources */,
+ C97A71D31517AF53005E1998 /* OSMemoryNotification.c in Sources */,
+ C97A71D41517AF53005E1998 /* OSThermalNotification.c in Sources */,
+ C97A71D51517AF53005E1998 /* posix_spawn.c in Sources */,
+ C97A71D61517AF53005E1998 /* semctl.c in Sources */,
+ C97A71D71517AF53005E1998 /* settimeofday.c in Sources */,
+ C97A71D81517AF53005E1998 /* shmctl.c in Sources */,
+ C97A71D91517AF53005E1998 /* sigaction.c in Sources */,
+ C97A71DA1517AF53005E1998 /* (null) in Sources */,
+ C97A71DD1517AF53005E1998 /* statx_np.c in Sources */,
+ C97A71DE1517AF53005E1998 /* umaskx_np.c in Sources */,
+ C97A71E21517AF53005E1998 /* fparseln.c in Sources */,
+ C97A71E31517AF53005E1998 /* login.c in Sources */,
+ C97A71E41517AF53005E1998 /* login_tty.c in Sources */,
+ C97A71E51517AF53005E1998 /* logout.c in Sources */,
+ C97A71E61517AF53005E1998 /* logwtmp.c in Sources */,
+ C97A71E71517AF53005E1998 /* mkpath_np.c in Sources */,
+ C97A71E81517AF53005E1998 /* opendev.c in Sources */,
+ C97A71E91517AF53005E1998 /* pty.c in Sources */,
+ C97A71EA1517AF53005E1998 /* clear.c in Sources */,
+ C97A71EB1517AF53005E1998 /* compare.c in Sources */,
+ C97A71EC1517AF53005E1998 /* copy.c in Sources */,
+ C97A71ED1517AF53005E1998 /* gen_uuid.c in Sources */,
+ C97A71EE1517AF53005E1998 /* isnull.c in Sources */,
+ C97A71EF1517AF53005E1998 /* pack.c in Sources */,
+ C97A71F01517AF53005E1998 /* parse.c in Sources */,
+ C97A71F11517AF53005E1998 /* unpack.c in Sources */,
+ C97A71F21517AF53005E1998 /* unparse.c in Sources */,
+ C97A71F71517AF53005E1998 /* (null) in Sources */,
+ C97A71F81517AF53005E1998 /* (null) in Sources */,
+ C97A71F91517AF53005E1998 /* (null) in Sources */,
+ C97A71FA1517AF53005E1998 /* (null) in Sources */,
+ C97A71FD1517AF53005E1998 /* scandir_b.c in Sources */,
+ C97A71FF1517AF53005E1998 /* init_cpu_capabilities.c in Sources */,
+ C97A72001517AF53005E1998 /* pthread_getspecific.s in Sources */,
+ C97A72011517AF53005E1998 /* pthread_self.s in Sources */,
+ C97A72021517AF53005E1998 /* pthread_set_self.s in Sources */,
+ C97A72031517AF53005E1998 /* start_wqthread.s in Sources */,
+ C97A72041517AF53005E1998 /* thread_start.s in Sources */,
+ C97A720D1517AF53005E1998 /* strcpy.c in Sources */,
+ C97A720E1517AF53005E1998 /* strlcpy.c in Sources */,
+ C97A720F1517AF53005E1998 /* strncpy.c in Sources */,
+ C97A72101517AF53005E1998 /* stpcpy.c in Sources */,
+ C97A72111517AF53005E1998 /* stpncpy.c in Sources */,
+ C97A72121517AF53005E1998 /* strcat.c in Sources */,
+ C97A72131517AF53005E1998 /* strncat.c in Sources */,
+ C97A72141517AF53005E1998 /* strlcat.c in Sources */,
+ C97A72161517AF53005E1998 /* sync_volume_np.c in Sources */,
+ C97A72171517AF53005E1998 /* dirfd.c in Sources */,
+ C925D1FD1518F4A2003D315B /* eos_stubs.c in Sources */,
+ 63505E3C1548525D00B637D7 /* strnlen.s in Sources */,
+ 4B2C64A415519BC400342BFA /* assumes.c in Sources */,
+ FC2ED611157D4BE80098EC69 /* inet_ntop.c in Sources */,
+ FC2ED61A157D4BE80098EC69 /* inet_pton.c in Sources */,
+ 2B9D61B9157D667600AF25B8 /* trace.c in Sources */,
+ 3F169A3E1643B7BA0029E851 /* memccpy_chk.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- C9EB2F82138F68CB0075BB52 /* cpu_number.s in Sources */,
- C9EB2F83138F68CB0075BB52 /* icacheinval.s in Sources */,
C9EB2F84138F68CB0075BB52 /* init_cpu_capabilities.c in Sources */,
- C9EB2F85138F68CB0075BB52 /* pthread_getspecific.s in Sources */,
- C9EB2F86138F68CB0075BB52 /* pthread_self.s in Sources */,
- C9EB2F87138F68CB0075BB52 /* pthread_set_self.s in Sources */,
- C9EB2F88138F68CB0075BB52 /* start_wqthread.s in Sources */,
- C9EB2F89138F68CB0075BB52 /* thread_start.s in Sources */,
- C9EB2F8B138F68CB0075BB52 /* bcopy_CortexA8.s in Sources */,
- C9EB2F8C138F68CB0075BB52 /* bcopy_CortexA9.s in Sources */,
- C9EB2F8D138F68CB0075BB52 /* bcopy_Generic.s in Sources */,
- C9EB2F8E138F68CB0075BB52 /* bzero_CortexA8.s in Sources */,
- C9EB2F8F138F68CB0075BB52 /* bzero_CortexA9.s in Sources */,
- C9EB2F90138F68CB0075BB52 /* bzero_Generic.s in Sources */,
- C9EB2F91138F68CB0075BB52 /* dyld_resolvers.c in Sources */,
- C9EB2F92138F68CB0075BB52 /* ffs.s in Sources */,
- C9EB2F93138F68CB0075BB52 /* memcmp.s in Sources */,
- C9EB2F94138F68CB0075BB52 /* memset_pattern.s in Sources */,
- C9EB2F95138F68CB0075BB52 /* strchr.s in Sources */,
- C9EB2F96138F68CB0075BB52 /* strcmp.s in Sources */,
C9EB2F99138F68CB0075BB52 /* strlen.s in Sources */,
- C9EB2F9A138F68CB0075BB52 /* strncmp.s in Sources */,
C9EB2F9C138F68CB0075BB52 /* strnlen.s in Sources */,
C9EB2F9D138F68CB0075BB52 /* strstr.s in Sources */,
- C9EB2F9E138F68CB0075BB52 /* _longjmp.s in Sources */,
- C9EB2FA0138F68CB0075BB52 /* _setjmp.s in Sources */,
- C9EB2FA1138F68CB0075BB52 /* arm_commpage_gettimeofday.c in Sources */,
- C9EB2FA2138F68CB0075BB52 /* gcc_atomic.c in Sources */,
- C9EB2FA3138F68CB0075BB52 /* longjmp.s in Sources */,
- C9EB2FA4138F68CB0075BB52 /* mach_absolute_time.s in Sources */,
- C9EB2FA5138F68CB0075BB52 /* OSAtomic-v4.c in Sources */,
- C9EB2FA7138F68CB0075BB52 /* OSAtomic_resolvers.c in Sources */,
- C9EB2FA9138F68CB0075BB52 /* setjmp.s in Sources */,
- C9EB2F4C138F68A80075BB52 /* _ctx_start.S in Sources */,
- C9EB2F4D138F68A80075BB52 /* _setcontext.S in Sources */,
- C9EB2F4E138F68A80075BB52 /* cpu_number.s in Sources */,
- C9EB2F4F138F68A80075BB52 /* getcontext.S in Sources */,
- C9EB2F50138F68A80075BB52 /* getmcontext.c in Sources */,
- C9EB2F51138F68A80075BB52 /* icacheinval.s in Sources */,
- C9EB2F52138F68A80075BB52 /* makecontext.c in Sources */,
C9EB2F53138F68A80075BB52 /* mcount.s in Sources */,
- C9EB2F54138F68A80075BB52 /* setcontext.c in Sources */,
- C9EB2F55138F68A80075BB52 /* setjmperr.c in Sources */,
- C9EB2F56138F68A80075BB52 /* swapcontext.c in Sources */,
- C9EB2F57138F68A80075BB52 /* init_cpu_capabilities.c in Sources */,
- C9EB2F58138F68A80075BB52 /* preempt.s in Sources */,
- C9EB2F59138F68A80075BB52 /* pthread_getspecific.s in Sources */,
- C9EB2F5A138F68A80075BB52 /* pthread_mutex_lock.s in Sources */,
- C9EB2F5B138F68A80075BB52 /* pthread_self.s in Sources */,
- C9EB2F5C138F68A80075BB52 /* pthread_set_self.s in Sources */,
- C9EB2F5D138F68A80075BB52 /* start_wqthread.s in Sources */,
- C9EB2F5E138F68A80075BB52 /* thread_start.s in Sources */,
- C9EB2F60138F68A80075BB52 /* __bzero.s in Sources */,
- C9EB2F61138F68A80075BB52 /* bcopy.c in Sources */,
- C9EB2F62138F68A80075BB52 /* bcopy_scalar.s in Sources */,
- C9EB2F63138F68A80075BB52 /* bcopy_sse2.s in Sources */,
- C9EB2F64138F68A80075BB52 /* bcopy_sse3x.s in Sources */,
- C9EB2F65138F68A80075BB52 /* bcopy_sse42.s in Sources */,
- C9EB2F66138F68A80075BB52 /* bzero.c in Sources */,
- C9EB2F67138F68A80075BB52 /* bzero_scalar.s in Sources */,
- C9EB2F68138F68A80075BB52 /* bzero_sse2.s in Sources */,
- C9EB2F69138F68A80075BB52 /* bzero_sse42.s in Sources */,
- C9EB2F6A138F68A80075BB52 /* ffs.s in Sources */,
- C9EB2F6B138F68A80075BB52 /* longcopy_sse3x.s in Sources */,
- C9EB2F6C138F68A80075BB52 /* memcmp.s in Sources */,
- C9EB2F6D138F68A80075BB52 /* memcpy.c in Sources */,
- C9EB2F6E138F68A80075BB52 /* memmove.c in Sources */,
- C9EB2F6F138F68A80075BB52 /* memset.s in Sources */,
- C9EB2F70138F68A80075BB52 /* memset_pattern_sse2.s in Sources */,
- C9EB2F71138F68A80075BB52 /* strcmp.s in Sources */,
C9EB2F72138F68A80075BB52 /* strcpy.s in Sources */,
C9EB2F73138F68A80075BB52 /* strlcat.s in Sources */,
C9EB2F74138F68A80075BB52 /* strlcpy.s in Sources */,
C9EB2F75138F68A80075BB52 /* strlen.s in Sources */,
- C9EB2F76138F68A80075BB52 /* strncmp.s in Sources */,
C9EB2F77138F68A80075BB52 /* strncpy.s in Sources */,
- C9EB2F78138F68A80075BB52 /* _setjmp.s in Sources */,
- C9EB2F79138F68A80075BB52 /* _sigtramp.s in Sources */,
- C9EB2F7A138F68A80075BB52 /* atomic.c in Sources */,
- C9EB2F7B138F68A80075BB52 /* i386_gettimeofday_asm.s in Sources */,
- C9EB2F7D138F68A80075BB52 /* mach_absolute_time_asm.s in Sources */,
- C9EB2F7E138F68A80075BB52 /* OSAtomic.s in Sources */,
- C9EB2F7F138F68A80075BB52 /* setjmp.s in Sources */,
- C9EB2F80138F68A80075BB52 /* spinlocks.c in Sources */,
- C9EB2F81138F68A80075BB52 /* spinlocks_asm.s in Sources */,
- C9B53E57138DA5910028D27C /* _ctx_start.S in Sources */,
- C9B53E58138DA5910028D27C /* _setcontext.S in Sources */,
- C9B53E59138DA5910028D27C /* cpu_number.s in Sources */,
- C9B53E5A138DA5910028D27C /* getcontext.S in Sources */,
- C9B53E5B138DA5910028D27C /* getmcontext.c in Sources */,
- C9B53E5C138DA5910028D27C /* icacheinval.s in Sources */,
- C9B53E5D138DA5910028D27C /* makecontext.c in Sources */,
C9B53E5E138DA5910028D27C /* mcount.s in Sources */,
- C9B53E5F138DA5910028D27C /* setcontext.c in Sources */,
- C9B53E60138DA5910028D27C /* swapcontext.c in Sources */,
- C9B53E62138DA5950028D27C /* preempt.s in Sources */,
- C9B53E63138DA5950028D27C /* pthread_getspecific.s in Sources */,
- C9B53E64138DA5950028D27C /* pthread_mutex_lock.s in Sources */,
- C9B53E65138DA5950028D27C /* pthread_self.s in Sources */,
- C9B53E66138DA5950028D27C /* pthread_set_self.s in Sources */,
- C9B53E67138DA5950028D27C /* start_wqthread.s in Sources */,
- C9B53E68138DA5950028D27C /* thread_start.s in Sources */,
- C9B53E69138DA59F0028D27C /* __bzero.s in Sources */,
- C9B53E6A138DA59F0028D27C /* bcopy.c in Sources */,
- C9B53E6B138DA59F0028D27C /* bcopy_sse3x.s in Sources */,
- C9B53E6C138DA59F0028D27C /* bcopy_sse42.s in Sources */,
- C9B53E6D138DA59F0028D27C /* bzero.c in Sources */,
- C9B53E6E138DA59F0028D27C /* bzero_sse2.s in Sources */,
- C9B53E6F138DA59F0028D27C /* bzero_sse42.s in Sources */,
- C9B53E70138DA59F0028D27C /* ffs.s in Sources */,
- C9B53E71138DA59F0028D27C /* longcopy_sse3x.s in Sources */,
- C9B53E72138DA59F0028D27C /* memcmp.s in Sources */,
- C9B53E73138DA59F0028D27C /* memcpy.c in Sources */,
- C9B53E74138DA59F0028D27C /* memmove.c in Sources */,
- C9B53E75138DA59F0028D27C /* memset.s in Sources */,
- C9B53E76138DA59F0028D27C /* strcmp.s in Sources */,
C9B53E77138DA59F0028D27C /* strcpy.s in Sources */,
- C9B53E78138DA59F0028D27C /* strlcat.s in Sources */,
- C9B53E79138DA59F0028D27C /* strlcpy.s in Sources */,
C9B53E7A138DA59F0028D27C /* strlen.s in Sources */,
- C9B53E7B138DA59F0028D27C /* strncmp.s in Sources */,
C9B53E7C138DA59F0028D27C /* strncpy.s in Sources */,
- C9B53E7D138DA5A30028D27C /* _setjmp.s in Sources */,
- C9B53E7E138DA5A30028D27C /* _sigtramp.s in Sources */,
- C9B53E7F138DA5A30028D27C /* atomic.c in Sources */,
- C9B53E80138DA5A30028D27C /* i386_gettimeofday_asm.s in Sources */,
- C9B53E81138DA5A30028D27C /* nanotime.s in Sources */,
- C9B53E82138DA5A30028D27C /* OSAtomic.s in Sources */,
- C9B53E83138DA5A30028D27C /* setjmp.s in Sources */,
- C9B53E84138DA5A30028D27C /* spinlocks.c in Sources */,
- C9B53E85138DA5A30028D27C /* spinlocks_asm.s in Sources */,
- C9EB3556138F7F6A0075BB52 /* setjmperr.c in Sources */,
- 6358199113B53DD800CDF61C /* bzero_Swift.s in Sources */,
- 6358199313B53ECC00CDF61C /* bcopy_Swift.s in Sources */,
- 634C4C3813BCEADC008CA66D /* memset_pattern_Swift.s in Sources */,
- C995462813AAA25000A531B4 /* OSAtomicUP.c in Sources */,
- C97C344113AB0E1B00713550 /* Spinlocks.c in Sources */,
- C980F8EC13AB168D0069AB06 /* SpinlocksUP.c in Sources */,
- C932C2D013AB1C73004EDA12 /* SpinlocksWFE.c in Sources */,
- C9B4E3D813BBBF2D0008A9BB /* OSAtomic.c in Sources */,
+ C921D3891395B7DD001CE070 /* init_cpu_capabilities.c in Sources */,
+ C921D38A1395B7DD001CE070 /* pthread_getspecific.s in Sources */,
+ C921D38B1395B7DD001CE070 /* pthread_self.s in Sources */,
+ C921D38C1395B7DD001CE070 /* pthread_set_self.s in Sources */,
+ C921D38D1395B7DD001CE070 /* start_wqthread.s in Sources */,
+ C921D38E1395B7DD001CE070 /* thread_start.s in Sources */,
+ 63505E3D1548525D00B637D7 /* strnlen.s in Sources */,
+ 639D126C15595DDE00D0403A /* strnlen.s in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- C9258122138E3CA100B3107C /* magmallocProvider.d in Sources */,
C9C2A95C138E03C700287F00 /* dirhelper.defs in Sources */,
- C9C2A99C138E06D900287F00 /* asl_ipc.defs in Sources */,
C9C2A959138E025700287F00 /* sigaltstk.c in Sources */,
C9C2A95A138E025700287F00 /* sigcompat.c in Sources */,
- C9C2A95D138E03C700287F00 /* libproc.c in Sources */,
- C9C2A95E138E03C700287F00 /* proc_listpidspath.c in Sources */,
C9C2A97D138E058200287F00 /* brk.c in Sources */,
C9C2A97E138E058200287F00 /* bsd_signal.c in Sources */,
C9C2A97F138E058200287F00 /* lchflags.c in Sources */,
C9C2A980138E058200287F00 /* lchmod.c in Sources */,
C9C2A981138E058200287F00 /* lutimes.c in Sources */,
C9C2A982138E058200287F00 /* statvfs.c in Sources */,
- C9C2A9A1138E06D900287F00 /* assumes.c in Sources */,
C9C2A9A2138E06D900287F00 /* backtrace.c in Sources */,
- C9C2A9A3138E06D900287F00 /* cache.c in Sources */,
C9C2A9A4138E06D900287F00 /* confstr.c in Sources */,
C9C2A9A5138E06D900287F00 /* crypt.c in Sources */,
C9C2A9A6138E06D900287F00 /* devname.c in Sources */,
C9C2A9AD138E072500287F00 /* getttyent.c in Sources */,
C9C2A9AE138E072500287F00 /* getusershell.c in Sources */,
C9C2A9AF138E072500287F00 /* getvfsbyname.c in Sources */,
- C9C2A9B0138E072500287F00 /* isinf.c in Sources */,
- C9C2A9B1138E072500287F00 /* isnan.c in Sources */,
C9C2A9B5138E072500287F00 /* nanosleep.c in Sources */,
C9C2A9B6138E072500287F00 /* nftw.c in Sources */,
- C9C2A9B7138E072500287F00 /* platfunc.c in Sources */,
C9C2A9B8138E072500287F00 /* setlogin.c in Sources */,
C9C2A9B9138E072600287F00 /* sigsetops.c in Sources */,
- C9C2A9BA138E072600287F00 /* stack_logging.c in Sources */,
- C9C2A9BB138E072600287F00 /* stack_logging_disk.c in Sources */,
C9C2A9BC138E072600287F00 /* strtofflags.c in Sources */,
- C9C2A9BD138E072600287F00 /* syslog.c in Sources */,
C9C2A9BE138E072600287F00 /* thread_stack_pcs.c in Sources */,
C9C2A9BF138E072600287F00 /* uname.c in Sources */,
C9C2A9C0138E072600287F00 /* utmpx-darwin.c in Sources */,
C9C2A9C1138E072600287F00 /* wordexp.c in Sources */,
C9A12853138E0BE00003880A /* gmon.c in Sources */,
C9A12854138E0C1C0003880A /* isctype.c in Sources */,
+ 3FD14576171D42B300B7BAF5 /* bcopy.c in Sources */,
C9A12855138E0C1C0003880A /* iswctype.c in Sources */,
C9A12856138E0C1C0003880A /* xlocale.c in Sources */,
C9A128A0138E0CD10003880A /* acl.c in Sources */,
C9A128A3138E0CD10003880A /* acl_flag.c in Sources */,
C9A128A4138E0CD10003880A /* acl_perm.c in Sources */,
C9A128A5138E0CD10003880A /* acl_translate.c in Sources */,
- C9A128A6138E0D0B0003880A /* pthread.c in Sources */,
- C9A128A7138E0D0B0003880A /* pthread_cancelable.c in Sources */,
- C9A128A8138E0D0B0003880A /* pthread_cond.c in Sources */,
- C9A128A9138E0D0B0003880A /* pthread_mutex.c in Sources */,
- C9A128AA138E0D0B0003880A /* pthread_rwlock.c in Sources */,
- C9A128AB138E0D0B0003880A /* pthread_tsd.c in Sources */,
- C9A128AC138E0D0B0003880A /* stack.s in Sources */,
- C9A128AD138E0D0B0003880A /* thread_setup.c in Sources */,
- C9A128B3138E0D950003880A /* chk_fail.c in Sources */,
- C9A128B4138E0D950003880A /* memcpy_chk.c in Sources */,
- C9A128B5138E0D950003880A /* memmove_chk.c in Sources */,
- C9A128B6138E0D950003880A /* memset_chk.c in Sources */,
- C9A128B7138E0D950003880A /* snprintf_chk.c in Sources */,
- C9A128B8138E0D950003880A /* sprintf_chk.c in Sources */,
- C9A128B9138E0D950003880A /* stpcpy_chk.c in Sources */,
- C9A128BA138E0D950003880A /* stpncpy_chk.c in Sources */,
- C9A128BB138E0D950003880A /* strcat_chk.c in Sources */,
- C9A128BC138E0D950003880A /* strcpy_chk.c in Sources */,
- C9A128BD138E0D950003880A /* strncat_chk.c in Sources */,
- C9A128BE138E0D950003880A /* strncpy_chk.c in Sources */,
- C9A128BF138E0D950003880A /* vsnprintf_chk.c in Sources */,
- C9A128C0138E0D950003880A /* vsprintf_chk.c in Sources */,
C9A12929138E0EF00003880A /* getdate.c in Sources */,
C9A1292A138E0EF00003880A /* timezone_unix03.c in Sources */,
- C9A12974138E10AB0003880A /* cprocs.c in Sources */,
- C9A12975138E10AB0003880A /* cthreads.c in Sources */,
- C9A12976138E10AB0003880A /* mig_support.c in Sources */,
+ B1795373158B0E35008990E8 /* xprintf_all_in_one.c in Sources */,
+ B126140515881A000077E3CC /* xprintf_comp.c in Sources */,
+ B126140615881A000077E3CC /* xprintf_domain.c in Sources */,
+ B1795374158B0E35008990E8 /* xprintf_exec.c in Sources */,
C9A12977138E10C40003880A /* fparseln.c in Sources */,
C9A12978138E10C40003880A /* login_tty.c in Sources */,
C9A12979138E10C40003880A /* logwtmp.c in Sources */,
C9A12984138E10FB0003880A /* unparse.c in Sources */,
C9C2A95B138E03C700287F00 /* _dirhelper.c in Sources */,
C9C2A983138E058200287F00 /* tcgetsid.c in Sources */,
- C9C2A998138E06D900287F00 /* _simple.c in Sources */,
- C9C2A999138E06D900287F00 /* asl.c in Sources */,
- C9C2A99A138E06D900287F00 /* asl_core.c in Sources */,
- C9C2A99B138E06D900287F00 /* asl_file.c in Sources */,
- C9C2A99D138E06D900287F00 /* asl_legacy1.c in Sources */,
- C9C2A99E138E06D900287F00 /* asl_msg.c in Sources */,
- C9C2A99F138E06D900287F00 /* asl_store.c in Sources */,
- C9C2A9A0138E06D900287F00 /* asl_util.c in Sources */,
- C9C2A9B4138E072500287F00 /* malloc.c in Sources */,
- C9C2A9B2138E072500287F00 /* magazine_malloc.c in Sources */,
C9FA32FB138E4BD00089A94B /* __libc_init.c in Sources */,
C9FA32FC138E4BD00089A94B /* _libc_fork_child.c in Sources */,
C9FA32FD138E4BD00089A94B /* chmodx_np.c in Sources */,
- C9FA32FE138E4BD00089A94B /* context-stubs.c in Sources */,
C9FA32FF138E4BD00089A94B /* crt_externs.c in Sources */,
- C9FA3300138E4BD00089A94B /* errno.c in Sources */,
C9FA3301138E4BD00089A94B /* fork.c in Sources */,
- C9FA3302138E4BD00089A94B /* getiopolicy_np.c in Sources */,
C9FA3303138E4BD00089A94B /* gettimeofday.c in Sources */,
C9FA3304138E4BD00089A94B /* openx_np.c in Sources */,
C9FA3307138E4BD00089A94B /* posix_spawn.c in Sources */,
C9FA3308138E4BD00089A94B /* settimeofday.c in Sources */,
C9FA3309138E4BD00089A94B /* sigaction.c in Sources */,
- C9FA330A138E4BD00089A94B /* sigcatch.c in Sources */,
- C9FA330B138E4BD00089A94B /* sigtramp.c in Sources */,
- C9FA330C138E4BD00089A94B /* slot_name.c in Sources */,
C9FA330D138E4BD00089A94B /* statx_np.c in Sources */,
C9FA330E138E4BD00089A94B /* umaskx_np.c in Sources */,
C9421014138F23CA004BA536 /* frune.c in Sources */,
C9EB3543138F7D0A0075BB52 /* logout.c in Sources */,
C9EB3558138F7FF40075BB52 /* nlist.c in Sources */,
C9EB355C138F81A40075BB52 /* kvm.c in Sources */,
- C9EB355E138F81AB0075BB52 /* MKGetTimeBaseInfo.c in Sources */,
C98373971395989E00E5C052 /* OSMemoryNotification.c in Sources */,
C98373981395989E00E5C052 /* OSThermalNotification.c in Sources */,
- C9CF595A13CD0B9600674871 /* memset_pattern.c in Sources */,
6310518A13D4D9E9004F7BA8 /* strcpy.c in Sources */,
6310518D13D4DABD004F7BA8 /* strlcpy.c in Sources */,
6310519013D4DAEA004F7BA8 /* strncpy.c in Sources */,
63D4060E13DDF26A0094DD56 /* strcat.c in Sources */,
63D4061113DDF4340094DD56 /* strncat.c in Sources */,
63D4061413DDF6A30094DD56 /* strlcat.c in Sources */,
- 3F2208E914358B4A00386F5B /* asl_fd.c in Sources */,
B19C645D1450F90200032373 /* sync_volume_np.c in Sources */,
3FB7E1B5146EF2E000843438 /* dirfd.c in Sources */,
+ 4B2C64BA1551B03700342BFA /* assumes.c in Sources */,
+ 2B9D61C0157D667C00AF25B8 /* trace.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
buildActionMask = 2147483647;
files = (
C9765EB2138EC61900741512 /* init_cpu_capabilities.c in Sources */,
- C9765EB3138EC61900741512 /* dyld_resolvers.c in Sources */,
- C9765EB4138EC61900741512 /* arm_commpage_gettimeofday.c in Sources */,
- C9765EB5138EC61900741512 /* gcc_atomic.c in Sources */,
- C9765EB6138EC61900741512 /* OSAtomic-v4.c in Sources */,
- C9765EB7138EC61900741512 /* OSAtomic_resolvers.c in Sources */,
C9765EB9138EC61900741512 /* creat.c in Sources */,
C9765EBA138EC61900741512 /* gethostid.c in Sources */,
C9765EBB138EC61900741512 /* getwd.c in Sources */,
C9765EC3138EC61900741512 /* sigaltstk.c in Sources */,
C9765EC4138EC61900741512 /* sigcompat.c in Sources */,
C9765EC5138EC61900741512 /* _dirhelper.c in Sources */,
- C9765EC7138EC61900741512 /* libproc.c in Sources */,
C9765EC6138EC61900741512 /* kvm.c in Sources */,
- C9765EC8138EC61900741512 /* MKGetTimeBaseInfo.c in Sources */,
- C9765EC9138EC61900741512 /* proc_listpidspath.c in Sources */,
C9765ECA138EC61900741512 /* forceLibcToBuild.c in Sources */,
C9765ECB138EC61900741512 /* bt_close.c in Sources */,
C9765ECC138EC61900741512 /* bt_conv.c in Sources */,
C9765F07138EC61900741512 /* machdep_ldisdd.c in Sources */,
C9765F08138EC61900741512 /* machdep_ldisQ.c in Sources */,
C9765F09138EC61900741512 /* machdep_ldisx.c in Sources */,
- C9765F0A138EC61900741512 /* _simple.c in Sources */,
- C9765F0B138EC61900741512 /* asl.c in Sources */,
- C9765F0C138EC61900741512 /* asl_core.c in Sources */,
- C9765F0D138EC61900741512 /* asl_file.c in Sources */,
- C9765F0E138EC61900741512 /* asl_legacy1.c in Sources */,
- C9765F0F138EC61900741512 /* asl_msg.c in Sources */,
- C9765F10138EC61900741512 /* asl_store.c in Sources */,
- C9765F11138EC61900741512 /* asl_util.c in Sources */,
- C9765F12138EC61900741512 /* assumes.c in Sources */,
C9765F13138EC61900741512 /* authentication.c in Sources */,
C9765F14138EC61900741512 /* backtrace.c in Sources */,
- C9765F15138EC61900741512 /* cache.c in Sources */,
C9765F16138EC61900741512 /* confstr.c in Sources */,
C9765F17138EC61900741512 /* crypt.c in Sources */,
C9765F18138EC61900741512 /* devname.c in Sources */,
C9765F6C138EC61900741512 /* getttyent.c in Sources */,
C9765F6D138EC61900741512 /* getusershell.c in Sources */,
C9765F6E138EC61900741512 /* getvfsbyname.c in Sources */,
- C9765F6F138EC61900741512 /* isinf.c in Sources */,
- C9765F70138EC61900741512 /* isnan.c in Sources */,
- C9765F71138EC61900741512 /* magazine_malloc.c in Sources */,
- C9765F72138EC61900741512 /* malloc.c in Sources */,
C9765F73138EC61900741512 /* nanosleep.c in Sources */,
C9765F74138EC61900741512 /* utmpx.c in Sources */,
C9765F75138EC61900741512 /* nftw.c in Sources */,
C9765F76138EC61900741512 /* nlist.c in Sources */,
C9765F77138EC61900741512 /* NSSystemDirectories.c in Sources */,
C9765F78138EC61900741512 /* oldsyslog.c in Sources */,
- C9765F79138EC61900741512 /* platfunc.c in Sources */,
- C9765F7A138EC61900741512 /* scalable_malloc.c in Sources */,
C9765F7B138EC61900741512 /* setlogin.c in Sources */,
C9765F7C138EC61900741512 /* sigsetops.c in Sources */,
- C9765F7D138EC61900741512 /* stack_logging.c in Sources */,
- C9765F7E138EC61900741512 /* stack_logging_disk.c in Sources */,
C9765F7F138EC61900741512 /* strtofflags.c in Sources */,
- C9765F80138EC61900741512 /* syslog.c in Sources */,
C9765F81138EC61900741512 /* thread_stack_pcs.c in Sources */,
C9765F82138EC61900741512 /* uname.c in Sources */,
C9765F83138EC61900741512 /* utmpx-darwin.c in Sources */,
C9765F84138EC61900741512 /* wordexp.c in Sources */,
C9765F86138EC61900741512 /* gmon.c in Sources */,
- C9765F87138EC61900741512 /* getmcontext.c in Sources */,
- C9765F88138EC61900741512 /* makecontext.c in Sources */,
- C9765F89138EC61900741512 /* setcontext.c in Sources */,
- C9765F8A138EC61900741512 /* setjmperr.c in Sources */,
- C9765F8B138EC61900741512 /* swapcontext.c in Sources */,
- C9765F8C138EC61900741512 /* init_cpu_capabilities.c in Sources */,
- C9765F8D138EC61900741512 /* bcopy.c in Sources */,
- C9765F8E138EC61900741512 /* bzero.c in Sources */,
- C9765F8F138EC61900741512 /* memcpy.c in Sources */,
- C9765F90138EC61900741512 /* memmove.c in Sources */,
- C9765F91138EC61900741512 /* atomic.c in Sources */,
- C9765F93138EC61900741512 /* spinlocks.c in Sources */,
C9765FA6138EC61900741512 /* ascii.c in Sources */,
C9765FA7138EC61900741512 /* big5.c in Sources */,
C9765FA8138EC61900741512 /* btowc.c in Sources */,
C9765FFB138EC61900741512 /* acl_flag.c in Sources */,
C9765FFC138EC61900741512 /* acl_perm.c in Sources */,
C9765FFD138EC61900741512 /* acl_translate.c in Sources */,
- C9766006138EC61900741512 /* mk_pthread_impl.c in Sources */,
- C9766007138EC61900741512 /* pthread.c in Sources */,
- C9766008138EC61900741512 /* pthread_cancelable.c in Sources */,
- C9766009138EC61900741512 /* pthread_cond.c in Sources */,
- C976600A138EC61900741512 /* pthread_mutex.c in Sources */,
- C976600B138EC61900741512 /* pthread_rwlock.c in Sources */,
- C976600C138EC61900741512 /* pthread_tsd.c in Sources */,
- C976600D138EC61900741512 /* pthread_atfork_test.c in Sources */,
- C976600E138EC61900741512 /* thread_setup.c in Sources */,
C9766011138EC61900741512 /* regerror.c in Sources */,
- C9766014138EC61900741512 /* chk_fail.c in Sources */,
- C9766015138EC61900741512 /* memcpy_chk.c in Sources */,
- C9766016138EC61900741512 /* memmove_chk.c in Sources */,
- C9766017138EC61900741512 /* memset_chk.c in Sources */,
- C9766018138EC61900741512 /* snprintf_chk.c in Sources */,
- C9766019138EC61900741512 /* sprintf_chk.c in Sources */,
- C976601A138EC61A00741512 /* stpcpy_chk.c in Sources */,
- C976601B138EC61A00741512 /* stpncpy_chk.c in Sources */,
- C976601C138EC61A00741512 /* strcat_chk.c in Sources */,
- C976601D138EC61A00741512 /* strcpy_chk.c in Sources */,
- C976601E138EC61A00741512 /* strncat_chk.c in Sources */,
- C976601F138EC61A00741512 /* strncpy_chk.c in Sources */,
- C9766020138EC61A00741512 /* vsnprintf_chk.c in Sources */,
- C9766021138EC61A00741512 /* vsprintf_chk.c in Sources */,
C9766022138EC61A00741512 /* _flock_stub.c in Sources */,
C9766023138EC61A00741512 /* asprintf.c in Sources */,
C9766024138EC61A00741512 /* clrerr.c in Sources */,
C97660C4138EC61A00741512 /* timelocal.c in Sources */,
C97660C5138EC61A00741512 /* getdate.c in Sources */,
C97660C6138EC61A00741512 /* timezone_unix03.c in Sources */,
- C97660C7138EC61A00741512 /* bcmp.c in Sources */,
- C97660C8138EC61A00741512 /* bcopy.c in Sources */,
- C97660C9138EC61A00741512 /* bzero.c in Sources */,
C97660CA138EC61A00741512 /* index.c in Sources */,
- C97660CB138EC61A00741512 /* memccpy.c in Sources */,
- C97660CC138EC61A00741512 /* memchr.c in Sources */,
- C97660CD138EC61A00741512 /* memcmp.c in Sources */,
- C97660CE138EC61A00741512 /* memcpy.c in Sources */,
C97660CF138EC61A00741512 /* memmem.c in Sources */,
- C97660D0138EC61A00741512 /* memmove.c in Sources */,
- C97660D1138EC61A00741512 /* memset.c in Sources */,
C97660D2138EC61A00741512 /* rindex.c in Sources */,
C97660D5138EC61A00741512 /* strcasecmp.c in Sources */,
C97660D6138EC61A00741512 /* strcasestr.c in Sources */,
- C97660D8138EC61A00741512 /* strchr.c in Sources */,
- C97660D9138EC61A00741512 /* strcmp.c in Sources */,
C97660DA138EC61A00741512 /* strcoll.c in Sources */,
C97660DC138EC61A00741512 /* strcspn.c in Sources */,
C97660DD138EC61A00741512 /* strdup.c in Sources */,
C97660DE138EC61A00741512 /* strerror.c in Sources */,
C97660E1138EC61A00741512 /* strlen.c in Sources */,
C97660E2138EC61A00741512 /* strmode.c in Sources */,
- C97660E4138EC61A00741512 /* strncmp.c in Sources */,
C97660E6138EC61A00741512 /* strndup.c in Sources */,
C97660E7138EC61A00741512 /* strnlen.c in Sources */,
C97660E8138EC61A00741512 /* strnstr.c in Sources */,
C9766110138EC61A00741512 /* __libc_init.c in Sources */,
C9766111138EC61A00741512 /* _libc_fork_child.c in Sources */,
C9766112138EC61A00741512 /* chmodx_np.c in Sources */,
- C9766113138EC61A00741512 /* context-stubs.c in Sources */,
C9766114138EC61A00741512 /* crt_externs.c in Sources */,
- C9766115138EC61A00741512 /* errno.c in Sources */,
C9766116138EC61A00741512 /* fork.c in Sources */,
C9766117138EC61A00741512 /* getgroups.c in Sources */,
- C9766118138EC61A00741512 /* getiopolicy_np.c in Sources */,
C9766119138EC61A00741512 /* gettimeofday.c in Sources */,
C976611A138EC61A00741512 /* msgctl.c in Sources */,
C976611B138EC61A00741512 /* stack_protector.c in Sources */,
C9766121138EC61A00741512 /* settimeofday.c in Sources */,
C9766122138EC61A00741512 /* shmctl.c in Sources */,
C9766123138EC61A00741512 /* sigaction.c in Sources */,
- C9766124138EC61A00741512 /* sigcatch.c in Sources */,
- C9766125138EC61A00741512 /* sigtramp.c in Sources */,
- C9766126138EC61A00741512 /* slot_name.c in Sources */,
C9766127138EC61A00741512 /* statx_np.c in Sources */,
C9766128138EC61A00741512 /* umaskx_np.c in Sources */,
- C9766129138EC61A00741512 /* cprocs.c in Sources */,
- C976612A138EC61A00741512 /* cthreads.c in Sources */,
- C976612B138EC61A00741512 /* mig_support.c in Sources */,
C976612C138EC61A00741512 /* fparseln.c in Sources */,
C976612D138EC61A00741512 /* login.c in Sources */,
C976612E138EC61A00741512 /* login_tty.c in Sources */,
C9766139138EC61A00741512 /* parse.c in Sources */,
C976613A138EC61A00741512 /* unpack.c in Sources */,
C976613B138EC61A00741512 /* unparse.c in Sources */,
- C976613C138EC61A00741512 /* getmcontext.c in Sources */,
- C976613D138EC61A00741512 /* makecontext.c in Sources */,
- C976613E138EC61A00741512 /* setcontext.c in Sources */,
- C976613F138EC61A00741512 /* swapcontext.c in Sources */,
- C9766140138EC61A00741512 /* bcopy.c in Sources */,
- C9766141138EC61A00741512 /* bzero.c in Sources */,
- C9766142138EC61A00741512 /* memcpy.c in Sources */,
- C9766143138EC61A00741512 /* memmove.c in Sources */,
- C9766144138EC61A00741512 /* atomic.c in Sources */,
- C9766145138EC61A00741512 /* spinlocks.c in Sources */,
- 3F2208EA14358B4A00386F5B /* asl_fd.c in Sources */,
B19C645E1450F90200032373 /* sync_volume_np.c in Sources */,
3FB7E1B6146EF2E000843438 /* dirfd.c in Sources */,
+ 4B2C64A515519BC600342BFA /* assumes.c in Sources */,
+ FC2ED613157D4BE80098EC69 /* inet_ntop.c in Sources */,
+ FC2ED61C157D4BE80098EC69 /* inet_pton.c in Sources */,
+ 2B9D61BA157D667800AF25B8 /* trace.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
buildActionMask = 2147483647;
files = (
C9EB2FCD138F6D880075BB52 /* init_cpu_capabilities.c in Sources */,
- C9EB2FCE138F6D880075BB52 /* dyld_resolvers.c in Sources */,
- C9EB2FCF138F6D880075BB52 /* arm_commpage_gettimeofday.c in Sources */,
- C9EB2FD0138F6D880075BB52 /* gcc_atomic.c in Sources */,
- C9EB2FD1138F6D880075BB52 /* OSAtomic-v4.c in Sources */,
- C9EB2FD2138F6D880075BB52 /* OSAtomic_resolvers.c in Sources */,
C9EB2FD4138F6D880075BB52 /* creat.c in Sources */,
C9EB2FD5138F6D880075BB52 /* gethostid.c in Sources */,
C9EB2FD6138F6D880075BB52 /* getwd.c in Sources */,
C9EB2FDF138F6D880075BB52 /* sigcompat.c in Sources */,
C9EB2FE0138F6D880075BB52 /* _dirhelper.c in Sources */,
C9EB2FE1138F6D880075BB52 /* kvm.c in Sources */,
- C9EB2FE2138F6D880075BB52 /* libproc.c in Sources */,
- C9EB2FE3138F6D880075BB52 /* MKGetTimeBaseInfo.c in Sources */,
- C9EB2FE4138F6D880075BB52 /* proc_listpidspath.c in Sources */,
C9EB2FE5138F6D880075BB52 /* forceLibcToBuild.c in Sources */,
C9EB2FE6138F6D880075BB52 /* bt_close.c in Sources */,
C9EB2FE7138F6D880075BB52 /* bt_conv.c in Sources */,
C9EB3022138F6D880075BB52 /* machdep_ldisdd.c in Sources */,
C9EB3023138F6D880075BB52 /* machdep_ldisQ.c in Sources */,
C9EB3024138F6D880075BB52 /* machdep_ldisx.c in Sources */,
- C9EB3025138F6D880075BB52 /* _simple.c in Sources */,
- C9EB3026138F6D880075BB52 /* asl.c in Sources */,
- C9EB3027138F6D880075BB52 /* asl_core.c in Sources */,
- C9EB3028138F6D880075BB52 /* asl_file.c in Sources */,
- C9EB3029138F6D880075BB52 /* asl_legacy1.c in Sources */,
- C9EB302A138F6D880075BB52 /* asl_msg.c in Sources */,
- C9EB302B138F6D880075BB52 /* asl_store.c in Sources */,
- C9EB302C138F6D880075BB52 /* asl_util.c in Sources */,
- C9EB302D138F6D880075BB52 /* assumes.c in Sources */,
C9EB302E138F6D880075BB52 /* authentication.c in Sources */,
C9EB302F138F6D880075BB52 /* backtrace.c in Sources */,
- C9EB3030138F6D880075BB52 /* cache.c in Sources */,
C9EB3031138F6D880075BB52 /* confstr.c in Sources */,
C9EB3032138F6D880075BB52 /* crypt.c in Sources */,
C9EB3033138F6D880075BB52 /* devname.c in Sources */,
C9EB3087138F6D880075BB52 /* getttyent.c in Sources */,
C9EB3088138F6D880075BB52 /* getusershell.c in Sources */,
C9EB3089138F6D880075BB52 /* getvfsbyname.c in Sources */,
- C9EB308A138F6D880075BB52 /* isinf.c in Sources */,
- C9EB308B138F6D880075BB52 /* isnan.c in Sources */,
- C9EB308C138F6D880075BB52 /* magazine_malloc.c in Sources */,
- C9EB308D138F6D880075BB52 /* malloc.c in Sources */,
C9EB308E138F6D880075BB52 /* nanosleep.c in Sources */,
C9EB308F138F6D880075BB52 /* utmpx.c in Sources */,
C9EB3090138F6D880075BB52 /* nftw.c in Sources */,
C9EB3091138F6D880075BB52 /* nlist.c in Sources */,
C9EB3092138F6D880075BB52 /* NSSystemDirectories.c in Sources */,
C9EB3093138F6D880075BB52 /* oldsyslog.c in Sources */,
- C9EB3094138F6D880075BB52 /* platfunc.c in Sources */,
- C9EB3095138F6D880075BB52 /* scalable_malloc.c in Sources */,
C9EB3096138F6D880075BB52 /* setlogin.c in Sources */,
C9EB3097138F6D880075BB52 /* sigsetops.c in Sources */,
- C9EB3098138F6D880075BB52 /* stack_logging.c in Sources */,
- C9EB3099138F6D880075BB52 /* stack_logging_disk.c in Sources */,
C9EB309A138F6D880075BB52 /* strtofflags.c in Sources */,
- C9EB309B138F6D880075BB52 /* syslog.c in Sources */,
C9EB309C138F6D880075BB52 /* thread_stack_pcs.c in Sources */,
C9EB309D138F6D880075BB52 /* uname.c in Sources */,
C9EB309E138F6D880075BB52 /* utmpx-darwin.c in Sources */,
C9EB309F138F6D880075BB52 /* wordexp.c in Sources */,
C9EB30A1138F6D880075BB52 /* gmon.c in Sources */,
- C9EB30A2138F6D880075BB52 /* getmcontext.c in Sources */,
- C9EB30A3138F6D880075BB52 /* makecontext.c in Sources */,
- C9EB30A4138F6D880075BB52 /* setcontext.c in Sources */,
- C9EB30A5138F6D880075BB52 /* setjmperr.c in Sources */,
- C9EB30A6138F6D880075BB52 /* swapcontext.c in Sources */,
- C9EB30A7138F6D880075BB52 /* init_cpu_capabilities.c in Sources */,
- C9EB30A8138F6D880075BB52 /* bcopy.c in Sources */,
- C9EB30A9138F6D880075BB52 /* bzero.c in Sources */,
- C9EB30AA138F6D880075BB52 /* memcpy.c in Sources */,
- C9EB30AB138F6D880075BB52 /* memmove.c in Sources */,
- C9EB30AC138F6D880075BB52 /* atomic.c in Sources */,
- C9EB30AE138F6D880075BB52 /* spinlocks.c in Sources */,
C9EB30C1138F6D880075BB52 /* ascii.c in Sources */,
C9EB30C2138F6D880075BB52 /* big5.c in Sources */,
C9EB30C3138F6D880075BB52 /* btowc.c in Sources */,
C9EB3116138F6D880075BB52 /* acl_flag.c in Sources */,
C9EB3117138F6D880075BB52 /* acl_perm.c in Sources */,
C9EB3118138F6D880075BB52 /* acl_translate.c in Sources */,
- C9EB3121138F6D880075BB52 /* mk_pthread_impl.c in Sources */,
- C9EB3122138F6D880075BB52 /* pthread.c in Sources */,
- C9EB3123138F6D880075BB52 /* pthread_cancelable.c in Sources */,
- C9EB3124138F6D880075BB52 /* pthread_cond.c in Sources */,
- C9EB3125138F6D880075BB52 /* pthread_mutex.c in Sources */,
- C9EB3126138F6D880075BB52 /* pthread_rwlock.c in Sources */,
- C9EB3127138F6D880075BB52 /* pthread_tsd.c in Sources */,
- C9EB3128138F6D880075BB52 /* pthread_atfork_test.c in Sources */,
- C9EB3129138F6D880075BB52 /* thread_setup.c in Sources */,
C9EB312C138F6D880075BB52 /* regerror.c in Sources */,
- C9EB312F138F6D880075BB52 /* chk_fail.c in Sources */,
- C9EB3130138F6D880075BB52 /* memcpy_chk.c in Sources */,
- C9EB3131138F6D880075BB52 /* memmove_chk.c in Sources */,
- C9EB3132138F6D880075BB52 /* memset_chk.c in Sources */,
- C9EB3133138F6D880075BB52 /* snprintf_chk.c in Sources */,
- C9EB3134138F6D880075BB52 /* sprintf_chk.c in Sources */,
- C9EB3135138F6D880075BB52 /* stpcpy_chk.c in Sources */,
- C9EB3136138F6D880075BB52 /* stpncpy_chk.c in Sources */,
- C9EB3137138F6D880075BB52 /* strcat_chk.c in Sources */,
- C9EB3138138F6D880075BB52 /* strcpy_chk.c in Sources */,
- C9EB3139138F6D880075BB52 /* strncat_chk.c in Sources */,
- C9EB313A138F6D880075BB52 /* strncpy_chk.c in Sources */,
- C9EB313B138F6D880075BB52 /* vsnprintf_chk.c in Sources */,
- C9EB313C138F6D880075BB52 /* vsprintf_chk.c in Sources */,
C9EB313D138F6D880075BB52 /* _flock_stub.c in Sources */,
C9EB313E138F6D880075BB52 /* asprintf.c in Sources */,
C9EB313F138F6D880075BB52 /* clrerr.c in Sources */,
C9EB31DF138F6D880075BB52 /* timelocal.c in Sources */,
C9EB31E0138F6D880075BB52 /* getdate.c in Sources */,
C9EB31E1138F6D880075BB52 /* timezone_unix03.c in Sources */,
- C9EB31E2138F6D880075BB52 /* bcmp.c in Sources */,
- C9EB31E3138F6D880075BB52 /* bcopy.c in Sources */,
- C9EB31E4138F6D880075BB52 /* bzero.c in Sources */,
C9EB31E5138F6D880075BB52 /* index.c in Sources */,
- C9EB31E6138F6D880075BB52 /* memccpy.c in Sources */,
- C9EB31E7138F6D880075BB52 /* memchr.c in Sources */,
- C9EB31E8138F6D880075BB52 /* memcmp.c in Sources */,
- C9EB31E9138F6D880075BB52 /* memcpy.c in Sources */,
C9EB31EA138F6D880075BB52 /* memmem.c in Sources */,
- C9EB31EB138F6D880075BB52 /* memmove.c in Sources */,
- C9EB31EC138F6D880075BB52 /* memset.c in Sources */,
C9EB31ED138F6D880075BB52 /* rindex.c in Sources */,
C9EB31F0138F6D880075BB52 /* strcasecmp.c in Sources */,
C9EB31F1138F6D880075BB52 /* strcasestr.c in Sources */,
- C9EB31F3138F6D880075BB52 /* strchr.c in Sources */,
- C9EB31F4138F6D880075BB52 /* strcmp.c in Sources */,
C9EB31F5138F6D880075BB52 /* strcoll.c in Sources */,
C9EB31F7138F6D880075BB52 /* strcspn.c in Sources */,
C9EB31F8138F6D880075BB52 /* strdup.c in Sources */,
C9EB31F9138F6D880075BB52 /* strerror.c in Sources */,
C9EB31FC138F6D880075BB52 /* strlen.c in Sources */,
C9EB31FD138F6D880075BB52 /* strmode.c in Sources */,
- C9EB31FF138F6D880075BB52 /* strncmp.c in Sources */,
C9EB3201138F6D880075BB52 /* strndup.c in Sources */,
C9EB3202138F6D880075BB52 /* strnlen.c in Sources */,
C9EB3203138F6D880075BB52 /* strnstr.c in Sources */,
C9EB322B138F6D880075BB52 /* __libc_init.c in Sources */,
C9EB322C138F6D880075BB52 /* _libc_fork_child.c in Sources */,
C9EB322D138F6D880075BB52 /* chmodx_np.c in Sources */,
- C9EB322E138F6D880075BB52 /* context-stubs.c in Sources */,
C9EB322F138F6D880075BB52 /* crt_externs.c in Sources */,
- C9EB3230138F6D880075BB52 /* errno.c in Sources */,
C9EB3231138F6D880075BB52 /* fork.c in Sources */,
C9EB3232138F6D880075BB52 /* getgroups.c in Sources */,
- C9EB3233138F6D880075BB52 /* getiopolicy_np.c in Sources */,
C9EB3234138F6D880075BB52 /* gettimeofday.c in Sources */,
C9EB3235138F6D880075BB52 /* msgctl.c in Sources */,
C9EB3236138F6D880075BB52 /* stack_protector.c in Sources */,
C9EB323C138F6D880075BB52 /* settimeofday.c in Sources */,
C9EB323D138F6D880075BB52 /* shmctl.c in Sources */,
C9EB323E138F6D880075BB52 /* sigaction.c in Sources */,
- C9EB323F138F6D880075BB52 /* sigcatch.c in Sources */,
- C9EB3240138F6D880075BB52 /* sigtramp.c in Sources */,
- C9EB3241138F6D880075BB52 /* slot_name.c in Sources */,
C9EB3242138F6D880075BB52 /* statx_np.c in Sources */,
C9EB3243138F6D880075BB52 /* umaskx_np.c in Sources */,
- C9EB3244138F6D880075BB52 /* cprocs.c in Sources */,
- C9EB3245138F6D880075BB52 /* cthreads.c in Sources */,
- C9EB3246138F6D880075BB52 /* mig_support.c in Sources */,
C9EB3247138F6D880075BB52 /* fparseln.c in Sources */,
C9EB3248138F6D880075BB52 /* login.c in Sources */,
C9EB3249138F6D880075BB52 /* login_tty.c in Sources */,
C9EB3254138F6D880075BB52 /* parse.c in Sources */,
C9EB3255138F6D880075BB52 /* unpack.c in Sources */,
C9EB3256138F6D880075BB52 /* unparse.c in Sources */,
- C9EB3257138F6D880075BB52 /* getmcontext.c in Sources */,
- C9EB3258138F6D880075BB52 /* makecontext.c in Sources */,
- C9EB3259138F6D880075BB52 /* setcontext.c in Sources */,
- C9EB325A138F6D880075BB52 /* swapcontext.c in Sources */,
- C9EB325B138F6D880075BB52 /* bcopy.c in Sources */,
- C9EB325C138F6D880075BB52 /* bzero.c in Sources */,
- C9EB325D138F6D880075BB52 /* memcpy.c in Sources */,
- C9EB325E138F6D880075BB52 /* memmove.c in Sources */,
- C9EB325F138F6D880075BB52 /* atomic.c in Sources */,
- C9EB3260138F6D880075BB52 /* spinlocks.c in Sources */,
B10BC41C14338AEB005E4366 /* regcomp.c in Sources */,
- 3F2208EE14358B4A00386F5B /* asl_fd.c in Sources */,
B19C64621450F90200032373 /* sync_volume_np.c in Sources */,
3FB7E1BA146EF2E000843438 /* dirfd.c in Sources */,
+ 4B2C64A915519BC800342BFA /* assumes.c in Sources */,
+ FC2ED617157D4BE80098EC69 /* inet_ntop.c in Sources */,
+ FC2ED620157D4BE80098EC69 /* inet_pton.c in Sources */,
+ 2B9D61BE157D667B00AF25B8 /* trace.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
buildActionMask = 2147483647;
files = (
C9EB3274138F75580075BB52 /* init_cpu_capabilities.c in Sources */,
- C9EB3275138F75580075BB52 /* dyld_resolvers.c in Sources */,
- C9EB3276138F75580075BB52 /* arm_commpage_gettimeofday.c in Sources */,
- C9EB3277138F75580075BB52 /* gcc_atomic.c in Sources */,
- C9EB3278138F75580075BB52 /* OSAtomic-v4.c in Sources */,
- C9EB3279138F75580075BB52 /* OSAtomic_resolvers.c in Sources */,
C9EB327B138F75580075BB52 /* creat.c in Sources */,
C9EB327C138F75580075BB52 /* gethostid.c in Sources */,
C9EB327D138F75580075BB52 /* getwd.c in Sources */,
C9EB3286138F75580075BB52 /* sigcompat.c in Sources */,
C9EB3287138F75580075BB52 /* _dirhelper.c in Sources */,
C9EB3288138F75580075BB52 /* kvm.c in Sources */,
- C9EB3289138F75580075BB52 /* libproc.c in Sources */,
- C9EB328A138F75580075BB52 /* MKGetTimeBaseInfo.c in Sources */,
- C9EB328B138F75580075BB52 /* proc_listpidspath.c in Sources */,
C9EB328C138F75580075BB52 /* forceLibcToBuild.c in Sources */,
C9EB328D138F75580075BB52 /* bt_close.c in Sources */,
C9EB328E138F75580075BB52 /* bt_conv.c in Sources */,
C9EB32C9138F75580075BB52 /* machdep_ldisdd.c in Sources */,
C9EB32CA138F75580075BB52 /* machdep_ldisQ.c in Sources */,
C9EB32CB138F75580075BB52 /* machdep_ldisx.c in Sources */,
- C9EB32CC138F75580075BB52 /* _simple.c in Sources */,
- C9EB32CD138F75580075BB52 /* asl.c in Sources */,
- C9EB32CE138F75580075BB52 /* asl_core.c in Sources */,
- C9EB32CF138F75580075BB52 /* asl_file.c in Sources */,
- C9EB32D0138F75580075BB52 /* asl_legacy1.c in Sources */,
- C9EB32D1138F75580075BB52 /* asl_msg.c in Sources */,
- C9EB32D2138F75580075BB52 /* asl_store.c in Sources */,
- C9EB32D3138F75580075BB52 /* asl_util.c in Sources */,
- C9EB32D4138F75580075BB52 /* assumes.c in Sources */,
C9EB32D5138F75580075BB52 /* authentication.c in Sources */,
C9EB32D6138F75580075BB52 /* backtrace.c in Sources */,
- C9EB32D7138F75580075BB52 /* cache.c in Sources */,
C9EB32D8138F75580075BB52 /* confstr.c in Sources */,
C9EB32D9138F75580075BB52 /* crypt.c in Sources */,
C9EB32DA138F75580075BB52 /* devname.c in Sources */,
C9EB332E138F75580075BB52 /* getttyent.c in Sources */,
C9EB332F138F75580075BB52 /* getusershell.c in Sources */,
C9EB3330138F75580075BB52 /* getvfsbyname.c in Sources */,
- C9EB3331138F75580075BB52 /* isinf.c in Sources */,
- C9EB3332138F75580075BB52 /* isnan.c in Sources */,
- C9EB3333138F75580075BB52 /* magazine_malloc.c in Sources */,
- C9EB3334138F75580075BB52 /* malloc.c in Sources */,
C9EB3335138F75580075BB52 /* nanosleep.c in Sources */,
C9EB3336138F75580075BB52 /* utmpx.c in Sources */,
C9EB3337138F75580075BB52 /* nftw.c in Sources */,
C9EB3338138F75580075BB52 /* nlist.c in Sources */,
C9EB3339138F75580075BB52 /* NSSystemDirectories.c in Sources */,
C9EB333A138F75580075BB52 /* oldsyslog.c in Sources */,
- C9EB333B138F75580075BB52 /* platfunc.c in Sources */,
- C9EB333C138F75580075BB52 /* scalable_malloc.c in Sources */,
C9EB333D138F75580075BB52 /* setlogin.c in Sources */,
C9EB333E138F75580075BB52 /* sigsetops.c in Sources */,
- C9EB333F138F75580075BB52 /* stack_logging.c in Sources */,
- C9EB3340138F75580075BB52 /* stack_logging_disk.c in Sources */,
C9EB3341138F75580075BB52 /* strtofflags.c in Sources */,
- C9EB3342138F75580075BB52 /* syslog.c in Sources */,
C9EB3343138F75580075BB52 /* thread_stack_pcs.c in Sources */,
C9EB3344138F75580075BB52 /* uname.c in Sources */,
C9EB3345138F75580075BB52 /* utmpx-darwin.c in Sources */,
C9EB3346138F75580075BB52 /* wordexp.c in Sources */,
C9EB3348138F75580075BB52 /* gmon.c in Sources */,
- C9EB3349138F75580075BB52 /* getmcontext.c in Sources */,
- C9EB334A138F75580075BB52 /* makecontext.c in Sources */,
- C9EB334B138F75580075BB52 /* setcontext.c in Sources */,
- C9EB334C138F75580075BB52 /* setjmperr.c in Sources */,
- C9EB334D138F75580075BB52 /* swapcontext.c in Sources */,
- C9EB334E138F75580075BB52 /* init_cpu_capabilities.c in Sources */,
- C9EB334F138F75580075BB52 /* bcopy.c in Sources */,
- C9EB3350138F75580075BB52 /* bzero.c in Sources */,
- C9EB3351138F75580075BB52 /* memcpy.c in Sources */,
- C9EB3352138F75580075BB52 /* memmove.c in Sources */,
- C9EB3353138F75580075BB52 /* atomic.c in Sources */,
- C9EB3355138F75580075BB52 /* spinlocks.c in Sources */,
C9EB3368138F75580075BB52 /* ascii.c in Sources */,
C9EB3369138F75580075BB52 /* big5.c in Sources */,
C9EB336A138F75580075BB52 /* btowc.c in Sources */,
C9EB33BD138F75580075BB52 /* acl_flag.c in Sources */,
C9EB33BE138F75580075BB52 /* acl_perm.c in Sources */,
C9EB33BF138F75580075BB52 /* acl_translate.c in Sources */,
- C9EB33C8138F75580075BB52 /* mk_pthread_impl.c in Sources */,
- C9EB33C9138F75580075BB52 /* pthread.c in Sources */,
- C9EB33CA138F75580075BB52 /* pthread_cancelable.c in Sources */,
- C9EB33CB138F75580075BB52 /* pthread_cond.c in Sources */,
- C9EB33CC138F75580075BB52 /* pthread_mutex.c in Sources */,
- C9EB33CD138F75580075BB52 /* pthread_rwlock.c in Sources */,
- C9EB33CE138F75580075BB52 /* pthread_tsd.c in Sources */,
- C9EB33CF138F75580075BB52 /* pthread_atfork_test.c in Sources */,
- C9EB33D0138F75580075BB52 /* thread_setup.c in Sources */,
C9EB33D3138F75580075BB52 /* regerror.c in Sources */,
- C9EB33D6138F75580075BB52 /* chk_fail.c in Sources */,
- C9EB33D7138F75580075BB52 /* memcpy_chk.c in Sources */,
- C9EB33D8138F75580075BB52 /* memmove_chk.c in Sources */,
- C9EB33D9138F75580075BB52 /* memset_chk.c in Sources */,
- C9EB33DA138F75580075BB52 /* snprintf_chk.c in Sources */,
- C9EB33DB138F75580075BB52 /* sprintf_chk.c in Sources */,
- C9EB33DC138F75580075BB52 /* stpcpy_chk.c in Sources */,
- C9EB33DD138F75580075BB52 /* stpncpy_chk.c in Sources */,
- C9EB33DE138F75580075BB52 /* strcat_chk.c in Sources */,
- C9EB33DF138F75580075BB52 /* strcpy_chk.c in Sources */,
- C9EB33E0138F75580075BB52 /* strncat_chk.c in Sources */,
- C9EB33E1138F75580075BB52 /* strncpy_chk.c in Sources */,
- C9EB33E2138F75580075BB52 /* vsnprintf_chk.c in Sources */,
- C9EB33E3138F75580075BB52 /* vsprintf_chk.c in Sources */,
C9EB33E4138F75580075BB52 /* _flock_stub.c in Sources */,
C9EB33E5138F75580075BB52 /* asprintf.c in Sources */,
C9EB33E6138F75580075BB52 /* clrerr.c in Sources */,
C9EB3486138F75580075BB52 /* timelocal.c in Sources */,
C9EB3487138F75580075BB52 /* getdate.c in Sources */,
C9EB3488138F75580075BB52 /* timezone_unix03.c in Sources */,
- C9EB3489138F75580075BB52 /* bcmp.c in Sources */,
- C9EB348A138F75580075BB52 /* bcopy.c in Sources */,
- C9EB348B138F75580075BB52 /* bzero.c in Sources */,
C9EB348C138F75580075BB52 /* index.c in Sources */,
- C9EB348D138F75580075BB52 /* memccpy.c in Sources */,
- C9EB348E138F75580075BB52 /* memchr.c in Sources */,
- C9EB348F138F75580075BB52 /* memcmp.c in Sources */,
- C9EB3490138F75580075BB52 /* memcpy.c in Sources */,
C9EB3491138F75580075BB52 /* memmem.c in Sources */,
- C9EB3492138F75580075BB52 /* memmove.c in Sources */,
- C9EB3493138F75580075BB52 /* memset.c in Sources */,
C9EB3494138F75580075BB52 /* rindex.c in Sources */,
C9EB3497138F75580075BB52 /* strcasecmp.c in Sources */,
C9EB3498138F75580075BB52 /* strcasestr.c in Sources */,
- C9EB349A138F75580075BB52 /* strchr.c in Sources */,
- C9EB349B138F75580075BB52 /* strcmp.c in Sources */,
C9EB349C138F75580075BB52 /* strcoll.c in Sources */,
C9EB349E138F75580075BB52 /* strcspn.c in Sources */,
C9EB349F138F75580075BB52 /* strdup.c in Sources */,
C9EB34A0138F75580075BB52 /* strerror.c in Sources */,
C9EB34A3138F75580075BB52 /* strlen.c in Sources */,
C9EB34A4138F75580075BB52 /* strmode.c in Sources */,
- C9EB34A6138F75580075BB52 /* strncmp.c in Sources */,
C9EB34A8138F75580075BB52 /* strndup.c in Sources */,
C9EB34A9138F75580075BB52 /* strnlen.c in Sources */,
C9EB34AA138F75580075BB52 /* strnstr.c in Sources */,
C9EB34D2138F75580075BB52 /* __libc_init.c in Sources */,
C9EB34D3138F75580075BB52 /* _libc_fork_child.c in Sources */,
C9EB34D4138F75580075BB52 /* chmodx_np.c in Sources */,
- C9EB34D5138F75580075BB52 /* context-stubs.c in Sources */,
C9EB34D6138F75580075BB52 /* crt_externs.c in Sources */,
- C9EB34D7138F75580075BB52 /* errno.c in Sources */,
C9EB34D8138F75580075BB52 /* fork.c in Sources */,
C9EB34D9138F75580075BB52 /* getgroups.c in Sources */,
- C9EB34DA138F75580075BB52 /* getiopolicy_np.c in Sources */,
C9EB34DB138F75580075BB52 /* gettimeofday.c in Sources */,
C9EB34DC138F75580075BB52 /* msgctl.c in Sources */,
C9EB34DD138F75580075BB52 /* stack_protector.c in Sources */,
C9EB34E3138F75580075BB52 /* settimeofday.c in Sources */,
C9EB34E4138F75580075BB52 /* shmctl.c in Sources */,
C9EB34E5138F75580075BB52 /* sigaction.c in Sources */,
- C9EB34E6138F75580075BB52 /* sigcatch.c in Sources */,
- C9EB34E7138F75580075BB52 /* sigtramp.c in Sources */,
- C9EB34E8138F75580075BB52 /* slot_name.c in Sources */,
C9EB34E9138F75580075BB52 /* statx_np.c in Sources */,
C9EB34EA138F75580075BB52 /* umaskx_np.c in Sources */,
- C9EB34EB138F75580075BB52 /* cprocs.c in Sources */,
- C9EB34EC138F75580075BB52 /* cthreads.c in Sources */,
- C9EB34ED138F75580075BB52 /* mig_support.c in Sources */,
C9EB34EE138F75580075BB52 /* fparseln.c in Sources */,
C9EB34EF138F75580075BB52 /* login.c in Sources */,
C9EB34F0138F75580075BB52 /* login_tty.c in Sources */,
C9EB34FB138F75580075BB52 /* parse.c in Sources */,
C9EB34FC138F75580075BB52 /* unpack.c in Sources */,
C9EB34FD138F75580075BB52 /* unparse.c in Sources */,
- C9EB34FE138F75580075BB52 /* getmcontext.c in Sources */,
- C9EB34FF138F75580075BB52 /* makecontext.c in Sources */,
- C9EB3500138F75580075BB52 /* setcontext.c in Sources */,
- C9EB3501138F75580075BB52 /* swapcontext.c in Sources */,
- C9EB3502138F75580075BB52 /* bcopy.c in Sources */,
- C9EB3503138F75580075BB52 /* bzero.c in Sources */,
- C9EB3504138F75580075BB52 /* memcpy.c in Sources */,
- C9EB3505138F75580075BB52 /* memmove.c in Sources */,
- C9EB3506138F75580075BB52 /* atomic.c in Sources */,
- C9EB3507138F75580075BB52 /* spinlocks.c in Sources */,
C9EB3510138F76A10075BB52 /* scandir_b.c in Sources */,
- 3F2208EF14358B4A00386F5B /* asl_fd.c in Sources */,
B19C64631450F90200032373 /* sync_volume_np.c in Sources */,
3FB7E1BB146EF2E000843438 /* dirfd.c in Sources */,
+ 4B2C64AA15519BCB00342BFA /* assumes.c in Sources */,
+ FC2ED618157D4BE80098EC69 /* inet_ntop.c in Sources */,
+ FC2ED621157D4BE80098EC69 /* inet_pton.c in Sources */,
+ 2B9D61BF157D667B00AF25B8 /* trace.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
+ 3F51211716C318EB00AFB431 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 3F51206A16C3174300AFB431 /* FortifySource */;
+ targetProxy = 3F51211616C318EB00AFB431 /* PBXContainerItemProxy */;
+ };
B122F2D91432BA8700AF95D0 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = B122F0E71432B8E600AF95D0 /* TRE */;
targetProxy = B122F2D81432BA8700AF95D0 /* PBXContainerItemProxy */;
};
- B1E96509157E749200FCCEE7 /* PBXTargetDependency */ = {
+ C925D2011518FA5D003D315B /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C95B7ED9138F3C55004311DA /* Variant_DarwinExtsn */;
+ targetProxy = C925D2001518FA5D003D315B /* PBXContainerItemProxy */;
+ };
+ C925D2031518FEBE003D315B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
- target = B1E96340157E722200FCCEE7 /* FreeBSD_gcc */;
- targetProxy = B1E96508157E749200FCCEE7 /* PBXContainerItemProxy */;
+ target = C97A6F1E1517AF53005E1998 /* libc_eOS.a */;
+ targetProxy = C925D2021518FEBE003D315B /* PBXContainerItemProxy */;
};
C942130913901709004BA536 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = C95B842A138F53DB004311DA /* Variant_Pre1050 */;
targetProxy = C95B86CB138F546E004311DA /* PBXContainerItemProxy */;
};
+ C9AE91BB1517D33100A2626C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C9C2A94C138DFFD900287F00 /* Base */;
+ targetProxy = C9AE91BA1517D33100A2626C /* PBXContainerItemProxy */;
+ };
+ C9AE91BD1517D33100A2626C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C9257ECF138E1B5000B3107C /* FreeBSD */;
+ targetProxy = C9AE91BC1517D33100A2626C /* PBXContainerItemProxy */;
+ };
+ C9AE91BF1517D33100A2626C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = B122F0E71432B8E600AF95D0 /* TRE */;
+ targetProxy = C9AE91BE1517D33100A2626C /* PBXContainerItemProxy */;
+ };
+ C9AE91C11517D33100A2626C /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = C9D9435F138EC3E300FB7ACC /* Variant_Cancelable */;
+ targetProxy = C9AE91C01517D33100A2626C /* PBXContainerItemProxy */;
+ };
C9BD3C39138F16EE00B389FD /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = C9D9435F138EC3E300FB7ACC /* Variant_Cancelable */;
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
- B122F2AB1432B8E600AF95D0 /* Debug */ = {
+ 3F5120EF16C3174300AFB431 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- EXCLUDED_SOURCE_FILE_NAMES = (
- "$(FreeBSD_EXCLUDED_SOURCE_GDTOA)",
- "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
- );
+ COMBINE_HIDPI_IMAGES = YES;
+ EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_DYNAMIC_NO_PIC = NO;
- GCC_ENABLE_OBJC_EXCEPTIONS = YES;
- GCC_OPTIMIZATION_LEVEL = 0;
- GCC_SYMBOLS_PRIVATE_EXTERN = NO;
- INCLUDED_SOURCE_FILE_NAMES = "$(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
- PRODUCT_NAME = TRE;
+ INCLUDED_SOURCE_FILE_NAMES = "$(BASE_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
+ PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
};
- B122F2AC1432B8E600AF95D0 /* Release */ = {
+ 3F5120F016C3174300AFB431 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- EXCLUDED_SOURCE_FILE_NAMES = (
- "$(FreeBSD_EXCLUDED_SOURCE_GDTOA)",
- "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
- );
+ COMBINE_HIDPI_IMAGES = YES;
+ EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
- GCC_C_LANGUAGE_STANDARD = gnu99;
- GCC_ENABLE_OBJC_EXCEPTIONS = YES;
- INCLUDED_SOURCE_FILE_NAMES = "$(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
- PRODUCT_NAME = TRE;
+ INCLUDED_SOURCE_FILE_NAMES = "$(BASE_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
+ PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
};
- B1E96504157E722200FCCEE7 /* Debug */ = {
+ B122F2AB1432B8E600AF95D0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = (
"$(FreeBSD_EXCLUDED_SOURCE_GDTOA)",
"$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
- GCC_VERSION = com.apple.compilers.llvmgcc42;
INCLUDED_SOURCE_FILE_NAMES = "$(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
- PRODUCT_NAME = FreeBSD_gcc;
+ PRODUCT_NAME = TRE;
};
name = Debug;
};
- B1E96505157E722200FCCEE7 /* Release */ = {
+ B122F2AC1432B8E600AF95D0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = (
"$(FreeBSD_EXCLUDED_SOURCE_GDTOA)",
"$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
EXECUTABLE_PREFIX = lib;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
- GCC_VERSION = com.apple.compilers.llvmgcc42;
INCLUDED_SOURCE_FILE_NAMES = "$(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
- PRODUCT_NAME = FreeBSD_gcc;
+ PRODUCT_NAME = TRE;
};
name = Release;
};
C9257ED1138E1B5000B3107C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = (
"$(FreeBSD_EXCLUDED_SOURCE_GDTOA)",
"$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
C9257ED2138E1B5000B3107C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = (
"$(FreeBSD_EXCLUDED_SOURCE_GDTOA)",
"$(BASE_EXCLUDED_SOURCE_FILE_NAMES)",
C9258103138E2D3100B3107C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
+ EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
C9258104138E2D3100B3107C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
+ EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
};
name = Release;
};
+ C97A721A1517AF53005E1998 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = C9AE91AE1517CDAC00A2626C /* eos.xcconfig */;
+ buildSettings = {
+ };
+ name = Debug;
+ };
+ C97A721B1517AF53005E1998 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = C9AE91AE1517CDAC00A2626C /* eos.xcconfig */;
+ buildSettings = {
+ };
+ name = Release;
+ };
C9B5359C138D9A690028D27C /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = C9C2A948138DF7DD00287F00 /* libc.xcconfig */;
C9B53E2E138DA0610028D27C /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- EXCLUDED_SOURCE_FILE_NAMES = (
- "*/*/*.c",
- "*/*/*.s",
- "*/*/*.S",
- );
+ EXCLUDED_SOURCE_FILE_NAMES = "*";
EXECUTABLE_PREFIX = lib;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
- GCC_WARN_UNUSED_VARIABLE = YES;
- INCLUDED_SOURCE_FILE_NAMES = (
- "$(ARCH_FAMILY)/*/*.c",
- "$(ARCH_FAMILY)/*/*.s",
- "$(ARCH_FAMILY)/*/*.S",
- );
+ INCLUDED_SOURCE_FILE_NAMES = "$(Platform_INCLUDED_SOURCE_FILE_NAMES)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
C9B53E2F138DA0610028D27C /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- EXCLUDED_SOURCE_FILE_NAMES = (
- "*/*/*.c",
- "*/*/*.s",
- "*/*/*.S",
- );
+ EXCLUDED_SOURCE_FILE_NAMES = "*";
EXECUTABLE_PREFIX = lib;
- GCC_WARN_UNUSED_VARIABLE = YES;
- INCLUDED_SOURCE_FILE_NAMES = (
- "$(ARCH_FAMILY)/*/*.c",
- "$(ARCH_FAMILY)/*/*.s",
- "$(ARCH_FAMILY)/*/*.S",
- );
+ INCLUDED_SOURCE_FILE_NAMES = "$(Platform_INCLUDED_SOURCE_FILE_NAMES)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
};
C9C2A94F138DFFDA00287F00 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(BASE_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
C9C2A950138DFFDA00287F00 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(BASE_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(BASE_INCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH))";
C9D94331138DB73300FB7ACC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
/usr/lib/system,
);
+ "ORDER_FILE[sdk=iphoneos*]" = "$(SDKROOT)/AppleInternal/OrderFiles/libsystem_c.order";
OTHER_LDFLAGS = "$(LIBSYSTEM_C_LDFLAGS)";
PRODUCT_NAME = c;
SKIP_INSTALL = NO;
C9D94332138DB73300FB7ACC /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
COPY_PHASE_STRIP = YES;
DYLIB_CURRENT_VERSION = "$(CURRENT_PROJECT_VERSION)";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
/usr/lib/system,
);
+ "ORDER_FILE[sdk=iphoneos*]" = "$(SDKROOT)/AppleInternal/OrderFiles/libsystem_c.order";
OTHER_LDFLAGS = "$(LIBSYSTEM_C_LDFLAGS)";
PRODUCT_NAME = c;
SKIP_INSTALL = NO;
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
isa = XCBuildConfiguration;
baseConfigurationReference = C9766153138ECF0000741512 /* variants.xcconfig */;
buildSettings = {
+ COMBINE_HIDPI_IMAGES = YES;
EXCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_EXCLUDED_SOURCE_FILE_NAMES)";
EXECUTABLE_PREFIX = lib;
INCLUDED_SOURCE_FILE_NAMES = "$(VARIANT_INCLUDED_SOURCE_FILE_NAMES)";
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
- B122F2AA1432B8E600AF95D0 /* Build configuration list for PBXNativeTarget "TRE" */ = {
+ 3F5120EE16C3174300AFB431 /* Build configuration list for PBXNativeTarget "FortifySource" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- B122F2AB1432B8E600AF95D0 /* Debug */,
- B122F2AC1432B8E600AF95D0 /* Release */,
+ 3F5120EF16C3174300AFB431 /* Debug */,
+ 3F5120F016C3174300AFB431 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
- B1E96503157E722200FCCEE7 /* Build configuration list for PBXNativeTarget "FreeBSD_gcc" */ = {
+ B122F2AA1432B8E600AF95D0 /* Build configuration list for PBXNativeTarget "TRE" */ = {
isa = XCConfigurationList;
buildConfigurations = (
- B1E96504157E722200FCCEE7 /* Debug */,
- B1E96505157E722200FCCEE7 /* Release */,
+ B122F2AB1432B8E600AF95D0 /* Debug */,
+ B122F2AC1432B8E600AF95D0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ C97A72191517AF53005E1998 /* Build configuration list for PBXNativeTarget "libc_eOS.a" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ C97A721A1517AF53005E1998 /* Debug */,
+ C97A721B1517AF53005E1998 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
C9B5359A138D9A690028D27C /* Build configuration list for PBXProject "Libc" */ = {
isa = XCConfigurationList;
buildConfigurations = (
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<Workspace
- version = "1.0">
- <FileRef
- location = "self:Libc.xcodeproj">
- </FileRef>
-</Workspace>
# Move localtime to /var/db/timezone
FEATURE_MOVE_LOCALTIME = 1
+# Use TZDIR symlink in /var/db
+FEATURE_TZDIR_SYMLINK = 1
+
.if RC_ProjectName _Sim$
FEATURE_MOVE_LOCALTIME = 0
+FEATURE_TZDIR_SYMLINK = 0
.endif
# No pre-1050 variants (should match sys/cdefs.h)
# Patch 3417676
#FEATURE_PATCH_3417676 = 1
-# Patch 5243343
-FEATURE_PATCH_5243343 = 1
-
# plockstat dtrace support
#FEATURE_PLOCKSTAT = 1
# Timezone change notification
FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1
-# Memorystatus support for posix_spawn()
-FEATURE_MEMORYSTATUS = 1
+# Smaller stdio buffers
+FEATURE_SMALL_STDIOBUF = 1
# Move localtime to /var/db/timezone
#FEATURE_MOVE_LOCALTIME = 1
+# Use TZDIR symlink in /var/db
+#FEATURE_TZDIR_SYMLINK = 1
+
# No pre-1050 variants (should match sys/cdefs.h)
#FEATURE_ONLY_1050_VARIANTS = 1
# Patch 3417676
FEATURE_PATCH_3417676 = 1
-# Patch 5243343
-FEATURE_PATCH_5243343 = 1
-
# plockstat dtrace support
FEATURE_PLOCKSTAT = 1
# Timezone change notification
FEATURE_TIMEZONE_CHANGE_NOTIFICATION = 1
-# Memorystatus support for posix_spawn()
-FEATURE_MEMORYSTATUS = 1
+# Extensible printf performance enhancement (uses more memory)
+FEATURE_XPRINTF_PERF = 1
+++ /dev/null
-/*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include <arm/arch.h>
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#undef __APPLE_API_PRIVATE
-
- .text
- .align 2
- .globl _cpu_number
-_cpu_number:
-#ifdef _ARM_ARCH_7
- mrc p15, 0, r0, c13, c0, 3
- and r0, r0, #3
-#else
- mov r0, #0
-#endif
- bx lr
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
- .text
- .align 2
-
-#include <mach/arm/syscall_sw.h>
-
-/* void sys_icache_invalidate(addr_t start, int length) */
-.globl _sys_icache_invalidate
-_sys_icache_invalidate:
- /* fast trap for icache_invalidate */
- mov r3, #0
- mov r12, #0x80000000
- swi #SWI_SYSCALL
- bx lr
-
-/* void sys_dcache_flush(addr_t start, int length) */
-.globl _sys_dcache_flush
-_sys_dcache_flush:
- /* fast trap for dcache_flush */
- mov r3, #1
- mov r12, #0x80000000
- swi #SWI_SYSCALL
- bx lr
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/* Initialize the "_cpu_capabilities" vector on ARM processors. */
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#undef __APPLE_API_PRIVATE
-
-extern int _get_cpu_capabilities(void);
-
-int _cpu_capabilities = 0;
-int _cpu_has_altivec = 0; // DEPRECATED: use _cpu_capabilities instead
-
-__private_extern__ void
-_init_cpu_capabilities( void )
-{
-}
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include "pthread_machdep.h"
-#include <arm/arch.h>
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#undef __APPLE_API_PRIVATE
-
- .text
- .align 4
- .globl _pthread_getspecific
-_pthread_getspecific:
-#ifdef _ARM_ARCH_6
- mrc p15, 0, r1, c13, c0, 3
- bic r1, r1, #3
- add r0, r1, r0, lsl #2
-#else
- add r0, r9, r0, lsl #2
-#endif
- ldr r0, [r0, #0]
- bx lr
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include <arm/arch.h>
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#undef __APPLE_API_PRIVATE
-
- .text
- .align 2
- .globl _pthread_self
-_pthread_self:
-#ifdef _ARM_ARCH_6
- mrc p15, 0, r0, c13, c0, 3
- bic r0, r0, #3
-#else
- mov r0, r9
-#endif
- ldr r0, [r0, #0]
- bx lr
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-#include <mach/arm/syscall_sw.h>
-
- .text
- .align 2
- .globl ___pthread_set_self
-___pthread_set_self:
-#ifndef _ARM_ARCH_6
- mov r9, r0
-#endif
- /* fast trap for thread_set_cthread */
- mov r3, #2
- mov r12, #0x80000000
- swi #SWI_SYSCALL
- bx lr
+++ /dev/null
-/*
- * Copyright (c) 2009, 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include <arm/arch.h>
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#undef __APPLE_API_PRIVATE
-
-// This routine is never called directly by user code, jumped from kernel
-// args 0 to 3 are already in the regs 0 to 3
-// should set stack with the 2 extra args before calling pthread_wqthread()
-// arg4 is in r[4]
-// arg5 is in r[5]
-
- .text
- .align 2
- .globl _start_wqthread
-_start_wqthread:
- stmfd sp!, {r4, r5}
- bl __pthread_wqthread
-
-// Stackshots will show the routine that happens to link immediately following
-// _start_wqthread. So we add an extra instruction (nop) to make stackshots
-// more readable.
- nop
+++ /dev/null
-/*
- * Copyright (c) 2009, 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include <arm/arch.h>
-
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#undef __APPLE_API_PRIVATE
-
-// This routine is never called directly by user code, jumped from kernel
-// args 0 to 3 are already in the regs 0 to 3
-// should set stack with the 2 extra args before calling pthread_wqthread()
-// arg4 is in r[4]
-// arg5 is in r[5]
-
- .text
- .align 2
- .globl _thread_start
-_thread_start:
- stmfd sp!, {r4, r5}
- bl __pthread_start
-
-// Stackshots will show the routine that happens to link immediately following
-// _thread_start. So we add an extra instruction (nop) to make stackshots
-// more readable.
- nop
+++ /dev/null
-/*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD
-
-/*****************************************************************************
- * Cortex-A8 implementation *
- *****************************************************************************/
-
-// Cortex-A8 implementations of memcpy( ), memmove( ) and bcopy( ).
-//
-// Our tests have shown that NEON is always a performance win for memcpy( ).
-// However, for the specific case of copies from a warm source to a cold
-// destination when the buffer size is between 1k and 32k, it is not enough
-// of a performance win to offset the increased power footprint, resulting
-// in an energy usage regression. Thus, we detect that particular case, and
-// pass those copies through the ARM core registers. All other copies larger
-// than 8 bytes are handled on NEON.
-//
-// Stephen Canon, August 2009
-
-.text
-.code 16
-.syntax unified
-
-// void bcopy(const void * source,
-// void * destination,
-// size_t length);
-//
-// void *memmove(void * destination,
-// const void * source,
-// size_t n);
-//
-// void *memcpy(void * restrict destination,
-// const void * restrict source,
-// size_t n);
-//
-// all copy n successive bytes from source to destination. memmove and memcpy
-// returns destination, whereas bcopy has no return value. copying takes place
-// as if it were through a temporary buffer -- after return destination contains
-// exactly the bytes from source, even if the buffers overlap.
-
-.thumb_func _bcopy$VARIANT$CortexA8
-.thumb_func _memmove$VARIANT$CortexA8
-.thumb_func _memcpy$VARIANT$CortexA8
-.globl _bcopy$VARIANT$CortexA8
-.globl _memmove$VARIANT$CortexA8
-.globl _memcpy$VARIANT$CortexA8
-
-#define SAVE_REGISTERS {r4,r5,r6,r8,r10,r11}
-#define COPY_REGISTERS {r3,r4,r5,r6,r8,r9,r10,r11}
-
-/*****************************************************************************
- * entry points *
- *****************************************************************************/
-
-.align 2
-_bcopy$VARIANT$CortexA8:
-
-// bcopy has the first and second arguments in the opposite order as the C
-// library functions memmove and memcpy. If bcopy is called, we swap these
-// two arguments and then fall into memmove.
-
- mov r3, r0
- mov r0, r1
- mov r1, r3
-
-.align 2
-_memmove$VARIANT$CortexA8:
-_memcpy$VARIANT$CortexA8:
-
-// At entry to memmove/memcpy, registers contain the following values:
-//
-// r0 pointer to the first byte of the destination buffer
-// r1 pointer to the first byte of the source buffer
-// r2 number of bytes to copy
-//
-// Our preference is to use a (faster and easier to understand) front-to-back
-// copy of the buffer. However, memmove requires that copies take place as
-// though through a temporary buffer. This means that if the buffers overlap,
-// it may be necessary to copy the buffer in reverse order.
-//
-// To properly detect such overlap, we begin by computing the offset between
-// the source and destination pointers. If the offset happens to be zero,
-// then there is no work to be done, so we can early out.
-
- subs r3, r0, r1
- it eq
- bxeq lr
-
-// r3 now contains the offset between the buffers, (destination - source). If
-// 0 < offset < length, then the high-addressed bits of the source alias the
-// low addressed bytes of the destination. Thus, if we were to perform the
-// copy in ascending address order, we would overwrite the high-addressed
-// source bytes before we had a chance to copy them, and the data would be lost.
-//
-// Thus, we can use the front-to-back copy only if offset is negative or
-// greater than the length. This is the case precisely if offset compares
-// unsigned higher than length.
-
- cmp r3, r2
- bhs L_copyFrontToBack
-
-/*****************************************************************************
- * back to front copy *
- *****************************************************************************/
-
-// Here we have fallen through into the back-to-front copy. We preserve the
-// original destination pointer in r0 because it is the return value for the
-// routine, and update the other registers as follows:
-//
-// r1 one byte beyond the end of the destination buffer
-// r2 number of bytes to copy
-// ip one byte beyond the end of the destination buffer
-
- mov ip, r0
- add r1, r2
- add ip, r2
-
-// Subtract 8 from the buffer length; if this is negative, then we will use
-// only single-byte copies, and we jump directly to a scalar copy loop.
-
- subs r2, $8
- blt L_scalarReverseCopy
-
-// If the destination pointer is 8-byte aligned we can use 8-byte NEON copies
-// to move the data.
-
- tst ip, $7
- beq L_vectorReverseCopy
-
-// Otherwise, we copy a single byte at a time, in order of descending memory
-// address, until the destination is 8 byte aligned. Within this loop,
-// registers are used as follows:
-//
-// r0 original destination pointer
-// r1 pointer to one byte past the next element to be copied
-// r2 (bytes remaining to be copied) - 8
-// r3 temporary to hold the byte that is being copied
-// ip pointer one byte past the destination of the next byte to be copied
-//
-// byte that will be copied in this iteration
-// | byte that was copied in the previous iteration
-// Source buffer: v v
-// ------------------------+---+---+-------------------------
-// bytes still to copy ... | | | ... bytes already copied
-// ------------------------+---+---+-------------------------
-// ^
-// r1 holds the address of this byte
-
-0: ldrb r3, [r1, $-1]!
- sub r2, $1
- strb r3, [ip, $-1]!
- tst ip, $7
- bne 0b
-
-// At this point, the destination pointer is 8 byte aligned. Check again that
-// there are at least 8 bytes remaining to copy by comparing the remaining
-// length minus 8 to zero. If fewer than 8 bytes remain, jump to the cleanup
-// path.
-
- cmp r2, $0
- blt L_scalarReverseCopy
-
-/*****************************************************************************
- * destination is 8 byte aligned *
- *****************************************************************************/
-
-L_vectorReverseCopy:
-
-// At this point, registers contain the following values:
-//
-// r0 original destination pointer
-// r1 pointer to one byte past the next element to be copied
-// r2 (bytes remaining to copy) - 8
-// ip pointer one byte past the destination of the next byte to be copied
-//
-// Furthermore, it is known that ip is 8 byte aligned, and that r2 is positive.
-// NEON has really excellent alignment handling in hardware, so we would like
-// to use that to handle cases where the source is not similarly aligned to the
-// destination (it supports even single-byte misalignment at speed). However,
-// on some SoC designs, not all of the DMA busses support such access. Thus,
-// we must unfortunately use a software workaround in those cases.
-//
-// Fortunately, 4-byte aligned loads are supported even on the DMA busses, so
-// we only need to handle the different possible source alignments modulo 4.
-// Here we have a dispatch table to jump to the correct copy implementation
-// for the given source alignment.
-//
-// The tbh instruction loads the address offset of the correct implementation
-// from the data table that immediately follows it and adds it to the pc to
-// jump to the correct branch.
-
- ands r3, r1, $3
- tbh [pc, r3, lsl $1]
-0:
-.short (L_reverseAligned0-0b)/2
-.short (L_reverseAligned1-0b)/2
-.short (L_reverseAligned2-0b)/2
-.short (L_reverseAligned3-0b)/2
-
-/*****************************************************************************
- * source is also at least word aligned *
- *****************************************************************************/
-
-L_reverseAligned0:
-
-// Subtract 56 from r2, so that it contains the number of bytes remaining to
-// copy minus 64. If this result is negative, then we jump into a loop that
-// copies 8 bytes at a time.
-
- subs r2, $0x38
- blt L_reverseVectorCleanup
-
-// Check if the destination pointer is 64-byte aligned. If so, jump to a loop
-// that copies whole cachelines.
-
- tst ip, $0x38
- beq L_reverseCachelineAligned
-
-// Otherwise, we copy a 8 bytes at a time, in order of descending memory
-// address, until the destination is 64 byte aligned. Within this loop,
-// registers are used as follows:
-//
-// r0 original destination pointer
-// r1 pointer to one byte past the next element to be copied
-// r2 (bytes remaining to be copied) - 64
-// ip pointer one byte past the destination of the next byte to be copied
-// d0 temporary storage for copy
-//
-// bytes that will be copied after this iteration
-// | 8 byte block that will be copied in this iteration
-// v v
-// --------------+-------------------------------+---------------------
-// | 0 1 2 3 4 5 6 7 | bytes already copied
-// --------------+-------------------------------+---------------------
-// ^
-// r1 points here
-
-0: sub r1, $8
- vld1.32 {d0}, [r1]
- sub ip, $8
- sub r2, $8
- tst ip, $0x38
- vst1.64 {d0}, [ip,:64]
- bne 0b
-
-// At this point, the destination pointer is 64 byte aligned. Check again that
-// there are at least 64 bytes remaining to copy by comparing the remaining
-// length minus 64 to zero. If fewer than 64 bytes remain, skip over the main
-// copy loop.
-
- cmp r2, $0
- blt L_reverseVectorCleanup
-
-/*****************************************************************************
- * destination is cacheline aligned *
- *****************************************************************************/
-
-L_reverseCachelineAligned:
-
-// In the special case that we are copying a buffer of between 1k and 32k bytes
-// we do not use a NEON copy for the main loop. This is because if we happen
-// to be doing a copy from a source in cache to a destination that is not in
-// cache, this will result in an increase in energy usage. In all other cases,
-// NEON gives superior energy conservation.
-
- sub r3, r2, $0x3c0
- cmp r3, $0x7c00
- blo L_useSTMDB
-
-// Pre-decrement the source (r1) and destination (ip) pointers so that they
-// point to the first byte of the trailing 32-byte window of each buffer.
-// Additionally, load the address increment of -32 into r3.
-
- sub r1, $32
- sub ip, $32
- mov r3, $-32
-
-// The destination pointer is known to be 64-byte aligned, so we can use the
-// maximal alignment hint (:256) for our vector stores. Detect if the source
-// is also at least 32-byte aligned and jump to a loop that uses maximal
-// alignment hints for the loads as well if possible.
-
- tst r1, $0x1f
- beq L_reverseSourceAligned
-
-// This loop copies 64 bytes per iteration, from a 4-byte aligned source to a
-// 64-byte aligned destination, in order of descending memory address. Within
-// this loop, registers are used as follows:
-//
-// r0 original destination pointer (unmodified)
-// r1 pointer to the next 32-byte block to load
-// r2 (number of bytes remaining to copy) - 64
-// r3 address increment of -32.
-// ip pointer to which the next 32-byte block is to be stored
-// q0-q3 temporary registers used for copies
-//
-// Note that the loop is arrange in such a way that a single cleanup store is
-// necessary after the final loop iteration. This occurs at label (1), and is
-// shared between the unaligned and aligned loops.
-
- vld1.32 {q2,q3}, [r1], r3
- vld1.32 {q0,q1}, [r1], r3
- subs r2, $64
- vst1.64 {q2,q3}, [ip,:256], r3
- blt 1f
-.align 3
-0: vld1.32 {q2,q3}, [r1], r3
- vst1.64 {q0,q1}, [ip,:256], r3
- vld1.32 {q0,q1}, [r1], r3
- subs r2, $64
- vst1.64 {q2,q3}, [ip,:256], r3
- bge 0b
- b 1f
-
-L_reverseSourceAligned:
-
-// This loop is identical to the immediately preceeding loop, except that it
-// uses the additional alignment hint that the source pointer (r1) is 32-byte
-// aligned. The two loops share cleanup code for the final iteration.
-
- vld1.64 {q2,q3}, [r1,:256], r3
- vld1.64 {q0,q1}, [r1,:256], r3
- subs r2, $64
- vst1.64 {q2,q3}, [ip,:256], r3
- blt 1f
-.align 3
-0: vld1.64 {q2,q3}, [r1,:256], r3
- vst1.64 {q0,q1}, [ip,:256], r3
- vld1.64 {q0,q1}, [r1,:256], r3
- subs r2, $64
- vst1.64 {q2,q3}, [ip,:256], r3
- bge 0b
-
-// Final vector store for both of the above loops.
-
-1: vst1.64 {q0,q1}, [ip,:256], r3
-
-// Adjust the source and destination pointers so that they once again point to
-// the last byte that we used (which is one byte higher than the address that
-// we will use next for any required cleanup).
-
- add r1, $32
- add ip, $32
-
-L_reverseVectorCleanup:
-
-// Add 56 to r2, so that it contains the number of bytes remaing to copy minus
-// 8. A comparison of this value with zero tells us if any more whole 8-byte
-// blocks need to be copied.
-
- adds r2, r2, $0x38
- blt L_scalarReverseCopy
-
-// This loop copies 8 bytes at a time in order of descending memory address,
-// until fewer than 8 bytes remain to be copied. Within this loop, registers
-// are used as follows:
-//
-// r0 original destination pointer
-// r1 pointer to one byte past the next element to be copied
-// r2 (bytes remaining to be copied) - 64
-// ip pointer one byte past the destination of the next byte to be copied
-// d0 temporary storage for copy
-
-0: sub r1, $8
- vld1.32 {d0}, [r1]
- sub ip, $8
- subs r2, $8
- vst1.64 {d0}, [ip,:64]
- bge 0b
-
-/*****************************************************************************
- * sub-doubleword cleanup copies *
- *****************************************************************************/
-
-L_scalarReverseCopy:
-
-// Add 8 to r2, so that it contains the number of bytes remaining to copy, and
-// return to the calling routine if zero bytes remain.
-
- adds r2, $8
- it eq
- bxeq lr
-
-// Copy one byte at a time in descending address order until we reach the front
-// of the buffer. Within this loop, registers are used as follows:
-//
-// r0 original destination pointer
-// r1 pointer to one byte past the next element to be copied
-// r2 (bytes remaining to be copied) - 8
-// r3 temporary to hold the byte that is being copied
-// ip pointer one byte past the destination of the next byte to be copied
-
-0: ldrb r3, [r1, $-1]!
- subs r2, $1
- strb r3, [ip, $-1]!
- bne 0b
- bx lr
-
-/*****************************************************************************
- * STMDB loop for 1k-32k buffers *
- *****************************************************************************/
-
-// This loop copies 64 bytes each iteration in order of descending memory
-// address, using the GPRs instead of NEON.
-//
-// r0 original destination pointer
-// r1 pointer to one byte past the next element to be copied
-// r2 (bytes remaining to be copied) - 64
-// r3-6,r8-11 (COPY_REGISTERS) temporary registers used for moving data
-// ip pointer to one byte past the next location to store to
-
-L_useSTMDB:
- push SAVE_REGISTERS
-.align 3
-0: ldmdb r1!, COPY_REGISTERS
- subs r2, r2, $64
- stmdb ip!, COPY_REGISTERS
- ldmdb r1!, COPY_REGISTERS
- pld [r1, $-64]
- stmdb ip!, COPY_REGISTERS
- bge 0b
- pop SAVE_REGISTERS
- b L_reverseVectorCleanup
-
-/*****************************************************************************
- * Misaligned reverse vld1 loop *
- *****************************************************************************/
-
-// Software alignment fixup to handle source and dest that are relatively
-// misaligned mod 4 bytes.
-//
-// The basic idea is to use 4-byte aligned loads to load 8 bytes per iteration,
-// which we combine with the 8 bytes loaded in the previous iteration to get a
-// 16 byte field; the next 8 bytes to be stored to the destination buffer are
-// somewhere in that field, and we get them using the VEXT instruction:
-//
-// | 8 bytes from this iteration | 8 bytes from last iteration |
-// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-// | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f |
-// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-// ^8 bytes to store this iteration^ |
-// could be a page boundary
-//
-// We need to be a little bit careful, however. Because the loads only have 4
-// byte alignment, the very first load could slop over into a page that is not
-// mapped readable. In order to prevent this scenario, we copy eight bytes
-// using byte-by-byte before beginning the main loop.
-//
-// At the beginning of each iteration through this loop, registers are used
-// as follows:
-//
-// r0 original destination pointer
-// r1 pointer to the next block of 8 bytes to load
-// r2 (bytes remaining to copy) - 8
-// ip pointer to the next block of 8 bytes to store
-// d0 next 8 bytes to store
-// d2 8 bytes loaded in the previous iteration
-// d3 8 bytes loaded two iterations ago
-
-#define RCOPY_UNALIGNED(offset) \
-0: ldrb r3, [r1,$-1]! ;\
- strb r3, [ip,$-1]! ;\
- subs r2, $1 ;\
- blt L_scalarReverseCopy ;\
- tst ip, $7 ;\
- bne 0b ;\
- bic r1, $3 ;\
- sub r1, $8 ;\
- sub ip, $8 ;\
- mov r3, $-8 ;\
- vld1.32 {d2,d3}, [r1], r3 ;\
- subs r2, $8 ;\
- blt 1f ;\
-0: vext.8 d0, d2, d3, $(offset);\
- vmov d3, d2 ;\
- vld1.32 {d2}, [r1], r3 ;\
- subs r2, $8 ;\
- vst1.64 {d0}, [ip, :64], r3 ;\
- bge 0b ;\
-1: vext.8 d0, d2, d3, $(offset);\
- add r1, $8 ;\
- vst1.64 {d0}, [ip, :64] ;\
-2: add r1, $(offset);\
- b L_scalarReverseCopy
-
-L_reverseAligned1:
- RCOPY_UNALIGNED(1)
-L_reverseAligned2:
- RCOPY_UNALIGNED(2)
-L_reverseAligned3:
- RCOPY_UNALIGNED(3)
-
-/*****************************************************************************
- * front to back copy *
- *****************************************************************************/
-
-L_copyFrontToBack:
-
-// Here the pointers are laid out such that we can use our preferred
-// front-to-back copy. We preserve original destination pointer in r0 because
-// it is the return value for the routine, and copy it to ip to use in this
-// routine.
-
- mov ip, r0
-
-// Subtract 8 from the buffer length; if this is negative, then we will use
-// only single-byte copies, and we jump directly to a scalar copy loop.
-
- subs r2, $8
- blt L_scalarCopy
-
-// If the destination pointer is 8-byte aligned we can use 8-byte NEON copies
-// to move the data.
-
- tst ip, $7
- beq L_vectorCopy
-
-// Otherwise, we copy a single byte at a time, in order of ascending memory
-// address, until the destination is 8 byte aligned. Within this loop,
-// registers are used as follows:
-//
-// r0 original destination pointer
-// r1 pointer to the next byte to copy
-// r2 (bytes remaining to be copied) - 8
-// r3 temporary to hold the byte that is being copied
-// ip pointer to the next byte to store to
-
-0: ldrb r3, [r1], $1
- sub r2, $1
- strb r3, [ip], $1
- tst ip, $7
- bne 0b
-
-// At this point, the destination pointer is 8 byte aligned. Check again that
-// there are at least 8 bytes remaining to copy by comparing the remaining
-// length minus 8 to zero. If fewer than 8 bytes remain, jump to the cleanup
-// path.
-
- cmp r2, $0
- blt L_scalarCopy
-
-/*****************************************************************************
- * destination is doubleword aligned *
- *****************************************************************************/
-
-L_vectorCopy:
-
-// At this point, registers contain the following values:
-//
-// r0 original destination pointer
-// r1 pointer to the next element to be copied
-// r2 (bytes remaining to copy) - 8
-// ip pointer to the destination of the next byte to be copied
-//
-// Furthermore, it is known that ip is 8 byte aligned, and that r2 is positive.
-// NEON has really excellent alignment handling in hardware, so we would like
-// to use that to handle cases where the source is not similarly aligned to the
-// destination (it supports even single-byte misalignment at speed). However,
-// on some SoC designs, not all of the DMA busses support such access. Thus,
-// we must unfortunately use a software workaround in those cases.
-//
-// Fortunately, 4-byte aligned loads are supported even on the DMA busses, so
-// we only need to handle the different possible source alignments modulo 4.
-// Here we have a dispatch table to jump to the correct copy implementation
-// for the given source alignment.
-//
-// The tbh instruction loads the address offset of the correct implementation
-// from the data table that immediately follows it and adds it to the pc to
-// jump to the correct branch.
-
- ands r3, r1, $3
- bic r1, $3
- tbh [pc, r3, lsl $1]
-0:
-.short (L_sourceAligned0-0b)/2
-.short (L_sourceAligned1-0b)/2
-.short (L_sourceAligned2-0b)/2
-.short (L_sourceAligned3-0b)/2
-
-/*****************************************************************************
- * source is also at least word aligned *
- *****************************************************************************/
-
-L_sourceAligned0:
-
-// Subtract 56 from r2, so that it contains the number of bytes remaining to
-// copy minus 64. If this result is negative, then we jump into a loop that
-// copies 8 bytes at a time.
-
- subs r2, $0x38
- blt L_vectorCleanup
-
-// Check if the destination pointer is 64-byte aligned. If so, jump to a loop
-// that copies whole cachelines.
-
- tst ip, $0x38
- beq L_cachelineAligned
-
-// Otherwise, we copy a 8 bytes at a time, in order of ascending memory
-// address, until the destination is 64 byte aligned. Within this loop,
-// registers are used as follows:
-//
-// r0 original destination pointer
-// r1 pointer to the next element to be copied
-// r2 (bytes remaining to be copied) - 64
-// ip pointer to the destination of the next byte to be copied
-// d0 temporary storage for copy
-
-0: vld1.32 {d0}, [r1]!
- sub r2, $8
- vst1.64 {d0}, [ip,:64]!
- tst ip, $0x38
- bne 0b
-
-// At this point, the destination pointer is 64 byte aligned. Check again that
-// there are at least 64 bytes remaining to copy by comparing the remaining
-// length minus 64 to zero. If fewer than 64 bytes remain, skip over the main
-// copy loop.
-
- cmp r2, $0
- blt L_vectorCleanup
-
-/*****************************************************************************
- * destination is cacheline aligned *
- *****************************************************************************/
-
-// In the special case that we are copying a buffer of between 1k and 32k bytes
-// we do not use a NEON copy for the main loop. This is because if we happen
-// to be doing a copy from a source in cache to a destination that is not in
-// cache, this will result in an increase in energy usage. In all other cases,
-// NEON gives superior energy conservation.
-
-L_cachelineAligned:
- sub r3, r2, $0x3c0
- cmp r3, $0x7c00
- blo L_useSTMIA
-
-// The destination pointer is known to be 64-byte aligned, so we can use the
-// maximal alignment hint (:256) for our vector stores. Detect if the source
-// is also at least 32-byte aligned and jump to a loop that uses maximal
-// alignment hints for the loads as well if possible.
-
- tst r1, $0x1f
- beq L_sourceAligned32
-
-// This loop copies 64 bytes per iteration, from a 4-byte aligned source to a
-// 64-byte aligned destination, in order of ascending memory address. Within
-// this loop, registers are used as follows:
-//
-// r0 original destination pointer (unmodified)
-// r1 pointer to the next 32-byte block to load
-// r2 (number of bytes remaining to copy) - 64
-// ip pointer to which the next 32-byte block is to be stored
-// q0-q3 temporary registers used for copies
-//
-// Note that the loop is arrange in such a way that a single cleanup store is
-// necessary after the final loop iteration. This occurs at label (1), and is
-// shared between the unaligned and aligned loops.
-
- vld1.32 {q2,q3}, [r1]!
- vld1.32 {q0,q1}, [r1]!
- subs r2, $64
- vst1.64 {q2,q3}, [ip,:256]!
- blt 1f
-.align 3
-0: vld1.32 {q2,q3}, [r1]!
- vst1.64 {q0,q1}, [ip,:256]!
- vld1.32 {q0,q1}, [r1]!
- subs r2, $64
- vst1.64 {q2,q3}, [ip,:256]!
- bge 0b
- b 1f
-
-L_sourceAligned32:
-
-// This loop is identical to the immediately preceeding loop, except that it
-// uses the additional alignment hint that the source pointer (r1) is 32-byte
-// aligned. The two loops share cleanup code for the final iteration.
-
- vld1.64 {q2,q3}, [r1,:256]!
- vld1.64 {q0,q1}, [r1,:256]!
- subs r2, $64
- vst1.64 {q2,q3}, [ip,:256]!
- blt 1f
-.align 3
-0: vld1.64 {q2,q3}, [r1,:256]!
- vst1.64 {q0,q1}, [ip,:256]!
- vld1.64 {q0,q1}, [r1,:256]!
- subs r2, $64
- vst1.64 {q2,q3}, [ip,:256]!
- bge 0b
-
-// Final vector store for both of the above loops.
-
-1: vst1.64 {q0,q1}, [ip,:256]!
-
-L_vectorCleanup:
-
-// Add 56 to r2, so that it contains the number of bytes remaing to copy minus
-// 8. A comparison of this value with zero tells us if any more whole 8-byte
-// blocks need to be copied.
-
- adds r2, $0x38
- blt L_scalarCopy
-
-// This loop copies 8 bytes at a time in order of descending memory address,
-// until fewer than 8 bytes remain to be copied. Within this loop, registers
-// are used as follows:
-//
-// r0 original destination pointer
-// r1 pointer to the next element to be copied
-// r2 (bytes remaining to be copied) - 64
-// ip pointer to the destination of the next byte to be copied
-// d0 temporary storage for copy
-
-0: vld1.32 {d0}, [r1]!
- subs r2, $8
- vst1.64 {d0}, [ip,:64]!
- bge 0b
-
-/*****************************************************************************
- * sub-doubleword cleanup copies *
- *****************************************************************************/
-
-L_scalarCopy:
-
-// Add 8 to r2, so that it contains the number of bytes remaining to copy, and
-// return to the calling routine if zero bytes remain.
-
- adds r2, $8
- it eq
- bxeq lr
-
-// Copy one byte at a time in descending address order until we reach the front
-// of the buffer. Within this loop, registers are used as follows:
-//
-// r0 original destination pointer
-// r1 pointer to one byte past the next element to be copied
-// r2 (bytes remaining to be copied) - 8
-// r3 temporary to hold the byte that is being copied
-// ip pointer one byte past the destination of the next byte to be copied
-
-0: ldrb r3, [r1], $1
- strb r3, [ip], $1
- subs r2, $1
- bne 0b
- bx lr
-
-/*****************************************************************************
- * STMIA loop for 1k-32k buffers *
- *****************************************************************************/
-
-// This loop copies 64 bytes each iteration in order of ascending memory
-// address, using the GPRs instead of NEON.
-//
-// r0 original destination pointer
-// r1 pointer to the next element to be copied
-// r2 (bytes remaining to be copied) - 64
-// r3-6,r8-11 (COPY_REGISTERS) temporary registers used for moving data
-// ip pointer to the next location to store to
-
-L_useSTMIA:
- push SAVE_REGISTERS
-.align 3
-0: ldmia r1!, COPY_REGISTERS
- subs r2, r2, $64
- stmia ip!, COPY_REGISTERS
- ldmia r1!, COPY_REGISTERS
- pld [r1, $64]
- stmia ip!, COPY_REGISTERS
- bge 0b
- pop SAVE_REGISTERS
- b L_vectorCleanup
-
-/*****************************************************************************
- * Misaligned forward vld1 loop *
- *****************************************************************************/
-
-// Software alignment fixup to handle source and dest that are relatively
-// misaligned mod 4 bytes.
-//
-// The basic idea is to use 4-byte aligned loads to load 8 bytes per iteration,
-// which we combine with the 8 bytes loaded in the previous iteration to get a
-// 16 byte field; the next 8 bytes to be stored to the destination buffer are
-// somewhere in that field, and we get them using the VEXT instruction:
-//
-// | 8 bytes from last iteration | 8 bytes from this iteration |
-// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-// | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f |
-// +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
-// ^8 bytes to store this iteration^ |
-// could be a page boundary
-//
-// We need to be a little bit careful, however. Because the loads only have 4
-// byte alignment, if we used this approach all the way to the end of the
-// buffer, the very last 8 byte load might slop over onto a new page by 4
-// bytes, and that new page might not be mapped into our process. Thus, we
-// terminate this copy loop when fewer than 12 bytes remain to be copied,
-// instead of the more natural-seeming termination condition of "8 bytes
-// remaining" (the illustration above shows the worst case and demonstrates
-// why 12 is a sufficiently safe condition).
-//
-// At the beginning of each iteration through this loop, registers are used
-// as follows:
-//
-// r0 original destination pointer
-// r1 pointer to the next block of 8 bytes to load
-// r2 (bytes remaining to copy) - 12
-// ip pointer to the next block of 8 bytes to store
-// d0 next 8 bytes to store
-// d2 8 bytes loaded in the previous iteration
-// d3 8 bytes loaded two iterations ago
-
-#define COPY_UNALIGNED(offset) \
- subs r2, $4 ;\
- blt 2f ;\
- vld1.32 {d2,d3}, [r1]! ;\
- subs r2, $8 ;\
- blt 1f ;\
-0: vext.8 d0, d2, d3, $(offset);\
- vmov d2, d3 ;\
- vld1.32 {d3}, [r1]! ;\
- subs r2, $8 ;\
- vst1.64 {d0}, [ip, :64]! ;\
- bge 0b ;\
-1: vext.8 d0, d2, d3, $(offset);\
- sub r1, $8 ;\
- vst1.64 {d0}, [ip, :64]! ;\
-2: add r1, $(offset);\
- add r2, $4 ;\
- b L_scalarCopy
-
-L_sourceAligned1:
- COPY_UNALIGNED(1)
-L_sourceAligned2:
- COPY_UNALIGNED(2)
-L_sourceAligned3:
- COPY_UNALIGNED(3)
-
-#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
+++ /dev/null
-/*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- *
- * This file implements the following functions for the Cortex-A9 processor:
- *
- * void bcopy(const void * source,
- * void * destination,
- * size_t length);
- *
- * void *memmove(void * destination,
- * const void * source,
- * size_t n);
- *
- * void *memcpy(void * restrict destination,
- * const void * restrict source,
- * size_t n);
- *
- * All copy n successive bytes from source to destination. Memmove and memcpy
- * return destination, whereas bcopy has no return value. Copying takes place
- * as if it were through a temporary buffer -- after return destination
- * contains exactly the bytes from source, even if the buffers overlap (this is
- * not required of memcpy by the C standard; its behavior is undefined if the
- * buffers overlap, but we are holding ourselves to the historical behavior of
- * this function on OS X and iOS).
- */
-
-#include <arm/arch.h>
-#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD
-
-/*****************************************************************************
- * Macros *
- *****************************************************************************/
-
-#define A9_ENTRY(name) \
- .align 2;\
- .globl _ ## name ## $VARIANT$CortexA9;\
- _ ## name ## $VARIANT$CortexA9:
-
-#define ESTABLISH_FRAME \
- push {r0,r4,r7,lr};\
- add r7, sp, #8
-
-#define CLEAR_FRAME_AND_RETURN \
- pop {r0,r4,r7,pc}
-
-#define ADDITIONAL_CALLEE_SAVE_REGISTERS {r5,r6,r8,r10}
-
-#define COPY_REGISTERS {r3,r4,r5,r6,r8,r9,r10,r12}
-
-/*****************************************************************************
- * entry points *
- *****************************************************************************/
-
-.text
-.syntax unified
-.code 32
-
-A9_ENTRY(bcopy)
-// Translate bcopy calls into memcpy calls by swapping the first and second
-// arguments.
- mov r3, r0
- mov r0, r1
- mov r1, r3
-
-A9_ENTRY(memcpy)
-A9_ENTRY(memmove)
-// Our preference is to copy the data in ascending address order, but if the
-// buffers overlap such that the beginning of the destination buffer aliases
-// the end of the source buffer, we need to copy in descending address order
-// instead to preserve the memmove semantics. We detect this case with the
-// test:
-//
-// destination - source < length (unsigned compare)
-//
-// If the address of the source buffer is higher than the address of the
-// destination buffer, this arithmetic can overflow, but the overflowed value
-// can only be smaller than length if the buffers do not overlap, so we don't
-// need to worry about false positives due to the overflow (they happen, but
-// only in cases where copying in either order is correct).
- subs r3, r0, r1
- bxeq lr
- ESTABLISH_FRAME
- cmp r3, r2
- blo L_descendingCopy
-
-/*****************************************************************************
- * ascending copy *
- *****************************************************************************/
-
-// The layout of the two buffers is such that we can use our preferred
-// (ascending address order) copy implementation. Throughout this copy,
-// registers are used as follows:
-//
-// r0 lowest unwritten address in the destination buffer.
-// r1 lowest unread address in the source buffer.
-// r2 number of bytes remaining to copy less an offset that varies
-// with the size of the copies that are being made.
-// r3, r4, r5, r6, r8, r9, r10, r12
-// temporary registers used to hold the data during copies.
-// r12 also used as a scratch register for alignment / length calculations
-
-L_ascendingCopy:
-// We begin by checking if less than four bytes are to be copied; if so, we
-// branch directly to a small-buffer copy and return. Otherwise, we copy up
-// to three bytes if needed to make the destination pointer have word (four
-// byte) alignment.
- subs r2, #4
- blo L_ascendingLengthLessThanFour
- ands ip, r0, #0x3
- beq L_ascendingDestinationWordAligned
- ldrb r3, [r1],#1
- cmp ip, #2
- ldrbls r4, [r1],#1
- strb r3, [r0],#1
- ldrblo r3, [r1],#1
- add r2, ip
- strbls r4, [r0],#1
- strblo r3, [r0],#1
- subs r2, #4
- bhs L_ascendingDestinationWordAligned
-
-L_ascendingLengthLessThanFour:
-// Conditionally copies up to three bytes, assuming no alignment. This is
-// only used if the original length of the buffer is smaller than four.
- lsls ip, r2, #31
- ldrbcs r3, [r1],#1
- ldrbcs ip, [r1],#1
- ldrbmi r4, [r1]
- strbcs r3, [r0],#1
- strbcs ip, [r0],#1
- strbmi r4, [r0]
- CLEAR_FRAME_AND_RETURN
-
-L_ascendingDestinationWordAligned:
-// We know that the destination has word alignment. If the source is not
-// similarly aligned, jump to an unaligned copy loop.
- tst r1, #0x3
- bne L_ascendingUnalignedCopy
-
-/*****************************************************************************
- * ascending copy, both buffers have word alignment *
- *****************************************************************************/
-
-// If less than sixty-four bytes remain to be copied, jump directly to the
-// word-aligned cleanup path. Otherwise, we copy up to 28 bytes as needed
-// to make the destination pointer have cacheline alignment.
- subs r2, r2, #0x3c
- blo L_ascendingLengthLessThanSixtyFour
-0: tst r0, #0x1c
- beq L_ascendingDestinationCachelineAligned
- ldr r3, [r1],#4
- subs r2, #4
- str r3, [r0],#4
- bhs 0b
- b L_ascendingLengthLessThanSixtyFour
-
-L_ascendingDestinationCachelineAligned:
-// Unrolled main copy loop; copies two cachelines (64 bytes) per iteration.
-// Empirical testing suggests that 0x60 is the optimal lookahead for preload,
-// though anything between 0x40 and 0x100 seems to be "acceptable".
- push ADDITIONAL_CALLEE_SAVE_REGISTERS
-0: ldm r1!, COPY_REGISTERS
- subs r2, r2, #0x40
- stm r0!, COPY_REGISTERS
- pld [r1, #0x60]
- ldm r1!, COPY_REGISTERS
- pld [r1, #0x60]
- stm r0!, COPY_REGISTERS
- bhs 0b
- pop ADDITIONAL_CALLEE_SAVE_REGISTERS
-
-L_ascendingLengthLessThanSixtyFour:
-// Cleanup copy of up to 63 bytes. We can assume that both the source and
-// destination addresses have word alignment here.
- tst r2, #0x30
- beq 1f
-0: ldm r1!, {r3,r4,r9,ip}
- sub r2, r2, #0x10
- stm r0!, {r3,r4,r9,ip}
- tst r2, #0x30
- bne 0b
-1: tst r2, #0xf
- beq 2f
- lsls ip, r2, #29
- ldmcs r1!, {r3,ip}
- stmcs r0!, {r3,ip}
- ldrmi r3, [r1],#4
- strmi r3, [r0],#4
- lsls ip, r2, #31
- ldrhcs r3, [r1],#2
- strhcs r3, [r0],#2
- ldrbmi ip, [r1]
- strbmi ip, [r0]
-2: CLEAR_FRAME_AND_RETURN
-
-/*****************************************************************************
- * ascending copy, source buffer is not word aligned *
- *****************************************************************************/
-
-L_ascendingUnalignedCopy:
-// Destination buffer is word aligned, but source buffer is not. Copy
-// byte-by-byte until the destination buffer has eightbyte alignment.
- subs r2, #4
- blo L_ascendingUnalignedByteCleanup
-0: tst r0, #0x7
- beq L_ascendingUnalignedVectorCopy
- ldrb r3, [r1],#1
- subs r2, #1
- strb r3, [r0],#1
- bhs 0b
-L_ascendingUnalignedByteCleanup:
- adds r2, #8
- beq 1f
-0: ldrb r3, [r1],#1
- subs r2, #1
- strb r3, [r0],#1
- bne 0b
-1: CLEAR_FRAME_AND_RETURN
-
-L_ascendingUnalignedVectorCopy:
-// Destination buffer is eightbyte aligned. Source buffer has unknown
-// alignment. Use NEON to handle the misaligned copies. We begin by copying
-// up to 24 bytes to get cacheline alignment of the destination buffer.
- subs r2, #0x18
- blo L_ascendingUnalignedVectorCleanup
-0: tst r0, #0x18
- beq L_ascendingUnalignedCachelineCopy
- vld1.8 {d0}, [r1]!
- subs r2, #8
- vst1.8 {d0}, [r0,:64]!
- bhs 0b
-L_ascendingUnalignedVectorCleanup:
- adds r2, #0x18
- blo L_ascendingUnalignedByteCleanup
-0: vld1.8 {d0}, [r1]!
- subs r2, #8
- vst1.8 {d0}, [r0,:64]!
- bhs 0b
- b L_ascendingUnalignedByteCleanup
-
-L_ascendingUnalignedCachelineCopy:
-// Main copy loop; moves 32 bytes per iteration. Requires only byte alignment
-// of the source address.
- vld1.8 {q0,q1},[r1]!
- pld [r1, #0x60]
- vst1.8 {q0,q1},[r0,:256]!
- subs r2, #0x20
- bhs L_ascendingUnalignedCachelineCopy
- b L_ascendingUnalignedVectorCleanup
-
-/*****************************************************************************
- * descending copy *
- *****************************************************************************/
-
-// The layout of the two buffers is such that we must copy in descending-
-// address order. Throughout this copy, registers are used as follows:
-//
-// r0 lowest address in the destination buffer that has been written to.
-// r1 lowest address in the source buffer that has been read from.
-// r2 number of bytes remaining to copy less an offset that varies
-// with the size of the copies that are being made.
-// r3, r4, r5, r6, r8, r9, r10, r12
-// temporary registers used to hold the data during copies.
-// r12 also used as a scratch register for alignment / length calculations
-
-L_descendingCopy:
-// We begin by checking if less than four bytes are to be copied; if so, we
-// branch directly to a small-buffer copy and return. Otherwise, we copy up
-// to three bytes if needed to make the destination pointer have word (four
-// byte) alignment.
- add r1, r2
- add r0, r2
- subs r2, #4
- blo L_descendingLengthLessThanFour
- ands ip, r0, #0x3
- beq L_descendingDestinationWordAligned
- ldrb r3, [r1, #-1]!
- cmp ip, #2
- ldrbhs r4, [r1, #-1]!
- strb r3, [r0, #-1]!
- ldrbhi r3, [r1, #-1]!
- strbhs r4, [r0, #-1]!
- strbhi r3, [r0, #-1]!
- subs r2, ip
- bhs L_descendingDestinationWordAligned
-
-L_descendingLengthLessThanFour:
-// Conditionally copies up to three bytes, assuming no alignment. This is
-// only used if the original length of the buffer is smaller than four.
- lsls ip, r2, #31
- ldrbcs r3, [r1, #-1]!
- ldrbcs ip, [r1, #-1]!
- ldrbmi r4, [r1, #-1]
- strbcs r3, [r0, #-1]!
- strbcs ip, [r0, #-1]!
- strbmi r4, [r0, #-1]
- CLEAR_FRAME_AND_RETURN
-
-L_descendingDestinationWordAligned:
-// We know that the destination has word alignment. If the source is not
-// similarly aligned, jump to an unaligned copy loop.
- tst r1, #0x3
- bne L_descendingUnalignedCopy
-
-/*****************************************************************************
- * descending copy, both buffers have word alignment *
- *****************************************************************************/
-
-// If less than sixty-four bytes remain to be copied, jump directly to the
-// word-aligned cleanup path. Otherwise, we copy up to 28 bytes as needed
-// to make the destination pointer have cacheline alignment.
- subs r2, r2, #0x3c
- blo L_descendingLengthLessThanSixtyFour
-0: tst r0, #0x1c
- beq L_descendingDestinationCachelineAligned
- ldr r3, [r1, #-4]!
- subs r2, #4
- str r3, [r0, #-4]!
- bhs 0b
- b L_descendingLengthLessThanSixtyFour
-
-L_descendingDestinationCachelineAligned:
-// Unrolled main copy loop; copies two cachelines (64 bytes) per iteration.
-// Empirical testing suggests that -0x80 is the optimal lookahead for preload,
-// though anything between -0x40 and -0x100 seems to be "acceptable".
- push ADDITIONAL_CALLEE_SAVE_REGISTERS
-0: ldmdb r1!, COPY_REGISTERS
- subs r2, r2, #0x40
- stmdb r0!, COPY_REGISTERS
- pld [r1, #-0x80]
- ldmdb r1!, COPY_REGISTERS
- pld [r1, #-0x80]
- stmdb r0!, COPY_REGISTERS
- bhs 0b
- pop ADDITIONAL_CALLEE_SAVE_REGISTERS
-
-L_descendingLengthLessThanSixtyFour:
-// Cleanup copy of up to 63 bytes. We can assume that both the source and
-// destination addresses have word alignment here.
- tst r2, #0x30
- beq 1f
-0: ldmdb r1!, {r3,r4,r9,ip}
- sub r2, r2, #0x10
- stmdb r0!, {r3,r4,r9,ip}
- tst r2, #0x30
- bne 0b
-1: tst r2, #0xf
- beq 2f
- lsls ip, r2, #29
- ldmdbcs r1!, {r3,ip}
- stmdbcs r0!, {r3,ip}
- ldrmi r3, [r1, #-4]!
- strmi r3, [r0, #-4]!
- lsls ip, r2, #31
- ldrhcs r3, [r1, #-2]!
- strhcs r3, [r0, #-2]!
- ldrbmi ip, [r1, #-1]
- strbmi ip, [r0, #-1]
-2: CLEAR_FRAME_AND_RETURN
-
-/*****************************************************************************
- * descending copy, source buffer is not word aligned *
- *****************************************************************************/
-
-L_descendingUnalignedCopy:
-// Destination buffer is word aligned, but source buffer is not. Copy
-// byte-by-byte until the destination buffer has eightbyte alignment.
- subs r2, #4
- blo L_descendingUnalignedByteCleanup
-0: tst r0, #0x7
- beq L_descendingUnalignedVectorCopy
- ldrb r3, [r1, #-1]!
- subs r2, #1
- strb r3, [r0, #-1]!
- bhs 0b
-L_descendingUnalignedByteCleanup:
- adds r2, #8
- beq 1f
-0: ldrb r3, [r1, #-1]!
- subs r2, #1
- strb r3, [r0, #-1]!
- bne 0b
-1: CLEAR_FRAME_AND_RETURN
-
-L_descendingUnalignedVectorCopy:
-// Destination buffer is eightbyte aligned. Source buffer has unknown
-// alignment. Use NEON to handle the misaligned copies. We begin by copying
-// up to 24 bytes to get cacheline alignment of the destination buffer.
- subs r2, #0x18
- blo L_descendingUnalignedVectorCleanup
-0: tst r0, #0x18
- beq L_descendingUnalignedCachelineCopy
- sub r1, #8
- vld1.8 {d0}, [r1]
- sub r0, #8
- vst1.8 {d0}, [r0,:64]
- subs r2, #8
- bhs 0b
-L_descendingUnalignedVectorCleanup:
- adds r2, #0x18
- blo L_descendingUnalignedByteCleanup
-0: sub r1, #8
- vld1.8 {d0}, [r1]
- sub r0, #8
- vst1.8 {d0}, [r0,:64]
- subs r2, #8
- bhs 0b
- b L_descendingUnalignedByteCleanup
-
-L_descendingUnalignedCachelineCopy:
-// Main copy loop; moves 32 bytes per iteration. Requires only byte alignment
-// of the source address.
- sub r1, #32
- sub r0, #32
- mov r4, #-32
-0: vld1.8 {q0,q1},[r1], r4
- pld [r1, #-0x60]
- vst1.8 {q0,q1},[r0,:256], r4
- subs r2, #0x20
- bhs 0b
- add r1, #32
- add r0, #32
- b L_descendingUnalignedVectorCleanup
-
-#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
+++ /dev/null
-/*
- * Copyright (c) 2006, 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*****************************************************************************
- * ARMv5 and ARMv6 implementation, also used in dyld on later archs *
- *****************************************************************************/
-
-#include <arm/arch.h>
-#if !defined _ARM_ARCH_7 || defined VARIANT_DYLD
-
-.text
-.align 2
-
- .globl _memcpy
- .globl _bcopy
- .globl _memmove
-
-_bcopy: /* void bcopy(const void *src, void *dest, size_t len); */
- mov r3, r0
- mov r0, r1
- mov r1, r3
-
-_memcpy: /* void *memcpy(void *dest, const void *src, size_t len); */
-_memmove: /* void *memmove(void *dest, const void *src, size_t len); */
- /* check for zero len or if the pointers are the same */
- cmp r2, #0
- cmpne r0, r1
- bxeq lr
-
- /* save r0 (return value), r4 (scratch), and r5 (scratch) */
- stmfd sp!, { r0, r4, r5, r7, lr }
- add r7, sp, #12
-
- /* check for overlap. r3 <- distance between src & dest */
- subhs r3, r0, r1
- sublo r3, r1, r0
- cmp r3, r2 /* if distance(src, dest) < len, we have overlap */
- blo Loverlap
-
-Lnormalforwardcopy:
- /* are src and dest dissimilarly word aligned? */
- mov r12, r0, lsl #30
- cmp r12, r1, lsl #30
- bne Lnonwordaligned_forward
-
- /* if len < 64, do a quick forward copy */
- cmp r2, #64
- blt Lsmallforwardcopy
-
- /* check for 16 byte src/dest unalignment */
- tst r0, #0xf
- bne Lsimilarlyunaligned
-
- /* check for 32 byte dest unalignment */
- tst r0, #(1<<4)
- bne Lunaligned_32
-
-Lmorethan64_aligned:
- /* save some more registers to use in the copy */
- stmfd sp!, { r6, r8, r10, r11 }
-
- /* pre-subtract 64 from the len counter to avoid an extra compare in the loop */
- sub r2, r2, #64
-
-L64loop:
- /* copy 64 bytes at a time */
- ldmia r1!, { r3, r4, r5, r6, r8, r10, r11, r12 }
-#ifdef _ARM_ARCH_6
- pld [r1, #32]
-#endif
- stmia r0!, { r3, r4, r5, r6, r8, r10, r11, r12 }
- ldmia r1!, { r3, r4, r5, r6, r8, r10, r11, r12 }
- subs r2, r2, #64
-#ifdef _ARM_ARCH_6
- pld [r1, #32]
-#endif
- stmia r0!, { r3, r4, r5, r6, r8, r10, r11, r12 }
- bge L64loop
-
- /* restore the scratch registers we just saved */
- ldmfd sp!, { r6, r8, r10, r11 }
-
- /* fix up the len counter (previously subtracted an extra 64 from it) and test for completion */
- adds r2, r2, #64
- beq Lexit
-
-Llessthan64_aligned:
- /* copy 16 bytes at a time until we have < 16 bytes */
- cmp r2, #16
- ldmgeia r1!, { r3, r4, r5, r12 }
- stmgeia r0!, { r3, r4, r5, r12 }
- subges r2, r2, #16
- bgt Llessthan64_aligned
- beq Lexit
-
-Llessthan16_aligned:
- mov r2, r2, lsl #28
- msr cpsr_f, r2
-
- ldmmiia r1!, { r2, r3 }
- ldreq r4, [r1], #4
- ldrcsh r5, [r1], #2
- ldrvsb r12, [r1], #1
-
- stmmiia r0!, { r2, r3 }
- streq r4, [r0], #4
- strcsh r5, [r0], #2
- strvsb r12, [r0], #1
- b Lexit
-
-Lsimilarlyunaligned:
- /* both src and dest are unaligned in similar ways, align to dest on 32 byte boundary */
- mov r12, r0, lsl #28
- rsb r12, r12, #0
- msr cpsr_f, r12
-
- ldrvsb r3, [r1], #1
- ldrcsh r4, [r1], #2
- ldreq r5, [r1], #4
-
- strvsb r3, [r0], #1
- strcsh r4, [r0], #2
- streq r5, [r0], #4
-
- ldmmiia r1!, { r3, r4 }
- stmmiia r0!, { r3, r4 }
-
- subs r2, r2, r12, lsr #28
- beq Lexit
-
-Lunaligned_32:
- /* bring up to dest 32 byte alignment */
- tst r0, #(1 << 4)
- ldmneia r1!, { r3, r4, r5, r12 }
- stmneia r0!, { r3, r4, r5, r12 }
- subne r2, r2, #16
-
- /* we should now be aligned, see what copy method we should use */
- cmp r2, #64
- bge Lmorethan64_aligned
- b Llessthan64_aligned
-
-Lbytewise2:
- /* copy 2 bytes at a time */
- subs r2, r2, #2
-
- ldrb r3, [r1], #1
- ldrplb r4, [r1], #1
-
- strb r3, [r0], #1
- strplb r4, [r0], #1
-
- bhi Lbytewise2
- b Lexit
-
-Lbytewise:
- /* simple bytewise forward copy */
- ldrb r3, [r1], #1
- subs r2, r2, #1
- strb r3, [r0], #1
- bne Lbytewise
- b Lexit
-
-Lsmallforwardcopy:
- /* src and dest are word aligned similarly, less than 64 bytes to copy */
- cmp r2, #4
- blt Lbytewise2
-
- /* bytewise copy until word aligned */
- tst r1, #3
-Lwordalignloop:
- ldrneb r3, [r1], #1
- strneb r3, [r0], #1
- subne r2, r2, #1
- tstne r1, #3
- bne Lwordalignloop
-
- cmp r2, #16
- bge Llessthan64_aligned
- blt Llessthan16_aligned
-
-Loverlap:
- /* src and dest overlap in some way, len > 0 */
- cmp r0, r1 /* if dest > src */
- bhi Loverlap_srclower
-
-Loverlap_destlower:
- /* dest < src, see if we can still do a fast forward copy or fallback to slow forward copy */
- cmp r3, #64
- bge Lnormalforwardcopy /* overlap is greater than one stride of the copy, use normal copy */
-
- cmp r3, #2
- bge Lbytewise2
- b Lbytewise
-
- /* the following routines deal with having to copy in the reverse direction */
-Loverlap_srclower:
- /* src < dest, with overlap */
-
- /* src += len; dest += len; */
- add r0, r0, r2
- add r1, r1, r2
-
- /* we have to copy in reverse no matter what, test if we can we use a large block reverse copy */
- cmp r2, #64 /* less than 64 bytes to copy? */
- cmpgt r3, #64 /* less than 64 bytes of nonoverlap? */
- blt Lbytewise_reverse
-
- /* test of src and dest are nonword aligned differently */
- mov r3, r0, lsl #30
- cmp r3, r1, lsl #30
- bne Lbytewise_reverse
-
- /* test if src and dest are non word aligned or dest is non 16 byte aligned */
- tst r0, #0xf
- bne Lunaligned_reverse_similarly
-
- /* test for dest 32 byte alignment */
- tst r0, #(1<<4)
- bne Lunaligned_32_reverse_similarly
-
- /* 64 byte reverse block copy, src and dest aligned */
-Lmorethan64_aligned_reverse:
- /* save some more registers to use in the copy */
- stmfd sp!, { r6, r8, r10, r11 }
-
- /* pre-subtract 64 from the len counter to avoid an extra compare in the loop */
- sub r2, r2, #64
-
-L64loop_reverse:
- /* copy 64 bytes at a time */
- ldmdb r1!, { r3, r4, r5, r6, r8, r10, r11, r12 }
-#ifdef _ARM_ARCH_6
- pld [r1, #-32]
-#endif
- stmdb r0!, { r3, r4, r5, r6, r8, r10, r11, r12 }
- ldmdb r1!, { r3, r4, r5, r6, r8, r10, r11, r12 }
- subs r2, r2, #64
-#ifdef _ARM_ARCH_6
- pld [r1, #-32]
-#endif
- stmdb r0!, { r3, r4, r5, r6, r8, r10, r11, r12 }
- bge L64loop_reverse
-
- /* restore the scratch registers we just saved */
- ldmfd sp!, { r6, r8, r10, r11 }
-
- /* fix up the len counter (previously subtracted an extra 64 from it) and test for completion */
- adds r2, r2, #64
- beq Lexit
-
-Lbytewise_reverse:
- ldrb r3, [r1, #-1]!
- strb r3, [r0, #-1]!
- subs r2, r2, #1
- bne Lbytewise_reverse
- b Lexit
-
-Lunaligned_reverse_similarly:
- /* both src and dest are unaligned in similar ways, align to dest on 32 byte boundary */
- mov r12, r0, lsl #28
- msr cpsr_f, r12
-
- ldrvsb r3, [r1, #-1]!
- ldrcsh r4, [r1, #-2]!
- ldreq r5, [r1, #-4]!
-
- strvsb r3, [r0, #-1]!
- strcsh r4, [r0, #-2]!
- streq r5, [r0, #-4]!
-
- ldmmidb r1!, { r3, r4 }
- stmmidb r0!, { r3, r4 }
-
- subs r2, r2, r12, lsr #28
- beq Lexit
-
-Lunaligned_32_reverse_similarly:
- /* bring up to dest 32 byte alignment */
- tst r0, #(1 << 4)
- ldmnedb r1!, { r3, r4, r5, r12 }
- stmnedb r0!, { r3, r4, r5, r12 }
- subne r2, r2, #16
-
- /* we should now be aligned, see what copy method we should use */
- cmp r2, #64
- bge Lmorethan64_aligned_reverse
- b Lbytewise_reverse
-
- /* the following routines deal with non word aligned copies */
-Lnonwordaligned_forward:
- cmp r2, #8
- blt Lbytewise2 /* not worth the effort with less than 24 bytes total */
-
- /* bytewise copy until src word aligned */
- tst r1, #3
-Lwordalignloop2:
- ldrneb r3, [r1], #1
- strneb r3, [r0], #1
- subne r2, r2, #1
- tstne r1, #3
- bne Lwordalignloop2
-
- /* figure out how the src and dest are unaligned */
- and r3, r0, #3
- cmp r3, #2
- blt Lalign1_forward
- beq Lalign2_forward
- bgt Lalign3_forward
-
-Lalign1_forward:
- /* the dest pointer is 1 byte off from src */
- mov r12, r2, lsr #2 /* number of words we should copy */
- sub r0, r0, #1
-
- /* prime the copy */
- ldrb r4, [r0] /* load D[7:0] */
-
-Lalign1_forward_loop:
- ldr r3, [r1], #4 /* load S */
- orr r4, r4, r3, lsl #8 /* D[31:8] = S[24:0] */
- str r4, [r0], #4 /* save D */
- mov r4, r3, lsr #24 /* D[7:0] = S[31:25] */
- subs r12, r12, #1
- bne Lalign1_forward_loop
-
- /* finish the copy off */
- strb r4, [r0], #1 /* save D[7:0] */
-
- ands r2, r2, #3
- beq Lexit
- b Lbytewise2
-
-Lalign2_forward:
- /* the dest pointer is 2 bytes off from src */
- mov r12, r2, lsr #2 /* number of words we should copy */
- sub r0, r0, #2
-
- /* prime the copy */
- ldrh r4, [r0] /* load D[15:0] */
-
-Lalign2_forward_loop:
- ldr r3, [r1], #4 /* load S */
- orr r4, r4, r3, lsl #16 /* D[31:16] = S[15:0] */
- str r4, [r0], #4 /* save D */
- mov r4, r3, lsr #16 /* D[15:0] = S[31:15] */
- subs r12, r12, #1
- bne Lalign2_forward_loop
-
- /* finish the copy off */
- strh r4, [r0], #2 /* save D[15:0] */
-
- ands r2, r2, #3
- beq Lexit
- b Lbytewise2
-
-Lalign3_forward:
- /* the dest pointer is 3 bytes off from src */
- mov r12, r2, lsr #2 /* number of words we should copy */
- sub r0, r0, #3
-
- /* prime the copy */
- ldr r4, [r0]
- and r4, r4, #0x00ffffff /* load D[24:0] */
-
-Lalign3_forward_loop:
- ldr r3, [r1], #4 /* load S */
- orr r4, r4, r3, lsl #24 /* D[31:25] = S[7:0] */
- str r4, [r0], #4 /* save D */
- mov r4, r3, lsr #8 /* D[24:0] = S[31:8] */
- subs r12, r12, #1
- bne Lalign3_forward_loop
-
- /* finish the copy off */
- strh r4, [r0], #2 /* save D[15:0] */
- mov r4, r4, lsr #16
- strb r4, [r0], #1 /* save D[23:16] */
-
- ands r2, r2, #3
- beq Lexit
- b Lbytewise2
-
-Lexit:
- ldmfd sp!, {r0, r4, r5, r7, pc}
-
-#endif // !defined _ARM_ARCH_7 || defined VARIANT_DYLD
-
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- *
- * This file implements the following functions for the Swift micro-arch:
- *
- * void bcopy(const void * source,
- * void * destination,
- * size_t length);
- *
- * void *memmove(void * destination,
- * const void * source,
- * size_t n);
- *
- * void *memcpy(void * restrict destination,
- * const void * restrict source,
- * size_t n);
- *
- * All copy n successive bytes from source to destination. Memmove and memcpy
- * return destination, whereas bcopy has no return value. Copying takes place
- * as if it were through a temporary buffer -- after return destination
- * contains exactly the bytes from source, even if the buffers overlap (this is
- * not required of memcpy by the C standard; its behavior is undefined if the
- * buffers overlap, but we are holding ourselves to the historical behavior of
- * this function on OS X and iOS).
- */
-
-#include <arm/arch.h>
-#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD
-
-.syntax unified
-.code 16
-.globl _bcopy$VARIANT$Swift
-.thumb_func _bcopy$VARIANT$Swift
-.globl _memmove$VARIANT$Swift
-.thumb_func _memmove$VARIANT$Swift
-.globl _memcpy$VARIANT$Swift
-.thumb_func _memcpy$VARIANT$Swift
-
-.text
-.align 4
-_bcopy$VARIANT$Swift:
-// Translate bcopy calls into memcpy calls by swapping the first and second
-// arguments.
- mov r3, r0
- mov r0, r1
- mov r1, r3
-
-_memmove$VARIANT$Swift:
-_memcpy$VARIANT$Swift:
-// Our preference is to copy the data in ascending address order, but if the
-// buffers overlap such that the beginning of the destination buffer aliases
-// the end of the source buffer, we need to copy in descending address order
-// instead to preserve the memmove semantics. We detect this case with the
-// test:
-//
-// destination - source < length (unsigned compare)
-//
-// If the address of the source buffer is higher than the address of the
-// destination buffer, this arithmetic can overflow, but the overflowed value
-// can only be smaller than length if the buffers do not overlap, so we don't
-// need to worry about false positives due to the overflow (they happen, but
-// only in cases where copying in either order is correct).
- push {r7,lr}
- mov r7, sp
- subs r3, r0, r1
- beq L_exit
- mov ip, r0
- cmp r3, r2
- blo L_descendingCopy
-
-/*****************************************************************************
- * Ascending copy *
- *****************************************************************************/
-
- subs r3, r2, #32 // If length < 32, jump to a dedicated code
- blo L_ascendingShort // path for short buffers.
-
- orr lr, r0, r1 // If the length is not a multiple of 16, or
- orr lr, r2 // either buffer is not 16-byte aligned, then
- ands lr, #0xf // some edging is needed; jump to a separate
- bne L_ascendingEdging // branch to handle it.
-
-/*****************************************************************************
- * Ascending vector aligned copy *
- *****************************************************************************/
-
-0: subs r3, #32 // Copy 32 bytes at a time from src to dst,
- vld1.8 {q0,q1}, [r1,:128]! // both of which have 16-byte alignment.
- vst1.8 {q0,q1}, [ip,:128]! // Terminate this loop when 32 or fewer bytes
- bhi 0b // remain to be copied.
-
- add r1, r3 // Backtrack both pointers by 32 - remaining
- vld1.8 {q0,q1}, [r1,:128] // and copy 32 bytes from src to dst. This
- add ip, r3 // copy may overlap the previous copy, and
- vst1.8 {q0,q1}, [ip,:128] // takes us precisely to the end of the
- pop {r7,pc} // buffer.
-
-/*****************************************************************************
- * Ascending vector misaligned copy *
- *****************************************************************************/
-
-L_ascendingEdging:
- tst ip, #0xf // Copy one byte at a time until the
- itttt ne // destination pointer has 16 byte alignment.
- ldrbne r3, [r1],#1
- strbne r3, [ip],#1
- subne r2, #1
- bne L_ascendingEdging
-
- and lr, r1, #0xf // Back the source pointer up to a 16-byte
- bic r1, #0xf // aligned location, and check if length > 32.
- subs r3, r2, #32
- blo L_ascendingEdgingExit
- tbh [pc, lr, lsl #1] // Otherwise, we have a jump table based on
-0: // the relative alignment of the buffers.
-.short (L_ascendingExtract0x0-0b)/2
-.short (L_ascendingExtract0x1-0b)/2
-.short (L_ascendingExtract0x2-0b)/2
-.short (L_ascendingExtract0x3-0b)/2
-.short (L_ascendingExtract0x4-0b)/2
-.short (L_ascendingExtract0x5-0b)/2
-.short (L_ascendingExtract0x6-0b)/2
-.short (L_ascendingExtract0x7-0b)/2
-.short (L_ascendingExtract0x8-0b)/2
-.short (L_ascendingExtract0x9-0b)/2
-.short (L_ascendingExtract0xa-0b)/2
-.short (L_ascendingExtract0xb-0b)/2
-.short (L_ascendingExtract0xc-0b)/2
-.short (L_ascendingExtract0xd-0b)/2
-.short (L_ascendingExtract0xe-0b)/2
-.short (L_ascendingExtract0xf-0b)/2
-
-L_ascendingExtract0x0: // If the two buffers are similarly aligned,
- subs r3, #32 // we use a slightly simpler loop that just
- vld1.8 {q0,q1}, [r1,:128]! // copies 32 bytes at a time.
- vst1.8 {q0,q1}, [ip,:128]!
- bhs L_ascendingExtract0x0
- b L_ascendingEdgingExit
-
-#define ASCENDING_EXTRACT(shift)\
-L_ascendingExtract ## shift:\
- vld1.8 {q8}, [r1,:128]!;\
-0: vld1.8 {q9,q10},[r1,:128]!;\
- vext.8 q0, q8, q9, $(shift);\
- vext.8 q1, q9, q10,$(shift);\
- vmov q8, q10;\
- vst1.8 {q0,q1}, [ip,:128]!;\
- subs r3, $32;\
- bhs 0b;\
- sub r1, $16;\
- b L_ascendingEdgingExit
-
-ASCENDING_EXTRACT(0x1) // Otherwise, we use the loop implemented in
-ASCENDING_EXTRACT(0x2) // the above macro. It loads 32 bytes per
-ASCENDING_EXTRACT(0x3) // iteration combines it with the residual
-ASCENDING_EXTRACT(0x4) // bytes from the previous iteration, and
-ASCENDING_EXTRACT(0x5) // uses the VEXT instruction to extract 32
-ASCENDING_EXTRACT(0x6) // bytes that can be stored to a 16-byte
-ASCENDING_EXTRACT(0x7) // aligned location in the destination buffer.
-ASCENDING_EXTRACT(0x8) // This continues until 32 or fewer bytes
-ASCENDING_EXTRACT(0x9) // remain to be copied. This is significantly
-ASCENDING_EXTRACT(0xa) // faster than using misaligned loads and
-ASCENDING_EXTRACT(0xb) // stores, which are very inefficient on
-ASCENDING_EXTRACT(0xc) // Swift.
-ASCENDING_EXTRACT(0xd)
-ASCENDING_EXTRACT(0xe)
-ASCENDING_EXTRACT(0xf)
-
-L_ascendingEdgingExit:
- add r1, lr // Restore the source pointer
- add r2, r3, #32 // Restore the length
-L_ascendingShort:
- subs r2, #1 // Copy one byte at a time until the buffer
- itt hs // is exhausted, then return.
- ldrbhs r3, [r1],#1
- strbhs r3, [ip],#1
- bhi L_ascendingShort
-L_exit:
- pop {r7,pc}
-
-/*****************************************************************************
- * Descending copy *
- *****************************************************************************/
-
-L_descendingCopy:
- add r1, r2 // Advance source and destination pointers to
- add ip, r2 // the end of the buffer.
-
- subs r3, r2, #32 // If length < 32, jump to a dedicated code
- blo L_descendingShort // path for short buffers.
-
- orr lr, r0, r1 // If the length is not a multiple of 16, or
- orr lr, r2 // either buffer is not 16-byte aligned, then
- ands lr, #0xf // some edging is needed; jump to a separate
- bne L_descendingEdging // branch to handle it.
-
-/*****************************************************************************
- * Descending vector aligned copy *
- *****************************************************************************/
-
-0: sub r1, #32 // Copies 32 bytes (16-byte aligned) from
- vld1.8 {q0,q1}, [r1,:128] // source to destination on each pass through
- sub ip, #32 // the loop. The loop ends when 32 or fewer
- vst1.8 {q0,q1}, [ip,:128] // bytes remain to be copied.
- subs r3, #32
- bhi 0b
- add r3, #32 // Copy the remaining up-to-32 bytes.
- sub r1, r3 // This copy may overlap the copy performed
- vld1.8 {q0,q1}, [r1,:128] // in the final iteration through the
- sub ip, r3 // previous loop, but this is more efficient
- vst1.8 {q0,q1}, [ip,:128] // than figuring out exactly which bytes
- pop {r7,pc} // need to be copied.
-
-/*****************************************************************************
- * Descending vector misaligned copy *
- *****************************************************************************/
-
-L_descendingEdging:
- tst ip, #0xf // Identical to how we handle misalignment for
- itttt ne // ascending copies. First we move one byte
- ldrbne r3, [r1,#-1]! // at a time until the destination has 16
- strbne r3, [ip,#-1]! // byte alignment.
- subne r2, #1
- bne L_descendingEdging
-
- and lr, r1, #0xf // Then we extract the alignment of the source
- bic r1, #0xf // buffer and use a jump table to dispatch
- subs r3, r2, #32 // into code that does the appropriate
- blo L_descendingEdgingExit // software alignment fixup.
- tbh [pc, lr, lsl #1]
-0:
-.short (L_descendingExtract0x0-0b)/2
-.short (L_descendingExtract0x1-0b)/2
-.short (L_descendingExtract0x2-0b)/2
-.short (L_descendingExtract0x3-0b)/2
-.short (L_descendingExtract0x4-0b)/2
-.short (L_descendingExtract0x5-0b)/2
-.short (L_descendingExtract0x6-0b)/2
-.short (L_descendingExtract0x7-0b)/2
-.short (L_descendingExtract0x8-0b)/2
-.short (L_descendingExtract0x9-0b)/2
-.short (L_descendingExtract0xa-0b)/2
-.short (L_descendingExtract0xb-0b)/2
-.short (L_descendingExtract0xc-0b)/2
-.short (L_descendingExtract0xd-0b)/2
-.short (L_descendingExtract0xe-0b)/2
-.short (L_descendingExtract0xf-0b)/2
-
-L_descendingExtract0x0: // For relative alignment, we have a fast
- sub r1, #32 // path identical to the aligned copy loop.
- vld1.8 {q0,q1}, [r1,:128]
- sub ip, #32
- vst1.8 {q0,q1}, [ip,:128]
- subs r3, #32
- bhs L_descendingExtract0x0
- b L_descendingEdgingExit
-
-#define DESCENDING_EXTRACT(shift)\
-L_descendingExtract ## shift:\
- vld1.8 {q10}, [r1,:128];\
-0: sub r1, #32;\
- vld1.8 {q8,q9}, [r1,:128];\
- vext.8 q1, q9, q10,$(shift);\
- vext.8 q0, q8, q9, $(shift);\
- vmov q10, q8;\
- sub ip, #32;\
- vst1.8 {q0,q1}, [ip,:128];\
- subs r3, $32;\
- bhs 0b;\
- b L_descendingEdgingExit
-
-DESCENDING_EXTRACT(0x1) // Otherwise, we use the loop above (almost
-DESCENDING_EXTRACT(0x2) // identical to the one we use in the
-DESCENDING_EXTRACT(0x3) // ascending copy case).
-DESCENDING_EXTRACT(0x4)
-DESCENDING_EXTRACT(0x5)
-DESCENDING_EXTRACT(0x6)
-DESCENDING_EXTRACT(0x7)
-DESCENDING_EXTRACT(0x8)
-DESCENDING_EXTRACT(0x9)
-DESCENDING_EXTRACT(0xa)
-DESCENDING_EXTRACT(0xb)
-DESCENDING_EXTRACT(0xc)
-DESCENDING_EXTRACT(0xd)
-DESCENDING_EXTRACT(0xe)
-DESCENDING_EXTRACT(0xf)
-
-L_descendingEdgingExit:
- add r1, lr // Restore source pointer
- add r2, r3, #32 // Restore length
-L_descendingShort:
- subs r2, #1 // Byte-by-byte copy loop for short overlapping
- itt hs // buffers.
- ldrbhs r3, [r1,#-1]!
- strbhs r3, [ip,#-1]!
- bhi L_descendingShort
- pop {r7,pc}
-
-#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD
-
-/**********************************************************************
- * Cortex-A8 implementation *
- **********************************************************************/
-
-// Cortex-A8 implementations of memset( ) and bzero( ). Main loop is 64-byte
-// NEON stores, unless the buffer length is > 1k. Beyond that point, there is
-// little to no speed advantage with NEON (and a slight regression in some
-// measured cases), so we switch to the GPRs.
-//
-// The crossover point should be reevaluated for future architectures.
-//
-// -- Stephen Canon, August 2009
-
-.text
-.syntax unified
-.code 16
-
-// void bzero(void * destination,
-// size_t length);
-//
-// zeros out a buffer length bytes long, beginning at the address destination.
-.thumb_func ___bzero$VARIANT$CortexA8
-.globl ___bzero$VARIANT$CortexA8
-.thumb_func _bzero$VARIANT$CortexA8
-.globl _bzero$VARIANT$CortexA8
-.align 2
-___bzero$VARIANT$CortexA8:
-_bzero$VARIANT$CortexA8:
- mov r2, r1 // match the API to memset(dest, 0, length)
- eor r1, r1 // and fall through into memset
-
-// void *memset(void * destination,
-// int value, size_t n);
-//
-// writes value converted to an unsigned char to n successive bytes, beginning
-// at destination.
-
-// Notes on register usage:
-//
-// Throughout this function, registers have nearly constant usage; the pattern
-// is:
-//
-// r0 holds the original destination pointer, unmodified. This value
-// must be returned by the routine, so it is easiest to just leave it
-// in place.
-// r1 holds the value that is being copied into the buffer, in some stage
-// of splattedness. The low byte is guaranteed to always have the value
-// but the higher bytes may or may not contain copies of it.
-// r2 holds the length minus some offset, where the offset is always the
-// number of bytes that the current loop stores per iteration.
-// r3-r6,r8,r10,r11 are used with stmia, and will only ever contain splatted
-// copies of the value to be stored.
-// ip holds a pointer to the lowest byte in the array that has not yet been
-// set to hold value.
-// q0 and q1 hold splatted copies of the value in the vector path, and are
-// otherwise unused.
-
-.thumb_func _memset$VARIANT$CortexA8
-.globl _memset$VARIANT$CortexA8
-.align 2
-_memset$VARIANT$CortexA8:
- mov ip, r0 // copy destination pointer.
- subs r2, #0x8 // if length - 8 is negative (i.e. length
- and r1, #0xff // is less than 8), jump to cleanup path.
- blt L_scalarCleanup //
-
- tst ip, #0x7 // if the destination is doubleword
- beq L_vectorCopy // aligned, jump to fast path.
-
-0: strb r1, [ip], #1 // store one byte at a time until
- sub r2, #1 // destination pointer is 8 byte aligned.
- tst ip, #7 //
- bne 0b //
-
- cmp r2, #0x0 // if length - 8 is negative,
- blt L_scalarCleanup // jump to the cleanup code
-
-L_vectorCopy:
- vdup.8 q0, r1 // splat the byte to be stored across
- subs r2, #0x38 // q0 and q1, and check if length - 64
- vmov q1, q0 // is negative; if so, jump to the
- blt L_vectorCleanup // cleanup code.
-
- tst ip, #0x38 // if the destination is cacheline
- beq L_cachelineAligned // aligned, jump to the fast path.
-
-0: vst1.64 {d0}, [ip, :64]! // store one double word at a time until
- sub r2, #8 // the destination is 64-byte aligned
- tst ip, #0x38 //
- bne 0b
-
- cmp r2, #0x0 // if length - 64 is negative,
- blt L_vectorCleanup // jump to the cleanup code
-
-L_cachelineAligned:
- cmp r2, #0x3c0 // if length > 1024
- bge L_useSTMIA // we use stmia instead
-
-.align 4 // main loop
-0: vst1.64 {q0,q1}, [ip, :256]! // store 32 bytes
- subs r2, #0x40 // decrement length by 64
- vst1.64 {q0,q1}, [ip, :256]! // store 32 bytes
- bge 0b // if length - 64 >= 0, continue
-
-L_vectorCleanup:
- adds r2, #0x38 // if (length - 8) < 0, goto scalar cleanup
- blt L_scalarCleanup //
-
-0: subs r2, #8 // store one double word at a time until
- vst1.64 {d0}, [ip, :64]! // (length - 8) < 0.
- bge 0b
-
-L_scalarCleanup:
- adds r2, #8 // restore length
- beq 1f // early out if zero.
-
-0: strb r1, [ip], #1 // store one byte at a time until length
- subs r2, #1 // is zero.
- bne 0b //
-1: bx lr // return.
-
-// STMIA loop for large buffers
-//
-// For stores larger than 1024 bytes, we use STMIA because we can't get enough
-// of a speedup from NEON to offset the higher power draw of the NEON unit.
-//
-// This crossover should be reevaluated on future architectures.
-//
-// We avoid using r7 and r9 even though it's not strictly necessary.
-
-L_useSTMIA:
- push {r4,r5,r6,r8,r10,r11}
- orr r1, r1, r1, lsl #8
- orr r1, r1, r1, lsl #16
- mov r3, r1
- mov r4, r1
- mov r5, r1
- mov r6, r1
- mov r8, r1
- mov r10, r1
- mov r11, r1
-.align 4
-0: stmia ip!, {r1,r3,r4,r5,r6,r8,r10,r11}
- subs r2, #0x40
- stmia ip!, {r1,r3,r4,r5,r6,r8,r10,r11}
- bge 0b
- pop {r4,r5,r6,r8,r10,r11}
- b L_vectorCleanup
-
-#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
-
+++ /dev/null
-/*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- *
- * This file implements the following functions for the Cortex-A9 processor:
- *
- * void bzero(void * destination,
- * size_t length);
- *
- * void __bzero(void * destination,
- * size_t length);
- *
- * zeros out a buffer length bytes long, beginning at the address destination.
- *
- * void *memset(void * destination,
- * int value,
- * size_t n);
- *
- * writes value converted to an unsigned char to n successive bytes, beginning
- * at destination.
- */
-
-#include <arm/arch.h>
-#if defined _ARM_ARCH_7
-
-/*****************************************************************************
- * Macros *
- *****************************************************************************/
-
-#define A9_ENTRY(name) \
- .align 2;\
- .globl _ ## name ## $VARIANT$CortexA9;\
- _ ## name ## $VARIANT$CortexA9:
-
-#define ESTABLISH_FRAME \
- push {r0,r4,r7,lr};\
- add r7, sp, #8
-
-#define CLEAR_FRAME_AND_RETURN \
- pop {r0,r4,r7,pc}
-
-#define ADDITIONAL_CALLEE_SAVE_REGISTERS {r5,r6,r8}
-
-#define STORE_REGISTERS {r1,r3,r4,r5,r6,r8,r9,ip}
-
-/*****************************************************************************
- * entry points *
- *****************************************************************************/
-
-.text
-.syntax unified
-.code 32
-
-A9_ENTRY(__bzero)
-A9_ENTRY(bzero)
- mov r2, r1
- eor r1, r1
-
-A9_ENTRY(memset)
-// Early out if fewer than four bytes are to be set. Otherwise, store up to
-// three bytes to align the destination pointer to a word boundary.
- ESTABLISH_FRAME
- and r1, #0xff
- subs r2, #4
- orr r1, r1, r1, lsl #8
- blo L_lengthLessThanFour
- orr r1, r1, r1, lsl #16
-0: tst r0, #0x3
- beq L_wordAligned
- strb r1, [r0],#1
- subs r2, #1
- bhs 0b
-L_lengthLessThanFour:
- adds r2, #4
- beq 1f
-0: strb r1, [r0],#1
- subs r2, #1
- bne 0b
-1: CLEAR_FRAME_AND_RETURN
-
-L_wordAligned:
-// Destination pointer has word alignment. Early out if fewer than 64 bytes
-// are to be set. Otherwise, store up to 28 bytes to align the destination
-// pointer to a cacheline boundary.
- mov r3, r1
- mov r4, r1
- subs r2, #0x3c
- mov r9, r1
- blo L_lengthLessThanSixtyFour
-0: tst r0, #0x1c
- beq L_cachelineAligned
- str r1, [r0],#4
- subs r2, #4
- bhs 0b
-L_lengthLessThanSixtyFour:
- tst r2, #0x30
- beq 1f
-0: stm r0!, {r1,r3,r4,r9}
- sub r2, #0x10
- tst r2, #0x30
- bne 0b
-1: tst r2, #0xf
- beq 2f
- lsls ip, r2, #29
- stmcs r0!, {r1,r3}
- strmi r1, [r0],#4
- lsls ip, r2, #31
- strhcs r1, [r0],#2
- strbmi r1, [r0]
-2: CLEAR_FRAME_AND_RETURN
-
-L_cachelineAligned:
-// Main unrolled loop; stores two complete cachelines per iteration.
- push ADDITIONAL_CALLEE_SAVE_REGISTERS
- mov r5, r1
- mov r6, r1
- mov r8, r1
- mov ip, r1
-.align 4
-0: stm r0!, STORE_REGISTERS
- subs r2, #0x40
- stm r0!, STORE_REGISTERS
- bhs 0b
- pop ADDITIONAL_CALLEE_SAVE_REGISTERS
- b L_lengthLessThanSixtyFour
-
-#endif // defined _ARM_ARCH_7
+++ /dev/null
-/*
- * Copyright (c) 2006, 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-#if !defined _ARM_ARCH_7 || defined VARIANT_DYLD
-
-#include <mach/machine/asm.h>
-#include <architecture/arm/asm_help.h>
-
-/*
- * A reasonably well-optimized bzero/memset. Should work equally well on arm11 and arm9 based
- * cores.
- *
- * The algorithm is to align the destination pointer on a 32 byte boundary and then
- * blast data 64 bytes at a time, in two stores of 32 bytes per loop.
- */
- .text
- .align 2
-
- .globl _memset
-/* void *memset(void *ptr, int c, size_t len); */
-_memset:
- /* move len into r1, unpack c into r2 */
- mov r3, r2
- and r1, r1, #0xff
- orr r1, r1, r1, lsl #8
- orr r2, r1, r1, lsl #16
- mov r1, r3
- b Lbzeroengine
-
- .globl _bzero
-/* void bzero(void *ptr, size_t len); */
-_bzero:
- /* zero out r2 so we can be just like memset(0) */
- mov r2, #0
-
-Lbzeroengine:
- /* move the base pointer into r12 and leave r0 alone so that we return the original pointer */
- mov r12, r0
-
- /* copy r2 into r3 for 64-bit stores */
- mov r3, r2
-
- /* check for zero len */
- cmp r1, #0
- bxeq lr
-
- /* fall back to a bytewise store for less than 32 bytes */
- cmp r1, #32
- blt L_bytewise
-
- /* check for 32 byte unaligned ptr */
- tst r12, #0x1f
- bne L_unaligned
-
- /* make sure we have more than 64 bytes to zero */
- cmp r1, #64
- blt L_lessthan64aligned
-
- /* >= 64 bytes of len, 32 byte aligned */
-L_64ormorealigned:
-
- /* we need some registers, avoid r7 (frame pointer) and r9 (thread register) */
- stmfd sp!, { r4-r6, r8, r10-r11 }
- mov r4, r2
- mov r5, r2
- mov r6, r2
- mov r8, r2
- mov r10, r2
- mov r11, r2
-
- /* pre-subtract 64 from the len to avoid an extra compare in the loop */
- sub r1, r1, #64
-
-L_64loop:
- stmia r12!, { r2-r6, r8, r10-r11 }
- subs r1, r1, #64
- stmia r12!, { r2-r6, r8, r10-r11 }
- bge L_64loop
-
- /* restore the saved regs */
- ldmfd sp!, { r4-r6, r8, r10-r11 }
-
- /* check for completion (had previously subtracted an extra 64 from len) */
- adds r1, r1, #64
- bxeq lr
-
-L_lessthan64aligned:
- /* do we have 16 or more bytes left */
- cmp r1, #16
- stmgeia r12!, { r2-r3 }
- stmgeia r12!, { r2-r3 }
- subges r1, r1, #16
- bgt L_lessthan64aligned
- bxeq lr
-
-L_lessthan16aligned:
- /* store 0 to 15 bytes */
- mov r1, r1, lsl #28 /* move the remaining len bits [3:0] to the flags area of cpsr */
- msr cpsr_f, r1
-
- stmmiia r12!, { r2-r3 } /* n is set, store 8 bytes */
- streq r2, [r12], #4 /* z is set, store 4 bytes */
- strcsh r2, [r12], #2 /* c is set, store 2 bytes */
- strvsb r2, [r12], #1 /* v is set, store 1 byte */
- bx lr
-
-L_bytewise:
- /* bytewise copy, 2 bytes at a time, alignment not guaranteed */
- subs r1, r1, #2
- strb r2, [r12], #1
- strplb r2, [r12], #1
- bhi L_bytewise
- bx lr
-
-L_unaligned:
- /* unaligned on 32 byte boundary, store 1-15 bytes until we're 16 byte aligned */
- mov r3, r12, lsl #28
- rsb r3, r3, #0x00000000
- msr cpsr_f, r3
-
- strvsb r2, [r12], #1 /* v is set, unaligned in the 1s column */
- strcsh r2, [r12], #2 /* c is set, unaligned in the 2s column */
- streq r2, [r12], #4 /* z is set, unaligned in the 4s column */
- strmi r2, [r12], #4 /* n is set, unaligned in the 8s column */
- strmi r2, [r12], #4
-
- subs r1, r1, r3, lsr #28
- bxeq lr
-
- /* we had previously trashed r3, restore it */
- mov r3, r2
-
- /* now make sure we're 32 byte aligned */
- tst r12, #(1 << 4)
- stmneia r12!, { r2-r3 }
- stmneia r12!, { r2-r3 }
- subnes r1, r1, #16
-
- /* we're now aligned, check for >= 64 bytes left */
- cmp r1, #64
- bge L_64ormorealigned
- b L_lessthan64aligned
-
-X_LEAF(___bzero, _bzero)
-
-#endif // !defined _ARM_ARCH_7 || defined VARIANT_DYLD
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- *
- * This file implements the following functions for the Swift micro-arch:
- *
- * void bzero(void * destination,
- * size_t length);
- *
- * void __bzero(void * destination,
- * size_t length);
- *
- * zeros out a buffer length bytes long, beginning at the address destination.
- *
- * void *memset(void * destination,
- * int value,
- * size_t n);
- *
- * writes value converted to an unsigned char to n successive bytes, beginning
- * at destination.
- */
-
-#include <arm/arch.h>
-#if defined _ARM_ARCH_7
-
-.syntax unified
-.code 32
-.globl ___bzero$VARIANT$Swift
-.globl _bzero$VARIANT$Swift
-.globl _memset$VARIANT$Swift
-
-.text
-.align 4
-___bzero$VARIANT$Swift:
-_bzero$VARIANT$Swift:
- mov r2, r1 // Set value to zero and move length to the
- eor r1, r1 // correct register to match the memset API.
-_memset$VARIANT$Swift:
- push {r7,lr} // Establish a frame, and make a copy of the
- mov r7, sp // pointer to increment so that we can
- mov ip, r0 // return the original pointer unmodified.
-
- vdup.8 q0, r1 // Splat the low byte of value across q0.
- subs r3, r2, #64 // If length < 64, jump to a dedicated
- blo L_lengthLessThan64 // code path to handle small buffers.
-
- vmov q1, q0 // Copy the splatted value to q1.
- orr lr, r2, r0 // If the length is not a multiple of 16 or
- ands lr, #0xf // the buffer is not 16-byte aligned, then
- bne L_edgingNeeded // some edging is needed; branch.
-
-0: subs r3, #64 // Write 64 bytes at a time to the 16-byte
- vst1.8 {q0,q1}, [ip,:128]! // aligned buffer. Terminate this loop when
- vst1.8 {q0,q1}, [ip,:128]! // 64 or fewer bytes remain to be written.
- bhi 0b
-
- add ip, r3 // Backtrack the destination pointer by
- vst1.8 {q0,q1}, [ip,:128]! // 64 - remaining bytes, and write 64 bytes
- vst1.8 {q0,q1}, [ip,:128] // to that address. This takes us precisely
- pop {r7,pc} // to the end of the buffer.
-
-L_edgingNeeded:
- vst1.8 {q0}, [ip] // Write 16 bytes to the [possibly unaligned]
- and lr, ip, #0xf // buffer, then advance the pointer to the
- bic ip, #0xf // next aligned location, and adjust the
- add r3, lr // length accordingly. Note that this means
- add ip, #16 // that the first write in the loop may
- subs r3, #16 // overlap with the write we just performed;
- blo 1f // this is the fastest way to get alignment
- nop // on Swift.
-
-0: subs r3, #64 // Write 64 bytes at a time to the 16-byte
- vst1.8 {q0,q1}, [ip,:128]! // aligned buffer. Terminate this loop when
- vst1.8 {q0,q1}, [ip,:128]! // 64 or fewer bytes remain to be written.
- bhi 0b
-
-1: add ip, r3 // Backtrack the destination pointer by
- vst1.8 {q0,q1}, [ip]! // 64 - remaining bytes, and write 64 bytes
- vst1.8 {q0,q1}, [ip] // to that address. This takes us precisely
- pop {r7,pc} // to the end of the buffer.
-
-L_lengthLessThan64:
- subs r3, r2, #8 // If the length is smaller than eight, jump
- blo 1f // into a dedicated byte store loop.
-
-0: subs r3, #8 // Write 8 bytes at a time to the destination
- vst1.8 {d0}, [ip]! // buffer, terminating when eight or fewer
- bhi 0b // bytes remain to be written.
-
- add ip, r3 // Backtrack the destination pointer by
- vst1.8 {d0}, [ip] // 8 - remaining bytes, and write 8 bytes
- pop {r7,pc} // to that address, then return.
-
-1: subs r2, #1 // Store one byte at a time to the destination
- strbhs r1, [ip], #1 // buffer, until we exhaust the length.
- bhi 1b
- pop {r7,pc}
-
-#endif // defined _ARM_ARCH_7
+++ /dev/null
-// This file implements resolvers to assist dyld in choosing the correct
-// implementation of <string.h> routines on ARMv7 processors. The
-// micro-architectural differences between Cortex-A8 and Cortex-A9 are such
-// that optimal write loops are quite different on the two processors.
-
-#include <arm/arch.h>
-#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD
-
-#include <stdlib.h>
-#include <machine/cpu_capabilities.h>
-#include <mach/machine.h>
-
-// The MakeResolver(name) macro creates a function that dyld calls to
-// pick an implementation of the name function. It does a check to determine
-// if it is running on a8 or a9 hardware, and returns a pointer to either
-//
-// name$VARIANT$CortexA8
-// or
-// name$VARIANT$CortexA9
-// or
-// name$VARIANT$Swift
-//
-// This resolution only occurs once per process; once a symbol is bound to an
-// implementation in dyld, no further calls to the resolver occur.
-//
-// On unknown implementations of the ARMv7 architecture, the Swift variant
-// is returned by these resolvers.
-#define MakeResolver(name) \
- void * name ## Resolver(void) __asm__("_" #name); \
- void * name ## Resolver(void) { \
- __asm__(".symbol_resolver _" #name); \
- switch (*(int *)_COMM_PAGE_CPUFAMILY) { \
- case CPUFAMILY_ARM_13: return name ## $VARIANT$CortexA8; \
- case CPUFAMILY_ARM_14: return name ## $VARIANT$CortexA9; \
- default: return name ## $VARIANT$Swift; \
- } \
- }
-
-void bzero$VARIANT$CortexA8(void *, size_t);
-void bzero$VARIANT$CortexA9(void *, size_t);
-void bzero$VARIANT$Swift(void *, size_t);
-MakeResolver(bzero)
-
-void __bzero$VARIANT$CortexA8(void *, size_t);
-void __bzero$VARIANT$CortexA9(void *, size_t);
-void __bzero$VARIANT$Swift(void *, size_t);
-MakeResolver(__bzero)
-
-void *memset$VARIANT$CortexA8(void *, int, size_t);
-void *memset$VARIANT$CortexA9(void *, int, size_t);
-void *memset$VARIANT$Swift(void *, int, size_t);
-MakeResolver(memset)
-
-void bcopy$VARIANT$CortexA8(const void *, void *, size_t);
-void bcopy$VARIANT$CortexA9(const void *, void *, size_t);
-void bcopy$VARIANT$Swift(const void *, void *, size_t);
-MakeResolver(bcopy)
-
-void *memmove$VARIANT$CortexA8(void *, const void *, size_t);
-void *memmove$VARIANT$CortexA9(void *, const void *, size_t);
-void *memmove$VARIANT$Swift(void *, const void *, size_t);
-MakeResolver(memmove)
-
-void *memcpy$VARIANT$CortexA8(void *, const void *, size_t);
-void *memcpy$VARIANT$CortexA9(void *, const void *, size_t);
-void *memcpy$VARIANT$Swift(void *, const void *, size_t);
-MakeResolver(memcpy)
-
-// The memset_patternx resolvers are a little different, because we only have
-// a generic implementation and a Swift implementation.
-#define MakeResolver_Swift(name) \
- void * name ## Resolver(void) __asm__("_" #name); \
- void * name ## Resolver(void) { \
- __asm__(".symbol_resolver _" #name); \
- switch (*(int *)_COMM_PAGE_CPUFAMILY) { \
- case CPUFAMILY_ARM_13: return name ## $VARIANT$Generic; \
- case CPUFAMILY_ARM_14: return name ## $VARIANT$Generic; \
- default: return name ## $VARIANT$Swift; \
- } \
- }
-
-void memset_pattern4$VARIANT$Generic(void *b, const void *c4, size_t len);
-void memset_pattern4$VARIANT$Swift(void *b, const void *c4, size_t len);
-MakeResolver_Swift(memset_pattern4);
-
-void memset_pattern8$VARIANT$Generic(void *b, const void *c8, size_t len);
-void memset_pattern8$VARIANT$Swift(void *b, const void *c8, size_t len);
-MakeResolver_Swift(memset_pattern8);
-
-void memset_pattern16$VARIANT$Generic(void *b, const void *c16, size_t len);
-void memset_pattern16$VARIANT$Swift(void *b, const void *c16, size_t len);
-MakeResolver_Swift(memset_pattern16);
-
-#else // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
-
-typedef int emptyFilesArentCFiles;
-
-#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-
-#ifdef _ARM_ARCH_5
- .text
-
- .align 2
- .globl _ffs
-_ffs:
- .globl _ffsl
-_ffsl:
- rsb r3, r0, #0
- and r0, r0, r3
- clz r0, r0
- rsb r0, r0, #32
- bx lr
-
- .align 2
- .globl _fls
-_fls:
- .globl _flsl
-_flsl:
- clz r0, r0
- rsb r0, r0, #32
- bx lr
-#else
-#error need to define ffs for this architecture
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-// ARM Assembly implementation of memcmp( ) from <string.h>
-// Uses Thumb2 if it is available, otherwise generates ARM code.
-//
-// -- Stephen Canon, August 2009
-//
-// The basic idea is to use word compares instead of byte compares as long as
-// at least four bytes remain to be compared. However, because memcmp( )
-// compares the buffers as though they were big-endian unsigned integers, we
-// need to byte-reverse each word before comparing them.
-//
-// If the buffers are not word aligned, or they are shorter than four bytes,
-// we just use a simple byte comparison loop instead.
-//
-// int bcmp(void *src1, void *src2, size_t length);
-// int memcmp(void *src1, void *src2, size_t length);
-
-.text
-.syntax unified
-#if defined __thumb2__
- .code 16
- .thumb_func _bcmp
- .thumb_func _memcmp
-#else
- .code 32
-#endif
-
-#define ESTABLISH_FRAME \
- push {r7,lr};\
- mov r7, sp
-#define CLEAR_FRAME_AND_RETURN \
- pop {r7,pc}
-
-#include <arm/arch.h>
-
-#if defined _ARM_ARCH_6
- #define BYTE_REVERSE(reg,tmp) \
- rev reg, reg
-#else // defined _ARM_ARCH_6
-// Prior to ARMv6, the REV instruction is not available. We use a very cute
-// software workaround instead, which needs only a single scratch register.
- #define BYTE_REVERSE(reg,tmp) \
- eor tmp, reg, reg, ror #16;\
- bic tmp, tmp, #0xff0000 ;\
- mov tmp, tmp, lsr #8 ;\
- eor reg, tmp, reg, ror #8
-#endif // defined _ARM_ARCH_6
-
-.globl _bcmp
-.globl _memcmp
-.align 2
-_bcmp:
-_memcmp:
- // If both buffers are not word aligned, jump to a byte-comparison loop.
- ESTABLISH_FRAME
- orr ip, r0, r1
- tst ip, #3
- bne L_useByteComparisons
-
- // As long as at least four bytes of length remain, load one word from each
- // buffer and check if they are equal.
-0: subs r2, #4
- blo L_lessThanFourBytesRemain
- ldr r3, [r0],#4
- ldr ip, [r1],#4
- cmp r3, ip
- beq 0b
-
- // If words from the two buffers compared unequal, we end up here. We need
- // to byte-swap both words, then subtract to determine the result (+/-1).
- BYTE_REVERSE(r3,r1)
- BYTE_REVERSE(ip,r2)
- mov r0, #1
- subs r3, ip
- it lo
- movlo r0, #-1
- CLEAR_FRAME_AND_RETURN
-
-L_lessThanFourBytesRemain:
- adds r2, #4
-L_useByteComparisons:
- mov r3, r0
- // If no bytes remain to compare, the buffers are equal and we return zero.
- // Otherwise, load one byte from each buffer and check if they are equal.
-0: subs r2, #1
- blo L_buffersAreEqual
- ldrb r0, [r3],#1
- ldrb ip, [r1],#1
- subs r0, ip
- beq 0b
- CLEAR_FRAME_AND_RETURN
-
-L_buffersAreEqual:
- mov r0, #0
- CLEAR_FRAME_AND_RETURN
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-
-// Only built for armv6 and higher.
-#if defined _ARM_ARCH_6
-
-// If we're building for armv7, and not for DYLD, then we have a symbol
-// resolver so we need to rename these implementations.
-#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD
-#define _memset_pattern4 _memset_pattern4$VARIANT$Generic
-#define _memset_pattern8 _memset_pattern8$VARIANT$Generic
-#define _memset_pattern16 _memset_pattern16$VARIANT$Generic
-#endif
-
-#include <mach/machine/asm.h>
-
-/*
- * This file contains the following functions:
- *
- * void memset_pattern4(void *b, const void *c4, size_t len)
- * void memset_pattern8(void *b, const void *c8, size_t len)
- * void memset_pattern16(void *b, const void *c16, size_t len)
- *
- * The memset() is implemented in the bzero.s file.
- *
- * This is a reasonably well optimized version of memset_pattern* routines
- * implemented for the ARM9 and ARM11 processors using the ARMv6 instruction
- * set. These routines use the ARM's core registers.
- *
- * The algorithm is to align the destination pointer on a 16 byte boundary
- * and then blast data 64 bytes at a time, in two stores of 32 bytes per loop.
- *
- */
- .text
- .align 2
- .syntax unified
-
-/*----------------------------------------------------------------------------*/
-/* void memset_pattern4(void *ptr, const void *pattern4, size_t len); */
-/* */
-/* r0 << destination pointer */
-/* r1 << pointer to 4-byte pattern */
-/* r2 << 'len' (length of destination buffer in bytes) */
-/*----------------------------------------------------------------------------*/
- .globl _memset_pattern4
-_memset_pattern4:
- cmp r2, #0 /* check if len is zero */
- bxeq lr /* return if length is zero */
-
- /* We need some registers, so save volatiles on stack */
- /* Avoid r7 (frame pointer) and r9 (thread register) */
- stmfd sp!, {r4-r7, lr}
- add r7, sp, #12 /* establish frame */
- stmfd sp!, {r8, r10-r11}
-
- /* copy destination base pointer r0 to r12 and leave r0 alone */
- /* so that we return original pointer back to the caller */
- mov r12, r0
-
- /* Check if 'len' is long enough to bother alignment of destination */
- /* pointer */
- cmp r2, #32 /* long enough to bother aligning? */
- movlt r3, #4 /* move pattern length into r3 */
- movlt r10, #4 /* pattern index */
- movlt r11, r1 /* move pattern pointer into r11 */
- blt L_Short /* no */
-
- /* move 'len' into r1, get 4-byte pattern in r2 */
- mov r6, r2 /* temporarily move 'len' in to r6 */
- ldr r2, [r1]/* load 4-byte pattern into r2 */
- mov r1, r6 /* move 'len' from r6 to r1 */
-
- mov r3, r2 /* copy 4-byte pattern into r3, r4 and r5 registers */
- mov r4, r2
- mov r5, r2
-
-L_NotShort:
-
- /* Check for 16 or 32 byte aligned destination pointer */
- tst r12, #0x1F /* check for 32 byte aligned */
- beq L_Aligned
- tst r12, #0xF /* check for 16 byte aligned */
- beq L_16ByteAligned
- b L_Unaligned /* yes */
-
-L_Bytewise:
- ldrb r4, [r11], #1
- strb r4, [r12], #1
- subs r10, #1
- moveq r10, r3
- moveq r11, r1
- sub r2, #1
-
-L_Short:
- cmp r2, #0 /* more bytes left? */
- bne L_Bytewise
- ldm sp!, {r8, r10-r11} /* restores registers from stack */
- ldm sp!, {r4-r7, pc} /* restore & return from subroutine */
-
-/* 'len' is long enough to justify aligning the destination pointer */
-/* */
-/* By the time we reach here, data is stored in registers as follows: */
-/* r1 << 'len' (length of destination buffer in bytes) */
-/* r2-r5 << pattern; either 4x4byte OR 2x8byte OR 1x16-byte */
-/* r12 << destination pointer copy (scratch register) */
-/* r0 << destination pointer original */
-/* */
-/* Use r11 as scratch register to store the #bytes offset to 16-byte align */
-/* */
-/* Unaligned on 32-byte boundary, store 1-15 bytes until 16-byte aligned */
-/* As we store these bytes, we rotate the pattern stored in r2-r5 to reflect */
-/* the alignment. */
-
-L_Unaligned:
- mov r11, r12, lsl #28
- rsb r11, r11, #0
- msr cpsr_f, r11 /* Bits[31:28] of cpsr now contain #bytes to align*/
-
-L_Store15BytesAndRotatePattern:
- strbvs r2, [r12], #1 /* v is set, unaligned in the 1s column */
- andvs r6, r2, #0xFF /* Rotate pattern right in r2-r5 by 1-byte */
- andvs r8, r3, #0xFF /* Consider register r2-r5 and a contiguous */
- andvs r10, r4, #0xFF /* 16-byte register with r2 containing LSB */
- andvs r11, r5, #0xFF /* and r5 containing MSB */
- lsrvs r2, r2, #8
- lsrvs r3, r3, #8
- lsrvs r4, r4, #8
- lsrvs r5, r5, #8
- orrvs r2, r2, r8, lsl #24
- orrvs r3, r3, r10, lsl #24
- orrvs r4, r4, r11, lsl #24
- orrvs r5, r5, r6, lsl #24
-
- strhcs r2, [r12], #2 /* c is set, unaligned in the 2s column */
- movcs r6, r2, lsl #16 /* Rotate pattern right in r2-r5 by 2-bytes */
- movcs r8, r3, lsl #16
- movcs r10, r4, lsl #16
- movcs r11, r5, lsl #16
- lsrcs r2, r2, #16
- lsrcs r3, r3, #16
- lsrcs r4, r4, #16
- lsrcs r5, r5, #16
- orrcs r2, r2, r8
- orrcs r3, r3, r10
- orrcs r4, r4, r11
- orrcs r5, r5, r6
-
- streq r2, [r12], #4 /* z is set, unaligned in the 4s column */
- moveq r6, r2 /* Rotate pattern right in r2-r5 by 4-bytes */
- moveq r2, r3
- moveq r3, r4
- moveq r4, r5
- moveq r5, r6
-
- stmmi r12!, {r2-r3} /* n is set, unaligned in the 8s column */
- movmi r6, r2 /* Rotate pattern right in r2-r5 by 4-bytes */
- movmi r8, r3
- movmi r2, r4
- movmi r3, r5
- movmi r4, r6
- movmi r5, r8
-
- mrs r11, cpsr /*copy cpsr in to r11 */
- subs r1, r1, r11, lsr #28
- ldmeq sp!, {r8, r10-r11} /* restores registers from stack */
- ldmeq sp!, {r4-r7, pc} /* restore & return from subroutine */
-
-/* By the time we reach here, we are 16-byte aligned and r2-r5 contains */
-/* rotated pattern. Now lets make sure we are 32-byte aligned. */
-L_16ByteAligned:
- tst r12, #(1 << 4)
- stmne r12!, {r2-r5}
- subsne r1, r1, #16
-
-/* By the time we reach here, data is stored in registers as follows: */
-/* r1 << 'len' (remaining length of destination buffer in bytes) */
-/* r2-r5 << rotated pattern; either 4x4byte OR 2x8byte OR 1x16-byte */
-/* r12 << aligned destination pointer copy (scratch register) */
-L_Aligned:
- cmp r1, #64
- blt L_AlignedLessThan64
-
-/* Copy pattern in four more registers so that we can do 64 byte transfers */
- mov r6, r2
- mov r8, r3
- mov r10, r4
- mov r11, r5
-
-/* At this point, we are 16-byte aligned and 'len' is greater than 64 bytes */
-/* Lets transfer 64 bytes at a time until len becomes less than 64 bytes */
- sub r1, r1, #64 /* pre-subtract to avoid extra compare in loop */
-L_Loop64:
- stm r12!, {r2-r6, r8, r10-r11}
- subs r1, r1, #64
- stm r12!, {r2-r6, r8, r10-r11}
- bge L_Loop64
-
- /* return if 'len' is zero */
- adds r1, r1, #64 /* readjust length; previously subtracted extra 64*/
- ldmeq sp!, {r8, r10-r11} /* restores registers from stack */
- ldmeq sp!, {r4-r7, pc} /* restore & return from subroutine */
-
-L_AlignedLessThan64:
- /* do we have 16 or more bytes left */
- cmp r1, #16
- stmge r12!, {r2-r5}
- subsge r1, r1, #16
- bgt L_AlignedLessThan64
- ldmeq sp!, {r8, r10-r11} /* restores registers from stack */
- ldmeq sp!, {r4-r7, pc} /* restore & return from subroutine */
-
-L_AlignedLessThan16:
- /* store last up-to 15 bytes */
- /* move the remaining len bits [3:0] to the flags area of cpsr */
- mov r1, r1, lsl #28
- msr cpsr_f, r1
-
- stmmi r12!, {r2-r3} /* n is set, store 8 bytes */
- movmi r2, r4 /* shift vector down 8 bytes */
- movmi r3, r5
-
- streq r2, [r12], #4 /* z is set, store 4 bytes */
- moveq r2, r3 /* shift vector down 4 bytes */
-
- strhcs r2, [r12], #2 /* c is set, store 2 bytes */
- lsrcs r2, #16 /* shift register right 2 bytes */
-
- strbvs r2, [r12], #1 /* v is set, store 1 byte */
- ldm sp!, {r8, r10-r11} /* restores registers from stack */
- ldm sp!, {r4-r7, pc} /* restore & return from subroutine */
-
-/*----------------------------------------------------------------------------*/
-/* void memset_pattern8(void *ptr, const void *pattern8, size_t len); */
-/* */
-/* r0 << destination pointer */
-/* r1 << pointer to 8-byte pattern */
-/* r2 << 'len' (length of destination buffer in bytes) */
-/*----------------------------------------------------------------------------*/
- .globl _memset_pattern8
-_memset_pattern8:
- cmp r2, #0 /* check if len is zero */
- bxeq lr /* return if length is zero */
-
- /* We need some registers, so save volatiles on stack */
- /* Avoid r7 (frame pointer) and r9 (thread register) */
- stmfd sp!, {r4-r7, lr}
- add r7, sp, #12 /* establish frame */
- stmfd sp!, {r8, r10-r11}
-
- /* copy destination base pointer r0 to r12 and leave r0 alone */
- /* so that we return original pointer back to the caller */
- mov r12, r0
-
- /* Check if 'len' is long enough to bother alignment of destination */
- /* pointer */
- cmp r2, #32 /* long enough to bother aligning? */
- movlt r3, #8 /* move pattern length into r3 */
- movlt r10, #8 /* pattern index */
- movlt r11, r1 /* move pattern pointer into r11 */
- blt L_Short /* no */
-
- /* move 'len' into r1, get 8-byte pattern in r2-r3 */
- mov r6, r2 /* temporarily move 'len' in to r6 */
- ldr r2, [r1], #4 /* load 8-byte pattern into r2-r3 */
- ldr r3, [r1], #4
- mov r1, r6 /* move 'len' from r6 to r1 */
-
- mov r4, r2 /* copy 8-byte pattern into r4-r5 registers */
- mov r5, r3
- b L_NotShort /* yes */
-
-
-/*----------------------------------------------------------------------------*/
-/* void memset_pattern16(void *ptr, const void *pattern16, size_t len); */
-/* */
-/* r0 << destination pointer */
-/* r1 << pointer to 16-byte pattern */
-/* r2 << 'len' (length of destination buffer in bytes) */
-/*----------------------------------------------------------------------------*/
- .globl _memset_pattern16
-_memset_pattern16:
- cmp r2, #0 /* check if len is zero */
- bxeq lr /* return if length is zero */
-
- /* We need some registers, so save volatiles on stack */
- /* Avoid r7 (frame pointer) and r9 (thread register) */
- stmfd sp!, {r4-r7, lr}
- add r7, sp, #12 /* establish frame */
- stmfd sp!, {r8, r10-r11}
-
- /* copy destination base pointer r0 to r12 and leave r0 alone */
- /* so that we return original pointer back to the caller */
- mov r12, r0
-
- /* Check if 'len' is long enough to bother alignment of destination */
- /* pointer */
- cmp r2, #32 /* long enough to bother aligning? */
- movlt r3, #16 /* move pattern length into r3 */
- movlt r10, #16 /* pattern index */
- movlt r11, r1 /* move pattern pointer into r11 */
- blt L_Short /* no */
-
- /* move 'len' into r1, get 16-byte pattern in r2-r5 */
- mov r6, r2 /* temporarily move 'len' in to r6 */
- ldr r2, [r1], #4 /* load 16-byte pattern into r2-r5 */
- ldr r3, [r1], #4
- ldr r4, [r1], #4
- ldr r5, [r1], #4
- mov r1, r6 /* move 'len' from r6 to r1 */
-
- b L_NotShort /* yes */
-
-
-#endif /* _ARM_ARCH_6 */
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- *
- * This file implements the following functions for the Swift micro-arch:
- *
- * void memset_pattern4(void *b, const void *pattern4, size_t len);
- * void memset_pattern8(void *b, const void *pattern8, size_t len);
- * void memset_pattern16(void *b, const void *pattern16, size_t len);
- *
- * The implementation of all three functions is fundamentally the same.
- * memset_pattern4 is extensively commented to explain, reference that
- * if you have any questions about the other two.
- */
-
-#include <arm/arch.h>
-#if defined _ARM_ARCH_7 && !defined VARIANT_DYLD
-
-.syntax unified
-.code 32
-.text
-.globl _memset_pattern4$VARIANT$Swift
-.globl _memset_pattern8$VARIANT$Swift
-.globl _memset_pattern16$VARIANT$Swift
-
-/******************************************************************************/
-
-.align 4
-_memset_pattern4$VARIANT$Swift:
- push {r7,lr}
- mov r7, sp
-
-// Load the pattern and splat it to q0, then check if the buffer is at least
-// 64 bytes long. If not, branch to a short-buffer implementation.
- ldr r1, [r1]
- vdup.32 q0, r1
- subs r3, r2, #64
- blo L_short4
-
-// We want to use aligned vector stores to fill the bulk of the buffer. In
-// order to make that work, we need to rotate the pattern as necessary to
-// match up with aligned locations, and we also need to extract the alignment
-// of the destination pointer mod 16.
- lsl ip, r0, #3
- and lr, r0, #0xf // alignment of destination pointer mod 16
- rsb ip, ip, #32 // low five bits contain 32 - 8*(address%4).
-
-// Before we start the aligned stores, we do a single unaligned store of
-// 16 bytes of the pattern to the start of the buffer. Since the buffer is
-// at least 64 bytes long, this store is known to lie entirely inside the
-// buffer:
-// first aligned address in buffer
-// v
-// ---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
-// ... | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | 0 | 1 | 2 | ...
-// ---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---
-// ^
-// unaligned store starts here:
-// [ 0 1 2 3 0 1 2 3 0 1 2 3 0 1 2 3 ]
- vst1.8 {q0}, [r0]!
-
-// Subsequent stores will be aligned, and will start at the first aligned
-// address in the buffer. We apply the rotation that we calculated before
-// the vector store (in the low five bits of ip) to get the pattern that
-// is to be stored starting at the aligned location. For example, in the
-// picture above, the buffer had alignment of 3 mod 4, so the rotation to
-// be applied is 32 - 8*3 = 8. Rotating the pattern right by 8 bits gives
-// us [ 1 2 3 0 ] (remember, we're little-endian), which we see is what
-// needs to be stored starting at the first aligned location.
-//
-// Besides rotating the pattern, we also need to adjust the length (by
-// subtracting 16 - alignment mod 16), and to advance the pointer to the
-// first aligned location.
- ror r1, ip // Pattern to use for aligned memory
- add r3, lr
- bic r0, #0xf // destination for first aligned store
- subs r3, #16 // updated length
- blo 1f
-
-// Splat the rotated value across q1 and q2
- vdup.32 q1, r1
- vmov q2, q1
-
-// Main store loop. We write the splatted aligned pattern across 64 bytes
-// per iteration, terminating the loop when the remaining length of the
-// buffer is 64 bytes or less.
-0: subs r3, #64
- vst1.32 {q1,q2}, [r0,:128]!
- vst1.32 {q1,q2}, [r0,:128]!
- bhi 0b
-
-// The remaining length of the buffer is 64 bytes or less (but the total
-// length of the buffer is at least 64 bytes; otherwise we would have
-// branched to the "short" path). Thus, we can handle the entirety of the
-// remaining buffer with two 32-byte unaligned stores.
-//
-// Again, we need to rotate the pattern to match the alignment, this time
-// by 8*(length%4), and we also need to back up the destination pointer
-// so that it points to precisely 64 bytes before the end of the buffer.
-// We accomplish this by adding r3, which contains the remaining length of
-// the buffer minus 64.
-1: lsl ip, r3, #3
- ror r1, ip
- vdup.32 q8, r1
- vmov q9, q8
- add r0, r3
- vst1.32 {q8,q9}, [r0]!
- vst1.32 {q8,q9}, [r0]
- pop {r7,pc}
-
-L_short4:
-// If we branch here, the buffer is less than 64 bytes long. At this point,
-// register contents are as follows:
-//
-// r0 pointer to the buffer
-// r1 pattern
-// r2 buffer length
-// q0 splatted pattern
-//
-// To begin, we store eight bytes at a time until the remaining length is
-// less than eight bytes.
- subs r3, r2, #8
- blo 1f
-0: subs r3, #8
- vst1.32 {d0}, [r0]!
- bhs 0b
-
-// Then we store one byte at a time, rotating the pattern to get the next
-// byte, until we reach the end of the buffer.
- add r2, r3, #8
-1: subs r2, #1
- strbhs r1, [r0],#1
- ror r1, #8
- bhi 1b
- pop {r7,pc}
-
-/******************************************************************************/
-
-.align 4
-_memset_pattern8$VARIANT$Swift:
-// The implementation of this function is substantially identical to that of
-// memset_pattern4. The only differences are in how we rotate the pattern for
-// the purposes of extracting the bytes to store. For clarity, only those
-// differences are commented here; consult memset_pattern4 (above) for
-// a detailed description of the algorithm used.
- push {r7,lr}
- mov r7, sp
- vld1.8 {d0}, [r1]
- vmov d1, d0
- subs r3, r2, #64
- blo L_short8
-
- bic sp, #0xf // Align stack to 16 bytes and write 32 bytes
- sub sp, #16 // of pattern to the stack. We will use
- vst1.8 {q0}, [sp,:128] // unaligned loads from this scratch buffer
- sub sp, #16 // to get rotated forms of the pattern.
- vst1.8 {q0}, [sp,:128]
- and ip, r0, #0x7 // Now generate an unaligned pointer to the
- rsb ip, ip, #8 // rotated pattern that we need to use for
- add ip, sp // aligned stores in the main loop.
- and lr, r0, #0xf
- vst1.8 {q0}, [r0]!
- add r3, lr
- bic r0, #0xf
- subs r3, #16
- blo 1f
- vld1.8 {q1}, [ip]
- vmov q2, q1
-0: subs r3, #64
- vst1.32 {q1,q2}, [r0,:128]!
- vst1.32 {q1,q2}, [r0,:128]!
- bhi 0b
-1: and lr, r3, #0x7 // Generate an unaligned pointer to the
- add ip, lr // rotated pattern to use for cleanup.
- vld1.8 {q8}, [ip]
- vmov q9, q8
- add r0, r3
- vst1.32 {q8,q9}, [r0]!
- vst1.32 {q8,q9}, [r0]
- mov sp, r7 // Restore stack pointer
- pop {r7,pc}
-
-L_short8:
- subs r2, #8
- blo 1f
-0: subs r2, #8
- vst1.32 {d0}, [r0]!
- bhs 0b
-1: adds r2, #8
- beq 3f
-2: vst1.8 {d0[0]}, [r0]! // Store one byte from NEON
- vext.8 d0, d0, d0, #1 // Use VEXT to rotate pattern
- subs r2, #1
- bhi 2b
-3: pop {r7,pc}
-
-/******************************************************************************/
-
-.align 4
-_memset_pattern16$VARIANT$Swift:
-// The implementation of this function is substantially identical to that of
-// memset_pattern4. The only differences are in how we rotate the pattern for
-// the purposes of extracting the bytes to store. For clarity, only those
-// differences are commented here; consult memset_pattern4 (above) for
-// a detailed description of the algorithm used.
- push {r7,lr}
- mov r7, sp
- vld1.8 {q0}, [r1]
- subs r3, r2, #64
- blo L_short16
-
- bic sp, #0xf // Align stack to 16 bytes and write 48 bytes
- sub sp, #16 // of pattern to the stack. We will use
- vst1.8 {q0}, [sp,:128] // unaligned loads from this scratch buffer
- sub sp, #16 // to get rotated forms of the pattern.
- vst1.8 {q0}, [sp,:128]
- sub sp, #16
- vst1.8 {q0}, [sp,:128]
- and lr, r0, #0xf // Now generate an unaligned pointer to the
- rsb ip, lr, #16 // rotated pattern that we need to use for
- add ip, sp // aligned stores in the main loop.
- vst1.8 {q0}, [r0]!
- add r3, lr
- bic r0, #0xf
- subs r3, #16
- blo 1f
- vld1.8 {q1}, [ip]
- vmov q2, q1
-0: subs r3, #64
- vst1.32 {q1,q2}, [r0,:128]!
- vst1.32 {q1,q2}, [r0,:128]!
- bhi 0b
-1: and lr, r3, #0xf // Generate an unaligned pointer to the
- add ip, lr // rotated pattern to use for cleanup.
- vld1.8 {q8}, [ip]
- vmov q9, q8
- add r0, r3
- vst1.32 {q8,q9}, [r0]!
- vst1.32 {q8,q9}, [r0]
- mov sp, r7 // Restore stack pointer
- pop {r7,pc}
-
-L_short16:
- subs r2, #16
- blo 1f
-0: subs r2, #16
- vst1.32 {q0}, [r0]!
- bhs 0b
-1: adds r2, #16
- beq 3f
-2: vst1.8 {d0[0]}, [r0]! // Store one byte from NEON
- vext.8 q0, q0, q0, #1 // Use VEXT to rotate pattern
- subs r2, #1
- bhi 2b
-3: pop {r7,pc}
-
-#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
+++ /dev/null
-/*
- * Copyright (c) 2010 Apple, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-// char * strchr(const char *s, int c);
-//
-// The strchr( ) function locates the first occurence of c (converted to a
-// char) in the string s. If c is '\0', the function locates the terminating
-// '\0' byte.
-
-.text
-.syntax unified
-.code 32
-.globl _strchr
-
-.align 3
-_strchr:
-// Setup a frame and convert c to a char.
- push {r7,lr}
- mov r7, sp
- and r1, r1, #0xff
-
-// Basic character-by-character search for c; on each pass through the loop
-// we load a byte from s and increment s. We then check if this byte is equal
-// to either c or to '\0'; if not, we continue the loop.
-0: ldrb r2, [r0],#1
- cmp r2, r1
- tstne r2, r2
- bne 0b
-
-// Either we have found a match, or we have reached the end of the string (or
-// both, if c == '\0'). Because we incremented s after loading the last
-// character, we need to decrement the pointer by one to get a pointer to
-// either the matching or terminating character.
- sub r0, r0, #1
-
-// Now compare the last character we loaded to the character that we're
-// searching for. If they don't match, the character was not found in the
-// string, so return NULL.
- cmp r2, r1
- movne r0, #0
- pop {r7,pc}
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-.text
-.syntax unified
-.code 32
-.globl _strcmp
-// int strcmp(const char *s1, const char *s2);
-//
-// Returns zero if the two NUL-terminated strings s1 and s2 are equal.
-// Otherwise, returns the difference between the first two
-// characters that do not match, interpreted as unsigned integers.
-
-#define ESTABLISH_FRAME \
- push {r4-r7,lr} ;\
- add r7, sp, #12 ;\
- push {r8}
-#define CLEAR_FRAME \
- pop {r8} ;\
- pop {r4-r7,lr}
-
-.align 3
-.long 0, 0x01010101
-_strcmp:
-// Load a character from each string and advance the pointers. If the loaded
-// characters are unequal or NUL, return their difference.
-0: ldrb r2, [r0],#1
- ldrb ip, [r1],#1
- cmp r2, #1
- cmphs r2, ip
- bne L_earlyReturn
-// If the address of the next character from s1 does not have word alignment,
-// continue with the character-by-character comparison. Otherwise, fall
-// through into the word-by-word comparison path.
- tst r0, #3
- bne 0b
-
-// We have not encountered a NUL or a mismatch, and s1 has word alignment.
-// Establish a frame, since we're going to need additional registers anyway.
- ESTABLISH_FRAME
- ldr lr, (_strcmp-4)
-
-// Word align s2, and place the remainder in r8. Compute the right- and
-// left-shifts to extract each word that we will compare to the other source
-// from the aligned words that we load:
-//
-// aligned s2 to be loaded on next iteration
-// | "true" s2 |
-// v v v
-// +---+---+---+---+ +---+---+---+---+
-// | 0 | 1 | 2 | 3 | | 4 | 5 | 6 | 7 |
-// +---+---+---+---+ +---+---+---+---+
-// ^-----------------^
-// to be compared on next iteration
- and r8, r1, #3
- bic r1, r1, #3
- mov r8, r8, lsl #3
- rsb r5, r8, #32
-
-// Load the first aligned word of s2. OR 0x01 into any bytes that preceed the
-// "true s2", to prevent our check for NUL from generating a false positive.
-// Then check for NUL, and jump to the byte-by-byte comparison loop after
-// unwinding the pointers if we enounter one.
- ldr r6, [r1],#4
- orr r6, r6, lr, lsr r5
- sub r2, r6, lr
- bic r2, r2, r6
- tst r2, lr, lsl #7
- mov r4, r6, lsr r8
- bne L_unwindLoopPreload
-
-.align 3
-L_wordCompareLoop:
- // Load the next aligned word of s2 and check if it contains any NUL bytes.
- // Load the next aligned word of s1, and extract the corresponding bytes from
- // the two words of s2 loaded in this and the previous iteration of the loop.
- // Compare these two words.
- // If no NUL or mismatched words have been encountered, continue the loop.
- ldr r6, [r1],#4
-#if defined _ARM_ARCH_6
- uqsub8 r2, lr, r6
- tst r2, r2
- ldr ip, [r0],#4
-#else
- sub r2, r6, lr
- bic r2, r2, r6
- ldr ip, [r0],#4
- tst r2, lr, lsl #7
-#endif
- orr r3, r4, r6, lsl r5
- cmpeq ip, r3
- mov r4, r6, lsr r8
- beq L_wordCompareLoop
-
-// Either we have encountered a NUL, or we have found a mismatch between s1
-// and s2. Unwind the pointers and use a byte-by-byte comparison loop.
- sub r0, r0, #4
- sub r1, r1, #4
-L_unwindLoopPreload:
- sub r1, r1, r5, lsr #3
- CLEAR_FRAME
-
-L_byteCompareLoop:
-// Load a character from each string and advance the pointers. If the loaded
-// characters are unequal or NUL, return their difference.
- ldrb r2, [r0],#1
- ldrb ip, [r1],#1
- cmp r2, #1
- cmpcs r2, ip
- beq L_byteCompareLoop
-
-L_earlyReturn:
-// Return the difference between the last two characters loaded.
- sub r0, r2, ip
- bx lr
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-.syntax unified
-.code 32
-.globl _strlen
-
-#define addr r0
-#define word r1
-#define temp r2
-#define mask r3
-#define save ip
-#define indx r0
-
-.macro IfWordDoesntContainNUL_SetZ
-#if defined _ARM_ARCH_6
-// In each word of the string, we check for NUL bytes via a saturating
-// unsigned subtraction of each byte from 0x1. The result of this is
-// non-zero if and only if the corresponding byte in the string is NUL.
-// Simply using a TST instruction checks all four bytes for NULs in one
-// go.
- uqsub8 temp, mask, word
- tst temp, temp
-#else
-// If we're on armv5, we do not have the uqsub8 instruction, so we need
-// to use a different test for NUL. Instead, we compute:
-//
-// byte - 0x1 & ~byte
-//
-// and test the high-order bit. If it is set, then byte is NUL. Just
-// as with the other test, this can be applied simultaneously to all
-// bytes in a word.
- sub temp, word, mask
- bic temp, temp, word
- tst temp, mask, lsl #7
-#endif
-.endm
-
-.text
-.align 4
-.long 0x0 // padding
-.long 0x01010101 // mask for use in finding NULs
-_strlen:
-// Establish stack frame, load mask that we will use to find NUL bytes,
-// and set aside a copy of the pointer to the string.
- push {r7,lr}
- mov r7, sp
- ldr mask, (_strlen-4)
- add save, addr, #4
-
-// Load the aligned word that contains the start of the string, then OR
-// 0x01 into any bytes that preceed the start of the string to prevent
-// false positives when we check for NUL bytes.
- and temp, addr, #3
- bic addr, addr, #3
- lsl temp, temp, #3
- ldr word, [addr], #4
- rsb temp, temp, #32
- orr word, word, mask, lsr temp
-
-// Check if the string ends in the first word. If so, don't load any
-// more of the string; instead jump directly to the cleanup code.
- IfWordDoesntContainNUL_SetZ
- bne 1f
-
-.align 4
-// Load one word of the string on each iteration, and check it for NUL
-// bytes. If a NUL is found, fall through into the cleanup code.
-0: ldr word, [addr], #4
- IfWordDoesntContainNUL_SetZ
- beq 0b
-
-// The last word that we loaded contained a NUL. Subtracting the saved
-// pointer from the current pointer gives us the number of bytes from
-// the start of the string to the word containing the NUL.
-1: sub indx, addr, save
-#if defined _ARM_ARCH_6
-// To that we add the index of the first NUL byte in the word, computed
-// using REV and CLZ followed by a shift.
- rev temp, temp
- clz temp, temp
- add indx, indx, temp, lsr #3
-#else
-// armv5 does not have the REV instruction, so instead we find the
-// index of the NUL byte in word with a linear search.
- tst word, #0x000000ff
- addne indx, #1
- tstne word, #0x0000ff00
- addne indx, #1
- tstne word, #0x00ff0000
- addne indx, #1
-#endif
- pop {r7,pc}
-
+++ /dev/null
-/*
- * Copyright (c) 2010, 2011 Apple, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-.text
-.syntax unified
-.code 32
-.globl _strncmp
-// int strncmp(const char *s1, const char *s2, size_t n);
-//
-// Returns zero if the two NUL-terminated strings s1 and s2 are equal up to
-// n characters. Otherwise, returns the difference between the first two
-// characters that do not match, interpreted as unsigned integers.
-
-#define ESTABLISH_FRAME \
- push {r4-r7,lr} ;\
- add r7, sp, #12 ;\
- push {r8,r10}
-#define CLEAR_FRAME \
- pop {r8,r10} ;\
- pop {r4-r7,lr}
-
-.align 3
-.long 0, 0x01010101
-_strncmp:
-// If n < 16, jump straight to the byte-by-byte comparison loop.
- cmp r2, #16
- blo L_byteCompareLoop
-// Load a character from each string and advance the pointers. If the loaded
-// characters are unequal or NUL, return their difference.
-0: ldrb r3, [r0],#1
- ldrb ip, [r1],#1
- sub r2, #1
- cmp r3, #1
- cmphs r3, ip
- bne L_earlyReturn
-// If the address of the next character from s1 does not have word alignment,
-// continue with the character-by-character comparison. Otherwise, fall
-// through into the word-by-word comparison path.
- tst r0, #3
- bne 0b
-
-// We have not encountered a NUL or a mismatch, and s1 has word alignment.
-// Establish a frame, since we're going to need additional registers anyway.
- ESTABLISH_FRAME
- ldr lr, (_strncmp-4)
-
-// Word align s2, and place the remainder in r10. Compute the right- and
-// left-shifts to extract each word that we will compare to the other source
-// from the aligned words that we load:
-//
-// aligned s2 to be loaded on next iteration
-// | "true" s2 |
-// v v v
-// +---+---+---+---+ +---+---+---+---+
-// | 0 | 1 | 2 | 3 | | 4 | 5 | 6 | 7 |
-// +---+---+---+---+ +---+---+---+---+
-// ^-----------------^
-// to be compared on next iteration
- and r10, r1, #3
- bic r1, r1, #3
- mov r10, r10, lsl #3
- rsb r6, r10,#32
-
-// Subtract the number of bytes of the initial word load from s2 that will
-// actually be used from n.
- sub r2, r2, r6, lsr #3
-
-// Load the first aligned word of s2. OR 0x01 into any bytes that preceed the
-// "true s2", to prevent our check for NUL from generating a false positive.
-// Then check for NUL, and jump to the byte-by-byte comparison loop after
-// unwinding the pointers if we enounter one.
- ldr r8, [r1],#4
- orr r8, r8, lr, lsr r6
- sub r3, r8, lr
- bic r3, r3, r8
- tst r3, lr, lsl #7
- mov r5, r8, lsr r10
- bne L_unwindLoopPreload
-
-.align 3
-L_wordCompareLoop:
-// If n < 4, abort the word compare loop before we load any more data.
- subs r2, r2, #4
- blo L_nIsLessThanFour
-// Load the next aligned word of s2 and check if it contains any NUL bytes.
-// Load the next aligned word of s1, and extract the corresponding bytes from
-// the two words of s2 loaded in this and the previous iteration of the loop.
-// Compare these two words.
-// If no NUL or mismatched words have been encountered, continue the loop.
- ldr r8, [r1],#4
-#if defined _ARM_ARCH_6
- uqsub8 r3, lr, r8
- tst r3, r3
- ldr ip, [r0],#4
-#else
- sub r3, r8, lr
- bic r3, r3, r8
- ldr ip, [r0],#4
- tst r3, lr, lsl #7
-#endif
- orr r4, r5, r8, lsl r6
- cmpeq ip, r4
- mov r5, r8, lsr r10
- beq L_wordCompareLoop
-
-// Either we have encountered a NUL, or we have found a mismatch between s1
-// and s2. Unwind the pointers and use a byte-by-byte comparison loop.
- sub r0, r0, #4
- sub r1, r1, #4
-L_nIsLessThanFour:
- add r2, r2, #4
-L_unwindLoopPreload:
- sub r1, r1, r6, lsr #3
- add r2, r2, r6, lsr #3
- CLEAR_FRAME
-
-L_byteCompareLoop:
-// If n-- == 0, we have exhausted the allowed number of comparisons, and need
-// to return zero without additional loads.
- subs r2, r2, #1
- movlo r0, #0
- bxlo lr
-// Load a character from each string and advance the pointers. If the loaded
-// characters are unequal or NUL, return their difference.
- ldrb r3, [r0],#1
- ldrb ip, [r1],#1
- cmp r3, #1
- cmpcs r3, ip
- beq L_byteCompareLoop
-
-L_earlyReturn:
-// Return the difference between the last two characters loaded.
- sub r0, r3, ip
- bx lr
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-.syntax unified
-.code 32
-.globl _strnlen
-
-#define addr r0
-#define maxl r1
-#define temp r2
-#define mask r3
-#define save ip
-#define word lr
-#define byte lr
-#define indx r0
-
-.macro IfHS_and_WordDoesntContainNUL_SetZ
-#if defined _ARM_ARCH_6
-// In each word of the string, we check for NUL bytes via a saturating
-// unsigned subtraction of each byte from 0x1. The result of this is
-// non-zero if and only if the corresponding byte in the string is NUL.
-// Simply using a TST instruction checks all four bytes for NULs in one
-// go.
- uqsub8 temp, mask, word
- tsths temp, temp
-#else
-// If we're on armv5, we do not have the uqsub8 instruction, so we need
-// to use a different test for NUL. Instead, we compute:
-//
-// byte - 0x1 & ~byte
-//
-// and test the high-order bit. If it is set, then byte is NUL. Just
-// as with the other test, this can be applied simultaneously to all
-// bytes in a word.
- sub temp, word, mask
- bic temp, temp, word
- tsths temp, mask, lsl #7
-#endif
-.endm
-
-.text
-.align 3
-.long 0x0 // padding
-.long 0x01010101 // mask for use in finding NULs
-_strnlen:
-// Establish stack frame, load mask that we will use to find NUL bytes,
-// and set aside a copy of the pointer to the string. Subtract 4 from
-// the maxlen, and jump into a byte-by-byte search if this requires a
-// borrow, as we cannot use a word-by-word search in that case.
- push {r7,lr}
- mov r7, sp
- ldr mask, (_strnlen-4)
- add save, addr, #4
- subs maxl, maxl, #4
- blo L_bytewiseSearch
-
-// Load the aligned word that contains the start of the string, then OR
-// 0x01 into any bytes that preceed the start to prevent false positives
-// when we check for NUL bytes. Additionally, add the number of unused
-// bytes to maxlen.
- and temp, addr, #3
- bic addr, addr, #3
- add maxl, maxl, temp
- lsl temp, temp, #3
- ldr word, [addr], #4
- rsb temp, temp, #32
- orr word, word, mask, lsr temp
-
- subs maxl, maxl, #4
- IfHS_and_WordDoesntContainNUL_SetZ
- bne 1f
-
-.align 4
-0: ldr word, [addr], #4
- subs maxl, maxl, #4
- IfHS_and_WordDoesntContainNUL_SetZ
- beq 0b
-
-.align 4
-// Either the last word that we loaded contained a NUL, or we will
-// exceed maxlen before we finish the next word in the string. Determine
-// which case we are in by repeating the check for NUL, and branch if
-// there was not a NUL byte. Padding ensures that we don't have two
-// branches in a single 16-byte fetch group, as this interferes with
-// branch prediction on Swift.
-1: tst temp, temp
- beq L_bytewiseSearch
-
-// The last word that we loaded contained a NUL. Subtracting the saved
-// pointer from the current pointer gives us the number of bytes from
-// the start of the string to the word containing the NUL.
- sub indx, addr, save
-#if defined _ARM_ARCH_6
-// To that we add the index of the first NUL byte in the word, computed
-// using REV and CLZ followed by a shift.
- rev temp, temp
- clz temp, temp
- add indx, indx, temp, lsr #3
-#else
-// armv5 does not have the REV instruction, so instead we find the
-// index of the NUL byte in word with a linear search.
- tst word, #0x000000ff
- addne indx, #1
- tstne word, #0x0000ff00
- addne indx, #1
- tstne word, #0x00ff0000
- addne indx, #1
-#endif
- pop {r7,pc}
-
-.align 4
-L_bytewiseSearch:
-// Restore maxlen (the last thing that happened before we branched here
-// was that we subtracted 4 from maxlen), and adjust the saved string
-// pointer. Then we do a simple byte-by-byte search until we either
-// reach the end of the string or maxlen reaches zero, at which point
-// the length to return is simply the difference between the current
-// and saved pointers.
- adds maxl, maxl, #4
- sub save, save, #4
- beq 1f
-0: ldrb byte, [addr]
- cmp byte, #0
- addhi addr, #1
- subshi maxl, #1
- bhi 0b
-1: sub indx, addr, save
- pop {r7,pc}
+++ /dev/null
-/*
- * Copyright (c) 2010, Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-// char * strstr(const char *s1, const char *s2);
-//
-// If s2 is empty, s1 is returned.
-// If s2 does not occur in s1, NULL is returned.
-// Otherwise, a pointer to the first character of the first occurrence of s2
-// in s1 is returned.
-//
-// We use a hand-tuned version of the naive quadratic time algorithm; we have
-// experimented with more sophisticated algorithms, however they have been
-// found wanting. The increased startup cost combines with the frequency of
-// calls to strstr with small strings to swamp the gains from improved
-// asymptotic complexity.
-
-#define CLEAR_FRAME_AND_RETURN \
- pop {r4,r5,r6,r7,pc}
-
-.text
-.syntax unified
-.code 32
-.globl _strstr
-.align 2
-_strstr:
- push {r4,r5,r6,r7,lr}
- add r7, sp, #12
-
-// Throughout this function, I will refer to the string in which we are
-// searching as "string" and the string for which we are searching as "word".
-// Using s1 and s2 is too confusing. Thus, we want to return a pointer to
-// the first occurrence of "word" in "string".
- mov r5, r1
- mov r4, r0
-
-// We begin by calling strlen to find the length of "word". We also handle
-// two special cases here: we early-out if word is an empty string (length
-// zero), and we call strchr if word is only a single character.
- mov r0, r5
- bl _strlen
- subs r0, r0, #1
- ble L_tinyWord
-
-// Load the first character of word
- ldrb ip, [r5]
-
-L_lookForFirstCharacter:
-// Load the first character from string. If it is equal to the first
-// character of word, or is a zero byte, then we do more processing;
-// otherwise, proceed to the next character.
- ldrb r1, [r4],#1
- cmp r1, ip
- tstne r1, r1
- bne L_lookForFirstCharacter
-
-// The byte that we loaded from string either matched the first character
-// of word, or was a zero byte. If it was a zero byte, then we have reached
-// the end of string without finding a match of word. Otherwise, we fall
-// into a loop that checks additional characters to see if we have a match.
- tst r1, r1
- beq L_noMatch
-
-// We have found a match for the first character of word; we want to read
-// characters from this point on to see if we have a match for the entirety
-// of word. We want to be sure to preserve the state of the outside loop,
-// however:
-//
-// r0: length(word) - 1
-// r4: pointer to the next character in string
-// r5: pointer to the first character in word
-// ip: first character in word
-//
-// The registers r1-r3, r6, and lr are available as scratch. We set them up
-// for the inner loop as follows:
-//
-// r1: remaining length to be matched
-// r2: pointer to next character of string to match
-// r3: pointer to next character of word to match
-// r6: current character from string
-// lr: current character from word
- mov r2, r4
- add r3, r5, #1
- mov r1, r0
-
-L_checkMatch:
-// Load the next byte from both the candidate match and from word. If they
-// are not equal, jump back to the outer loop. If they are equal, decrement
-// the length, and continue the inner loop if we have not yet found a
-// complete match.
-//
-// We don't need to worry about looking for null bytes in this loop; we know
-// that we won't load a null byte from word, because we computed it's length
-// earlier, and are using that as a termination condition. If we hit a null
-// byte in string, the comparison will fail (because the corresponding byte
-// in word is non-null), and we will return to the outer loop, where the
-// null byte will be detected and handled properly.
- ldrb r6, [r2],#1
- ldrb lr, [r3],#1
- cmp r6, lr
- bne L_lookForFirstCharacter
- subs r1, r1, #1
- bne L_checkMatch
-
-// We have exhausted the length of word without finding a mismatched character
-// so we have found a match. Return a pointer to the beginning of the match
-// string. (This pointer is r4 - 1 because r4 was auto-incremented when we
-// loaded the first character).
- sub r0, r4, #1
- CLEAR_FRAME_AND_RETURN
-
-L_noMatch:
-// No match was found; return NULL.
- mov r0, #0
- CLEAR_FRAME_AND_RETURN
-
-L_tinyWord:
-// "word" is either empty or a single character. If it is a single character,
-// translate strstr into a call to the (more efficient) strchr.
- blt L_emptyWord
- ldrb r1, [r5]
- mov r0, r4
- bl _strchr
- CLEAR_FRAME_AND_RETURN
-
-L_emptyWord:
-// "word" is empty; return "string".
- movlt r0, r4
- CLEAR_FRAME_AND_RETURN
-
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2004, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <libkern/OSAtomic.h>
-#include <arm/arch.h>
-
-
-#if !defined(_ARM_ARCH_6)
-
-/*
- * The only atomic operation ARMv4T provides (atomic swap) is not
- * sufficient for the general 32-bit arithmetic and compare-and-swap
- * operations OSAtomic is supposed to provide. So we use a global
- * spin lock around all operations.
- *
- * Since we have only a single, in-order, CPU, we do not need
- * memory barriers for data.
- */
-
-static OSSpinLock _atomic_lock = OS_SPINLOCK_INIT;
-
-int32_t OSAtomicAdd32( int32_t theAmount, volatile int32_t *theValue )
-{
- int32_t result;
-
- OSSpinLockLock(&_atomic_lock);
- result = (*theValue += theAmount);
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-int32_t OSAtomicAdd32Barrier( int32_t theAmount, volatile int32_t *theValue )
-{
- return OSAtomicAdd32(theAmount, theValue);
-}
-
-int64_t OSAtomicAdd64( int64_t theAmount, volatile int64_t *theValue )
-{
- int64_t result;
-
- OSSpinLockLock(&_atomic_lock);
- result = (*theValue += theAmount);
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-int64_t OSAtomicAdd64Barrier( int64_t theAmount, volatile int64_t *theValue )
-{
- return OSAtomicAdd64(theAmount, theValue);
-}
-
-int32_t OSAtomicOr32( uint32_t theMask, volatile uint32_t *theValue )
-{
- int32_t result;
-
- OSSpinLockLock(&_atomic_lock);
- result = (*theValue |= theMask);
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-int32_t OSAtomicOr32Barrier( uint32_t theMask, volatile uint32_t *theValue )
-{
- return OSAtomicOr32(theMask, theValue);
-}
-
-int32_t OSAtomicOr32Orig( uint32_t theMask, volatile uint32_t *theValue )
-{
- int32_t result;
-
- OSSpinLockLock(&_atomic_lock);
- result = *theValue;
- *theValue |= theMask;
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-int32_t OSAtomicOr32OrigBarrier( uint32_t theMask, volatile uint32_t *theValue )
-{
- return OSAtomicOr32Orig(theMask, theValue);
-}
-
-int32_t OSAtomicAnd32( uint32_t theMask, volatile uint32_t *theValue )
-{
- int32_t result;
-
- OSSpinLockLock(&_atomic_lock);
- result = (*theValue &= theMask);
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-int32_t OSAtomicAnd32Barrier( uint32_t theMask, volatile uint32_t *theValue )
-{
- return OSAtomicAnd32(theMask, theValue);
-}
-
-int32_t OSAtomicAnd32Orig( uint32_t theMask, volatile uint32_t *theValue )
-{
- int32_t result;
-
- OSSpinLockLock(&_atomic_lock);
- result = *theValue;
- *theValue &= theMask;
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-int32_t OSAtomicAnd32OrigBarrier( uint32_t theMask, volatile uint32_t *theValue )
-{
- return OSAtomicAnd32Orig(theMask, theValue);
-}
-
-int32_t OSAtomicXor32( uint32_t theMask, volatile uint32_t *theValue )
-{
- int32_t result;
-
- OSSpinLockLock(&_atomic_lock);
- result = (*theValue ^= theMask);
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-int32_t OSAtomicXor32Barrier( uint32_t theMask, volatile uint32_t *theValue )
-{
- return OSAtomicXor32(theMask, theValue);
-}
-
-int32_t OSAtomicXor32Orig( uint32_t theMask, volatile uint32_t *theValue )
-{
- int32_t result;
-
- OSSpinLockLock(&_atomic_lock);
- result = *theValue;
- *theValue ^= theMask;
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-int32_t OSAtomicXor32OrigBarrier( uint32_t theMask, volatile uint32_t *theValue )
-{
- return OSAtomicXor32Orig(theMask, theValue);
-}
-
-bool OSAtomicCompareAndSwap32( int32_t oldValue, int32_t newValue, volatile int32_t *theValue )
-{
- bool result;
-
- OSSpinLockLock(&_atomic_lock);
- result = (*theValue == oldValue);
- if (result) *theValue = newValue;
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue, int32_t newValue, volatile int32_t *theValue )
-{
- return OSAtomicCompareAndSwap32(oldValue, newValue, theValue);
-}
-
-bool
-OSAtomicCompareAndSwapInt(int oldValue, int newValue, volatile int *theValue)
-{
- return OSAtomicCompareAndSwap32(oldValue, newValue, theValue);
-}
-
-bool
-OSAtomicCompareAndSwapIntBarrier(int oldValue, int newValue, volatile int *theValue)
-{
- return OSAtomicCompareAndSwap32(oldValue, newValue, theValue);
-}
-
-bool
-OSAtomicCompareAndSwapLong(long oldValue, long newValue, volatile long *theValue)
-{
- return OSAtomicCompareAndSwap32(oldValue, newValue, (volatile int32_t *)theValue);
-}
-
-bool
-OSAtomicCompareAndSwapLongBarrier(long oldValue, long newValue, volatile long *theValue)
-{
- return OSAtomicCompareAndSwap32(oldValue, newValue, (volatile int32_t *)theValue);
-}
-
-bool OSAtomicCompareAndSwap64( int64_t oldValue, int64_t newValue, volatile int64_t *theValue )
-{
- bool result;
-
- OSSpinLockLock(&_atomic_lock);
- result = (*theValue == oldValue);
- if (result) *theValue = newValue;
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-bool OSAtomicCompareAndSwap64Barrier( int64_t oldValue, int64_t newValue, volatile int64_t *theValue )
-{
- return OSAtomicCompareAndSwap64(oldValue, newValue, theValue);
-}
-
-bool OSAtomicTestAndSet( uint32_t n, volatile void *theAddress )
-{
- char *byteAddress = ((char*)theAddress + (n>>3));
- uint32_t byteBit = (0x80>>(n&7));
- bool result;
-
- OSSpinLockLock(&_atomic_lock);
- result = *byteAddress & byteBit;
- *byteAddress |= byteBit;
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-bool OSAtomicTestAndSetBarrier( uint32_t n, volatile void *theAddress )
-{
- return OSAtomicTestAndSet(n, theAddress);
-}
-
-bool OSAtomicTestAndClear( uint32_t n, volatile void *theAddress )
-{
- char *byteAddress = ((char*)theAddress + (n>>3));
- uint32_t byteBit = (0x80>>(n&7));
- bool result;
-
- OSSpinLockLock(&_atomic_lock);
- result = *byteAddress & byteBit;
- *byteAddress &= (~byteBit);
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-bool OSAtomicTestAndClearBarrier( uint32_t n, volatile void *theAddress )
-{
- return OSAtomicTestAndClear(n, theAddress);
-}
-
-void OSMemoryBarrier( void )
-{
- return;
-}
-
-
-bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue )
-{
- return OSAtomicCompareAndSwapPtr(__oldValue, __newValue, __theValue);
-}
-
-bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue )
-{
- bool result;
-
- OSSpinLockLock(&_atomic_lock);
- result = (*__theValue == __oldValue);
- if (result) *__theValue = __newValue;
- OSSpinLockUnlock(&_atomic_lock);
-
- return result;
-}
-
-void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset )
-{
- OSSpinLockLock(&_atomic_lock);
- *((void **)((char *)__new + __offset)) = __list->opaque1;
- __list->opaque1 = __new;
- OSSpinLockUnlock(&_atomic_lock);
-}
-
-void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset )
-{
- void *head;
-
- OSSpinLockLock(&_atomic_lock);
- head = __list->opaque1;
- if (head != NULL) {
- void **next = (void **)((char *)head + __offset);
- __list->opaque1 = *next;
- }
- OSSpinLockUnlock(&_atomic_lock);
-
- return head;
-}
-
-#endif /* !defined(_ARM_ARCH_6) */
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "OSAtomic.h"
-#include "../../darwin/OSAtomicLoadStoreEx.c"
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __ARM_OSATOMIC_SHIMS__
-#define __ARM_OSATOMIC_SHIMS__
-
-#include <sys/cdefs.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#define fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l))
-#define slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l))
-
-#if defined(__arm__)
-#include <arm/arch.h>
-
-#define _osatomic_load_exclusive(p, r) \
- __asm__ __volatile__( \
- "ldrex %[_r], %[_p]" \
- : [_r] "=&r" (r) \
- : [_p] "m" (*(p)) : "memory")
-
-#define _osatomic_load_exclusive64(p, r) \
- do { \
- register uint32_t rl asm("r4"), rh asm("r5"); \
- __asm__ __volatile__( \
- "ldrexd %[_rl], %[_rh], %[_p]" \
- : [_rl] "=r" (rl), [_rh] "=r" (rh) \
- : [_p] "m" (*(p)) : "memory"); \
- r = (typeof(r))(((uint64_t)rh << 32) | (uint64_t)rl); \
- } while (0);
-
-#define _osatomic_store_exclusive(p, r, t) \
- __asm__ __volatile__( \
- "strex %[_t], %[_r], %[_p]" \
- : [_t] "=&r" (t) \
- : [_p] "m" (*(p)), [_r] "r" (r) : "memory")
-
-#define _osatomic_store_exclusive64(p, r, t) \
- do { \
- register uint32_t rl asm("r4"), rh asm("r5"); \
- rh = (uint32_t)(r >> 32); \
- rl = (uint32_t)(r); \
- __asm__ __volatile__( \
- "strexd %[_t], %[_rl], %[_rh], %[_p]" \
- : [_t] "=&r" (t) \
- : [_p] "m" (*(p)), [_rl] "r" (rl), [_rh] "r" (rh) : "memory"); \
- } while (0);
-
-#if defined(_ARM_ARCH_7)
-
-#ifdef _OSATOMIC_WFE
-# define MP_SPIN_TRIES 10
-# define _osatomic_pause() __asm__ __volatile__("wfe")
-#else
-# define MP_SPIN_TRIES 1000
-# define _osatomic_pause() __asm__ __volatile__("yield")
-#endif // _OSATOMIC_WFE
-
-#define _osatomic_barrier() \
- __asm__ __volatile__( \
- "dmb ish" \
- : : : "memory")
-
-#define _osatomic_store_barrier() \
- __asm__ __volatile__( \
- "dmb ishst" \
- : : : "memory")
-
-#elif defined(_ARM_ARCH_6) && !defined(__thumb__) // _ARM_ARCH_7
-
-#define _osatomic_barrier() \
- __asm__ __volatile__( \
- "mcr p15, 0, %0, c7, c10, 5" \
- : : "r" (0) : "memory")
-
-#define _osatomic_store_barrier() _osatomic_barrier()
-#define _osatomic_pause()
-
-#elif defined(_ARM_ARCH_6) && defined(__thumb__)
-#error Atomic operations not available on ARMv6 Thumb
-#endif // _ARM_ARCH_7
-
-#if !defined(_ARM_ARCH_7)
-# ifndef _OSATOMIC_NO_BARRIERS
-# define __OSATOMIC_SUFFIX ""
-# define __OSATOMIC_BARRIER "Barrier"
-# define _OSATOMIC_ALIAS_NB(x)
-# else
-# define _OSATOMIC_EXTRAS 1
-# define __OSATOMIC_SUFFIX ""
-# define __OSATOMIC_BARRIER ""
-# define _OSATOMIC_ALIAS_NB(x)
-# endif // _OSATOMIC_NO_BARRIERS
-#else
-# define _OSATOMIC_EXTRAS 1
-# ifndef _OSATOMIC_NO_BARRIERS
-# ifdef _OSATOMIC_WFE
-# define __OSATOMIC_SUFFIX "$VARIANT$wfe"
-# else
-# define __OSATOMIC_SUFFIX "$VARIANT$mp"
-# endif // _OSATOMIC_ONLY_WFE
-# define __OSATOMIC_BARRIER "Barrier" __OSATOMIC_SUFFIX
-# define _OSATOMIC_ALIAS_NB(x)
-# else
-# define __OSATOMIC_SUFFIX "$VARIANT$up"
-# define __OSATOMIC_BARRIER "Barrier" __OSATOMIC_SUFFIX
-// Undefine the barrier operations
-# undef _osatomic_barrier
-# define _osatomic_barrier()
-# undef _osatomic_store_barrier
-# define _osatomic_store_barrier()
-// Aliases to alias non-barrier operations to UP variant names
-# if defined(__thumb__)
-# define _OSATOMIC_ALIAS_NB(sym) __asm __volatile__(".globl _" __STRING(sym) "; .thumb_func _" __STRING(sym) " ; .set _" __STRING(sym) ", _" __STRING(sym) __OSATOMIC_BARRIER)
-# else
-# define _OSATOMIC_ALIAS_NB(sym) __asm __volatile__(".globl _" __STRING(sym) "; .set _" __STRING(sym) ", _" __STRING(sym) __OSATOMIC_BARRIER)
-# endif // __thumb__
-# endif // _OSATOMIC_NO_BARRIERS
-#endif // !_ARM_ARCH_7
-
-// Allow us to mark up functions as being uni/multiprocessor.
-#define _OSATOMIC_VARIANT(sym) __asm("_" __STRING(sym) __OSATOMIC_SUFFIX)
-#define _OSATOMIC_VARIANT_B(sym) __asm("_" __STRING(sym) __OSATOMIC_BARRIER)
-
-#if defined(__thumb__)
- // For aliasing CompareAndSwap operations of the same size
- #define _OSATOMIC_ALIAS_B(newsym, sym) \
- __asm __volatile__( \
- ".globl _" __STRING(newsym) __OSATOMIC_BARRIER ";" \
- ".thumb_func _" __STRING(newsym) __OSATOMIC_BARRIER ";" \
- ".set _" __STRING(newsym) __OSATOMIC_BARRIER ", _" __STRING(sym) __OSATOMIC_BARRIER \
- )
-
- #define _OSATOMIC_ALIAS(newsym, sym) \
- __asm __volatile__( \
- ".globl _" __STRING(newsym) __OSATOMIC_SUFFIX ";" \
- ".thumb_func _" __STRING(newsym) __OSATOMIC_SUFFIX ";" \
- ".set _" __STRING(newsym) __OSATOMIC_SUFFIX ", _" __STRING(sym) __OSATOMIC_SUFFIX \
- )
-#else
- // For aliasing CompareAndSwap operations of the same size
- #define _OSATOMIC_ALIAS_B(newsym, sym) \
- __asm __volatile__( \
- ".globl _" __STRING(newsym) __OSATOMIC_BARRIER ";" \
- ".set _" __STRING(newsym) __OSATOMIC_BARRIER ", _" __STRING(sym) __OSATOMIC_BARRIER \
- )
-
- #define _OSATOMIC_ALIAS(newsym, sym) \
- __asm __volatile__( \
- ".globl _" __STRING(newsym) __OSATOMIC_SUFFIX ";" \
- ".set _" __STRING(newsym) __OSATOMIC_SUFFIX ", _" __STRING(sym) __OSATOMIC_SUFFIX \
- )
-#endif // __thumb__
-
-#endif // __arm__
-
-#endif // __ARM_OSATOMIC_SHIMS__
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#define _OSATOMIC_NO_BARRIERS
-#include "OSAtomic.c"
+++ /dev/null
-/*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * This holds the C versions of OSAtomic.s resolver functions, used by
- * everyone except dyld.
- */
-
-#include <arm/arch.h>
-#if defined(_ARM_ARCH_7)
-
-#include <stdlib.h>
-#include <machine/cpu_capabilities.h>
-#include <mach/machine.h>
-
-#if defined(VARIANT_DYLD)
-
-#define _STRDEF(x) __STRING(x)
-
-#define makeResolver_up_mp(name) \
- void* name ## $VARIANT$up(void); \
- void* name ## $VARIANT$mp(void); \
- void* name ## Resolver(void) __asm__( "_" #name ); \
- void* name ## Resolver(void) { \
- __asm__ __volatile__ ( \
- "ldr ip, L" #name "$commpage ;" \
- "ldr ip, [ip] ;" \
- "tst ip, $(" _STRDEF(kUP) ") ;" \
- "bne 1f ; " \
- "b _" __STRING(name) "$VARIANT$mp ;" \
- "1: b _" __STRING(name) "$VARIANT$up ;" \
- "L" #name "$commpage: .long " _STRDEF(_COMM_PAGE_CPU_CAPABILITIES) " ;" \
- : : : ); \
- }
-
-#define makeResolver_up_mp_wfe(name) makeResolver_up_mp(name)
-
-#else
-
-#define makeResolver_up_mp(name) \
- void name ## $VARIANT$up(void); \
- void name ## $VARIANT$mp(void); \
- void* name ## Resolver(void) __asm__( "_" #name ) ; \
- void* name ## Resolver(void) { \
- __asm__(".symbol_resolver _" #name); \
- /* return MP variant functions on kNumCPUs > 1 */ \
- if ((*(uint32_t*)(uintptr_t)_COMM_PAGE_CPU_CAPABILITIES & kUP) == 0) { \
- return name ## $VARIANT$mp; \
- } \
- return name ## $VARIANT$up; \
- }
-
-#define makeResolver_up_mp_wfe(name) \
- void name ## $VARIANT$up(void); \
- void name ## $VARIANT$mp(void); \
- void name ## $VARIANT$wfe(void); \
- void* name ## Resolver(void) __asm__( "_" #name ) ; \
- void* name ## Resolver(void) { \
- __asm__(".symbol_resolver _" #name); \
- uint32_t caps = *(uint32_t*)(uintptr_t)_COMM_PAGE_CPU_CAPABILITIES; \
- /* return WFE variant if we will get woken up */ \
- if ((caps & (kHasEvent | kUP)) == kHasEvent) { \
- return name ## $VARIANT$wfe; \
- } \
- /* return MP variant functions on kNumCPUs > 1 */ \
- else if ((caps & kUP) == 0) { \
- return name ## $VARIANT$mp; \
- } \
- return name ## $VARIANT$up; \
- }
-
-#endif // defined VARIANT_DYLD
-
-#include "OSAtomic_resolvers.h"
-
-#else // defined _ARM_ARCH_7
-
-typedef int emptyFilesArentCFiles;
-
-#endif // defined _ARM_ARCH_7 && !defined VARIANT_DYLD
+++ /dev/null
-/*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * This header file gets included by OSAtomic_resolvers.c and OSAtomic.s
- * in order to create the appropriate resolvers for both libsystem_c.dylib
- * and dyld's libc.a
- */
-
-makeResolver_up_mp(OSAtomicAdd32Barrier)
-makeResolver_up_mp(OSAtomicOr32Barrier)
-makeResolver_up_mp(OSAtomicOr32OrigBarrier)
-makeResolver_up_mp(OSAtomicAnd32Barrier)
-makeResolver_up_mp(OSAtomicAnd32OrigBarrier)
-makeResolver_up_mp(OSAtomicXor32Barrier)
-makeResolver_up_mp(OSAtomicXor32OrigBarrier)
-makeResolver_up_mp(OSAtomicCompareAndSwap32Barrier)
-makeResolver_up_mp(OSAtomicCompareAndSwapIntBarrier)
-makeResolver_up_mp(OSAtomicCompareAndSwapLongBarrier)
-makeResolver_up_mp(OSAtomicCompareAndSwapPtrBarrier)
-makeResolver_up_mp(OSAtomicTestAndSetBarrier)
-makeResolver_up_mp(OSAtomicTestAndClearBarrier)
-makeResolver_up_mp(OSMemoryBarrier)
-makeResolver_up_mp(OSAtomicEnqueue)
-makeResolver_up_mp(OSAtomicDequeue)
-makeResolver_up_mp(OSAtomicAdd64Barrier)
-makeResolver_up_mp(OSAtomicCompareAndSwap64Barrier)
-
-makeResolver_up_mp_wfe(spin_lock)
-makeResolver_up_mp_wfe(_spin_lock)
-makeResolver_up_mp_wfe(OSSpinLockLock)
-
-makeResolver_up_mp(spin_lock_try)
-makeResolver_up_mp(_spin_lock_try)
-makeResolver_up_mp(OSSpinLockTry)
-
-makeResolver_up_mp(spin_unlock)
-makeResolver_up_mp(_spin_unlock)
-makeResolver_up_mp(OSSpinLockUnlock)
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "OSAtomic.h"
-#include "../../darwin/SpinlocksLoadStoreEx.c"
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-
-// On ARMv6, the default implementation already has no barriers, no need to do it again
-#if defined(_ARM_ARCH_7)
-
-#define _OSATOMIC_NO_BARRIERS
-#include "Spinlocks.c"
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <arm/arch.h>
-
-#if defined(_ARM_ARCH_7)
-
-#define _OSATOMIC_WFE
-#include "Spinlocks.c"
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Copyright (c) 1998-2008 Apple Inc. All rights reserved.
- *
- * Implements _longjmp()
- *
- */
-
-#include <architecture/arm/asm_help.h>
-#include "_setjmp.h"
-#include <arm/arch.h>
-
-/* int _longjmp(jmp_buf env, int val); */
-
-ENTRY_POINT(__longjmp)
- ldmia r0!, { r4-r8, r10-r11, sp, lr }
- vldmia r0, { d8-d15 }
- movs r0, r1
- moveq r0, #1
- bx lr
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1998, Apple Computer Inc. All rights reserved.
- *
- * File: _setjmp.h
- *
- * Defines for register offsets in the save area.
- *
- */
-
-#if defined(__arm__)
-
-#define JMP_r4 0x00
-#define JMP_r5 0x04
-#define JMP_r6 0x08
-#define JMP_r7 0x0c
-#define JMP_r8 0x10
-#define JMP_r10 0x14
-#define JMP_fp 0x18
-#define JMP_sp 0x1c
-#define JMP_lr 0x20
-
-#define JMP_VFP 0x24
-
-#define JMP_sig 0x68
-
-#define JMP_SIGFLAG 0x70
-
-#else
-#error architecture not supported
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Copyright (c) 1998-2008 Apple Inc. All rights reserved.
- *
- * Implements _setjmp()
- *
- */
-
-#include <architecture/arm/asm_help.h>
-#include "_setjmp.h"
-#include <arm/arch.h>
-
-ENTRY_POINT(__setjmp)
- stmia r0!, { r4-r8, r10-r11, sp, lr }
- vstmia r0, { d8-d15 }
- mov r0, #0
- bx lr
+++ /dev/null
-/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include <time.h>
-#include <tzfile.h>
-#include <sys/time.h>
-#include <errno.h>
-#include <sys/syscall.h>
-#include <unistd.h>
-#include <mach/clock_types.h>
-#include <mach/mach.h>
-#include <mach/mach_time.h>
-#include <machine/cpu_capabilities.h>
-
-int __commpage_gettimeofday(struct timeval *);
-
-
-#define TIME_ADD(rsecs, secs, rfrac, frac, unit) \
-{ \
- (rfrac) += (frac); \
- while ((rfrac) >= (unit)) { \
- (rfrac) -= (unit); \
- (rsecs) += 1; \
- } \
- (rsecs) += (secs); \
-}
-
-
-int __commpage_gettimeofday(struct timeval *tp) {
- commpage_timeofday_data_t *commpage_timeofday_datap;
- uint64_t tbr;
- uint64_t t64;
- uint64_t TimeBase;
- uint32_t TimeStamp_usec;
- uint32_t TimeStamp_sec;
- uint32_t TimeBaseTicks_per_sec;
- uint64_t TimeBase_magic;
- uint32_t TimeBase_add;
- uint32_t TimeBase_shift;
- uint32_t x, q;
-
-
- commpage_timeofday_datap = (commpage_timeofday_data_t *)_COMM_PAGE_TIMEOFDAY_DATA;
-
- do {
- TimeBase = commpage_timeofday_datap->TimeBase;
- TimeStamp_sec = commpage_timeofday_datap->TimeStamp_sec;
- TimeStamp_usec = commpage_timeofday_datap->TimeStamp_usec;
- TimeBaseTicks_per_sec = commpage_timeofday_datap->TimeBaseTicks_per_sec;
- TimeBase_magic = commpage_timeofday_datap->TimeBase_magic;
- TimeBase_add = commpage_timeofday_datap->TimeBase_add;
- TimeBase_shift = commpage_timeofday_datap->TimeBase_shift;
- } while (TimeBase != commpage_timeofday_datap->TimeBase);
-
- if (TimeBase == 0)
- return(1);
-
- tbr = mach_absolute_time();
-
- t64 = tbr - TimeBase;
-
- if (t64 >= (uint64_t)TimeBaseTicks_per_sec)
- return(1);
-
- x = (uint32_t)t64;
- q = ((uint64_t)x * (uint32_t)(TimeBase_magic)) >> 32;
- tp->tv_usec = TimeBase_add ? (((x - q) >> 1) + q) >> (TimeBase_shift - 1) : q >> TimeBase_shift;
- tp->tv_sec = 0;
-
- TIME_ADD(tp->tv_sec, TimeStamp_sec, tp->tv_usec, TimeStamp_usec, USEC_PER_SEC);
-
- return(0);
-}
+++ /dev/null
-/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __clang__
-
-#include <stdint.h>
-#include <libkern/OSAtomic.h>
-#include <arm/arch.h>
-#include <stdbool.h>
-
-/*
- * Implement gcc atomic "builtins" in terms of OSAtomic routines,
- * since the ARM GCC target does not currently support them
- */
-
-int32_t __sync_fetch_and_add_4 (int32_t *ptr, int32_t value, ...)
-{
- return OSAtomicAdd32Barrier(value, ptr) - value;
-}
-
-int32_t __sync_fetch_and_sub_4 (int32_t *ptr, int32_t value, ...)
-{
- return OSAtomicAdd32Barrier(-value, ptr) + value;
-}
-
-uint32_t __sync_fetch_and_or_4(uint32_t *ptr, uint32_t value, ...)
-{
- return OSAtomicOr32OrigBarrier(value, ptr);
-}
-
-uint32_t __sync_fetch_and_and_4(uint32_t *ptr, uint32_t value, ...)
-{
- return OSAtomicAnd32OrigBarrier(value, ptr);
-}
-
-uint32_t __sync_fetch_and_xor_4(uint32_t *ptr, uint32_t value, ...)
-{
- return OSAtomicXor32OrigBarrier(value, ptr);
-}
-
-int32_t __sync_add_and_fetch_4 (int32_t *ptr, int32_t value, ...)
-{
- return OSAtomicAdd32Barrier(value, ptr);
-}
-
-int32_t __sync_sub_and_fetch_4 (int32_t *ptr, int32_t value, ...)
-{
- return OSAtomicAdd32Barrier(-value, ptr);
-}
-
-uint32_t __sync_or_and_fetch_4 (uint32_t *ptr, int32_t value, ...)
-{
- return OSAtomicOr32Barrier(value, ptr);
-}
-
-uint32_t __sync_and_and_fetch_4 (uint32_t *ptr, int32_t value, ...)
-{
- return OSAtomicAnd32Barrier(value, ptr);
-}
-
-uint32_t __sync_xor_and_fetch_4 (uint32_t *ptr, int32_t value, ...)
-{
- return OSAtomicXor32Barrier(value, ptr);
-}
-
-bool __sync_bool_compare_and_swap_4(int32_t *ptr, int32_t oldval, int32_t newval, ...)
-{
- return OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr);
-}
-
-int32_t __sync_val_compare_and_swap_4(int32_t *ptr, int32_t oldval, int32_t newval, ...)
-{
- int32_t old = *ptr;
- OSAtomicCompareAndSwap32Barrier(oldval, newval, ptr);
- return old;
-}
-
-int32_t __sync_lock_test_and_set_4(int32_t *ptr, int32_t value, ...)
-{
- int32_t old;
-
- do {
- old = *ptr;
- } while (!OSAtomicCompareAndSwap32Barrier(old, value, ptr));
-
- return old;
-}
-
-void __sync_lock_release_4(int32_t *ptr, ...)
-{
- *ptr = 0;
-}
-
-__private_extern__
-void __sync_synchronize(void)
-{
- OSMemoryBarrier();
-}
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1998-2008 Apple Inc. All rights reserved.
- *
- * File: sys/arm/longjmp.s
- *
- * Implements siglongjmp(), longjmp(), _longjmp()
- *
- */
-
-#include <architecture/arm/asm_help.h>
-#include "_setjmp.h"
-
-/*
- * longjmp routines
- */
-
-/* void siglongjmp(sigjmp_buf env, int val); */
-
-ENTRY_POINT(_siglongjmp)
- ldr r2, [ r0, #JMP_SIGFLAG ] // load sigflag
- tst r2, #0 // test if zero
- beq L__exit // if zero do _longjmp()
- // else *** fall through *** to longjmp()
-
-/* void longjmp(jmp_buf env, int val); */
-
-ENTRY_POINT(_longjmp)
- mov r6, r0 // preserve args across _sigsetmask
- mov r8, r1
- ldr r0, [ r0, #JMP_sig ] // restore the signal mask
- CALL_EXTERNAL(_sigsetmask) // make a (deprecated!) syscall to set the mask
- mov r1, r8
- mov r0, r6
-L__exit:
- BRANCH_EXTERNAL(__longjmp)
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-
-#if __arm__
- .text
- .align 2
- .globl _mach_absolute_time
-_mach_absolute_time:
- mov r12, #-3
- swi 0x80
- bx lr
-#endif
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1998-2008 Apple Inc. All rights reserved.
- *
- * File: sys/arm/setjmp.s
- *
- * Implements sigsetjmp(), setjmp(), _setjmp()
- *
- */
-
-#include <architecture/arm/asm_help.h>
-#include "_setjmp.h"
-
-/*
- * setjmp routines
- */
-
-/* int sigsetjmp(sigjmp_buf env, int savemask); */
-
-ENTRY_POINT(_sigsetjmp)
- str r1, [ r0, #JMP_SIGFLAG ] // save sigflag
- tst r1, #0 // test if r1 is 0
- beq L__exit // if r1 == 0 do _setjmp()
- // else *** fall through *** to setjmp()
-
-/* int setjmp(jmp_buf env); */
-
-ENTRY_POINT(_setjmp)
- str lr, [ r0, #JMP_lr ]
- str r8, [ r0, #JMP_r8 ]
- mov r8, r0
- mov r0, #1 // get the previous signal mask
- mov r1, #0 //
- add r2, r8, #JMP_sig // get address where previous mask needs to be
- CALL_EXTERNAL(_sigprocmask) // make a syscall to get mask
- mov r0, r8 // restore jmp_buf ptr
- ldr r8, [ r0, #JMP_r8 ]
- ldr lr, [ r0, #JMP_lr ]
-L__exit:
- BRANCH_EXTERNAL(__setjmp)
#if __DARWIN_UNIX03
#ifdef VARIANT_CANCELABLE
#include <pthread.h>
-
-extern void _pthread_testcancel(pthread_t thread, int isconforming);
#endif /* VARIANT_CANCELABLE */
extern int __unix_conforming;
#endif /* __DARWIN_UNIX03 */
#ifndef BUILDING_VARIANT
#if defined(__DYNAMIC__)
extern int _sigaction_nobind (int sig, const struct sigaction *nsv, struct sigaction *osv);
+extern int _sigvec_nobind (int, struct sigvec *, struct sigvec *);
#endif
static int
-sigvec__(signo, sv, osv, bind)
- int signo;
- struct sigvec *sv, *osv;
- int bind;
+sigvec__(int signo,
+ struct sigvec *sv,
+ struct sigvec *osv,
+ int bind)
{
int ret;
}
int
-sigvec(signo, sv, osv)
- int signo;
- struct sigvec *sv, *osv;
+sigvec(int signo,
+ struct sigvec *sv,
+ struct sigvec *osv)
{
return sigvec__(signo, sv, osv, 1);
}
#if defined(__DYNAMIC__)
int
-_sigvec_nobind(signo, sv, osv)
- int signo;
- struct sigvec *sv, *osv;
+_sigvec_nobind(int signo,
+ struct sigvec *sv,
+ struct sigvec *osv)
{
return sigvec__(signo, sv, osv, 0);
}
#endif
int
-sigsetmask(mask)
- int mask;
+sigsetmask(int mask)
{
int omask, n;
}
int
-sigblock(mask)
- int mask;
+sigblock(int mask)
{
int omask, n;
#if __DARWIN_UNIX03
int
-sigpause(sig)
- int sig;
+sigpause(int sig)
{
sigset_t mask;
if (__unix_conforming == 0)
__unix_conforming = 1;
#ifdef VARIANT_CANCELABLE
- _pthread_testcancel(pthread_self(), 1);
+ pthread_testcancel();
#endif /* VARIANT_CANCELABLE */
if ((sig <= 0) || (sig >= NSIG)) {
}
#else
int
-sigpause(mask)
- int mask;
+sigpause(int mask)
{
return (sigsuspend((sigset_t *)&mask));
}
#ifndef BUILDING_VARIANT
int
-sighold(sig)
- int sig;
+sighold(int sig)
{
sigset_t mask;
}
int
-sigrelse(sig)
- int sig;
+sigrelse(int sig)
{
sigset_t mask;
int
-sigignore(sig)
- int sig;
+sigignore(int sig)
{
return (signal(sig, SIG_IGN) == SIG_ERR ? -1 : 0);
}
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <mach/kern_return.h>
-#include <mach/mach_time.h>
-#include <stdint.h>
-
-extern void spin_lock(int *);
-extern void spin_unlock(int *);
-
-/* deprecated function stub */
-kern_return_t
-MKGetTimeBaseInfo(
- uint32_t *minAbsoluteTimeDelta,
- uint32_t *theAbsoluteTimeToNanosecondNumerator,
- uint32_t *theAbsoluteTimeToNanosecondDenominator,
- uint32_t *theProcessorToAbsoluteTimeNumerator,
- uint32_t *theProcessorToAbsoluteTimeDenominator
-) {
- static struct mach_timebase_info mti = {0};
- static int MKGetTimeBaseInfo_spin_lock = 0;
-
- if(mti.numer == 0) {
- kern_return_t err;
- spin_lock(&MKGetTimeBaseInfo_spin_lock);
- err = mach_timebase_info(&mti);
- spin_unlock(&MKGetTimeBaseInfo_spin_lock);
- if(err != KERN_SUCCESS)
- return err;
- }
- if(theAbsoluteTimeToNanosecondNumerator)
- *theAbsoluteTimeToNanosecondNumerator = mti.numer;
- if(theAbsoluteTimeToNanosecondDenominator)
- *theAbsoluteTimeToNanosecondDenominator = mti.denom;
- if(minAbsoluteTimeDelta)
- *minAbsoluteTimeDelta = 1;
- if(theProcessorToAbsoluteTimeNumerator)
- *theProcessorToAbsoluteTimeNumerator = 1;
- if(theProcessorToAbsoluteTimeDenominator)
- *theProcessorToAbsoluteTimeDenominator = 1;
- return KERN_SUCCESS;
-}
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-// OSAtomic.h is included by files that include this C file.
-/* #include "OSAtomic.h" */
-
-int32_t OSAtomicAdd32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicAdd32);
-int32_t OSAtomicAdd32(int32_t v, volatile int32_t *p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicAdd32);
- int32_t r;
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(p, r);
- r += v;
- _osatomic_store_exclusive(p, r, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return r;
-}
-
-int64_t OSAtomicAdd64(int64_t v, volatile int64_t *p) _OSATOMIC_VARIANT_B(OSAtomicAdd64);
-int64_t OSAtomicAdd64(int64_t v, volatile int64_t *p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicAdd64);
-
- int64_t r;
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive64(p, r);
- r += v;
- _osatomic_store_exclusive64(p, r, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return r;
-}
-
-int32_t OSAtomicOr32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicOr32);
-int32_t OSAtomicOr32(int32_t v, volatile int32_t *p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicOr32);
- int32_t r;
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(p, r);
- r |= v;
- _osatomic_store_exclusive(p, r, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return r;
-}
-
-int32_t OSAtomicOr32Orig(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicOr32Orig);
-int32_t OSAtomicOr32Orig(int32_t v, volatile int32_t *p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicOr32Orig);
- int32_t r, n;
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(p, r);
- n = r | v;
- _osatomic_store_exclusive(p, n, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return r;
-}
-
-int32_t OSAtomicAnd32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicAnd32);
-int32_t OSAtomicAnd32(int32_t v, volatile int32_t *p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicAnd32);
- int32_t r;
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(p, r);
- r &= v;
- _osatomic_store_exclusive(p, r, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return r;
-}
-
-int32_t OSAtomicAnd32Orig(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicAnd32Orig);
-int32_t OSAtomicAnd32Orig(int32_t v, volatile int32_t *p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicAnd32Orig);
- int32_t r, n;
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(p, r);
- n = r & v;
- _osatomic_store_exclusive(p, n, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return r;
-}
-
-int32_t OSAtomicXor32(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicXor32);
-int32_t OSAtomicXor32(int32_t v, volatile int32_t *p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicXor32);
- int32_t r;
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(p, r);
- r ^= v;
- _osatomic_store_exclusive(p, r, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return r;
-}
-
-int32_t OSAtomicXor32Orig(int32_t v, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicXor32Orig);
-int32_t OSAtomicXor32Orig(int32_t v, volatile int32_t *p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicXor32Orig);
- int32_t r, n;
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(p, r);
- n = r ^ v;
- _osatomic_store_exclusive(p, n, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return r;
-}
-
-bool OSAtomicCompareAndSwap32(int32_t o, int32_t n, volatile int32_t *p) _OSATOMIC_VARIANT_B(OSAtomicCompareAndSwap32);
-bool OSAtomicCompareAndSwap32(int32_t o, int32_t n, volatile int32_t *p)
-{
- _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapInt, OSAtomicCompareAndSwap32);
-
- _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwap32);
- _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapInt);
-#ifndef __LP64__
- _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapLong, OSAtomicCompareAndSwap32);
- _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapPtr, OSAtomicCompareAndSwap32);
- _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapLong);
- _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapPtr);
-#endif
-
- int32_t r;
- uint32_t t;
-
- do {
- _osatomic_load_exclusive(p, r);
- if (r != o) return false;
- _osatomic_store_barrier();
- _osatomic_store_exclusive(p, n, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return true;
-}
-
-bool OSAtomicCompareAndSwap64(int64_t o, int64_t n, volatile int64_t *p) _OSATOMIC_VARIANT_B(OSAtomicCompareAndSwap64);
-bool OSAtomicCompareAndSwap64(int64_t o, int64_t n, volatile int64_t *p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwap64);
-#ifdef __LP64__
- _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapLong, OSAtomicCompareAndSwap64);
- _OSATOMIC_ALIAS_B(OSAtomicCompareAndSwapPtr, OSAtomicCompareAndSwap64);
- _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapLong);
- _OSATOMIC_ALIAS_NB(OSAtomicCompareAndSwapPtr);
-#endif
-
- int64_t r;
- uint32_t t;
-
- do {
- _osatomic_load_exclusive64(p, r);
- if (r != o) return false;
- _osatomic_store_barrier();
- _osatomic_store_exclusive64(p, n, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return true;
-}
-
-#if defined(_OSATOMIC_EXTRAS)
-
-void OSMemoryBarrier(void) _OSATOMIC_VARIANT(OSMemoryBarrier);
-void OSMemoryBarrier(void)
-{
- _osatomic_barrier();
-}
-
-typedef volatile struct {
- void *item;
- long unused;
-} OSQueueHead;
-
-void OSAtomicEnqueue(OSQueueHead *l, void *n, size_t o) _OSATOMIC_VARIANT(OSAtomicEnqueue);
-void OSAtomicEnqueue(OSQueueHead *l, void *n, size_t o)
-{
- void ** r = (void **)((char *)n + o);
- void * volatile * i = (void **)&(l->item);
- void * q;
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(i, q);
- *r = q;
- _osatomic_store_exclusive(i, n, t);
- } while (slowpath(t));
- _osatomic_barrier();
-}
-
-void* OSAtomicDequeue(OSQueueHead *l, size_t o) _OSATOMIC_VARIANT(OSAtomicDequeue);
-void* OSAtomicDequeue(OSQueueHead *l, size_t o)
-{
- void * h;
- void ** r;
- void * volatile * i = (void **)&(l->item);
- uint32_t t;
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(i, r);
- if (!r) return NULL;
- h = *(void **)((char *)r + o);
- _osatomic_store_exclusive(i, h, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return r;
-}
-
-#endif
-
-bool OSAtomicTestAndSet(uint32_t n, volatile void * p) _OSATOMIC_VARIANT_B(OSAtomicTestAndSet);
-bool OSAtomicTestAndSet(uint32_t n, volatile void * p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicTestAndSet);
- uint32_t * ptr = (uint32_t *)((char *)p + (4 * (n / 32)));
- uint32_t i, r, t;
-
- n = (0x80 >> (n & 7)) << (n & ~7 & 31);
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(ptr, r);
- i = r | n;
- if (i == r) break;
- _osatomic_store_exclusive(ptr, i, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return ((r & n) != 0);
-}
-
-bool OSAtomicTestAndClear(uint32_t n, volatile void * p) _OSATOMIC_VARIANT_B(OSAtomicTestAndClear);
-bool OSAtomicTestAndClear(uint32_t n, volatile void * p)
-{
- _OSATOMIC_ALIAS_NB(OSAtomicTestAndClear);
- uint32_t * ptr = (uint32_t *)((char *)p + (4 * (n / 32)));
- uint32_t i, r, t;
-
- n = (0x80 >> (n & 7)) << (n & ~7 & 31);
-
- _osatomic_store_barrier();
- do {
- _osatomic_load_exclusive(ptr, r);
- i = r & ~n;
- if (i == r) break;
- _osatomic_store_exclusive(ptr, i, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return ((r & n) != 0);
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-// OSAtomic.h is included by files that include this C file.
-/* #include "OSAtomic.h" */
-
-typedef int32_t OSSpinLock;
-
-/*
- * Bear with me, there's method to this madness. clang actually produces more optimal
- * fastpath code if the lock code is split in half like this.
- *
- * Once we're spinning in userspace/kernel like this then we can be more lenient about
- * how much effort is spent doing the spin. Where the lock is uncontended, this split
- * arrangement produces a very good fastpath at the cost of some code duplication.
- *
- * Similarly, the gotos produce less wasteful code during spins then the equivalent code
- * defined with loops.
- */
-
-#import <mach/mach_traps.h>
-
-static inline void _OSSpinLockSlow(volatile OSSpinLock * lock) _OSATOMIC_VARIANT(_OSSpinLockSlow);
-static inline void _OSSpinLockSlow(volatile OSSpinLock * lock)
-{
- int32_t r;
- uint32_t t;
-
-_spin: ;
-#if (defined(_ARM_ARCH_7) && !defined(_OSATOMIC_NO_BARRIERS))
- uint32_t tries = MP_SPIN_TRIES;
- do {
- if (*lock == 0) goto _try_store;
- _osatomic_pause();
- } while (--tries);
-#endif
-
- __asm__ ("mov r0, %[_a] ;"
- "mov r1, %[_b] ;"
- "mov r2, %[_c] ;"
- "bl _syscall_thread_switch ;"
- : : [_a] "i" (0), [_b] "i" (1), [_c] "i" (1)
- : "r0", "r1", "r2", "r9", "r12", "lr" );
-
-_try_store:
- do {
- _osatomic_load_exclusive(lock, r);
- if (slowpath(r)) goto _spin;
- _osatomic_store_exclusive(lock, 1, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
-}
-
-void OSSpinLockLock(volatile OSSpinLock * lock) _OSATOMIC_VARIANT(OSSpinLockLock);
-void OSSpinLockLock(volatile OSSpinLock * lock)
-{
- _OSATOMIC_ALIAS(spin_lock, OSSpinLockLock);
- _OSATOMIC_ALIAS(_spin_lock, OSSpinLockLock);
-
- int32_t r;
- uint32_t t;
-
- do {
- _osatomic_load_exclusive(lock, r);
- if (slowpath(r)) return _OSSpinLockSlow(lock);
- _osatomic_store_exclusive(lock, 1, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
-}
-
-#ifndef _OSATOMIC_WFE
-
-bool OSSpinLockTry(OSSpinLock * lock) _OSATOMIC_VARIANT(OSSpinLockTry);
-bool OSSpinLockTry(OSSpinLock * lock)
-{
- _OSATOMIC_ALIAS(spin_lock_try, OSSpinLockTry);
- _OSATOMIC_ALIAS(_spin_lock_try, OSSpinLockTry);
-
- int32_t r;
- uint32_t t;
-
- do {
- _osatomic_load_exclusive(lock, r);
- if (slowpath(r)) return false;
- _osatomic_store_exclusive(lock, 1, t);
- } while (slowpath(t));
-
- _osatomic_barrier();
- return (r == 0);
-}
-
-void OSSpinLockUnlock(OSSpinLock * lock) _OSATOMIC_VARIANT(OSSpinLockUnlock);
-void OSSpinLockUnlock(OSSpinLock * lock)
-{
- _OSATOMIC_ALIAS(spin_unlock, OSSpinLockUnlock);
- _OSATOMIC_ALIAS(_spin_unlock, OSSpinLockUnlock);
-
- _osatomic_barrier();
- *lock = 0;
-}
-
-#endif // _OSATOMIC_WFE
/*
- * Copyright (c) 2006, 2007, 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2006, 2007, 2009-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <servers/bootstrap.h>
+#include <bootstrap_priv.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
+#include <mach-o/dyld_priv.h>
#include <membership.h>
#include <pthread.h>
#include <errno.h>
#include <TargetConditionals.h>
#include <xpc/xpc.h>
#include <xpc/private.h>
+#if !TARGET_OS_IPHONE
+#include <CrashReporterClient.h>
+#endif /* !TARGET_OS_IPHONE */
#include "dirhelper.h"
#include "dirhelper_priv.h"
#define BUCKETLEN 2
-#define MUTEX_LOCK(x) if(__is_threaded) pthread_mutex_lock(x)
-#define MUTEX_UNLOCK(x) if(__is_threaded) pthread_mutex_unlock(x)
+#define MUTEX_LOCK(x) pthread_mutex_lock(x)
+#define MUTEX_UNLOCK(x) pthread_mutex_unlock(x)
// Use 5 bits per character, to avoid uppercase and shell magic characters
#define ENCODEBITS 5
#define MASK(x) ((1 << (x)) - 1)
#define UUID_UID_SIZE (sizeof(uuid_t) + sizeof(uid_t))
-extern int __is_threaded;
-
static const mode_t modes[] = {
0755, /* user */
0700, /* temp */
// 32 characters.
static const char encode[] = "0123456789_bcdfghjklmnpqrstvwxyz";
+#if TARGET_OS_IPHONE
+
+#define setcrashlogmessage(fmt, ...) /* nothing */
+
+#else /* !TARGET_OS_IPHONE */
+
static void
encode_uuid_uid(const uuid_t uuid, uid_t uid, char *str)
{
*str = 0;
}
+static void
+_setcrashlogmessage(const char *fmt, ...) __attribute__((__format__(__printf__,1,2)))
+{
+ char *mess = NULL;
+ int res;
+ va_list ap;
+
+ va_start(ap, fmt);
+ res = vasprintf(&mess, fmt, ap);
+ va_end(ap);
+ if (res < 0)
+ mess = (char *)fmt; /* the format string is better than nothing */
+ CRSetCrashLogMessage(mess);
+}
+
+#define setcrashlogmessage(fmt, ...) _setcrashlogmessage("%s: %u: " fmt, __func__, __LINE__, ##__VA_ARGS__)
+
+#endif /* !TARGET_OS_IPHONE */
+
char *
__user_local_dirname(uid_t uid, dirhelper_which_t which, char *path, size_t pathlen)
{
#endif
int res;
- if(which < 0 || which > DIRHELPER_USER_LOCAL_LAST) {
+ if((int)which < 0 || which > DIRHELPER_USER_LOCAL_LAST) {
+ setcrashlogmessage("Out of range: which=%d", (int)which);
errno = EINVAL;
return NULL;
}
if(which == DIRHELPER_USER_LOCAL_TEMP) {
tmpdir = getenv("TMPDIR");
if(!tmpdir) {
+ setcrashlogmessage("TMPDIR not set");
errno = EINVAL;
return NULL;
}
res = snprintf(path, pathlen, "%s", tmpdir);
} else {
+ setcrashlogmessage("Only DIRHELPER_USER_LOCAL_TEMP is supported: which=%d", (int)which);
errno = EINVAL;
return NULL;
}
#else
res = mbr_uid_to_uuid(uid, uuid);
if(res != 0) {
+ setcrashlogmessage("mbr_uid_to_uuid returned %d, uid=%d", res, (int)uid);
errno = res;
return NULL;
}
VAR_FOLDERS_PATH, BUCKETLEN, str, str + BUCKETLEN, subdirs[which]);
#endif
if(res >= pathlen) {
+ setcrashlogmessage("snprintf: buffer too small: res=%d >= pathlen=%zu", res, pathlen);
errno = EINVAL;
return NULL; /* buffer too small */
}
while ((next = strchr(next, '/')) != NULL) {
*next = 0; // temporarily truncate
res = mkdir(path, 0755);
- if (res != 0 && errno != EEXIST)
+ if (res != 0 && errno != EEXIST) {
+ setcrashlogmessage("mkdir: path=%s mode=0755: %s", path, strerror(errno));
return NULL;
+ }
*next++ = '/'; // restore the slash and increment
}
return path;
* There is a rare case when launchd will have userdir set, and child process
* will sometimes inherit this cached value.
*/
+__private_extern__ void _dirhelper_fork_child(void);
__private_extern__ void
_dirhelper_fork_child(void)
{
if(userdir) *userdir = 0;
}
+__private_extern__ char *_dirhelper(dirhelper_which_t which, char *path, size_t pathlen);
__private_extern__ char *
_dirhelper(dirhelper_which_t which, char *path, size_t pathlen)
{
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
struct stat sb;
- if(which < 0 || which > DIRHELPER_USER_LOCAL_LAST) {
+ if((int)which < 0 || which > DIRHELPER_USER_LOCAL_LAST) {
+ setcrashlogmessage("Out of range: which=%d", (int)which);
errno = EINVAL;
return NULL;
}
if (pthread_once(&userdir_control, userdir_allocate)
|| !userdir) {
+ setcrashlogmessage("Out of memory in userdir_allocate");
errno = ENOMEM;
return NULL;
}
mach_port_t mp;
if(errno != ENOENT) { /* some unknown error */
+ setcrashlogmessage("stat: %s: %s", userdir, strerror(errno));
*userdir = 0;
MUTEX_UNLOCK(&lock);
return NULL;
return NULL;
}
} else {
- if(bootstrap_look_up(bootstrap_port, DIRHELPER_BOOTSTRAP_NAME, &mp) != KERN_SUCCESS) {
- errno = EPERM;
+ kern_return_t res;
+#if TARGET_IPHONE_SIMULATOR
+ res = bootstrap_look_up(bootstrap_port, DIRHELPER_BOOTSTRAP_NAME, &mp);
+#else
+ res = bootstrap_look_up2(bootstrap_port, DIRHELPER_BOOTSTRAP_NAME, &mp, 0, BOOTSTRAP_PRIVILEGED_SERVER);
+#endif
+
+ if(res != KERN_SUCCESS) {
+ setcrashlogmessage("bootstrap_look_up returned %d", res);
+ errno = EPERM;
server_error:
- mach_port_deallocate(mach_task_self(), mp);
- MUTEX_UNLOCK(&lock);
- return NULL;
+ mach_port_deallocate(mach_task_self(), mp);
+ MUTEX_UNLOCK(&lock);
+ return NULL;
}
- if(__dirhelper_create_user_local(mp) != KERN_SUCCESS) {
- errno = EPERM;
- goto server_error;
+ if((res = __dirhelper_create_user_local(mp)) != KERN_SUCCESS) {
+ setcrashlogmessage("__dirhelper_create_user_local returned %d", res);
+ errno = EPERM;
+ goto server_error;
}
/* double check that the directory really got created */
if(stat(userdir, &sb) < 0) {
- goto server_error;
+ setcrashlogmessage("stat: %s: %s", userdir, strerror(errno));
+ goto server_error;
}
mach_port_deallocate(mach_task_self(), mp);
}
}
if(pathlen < strlen(userdir) + strlen(subdirs[which]) + 1) {
+ setcrashlogmessage("buffer too small: pathlen=%zu userdir=%s subdirs[%d]=%s", pathlen, userdir, which, subdirs[which]);
errno = EINVAL;
return NULL; /* buffer too small */
}
#if !TARGET_OS_IPHONE
if (!_xpc_runtime_is_app_sandboxed())
#endif
- if(mkdir(path, modes[which]) != 0 && errno != EEXIST)
+ if(mkdir(path, modes[which]) != 0 && errno != EEXIST) {
+ setcrashlogmessage("mkdir: path=%s modes[%d]=0%o: %s", path, which, modes[which], strerror(errno));
return NULL;
+ }
#if !TARGET_OS_IPHONE
char *userdir_suffix = NULL;
* permission to create it ourselves.
*/
if(stat(path, &sb) < 0) {
+ setcrashlogmessage("stat: %s: %s", path, strerror(errno));
errno = EPERM;
return NULL;
}
*/
userdir_suffix = getenv(XPC_ENV_SANDBOX_CONTAINER_ID);
if (!userdir_suffix) {
+ setcrashlogmessage("XPC_ENV_SANDBOX_CONTAINER_ID not set");
errno = EINVAL;
return NULL;
}
- } else
+ } else if (!dyld_process_is_restricted()) {
userdir_suffix = getenv(DIRHELPER_ENV_USER_DIR_SUFFIX);
+ }
if (userdir_suffix) {
+ /*
+ * do not allow paths that contain path traversal dots.
+ */
+ const char *pos = userdir_suffix;
+ while ((pos = strnstr(pos, "..", strlen(pos)))) {
+ if ((pos == userdir_suffix && strlen(userdir_suffix) == 2) || // string is ".." only
+ (pos == userdir_suffix && strlen(userdir_suffix) > 2 && userdir_suffix[2] == '/') || // prefixed with "../"
+ ((pos - userdir_suffix == strlen(userdir_suffix) - 2) && pos[-1] == '/') || // suffixed with "/.."
+ (pos[-1] == '/' && pos[2] == '/')) // middle of string with '/../'
+ {
+ setcrashlogmessage("illegal path traversal (..) pattern found in DIRHELPER_USER_DIR_SUFFIX");
+ errno = EINVAL;
+ return NULL;
+ }
+ pos += 2;
+ }
+
/*
* suffix (usually container ID) doesn't end in a slash, so +2 is for slash and \0
*/
if (pathlen < strlen(path) + strlen(userdir_suffix) + 2) {
+ setcrashlogmessage("buffer too small: pathlen=%zu path=%s userdir_suffix=%s", pathlen, path, userdir_suffix);
errno = EINVAL;
return NULL; /* buffer too small */
}
* create suffix subdirectory with the appropriate permissions
* if it doesn't already exist.
*/
- if (mkdir(path, modes[which]) != 0 && errno != EEXIST)
+ if (mkdir(path, modes[which]) != 0 && errno != EEXIST) {
+ setcrashlogmessage("mkdir: path=%s modes[%d]=0%o: %s", path, which, modes[which], strerror(errno));
return NULL;
+ }
/*
* update TMPDIR if necessary
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#define __APPLE_API_PRIVATE
+#include <machine/cpu_capabilities.h>
+#undef __APPLE_API_PRIVATE
+
+extern int _get_cpu_capabilities(void);
+
+int _cpu_capabilities = 0;
+int _cpu_has_altivec = 0; // DEPRECATED: use _cpu_capabilities instead
+
+__private_extern__ void
+_init_cpu_capabilities( void )
+{
+}
+++ /dev/null
-/*
- * Copyright (c) 2006, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <sys/cdefs.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/errno.h>
-#include <sys/msgbuf.h>
-#define CONFIG_EMBEDDED 1
-#include <sys/process_policy.h>
-
-#include "libproc_internal.h"
-
-int __proc_info(int callnum, int pid, int flavor, uint64_t arg, void * buffer, int buffersize);
-__private_extern__ int proc_setthreadname(void * buffer, int buffersize);
-int __process_policy(int scope, int action, int policy, int policy_subtype, proc_policy_attribute_t * attrp, pid_t target_pid, uint64_t target_threadid);
-
-
-
-int
-proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize)
-{
- int retval;
-
- if ((type >= PROC_ALL_PIDS) || (type <= PROC_PPID_ONLY)) {
- if ((retval = __proc_info(1, type, typeinfo,(uint64_t)0, buffer, buffersize)) == -1)
- return(0);
- } else {
- errno = EINVAL;
- retval = 0;
- }
- return(retval);
-}
-
-
-int
-proc_listallpids(void * buffer, int buffersize)
-{
- int numpids;
- numpids = proc_listpids(PROC_ALL_PIDS, (uint32_t)0, buffer, buffersize);
-
- if (numpids == -1)
- return(-1);
- else
- return(numpids/sizeof(int));
-}
-
-int
-proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize)
-{
- int numpids;
- numpids = proc_listpids(PROC_PGRP_ONLY, (uint32_t)pgrpid, buffer, buffersize);
- if (numpids == -1)
- return(-1);
- else
- return(numpids/sizeof(int));
-}
-
-int
-proc_listchildpids(pid_t ppid, void * buffer, int buffersize)
-{
- int numpids;
- numpids = proc_listpids(PROC_PPID_ONLY, (uint32_t)ppid, buffer, buffersize);
- if (numpids == -1)
- return(-1);
- else
- return(numpids/sizeof(int));
-}
-
-
-int
-proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize)
-{
- int retval;
-
- if ((retval = __proc_info(2, pid, flavor, arg, buffer, buffersize)) == -1)
- return(0);
-
- return(retval);
-}
-
-
-int
-proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize)
-{
- int retval;
-
- if ((retval = __proc_info(3, pid, flavor, (uint64_t)fd, buffer, buffersize)) == -1)
- return(0);
-
- return (retval);
-}
-
-
-int
-proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize)
-{
- int retval;
-
- if ((retval = __proc_info(6, pid, flavor, (uint64_t)fileport, buffer, buffersize)) == -1)
- return (0);
- return (retval);
-}
-
-
-int
-proc_name(int pid, void * buffer, uint32_t buffersize)
-{
- int retval = 0, len;
- struct proc_bsdinfo pbsd;
-
-
- if (buffersize < sizeof(pbsd.pbi_name)) {
- errno = ENOMEM;
- return(0);
- }
-
- retval = proc_pidinfo(pid, PROC_PIDTBSDINFO, (uint64_t)0, &pbsd, sizeof(struct proc_bsdinfo));
- if (retval != 0) {
- if (pbsd.pbi_name[0]) {
- bcopy(&pbsd.pbi_name, buffer, sizeof(pbsd.pbi_name));
- } else {
- bcopy(&pbsd.pbi_comm, buffer, sizeof(pbsd.pbi_comm));
- }
- len = strlen(buffer);
- return(len);
- }
- return(0);
-}
-
-int
-proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize)
-{
- int retval = 0, len;
- struct proc_regionwithpathinfo reginfo;
-
- if (buffersize < MAXPATHLEN) {
- errno = ENOMEM;
- return(0);
- }
-
- retval = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, (uint64_t)address, ®info, sizeof(struct proc_regionwithpathinfo));
- if (retval != -1) {
- len = strlen(®info.prp_vip.vip_path[0]);
- if (len != 0) {
- if (len > MAXPATHLEN)
- len = MAXPATHLEN;
- bcopy(®info.prp_vip.vip_path[0], buffer, len);
- return(len);
- }
- return(0);
- }
- return(0);
-
-}
-
-int
-proc_kmsgbuf(void * buffer, uint32_t buffersize)
-{
- int retval;
-
- if ((retval = __proc_info(4, 0, 0, (uint64_t)0, buffer, buffersize)) == -1)
- return(0);
- return (retval);
-}
-
-int
-proc_pidpath(int pid, void * buffer, uint32_t buffersize)
-{
- int retval, len;
-
- if (buffersize < PROC_PIDPATHINFO_SIZE) {
- errno = ENOMEM;
- return(0);
- }
- if (buffersize > PROC_PIDPATHINFO_MAXSIZE) {
- errno = EOVERFLOW;
- return(0);
- }
-
- retval = __proc_info(2, pid, PROC_PIDPATHINFO, (uint64_t)0, buffer, buffersize);
- if (retval != -1) {
- len = strlen(buffer);
- return(len);
- }
- return (0);
-}
-
-
-int
-proc_libversion(int *major, int * minor)
-{
-
- if (major != NULL)
- *major = 1;
- if (minor != NULL)
- *minor = 1;
- return(0);
-}
-
-int
-proc_setpcontrol(const int control)
-{
- int retval ;
-
- if (control < PROC_SETPC_NONE || control > PROC_SETPC_TERMINATE)
- return(EINVAL);
-
- if ((retval = __proc_info(5, getpid(), PROC_SELFSET_PCONTROL, (uint64_t)control, NULL, 0)) == -1)
- return(errno);
-
- return(0);
-}
-
-
-__private_extern__ int
-proc_setthreadname(void * buffer, int buffersize)
-{
- int retval;
-
- retval = __proc_info(5, getpid(), PROC_SELFSET_THREADNAME, (uint64_t)0, buffer, buffersize);
-
- if (retval == -1)
- return(errno);
- else
- return(0);
-}
-
-int
-proc_track_dirty(pid_t pid, uint32_t flags)
-{
- if (__proc_info(8, pid, PROC_DIRTYCONTROL_TRACK, flags, NULL, 0) == -1) {
- return errno;
- }
-
- return 0;
-}
-
-int
-proc_set_dirty(pid_t pid, bool dirty)
-{
- if (__proc_info(8, pid, PROC_DIRTYCONTROL_SET, dirty, NULL, 0) == -1) {
- return errno;
- }
-
- return 0;
-}
-
-int
-proc_get_dirty(pid_t pid, uint32_t *flags)
-{
- int retval;
-
- if (!flags) {
- return EINVAL;
- }
-
- retval = __proc_info(8, pid, PROC_DIRTYCONTROL_GET, 0, NULL, 0);
- if (retval == -1) {
- return errno;
- }
-
- *flags = retval;
-
- return 0;
-}
-
-int
-proc_terminate(pid_t pid, int *sig)
-{
- int retval;
-
- if (!sig) {
- return EINVAL;
- }
-
- retval = __proc_info(7, pid, 0, 0, NULL, 0);
- if (retval == -1) {
- return errno;
- }
-
- *sig = retval;
-
- return 0;
-}
-
-#if TARGET_OS_EMBEDDED
-
-int
-proc_setcpu_percentage(pid_t pid, int action, int percentage)
-{
- proc_policy_cpuusage_attr_t attr;
-
- bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
- attr.ppattr_cpu_attr = action;
- attr.ppattr_cpu_percentage = percentage;
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, &attr, pid, (uint64_t)0) != -1)
- return(0);
- else
- return(errno);
-}
-
-int
-proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline)
-{
- proc_policy_cpuusage_attr_t attr;
-
- bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
- attr.ppattr_cpu_attr = action;
- attr.ppattr_cpu_attr_deadline = deadline;
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, &attr, pid, (uint64_t)0) != -1)
- return(0);
- else
- return(errno);
-
-}
-
-
-int
-proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline)
-{
- proc_policy_cpuusage_attr_t attr;
-
- bzero(&attr, sizeof(proc_policy_cpuusage_attr_t));
- attr.ppattr_cpu_attr = action;
- attr.ppattr_cpu_percentage = percentage;
- attr.ppattr_cpu_attr_deadline = deadline;
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, &attr, pid, (uint64_t)0) != -1)
- return(0);
- else
- return(errno);
-}
-
-int
-proc_clear_cpulimits(pid_t pid)
-{
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_RESTORE, PROC_POLICY_RESOURCE_USAGE, PROC_POLICY_RUSAGE_CPU, NULL, pid, (uint64_t)0) != -1)
- return(0);
- else
- return(errno);
-
-
-}
-
-int
-proc_appstate(int pid, int * appstatep)
-{
- int state;
-
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_GET, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (int *)&state, pid, (uint64_t)0) != -1) {
- if (appstatep != NULL)
- *appstatep = state;
- return(0);
- } else
- return(errno);
-
-}
-
-
-int
-proc_setappstate(int pid, int appstate)
-{
- int state = appstate;
-
- switch (state) {
- case PROC_APPSTATE_NONE:
- case PROC_APPSTATE_ACTIVE:
- case PROC_APPSTATE_INACTIVE:
- case PROC_APPSTATE_BACKGROUND:
- case PROC_APPSTATE_NONUI:
- break;
- default:
- return(EINVAL);
- }
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_STATE, (int *)&state, pid, (uint64_t)0) != -1)
- return(0);
- else
- return(errno);
-}
-
-int
-proc_devstatusnotify(int devicestatus)
-{
- int state = devicestatus;
-
- switch (devicestatus) {
- case PROC_DEVSTATUS_SHORTTERM:
- case PROC_DEVSTATUS_LONGTERM:
- break;
- default:
- return(EINVAL);
- }
-
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_DEVSTATUS, (int *)&state, getpid(), (uint64_t)0) != -1) {
- return(0);
- } else
- return(errno);
-
-}
-
-int
-proc_pidbind(int pid, uint64_t threadid, int bind)
-{
- int state = bind;
- pid_t passpid = pid;
-
- switch (bind) {
- case PROC_PIDBIND_CLEAR:
- passpid = getpid(); /* ignore pid on clear */
- break;
- case PROC_PIDBIND_SET:
- break;
- default:
- return(EINVAL);
- }
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_APPLY, PROC_POLICY_APP_LIFECYCLE, PROC_POLICY_APPLIFE_PIDBIND, (int *)&state, passpid, threadid) != -1)
- return(0);
- else
- return(errno);
-}
-
-#else /* TARGET_OS_EMBEDDED */
-
-int
-proc_clear_vmpressure(pid_t pid)
-{
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_RESTORE, PROC_POLICY_RESOURCE_STARVATION, PROC_POLICY_RS_VIRTUALMEM, NULL, pid, (uint64_t)0) != -1)
- return(0);
- else
- return(errno);
-}
-
-/* set the current process as one who can resume suspended processes due to low virtual memory. Need to be root */
-int
-proc_set_owner_vmpressure(void)
-{
- int retval;
-
- if ((retval = __proc_info(5, getpid(), PROC_SELFSET_VMRSRCOWNER, (uint64_t)0, NULL, 0)) == -1)
- return(errno);
-
- return(0);
-}
-
-/* mark yourself to delay idle sleep on disk IO */
-int
-proc_set_delayidlesleep(void)
-{
- int retval;
-
- if ((retval = __proc_info(5, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)1, NULL, 0)) == -1)
- return(errno);
-
- return(0);
-}
-
-/* Reset yourself to delay idle sleep on disk IO, if already set */
-int
-proc_clear_delayidlesleep(void)
-{
- int retval;
-
- if ((retval = __proc_info(5, getpid(), PROC_SELFSET_DELAYIDLESLEEP, (uint64_t)0, NULL, 0)) == -1)
- return(errno);
-
- return(0);
-}
-
-/* disable the launch time backgroudn policy and restore the process to default group */
-int
-proc_disable_apptype(pid_t pid, int apptype)
-{
- switch (apptype) {
- case PROC_POLICY_OSX_APPTYPE_TAL:
- case PROC_POLICY_OSX_APPTYPE_DASHCLIENT:
- break;
- default:
- return(EINVAL);
-
- }
-
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_DISABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1)
- return(0);
- else
- return(errno);
-
-}
-
-/* re-enable the launch time background policy if it had been disabled. */
-int
-proc_enable_apptype(pid_t pid, int apptype)
-{
- switch (apptype) {
- case PROC_POLICY_OSX_APPTYPE_TAL:
- case PROC_POLICY_OSX_APPTYPE_DASHCLIENT:
- break;
- default:
- return(EINVAL);
-
- }
-
- if (__process_policy(PROC_POLICY_SCOPE_PROCESS, PROC_POLICY_ACTION_ENABLE, PROC_POLICY_APPTYPE, apptype, NULL, pid, (uint64_t)0) != -1)
- return(0);
- else
- return(errno);
-
-}
-
-#endif /* TARGET_OS_EMBEDDED */
-
+++ /dev/null
-/*
- * Copyright (c) 2006, 2007, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#ifndef _LIBPROC_H_
-#define _LIBPROC_H_
-
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mount.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <sys/proc_info.h>
-
-#include <Availability.h>
-
-/*
- * This header file contains private interfaces to obtain process information.
- * These interfaces are subject to change in future releases.
- */
-
-/*!
- @define PROC_LISTPIDSPATH_PATH_IS_VOLUME
- @discussion This flag indicates that all processes that hold open
- file references on the volume associated with the specified
- path should be returned.
- */
-#define PROC_LISTPIDSPATH_PATH_IS_VOLUME 1
-
-
-/*!
- @define PROC_LISTPIDSPATH_EXCLUDE_EVTONLY
- @discussion This flag indicates that file references that were opened
- with the O_EVTONLY flag should be excluded from the matching
- criteria.
- */
-#define PROC_LISTPIDSPATH_EXCLUDE_EVTONLY 2
-
-__BEGIN_DECLS
-
-
-/*!
- @function proc_listpidspath
- @discussion A function which will search through the current
- processes looking for open file references which match
- a specified path or volume.
- @param type types of processes to be searched (see proc_listpids)
- @param typeinfo adjunct information for type
- @param path file or volume path
- @param pathflags flags to control which files should be considered
- during the process search.
- @param buffer a C array of int-sized values to be filled with
- process identifiers that hold an open file reference
- matching the specified path or volume. Pass NULL to
- obtain the minimum buffer size needed to hold the
- currently active processes.
- @param buffersize the size (in bytes) of the provided buffer.
- @result the number of bytes of data returned in the provided buffer;
- -1 if an error was encountered;
- */
-int proc_listpidspath(uint32_t type,
- uint32_t typeinfo,
- const char *path,
- uint32_t pathflags,
- void *buffer,
- int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int proc_listallpids(void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1);
-int proc_listpgrppids(pid_t pgrpid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1);
-int proc_listchildpids(pid_t ppid, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_1);
-int proc_pidinfo(int pid, int flavor, uint64_t arg, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int proc_pidfdinfo(int pid, int fd, int flavor, void * buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int proc_pidfileportinfo(int pid, uint32_t fileport, int flavor, void *buffer, int buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-int proc_name(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int proc_regionfilename(int pid, uint64_t address, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int proc_kmsgbuf(void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int proc_pidpath(int pid, void * buffer, uint32_t buffersize) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int proc_libversion(int *major, int * minor) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-/*
- * A process can use the following api to set its own process control
- * state on resoure starvation. The argument can have one of the PROC_SETPC_XX values
- */
-#define PROC_SETPC_NONE 0
-#define PROC_SETPC_THROTTLEMEM 1
-#define PROC_SETPC_SUSPEND 2
-#define PROC_SETPC_TERMINATE 3
-
-int proc_setpcontrol(const int control) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-int proc_setpcontrol(const int control);
-
-int proc_track_dirty(pid_t pid, uint32_t flags);
-int proc_set_dirty(pid_t pid, bool dirty);
-int proc_get_dirty(pid_t pid, uint32_t *flags);
-
-int proc_terminate(pid_t pid, int *sig);
-
-__END_DECLS
-
-#endif /*_LIBPROC_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#ifndef _LIBPROC_INTERNALH_
-#define _LIBPROC_INTERNALH_
-
-#include <TargetConditionals.h>
-
-#include <sys/cdefs.h>
-#include <libproc.h>
-
-__BEGIN_DECLS
-
-#if TARGET_OS_EMBEDDED
-
-#define PROC_SETCPU_ACTION_NONE 0
-#define PROC_SETCPU_ACTION_THROTTLE 1
-#define PROC_SETCPU_ACTION_SUSPEND 2
-#define PROC_SETCPU_ACTION_TERMINATE 3
-#define PROC_SETCPU_ACTION_NOTIFY 4
-
-int proc_setcpu_percentage(pid_t pid, int action, int percentage) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0);
-int proc_setcpu_deadline(pid_t pid, int action, uint64_t deadline) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0);
-int proc_setcpu_percentage_withdeadline(pid_t pid, int action, int percentage, uint64_t deadline) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0);
-int proc_clear_cpulimits(pid_t pid) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0);
-
-#define PROC_APPSTATE_NONE 0
-#define PROC_APPSTATE_ACTIVE 1
-#define PROC_APPSTATE_BACKGROUND 2
-#define PROC_APPSTATE_NONUI 3
-#define PROC_APPSTATE_INACTIVE 4
-
-int proc_setappstate(int pid, int appstate);
-int proc_appstate(int pid, int * appstatep);
-
-#define PROC_DEVSTATUS_SHORTTERM 1
-#define PROC_DEVSTATUS_LONGTERM 2
-
-int proc_devstatusnotify(int devicestatus);
-
-#define PROC_PIDBIND_CLEAR 0
-#define PROC_PIDBIND_SET 1
-int proc_pidbind(int pid, uint64_t threadid, int bind);
-
-
-#else /* TARGET_OS_EMBEDDED */
-
-/* resume the process suspend due to low VM resource */
-int proc_clear_vmpressure(pid_t pid);
-/* set self as the one who is going to resume suspended processes due to low VM. Need to be root */
-int proc_set_owner_vmpressure(void);
-
-/* mark yourself to delay idle sleep on disk IO */
-int proc_set_delayidlesleep(void);
-/* Reset yourself to delay idle sleep on disk IO, if already set */
-int proc_clear_delayidlesleep(void);
-
-
-/* sub policies for PROC_POLICY_APPTYPE */
-#define PROC_POLICY_OSX_APPTYPE_NONE 0
-#define PROC_POLICY_OSX_APPTYPE_TAL 1 /* TAL based launched */
-#define PROC_POLICY_OSX_APPTYPE_WIDGET 2 /* for dashboard client */
-#define PROC_POLICY_OSX_APPTYPE_DASHCLIENT 2 /* rename to move away from widget */
-
-/*
- * Resumes the backgrounded TAL or dashboard client. Only priv users can disable TAL apps.
- * Valid apptype are PROC_POLICY_OSX_APPTYPE_DASHCLIENT and PROC_POLICY_OSX_APPTYPE_TAL.
- * Returns 0 on success otherwise appropriate error code.
- */
-int proc_disable_apptype(pid_t pid, int apptype);
-int proc_enable_apptype(pid_t pid, int apptype);
-
-#endif /* TARGET_OS_EMBEDDED */
-
-__END_DECLS
-
-#endif /* _LIBPROC_INTERNALH_ */
-
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/fcntl.h>
-#include <sys/errno.h>
-#include <sys/param.h>
-#include <sys/mount.h>
-#include <libproc.h>
-
-
-typedef struct {
- // process IDs
- int *pids;
- int pids_count;
- size_t pids_size;
-
- // threads
- uint64_t *threads;
- int thr_count;
- size_t thr_size;
-
- // open file descriptors
- struct proc_fdinfo *fds;
- int fds_count;
- size_t fds_size;
-
- // file/volume of interest
- struct stat match_stat;
-
- // flags
- uint32_t flags;
-
-} fdOpenInfo, *fdOpenInfoRef;
-
-
-/*
- * check_init
- */
-static fdOpenInfoRef
-check_init(const char *path, uint32_t flags)
-{
- fdOpenInfoRef info;
- int status;
-
- info = malloc(sizeof(*info));
- if (!info)
- return NULL;
-
- info->pids = NULL;
- info->pids_count = 0;
- info->pids_size = 0;
-
- info->threads = NULL;
- info->thr_count = 0;
- info->thr_size = 0;
-
- info->fds = NULL;
- info->fds_count = 0;
- info->fds_size = 0;
-
- status = stat(path, &info->match_stat);
- if (status == -1) {
- goto fail;
- }
-
- info->flags = flags;
-
- return info;
-
- fail :
-
- free(info);
- return NULL;
-}
-
-
-/*
- * check_free
- */
-static void
-check_free(fdOpenInfoRef info)
-{
- if (info->pids != NULL) {
- free(info->pids);
- }
-
- if (info->threads != NULL) {
- free(info->threads);
- }
-
- if (info->fds != NULL) {
- free(info->fds);
- }
-
- free(info);
-
- return;
-}
-
-
-/*
- * check_file
- * check if a process vnode is of interest
- *
- * in : vnode stat(2)
- * out : -1 if error
- * 0 if no match
- * 1 if match
- */
-static int
-check_file(fdOpenInfoRef info, struct vinfo_stat *sb)
-{
- if (sb->vst_dev == 0) {
- // if no info
- return 0;
- }
-
- if (sb->vst_dev != info->match_stat.st_dev) {
- // if not the requested filesystem
- return 0;
- }
-
- if (!(info->flags & PROC_LISTPIDSPATH_PATH_IS_VOLUME) &&
- (sb->vst_ino != info->match_stat.st_ino)) {
- // if not the requested file
- return 0;
- }
-
- return 1;
-}
-
-
-/*
- * check_process_vnodes
- * check [process] current working directory
- * check [process] root directory
- *
- * in : pid
- * out : -1 if error
- * 0 if no match
- * 1 if match
- */
-static int
-check_process_vnodes(fdOpenInfoRef info, int pid)
-{
- int buf_used;
- int status;
- struct proc_vnodepathinfo vpi;
-
- buf_used = proc_pidinfo(pid, PROC_PIDVNODEPATHINFO, 0, &vpi, sizeof(vpi));
- if (buf_used <= 0) {
- if (errno == ESRCH) {
- // if the process is gone
- return 0;
- }
- return -1;
- } else if (buf_used < sizeof(vpi)) {
- // if we didn't get enough information
- return -1;
- }
-
- // processing current working directory
- status = check_file(info, &vpi.pvi_cdir.vip_vi.vi_stat);
- if (status != 0) {
- // if error or match
- return status;
- }
-
- // processing root directory
- status = check_file(info, &vpi.pvi_rdir.vip_vi.vi_stat);
- if (status != 0) {
- // if error or match
- return status;
- }
-
- return 0;
-}
-
-
-/*
- * check_process_text
- * check [process] text (memory)
- *
- * in : pid
- * out : -1 if error
- * 0 if no match
- * 1 if match
- */
-static int
-check_process_text(fdOpenInfoRef info, int pid)
-{
- uint64_t a = 0;
- int status;
-
- while (1) { // for all memory regions
- int buf_used;
- struct proc_regionwithpathinfo rwpi;
-
- // processing next address
- buf_used = proc_pidinfo(pid, PROC_PIDREGIONPATHINFO, a, &rwpi, sizeof(rwpi));
- if (buf_used <= 0) {
- if ((errno == ESRCH) || (errno == EINVAL)) {
- // if no more text information is available for this process.
- break;
- }
- return -1;
- } else if (buf_used < sizeof(rwpi)) {
- // if we didn't get enough information
- return -1;
- }
-
- status = check_file(info, &rwpi.prp_vip.vip_vi.vi_stat);
- if (status != 0) {
- // if error or match
- return status;
- }
-
- a = rwpi.prp_prinfo.pri_address + rwpi.prp_prinfo.pri_size;
- }
-
- return 0;
-}
-
-
-/*
- * check_process_fds
- * check [process] open file descriptors
- *
- * in : pid
- * out : -1 if error
- * 0 if no match
- * 1 if match
- */
-static int
-check_process_fds(fdOpenInfoRef info, int pid)
-{
- int buf_used;
- int i;
- int status;
-
- // get list of open file descriptors
- buf_used = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
- if (buf_used <= 0) {
- return -1;
- }
-
- while (1) {
- if (buf_used > info->fds_size) {
- // if we need to allocate [more] space
- while (buf_used > info->fds_size) {
- info->fds_size += (sizeof(struct proc_fdinfo) * 32);
- }
-
- if (info->fds == NULL) {
- info->fds = malloc(info->fds_size);
- } else {
- info->fds = reallocf(info->fds, info->fds_size);
- }
- if (info->fds == NULL) {
- return -1;
- }
- }
-
- buf_used = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info->fds, info->fds_size);
- if (buf_used <= 0) {
- return -1;
- }
-
- if ((buf_used + sizeof(struct proc_fdinfo)) >= info->fds_size) {
- // if not enough room in the buffer for an extra fd
- buf_used = info->fds_size + sizeof(struct proc_fdinfo);
- continue;
- }
-
- info->fds_count = buf_used / sizeof(struct proc_fdinfo);
- break;
- }
-
- // iterate through each file descriptor
- for (i = 0; i < info->fds_count; i++) {
- struct proc_fdinfo *fdp;
-
- fdp = &info->fds[i];
- switch (fdp->proc_fdtype) {
- case PROX_FDTYPE_VNODE : {
- int buf_used;
- struct vnode_fdinfo vi;
-
- buf_used = proc_pidfdinfo(pid, fdp->proc_fd, PROC_PIDFDVNODEINFO, &vi, sizeof(vi));
- if (buf_used <= 0) {
- if (errno == ENOENT) {
- /*
- * The file descriptor's vnode may have been revoked. This is a
- * bit of a hack, since an ENOENT error might not always mean the
- * descriptor's vnode has been revoked. As the libproc API
- * matures, this code may need to be revisited.
- */
- continue;
- }
- return -1;
- } else if (buf_used < sizeof(vi)) {
- // if we didn't get enough information
- return -1;
- }
-
- if ((info->flags & PROC_LISTPIDSPATH_EXCLUDE_EVTONLY) &&
- (vi.pfi.fi_openflags & O_EVTONLY)) {
- // if this file should be excluded
- continue;
- }
-
- status = check_file(info, &vi.pvi.vi_stat);
- if (status != 0) {
- // if error or match
- return status;
- }
- break;
- }
- default :
- break;
- }
- }
-
- return 0;
-}
-
-
-/*
- * check_process_threads
- * check [process] thread working directories
- *
- * in : pid
- * out : -1 if error
- * 0 if no match
- * 1 if match
- */
-static int
-check_process_threads(fdOpenInfoRef info, int pid)
-{
- int buf_used;
- int status;
- struct proc_taskallinfo tai;
-
- buf_used = proc_pidinfo(pid, PROC_PIDTASKALLINFO, 0, &tai, sizeof(tai));
- if (buf_used <= 0) {
- if (errno == ESRCH) {
- // if the process is gone
- return 0;
- }
- return -1;
- } else if (buf_used < sizeof(tai)) {
- // if we didn't get enough information
- return -1;
- }
-
- // check thread info
- if (tai.pbsd.pbi_flags & PROC_FLAG_THCWD) {
- int i;
-
- // get list of threads
- buf_used = tai.ptinfo.pti_threadnum * sizeof(uint64_t);
-
- while (1) {
- if (buf_used > info->thr_size) {
- // if we need to allocate [more] space
- while (buf_used > info->thr_size) {
- info->thr_size += (sizeof(uint64_t) * 32);
- }
-
- if (info->threads == NULL) {
- info->threads = malloc(info->thr_size);
- } else {
- info->threads = reallocf(info->threads, info->thr_size);
- }
- if (info->threads == NULL) {
- return -1;
- }
- }
-
- buf_used = proc_pidinfo(pid, PROC_PIDLISTTHREADS, 0, info->threads, info->thr_size);
- if (buf_used <= 0) {
- return -1;
- }
-
- if ((buf_used + sizeof(uint64_t)) >= info->thr_size) {
- // if not enough room in the buffer for an extra thread
- buf_used = info->thr_size + sizeof(uint64_t);
- continue;
- }
-
- info->thr_count = buf_used / sizeof(uint64_t);
- break;
- }
-
- // iterate through each thread
- for (i = 0; i < info->thr_count; i++) {
- uint64_t thr = info->threads[i];
- struct proc_threadwithpathinfo tpi;
-
- buf_used = proc_pidinfo(pid, PROC_PIDTHREADPATHINFO, thr, &tpi, sizeof(tpi));
- if (buf_used <= 0) {
- if ((errno == ESRCH) || (errno == EINVAL)) {
- // if the process or thread is gone
- continue;
- }
- } else if (buf_used < sizeof(tai)) {
- // if we didn't get enough information
- return -1;
- }
-
- status = check_file(info, &tpi.pvip.vip_vi.vi_stat);
- if (status != 0) {
- // if error or match
- return status;
- }
- }
- }
-
- return 0;
-}
-
-
-/*
- * check_process
- * check [process] current working and root directories
- * check [process] text (memory)
- * check [process] open file descriptors
- *
- * in : pid
- * out : -1 if error
- * 0 if no match
- * 1 if match
- */
-static int
-check_process(fdOpenInfoRef info, int pid)
-{
- int status;
-
- // check root and current working directory
- status = check_process_vnodes(info, pid);
- if (status != 0) {
- // if error or match
- return status;
- }
-
- // check process text (memory)
- status = check_process_text(info, pid);
- if (status != 0) {
- // if error or match
- return status;
- }
-
- // check open file descriptors
- status = check_process_fds(info, pid);
- if (status != 0) {
- // if error or match
- return status;
- }
-
- // check per-thread working directories
- status = check_process_threads(info, pid);
- if (status != 0) {
- // if error or match
- return status;
- }
-
- return 0;
-}
-
-
-/*
- * proc_listpidspath
- *
- * in : type
- * : typeinfo
- * : path
- * : pathflags
- * : buffer
- * : buffersize
- * out : buffer filled with process IDs that have open file
- * references that match the specified path or volume;
- * return value is the bytes of the returned buffer
- * that contains valid information.
- */
-int
-proc_listpidspath(uint32_t type,
- uint32_t typeinfo,
- const char *path,
- uint32_t pathflags,
- void *buffer,
- int buffersize)
-{
- int buf_used;
- int *buf_next = (int *)buffer;
- int i;
- fdOpenInfoRef info;
- int status = -1;
-
- if (buffer == NULL) {
- // if this is a sizing request
- return proc_listpids(type, typeinfo, NULL, 0);
- }
-
- buffersize -= (buffersize % sizeof(int)); // make whole number of ints
- if (buffersize < sizeof(int)) {
- // if we can't even return a single PID
- errno = ENOMEM;
- return -1;
- }
-
- // init
- info = check_init(path, pathflags);
- if (info == NULL) {
- return -1;
- }
-
- // get list of processes
- buf_used = proc_listpids(type, typeinfo, NULL, 0);
- if (buf_used <= 0) {
- goto done;
- }
-
- while (1) {
- if (buf_used > info->pids_size) {
- // if we need to allocate [more] space
- while (buf_used > info->pids_size) {
- info->pids_size += (sizeof(int) * 32);
- }
-
- if (info->pids == NULL) {
- info->pids = malloc(info->pids_size);
- } else {
- info->pids = reallocf(info->pids, info->pids_size);
- }
- if (info->pids == NULL) {
- goto done;
- }
- }
-
- buf_used = proc_listpids(type, typeinfo, info->pids, info->pids_size);
- if (buf_used <= 0) {
- goto done;
- }
-
- if ((buf_used + sizeof(int)) >= info->pids_size) {
- // if not enough room in the buffer for an extra pid
- buf_used = info->pids_size + sizeof(int);
- continue;
- }
-
- info->pids_count = buf_used / sizeof(int);
- break;
- }
-
- // iterate through each process
- buf_used = 0;
- for (i = info->pids_count - 1; i >= 0; i--) {
- int pid;
- int status;
-
- pid = info->pids[i];
- if (pid == 0) {
- continue;
- }
-
- status = check_process(info, pid);
- if (status != 1) {
- // if not a match
- continue;
- }
-
- *buf_next++ = pid;
- buf_used += sizeof(int);
-
- if (buf_used >= buffersize) {
- // if we have filled the buffer
- break;
- }
- }
-
- status = buf_used;
-
- done :
-
- // cleanup
- check_free(info);
-
- return status;
-}
* NULL on failure
*/
extern DBM *
-dbm_open(file, flags, mode)
- const char *file;
- int flags;
- mode_t mode;
+dbm_open(const char *file, int flags, mode_t mode)
{
HASHINFO info;
char path[MAXPATHLEN];
/* Walk the lru chain, flushing any dirty pages to disk. */
TAILQ_FOREACH(bp, &mp->lqh, q) {
- if (bp->flags & MPOOL_DIRTY)
+ if (bp->flags & MPOOL_DIRTY) {
if (mpool_write(mp, bp) == RET_ERROR) {
return (RET_ERROR);
} else {
if (mp->pgin != NULL)
(mp->pgin)(mp->pgcookie, bp->pgno, bp->page);
}
+ }
}
/* Sync the file descriptor. */
#include <mach/mach.h> /* for vm_allocate, vm_offset_t */
#include <mach/vm_statistics.h>
#include <errno.h>
+#include <unistd.h>
static int sbrk_needs_init = TRUE;
static vm_size_t sbrk_region_size = 4*1024*1024; /* Well, what should it be? */
return((void *)(sbrk_curbrk - size));
}
-void *brk(void *x)
+void *brk(const void *x)
{
errno = ENOMEM;
return((void *)-1);
#define _LIBC_PRIVATE_H_
#ifdef __APPLE__
-#define __isthreaded __is_threaded
-#endif // __APPLE__
-
+#define __isthreaded 1
+#else
/*
* This global flag is non-zero when a process has created one
* or more threads. It is used to avoid calling locking functions
* when they are not required.
*/
extern int __isthreaded;
+#endif // __APPLE__
/*
* File lock contention is difficult to diagnose without knowing
int
#ifdef KR_headers
gethex(sp, fpi, exp, bp, sign, loc)
- CONST char **sp; FPI *fpi; Long *exp; Bigint **bp; int sign; locale_t loc;
+ CONST char **sp; CONST FPI *fpi; Long *exp; Bigint **bp; int sign; locale_t loc;
#else
-gethex( CONST char **sp, FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t loc)
+gethex( CONST char **sp, CONST FPI *fpi, Long *exp, Bigint **bp, int sign, locale_t loc)
#endif
{
Bigint *b;
#include "gdtoaimp.h"
- unsigned char hexdig[256];
+CONST unsigned char hexdig[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0, 0, 0, 0, 0, 0,
+ 0, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+};
+#ifndef __APPLE__
static void
#ifdef KR_headers
htinit(h, s, inc) unsigned char *h; unsigned char *s; int inc;
htinit(hexdig, USC "abcdef", 0x10 + 10);
htinit(hexdig, USC "ABCDEF", 0x10 + 10);
}
+#else
+void hexdig_init_D2A(void) {}
+#endif
int
#ifdef KR_headers
hexnan(sp, fpi, x0)
- CONST char **sp; FPI *fpi; ULong *x0;
+ CONST char **sp; CONST FPI *fpi; ULong *x0;
#else
-hexnan( CONST char **sp, FPI *fpi, ULong *x0)
+hexnan( CONST char **sp, CONST FPI *fpi, ULong *x0)
#endif
{
#ifdef __APPLE__
if (*s == '0') {
#ifndef NO_HEX_FP /*{*/
{
- static FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
+ static CONST FPI fpi = { 53, 1-1023-53+1, 2046-1023-53+1, 1, SI };
Long exp;
ULong bits[2];
switch(s[1]) {
#ifdef INFNAN_CHECK
/* Check for Nan and Infinity */
ULong bits[2];
- static FPI fpinan = /* only 52 explicit bits */
+ static CONST FPI fpinan = /* only 52 explicit bits */
{ 52, 1-1023-53+1, 2046-1023-53+1, 1, SI };
if (!decpt)
switch(c) {
extern CONST int fivesbits[];
int all_on(Bigint *b, int n);
Bigint *set_ones(Bigint *b, int n);
-int rvOK(U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv);
+int rvOK(U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv);
int mantbits(U *d);
#else /* !BUILDING_VARIANT */
rvOK
#ifdef KR_headers
(d, fpi, exp, bits, exact, rd, irv)
- U *d; FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv;
+ U *d; CONST FPI *fpi; Long *exp; ULong *bits; int exact, rd, *irv;
#else
- (U *d, FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv)
+ (U *d, CONST FPI *fpi, Long *exp, ULong *bits, int exact, int rd, int *irv)
#endif
{
Bigint *b;
strtodg
#ifdef KR_headers
(s00, se, fpi, exp, bits, loc)
- CONST char *s00; char **se; FPI *fpi; Long *exp; ULong *bits; locale_t loc;
+ CONST char *s00; char **se; CONST FPI *fpi; Long *exp; ULong *bits; locale_t loc;
#else
- (CONST char *s00, char **se, FPI *fpi, Long *exp, ULong *bits, locale_t loc)
+ (CONST char *s00, char **se, CONST FPI *fpi, Long *exp, ULong *bits, locale_t loc)
#endif
{
int abe, abits, asub;
strtof_l(CONST char *s, char **sp, locale_t loc)
#endif
{
- static FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
+ static CONST FPI fpi0 = { 24, 1-127-24+1, 254-127-24+1, 1, SI };
ULong bits[1];
Long exp;
int k;
#endif
{
#ifdef Sudden_Underflow
- static FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
+ static CONST FPI fpi0 = { 106, 1-1023, 2046-1023-106+1, 1, 1 };
#else
- static FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
+ static CONST FPI fpi0 = { 106, 1-1023-53+1, 2046-1023-106+1, 1, 0 };
#endif
ULong bits[4];
Long exp;
extern void freedtoa ANSI((char*));
extern float strtof ANSI((CONST char *, char **));
extern double strtod ANSI((CONST char *, char **));
-extern int strtodg ANSI((CONST char*, char**, FPI*, Long*, ULong*, locale_t)) __DARWIN_ALIAS(strtodg);
+extern int strtodg ANSI((CONST char*, char**, CONST FPI*, Long*, ULong*, locale_t)) __DARWIN_ALIAS(strtodg);
extern char* g_ddfmt ANSI((char*, double*, int, size_t));
extern char* g_dfmt ANSI((char*, double*, int, size_t));
- FPI *fpi, fpi1;
+ CONST FPI *fpi;
+ FPI fpi1;
int Rounding;
#ifdef Trust_FLT_ROUNDS /*{{ only define this if FLT_ROUNDS really works! */
Rounding = Flt_Rounds;
extern char *dtoa_result;
extern CONST double bigtens[], tens[], tinytens[];
- extern unsigned char hexdig[];
+ extern CONST unsigned char hexdig[];
extern Bigint *Balloc ANSI((int));
extern void Bfree ANSI((Bigint*));
extern char *dtoa ANSI((double d, int mode, int ndigits,
int *decpt, int *sign, char **rve));
extern char *g__fmt ANSI((char*, char*, char*, int, ULong, size_t));
- extern int gethex ANSI((CONST char**, FPI*, Long*, Bigint**, int, locale_t));
+ extern int gethex ANSI((CONST char**, CONST FPI*, Long*, Bigint**, int, locale_t));
extern void hexdig_init_D2A(Void);
- extern int hexnan ANSI((CONST char**, FPI*, ULong*));
+ extern int hexnan ANSI((CONST char**, CONST FPI*, ULong*));
extern int hi0bits_D2A ANSI((ULong));
extern Bigint *i2b ANSI((int));
extern Bigint *increment ANSI((Bigint*));
240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255
}
};
-static int rs_initialized;
static int rs_stired;
static int arc4_count;
* otherwise use \x (x is value)
* (NUL isn't used)
*/
-static unsigned char escape[256] = {
+static const unsigned char escape[256] = {
/* NUL */
0, /* Unused: strings can't contain nulls */
/* SOH STX ETX EOT ENQ ACK BEL */
fprintf(_e_err_file, ": ");
}
fprintf(_e_err_file, "%s\n", strerror(code));
- if (_e_err_exit.type)
+ if (_e_err_exit.type) {
#ifdef __BLOCKS__
- if (_e_err_exit.type == ERR_EXIT_BLOCK)
+ if (_e_err_exit.type == ERR_EXIT_BLOCK) {
_e_err_exit.block(eval);
- else
-#endif /* __BLOCKS__ */
+ } else {
_e_err_exit.func(eval);
+ }
+#else
+ _e_err_exit.func(eval);
+#endif /* __BLOCKS__ */
+ }
exit(eval);
}
if (fmt != NULL)
_e_visprintf(_e_err_file, fmt, ap);
fprintf(_e_err_file, "\n");
- if (_e_err_exit.type)
+ if (_e_err_exit.type) {
#ifdef __BLOCKS__
- if (_e_err_exit.type == ERR_EXIT_BLOCK)
+ if (_e_err_exit.type == ERR_EXIT_BLOCK) {
_e_err_exit.block(eval);
- else
-#endif /* __BLOCKS__ */
+ } else {
_e_err_exit.func(eval);
+ }
+#else
+ _e_err_exit.func(eval);
+#endif /* __BLOCKS__ */
+ }
exit(eval);
}
*sevinfo(int);
static int validmsgverb(const char *);
-static const char *validlist[] = {
+static const char * const validlist[] = {
"label", "severity", "text", "action", "tag", NULL
};
pattern++;
else if (*pattern == '[' && ((special = *(pattern + 1)) == '.' || special == '=' || special == ':')) {
cp = (pattern += 2);
- while(cp = strchr(cp, special)) {
+ while((cp = strchr(cp, special))) {
if (*(cp + 1) == ']')
break;
cp++;
*(cp + 3) != ']')
return (RANGE_ERROR);
len = __collate_equiv_match(ec, NULL, 0, test, string, strlen(string), strmbs, &sclen, loc);
- if (len < 0)
+ if (len == (size_t)-1) {
return (RANGE_ERROR);
+ }
if (len > 0) {
ok = 1;
string += sclen;
if (c2 == EOS)
return (RANGE_ERROR);
- if (c2 == '[' && (special = *pattern) == '.' || special == '=' || special == ':') {
+ if ((c2 == '[' && (special = *pattern) == '.') || special == '=' || special == ':') {
/* no equivalence classes or character classes as end of range */
if (special == '=' || special == ':')
return (RANGE_ERROR);
cp = ++pattern;
- while(cp = strchr(cp, special)) {
+ while((cp = strchr(cp, special))) {
if (*(cp + 1) == ']')
break;
cp++;
+++ /dev/null
-.\" Copyright (c) 2002 Packet Design, LLC.
-.\" All rights reserved.
-.\"
-.\" Subject to the following obligations and disclaimer of warranty,
-.\" use and redistribution of this software, in source or object code
-.\" forms, with or without modifications are expressly permitted by
-.\" Packet Design; provided, however, that:
-.\"
-.\" (i) Any and all reproductions of the source or object code
-.\" must include the copyright notice above and the following
-.\" disclaimer of warranties; and
-.\" (ii) No rights are granted, in any manner or form, to use
-.\" Packet Design trademarks, including the mark "PACKET DESIGN"
-.\" on advertising, endorsements, or otherwise except as such
-.\" appears in the above copyright notice or in the software.
-.\"
-.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
-.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
-.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
-.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
-.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
-.\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
-.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
-.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
-.\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
-.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
-.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
-.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
-.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
-.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
-.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-.\" THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
-.\" THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc/gen/getcontext.3,v 1.3 2004/12/03 14:10:04 rse Exp $
-.\"
-.Dd September 10, 2002
-.Dt GETCONTEXT 3
-.Os
-.Sh NAME
-.Nm getcontext , setcontext
-.Nd get and set user thread context
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In ucontext.h
-.Ft int
-.Fn getcontext "ucontext_t *ucp"
-.Ft int
-.Fn setcontext "const ucontext_t *ucp"
-.Sh DESCRIPTION
-The
-.Fn getcontext
-function
-saves the current thread's execution context in the structure pointed to by
-.Fa ucp .
-This saved context may then later be restored by calling
-.Fn setcontext .
-.Pp
-The
-.Fn setcontext
-function
-makes a previously saved thread context the current thread context, i.e.,
-the current context is lost and
-.Fn setcontext
-does not return.
-Instead, execution continues in the context specified by
-.Fa ucp ,
-which must have been previously initialized by a call to
-.Fn getcontext ,
-.Xr makecontext 3 ,
-or by being passed as an argument to a signal handler (see
-.Xr sigaction 2 ) .
-.Pp
-If
-.Fa ucp
-was initialized by
-.Fn getcontext ,
-then execution continues as if the original
-.Fn getcontext
-call had just returned (again).
-.Pp
-If
-.Fa ucp
-was initialized by
-.Xr makecontext 3 ,
-execution continues with the invocation of the function specified to
-.Xr makecontext 3 .
-When that function returns,
-.Fa "ucp->uc_link"
-determines what happens next:
-if
-.Fa "ucp->uc_link"
-is
-.Dv NULL ,
-the process exits;
-otherwise,
-.Fn setcontext "ucp->uc_link"
-is implicitly invoked.
-.Pp
-If
-.Fa ucp
-was initialized by the invocation of a signal handler, execution continues
-at the point the thread was interrupted by the signal.
-.Sh RETURN VALUES
-If successful,
-.Fn getcontext
-returns zero and
-.Fn setcontext
-does not return; otherwise \-1 is returned.
-.Sh ERRORS
-No errors are defined for
-.Fn getcontext
-or
-.Fn setcontext .
-.Sh SEE ALSO
-.Xr sigaction 2 ,
-.Xr sigaltstack 2 ,
-.Xr makecontext 3 ,
-.Xr ucontext 3
ino_t root_ino;
size_t ptsize, upsize;
int save_errno;
- char *ept, *eup, *up, c;
+ char *ept, *eup, *up;
/*
* If no buffer specified by the user, allocate one as necessary.
#include "libc_private.h"
-#define THREAD_LOCK() if (__isthreaded) _pthread_mutex_lock(&logname_mutex)
-#define THREAD_UNLOCK() if (__isthreaded) _pthread_mutex_unlock(&logname_mutex)
+extern int __getlogin(char *, int);
-extern int __getlogin(char *, int);
-
-int _logname_valid; /* known to setlogin() */
-static pthread_mutex_t logname_mutex = PTHREAD_MUTEX_INITIALIZER;
+__private_extern__ pthread_mutex_t __logname_mutex = PTHREAD_MUTEX_INITIALIZER;
+__private_extern__ char *__logname = NULL;
static char *
getlogin_basic(int *status)
{
- static char logname[MAXLOGNAME];
+ if (__logname == NULL) {
+ __logname = calloc(1, MAXLOGNAME);
+ if (__logname == NULL) {
+ *status = ENOMEM;
+ return (NULL);
+ }
+ }
- if (_logname_valid == 0) {
- if (__getlogin(logname, sizeof(logname)) < 0) {
+ if (__logname[0] == 0) {
+ if (__getlogin(__logname, MAXLOGNAME) < 0) {
*status = errno;
return (NULL);
}
- _logname_valid = 1;
}
*status = 0;
- return (*logname ? logname : NULL);
+ return (*__logname ? __logname : NULL);
}
char *
char *result;
int status;
- THREAD_LOCK();
+ pthread_mutex_lock(&__logname_mutex);
result = getlogin_basic(&status);
- THREAD_UNLOCK();
+ pthread_mutex_unlock(&__logname_mutex);
return (result);
}
char *result;
int len;
int status;
-
- THREAD_LOCK();
+
+ pthread_mutex_lock(&__logname_mutex);
result = getlogin_basic(&status);
if (status == 0) {
- if ((len = strlen(result) + 1) > namelen)
+ if (strlcpy(logname, __logname, namelen) > namelen) {
status = ERANGE;
- else
- strncpy(logname, result, len);
+ }
}
- THREAD_UNLOCK();
+ pthread_mutex_unlock(&__logname_mutex);
+
return (status);
}
+++ /dev/null
-.\" Copyright (c) 2002 Packet Design, LLC.
-.\" All rights reserved.
-.\"
-.\" Subject to the following obligations and disclaimer of warranty,
-.\" use and redistribution of this software, in source or object code
-.\" forms, with or without modifications are expressly permitted by
-.\" Packet Design; provided, however, that:
-.\"
-.\" (i) Any and all reproductions of the source or object code
-.\" must include the copyright notice above and the following
-.\" disclaimer of warranties; and
-.\" (ii) No rights are granted, in any manner or form, to use
-.\" Packet Design trademarks, including the mark "PACKET DESIGN"
-.\" on advertising, endorsements, or otherwise except as such
-.\" appears in the above copyright notice or in the software.
-.\"
-.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
-.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
-.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
-.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
-.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
-.\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
-.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
-.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
-.\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
-.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
-.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
-.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
-.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
-.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
-.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-.\" THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
-.\" THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc/gen/makecontext.3,v 1.4 2002/12/19 09:40:21 ru Exp $
-.\"
-.Dd September 10, 2002
-.Dt MAKECONTEXT 3
-.Os
-.Sh NAME
-.Nm makecontext , swapcontext
-.Nd modify and exchange user thread contexts
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In ucontext.h
-.Ft void
-.Fo makecontext
-.Fa "ucontext_t *ucp"
-.Fa "void \*[lp]*func\*[rp]\*[lp]\*[rp]"
-.Fa "int argc" ...
-.Fc
-.Ft int
-.Fn swapcontext "ucontext_t *oucp" "const ucontext_t *ucp"
-.Sh DESCRIPTION
-The
-.Fn makecontext
-function
-modifies the user thread context pointed to by
-.Fa ucp ,
-which must have previously been initialized by a call to
-.Xr getcontext 3
-and had a stack allocated for it.
-The context is modified so that it will continue execution by invoking
-.Fn func
-with the arguments (of type
-.Ft int )
-provided.
-The
-.Fa argc
-argument
-must be equal to the number of additional arguments provided to
-.Fn makecontext
-and also equal to the number of arguments to
-.Fn func ,
-or else the behavior is undefined.
-.Pp
-The
-.Fa "ucp->uc_link"
-argument
-must be initialized before calling
-.Fn makecontext
-and determines the action to take when
-.Fn func
-returns:
-if equal to
-.Dv NULL ,
-the process exits;
-otherwise,
-.Fn setcontext "ucp->uc_link"
-is implicitly invoked.
-.Pp
-The
-.Fn swapcontext
-function
-saves the current thread context in
-.Fa "*oucp"
-and makes
-.Fa "*ucp"
-the currently active context.
-.Sh RETURN VALUES
-If successful,
-.Fn swapcontext
-returns zero;
-otherwise \-1 is returned and the global variable
-.Va errno
-is set appropriately.
-.Sh ERRORS
-The
-.Fn swapcontext
-function
-will fail if:
-.Bl -tag -width Er
-.It Bq Er ENOMEM
-There is not enough stack space in
-.Fa ucp
-to complete the operation.
-.El
-.Sh SEE ALSO
-.Xr setcontext 3 ,
-.Xr ucontext 3
/*
* This sort must be stable.
*/
- mergesort(dpv, n, sizeof(*dpv), alphasort);
+ mergesort(dpv, n, sizeof(*dpv), (int (*)(const void *, const void *))alphasort);
dpv[n] = NULL;
xp = NULL;
* SUCH DAMAGE.
*/
+#if defined(VARIANT_CANCELABLE) && __DARWIN_NON_CANCELABLE != 0
+#error cancellable call vs. __DARWIN_NON_CANCELABLE mismatch
+#endif
+
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)pause.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
-/* For the cancelable variant, we call the cancelable sigsuspend */
-#ifdef VARIANT_CANCELABLE
-#undef __DARWIN_NON_CANCELABLE
-#define __DARWIN_NON_CANCELABLE 0
-#endif /* VARIANT_CANCELABLE */
-
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/lib/libc/gen/pause.c,v 1.8 2009/12/05 19:31:38 ed Exp $");
* SUCH DAMAGE.
*/
-#if defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050)
-#undef __DARWIN_NON_CANCELABLE
-#endif /* VARIANT_CANCELABLE */
+#if (defined(VARIANT_CANCELABLE) || defined(VARIANT_PRE1050)) && __DARWIN_NON_CANCELABLE != 0
+#error cancellable call vs. __DARWIN_NON_CANCELABLE mismatch
+#endif
#ifdef VARIANT_DARWINEXTSN
#define _DARWIN_UNLIMITED_SELECT
__weak_reference(__pselect, pselect);
+// Returns -1 and sets errno in contrast to pthread_sigmask which returns errno
+extern int __pthread_sigmask(int, const sigset_t *, sigset_t *);
+
/*
* Emulate the POSIX 1003.1g-2000 `pselect' interface. This is the
* same as the traditional BSD `select' function, except that it uses
tvp = 0;
if (mask != 0) {
- rv = _sigprocmask(SIG_SETMASK, mask, &omask);
+ rv = __pthread_sigmask(SIG_SETMASK, mask, &omask);
if (rv != 0)
return rv;
}
rv = _select(count, rfds, wfds, efds, tvp);
if (mask != 0) {
sverrno = errno;
- _sigprocmask(SIG_SETMASK, &omask, (sigset_t *)0);
+ __pthread_sigmask(SIG_SETMASK, &omask, (sigset_t *)0);
errno = sverrno;
}
char *
getpass(const char *prompt)
{
- static char buf[_PASSWORD_LEN + 1];
+ const size_t bufsiz = _PASSWORD_LEN + 1;
+ static char *buf = NULL;
- if (readpassphrase(prompt, buf, sizeof(buf), RPP_ECHO_OFF) == NULL)
+ if (buf == NULL) {
+ buf = malloc(bufsiz);
+ if (buf == NULL) {
+ return NULL;
+ }
+ }
+
+ if (readpassphrase(prompt, buf, bufsiz, RPP_ECHO_OFF) == NULL) {
buf[0] = '\0';
- return(buf);
+ }
+ return buf;
}
static void handler(int s)
It returns the number of entries in the array.
A pointer to the array of directory entries is stored in the location
referenced by
-.Fa namelist .
+.Fa namelist
+(even if the number of entries is 0).
.Pp
The
.Fa select
* SUCH DAMAGE.
*/
-#ifdef VARIANT_CANCELABLE
-#undef __DARWIN_NON_CANCELABLE
-#define __DARWIN_NON_CANCELABLE 0
-#endif /* VARIANT_CANCELABLE */
+#if defined(VARIANT_CANCELABLE) && __DARWIN_NON_CANCELABLE != 0
+#error cancellable call vs. __DARWIN_NON_CANCELABLE mismatch
+#endif
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)sleep.c 8.1 (Berkeley) 6/4/93";
as the standard
.Fn sysctl
function.
+For a list of ASCII representations of commonly used sysctl names, please see
+.Xr sysctl 1 .
.Pp
The information is copied into the buffer specified by
.Fa oldp .
definitions for fourth level UDP identifiers
.El
.Sh SEE ALSO
+.Xr sysctl 1 ,
.Xr sysconf 3 ,
.Xr sysctl 8
.Sh HISTORY
#if __DARWIN_UNIX03
#ifdef VARIANT_CANCELABLE
#include <pthread.h>
-
-extern void _pthread_testcancel(pthread_t thread, int isconforming);
#endif /* VARIANT_CANCELABLE */
#endif /* __DARWIN_UNIX03 */
{
#if __DARWIN_UNIX03
#ifdef VARIANT_CANCELABLE
- _pthread_testcancel(pthread_self(), 1);
+ pthread_testcancel();
#endif /* VARIANT_CANCELABLE */
#endif /* __DARWIN_UNIX03 */
return (_ioctl(fd, TIOCDRAIN, 0));
tcflow(fd, action)
int fd, action;
{
- struct termios term;
- u_char c;
-
switch (action) {
case TCOOFF:
return (_ioctl(fd, TIOCSTOP, 0));
+++ /dev/null
-.\" Copyright (c) 2002 Packet Design, LLC.
-.\" All rights reserved.
-.\"
-.\" Subject to the following obligations and disclaimer of warranty,
-.\" use and redistribution of this software, in source or object code
-.\" forms, with or without modifications are expressly permitted by
-.\" Packet Design; provided, however, that:
-.\"
-.\" (i) Any and all reproductions of the source or object code
-.\" must include the copyright notice above and the following
-.\" disclaimer of warranties; and
-.\" (ii) No rights are granted, in any manner or form, to use
-.\" Packet Design trademarks, including the mark "PACKET DESIGN"
-.\" on advertising, endorsements, or otherwise except as such
-.\" appears in the above copyright notice or in the software.
-.\"
-.\" THIS SOFTWARE IS BEING PROVIDED BY PACKET DESIGN "AS IS", AND
-.\" TO THE MAXIMUM EXTENT PERMITTED BY LAW, PACKET DESIGN MAKES NO
-.\" REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING
-.\" THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED
-.\" WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
-.\" OR NON-INFRINGEMENT. PACKET DESIGN DOES NOT WARRANT, GUARANTEE,
-.\" OR MAKE ANY REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS
-.\" OF THE USE OF THIS SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY,
-.\" RELIABILITY OR OTHERWISE. IN NO EVENT SHALL PACKET DESIGN BE
-.\" LIABLE FOR ANY DAMAGES RESULTING FROM OR ARISING OUT OF ANY USE
-.\" OF THIS SOFTWARE, INCLUDING WITHOUT LIMITATION, ANY DIRECT,
-.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE, OR CONSEQUENTIAL
-.\" DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, LOSS OF
-.\" USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY THEORY OF
-.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-.\" THE USE OF THIS SOFTWARE, EVEN IF PACKET DESIGN IS ADVISED OF
-.\" THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc/gen/ucontext.3,v 1.3 2004/07/03 22:30:08 ru Exp $
-.\"
-.Dd September 10, 2002
-.Dt UCONTEXT 3
-.Os
-.Sh NAME
-.Nm ucontext
-.Nd user thread context
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In ucontext.h
-.Sh DESCRIPTION
-The
-.Vt ucontext_t
-type is a structure type suitable for holding the context for a user
-thread of execution.
-A thread's context includes its stack, saved registers, and list of
-blocked signals.
-.Pp
-The
-.Vt ucontext_t
-structure contains at least these fields:
-.Pp
-.Bl -tag -width ".Va mcontext_t\ \ uc_mcontext" -offset 3n -compact
-.It Va "ucontext_t *uc_link"
-context to assume when this one returns
-.It Va "sigset_t uc_sigmask"
-signals being blocked
-.It Va "stack_t uc_stack"
-stack area
-.It Va "mcontext_t uc_mcontext"
-saved registers
-.El
-.Pp
-The
-.Va uc_link
-field points to the context to resume when this context's entry point
-function returns.
-If
-.Va uc_link
-is equal to
-.Dv NULL ,
-then the process exits when this context returns.
-.Pp
-The
-.Va uc_mcontext
-field is machine-dependent and should be treated as opaque by
-portable applications.
-.Pp
-The following functions are defined to manipulate
-.Vt ucontext_t
-structures:
-.Pp
-.Bl -item -offset 3n -compact
-.It
-.Ft int
-.Fn getcontext "ucontext_t *" ;
-.It
-.Ft int
-.Fn setcontext "const ucontext_t *" ;
-.It
-.Ft void
-.Fn makecontext "ucontext_t *" "void \*[lp]*\*[rp]\*[lp]void\*[rp]" int ... ;
-.It
-.Ft int
-.Fn swapcontext "ucontext_t *" "const ucontext_t *" ;
-.El
-.Sh SEE ALSO
-.Xr sigaltstack 2 ,
-.Xr getcontext 3 ,
-.Xr makecontext 3
* SUCH DAMAGE.
*/
-#ifdef VARIANT_CANCELABLE
-#undef __DARWIN_NON_CANCELABLE
-#define __DARWIN_NON_CANCELABLE 0
-#endif /* VARIANT_CANCELABLE */
+#if defined(VARIANT_CANCELABLE) && __DARWIN_NON_CANCELABLE != 0
+#error cancellable call vs. __DARWIN_NON_CANCELABLE mismatch
+#endif
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)usleep.c 8.1 (Berkeley) 6/4/93";
--- /dev/null
+/* $NetBSD: rb.c,v 1.11 2011/06/20 09:11:16 mrg Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <matt@3am-software.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <stddef.h>
+#include <assert.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+#undef RBSMALL
+#undef RBDEBUG
+#undef RBSTATS
+#undef RBTEST
+
+#define _RBTREE_NO_OPAQUE_STRUCTS_
+
+#ifdef RBTEST
+#include "rbtree.h"
+#else
+#include <sys/rbtree.h>
+#endif
+
+#ifndef __predict_false
+#ifdef __GNUC__
+#define __predict_false(x) ((typeof(x))__builtin_expect((long)(x), 0l))
+#else
+#define __predict_false(x) (x)
+#endif
+#endif
+
+#define RB_DIR_OTHER RB_DIR_RIGHT
+
+#define rb_left rb_nodes[RB_DIR_LEFT]
+#define rb_right rb_nodes[RB_DIR_RIGHT]
+
+#define RB_FLAG_POSITION 0x2
+#define RB_FLAG_RED 0x1
+#define RB_FLAG_MASK (RB_FLAG_POSITION|RB_FLAG_RED)
+#define RB_FATHER(rb) \
+ ((struct rb_node *)((rb)->rb_info & ~RB_FLAG_MASK))
+#define RB_SET_FATHER(rb, father) \
+ ((void)((rb)->rb_info = (uintptr_t)(father)|((rb)->rb_info & RB_FLAG_MASK)))
+
+#define RB_SENTINEL_P(rb) ((rb) == NULL)
+#define RB_LEFT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_left)
+#define RB_RIGHT_SENTINEL_P(rb) RB_SENTINEL_P((rb)->rb_right)
+#define RB_FATHER_SENTINEL_P(rb) RB_SENTINEL_P(RB_FATHER((rb)))
+#define RB_CHILDLESS_P(rb) \
+ (RB_SENTINEL_P(rb) || (RB_LEFT_SENTINEL_P(rb) && RB_RIGHT_SENTINEL_P(rb)))
+#define RB_TWOCHILDREN_P(rb) \
+ (!RB_SENTINEL_P(rb) && !RB_LEFT_SENTINEL_P(rb) && !RB_RIGHT_SENTINEL_P(rb))
+
+#define RB_POSITION(rb) \
+ (((rb)->rb_info & RB_FLAG_POSITION) ? RB_DIR_RIGHT : RB_DIR_LEFT)
+#define RB_RIGHT_P(rb) (RB_POSITION(rb) == RB_DIR_RIGHT)
+#define RB_LEFT_P(rb) (RB_POSITION(rb) == RB_DIR_LEFT)
+#define RB_RED_P(rb) (!RB_SENTINEL_P(rb) && ((rb)->rb_info & RB_FLAG_RED) != 0)
+#define RB_BLACK_P(rb) (RB_SENTINEL_P(rb) || ((rb)->rb_info & RB_FLAG_RED) == 0)
+#define RB_MARK_RED(rb) ((void)((rb)->rb_info |= RB_FLAG_RED))
+#define RB_MARK_BLACK(rb) ((void)((rb)->rb_info &= ~RB_FLAG_RED))
+#define RB_INVERT_COLOR(rb) ((void)((rb)->rb_info ^= RB_FLAG_RED))
+#define RB_ROOT_P(rbt, rb) ((rbt)->rbt_root == (rb))
+#define RB_SET_POSITION(rb, position) \
+ ((void)((position) ? ((rb)->rb_info |= RB_FLAG_POSITION) : \
+ ((rb)->rb_info &= ~RB_FLAG_POSITION)))
+#define RB_ZERO_PROPERTIES(rb) ((void)((rb)->rb_info &= ~RB_FLAG_MASK))
+#define RB_COPY_PROPERTIES(dst, src) \
+ ((void)((dst)->rb_info ^= ((dst)->rb_info ^ (src)->rb_info) & RB_FLAG_MASK))
+#define RB_SWAP_PROPERTIES(a, b) do { \
+ uintptr_t xorinfo = ((a)->rb_info ^ (b)->rb_info) & RB_FLAG_MASK; \
+ (a)->rb_info ^= xorinfo; \
+ (b)->rb_info ^= xorinfo; \
+ } while (/*CONSTCOND*/ 0)
+
+#ifndef static_assert
+#define _static_assert_concat_(a,b) a##b
+#define _static_assert_concat(a,b) _static_assert_concat_(a,b)
+#define static_assert(c, m) struct _static_assert_concat(static_assert_failure_, __LINE__) { int _static_assert_concat(static_assert_failure_, __LINE__)[(c)? 1 : -1]; }
+#endif
+
+/* The size of struct_rbnode must match:
+ * sizeof(struct rb_node { void * opaque[3] })
+ */
+typedef struct rb_node {
+ struct rb_node *rb_nodes[2];
+
+ /*
+ * rb_info contains the two flags and the parent back pointer.
+ * We put the two flags in the low two bits since we know that
+ * rb_node will have an alignment of 4 or 8 bytes.
+ */
+ uintptr_t rb_info;
+} rb_node_t;
+
+static_assert(sizeof(struct { void * opaque[3]; }) == sizeof(rb_node_t),
+ "Mismatch in size between opaque and internal rb_node_t");
+
+typedef struct rb_tree {
+ struct rb_node *rbt_root;
+ const rb_tree_ops_t *rbt_ops;
+ struct rb_node *rbt_minmax[2];
+ uintptr_t rbt_count;
+ void *unused[3]; // Unused padding for possible future use
+} rb_tree_t;
+
+static_assert(sizeof(struct { void * opaque[8]; }) == sizeof(rb_tree_t),
+ "Mismatch in size between opaque and internal rb_tree_t");
+
+static void rb_tree_insert_rebalance(struct rb_tree *, struct rb_node *);
+static void rb_tree_removal_rebalance(struct rb_tree *, struct rb_node *,
+ unsigned int);
+#ifdef RBDEBUG
+static const struct rb_node *rb_tree_iterate_const(const struct rb_tree *,
+ const struct rb_node *, const unsigned int);
+static bool rb_tree_check_node(const struct rb_tree *, const struct rb_node *,
+ const struct rb_node *, bool);
+
+TAILQ_HEAD(rb_node_qh, rb_node);
+
+#define RB_TAILQ_REMOVE(a, b, c) TAILQ_REMOVE(a, b, c)
+#define RB_TAILQ_INIT(a) TAILQ_INIT(a)
+#define RB_TAILQ_INSERT_HEAD(a, b, c) TAILQ_INSERT_HEAD(a, b, c)
+#define RB_TAILQ_INSERT_BEFORE(a, b, c) TAILQ_INSERT_BEFORE(a, b, c)
+#define RB_TAILQ_INSERT_AFTER(a, b, c, d) TAILQ_INSERT_AFTER(a, b, c, d)
+
+#define KASSERT(s) assert(s)
+#else
+
+#define rb_tree_check_node(a, b, c, d) true
+
+#define RB_TAILQ_REMOVE(a, b, c) do { } while (/*CONSTCOND*/0)
+#define RB_TAILQ_INIT(a) do { } while (/*CONSTCOND*/0)
+#define RB_TAILQ_INSERT_HEAD(a, b, c) do { } while (/*CONSTCOND*/0)
+#define RB_TAILQ_INSERT_BEFORE(a, b, c) do { } while (/*CONSTCOND*/0)
+#define RB_TAILQ_INSERT_AFTER(a, b, c, d) do { } while (/*CONSTCOND*/0)
+
+#define KASSERT(s) do { } while (/*CONSTCOND*/ 0)
+#endif
+
+#ifdef RBSTATS
+#define RBSTAT_INC(v) ((void)((v)++))
+#define RBSTAT_DEC(v) ((void)((v)--))
+#else
+#define RBSTAT_INC(v) do { } while (/*CONSTCOND*/0)
+#define RBSTAT_DEC(v) do { } while (/*CONSTCOND*/0)
+#endif
+
+#define RB_NODETOITEM(rbto, rbn) \
+ ((void *)((uintptr_t)(rbn) - (rbto)->rbto_node_offset))
+#define RB_ITEMTONODE(rbto, rbn) \
+ ((rb_node_t *)((uintptr_t)(rbn) + (rbto)->rbto_node_offset))
+
+#define RB_SENTINEL_NODE NULL
+
+void
+rb_tree_init(struct rb_tree *rbt, const rb_tree_ops_t *ops)
+{
+
+ rbt->rbt_ops = ops;
+ rbt->rbt_root = RB_SENTINEL_NODE;
+ RB_TAILQ_INIT(&rbt->rbt_nodes);
+#ifndef RBSMALL
+ rbt->rbt_minmax[RB_DIR_LEFT] = rbt->rbt_root; /* minimum node */
+ rbt->rbt_minmax[RB_DIR_RIGHT] = rbt->rbt_root; /* maximum node */
+#endif
+ rbt->rbt_count = 0;
+#ifdef RBSTATS
+ rbt->rbt_insertions = 0;
+ rbt->rbt_removals = 0;
+ rbt->rbt_insertion_rebalance_calls = 0;
+ rbt->rbt_insertion_rebalance_passes = 0;
+ rbt->rbt_removal_rebalance_calls = 0;
+ rbt->rbt_removal_rebalance_passes = 0;
+#endif
+}
+
+void *
+rb_tree_find_node(struct rb_tree *rbt, const void *key)
+{
+ const rb_tree_ops_t *rbto = rbt->rbt_ops;
+ rbto_compare_key_fn compare_key = rbto->rbto_compare_key;
+ struct rb_node *parent = rbt->rbt_root;
+
+ while (!RB_SENTINEL_P(parent)) {
+ void *pobj = RB_NODETOITEM(rbto, parent);
+ const signed int diff = (*compare_key)(rbto->rbto_context,
+ pobj, key);
+ if (diff == 0)
+ return pobj;
+ parent = parent->rb_nodes[diff < 0];
+ }
+
+ return NULL;
+}
+
+void *
+rb_tree_find_node_geq(struct rb_tree *rbt, const void *key)
+{
+ const rb_tree_ops_t *rbto = rbt->rbt_ops;
+ rbto_compare_key_fn compare_key = rbto->rbto_compare_key;
+ struct rb_node *parent = rbt->rbt_root, *last = NULL;
+
+ while (!RB_SENTINEL_P(parent)) {
+ void *pobj = RB_NODETOITEM(rbto, parent);
+ const signed int diff = (*compare_key)(rbto->rbto_context,
+ pobj, key);
+ if (diff == 0)
+ return pobj;
+ if (diff > 0)
+ last = parent;
+ parent = parent->rb_nodes[diff < 0];
+ }
+
+ return RB_NODETOITEM(rbto, last);
+}
+
+void *
+rb_tree_find_node_leq(struct rb_tree *rbt, const void *key)
+{
+ const rb_tree_ops_t *rbto = rbt->rbt_ops;
+ rbto_compare_key_fn compare_key = rbto->rbto_compare_key;
+ struct rb_node *parent = rbt->rbt_root, *last = NULL;
+
+ while (!RB_SENTINEL_P(parent)) {
+ void *pobj = RB_NODETOITEM(rbto, parent);
+ const signed int diff = (*compare_key)(rbto->rbto_context,
+ pobj, key);
+ if (diff == 0)
+ return pobj;
+ if (diff < 0)
+ last = parent;
+ parent = parent->rb_nodes[diff < 0];
+ }
+
+ return RB_NODETOITEM(rbto, last);
+}
+
+void *
+rb_tree_insert_node(struct rb_tree *rbt, void *object)
+{
+ const rb_tree_ops_t *rbto = rbt->rbt_ops;
+ rbto_compare_nodes_fn compare_nodes = rbto->rbto_compare_nodes;
+ struct rb_node *parent, *tmp, *self = RB_ITEMTONODE(rbto, object);
+ unsigned int position;
+ bool rebalance;
+
+ RBSTAT_INC(rbt->rbt_insertions);
+
+ tmp = rbt->rbt_root;
+ /*
+ * This is a hack. Because rbt->rbt_root is just a struct rb_node *,
+ * just like rb_node->rb_nodes[RB_DIR_LEFT], we can use this fact to
+ * avoid a lot of tests for root and know that even at root,
+ * updating RB_FATHER(rb_node)->rb_nodes[RB_POSITION(rb_node)] will
+ * update rbt->rbt_root.
+ */
+ parent = (struct rb_node *)(void *)&rbt->rbt_root;
+ position = RB_DIR_LEFT;
+
+ /*
+ * Find out where to place this new leaf.
+ */
+ while (!RB_SENTINEL_P(tmp)) {
+ void *tobj = RB_NODETOITEM(rbto, tmp);
+ const signed int diff = (*compare_nodes)(rbto->rbto_context,
+ tobj, object);
+ if (__predict_false(diff == 0)) {
+ /*
+ * Node already exists; return it.
+ */
+ return tobj;
+ }
+ parent = tmp;
+ position = (diff < 0);
+ tmp = parent->rb_nodes[position];
+ }
+
+#ifdef RBDEBUG
+ {
+ struct rb_node *prev = NULL, *next = NULL;
+
+ if (position == RB_DIR_RIGHT)
+ prev = parent;
+ else if (tmp != rbt->rbt_root)
+ next = parent;
+
+ /*
+ * Verify our sequential position
+ */
+ KASSERT(prev == NULL || !RB_SENTINEL_P(prev));
+ KASSERT(next == NULL || !RB_SENTINEL_P(next));
+ if (prev != NULL && next == NULL)
+ next = TAILQ_NEXT(prev, rb_link);
+ if (prev == NULL && next != NULL)
+ prev = TAILQ_PREV(next, rb_node_qh, rb_link);
+ KASSERT(prev == NULL || !RB_SENTINEL_P(prev));
+ KASSERT(next == NULL || !RB_SENTINEL_P(next));
+ KASSERT(prev == NULL || (*compare_nodes)(rbto->rbto_context,
+ RB_NODETOITEM(rbto, prev), RB_NODETOITEM(rbto, self)) < 0);
+ KASSERT(next == NULL || (*compare_nodes)(rbto->rbto_context,
+ RB_NODETOITEM(rbto, self), RB_NODETOITEM(rbto, next)) < 0);
+ }
+#endif
+
+ /*
+ * Initialize the node and insert as a leaf into the tree.
+ */
+ RB_SET_FATHER(self, parent);
+ RB_SET_POSITION(self, position);
+ if (__predict_false(parent == (struct rb_node *)(void *)&rbt->rbt_root)) {
+ RB_MARK_BLACK(self); /* root is always black */
+#ifndef RBSMALL
+ rbt->rbt_minmax[RB_DIR_LEFT] = self;
+ rbt->rbt_minmax[RB_DIR_RIGHT] = self;
+#endif
+ rebalance = false;
+ } else {
+ KASSERT(position == RB_DIR_LEFT || position == RB_DIR_RIGHT);
+#ifndef RBSMALL
+ /*
+ * Keep track of the minimum and maximum nodes. If our
+ * parent is a minmax node and we on their min/max side,
+ * we must be the new min/max node.
+ */
+ if (parent == rbt->rbt_minmax[position])
+ rbt->rbt_minmax[position] = self;
+#endif /* !RBSMALL */
+ /*
+ * All new nodes are colored red. We only need to rebalance
+ * if our parent is also red.
+ */
+ RB_MARK_RED(self);
+ rebalance = RB_RED_P(parent);
+ }
+ KASSERT(RB_SENTINEL_P(parent->rb_nodes[position]));
+ self->rb_left = parent->rb_nodes[position];
+ self->rb_right = parent->rb_nodes[position];
+ parent->rb_nodes[position] = self;
+ KASSERT(RB_CHILDLESS_P(self));
+
+ /*
+ * Insert the new node into a sorted list for easy sequential access
+ */
+ rbt->rbt_count++;
+#ifdef RBDEBUG
+ if (RB_ROOT_P(rbt, self)) {
+ RB_TAILQ_INSERT_HEAD(&rbt->rbt_nodes, self, rb_link);
+ } else if (position == RB_DIR_LEFT) {
+ KASSERT((*compare_nodes)(rbto->rbto_context,
+ RB_NODETOITEM(rbto, self),
+ RB_NODETOITEM(rbto, RB_FATHER(self))) < 0);
+ RB_TAILQ_INSERT_BEFORE(RB_FATHER(self), self, rb_link);
+ } else {
+ KASSERT((*compare_nodes)(rbto->rbto_context,
+ RB_NODETOITEM(rbto, RB_FATHER(self)),
+ RB_NODETOITEM(rbto, self)) < 0);
+ RB_TAILQ_INSERT_AFTER(&rbt->rbt_nodes, RB_FATHER(self),
+ self, rb_link);
+ }
+#endif
+ KASSERT(rb_tree_check_node(rbt, self, NULL, !rebalance));
+
+ /*
+ * Rebalance tree after insertion
+ */
+ if (rebalance) {
+ rb_tree_insert_rebalance(rbt, self);
+ KASSERT(rb_tree_check_node(rbt, self, NULL, true));
+ }
+
+ /* Succesfully inserted, return our node pointer. */
+ return object;
+}
+
+/*
+ * Swap the location and colors of 'self' and its child @ which. The child
+ * can not be a sentinel node. This is our rotation function. However,
+ * since it preserves coloring, it great simplifies both insertion and
+ * removal since rotation almost always involves the exchanging of colors
+ * as a separate step.
+ */
+/*ARGSUSED*/
+static void
+rb_tree_reparent_nodes(struct rb_tree *rbt, struct rb_node *old_father,
+ const unsigned int which)
+{
+ const unsigned int other = which ^ RB_DIR_OTHER;
+ struct rb_node * const grandpa = RB_FATHER(old_father);
+ struct rb_node * const old_child = old_father->rb_nodes[which];
+ struct rb_node * const new_father = old_child;
+ struct rb_node * const new_child = old_father;
+
+ KASSERT(which == RB_DIR_LEFT || which == RB_DIR_RIGHT);
+
+ KASSERT(!RB_SENTINEL_P(old_child));
+ KASSERT(RB_FATHER(old_child) == old_father);
+
+ KASSERT(rb_tree_check_node(rbt, old_father, NULL, false));
+ KASSERT(rb_tree_check_node(rbt, old_child, NULL, false));
+ KASSERT(RB_ROOT_P(rbt, old_father) ||
+ rb_tree_check_node(rbt, grandpa, NULL, false));
+
+ /*
+ * Exchange descendant linkages.
+ */
+ grandpa->rb_nodes[RB_POSITION(old_father)] = new_father;
+ new_child->rb_nodes[which] = old_child->rb_nodes[other];
+ new_father->rb_nodes[other] = new_child;
+
+ /*
+ * Update ancestor linkages
+ */
+ RB_SET_FATHER(new_father, grandpa);
+ RB_SET_FATHER(new_child, new_father);
+
+ /*
+ * Exchange properties between new_father and new_child. The only
+ * change is that new_child's position is now on the other side.
+ */
+#if 0
+ {
+ struct rb_node tmp;
+ tmp.rb_info = 0;
+ RB_COPY_PROPERTIES(&tmp, old_child);
+ RB_COPY_PROPERTIES(new_father, old_father);
+ RB_COPY_PROPERTIES(new_child, &tmp);
+ }
+#else
+ RB_SWAP_PROPERTIES(new_father, new_child);
+#endif
+ RB_SET_POSITION(new_child, other);
+
+ /*
+ * Make sure to reparent the new child to ourself.
+ */
+ if (!RB_SENTINEL_P(new_child->rb_nodes[which])) {
+ RB_SET_FATHER(new_child->rb_nodes[which], new_child);
+ RB_SET_POSITION(new_child->rb_nodes[which], which);
+ }
+
+ KASSERT(rb_tree_check_node(rbt, new_father, NULL, false));
+ KASSERT(rb_tree_check_node(rbt, new_child, NULL, false));
+ KASSERT(RB_ROOT_P(rbt, new_father) ||
+ rb_tree_check_node(rbt, grandpa, NULL, false));
+}
+
+static void
+rb_tree_insert_rebalance(struct rb_tree *rbt, struct rb_node *self)
+{
+ struct rb_node * father = RB_FATHER(self);
+ struct rb_node * grandpa = RB_FATHER(father);
+ struct rb_node * uncle;
+ unsigned int which;
+ unsigned int other;
+
+ KASSERT(!RB_ROOT_P(rbt, self));
+ KASSERT(RB_RED_P(self));
+ KASSERT(RB_RED_P(father));
+ RBSTAT_INC(rbt->rbt_insertion_rebalance_calls);
+
+ for (;;) {
+ KASSERT(!RB_SENTINEL_P(self));
+
+ KASSERT(RB_RED_P(self));
+ KASSERT(RB_RED_P(father));
+ /*
+ * We are red and our parent is red, therefore we must have a
+ * grandfather and he must be black.
+ */
+ grandpa = RB_FATHER(father);
+ KASSERT(RB_BLACK_P(grandpa));
+ KASSERT(RB_DIR_RIGHT == 1 && RB_DIR_LEFT == 0);
+ which = (father == grandpa->rb_right);
+ other = which ^ RB_DIR_OTHER;
+ uncle = grandpa->rb_nodes[other];
+
+ if (RB_BLACK_P(uncle))
+ break;
+
+ RBSTAT_INC(rbt->rbt_insertion_rebalance_passes);
+ /*
+ * Case 1: our uncle is red
+ * Simply invert the colors of our parent and
+ * uncle and make our grandparent red. And
+ * then solve the problem up at his level.
+ */
+ RB_MARK_BLACK(uncle);
+ RB_MARK_BLACK(father);
+ if (__predict_false(RB_ROOT_P(rbt, grandpa))) {
+ /*
+ * If our grandpa is root, don't bother
+ * setting him to red, just return.
+ */
+ KASSERT(RB_BLACK_P(grandpa));
+ return;
+ }
+ RB_MARK_RED(grandpa);
+ self = grandpa;
+ father = RB_FATHER(self);
+ KASSERT(RB_RED_P(self));
+ if (RB_BLACK_P(father)) {
+ /*
+ * If our greatgrandpa is black, we're done.
+ */
+ KASSERT(RB_BLACK_P(rbt->rbt_root));
+ return;
+ }
+ }
+
+ KASSERT(!RB_ROOT_P(rbt, self));
+ KASSERT(RB_RED_P(self));
+ KASSERT(RB_RED_P(father));
+ KASSERT(RB_BLACK_P(uncle));
+ KASSERT(RB_BLACK_P(grandpa));
+ /*
+ * Case 2&3: our uncle is black.
+ */
+ if (self == father->rb_nodes[other]) {
+ /*
+ * Case 2: we are on the same side as our uncle
+ * Swap ourselves with our parent so this case
+ * becomes case 3. Basically our parent becomes our
+ * child.
+ */
+ rb_tree_reparent_nodes(rbt, father, other);
+ KASSERT(RB_FATHER(father) == self);
+ KASSERT(self->rb_nodes[which] == father);
+ KASSERT(RB_FATHER(self) == grandpa);
+ self = father;
+ father = RB_FATHER(self);
+ }
+ KASSERT(RB_RED_P(self) && RB_RED_P(father));
+ KASSERT(grandpa->rb_nodes[which] == father);
+ /*
+ * Case 3: we are opposite a child of a black uncle.
+ * Swap our parent and grandparent. Since our grandfather
+ * is black, our father will become black and our new sibling
+ * (former grandparent) will become red.
+ */
+ rb_tree_reparent_nodes(rbt, grandpa, which);
+ KASSERT(RB_FATHER(self) == father);
+ KASSERT(RB_FATHER(self)->rb_nodes[RB_POSITION(self) ^ RB_DIR_OTHER] == grandpa);
+ KASSERT(RB_RED_P(self));
+ KASSERT(RB_BLACK_P(father));
+ KASSERT(RB_RED_P(grandpa));
+
+ /*
+ * Final step: Set the root to black.
+ */
+ RB_MARK_BLACK(rbt->rbt_root);
+}
+
+static void
+rb_tree_prune_node(struct rb_tree *rbt, struct rb_node *self, bool rebalance)
+{
+ const unsigned int which = RB_POSITION(self);
+ struct rb_node *father = RB_FATHER(self);
+#ifndef RBSMALL
+ const bool was_root = RB_ROOT_P(rbt, self);
+#endif
+
+ KASSERT(rebalance || (RB_ROOT_P(rbt, self) || RB_RED_P(self)));
+ KASSERT(!rebalance || RB_BLACK_P(self));
+ KASSERT(RB_CHILDLESS_P(self));
+ KASSERT(rb_tree_check_node(rbt, self, NULL, false));
+
+ /*
+ * Since we are childless, we know that self->rb_left is pointing
+ * to the sentinel node.
+ */
+ father->rb_nodes[which] = self->rb_left;
+
+ /*
+ * Remove ourselves from the node list, decrement the count,
+ * and update min/max.
+ */
+ RB_TAILQ_REMOVE(&rbt->rbt_nodes, self, rb_link);
+ rbt->rbt_count--;
+#ifndef RBSMALL
+ if (__predict_false(rbt->rbt_minmax[RB_POSITION(self)] == self)) {
+ rbt->rbt_minmax[RB_POSITION(self)] = father;
+ /*
+ * When removing the root, rbt->rbt_minmax[RB_DIR_LEFT] is
+ * updated automatically, but we also need to update
+ * rbt->rbt_minmax[RB_DIR_RIGHT];
+ */
+ if (__predict_false(was_root)) {
+ rbt->rbt_minmax[RB_DIR_RIGHT] = father;
+ }
+ }
+ RB_SET_FATHER(self, NULL);
+#endif
+
+ /*
+ * Rebalance if requested.
+ */
+ if (rebalance)
+ rb_tree_removal_rebalance(rbt, father, which);
+ KASSERT(was_root || rb_tree_check_node(rbt, father, NULL, true));
+}
+
+/*
+ * When deleting an interior node
+ */
+static void
+rb_tree_swap_prune_and_rebalance(struct rb_tree *rbt, struct rb_node *self,
+ struct rb_node *standin)
+{
+ const unsigned int standin_which = RB_POSITION(standin);
+ unsigned int standin_other = standin_which ^ RB_DIR_OTHER;
+ struct rb_node *standin_son;
+ struct rb_node *standin_father = RB_FATHER(standin);
+ bool rebalance = RB_BLACK_P(standin);
+
+ if (standin_father == self) {
+ /*
+ * As a child of self, any childen would be opposite of
+ * our parent.
+ */
+ KASSERT(RB_SENTINEL_P(standin->rb_nodes[standin_other]));
+ standin_son = standin->rb_nodes[standin_which];
+ } else {
+ /*
+ * Since we aren't a child of self, any childen would be
+ * on the same side as our parent.
+ */
+ KASSERT(RB_SENTINEL_P(standin->rb_nodes[standin_which]));
+ standin_son = standin->rb_nodes[standin_other];
+ }
+
+ /*
+ * the node we are removing must have two children.
+ */
+ KASSERT(RB_TWOCHILDREN_P(self));
+ /*
+ * If standin has a child, it must be red.
+ */
+ KASSERT(RB_SENTINEL_P(standin_son) || RB_RED_P(standin_son));
+
+ /*
+ * Verify things are sane.
+ */
+ KASSERT(rb_tree_check_node(rbt, self, NULL, false));
+ KASSERT(rb_tree_check_node(rbt, standin, NULL, false));
+
+ if (__predict_false(RB_RED_P(standin_son))) {
+ /*
+ * We know we have a red child so if we flip it to black
+ * we don't have to rebalance.
+ */
+ KASSERT(rb_tree_check_node(rbt, standin_son, NULL, true));
+ RB_MARK_BLACK(standin_son);
+ rebalance = false;
+
+ if (standin_father == self) {
+ KASSERT(RB_POSITION(standin_son) == standin_which);
+ } else {
+ KASSERT(RB_POSITION(standin_son) == standin_other);
+ /*
+ * Change the son's parentage to point to his grandpa.
+ */
+ RB_SET_FATHER(standin_son, standin_father);
+ RB_SET_POSITION(standin_son, standin_which);
+ }
+ }
+
+ if (standin_father == self) {
+ /*
+ * If we are about to delete the standin's father, then when
+ * we call rebalance, we need to use ourselves as our father.
+ * Otherwise remember our original father. Also, sincef we are
+ * our standin's father we only need to reparent the standin's
+ * brother.
+ *
+ * | R --> S |
+ * | Q S --> Q T |
+ * | t --> |
+ */
+ KASSERT(RB_SENTINEL_P(standin->rb_nodes[standin_other]));
+ KASSERT(!RB_SENTINEL_P(self->rb_nodes[standin_other]));
+ KASSERT(self->rb_nodes[standin_which] == standin);
+ /*
+ * Have our son/standin adopt his brother as his new son.
+ */
+ standin_father = standin;
+ } else {
+ /*
+ * | R --> S . |
+ * | / \ | T --> / \ | / |
+ * | ..... | S --> ..... | T |
+ *
+ * Sever standin's connection to his father.
+ */
+ standin_father->rb_nodes[standin_which] = standin_son;
+ /*
+ * Adopt the far son.
+ */
+ standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
+ RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
+ KASSERT(RB_POSITION(self->rb_nodes[standin_other]) == standin_other);
+ /*
+ * Use standin_other because we need to preserve standin_which
+ * for the removal_rebalance.
+ */
+ standin_other = standin_which;
+ }
+
+ /*
+ * Move the only remaining son to our standin. If our standin is our
+ * son, this will be the only son needed to be moved.
+ */
+ KASSERT(standin->rb_nodes[standin_other] != self->rb_nodes[standin_other]);
+ standin->rb_nodes[standin_other] = self->rb_nodes[standin_other];
+ RB_SET_FATHER(standin->rb_nodes[standin_other], standin);
+
+ /*
+ * Now copy the result of self to standin and then replace
+ * self with standin in the tree.
+ */
+ RB_COPY_PROPERTIES(standin, self);
+ RB_SET_FATHER(standin, RB_FATHER(self));
+ RB_FATHER(standin)->rb_nodes[RB_POSITION(standin)] = standin;
+
+ /*
+ * Remove ourselves from the node list, decrement the count,
+ * and update min/max.
+ */
+ RB_TAILQ_REMOVE(&rbt->rbt_nodes, self, rb_link);
+ rbt->rbt_count--;
+#ifndef RBSMALL
+ if (__predict_false(rbt->rbt_minmax[RB_POSITION(self)] == self))
+ rbt->rbt_minmax[RB_POSITION(self)] = RB_FATHER(self);
+ RB_SET_FATHER(self, NULL);
+#endif
+
+ KASSERT(rb_tree_check_node(rbt, standin, NULL, false));
+ KASSERT(RB_FATHER_SENTINEL_P(standin)
+ || rb_tree_check_node(rbt, standin_father, NULL, false));
+ KASSERT(RB_LEFT_SENTINEL_P(standin)
+ || rb_tree_check_node(rbt, standin->rb_left, NULL, false));
+ KASSERT(RB_RIGHT_SENTINEL_P(standin)
+ || rb_tree_check_node(rbt, standin->rb_right, NULL, false));
+
+ if (!rebalance)
+ return;
+
+ rb_tree_removal_rebalance(rbt, standin_father, standin_which);
+ KASSERT(rb_tree_check_node(rbt, standin, NULL, true));
+}
+
+/*
+ * We could do this by doing
+ * rb_tree_node_swap(rbt, self, which);
+ * rb_tree_prune_node(rbt, self, false);
+ *
+ * But it's more efficient to just evalate and recolor the child.
+ */
+static void
+rb_tree_prune_blackred_branch(struct rb_tree *rbt, struct rb_node *self,
+ unsigned int which)
+{
+ struct rb_node *father = RB_FATHER(self);
+ struct rb_node *son = self->rb_nodes[which];
+#ifndef RBSMALL
+ const bool was_root = RB_ROOT_P(rbt, self);
+#endif
+
+ KASSERT(which == RB_DIR_LEFT || which == RB_DIR_RIGHT);
+ KASSERT(RB_BLACK_P(self) && RB_RED_P(son));
+ KASSERT(!RB_TWOCHILDREN_P(son));
+ KASSERT(RB_CHILDLESS_P(son));
+ KASSERT(rb_tree_check_node(rbt, self, NULL, false));
+ KASSERT(rb_tree_check_node(rbt, son, NULL, false));
+
+ /*
+ * Remove ourselves from the tree and give our former child our
+ * properties (position, color, root).
+ */
+ RB_COPY_PROPERTIES(son, self);
+ father->rb_nodes[RB_POSITION(son)] = son;
+ RB_SET_FATHER(son, father);
+
+ /*
+ * Remove ourselves from the node list, decrement the count,
+ * and update minmax.
+ */
+ RB_TAILQ_REMOVE(&rbt->rbt_nodes, self, rb_link);
+ rbt->rbt_count--;
+#ifndef RBSMALL
+ if (__predict_false(was_root)) {
+ KASSERT(rbt->rbt_minmax[which] == son);
+ rbt->rbt_minmax[which ^ RB_DIR_OTHER] = son;
+ } else if (rbt->rbt_minmax[RB_POSITION(self)] == self) {
+ rbt->rbt_minmax[RB_POSITION(self)] = son;
+ }
+ RB_SET_FATHER(self, NULL);
+#endif
+
+ KASSERT(was_root || rb_tree_check_node(rbt, father, NULL, true));
+ KASSERT(rb_tree_check_node(rbt, son, NULL, true));
+}
+
+void
+rb_tree_remove_node(struct rb_tree *rbt, void *object)
+{
+ const rb_tree_ops_t *rbto = rbt->rbt_ops;
+ struct rb_node *standin, *self = RB_ITEMTONODE(rbto, object);
+ unsigned int which;
+
+ KASSERT(!RB_SENTINEL_P(self));
+ RBSTAT_INC(rbt->rbt_removals);
+
+ /*
+ * In the following diagrams, we (the node to be removed) are S. Red
+ * nodes are lowercase. T could be either red or black.
+ *
+ * Remember the major axiom of the red-black tree: the number of
+ * black nodes from the root to each leaf is constant across all
+ * leaves, only the number of red nodes varies.
+ *
+ * Thus removing a red leaf doesn't require any other changes to a
+ * red-black tree. So if we must remove a node, attempt to rearrange
+ * the tree so we can remove a red node.
+ *
+ * The simpliest case is a childless red node or a childless root node:
+ *
+ * | T --> T | or | R --> * |
+ * | s --> * |
+ */
+ if (RB_CHILDLESS_P(self)) {
+ const bool rebalance = RB_BLACK_P(self) && !RB_ROOT_P(rbt, self);
+ rb_tree_prune_node(rbt, self, rebalance);
+ return;
+ }
+ KASSERT(!RB_CHILDLESS_P(self));
+ if (!RB_TWOCHILDREN_P(self)) {
+ /*
+ * The next simpliest case is the node we are deleting is
+ * black and has one red child.
+ *
+ * | T --> T --> T |
+ * | S --> R --> R |
+ * | r --> s --> * |
+ */
+ which = RB_LEFT_SENTINEL_P(self) ? RB_DIR_RIGHT : RB_DIR_LEFT;
+ KASSERT(RB_BLACK_P(self));
+ KASSERT(RB_RED_P(self->rb_nodes[which]));
+ KASSERT(RB_CHILDLESS_P(self->rb_nodes[which]));
+ rb_tree_prune_blackred_branch(rbt, self, which);
+ return;
+ }
+ KASSERT(RB_TWOCHILDREN_P(self));
+
+ /*
+ * We invert these because we prefer to remove from the inside of
+ * the tree.
+ */
+ which = RB_POSITION(self) ^ RB_DIR_OTHER;
+
+ /*
+ * Let's find the node closes to us opposite of our parent
+ * Now swap it with ourself, "prune" it, and rebalance, if needed.
+ */
+ standin = RB_ITEMTONODE(rbto, rb_tree_iterate(rbt, object, which));
+ rb_tree_swap_prune_and_rebalance(rbt, self, standin);
+}
+
+static void
+rb_tree_removal_rebalance(struct rb_tree *rbt, struct rb_node *parent,
+ unsigned int which)
+{
+ KASSERT(!RB_SENTINEL_P(parent));
+ KASSERT(RB_SENTINEL_P(parent->rb_nodes[which]));
+ KASSERT(which == RB_DIR_LEFT || which == RB_DIR_RIGHT);
+ RBSTAT_INC(rbt->rbt_removal_rebalance_calls);
+
+ while (RB_BLACK_P(parent->rb_nodes[which])) {
+ unsigned int other = which ^ RB_DIR_OTHER;
+ struct rb_node *brother = parent->rb_nodes[other];
+
+ RBSTAT_INC(rbt->rbt_removal_rebalance_passes);
+
+ KASSERT(!RB_SENTINEL_P(brother));
+ /*
+ * For cases 1, 2a, and 2b, our brother's children must
+ * be black and our father must be black
+ */
+ if (RB_BLACK_P(parent)
+ && RB_BLACK_P(brother->rb_left)
+ && RB_BLACK_P(brother->rb_right)) {
+ if (RB_RED_P(brother)) {
+ /*
+ * Case 1: Our brother is red, swap its
+ * position (and colors) with our parent.
+ * This should now be case 2b (unless C or E
+ * has a red child which is case 3; thus no
+ * explicit branch to case 2b).
+ *
+ * B -> D
+ * A d -> b E
+ * C E -> A C
+ */
+ KASSERT(RB_BLACK_P(parent));
+ rb_tree_reparent_nodes(rbt, parent, other);
+ brother = parent->rb_nodes[other];
+ KASSERT(!RB_SENTINEL_P(brother));
+ KASSERT(RB_RED_P(parent));
+ KASSERT(RB_BLACK_P(brother));
+ KASSERT(rb_tree_check_node(rbt, brother, NULL, false));
+ KASSERT(rb_tree_check_node(rbt, parent, NULL, false));
+ } else {
+ /*
+ * Both our parent and brother are black.
+ * Change our brother to red, advance up rank
+ * and go through the loop again.
+ *
+ * B -> *B
+ * *A D -> A d
+ * C E -> C E
+ */
+ RB_MARK_RED(brother);
+ KASSERT(RB_BLACK_P(brother->rb_left));
+ KASSERT(RB_BLACK_P(brother->rb_right));
+ if (RB_ROOT_P(rbt, parent))
+ return; /* root == parent == black */
+ KASSERT(rb_tree_check_node(rbt, brother, NULL, false));
+ KASSERT(rb_tree_check_node(rbt, parent, NULL, false));
+ which = RB_POSITION(parent);
+ parent = RB_FATHER(parent);
+ continue;
+ }
+ }
+ /*
+ * Avoid an else here so that case 2a above can hit either
+ * case 2b, 3, or 4.
+ */
+ if (RB_RED_P(parent)
+ && RB_BLACK_P(brother)
+ && RB_BLACK_P(brother->rb_left)
+ && RB_BLACK_P(brother->rb_right)) {
+ KASSERT(RB_RED_P(parent));
+ KASSERT(RB_BLACK_P(brother));
+ KASSERT(RB_BLACK_P(brother->rb_left));
+ KASSERT(RB_BLACK_P(brother->rb_right));
+ /*
+ * We are black, our father is red, our brother and
+ * both nephews are black. Simply invert/exchange the
+ * colors of our father and brother (to black and red
+ * respectively).
+ *
+ * | f --> F |
+ * | * B --> * b |
+ * | N N --> N N |
+ */
+ RB_MARK_BLACK(parent);
+ RB_MARK_RED(brother);
+ KASSERT(rb_tree_check_node(rbt, brother, NULL, true));
+ break; /* We're done! */
+ } else {
+ /*
+ * Our brother must be black and have at least one
+ * red child (it may have two).
+ */
+ KASSERT(RB_BLACK_P(brother));
+ KASSERT(RB_RED_P(brother->rb_nodes[which]) ||
+ RB_RED_P(brother->rb_nodes[other]));
+ if (RB_BLACK_P(brother->rb_nodes[other])) {
+ /*
+ * Case 3: our brother is black, our near
+ * nephew is red, and our far nephew is black.
+ * Swap our brother with our near nephew.
+ * This result in a tree that matches case 4.
+ * (Our father could be red or black).
+ *
+ * | F --> F |
+ * | x B --> x B |
+ * | n --> n |
+ */
+ KASSERT(RB_RED_P(brother->rb_nodes[which]));
+ rb_tree_reparent_nodes(rbt, brother, which);
+ KASSERT(RB_FATHER(brother) == parent->rb_nodes[other]);
+ brother = parent->rb_nodes[other];
+ KASSERT(RB_RED_P(brother->rb_nodes[other]));
+ }
+ /*
+ * Case 4: our brother is black and our far nephew
+ * is red. Swap our father and brother locations and
+ * change our far nephew to black. (these can be
+ * done in either order so we change the color first).
+ * The result is a valid red-black tree and is a
+ * terminal case. (again we don't care about the
+ * father's color)
+ *
+ * If the father is red, we will get a red-black-black
+ * tree:
+ * | f -> f --> b |
+ * | B -> B --> F N |
+ * | n -> N --> |
+ *
+ * If the father is black, we will get an all black
+ * tree:
+ * | F -> F --> B |
+ * | B -> B --> F N |
+ * | n -> N --> |
+ *
+ * If we had two red nephews, then after the swap,
+ * our former father would have a red grandson.
+ */
+ KASSERT(RB_BLACK_P(brother));
+ KASSERT(RB_RED_P(brother->rb_nodes[other]));
+ RB_MARK_BLACK(brother->rb_nodes[other]);
+ rb_tree_reparent_nodes(rbt, parent, other);
+ break; /* We're done! */
+ }
+ }
+ KASSERT(rb_tree_check_node(rbt, parent, NULL, true));
+}
+
+void *
+rb_tree_iterate(struct rb_tree *rbt, void *object, const unsigned int direction)
+{
+ const rb_tree_ops_t *rbto = rbt->rbt_ops;
+ const unsigned int other = direction ^ RB_DIR_OTHER;
+ struct rb_node *self;
+
+ KASSERT(direction == RB_DIR_LEFT || direction == RB_DIR_RIGHT);
+
+ if (object == NULL) {
+#ifndef RBSMALL
+ if (RB_SENTINEL_P(rbt->rbt_root))
+ return NULL;
+ return RB_NODETOITEM(rbto, rbt->rbt_minmax[direction == RB_DIR_LEFT ? RB_DIR_RIGHT : RB_DIR_LEFT]);
+#else
+ self = rbt->rbt_root;
+ if (RB_SENTINEL_P(self))
+ return NULL;
+ while (!RB_SENTINEL_P(self->rb_nodes[direction == RB_DIR_LEFT ? RB_DIR_RIGHT : RB_DIR_LEFT]))
+ self = self->rb_nodes[direction == RB_DIR_LEFT ? RB_DIR_RIGHT : RB_DIR_LEFT];
+ return RB_NODETOITEM(rbto, self);
+#endif /* !RBSMALL */
+ }
+ self = RB_ITEMTONODE(rbto, object);
+ KASSERT(!RB_SENTINEL_P(self));
+ /*
+ * We can't go any further in this direction. We proceed up in the
+ * opposite direction until our parent is in direction we want to go.
+ */
+ if (RB_SENTINEL_P(self->rb_nodes[direction])) {
+ while (!RB_ROOT_P(rbt, self)) {
+ if (other == RB_POSITION(self))
+ return RB_NODETOITEM(rbto, RB_FATHER(self));
+ self = RB_FATHER(self);
+ }
+ return NULL;
+ }
+
+ /*
+ * Advance down one in current direction and go down as far as possible
+ * in the opposite direction.
+ */
+ self = self->rb_nodes[direction];
+ KASSERT(!RB_SENTINEL_P(self));
+ while (!RB_SENTINEL_P(self->rb_nodes[other]))
+ self = self->rb_nodes[other];
+ return RB_NODETOITEM(rbto, self);
+}
+
+#ifdef RBDEBUG
+static const struct rb_node *
+rb_tree_iterate_const(const struct rb_tree *rbt, const struct rb_node *self,
+ const unsigned int direction)
+{
+ const unsigned int other = direction ^ RB_DIR_OTHER;
+ KASSERT(direction == RB_DIR_LEFT || direction == RB_DIR_RIGHT);
+
+ if (self == NULL) {
+#ifndef RBSMALL
+ if (RB_SENTINEL_P(rbt->rbt_root))
+ return NULL;
+ return rbt->rbt_minmax[direction];
+#else
+ self = rbt->rbt_root;
+ if (RB_SENTINEL_P(self))
+ return NULL;
+ while (!RB_SENTINEL_P(self->rb_nodes[direction]))
+ self = self->rb_nodes[direction];
+ return self;
+#endif /* !RBSMALL */
+ }
+ KASSERT(!RB_SENTINEL_P(self));
+ /*
+ * We can't go any further in this direction. We proceed up in the
+ * opposite direction until our parent is in direction we want to go.
+ */
+ if (RB_SENTINEL_P(self->rb_nodes[direction])) {
+ while (!RB_ROOT_P(rbt, self)) {
+ if (other == RB_POSITION(self))
+ return RB_FATHER(self);
+ self = RB_FATHER(self);
+ }
+ return NULL;
+ }
+
+ /*
+ * Advance down one in current direction and go down as far as possible
+ * in the opposite direction.
+ */
+ self = self->rb_nodes[direction];
+ KASSERT(!RB_SENTINEL_P(self));
+ while (!RB_SENTINEL_P(self->rb_nodes[other]))
+ self = self->rb_nodes[other];
+ return self;
+}
+
+static unsigned int
+rb_tree_count_black(const struct rb_node *self)
+{
+ unsigned int left, right;
+
+ if (RB_SENTINEL_P(self))
+ return 0;
+
+ left = rb_tree_count_black(self->rb_left);
+ right = rb_tree_count_black(self->rb_right);
+
+ KASSERT(left == right);
+
+ return left + RB_BLACK_P(self);
+}
+
+static bool
+rb_tree_check_node(const struct rb_tree *rbt, const struct rb_node *self,
+ const struct rb_node *prev, bool red_check)
+{
+ const rb_tree_ops_t *rbto = rbt->rbt_ops;
+ rbto_compare_nodes_fn compare_nodes = rbto->rbto_compare_nodes;
+
+ KASSERT(!RB_SENTINEL_P(self));
+ KASSERT(prev == NULL || (*compare_nodes)(rbto->rbto_context,
+ RB_NODETOITEM(rbto, prev), RB_NODETOITEM(rbto, self)) < 0);
+
+ /*
+ * Verify our relationship to our parent.
+ */
+ if (RB_ROOT_P(rbt, self)) {
+ KASSERT(self == rbt->rbt_root);
+ KASSERT(RB_POSITION(self) == RB_DIR_LEFT);
+ KASSERT(RB_FATHER(self)->rb_nodes[RB_DIR_LEFT] == self);
+ KASSERT(RB_FATHER(self) == (const struct rb_node *) &rbt->rbt_root);
+ } else {
+ int diff = (*compare_nodes)(rbto->rbto_context,
+ RB_NODETOITEM(rbto, self),
+ RB_NODETOITEM(rbto, RB_FATHER(self)));
+
+ KASSERT(self != rbt->rbt_root);
+ KASSERT(!RB_FATHER_SENTINEL_P(self));
+ if (RB_POSITION(self) == RB_DIR_LEFT) {
+ KASSERT(diff < 0);
+ KASSERT(RB_FATHER(self)->rb_nodes[RB_DIR_LEFT] == self);
+ } else {
+ KASSERT(diff > 0);
+ KASSERT(RB_FATHER(self)->rb_nodes[RB_DIR_RIGHT] == self);
+ }
+ }
+
+ /*
+ * Verify our position in the linked list against the tree itself.
+ */
+ {
+ const struct rb_node *prev0 = rb_tree_iterate_const(rbt, self, RB_DIR_LEFT);
+ const struct rb_node *next0 = rb_tree_iterate_const(rbt, self, RB_DIR_RIGHT);
+ KASSERT(prev0 == TAILQ_PREV(self, rb_node_qh, rb_link));
+ KASSERT(next0 == TAILQ_NEXT(self, rb_link));
+#ifndef RBSMALL
+ KASSERT(prev0 != NULL || self == rbt->rbt_minmax[RB_DIR_LEFT]);
+ KASSERT(next0 != NULL || self == rbt->rbt_minmax[RB_DIR_RIGHT]);
+#endif
+ }
+
+ /*
+ * The root must be black.
+ * There can never be two adjacent red nodes.
+ */
+ if (red_check) {
+ KASSERT(!RB_ROOT_P(rbt, self) || RB_BLACK_P(self));
+ (void) rb_tree_count_black(self);
+ if (RB_RED_P(self)) {
+ const struct rb_node *brother;
+ KASSERT(!RB_ROOT_P(rbt, self));
+ brother = RB_FATHER(self)->rb_nodes[RB_POSITION(self) ^ RB_DIR_OTHER];
+ KASSERT(RB_BLACK_P(RB_FATHER(self)));
+ /*
+ * I'm red and have no children, then I must either
+ * have no brother or my brother also be red and
+ * also have no children. (black count == 0)
+ */
+ KASSERT(!RB_CHILDLESS_P(self)
+ || RB_SENTINEL_P(brother)
+ || RB_RED_P(brother)
+ || RB_CHILDLESS_P(brother));
+ /*
+ * If I'm not childless, I must have two children
+ * and they must be both be black.
+ */
+ KASSERT(RB_CHILDLESS_P(self)
+ || (RB_TWOCHILDREN_P(self)
+ && RB_BLACK_P(self->rb_left)
+ && RB_BLACK_P(self->rb_right)));
+ /*
+ * If I'm not childless, thus I have black children,
+ * then my brother must either be black or have two
+ * black children.
+ */
+ KASSERT(RB_CHILDLESS_P(self)
+ || RB_BLACK_P(brother)
+ || (RB_TWOCHILDREN_P(brother)
+ && RB_BLACK_P(brother->rb_left)
+ && RB_BLACK_P(brother->rb_right)));
+ } else {
+ /*
+ * If I'm black and have one child, that child must
+ * be red and childless.
+ */
+ KASSERT(RB_CHILDLESS_P(self)
+ || RB_TWOCHILDREN_P(self)
+ || (!RB_LEFT_SENTINEL_P(self)
+ && RB_RIGHT_SENTINEL_P(self)
+ && RB_RED_P(self->rb_left)
+ && RB_CHILDLESS_P(self->rb_left))
+ || (!RB_RIGHT_SENTINEL_P(self)
+ && RB_LEFT_SENTINEL_P(self)
+ && RB_RED_P(self->rb_right)
+ && RB_CHILDLESS_P(self->rb_right)));
+
+ /*
+ * If I'm a childless black node and my parent is
+ * black, my 2nd closet relative away from my parent
+ * is either red or has a red parent or red children.
+ */
+ if (!RB_ROOT_P(rbt, self)
+ && RB_CHILDLESS_P(self)
+ && RB_BLACK_P(RB_FATHER(self))) {
+ const unsigned int which = RB_POSITION(self);
+ const unsigned int other = which ^ RB_DIR_OTHER;
+ const struct rb_node *relative0, *relative;
+
+ relative0 = rb_tree_iterate_const(rbt,
+ self, other);
+ KASSERT(relative0 != NULL);
+ relative = rb_tree_iterate_const(rbt,
+ relative0, other);
+ KASSERT(relative != NULL);
+ KASSERT(RB_SENTINEL_P(relative->rb_nodes[which]));
+#if 0
+ KASSERT(RB_RED_P(relative)
+ || RB_RED_P(relative->rb_left)
+ || RB_RED_P(relative->rb_right)
+ || RB_RED_P(RB_FATHER(relative)));
+#endif
+ }
+ }
+ /*
+ * A grandparent's children must be real nodes and not
+ * sentinels. First check out grandparent.
+ */
+ KASSERT(RB_ROOT_P(rbt, self)
+ || RB_ROOT_P(rbt, RB_FATHER(self))
+ || RB_TWOCHILDREN_P(RB_FATHER(RB_FATHER(self))));
+ /*
+ * If we are have grandchildren on our left, then
+ * we must have a child on our right.
+ */
+ KASSERT(RB_LEFT_SENTINEL_P(self)
+ || RB_CHILDLESS_P(self->rb_left)
+ || !RB_RIGHT_SENTINEL_P(self));
+ /*
+ * If we are have grandchildren on our right, then
+ * we must have a child on our left.
+ */
+ KASSERT(RB_RIGHT_SENTINEL_P(self)
+ || RB_CHILDLESS_P(self->rb_right)
+ || !RB_LEFT_SENTINEL_P(self));
+
+ /*
+ * If we have a child on the left and it doesn't have two
+ * children make sure we don't have great-great-grandchildren on
+ * the right.
+ */
+ KASSERT(RB_TWOCHILDREN_P(self->rb_left)
+ || RB_CHILDLESS_P(self->rb_right)
+ || RB_CHILDLESS_P(self->rb_right->rb_left)
+ || RB_CHILDLESS_P(self->rb_right->rb_left->rb_left)
+ || RB_CHILDLESS_P(self->rb_right->rb_left->rb_right)
+ || RB_CHILDLESS_P(self->rb_right->rb_right)
+ || RB_CHILDLESS_P(self->rb_right->rb_right->rb_left)
+ || RB_CHILDLESS_P(self->rb_right->rb_right->rb_right));
+
+ /*
+ * If we have a child on the right and it doesn't have two
+ * children make sure we don't have great-great-grandchildren on
+ * the left.
+ */
+ KASSERT(RB_TWOCHILDREN_P(self->rb_right)
+ || RB_CHILDLESS_P(self->rb_left)
+ || RB_CHILDLESS_P(self->rb_left->rb_left)
+ || RB_CHILDLESS_P(self->rb_left->rb_left->rb_left)
+ || RB_CHILDLESS_P(self->rb_left->rb_left->rb_right)
+ || RB_CHILDLESS_P(self->rb_left->rb_right)
+ || RB_CHILDLESS_P(self->rb_left->rb_right->rb_left)
+ || RB_CHILDLESS_P(self->rb_left->rb_right->rb_right));
+
+ /*
+ * If we are fully interior node, then our predecessors and
+ * successors must have no children in our direction.
+ */
+ if (RB_TWOCHILDREN_P(self)) {
+ const struct rb_node *prev0;
+ const struct rb_node *next0;
+
+ prev0 = rb_tree_iterate_const(rbt, self, RB_DIR_LEFT);
+ KASSERT(prev0 != NULL);
+ KASSERT(RB_RIGHT_SENTINEL_P(prev0));
+
+ next0 = rb_tree_iterate_const(rbt, self, RB_DIR_RIGHT);
+ KASSERT(next0 != NULL);
+ KASSERT(RB_LEFT_SENTINEL_P(next0));
+ }
+ }
+
+ return true;
+}
+
+void
+rb_tree_check(const struct rb_tree *rbt, bool red_check)
+{
+ const struct rb_node *self;
+ const struct rb_node *prev;
+#ifdef RBSTATS
+ unsigned int count = 0;
+#endif
+
+ KASSERT(rbt->rbt_root != NULL);
+ KASSERT(RB_LEFT_P(rbt->rbt_root));
+
+#if defined(RBSTATS) && !defined(RBSMALL)
+ KASSERT(rbt->rbt_count > 1
+ || rbt->rbt_minmax[RB_DIR_LEFT] == rbt->rbt_minmax[RB_DIR_RIGHT]);
+#endif
+
+ prev = NULL;
+ TAILQ_FOREACH(self, &rbt->rbt_nodes, rb_link) {
+ rb_tree_check_node(rbt, self, prev, false);
+#ifdef RBSTATS
+ count++;
+#endif
+ }
+#ifdef RBSTATS
+ KASSERT(rbt->rbt_count == count);
+#endif
+ if (red_check) {
+ KASSERT(RB_BLACK_P(rbt->rbt_root));
+ KASSERT(RB_SENTINEL_P(rbt->rbt_root)
+ || rb_tree_count_black(rbt->rbt_root));
+
+ /*
+ * The root must be black.
+ * There can never be two adjacent red nodes.
+ */
+ TAILQ_FOREACH(self, &rbt->rbt_nodes, rb_link) {
+ rb_tree_check_node(rbt, self, NULL, true);
+ }
+ }
+}
+#endif /* RBDEBUG */
+
+#ifdef RBSTATS
+static void
+rb_tree_mark_depth(const struct rb_tree *rbt, const struct rb_node *self,
+ size_t *depths, size_t depth)
+{
+ if (RB_SENTINEL_P(self))
+ return;
+
+ if (RB_TWOCHILDREN_P(self)) {
+ rb_tree_mark_depth(rbt, self->rb_left, depths, depth + 1);
+ rb_tree_mark_depth(rbt, self->rb_right, depths, depth + 1);
+ return;
+ }
+ depths[depth]++;
+ if (!RB_LEFT_SENTINEL_P(self)) {
+ rb_tree_mark_depth(rbt, self->rb_left, depths, depth + 1);
+ }
+ if (!RB_RIGHT_SENTINEL_P(self)) {
+ rb_tree_mark_depth(rbt, self->rb_right, depths, depth + 1);
+ }
+}
+
+void
+rb_tree_depths(const struct rb_tree *rbt, size_t *depths)
+{
+ rb_tree_mark_depth(rbt, rbt->rbt_root, depths, 1);
+}
+#endif /* RBSTATS */
+
+size_t rb_tree_count(rb_tree_t *rbt) {
+ if (__predict_false(rbt == NULL))
+ return 0;
+
+ return rbt->rbt_count;
+}
--- /dev/null
+.\" $NetBSD: rbtree.3,v 1.7 2012/08/19 19:31:13 wiz Exp $
+.\"
+.\" Copyright (c) 2010 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" Portions Copyright (c) 2012 Apple Inc. All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Matt Thomas, Niels Provos, and David Young.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd August 19, 2012
+.Dt RBTREE 3
+.Os
+.Sh NAME
+.Nm rbtree
+.Nd red-black tree
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/rbtree.h
+.Ft void
+.Fn rb_tree_init "rb_tree_t *rbt" "const rb_tree_ops_t *ops"
+.Ft void *
+.Fn rb_tree_insert_node "rb_tree_t *rbt" "void *rb"
+.Ft void
+.Fn rb_tree_remove_node "rb_tree_t *rbt" "void *rb"
+.Ft void *
+.Fn rb_tree_find_node "rb_tree_t *rbt" "const void *key"
+.Ft void *
+.Fn rb_tree_find_node_geq "rb_tree_t *rbt" "const void *key"
+.Ft void *
+.Fn rb_tree_find_node_leq "rb_tree_t *rbt" "const void *key"
+.Ft void *
+.Fn rb_tree_iterate "rb_tree_t *rbt" "void *rb" "const unsigned int direction"
+.Ft size_t
+.Fn rb_tree_count "rb_tree_t *rbt"
+.Sh DESCRIPTION
+.Nm
+provides red-black trees.
+A red-black tree is a binary search tree with the node color as an
+extra attribute.
+It fulfills a set of conditions:
+.Bl -enum -offset indent
+.It
+Every search path from the root to a leaf consists of the same number of
+black nodes.
+.It
+Each red node (except for the root) has a black parent.
+.It
+Each leaf node is black.
+.El
+.Pp
+Every operation on a red-black tree is bounded as O(lg n).
+The maximum height of a red-black tree is 2lg (n+1).
+.Sh TYPES
+.Bl -tag -width compact
+.It Vt rb_tree_t
+A red-black tree.
+.It Vt typedef signed int \
+(* rbto_compare_nodes_fn)(void *context, const void *node1, const void *node2);
+The node-comparison operator.
+Defines an ordering on nodes.
+Returns a negative value if the first node
+.Ar node1
+precedes the second node
+.Ar node2 .
+Returns a positive value if the first node
+.Ar node1
+follows the second node
+.Ar node2 .
+Returns 0 if the first node
+.Ar node1
+and the second node
+.Ar node2
+are identical according to the ordering.
+.It Vt typedef signed int \
+(* rbto_compare_key_fn)(void *context, const void *node, const void *key);
+The node-key comparison operator.
+Defines the order of nodes and keys.
+Returns a negative value if the node
+.Ar node
+precedes the key
+.Ar key .
+Returns a positive value if the node
+.Ar node
+follows the key
+.Ar key .
+Returns 0 if the node
+.Ar node
+is identical to the key
+.Ar key
+according to the ordering.
+.It Vt rb_tree_ops_t
+Defines the operator for comparing two nodes in the same tree,
+the operator for comparing a node in the tree with a key,
+the offset of member
+.Vt rb_node_t
+within a node,
+and the opaque context passed to the operators.
+Members of
+.Vt rb_tree_ops_t
+are
+.Bd -literal
+ rbto_compare_nodes_fn rbto_compare_nodes;
+ rbto_compare_key_fn rbto_compare_key;
+ size_t rbto_node_offset;
+ void *rbto_context;
+.Ed
+.It Vt rb_node_t
+A node in a red-black tree has this structure as a member.
+.El
+.Sh FUNCTIONS
+.Bl -tag -width compact
+.It Fn rb_tree_init "rbt" "ops"
+Initialize the red-black tree
+.Fa rbt .
+Let the comparison operators given by
+.Fa ops
+define the order of nodes in the tree for
+the purposes of insertion, search, and iteration.
+.Fn rb_tree_init
+always succeeds.
+.It Fn rb_tree_insert_node "rbt" "rb"
+Insert the node
+.Fa rb
+into the tree
+.Fa rbt .
+Return inserted node on success,
+already existing node on failure.
+.It Fn rb_tree_remove_node "rbt" "rb"
+Remove the node
+.Fa rb
+from the tree
+.Fa rbt .
+.It Fn rb_tree_find_node "rbt" "key"
+Search the tree
+.Fa rbt
+for a node exactly matching
+.Fa key .
+If no such node is in the tree, return
+.Dv NULL .
+Otherwise, return the matching node.
+.It Fn rb_tree_find_node_geq "rbt" "key"
+Search the tree
+.Fa rbt
+for a node that exactly matches
+.Fa key
+and return it.
+If no such node is present, return the first node following
+.Fa key
+or, if no such node is in the tree, return
+.Dv NULL .
+.It Fn rb_tree_find_node_leq "rbt" "key"
+Search the tree
+.Fa rbt
+for a node that exactly matches
+.Fa key
+and return it.
+If no such node is present, return the first node preceding
+.Fa key
+or, if no such node is in the tree, return
+.Dv NULL .
+.It Fn rb_tree_iterate "rbt" "rb" "direction"
+If
+.Fa direction
+is
+.Dv RB_DIR_LEFT ,
+return the node in the tree
+.Fa rbt
+immediately preceding the node
+.Fa rb
+or, if
+.Fa rb
+is
+.Dv NULL ,
+return the last node in
+.Fa rbt
+or, if the tree is empty, return
+.Dv NULL .
+.Pp
+If
+.Fa direction
+is
+.Dv RB_DIR_RIGHT ,
+return the node in the tree
+.Fa rbt
+immediately following the node
+.Fa rb
+or, if
+.Fa rb
+is
+.Dv NULL ,
+return the first node in
+.Fa rbt
+or, if the tree is empty, return
+.Dv NULL .
+.It Fn rb_tree_count "rbt"
+Return the number of nodes in the tree
+.Fa rbt .
+If
+.Fa rbt
+is
+.Dv NULL ,
+0 is returned.
+.El
+.Sh IMPLEMENTATION DETAILS
+.Nx 6.0
+included a version of this API that returned the wrong result when using
+.Fn rb_tree_iterate
+to find the first or last node.
+This implementation does not have this bug.
+If you wish to maintain portability with
+.Nx 6.0 ,
+it is recomended that you use the
+.Fn RB_TREE_MIN
+and
+.Fn RB_TREE_MAX
+macros rather than using
+.Fn rb_tree_iterate
+directly.
+.Sh SEE ALSO
+.Xr queue 3
+.Sh HISTORY
+The
+.Nm
+interface first appeared in
+.Nx 6.0 .
+.Sh AUTHORS
+.An Matt Thomas Aq matt@NetBSD.org
+wrote
+.Nm .
+.Pp
+.An Niels Provos Aq provos@citi.umich.edu
+wrote the
+.Xr tree 3
+manual page.
+Portions of this page derive from that page.
+.\" .Sh CAVEATS
+.\" .Sh BUGS
+.\" .Sh SECURITY CONSIDERATIONS
#include <vis.h>
#include <notify.h>
-/* This is the default struct _utmpx shared by the POSIX APIs */
-__private_extern__
-struct _utmpx __utx__ = {
- __UTX_MAGIC__, /* magic */
- {}, /* ut */
- PTHREAD_MUTEX_INITIALIZER, /* utmpx_mutex */
- _PATH_UTMPX, /* utfile */
- NULL, /* fp */
- 1, /* utfile_system */
- 0, /* readonly */
-};
+static struct _utmpx *__utx__ = NULL;
+
+static void
+__default_utx_init(void)
+{
+ __utx__ = calloc(1, sizeof(struct _utmpx));
+ const char magic[] = __UTX_MAGIC__;
+ memcpy(&__utx__->magic, magic, UTMPX_MAGIC);
+ pthread_mutex_init(&__utx__->utmpx_mutex, NULL);
+ __utx__->utfile = _PATH_UTMPX;
+ __utx__->utfile_system = 1;
+}
+
+struct _utmpx *
+__default_utx(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ pthread_once(&once, &__default_utx_init);
+ return __utx__;
+}
static struct utmpx *__getutxid(struct _utmpx *, const struct utmpx *);
void
-setutxent()
+setutxent(void)
{
- _setutxent(&__utx__);
+ _setutxent(__default_utx());
}
void
-endutxent()
+endutxent(void)
{
- _endutxent(&__utx__);
+ _endutxent(__default_utx());
}
struct utmpx *
-getutxent()
+getutxent(void)
{
- return _getutxent(&__utx__);
+ return _getutxent(__default_utx());
}
struct utmpx *
getutxid(const struct utmpx *utx)
{
- return _getutxid(&__utx__, utx);
+ return _getutxid(__default_utx(), utx);
}
struct utmpx *
getutxline(const struct utmpx *utx)
{
- return _getutxline(&__utx__, utx);
+ return _getutxline(__default_utx(), utx);
}
TEST_UTMPX_T("_pututxline", U);
UTMPX_LOCK(U);
- if ((ux = __pututxline(&__utx__, utx)) != NULL && __utx__.utfile_system) {
+ if ((ux = __pututxline(__default_utx(), utx)) != NULL && __default_utx()->utfile_system) {
_utmpx_asl(ux); /* the equivalent of wtmpx and lastlogx */
#ifdef UTMP_COMPAT
_write_utmp_compat(ux);
struct utmpx *
pututxline(const struct utmpx *utx)
{
- return _pututxline(&__utx__, utx);
+ return _pututxline(__default_utx(), utx);
}
__private_extern__ struct utmpx *
int
utmpxname(const char *fname)
{
- return _utmpxname(&__utx__, fname);
+ return _utmpxname(__default_utx(), fname);
}
#ifdef UNIFDEF_LEGACY_UTMP_APIS
+++ /dev/null
-/*
- * Copyright (c) 2005, 2006, 2009 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include <string.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#ifndef VARIANT_DYLD
-#include <setjmp.h>
-#endif /* !VARIANT_DYLD */
-#include <sys/types.h>
-#include <unistd.h>
-#include <mach/mach_init.h>
-#include <mach/vm_map.h>
-#include <asl.h>
-#include <fcntl.h>
-#include <sys/syslog.h>
-#include <sys/time.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <pthread.h>
-#include <errno.h>
-#include <servers/bootstrap.h>
-#include <asl_ipc.h>
-
-#include "_simple.h"
-
-#ifndef VM_PAGE_SIZE
-#define VM_PAGE_SIZE 4096
-#endif
-
-#define SBUF_SIZE(s) (((SBUF *)(s))->b.end - ((SBUF *)(s))->b.buf + 1)
-/* we use a small buffer to minimize stack usage constraints */
-#define MYBUFSIZE 32
-
-typedef struct _BUF {
- char *buf;
- char *ptr;
- char *end;
- int fd;
- void (*full)(struct _BUF *);
-} BUF;
-
-typedef struct _SBUF {
- BUF b;
-#ifndef VARIANT_DYLD
- jmp_buf j;
-#endif /* !VARIANT_DYLD */
-} SBUF;
-
-#define ASL_SERVICE_NAME "com.apple.system.logger"
-
-static mach_port_t asl_port;
-static pthread_once_t asl_init_once = PTHREAD_ONCE_INIT;
-
-/* private extern exports from asl.c */
-const char *_asl_escape(unsigned char);
-
-/* flush the buffer */
-static void
-_flush(BUF *b)
-{
- char *buf = b->buf;
- int n = b->ptr - buf;
- int w;
-
- while(n > 0) {
- w = write(b->fd, buf, n);
- if(w < 0) {
- if(errno == EINTR || errno == EAGAIN)
- continue;
- break;
- }
- n -= w;
- buf += n;
- }
-}
-
-/* flush the buffer and reset the pointer */
-static void
-_flush_reset(BUF *b)
-{
- _flush(b);
- b->ptr = b->buf;
-}
-
-/* enlarge the buffer */
-static void
-_enlarge(BUF *b)
-{
- vm_address_t new;
- vm_size_t sold, snew;
- intptr_t diff;
-
- new = (vm_address_t)(b->end + 1);
- if(vm_allocate(mach_task_self(), &new, VM_PAGE_SIZE, 0) == 0) {
- /* page is adjacent */
- b->end += VM_PAGE_SIZE;
- return;
- }
- sold = SBUF_SIZE(b);
- snew = (sold + VM_PAGE_SIZE) & ~(VM_PAGE_SIZE - 1);
- if(vm_allocate(mach_task_self(), &new, snew, 1) != 0)
-#ifndef VARIANT_DYLD
- longjmp(((SBUF *)b)->j, 1); /* out of memory */
-#else /* VARIANT_DYLD */
- abort(); /* out of memory */
-#endif /* !VARIANT_DYLD */
- diff = new - (vm_address_t)b->buf;
- memcpy((void *)new, b->buf, sold);
- if((intptr_t)(b->buf) & (VM_PAGE_SIZE - 1)) {
- sold &= ~(VM_PAGE_SIZE - 1);
- b->buf = (char *)((intptr_t)(b->buf + VM_PAGE_SIZE) & ~(VM_PAGE_SIZE - 1));
- b->end = (char *)(new + snew - 1);
- } else
- b->end += diff + VM_PAGE_SIZE;
- if(sold > 0) {
- vm_deallocate(mach_task_self(), (vm_address_t)b->buf, sold);
- }
- b->buf = (char *)new;
- b->ptr += diff;
-}
-
-static inline void put_s(BUF *, _esc_func, const char *);
-/* output a single character */
-static inline void
-put_c(BUF *b, _esc_func esc, unsigned char c)
-{
- const char *cp;
-
- if(esc && (cp = esc(c)) != NULL)
- put_s(b, NULL, cp);
- else {
- if(b->ptr >= b->end)
- b->full(b);
- *b->ptr++ = c;
- }
-}
-
-/* output a null-terminated string */
-static inline void
-put_s(BUF *b, _esc_func esc, const char *str)
-{
- while(*str)
- put_c(b, esc, *str++);
-}
-
-/* output a string of the specified size */
-static inline void
-put_n(BUF *b, _esc_func esc, const char *str, int n)
-{
- while(n-- > 0)
- put_c(b, esc, *str++);
-}
-
-/*
- * Output the signed decimal string representing the number in "in". "width" is
- * the minimum field width, and "zero" is a boolean value, true for zero padding
- * (otherwise blank padding).
- */
-static void
-dec(BUF *b, _esc_func esc, long long in, int width, int zero)
-{
- char buf[32];
- char *cp = buf + sizeof(buf);
- int pad;
- int neg = 0;
- unsigned long long n = (unsigned long long)in;
-
- if(in < 0) {
- neg++;
- width--;
- n = ~n + 1;
- }
- *--cp = 0;
- if(n) {
- while(n) {
- *--cp = (n % 10) + '0';
- n /= 10;
- }
- } else
- *--cp = '0';
- if(neg && zero) {
- put_c(b, esc, '-');
- neg = 0;
- }
- pad = width - strlen(cp);
- zero = zero ? '0' : ' ';
- while(pad-- > 0)
- put_c(b, esc, zero);
- if(neg)
- put_c(b, esc, '-');
- put_s(b, esc, cp);
-}
-
-/*
- * Output the hex string representing the number in "n". "width" is the
- * minimum field width, and "zero" is a boolean value, true for zero padding
- * (otherwise blank padding). "upper" is a boolean value, true for upper
- * case hex characters, lower case otherwise. "p" is a boolean value, true
- * if 0x should be prepended (for %p), otherwise nothing.
- */
-static char _h[] = "0123456789abcdef";
-static char _H[] = "0123456789ABCDEF";
-static char _0x[] = "0x";
-
-static void
-hex(BUF *b, _esc_func esc, unsigned long long n, int width, int zero, int upper, int p)
-{
- char buf[32];
- char *cp = buf + sizeof(buf);
- char *h = upper ? _H : _h;
-
- *--cp = 0;
- if(n) {
- while(n) {
- *--cp = h[n & 0xf];
- n >>= 4;
- }
- } else
- *--cp = '0';
- if(p) {
- width -= 2;
- if(zero) {
- put_s(b, esc, _0x);
- p = 0;
- }
- }
- width -= strlen(cp);
- zero = zero ? '0' : ' ';
- while(width-- > 0)
- put_c(b, esc, zero);
- if(p)
- put_s(b, esc, _0x);
- put_s(b, esc, cp);
-}
-
-/*
- * Output the unsigned decimal string representing the number in "n". "width"
- * is the minimum field width, and "zero" is a boolean value, true for zero
- * padding (otherwise blank padding).
- */
-static void
-udec(BUF *b, _esc_func esc, unsigned long long n, int width, int zero)
-{
- char buf[32];
- char *cp = buf + sizeof(buf);
- int pad;
-
- *--cp = 0;
- if(n) {
- while(n) {
- *--cp = (n % 10) + '0';
- n /= 10;
- }
- } else
- *--cp = '0';
- pad = width - strlen(cp);
- zero = zero ? '0' : ' ';
- while(pad-- > 0)
- put_c(b, esc, zero);
- put_s(b, esc, cp);
-}
-
-/*
- * Output the unsigned decimal string representing the number in "n", rounded
- * to the nearest MB, KB or b. "width" is the minimum field width, and "zero"
- * is a boolean value, true for zero padding (otherwise blank padding).
- */
-static void
-ydec(BUF *b, _esc_func esc, unsigned long long n, int width, int zero)
-{
- if(n >= 10 * (1 << 20)) {
- n += (1 << 19);
- udec(b, esc, n >> 20, width, zero);
- put_s(b, esc, "MB");
- } else if (n >= 10 * (1 << 10)) {
- n += (1 << 9);
- udec(b, esc, n >> 10, width, zero);
- put_s(b, esc, "KB");
- } else {
- udec(b, esc, n, width, zero);
- put_s(b, esc, "b");
- }
-}
-
-/*
- * The actual engine for all the _simple_*printf routines.
- */
-static void
-__simple_bprintf(BUF *b, _esc_func esc, const char *fmt, va_list ap)
-{
- while(*fmt) {
- int lflag, zero, width;
- char *cp;
- if(!(cp = strchr(fmt, '%'))) {
- put_s(b, esc, fmt);
- break;
- }
- put_n(b, esc, fmt, cp - fmt);
- fmt = cp + 1;
- if(*fmt == '%') {
- put_c(b, esc, '%');
- fmt++;
- continue;
- }
- lflag = zero = width = 0;
- for(;;) {
- switch(*fmt) {
- case '0':
- zero++;
- fmt++;
- /* drop through */
- case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- while(*fmt >= '0' && *fmt <= '9')
- width = 10 * width + (*fmt++ - '0');
- continue;
- case 'c':
- zero = zero ? '0' : ' ';
- width--;
- while(width-- > 0)
- put_c(b, esc, zero);
- put_c(b, esc, va_arg(ap, int));
- break;
- case 'd': case 'i':
- switch(lflag) {
- case 0:
- dec(b, esc, va_arg(ap, int), width, zero);
- break;
- case 1:
- dec(b, esc, va_arg(ap, long), width, zero);
- break;
- default:
- dec(b, esc, va_arg(ap, long long), width, zero);
- break;
- }
- break;
- case 'l':
- lflag++;
- fmt++;
- continue;
- case 'p':
- hex(b, esc, (unsigned long)va_arg(ap, void *), width, zero, 0, 1);
- break;
- case 's':
- cp = va_arg(ap, char *);
- width -= strlen(cp);
- zero = zero ? '0' : ' ';
- while(width-- > 0)
- put_c(b, esc, zero);
- put_s(b, esc, cp);
- break;
- case 'u':
- switch(lflag) {
- case 0:
- udec(b, esc, va_arg(ap, unsigned int), width, zero);
- break;
- case 1:
- udec(b, esc, va_arg(ap, unsigned long), width, zero);
- break;
- default:
- udec(b, esc, va_arg(ap, unsigned long long), width, zero);
- break;
- }
- break;
- case 'X': case 'x':
- switch(lflag) {
- case 0:
- hex(b, esc, va_arg(ap, unsigned int), width, zero,
- *fmt == 'X', 0);
- break;
- case 1:
- hex(b, esc, va_arg(ap, unsigned long), width, zero,
- *fmt == 'X', 0);
- break;
- default:
- hex(b, esc, va_arg(ap, unsigned long long), width, zero,
- *fmt == 'X', 0);
- break;
- }
- break;
- case 'y':
- switch(lflag) {
- case 0:
- ydec(b, esc, va_arg(ap, unsigned int), width, zero);
- break;
- case 1:
- ydec(b, esc, va_arg(ap, unsigned long), width, zero);
- break;
- default:
- ydec(b, esc, va_arg(ap, unsigned long long), width, zero);
- break;
- }
- break;
- default:
- put_c(b, esc, *fmt);
- break;
- }
- break;
- }
- fmt++;
- }
-}
-
-/*
- * A simplified vfprintf variant. The format string is interpreted with
- * arguments from the va_list, and the results are written to the given
- * file descriptor.
- */
-void
-_simple_vdprintf(int fd, const char *fmt, va_list ap)
-{
- BUF b;
- char buf[MYBUFSIZE];
-
- b.buf = buf;
- b.fd = fd;
- b.ptr = b.buf;
- b.end = b.buf + MYBUFSIZE;
- b.full = _flush_reset;
- __simple_bprintf(&b, NULL, fmt, ap);
- _flush(&b);
-}
-
-/*
- * A simplified fprintf variant. The format string is interpreted with
- * arguments from the variable argument list, and the results are written
- * to the given file descriptor.
- */
-void
-_simple_dprintf(int fd, const char *fmt, ...)
-{
- va_list ap;
-
- va_start(ap, fmt);
- _simple_vdprintf(fd, fmt, ap);
- va_end(ap);
-}
-
-/*
- * A simplified string allocate routine. Pass the opaque pointer to structure
- * to _simple_*sprintf() routines. Use _simple_string() to retrieve the
- * current string (the string is guaranteed to be null terminated only on
- * the call to _simple_string()). Use _simple_sfree() to free the structure
- * and string memory.
- */
-_SIMPLE_STRING
-_simple_salloc(void)
-{
- SBUF *b;
-
- if(vm_allocate(mach_task_self(), (vm_address_t *)&b, VM_PAGE_SIZE, 1))
- return NULL;
- b->b.ptr = b->b.buf = (char *)b + sizeof(SBUF);
- b->b.end = (char *)b + VM_PAGE_SIZE - 1;
- b->b.full = _enlarge;
- return (_SIMPLE_STRING)b;
-}
-
-/*
- * The format string is interpreted with arguments from the va_list, and the
- * results are appended to the string maintained by the opaque structure, as
- * returned by a previous call to _simple_salloc(). Non-zero is returned on
- * out-of-memory error.
- */
-int
-_simple_vsprintf(_SIMPLE_STRING b, const char *fmt, va_list ap)
-{
- return _simple_vesprintf(b, NULL, fmt, ap);
-}
-
-/*
- * The format string is interpreted with arguments from the variable argument
- * list, and the results are appended to the string maintained by the opaque
- * structure, as returned by a previous call to _simple_salloc(). Non-zero is
- * returned on out-of-memory error.
- */
-int
-_simple_sprintf(_SIMPLE_STRING b, const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = _simple_vesprintf(b, NULL, fmt, ap);
- va_end(ap);
- return ret;
-}
-
-/*
- * Like _simple_vsprintf(), except __esc is a function to call on each
- * character; the function returns NULL if the character should be passed
- * as is, otherwise, the returned character string is used instead.
- */
-int
-_simple_vesprintf(_SIMPLE_STRING b, _esc_func esc, const char *fmt, va_list ap)
-{
-#ifndef VARIANT_DYLD
- if(setjmp(((SBUF *)b)->j))
- return -1;
-#endif /* !VARIANT_DYLD */
- __simple_bprintf((BUF *)b, esc, fmt, ap);
- return 0;
-}
-
-/*
- * Like _simple_sprintf(), except __esc is a function to call on each
- * character; the function returns NULL if the character should be passed
- * as is, otherwise, the returned character string is used instead.
- */
-int _simple_esprintf(_SIMPLE_STRING b, _esc_func esc, const char *fmt, ...)
-{
- va_list ap;
- int ret;
-
- va_start(ap, fmt);
- ret = _simple_vesprintf(b, esc, fmt, ap);
- va_end(ap);
- return ret;
-}
-
-/*
- * Return the null terminated string from the opaque structure, as returned
- * by a previous call to _simple_salloc().
- */
-char *
-_simple_string(_SIMPLE_STRING b)
-{
- *((BUF *)b)->ptr = 0;
- return ((BUF *)b)->buf;
-}
-
-/*
- * Reposition the pointer to the first null in the buffer. After a call to
- * _simple_string, the buffer can be modified, and shrunk.
- */
-void
-_simple_sresize(_SIMPLE_STRING b)
-{
- ((BUF *)b)->ptr = ((BUF *)b)->buf + strlen(((BUF *)b)->buf);
-}
-
-/*
- * Append the null-terminated string to the string associated with the opaque
- * structure. Non-zero is returned on out-of-memory error.
- */
-int
-_simple_sappend(_SIMPLE_STRING b, const char *str)
-{
- return _simple_esappend(b, NULL, str);
-}
-
-/*
- * Like _simple_sappend(), except __esc is a function to call on each
- * character; the function returns NULL if the character should be passed
- * as is, otherwise, the returned character string is used instead.
- */
-int _simple_esappend(_SIMPLE_STRING b, _esc_func esc, const char *str)
-{
-#ifndef VARIANT_DYLD
- if(setjmp(((SBUF *)b)->j))
- return -1;
-#endif /* !VARIANT_DYLD */
- put_s((BUF *)b, esc, str);
- return 0;
-}
-
-/*
- * Write the string associated with the opaque structure to the file descriptor.
- */
-void
-_simple_put(_SIMPLE_STRING b, int fd)
-{
- ((BUF *)b)->fd = fd;
- _flush((BUF *)b);
-}
-
-/*
- * Write the string associated with the opaque structure and a trailing newline,
- * to the file descriptor.
- */
-void
-_simple_putline(_SIMPLE_STRING b, int fd)
-{
- ((BUF *)b)->fd = fd;
- *((BUF *)b)->ptr++ = '\n';
- _flush((BUF *)b);
- ((BUF *)b)->ptr--;
-}
-
-/*
- * Free the opaque structure, and the associated string.
- */
-void
-_simple_sfree(_SIMPLE_STRING b)
-{
- vm_size_t s;
-
- if(b == NULL) return;
- if(((intptr_t)(((SBUF *)b)->b.buf) & (VM_PAGE_SIZE - 1)) == 0) {
- vm_deallocate(mach_task_self(), (vm_address_t)((SBUF *)b)->b.buf, SBUF_SIZE(b));
- s = VM_PAGE_SIZE;
- } else
- s = ((SBUF *)b)->b.end - (char *)b + 1;
- vm_deallocate(mach_task_self(), (vm_address_t)b, s);
-}
-
-/*
- * Simplified ASL log interface; does not use malloc. Unfortunately, this
- * requires knowledge of the format used by ASL.
- */
-
-static void
-_simple_asl_init(void)
-{
- kern_return_t status;
- char *str;
-
- if (asl_port == MACH_PORT_NULL)
- {
- str = getenv("ASL_DISABLE");
- if ((str != NULL) && (!strcmp(str, "1"))) return;
-
- status = bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &asl_port);
- if (status != KERN_SUCCESS) asl_port = MACH_PORT_NULL;
- }
-}
-
-void
-_simple_asl_log_prog(int level, const char *facility, const char *message, const char *prog)
-{
- _SIMPLE_STRING b;
-
- if (pthread_once(&asl_init_once, _simple_asl_init) != 0) return;
- if (asl_port == MACH_PORT_NULL) return;
-
- if ((b = _simple_salloc()) == NULL) return;
-
- do
- {
- kern_return_t kstatus;
- vm_address_t out;
- int outlen;
- char *cp;
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
-
- if (_simple_sprintf(b, " 0 [Time ", 0)) break;
- if (_simple_esprintf(b, _asl_escape, "%lu", tv.tv_sec)) break;
- if (_simple_sappend(b, "] [Sender ")) break;
- if (_simple_esappend(b, _asl_escape, prog)) break;
- if (_simple_sappend(b, "] [Level ")) break;
- if (_simple_esprintf(b, _asl_escape, "%d", level)) break;
- if (_simple_sappend(b, "] [Facility ")) break;
- if (_simple_esappend(b, _asl_escape, facility)) break;
- if (_simple_sappend(b, "] [Message ")) break;
- if (_simple_esappend(b, _asl_escape, message)) break;
-
- /* remove trailing (escaped) newlines */
- cp = _simple_string(b);
- cp += strlen(cp);
- for (;;)
- {
- cp -= 2;
- if (strcmp(cp, "\\n") != 0) break;
- *cp = 0;
- }
-
- _simple_sresize(b);
-
- if (_simple_sappend(b, "]\n")) break;
-
- cp = _simple_string(b);
-
- /*
- * The MIG defs for _asl_server_message specifies "dealloc",
- * so we copy the string into a new vm buffer and send that.
- */
- outlen = strlen(cp);
- kstatus = vm_allocate(mach_task_self(), &out, outlen, TRUE);
- if (kstatus != KERN_SUCCESS) break;
-
- memcpy((void *)out, cp, outlen);
- _asl_server_message(asl_port, (caddr_t)out, outlen);
- } while (0);
-
- _simple_sfree(b);
-}
-
-void
-_simple_asl_log(int level, const char *facility, const char *message)
-{
- _simple_asl_log_prog(level, facility, message, getprogname());
-}
+++ /dev/null
-/*
- * Copyright (c) 2006, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include <sys/cdefs.h>
-#include <stdarg.h>
-#include <asl.h>
-
-typedef void *_SIMPLE_STRING;
-typedef const char *_esc_func(unsigned char);
-
-__BEGIN_DECLS
-/*
- * A simplified vfprintf variant. The format string is interpreted with
- * arguments from the va_list, and the results are written to the given
- * file descriptor.
- */
-void _simple_vdprintf(int __fd, const char *__fmt, va_list __ap);
-
-/*
- * A simplified fprintf variant. The format string is interpreted with
- * arguments from the variable argument list, and the results are written
- * to the given file descriptor.
- */
-void _simple_dprintf(int __fd, const char *__fmt, ...);
-
-/*
- * A simplified string allocate routine. Pass the opaque pointer to structure
- * to _simple_*sprintf() routines. Use _simple_string() to retrieve the
- * current string (the string is guaranteed to be null terminated only on
- * the call to _simple_string()). Use _simple_sfree() to free the structure
- * and string memory.
- */
-_SIMPLE_STRING _simple_salloc(void);
-
-/*
- * The format string is interpreted with arguments from the va_list, and the
- * results are appended to the string maintained by the opaque structure, as
- * returned by a previous call to _simple_salloc(). Non-zero is returned on
- * out-of-memory error.
- */
-int _simple_vsprintf(_SIMPLE_STRING __b, const char *__fmt, va_list __ap);
-
-/*
- * The format string is interpreted with arguments from the variable argument
- * list, and the results are appended to the string maintained by the opaque
- * structure, as returned by a previous call to _simple_salloc(). Non-zero is
- * returned on out-of-memory error.
- */
-int _simple_sprintf(_SIMPLE_STRING __b, const char *__fmt, ...);
-
-/*
- * Like _simple_vsprintf(), except __esc is a function to call on each
- * character; the function returns NULL if the character should be passed
- * as is, otherwise, the returned character string is used instead.
- */
-int _simple_vesprintf(_SIMPLE_STRING __b, _esc_func __esc, const char *__fmt, va_list __ap);
-
-/*
- * Like _simple_sprintf(), except __esc is a function to call on each
- * character; the function returns NULL if the character should be passed
- * as is, otherwise, the returned character string is used instead.
- */
-int _simple_esprintf(_SIMPLE_STRING __b, _esc_func __esc, const char *__fmt, ...);
-
-/*
- * Return the null terminated string from the opaque structure, as returned
- * by a previous call to _simple_salloc().
- */
-char *_simple_string(_SIMPLE_STRING __b);
-
-/*
- * Reposition the pointer to the first null in the buffer. After a call to
- * _simple_string, the buffer can be modified, and shrunk.
- */
-void _simple_sresize(_SIMPLE_STRING __b);
-
-/*
- * Append the null-terminated string to the string associated with the opaque
- * structure. Non-zero is returned on out-of-memory error.
- */
-int _simple_sappend(_SIMPLE_STRING __b, const char *__str);
-
-/*
- * Like _simple_sappend(), except __esc is a function to call on each
- * character; the function returns NULL if the character should be passed
- * as is, otherwise, the returned character string is used instead.
- */
-int _simple_esappend(_SIMPLE_STRING __b, _esc_func __esc, const char *__str);
-
-/*
- * Write the string associated with the opaque structure to the file descriptor.
- */
-void _simple_put(_SIMPLE_STRING __b, int __fd);
-
-/*
- * Write the string associated with the opaque structure and a trailing newline,
- * to the file descriptor.
- */
-void _simple_putline(_SIMPLE_STRING __b, int __fd);
-
-/*
- * Free the opaque structure, and the associated string.
- */
-void _simple_sfree(_SIMPLE_STRING __b);
-
-/*
- * Simplified ASL log interface; does not use malloc. Unfortunately, this
- * requires knowledge of the format used by ASL.
- */
-void _simple_asl_log(int __level, const char *__facility, const char *__message);
-void _simple_asl_log_prog(int level, const char *facility, const char *message, const char *progname);
-__END_DECLS
+++ /dev/null
-.\" Copyright (c) 2005-2011 Apple Inc.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 4. Neither the name of Apple Computer nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\"
-.Dd October 1, 2011
-.Dt asl 3
-.Os "Mac OS X"
-.Sh NAME
-.Nm asl_add_log_file ,
-.Nm asl_close ,
-.Nm asl_close_auxiliary_file ,
-.Nm asl_create_auxiliary_file ,
-.Nm asl_free ,
-.Nm asl_get ,
-.Nm asl_key ,
-.Nm asl_log ,
-.Nm asl_log_auxiliary_location ,
-.Nm asl_log_descriptor ,
-.Nm asl_new ,
-.Nm asl_open ,
-.Nm asl_open_from_file ,
-.Nm asl_remove_log_file ,
-.Nm asl_search ,
-.Nm asl_send ,
-.Nm asl_set ,
-.Nm asl_set_filter ,
-.Nm asl_set_query ,
-.Nm asl_unset ,
-.Nm asl_vlog ,
-.Nm aslresponse_free ,
-.Nm aslresponse_next
-.Nd system log message sending and searching functions
-.Sh SYNOPSIS
-.Fd #include <asl.h>
-.\"
-.Ft int
-.Fo asl_add_log_file
-.Fa "aslclient asl"
-.Fa "int descriptor"
-.Fc
-.Ft void
-.Fo asl_close
-.Fa "aslclient asl"
-.Fc
-.Ft void
-.Fo asl_close_auxiliary_file
-.Fa "int descriptor"
-.Fc
-.Ft void
-.Fo asl_create_auxiliary_file
-.Fa "aslmsg msg"
-.Fa "const char *title"
-.Fa "const char *uti"
-.Fa "int *out_descriptor"
-.Fc
-.Ft void
-.Fo asl_free
-.Fa "aslmsg msg"
-.Fc
-.Ft const char *
-.Fo asl_get
-.Fa "aslmsg msg"
-.Fa "const char *key"
-.Fc
-.Ft const char *
-.Fo asl_key
-.Fa "aslmsg msg"
-.Fa "uint32_t n"
-.Fc
-.Ft int
-.Fo asl_log
-.Fa "aslclient asl"
-.Fa "aslmsg msg"
-.Fa "int level"
-.Fa "const char *format"
-.Fa "..."
-.Fc
-.Ft void
-.Fo asl_log_auxiliary_location
-.Fa "aslmsg msg"
-.Fa "const char *title"
-.Fa "const char *uti"
-.Fa "const char *url"
-.Fc
-.Ft int
-.Fo asl_log_descriptor
-.Fa "aslclient asl"
-.Fa "aslmsg msg"
-.Fa "int level"
-.Fa "int descriptor"
-.Fa "uint32_t fd_type"
-.Fc
-.Ft aslmsg
-.Fo asl_new
-.Fa "uint32_t type"
-.Fc
-.Ft aslclient
-.Fo asl_open
-.Fa "const char *ident"
-.Fa "const char *facility"
-.Fa "uint32_t opts"
-.Fc
-.Ft aslclient
-.Fo asl_open_from_file
-.Fa "int descriptor"
-.Fa "const char *ident"
-.Fa "const char *facility"
-.Fc
-.Ft int
-.Fo asl_remove_log_file
-.Fa "aslclient asl"
-.Fa "int descriptor"
-.Fc
-.Ft aslresponse
-.Fo asl_search
-.Fa "aslclient asl"
-.Fa "aslmsg msg"
-.Fc
-.Ft int
-.Fo asl_send
-.Fa "aslclient asl"
-.Fa "aslmsg msg"
-.Fc
-.Ft int
-.Fo asl_set
-.Fa "aslmsg msg"
-.Fa "const char *key"
-.Fa "const char *value"
-.Fc
-.Ft int
-.Fo asl_set_filter
-.Fa "aslclient asl"
-.Fa "int f"
-.Fc
-.Ft int
-.Fo asl_set_query
-.Fa "aslmsg msg"
-.Fa "const char *key"
-.Fa "const char *value"
-.Fa "uint32_t op"
-.Fc
-.Ft int
-.Fo asl_unset
-.Fa "aslmsg msg"
-.Fa "const char *key"
-.Fc
-.Ft int
-.Fo asl_vlog
-.Fa "aslclient asl"
-.Fa "aslmsg msg"
-.Fa "int level"
-.Fa "const char *format"
-.Fa "va_list ap"
-.Fc
-.Ft void
-.Fo aslresponse_free
-.Fa "aslresponse r"
-.Fc
-.Ft aslmsg
-.Fo aslresponse_next
-.Fa "aslresponse r"
-.Fc
-.Sh DESCRIPTION
-These routines provide an interface to the Apple System Log facility.
-They are intended to be a replacement for the
-.Xr syslog 3
-API, which will continue to be supported for backwards compatibility.
-The new API allows client applications
-to create flexible, structured messages and send them to the
-.Nm syslogd
-server, where they may undergo additional processing.
-Messages received by the server are saved in a data store
-(subject to input filtering constraints).
-This API permits clients to create queries
-and search the message data store for matching messages.
-.Pp
-An introduction to the concepts underlying this interface follows the interface summary below.
-.Ss INTERFACE SUMMARY
-.Fo asl_open
-.Fa ident
-.Fa facility
-.Fa opts
-.Fc
-creates and returns a client handle, or NULL if an error occurs in the library.
-Messages sent using this handle will default to having the string
-.Ar ident
-as the value associated with the ASL_KEY_SENDER key, and the value
-.Ar facility
-associated with the ASL_KEY_FACILITY key.
-Several options are available, as described in the
-.Sx CLIENT HANDLES
-section.
-.Pp
-Multi-threaded applications should create one client handle for each thread that logs messages.
-A client may use NULL as a client handle, in which case a default handle managed by the library will be used.
-A NULL handle may be used safely by multiple threads, but the threads will contend for a single internal lock when
-sending log messages using a NULL handle.
-.Pp
-.Fo asl_close
-.Fa asl
-.Fc
-closes the client handle
-.Ar asl
-and releases its associated resources.
-.Pp
-.Fo asl_add_log_file
-.Fa asl
-.Fa descriptor
-.Fc
-adds the file descriptor
-.Ar descriptor
-to the a set of file descriptors associated with the client handle
-.Ar asl .
-Each log message sent by that client handle is also written to these file descriptors.
-Returns 0 on success, non-zero on failure.
-.Pp
-.Fo asl_remove_log_file
-.Fa asl
-.Fa descriptor
-.Fc
-removes a file descriptor from the set of file descriptors associated with a client handle.
-Returns 0 on success, non-zero on failure.
-.Pp
-.Fo asl_new
-.Fa type
-.Fc
-allocates and returns an aslmsg structure, or NULL in the case of a failure in the library.
-The
-.Ar type
-argument must be ASL_TYPE_MSG or ASL_TYPE_QUERY.
-.Pp
-.Fo asl_free
-.Fa msg
-.Fc
-frees an aslmsg and releases resources associated with the structure.
-.Pp
-.Fo asl_set
-.Fa msg
-.Fa key
-.Fa value
-.Fc
-creates a new key and value in an aslmsg structure, or replaces the value of an existing key.
-Returns 0 on success, non-zero on failure.
-.Pp
-.Fo asl_set_query
-.Fa msg
-.Fa key
-.Fa op
-.Fa value
-.Fc
-is used to construct searches.
-It is similar to
-.Fn asl_set ,
-except that it takes an additional
-.Ar op
-(operation) argument.
-Creates a new (key, op, value) triple in an aslmsg structure,
-or replaces the value and operation for an existing key.
-See the
-.Sx SEARCHING
-section for more information.
-Returns 0 on success, non-zero on failure.
-.Pp
-.Fo asl_unset
-.Fa msg
-.Fa key
-.Fc
-removes a key and its associated value from an aslmsg structure.
-Returns 0 on success, non-zero on failure.
-.Pp
-.Fo asl_key
-.Fa msg
-.Fa n
-.Fc
-returns the nth key in an aslmsg (beginning at zero),
-allowing an application to iterate through the keys.
-Returns NULL if
-.Ar n
-indexes beyond the number of keys in
-.Ar msg .
-.Pp
-.Fo asl_get
-.Fa msg
-.Fa key
-.Fc
-returns the value associated with
-.Ar key
-in the aslmsg
-.Ar msg .
-Returns NULL if
-.Ar msg
-does not contain
-. Ar key .
-.Pp
-.Fo asl_set_filter
-.Fa asl
-.Fa f
-.Fc
-sets a filter for messages being sent to the server.
-The filter is a bitmask representing priority levels.
-Only messages having a priority level with a corresponding bit set in the filter mask are sent to the
-.Nm syslogd
-server.
-The filter does not control writes to additional files associated with the client handle using
-.Fn asl_add_log_file .
-Returns the previous filter value.
-.Pp
-.Fo asl_log
-.Fa asl
-.Fa msg
-.Fa level
-.Fa format
-.Fa args...
-.Fc
-sends a log to the server (subject to filtering, see
-.Fn asl_set_filter
-above) and to any file descriptors associated with the client handle
-.Ar asl .
-The
-.Ar msg
-argument may contain any keys and values, which will be formatted as part of the log message.
-The value for ASL_KEY_LEVEL is supplied by the
-.Ar level
-argument.
-The value for ASL_KEY_MESSAGE is computed from
-.Ar format
-and the associated arguments
-.Ar args... .
-Normal
-.Fn printf
-style argument processing is applied to the format and the arguments.
-The format may also contain
-.Dq %m
-which will be substituted with the string value corresponding to the current
-.Em errno .
-.Pp
-The ASL_PREFILTER_LOG(asl, msg, level, format, ...) macro may be used in
-place of
-.Fn asl_log .
-The macro avoids processing the variable argument list in those cases where
-the message would be filtered out due to filter settings, would not be
-written to a log file associated with the aslclient, or would not be
-written to stderr.
-The macro may provide a performance benefit for some applications.
-Details on filter setting, additional log files, and aslclient options
-are described below in this manual.
-.Pp
-.Fo asl_vlog
-.Fa asl
-.Fa msg
-.Fa level
-.Fa format
-.Fa ap
-.Fc
-is similar to
-.Fn asl_log
-except that it takes a va_list argument.
-.Pp
-.Fo asl_send
-.Fa asl
-.Fa msg
-.Fc
-is similar to
-.Fn asl_log ,
-exceopt the value for ASL_KEY_MESSAGE is taken from
-.Ar msg
-rather than being constructed using a
-.Fn printf
-style syntax.
-.Pp
-.Fo asl_log_descriptor
-.Fa asl
-.Fa msg
-.Fa level
-.Fa descriptor
-.Fa fd_type
-.Fc
-provides functionality to use file descriptors to send logging data to ASL.
-.Ar asl
-is retained by ASL and must still be closed by the caller by calling
-.Fn asl_close
-if the caller loses reference to it.
-.Ar msg
-is copied by ASL and similarly must still be freed by the caller by calling
-.Fn asl_free
-if the caller loses reference to it. Any changes made to it after calling
-.Fn asl_log_descriptor()
-are not applicable to the message used.
-.Ar descriptor is treated differentlty based on the value of
-.Ar fd_type .
-.Pp
-If
-.Ar fd_type
-is ASL_LOG_DESCRIPTOR_READ, the descriptor must be open for read access. ASL
-uses
-.Xr dispatch 2
-to read from the descriptor as data becomes available. These data are line
-buffered and passed to
-.Fn asl_log .
-When EOF is read, ASL will
-.Xr close 2
-.Ar descriptor ..
-.Pp
-If
-.Ar fd_type
-is ASL_LOG_DESCRIPTOR_WRITE, the descriptor is closed and a new writable
-descriptor is created with the same fileno. Any data written to this new
-descriptor are line buffered and passed to
-.Fn asl_log .
-When EOF is sent, no further data are read. The caller is responsible for
-closing the new descriptor. One common use for this API is to redirect writes
-to stdout or stderr to ASL by passing STDOUT_FILENO or STDERR_FILENO as
-.Ar descriptor .
-.Pp
-.Fo asl_search
-.Fa asl
-.Fa msg
-.Fc
-searches for messages that match the keys and values in
-.Ar msg ,
-subject to matching operations associated with those keys and values.
-The
-.Ar msg
-argument should be constructed using
-.Fn asl_set_query .
-See the
-.Sx SEARCHING
-section for details on constructing queries.
-Returns an aslresponse structure that contains matching log messages.
-NULL is returned in case of error or if there are no matching messages in the ASL database.
-.Pp
-.Fo aslresponse_next
-.Fa r
-.Fc
-iterates over an aslresponse structure returned by
-.Fn asl_search .
-Each call returns the next aslmsg in the response.
-Returns NULL when there are no further messages.
-.Pp
-.Fo aslresponse_free
-.Fa r
-.Fc
-frees the aslresponse structure
-.Ar r
-and all of its associated resources.
-.Pp
-.Fo asl_create_auxiliary_file
-.Fa msg
-.Fa title
-.Fa uti
-.Fa out_descriptor
-.Fc
-Creates an auxiliary file that may be used by the client to save arbitrary data.
-When the file is closed using
-.Fo asl_close_auxiliary_file
-.Fc ,
-.Nm syslogd
-will log the specified
-.Fa msg
-along with the
-.Fa title
-and the Uniform Type Identifier provided by
-.Fa uti .
-If a NULL value is supplied for
-.Fa uti
-the type
-.Dq public.data
-will be used.
-The
-.Nm Console
-application will display the message with a link to the file.
-.Pp
-Auxiliary files are saved in the ASL data store.
-They are automatically deleted at the same time that the log message expires.
-Messages expire in 7 days by default.
-A value set for the ASLExpireTime key will override the default.
-Read access for the auxiliary file will be the same as read access for
-.Fa msg .
-By default, messages (and auxiliary files) are world-readable.
-Access may be limited by setting values for the ReadUID and ReadGID keys.
-.Pp
-.Fo asl_close_auxiliary_file
-.Fa descriptor
-.Fc
-closes the file descriptor
-.Ar descriptor
-previously returned by a call to
-.Fn asl_create_auxiliary_file .
-.Pp
-.Fo asl_log_auxiliary_location
-.Fa msg
-.Fa title
-.Fa uti
-.Fa url
-.Fc
-will log the specified
-.Fa msg
-along with the
-.Fa title ,
-the Uniform Type Identifier provided by
-.Fa uti ,
-and the Uniform Resource Locator provided by
-.Fa url .
-The
-.Nm Console
-application will display the message with a link to the file.
-This allows a client to save data in an auxiliary file, but unlike
-.Fo asl_create_auxiliary_file
-.Fc ,
-the life-cycle of this file must be managed by some external system.
-The file will not be removed when the corresponding log message expired from the ASL data store.
-.Pp
-.Fo asl_open_from_file
-.Fa descriptor
-.Fa facility
-.Fa opts
-.Fc
-creates a client handle for an open file descriptor
-.Fa descriptor .
-This routine may be used in conjunction with
-.Fo asl_create_auxiliary_file
-.Fc
-or
-.Fo asl_log_auxiliary_location
-.Fc
-to save ASL format log messages in an auxiliary file.
-The UTI type
-.Dq com.apple.asl-file
-should be used for ASL format auxiliary files.
-.Pp
-Files with this format may be read from the command line using
-.Nm syslog Fl f Ar file ,
-or from the
-.Nm Console
-utility.
-.Pp
-The file must be open for read and write access.
-The file will be truncated and its existing contents will be lost.
-.Fo asl_close
-.Fc
-must be called to close the client handle when logging to this file is complete.
-The file should be closed using
-.Fo asl_close_auxiliary_file
-.Fc
-if it was returned by
-.Fo asl_create_auxiliary_file
-.Fc ,
-or
-.Fo close
-.Fc
-otherwise.
-.Pp
-The client handle may be used safely by multiple threads.
-The threads will contend for a single internal lock when saving log messages to a file.
-.Pp
-Note that messages with ReadUID or ReadGID values will simply be saved to the file,
-and will not effect read access to either the message or the file itself.
-Similarly, messages with ASLExpireTime values will be saved, but will not effect the
-life-cycle of either the individual messages or the file.
-.Ss MESSAGES
-At the core of this API is the aslmsg structure.
-Although the structure is opaque and may not be directly manipulated,
-it contains a list of key/value pairs.
-All keys and values are NUL-character terminated C language strings.
-UTF-8 encoding may be used for non-ASCII characters.
-.Pp
-Message structures are generally used to send log messages,
-and are created thusly:
-.Pp
- aslmsg m = asl_new(ASL_TYPE_MSG);
-.Pp
-Another message type, ASL_TYPE_QUERY,
-is used to create queries when searching the data store.
-Query type messages and searching are described in detail in the
-.Sx SEARCHING
-section.
-For the remainder of this section,
-the messages described will be of the ASL_TYPE_MSG variety.
-.Pp
-Each aslmsg contains a default set of keys
-and values that are associated with them.
-These keys are listed in the asl.h header file.
-They are:
-.Pp
- #define ASL_KEY_TIME "Time"
- #define ASL_KEY_HOST "Host"
- #define ASL_KEY_SENDER "Sender"
- #define ASL_KEY_FACILITY "Facility"
- #define ASL_KEY_PID "PID"
- #define ASL_KEY_UID "UID"
- #define ASL_KEY_GID "GID"
- #define ASL_KEY_LEVEL "Level"
- #define ASL_KEY_MSG "Message"
-.Pp
-Many of these correspond to equivalent parts of messages described in the
-.Xr syslog 3
-API.
-Values associated with these message keys are assigned appropriate defaults.
-The value for ASL_KEY_HOST is the local host name,
-the value associated with ASL_KEY_SENDER is the process name,
-the ASL_KEY_PID is the client's process ID number, and so on.
-.Pp
-Note the addition of the UID and GID keys.
-The values for UID and GID are set in library code by the message sender.
-The server will attempt to confirm the values,
-but no claim is made that these values cannot be maliciously overridden
-in an attempt to deceive a log message reader
-as to the identity of the sender of a message.
-The contents of log messages must be regarded as insecure.
-.Pp
-The
-.Xr asl 3
-API does not require a process to choose a facility name.
-The
-.Nm syslogd
-server will use a default value of
-.Dq user
-if a facility is not set.
-However, a client may set a facility name as an argument in the
-.Nm asl_open
-call, or by setting a specific value for the ASL_KEY_FACILITY in a message:
-.Pp
- asl_set(m, ASL_KEY_FACILITY, "com.somename.greatservice");
-.Pp
-An application may choose any facility name at will.
-Different facility names may be attached to different messages, perhaps to distinguish different subsystems in log messages.
-Developers are encouraged to adopt a
-.Dq Reverse ICANN
-naming convention to avoid conflicting facility names.
-.Pp
-Default values are set in the message for each of the keys listed above,
-except for ASL_KEY_MSG,
-which may be explicitly set at any time using the
-.Nm asl_set
-routine, or implicitly set at the time the message is sent using the
-.Nm asl_log
-or
-.Nm asl_vlog
-routines.
-These two routines also have an integer-level parameter
-for specifying the log priority.
-The ASL_KEY_LEVEL value is set accordingly.
-Finally, the value associated with ASL_KEY_TIME
-is set in the sending routine.
-.Pp
-Although it may appear that there is significant overhead required
-to send a log message using this API,
-the opposite is actually true.
-A simple
-.Dq Hello World
-program requires only:
-.Pp
- #include <asl.h>
- ...
- asl_log(NULL, NULL, ASL_LEVEL_INFO, "Hello World!");
-.Pp
-Both
-.Nm asl_log
-and
-.Nm asl_vlog
-will provide the appropriate default values
-when passed a NULL aslmsg argument.
-.Pp
-.Pp
-In this example, the aslclient argument is NULL.
-This is sufficient for a single-threaded application,
-or for an application which only sends log messages from a single thread.
-When logging from multiple threads,
-each thread
-.Em should
-open a separate client handle using
-.Nm asl_open .
-The client handle may then be closed when it is no longer required using
-.Nm asl_close .
-Multiple threads may log messages safely using a NULL aslclient argument,
-but the library will use an internal lock, so that in fact only one thread
-will log at a time.
-.Pp
-When an application requires additional keys and values
-to be associated with each log message,
-a single message structure may be allocated and set up as
-.Dq template
-message of sorts:
-.Pp
- aslmsg m = asl_new(ASL_TYPE_MSG);
- asl_set(m, ASL_KEY_FACILITY, "com.secrets.r.us");
- asl_set(m, "Clearance", "Top Secret");
- ...
- asl_log(NULL, m, ASL_LEVEL_NOTICE, "Message One");
- ...
- asl_log(NULL, m, ASL_LEVEL_ERR, "Message Two");
-.Pp
-The message structure will carry the values set for the
-.Dq Facility
-and
-.Dq Clearance
-keys so that they are used in each call to
-.Nm asl_log ,
-while the log level and the message text
-are taken from the calling parameters.
-.Pp
-The
-.Ar format
-argument to
-.Nm asl_log
-and
-.Nm asl_vlog
-is identical to
-.Xr printf 3 ,
-and may include
-.Ql %m ,
-which is replaced by the current error message
-(as denoted by the global variable
-.Va errno ;
-see
-.Xr strerror 3 . )
-.Pp
-Key/value pairs may be removed from a message structure with
-.Nm asl_unset .
-A message may be freed using
-.Nm asl_free .
-.Pp
-The
-.Nm asl_send
-routine is used by
-.Nm asl_log
-and
-.Nm asl_vlog
-to transmit a message to the server.
-This routine sets the value associated with ASL_KEY_TIME
-and sends the message.
-It may be called directly if all of a message's key/value pairs
-have been created using
-.Nm asl_set .
-.Ss SECURITY
-Messages that are sent to the
-.Nm syslogd
-server may be saved in a message store.
-The store may be searched using
-.Nm asl_search ,
-as described below.
-By default, all messages are readable by any user.
-However, some applications may wish to restrict read access
-for some messages.
-To accomodate this,
-a client may set a value for the "ReadUID" and "ReadGID" keys.
-These keys may be associated with a value
-containing an ASCII representation of a numeric UID or GID.
-Only the root user (UID 0),
-the user with the given UID,
-or a member of the group with the given GID
-may fetch access-controlled messages from the database.
-.Pp
-Although the ASL system does not require a "Facility" key in a message,
-many processes specify a "Facility" value similar
-to the common usage of the BSD
-.Nm syslog
-API, although developers are encouraged to adopt facility names that make sense for their application.
-A
-.Dq Reverse ICANN
-naming convention (e.g. "com.apple.system.syslog") should be adopted to avoid conflicting names.
-The ASL system generally allows any string to be used as a facility value,
-with one exception.
-The value "com.apple.system",
-or any string that has "com.apple.system" as a prefix,
-may only be used by processes running with the UID 0.
-This allows system processes to log messages that can not be "spoofed" by user processes.
-Non-UID 0 client processes that specify "com.apple.system" as a facility, will be assigned the value "user"
-by the
-.Nm syslogd
-server.
-.Ss CLIENT HANDLES
-When logging is done from a single thread,
-a NULL value may be used in any of the routines
-that require an aslclient argument.
-In this case, the library will open an internal client handle
-on behalf of the application.
-.Pp
-If multiple threads must do logging,
-or if client options are desired,
-then the application should call
-.Nm asl_open
-to create a client handle for each thread.
-As a convenience,
-the
-.Nm asl_open
-routine may be given an ident argument,
-which becomes the default value for the ASL_KEY_SENDER key,
-and a facility argument,
-which becomes the value associated with the ASL_KEY_FACILITY key.
-.Pp
-Several options are available when creating a client handle.
-They are:
-.Pp
-.Bl -tag -width "ASL_OPT_NO_REMOTE" -compact
-.It ASL_OPT_STDERR
-adds stderr as an output file descriptor
-.It ASL_OPT_NO_DELAY
-connects to the server immediately
-.It ASL_OPT_NO_REMOTE
-disables remote-control filter adjustment
-.El
-.Pp
-ASL_OPT_NO_DELAY makes the client library connect to the
-.Nm syslogd
-server at the time that
-.Nm asl_open
-is called, rather than waiting for the first message to be sent.
-Opening the connection is quite fast, but some applications may want to avoid any unnecessary delays when calling
-.Nm asl_log ,
-.Nm asl_vlog ,
-or
-.Nm asl_send .
-.Pp
-See the FILTERING section below, and the
-.Xr syslog 1
-for additional details on filter controls.
-.Pp
-A client handle is closed and it's resources released using
-.Nm asl_close .
-Note that if additional file descriptors were added to the handle,
-either using the ASL_OPT_STDERR option
-or afterwards with the
-.Nm asl_add_log_file
-routine, those file descriptors are not closed by
-.Nm asl_close .
-.Ss LOGGING TO ADDITIONAL FILES
-If a client handle is opened with the ASL_OPT_STDERR option to
-.Nm asl_open ,
-a copy of each log message will be sent to stderr.
-Additional output streams may be include using
-.Nm asl_add_log_file .
-.Pp
-Messages sent to stderr or other files are printed in the "standard" message format
-also used as a default format by the
-.Xr syslog 1
-command line utility.
-Non-ASCII characters in a message are encoded using the
-.Dq safe
-encoding style used by
-.Xr syslog 1
-with the
-.Fl E Ar safe
-option.
-Backspace characters are printed as ^H.
-Carriage returns are mapped to newlines.
-A tab character is appended after newlines so that message text is indented.
-.Pp
-File descriptors may be removed from the list of outputs associated
-with a client handle with
-.Nm asl_remove_log_file .
-This routine simply removes the file descriptor from the output list.
-The file is not closed as a result.
-.Pp
-The ASL_OPT_STDERR option may not be unset
-after a client handle has been opened.
-.Ss SEARCHING
-The
-.Nm syslogd
-server archives received messages in a data store
-that may be searched using the
-.Nm asl_search ,
-.Nm aslresponse_next ,
-and
-.Nm aslresponse_free
-routines.
-A query message is created using:
-.Pp
- aslmsg q = asl_new(ASL_TYPE_QUERY);
-.Pp
-Search settings are made in the query using
-.Nm asl_set_query .
-A search is performed on the data store with
-.Nm asl_search .
-It returns an
-.Ft aslresponse
-structure.
-The caller may then call
-.Nm aslresponse_next
-to iterate through matching messages.
-The
-.Ft aslresponse
-structure may be freed with
-.Nm aslresponse_free .
-.Pp
-Like other messages, ASL_TYPE_QUERY messages contain keys and values.
-They also associate an operation with each key and value.
-The operation is used to decide if a message matches the query.
-The simplest operation is ASL_QUERY_OP_EQUAL, which tests for equality.
-For example, the following code snippet searches for messages
-with a Sender value equal to
-.Dq MyApp .
-.Pp
- aslmsg m;
- aslresponse r;
- q = asl_new(ASL_TYPE_QUERY);
- asl_set_query(q, ASL_KEY_SENDER, "MyApp", ASL_QUERY_OP_EQUAL);
- r = asl_search(NULL, q);
-.Pp
-More complex searches may be performed using other query operations.
-.Pp
-.Bl -tag -width "ASL_QUERY_OP_GREATER_EQUAL" -compact
-.It ASL_QUERY_OP_EQUAL
-value equality
-.It ASL_QUERY_OP_GREATER
-value greater than
-.It ASL_QUERY_OP_GREATER_EQUAL
-value greater than or equal to
-.It ASL_QUERY_OP_LESS
-value less than
-.It ASL_QUERY_OP_LESS_EQUAL
-value less than or equal to
-.It ASL_QUERY_OP_NOT_EQUAL
-value not equal
-.It ASL_QUERY_OP_REGEX
-regular expression search
-.It ASL_QUERY_OP_TRUE
-always true - use to test for the existence of a key
-.El
-.Pp
-Regular expression search uses
-.Xr regex 3
-library.
-Patterns are compiled using the REG_EXTENDED and REG_NOSUB options.
-.Pp
-Modifiers that change the behavior of these operations
-may also be specified by ORing the modifier value with the operation.
-The modifiers are:
-.Pp
-.Bl -tag -width "ASL_QUERY_OP_SUBSTRING" -compact
-.It ASL_QUERY_OP_CASEFOLD
-string comparisons are case-folded
-.It ASL_QUERY_OP_PREFIX
-match a leading substring
-.It ASL_QUERY_OP_SUFFIX
-match a trailing substring
-.It ASL_QUERY_OP_SUBSTRING
-match any substring
-.It ASL_QUERY_OP_NUMERIC
-values are converted to integer using
-.Nm atoi
-.El
-.Pp
-The only modifier that is checked
-for ASL_QUERY_OP_REGEX search is ASL_QUERY_OP_CASEFOLD.
-This causes the regular expression to be compiled
-with the REG_ICASE option.
-.Pp
-If a query message contains more than one set of key/value/operation triples,
-the result will be a logical AND. For example, to find messages from
-.Dq MyApp
-with a priority level less than or equal to
-.Dq 3 :
-.Pp
- aslmsg q;
- aslresponse r;
- q = asl_new(ASL_TYPE_QUERY);
- asl_set_query(q, ASL_KEY_SENDER, "MyApp", ASL_QUERY_OP_EQUAL);
- asl_set_query(q, ASL_KEY_LEVEL, "3",
- ASL_QUERY_OP_LESS_EQUAL | ASL_QUERY_OP_NUMERIC);
- r = asl_search(NULL, q);
-.Pp
-After calling
-.Nm asl_search
-to get an
-.Ft aslresponse
-structure, use
-.Nm aslresponse_next
-to iterate through all matching messages.
-To iterate through the keys and values in a message, use
-.Nm asl_key
-to iterate through the keys, then call
-.Nm asl_get
-to get the value associated with each key.
-.Pp
- aslmsg q, m;
- int i;
- const char *key, *val;
-.Pp
- ...
- r = asl_search(NULL, q);
- while (NULL != (m = aslresponse_next(r)))
- {
- for (i = 0; (NULL != (key = asl_key(m, i))); i++)
- {
- val = asl_get(m, key);
- ...
- }
- }
- aslresponse_free(r);
-.Pp
-.Ss FILTERING AND REMOTE CONTROL
-Clients may set a filter mask value with
-.Nm asl_set_filter .
-The mask specifies which messages should be sent to the
-.Nm syslogd
-daemon by specifying a yes/no setting for each priority level.
-Clients typically set a filter mask
-to avoid sending relatively unimportant messages.
-For example, Debug or Info priority level messages
-are generally only useful for debugging operations.
-By setting a filter mask, a process can improve performance
-by avoiding sending messages that are in most cases unnecessary.
-.Pp
-.Nm asl_set_filter returns the previous value of the filter, i.e. the value of the filter before the routine was called.
-.Pp
-As a convenience, the macros ASL_FILTER_MASK(level) and ASL_FILTER_MASK_UPTO(level)
-may be used to construct a bit mask corresponding to a given priority level,
-or corresponding to a bit mask for all priority levels
-from ASL_LEVEL_EMERG to a given input level.
-.Pp
-The default filter mask is ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE).
-This means that by default,
-and in the absence of remote-control changes (described below),
-ASL_LEVEL_DEBUG and ASL_LEVEL_INFO priority level messages
-are not sent to the
-.Mn syslogd
-server.
-.Pp
-Three different filters exist for each application.
-The first is the filter mask set using
-.Nm asl_set_filter
-as described above.
-The Apple System Log facility also manages a
-.Dq master
-filter mask.
-The master filter mask usually has a value
-that indicates to the library that it is
-.Dq off ,
-and thus it has no effect.
-However, the mask filter mask may be enabled
-by giving it a value using the
-.Nm syslog
-command, using the
-.Fl c
-0 option.
-When the master filter mask has been set,
-it takes precedence over the client's filter mask.
-The client's mask is unmodified,
-and will become active again if remote-control filtering is disabled.
-.Pp
-In addition to the master filter mask,
-The Apple System Log facility
-also manages a per-client remote-control filter mask.
-Like the master filter mask, the per-client mask is usually
-.Dq off ,
-having no effect on a client.
-If a per-client filter mask is set using the
-.Nm syslog
-command, using the
-.Fl c Ar process
-option, then it takes precedence
-over both the client's filter mask and the master filter mask.
-As is the case with the master filter mask,
-a per-client mask ceases having any effect when if is disabled.
-.Pp
-The ASL_OPT_NO_REMOTE option to
-.Nm asl_open
-causes both the master and per-client remote-control masks
-to be ignored in the library.
-In that case, only the client's own filter mask
-is used to determine which messages are sent to the server.
-This may be useful for Applications that produce log messages
-that should never be filtered, due to security considerations.
-Note that root (administrator) access is required
-to set or change the master filter mask,
-and that only root may change a per-client remote-control filter mask
-for a root (UID 0) process.
-.Pp
-The per-process remote control filter value is kept as a state value
-associated with a key managed by
-.Nm notifyd .
-The key is protected by an access control mechanism that only permits the
-filter value to be accessed and modified by the same effective UID as the
-ASL client at the time that the first ASL connection was created.
-Remote filter control using
-.Nm syslog Fl c
-will fail for processes that change effective UID after starting an ASL connection.
-Those processes should close all ASL client handles and then re-open ASL connections
-if remote filter control support is desired.
-.Sh HISTORY
-These functions first appeared in
-Mac OS X 10.4.
-.Sh SEE ALSO
-.Xr syslog 1 ,
-.Xr strvis 3 ,
-.Xr syslogd 8
+++ /dev/null
-/*
- * Copyright (c) 2004-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <assert.h>
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <syslog.h>
-#include <errno.h>
-#include <limits.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/fcntl.h>
-#include <crt_externs.h>
-#include <asl.h>
-#include <regex.h>
-#include <notify.h>
-#include <mach/mach.h>
-#include <mach/std_types.h>
-#include <mach/mig.h>
-#include <mach/mach_types.h>
-#include <sys/types.h>
-#include <servers/bootstrap.h>
-#include <pthread.h>
-#include <dispatch/dispatch.h>
-#include <libkern/OSAtomic.h>
-#include <asl_ipc.h>
-#include "asl_core.h"
-#include "asl_msg.h"
-#include "asl_store.h"
-#include "asl_private.h"
-
-#define streq(A, B) (strcmp(A, B) == 0)
-#define strcaseeq(A, B) (strcasecmp(A, B) == 0)
-
-#define forever for(;;)
-
-#define FETCH_BATCH 256
-
-#define LEVEL_MASK 0x0000000f
-#define EVAL_MASK 0x000000f0
-#define EVAL_IGNORE 0x00000000
-#define EVAL_ASLFILE 0x00000010
-#define EVAL_SEND 0x00000020
-#define EVAL_TUNNEL 0x00000040
-#define EVAL_FILE 0x00000080
-
-/* forward */
-time_t asl_parse_time(const char *);
-const char *asl_syslog_faciliy_num_to_name(int n);
-static int _asl_send_message(aslclient ac, uint32_t eval, asl_msg_t *msg, const char *mstring);
-__private_extern__ asl_client_t *_asl_open_default();
-
-/* private asl_file SPI */
-__private_extern__ uint32_t asl_file_open_write_fd(int fd, asl_file_t **s);
-
-/* private asl_msg SPI */
-__private_extern__ asl_string_t *asl_msg_to_string_raw(uint32_t encoding, asl_msg_t *msg, int tf);
-
-/* notify SPI */
-uint32_t notify_register_plain(const char *name, int *out_token);
-
-/* fork handling in syslog.c */
-extern void _syslog_fork_child();
-
-typedef struct
-{
- int fd;
- asl_msg_t *msg;
- dispatch_semaphore_t sem;
-} asl_aux_context_t;
-
-typedef struct
-{
- int notify_count;
- int rc_change_token;
- int notify_token;
- int master_token;
- uint64_t proc_filter;
- uint64_t master_filter;
- dispatch_once_t port_lookup_once;
- mach_port_t server_port;
- char *sender;
- pthread_mutex_t lock;
- int aux_count;
- asl_aux_context_t **aux_ctx;
- asl_client_t *asl;
-} _asl_global_t;
-
-
-#ifndef BUILDING_VARIANT
-__private_extern__ _asl_global_t _asl_global = {0, -1, -1, -1, 0LL, 0LL, 0, MACH_PORT_NULL, NULL, PTHREAD_MUTEX_INITIALIZER, 0, NULL, NULL};
-
-#define ASL_SERVICE_NAME "com.apple.system.logger"
-
-/*
- * Called from the child process inside fork() to clean up
- * inherited state from the parent process.
- *
- * NB. A lock isn't required, since we're single threaded in this call.
- */
-__private_extern__ void
-_asl_fork_child()
-{
- _asl_global.notify_count = 0;
- _asl_global.rc_change_token = -1;
- _asl_global.master_token = -1;
- _asl_global.notify_token = -1;
-
- _asl_global.port_lookup_once = 0;
- _asl_global.server_port = MACH_PORT_NULL;
-
- pthread_mutex_init(&(_asl_global.lock), NULL);
-}
-
-/*
- * asl_remote_notify_name: returns the notification key for remote-control filter
- * changes for this process.
- */
-char *
-asl_remote_notify_name()
-{
- pid_t pid = getpid();
- uid_t euid = geteuid();
- char *str = NULL;
-
- if (euid == 0) asprintf(&str, "%s.%d", NOTIFY_PREFIX_SYSTEM, pid);
- else asprintf(&str, "user.uid.%d.syslog.%d", euid, pid);
-
- return str;
-}
-
-static int
-_asl_notify_open(int do_lock)
-{
- char *notify_name;
- uint32_t status;
-
- if (do_lock != 0) pthread_mutex_lock(&_asl_global.lock);
-
- _asl_global.notify_count++;
-
- if (_asl_global.notify_token != -1)
- {
- if (do_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return 0;
- }
-
- if (_asl_global.rc_change_token == -1)
- {
- status = notify_register_check(NOTIFY_RC, &_asl_global.rc_change_token);
- if (status != NOTIFY_STATUS_OK) _asl_global.rc_change_token = -1;
- }
-
- if (_asl_global.master_token == -1)
- {
- status = notify_register_plain(NOTIFY_SYSTEM_MASTER, &_asl_global.master_token);
- if (status != NOTIFY_STATUS_OK) _asl_global.master_token = -1;
- }
-
- notify_name = asl_remote_notify_name();
- if (notify_name != NULL)
- {
- status = notify_register_plain(notify_name, &_asl_global.notify_token);
- free(notify_name);
- if (status != NOTIFY_STATUS_OK) _asl_global.notify_token = -1;
- }
-
- if (do_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
-
- if (_asl_global.notify_token == -1) return -1;
- return 0;
-}
-
-static void
-_asl_notify_close()
-{
- pthread_mutex_lock(&_asl_global.lock);
-
- if (_asl_global.notify_count > 0) _asl_global.notify_count--;
-
- if (_asl_global.notify_count > 0)
- {
- pthread_mutex_unlock(&_asl_global.lock);
- return;
- }
-
- if (_asl_global.rc_change_token >= 0) notify_cancel(_asl_global.rc_change_token);
- _asl_global.rc_change_token = -1;
-
- if (_asl_global.master_token >= 0) notify_cancel(_asl_global.master_token);
- _asl_global.master_token = -1;
-
- if (_asl_global.notify_token >= 0) notify_cancel(_asl_global.notify_token);
- _asl_global.notify_token = -1;
-
- pthread_mutex_unlock(&_asl_global.lock);
-}
-
-static void
-_asl_global_init()
-{
- if (_asl_global.server_port == MACH_PORT_NULL)
- {
- mach_port_t newport = MACH_PORT_NULL;
- char *str = getenv("ASL_DISABLE");
- if ((str == NULL) || strcmp(str, "1"))
- {
- bootstrap_look_up(bootstrap_port, ASL_SERVICE_NAME, &newport);
- if (newport != MACH_PORT_NULL)
- {
- if (!OSAtomicCompareAndSwap32Barrier(MACH_PORT_NULL, newport, (int32_t *)&_asl_global.server_port))
- {
- mach_port_deallocate(mach_task_self(), newport);
- }
- }
- }
- }
-}
-
-static void
-_asl_global_reset()
-{
- mach_port_t tmp = _asl_global.server_port;
- _asl_global.server_port = MACH_PORT_NULL;
- mach_port_deallocate(mach_task_self(), tmp);
-}
-
-aslclient
-asl_open(const char *ident, const char *facility, uint32_t opts)
-{
- char *name, *x;
- asl_client_t *asl;
-
- asl = (asl_client_t *)calloc(1, sizeof(asl_client_t));
- if (asl == NULL)
- {
- errno = ENOMEM;
- return NULL;
- }
-
- asl->options = opts;
-
- asl->sock = -1;
-
- _asl_global_init();
-
- asl->pid = getpid();
- asl->uid = getuid();
- asl->gid = getgid();
-
- asl->filter = ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE);
-
- if (ident != NULL)
- {
- asl->name = strdup(ident);
- if (asl->name == NULL)
- {
- if (asl->sock >= 0) close(asl->sock);
- free(asl);
- return NULL;
- }
- }
- else
- {
- name = *(*_NSGetArgv());
- if (name != NULL)
- {
- x = strrchr(name, '/');
- if (x != NULL) x++;
- else x = name;
- asl->name = strdup(x);
- if (asl->name == NULL)
- {
- if (asl->sock >= 0) close(asl->sock);
- free(asl);
- return NULL;
- }
- }
- }
-
- asl->facility = NULL;
- if (facility != NULL) asl->facility = strdup(facility);
- else asl->facility = strdup(asl_syslog_faciliy_num_to_name(LOG_USER));
- if (asl->facility == NULL)
- {
- if (asl->sock >= 0) close(asl->sock);
- if (asl->name != NULL) free(asl->name);
- free(asl);
- return NULL;
- }
-
- if (!(asl->options & ASL_OPT_NO_REMOTE)) _asl_notify_open(1);
-
- if (asl->options & ASL_OPT_STDERR) asl_add_output((aslclient)asl, fileno(stderr), ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL, ASL_ENCODE_SAFE);
-
- asl->refcount = 1;
-
- return (aslclient)asl;
-}
-
-aslclient
-asl_open_from_file(int fd, const char *ident, const char *facility)
-{
- char *name, *x;
- asl_client_t *asl;
- uint32_t status;
-
- asl = (asl_client_t *)calloc(1, sizeof(asl_client_t));
- if (asl == NULL)
- {
- errno = ENOMEM;
- return NULL;
- }
-
- asl->options = ASL_OPT_NO_REMOTE;
- asl->sock = -1;
-
- asl->pid = getpid();
- asl->uid = getuid();
- asl->gid = getgid();
-
- asl->filter = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG);
-
- if (ident != NULL)
- {
- asl->name = strdup(ident);
- if (asl->name == NULL)
- {
- free(asl);
- return NULL;
- }
- }
- else
- {
- name = *(*_NSGetArgv());
- if (name != NULL)
- {
- x = strrchr(name, '/');
- if (x != NULL) x++;
- else x = name;
- asl->name = strdup(x);
- if (asl->name == NULL)
- {
- free(asl);
- return NULL;
- }
- }
- }
-
- asl->facility = NULL;
- if (facility != NULL) asl->facility = strdup(facility);
- else asl->facility = strdup(asl_syslog_faciliy_num_to_name(LOG_USER));
- if (asl->facility == NULL)
- {
- if (asl->name != NULL) free(asl->name);
- free(asl);
- return NULL;
- }
-
- status = asl_file_open_write_fd(fd, &(asl->aslfile));
- if (status != ASL_STATUS_OK)
- {
- if (asl->name != NULL) free(asl->name);
- if (asl->facility != NULL) free(asl->facility);
- free(asl);
- return NULL;
- }
-
- asl->aslfileid = 1;
- asl->refcount = 1;
-
- return (aslclient)asl;
-}
-
-__private_extern__ void
-asl_client_release(asl_client_t *asl)
-{
- uint32_t i;
-
- if (asl == NULL) return;
-
- if(OSAtomicDecrement32(&asl->refcount) > 0)
- return;
-
- free(asl->name);
- free(asl->facility);
-
- if (asl->sock >= 0) close(asl->sock);
- if (!(asl->options & ASL_OPT_NO_REMOTE)) _asl_notify_close();
- if (asl->fd_list != NULL) free(asl->fd_list);
-
- if (asl->fd_mfmt != NULL)
- {
- for (i = 0; i < asl->fd_count; i++) if (asl->fd_mfmt[i] != NULL) free(asl->fd_mfmt[i]);
- free(asl->fd_mfmt);
- }
-
- if (asl->fd_tfmt != NULL)
- {
- for (i = 0; i < asl->fd_count; i++) if (asl->fd_tfmt[i] != NULL) free(asl->fd_tfmt[i]);
- free(asl->fd_tfmt);
- }
-
- if (asl->fd_encoding != NULL) free(asl->fd_encoding);
-
- memset(asl, 0, sizeof(asl_client_t));
- free(asl);
-}
-
-void
-asl_close(aslclient ac)
-{
- asl_client_release((asl_client_t *)ac);
-}
-
-__private_extern__ asl_client_t *
-asl_client_retain(asl_client_t *asl)
-{
- int32_t new;
-
- if (asl == NULL) return NULL;
-
- new = OSAtomicIncrement32(&asl->refcount);
- assert(new >= 1);
-
- return asl;
-}
-
-__private_extern__ asl_client_t *
-_asl_open_default()
-{
- static dispatch_once_t once;
-
- dispatch_once(&once, ^{
- /*
- * Do a sleight-of-hand with ASL_OPT_NO_REMOTE to avoid a deadlock
- * since asl_open(xxx, yyy, 0) calls _asl_notify_open(1)
- * which locks _asl_global.lock.
- */
- _asl_global.asl = asl_open(NULL, NULL, ASL_OPT_NO_REMOTE);
-
- /* Reset options to clear ASL_OPT_NO_REMOTE bit */
- if (_asl_global.asl != NULL) _asl_global.asl->options = 0;
-
- /* Now call _asl_notify_open(0) to finish the work */
- _asl_notify_open(0);
- });
-
- return _asl_global.asl;
-}
-
-/*
- * asl_add_file: write log messages to the given file descriptor
- * Log messages will be written to this file as well as to the server.
- */
-int
-asl_add_output(aslclient ac, int fd, const char *mfmt, const char *tfmt, uint32_t text_encoding)
-{
- uint32_t i;
- int use_global_lock;
- asl_client_t *asl;
-
- use_global_lock = 0;
- asl = (asl_client_t *)ac;
- if (asl == NULL)
- {
- asl = _asl_open_default();
- if (asl == NULL) return -1;
- pthread_mutex_lock(&_asl_global.lock);
- use_global_lock = 1;
- }
-
- for (i = 0; i < asl->fd_count; i++)
- {
- if (asl->fd_list[i] == fd)
- {
- /* update message format, time format, and text encoding */
- if (asl->fd_mfmt[i] != NULL) free(asl->fd_mfmt[i]);
- asl->fd_mfmt[i] = NULL;
- if (mfmt != NULL) asl->fd_mfmt[i] = strdup(mfmt);
-
- if (asl->fd_tfmt[i] != NULL) free(asl->fd_tfmt[i]);
- asl->fd_tfmt[i] = NULL;
- if (tfmt != NULL) asl->fd_tfmt[i] = strdup(tfmt);
-
- asl->fd_encoding[i] = text_encoding;
-
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return 0;
- }
- }
-
- if (asl->fd_count == 0)
- {
- asl->fd_list = (int *)calloc(1, sizeof(int));
- asl->fd_mfmt = (char **)calloc(1, sizeof(char *));
- asl->fd_tfmt = (char **)calloc(1, sizeof(char *));
- asl->fd_encoding = (uint32_t *)calloc(1, sizeof(int));
- }
- else
- {
- asl->fd_list = (int *)reallocf(asl->fd_list, (1 + asl->fd_count) * sizeof(int));
- asl->fd_mfmt = (char **)reallocf(asl->fd_mfmt, (1 + asl->fd_count) * sizeof(char *));
- asl->fd_tfmt = (char **)reallocf(asl->fd_tfmt, (1 + asl->fd_count) * sizeof(char *));
- asl->fd_encoding = (uint32_t *)reallocf(asl->fd_encoding, (1 + asl->fd_count) * sizeof(uint32_t));
- }
-
- if ((asl->fd_list == NULL) || (asl->fd_mfmt == NULL) || (asl->fd_tfmt == NULL) || (asl->fd_encoding == NULL))
- {
- if (asl->fd_list != NULL) free(asl->fd_list);
- if (asl->fd_mfmt != NULL) free(asl->fd_mfmt);
- if (asl->fd_tfmt != NULL) free(asl->fd_tfmt);
- if (asl->fd_encoding != NULL) free(asl->fd_encoding);
-
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return -1;
- }
-
- asl->fd_list[asl->fd_count] = fd;
- if (mfmt != NULL) asl->fd_mfmt[asl->fd_count] = strdup(mfmt);
- if (tfmt != NULL) asl->fd_tfmt[asl->fd_count] = strdup(tfmt);
- asl->fd_encoding[asl->fd_count] = text_encoding;
-
- asl->fd_count++;
-
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return 0;
-}
-
-int
-asl_add_log_file(aslclient ac, int fd)
-{
- return asl_add_output(ac, fd, ASL_MSG_FMT_STD, ASL_TIME_FMT_LCL, ASL_ENCODE_SAFE);
-}
-
-/*
- * asl_remove_output: stop writing log messages to the given file descriptor
- */
-int
-asl_remove_output(aslclient ac, int fd)
-{
- uint32_t i;
- int x, use_global_lock;
- asl_client_t *asl;
-
- use_global_lock = 0;
- asl = (asl_client_t *)ac;
- if (asl == NULL)
- {
- asl = _asl_open_default();
- if (asl == NULL) return -1;
- pthread_mutex_lock(&_asl_global.lock);
- use_global_lock = 1;
- }
-
- if (asl->fd_count == 0)
- {
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return 0;
- }
-
- x = -1;
- for (i = 0; i < asl->fd_count; i++)
- {
- if (asl->fd_list[i] == fd)
- {
- x = i;
- break;
- }
- }
-
- if (x == -1)
- {
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return 0;
- }
-
- if (asl->fd_mfmt[x] != NULL) free(asl->fd_mfmt[x]);
- if (asl->fd_tfmt[x] != NULL) free(asl->fd_tfmt[x]);
-
- for (i = x + 1; i < asl->fd_count; i++, x++)
- {
- asl->fd_list[x] = asl->fd_list[i];
- asl->fd_mfmt[x] = asl->fd_mfmt[i];
- asl->fd_tfmt[x] = asl->fd_tfmt[i];
- asl->fd_encoding[x] = asl->fd_encoding[i];
- }
-
- asl->fd_count--;
-
- if (asl->fd_count == 0)
- {
- free(asl->fd_list);
- asl->fd_list = NULL;
-
- free(asl->fd_mfmt);
- asl->fd_mfmt = NULL;
-
- free(asl->fd_tfmt);
- asl->fd_tfmt = NULL;
-
- free(asl->fd_encoding);
- asl->fd_encoding = NULL;
- }
- else
- {
- asl->fd_list = (int *)reallocf(asl->fd_list, asl->fd_count * sizeof(int));
- asl->fd_mfmt = (char **)reallocf(asl->fd_mfmt, asl->fd_count * sizeof(char *));
- asl->fd_tfmt = (char **)reallocf(asl->fd_tfmt, asl->fd_count * sizeof(char *));
- asl->fd_encoding = (uint32_t *)reallocf(asl->fd_encoding, asl->fd_count * sizeof(uint32_t));
-
- if ((asl->fd_list == NULL) || (asl->fd_mfmt == NULL) || (asl->fd_tfmt == NULL) || (asl->fd_encoding == NULL))
- {
- if (asl->fd_list != NULL)
- {
- free(asl->fd_list);
- asl->fd_list = NULL;
- }
-
- if (asl->fd_mfmt != NULL)
- {
- for (i = 0; i < asl->fd_count; i++) if (asl->fd_mfmt[i] != NULL) free(asl->fd_mfmt[i]);
- free(asl->fd_mfmt);
- asl->fd_mfmt = NULL;
- }
-
- if (asl->fd_tfmt != NULL)
- {
- for (i = 0; i < asl->fd_count; i++) if (asl->fd_tfmt[i] != NULL) free(asl->fd_tfmt[i]);
- free(asl->fd_tfmt);
- asl->fd_tfmt = NULL;
- }
-
- if (asl->fd_encoding != NULL)
- {
- free(asl->fd_encoding);
- asl->fd_encoding = NULL;
- }
-
- asl->fd_count = 0;
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return -1;
- }
- }
-
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return 0;
-}
-
-int
-asl_remove_log_file(aslclient ac, int fd)
-{
- return asl_remove_output(ac, fd);
-}
-
-int
-asl_set_filter(aslclient ac, int f)
-{
- int last, use_global_lock;
- asl_client_t *asl;
-
- use_global_lock = 0;
- asl = (asl_client_t *)ac;
- if (asl == NULL)
- {
- asl = _asl_open_default();
- if (asl == NULL) return -1;
- pthread_mutex_lock(&_asl_global.lock);
- use_global_lock = 1;
- }
-
- last = asl->filter;
- asl->filter = f;
-
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return last;
-}
-
-/*
- * Evaluate client / message / level to determine what to do with a message.
- * Checks filters, tunneling, and log files. Returns EVAL_IGNORE if the message
- * can be ignored. Otherwise it returns the bits below, ORed with the level.
- *
- * EVAL_ASLFILE - will write to an asl file (see asl_open_from_file)
- * EVAL_SEND - will send to syslogd
- * EVAL_TUNNEL - will send to syslogd with tunneling enabled
- * EVAL_FILE - will write to file
- */
-uint32_t
-_asl_evaluate_send(aslclient ac, aslmsg msg, int slevel)
-{
- asl_client_t *asl = (asl_client_t *)ac;
- uint32_t level, lmask, filter, status, tunnel;
- int check, out;
- uint64_t v64;
- const char *val;
-
- if (asl == NULL)
- {
- asl = _asl_open_default();
- if (asl == NULL) return EVAL_IGNORE;
- }
-
- check = ASL_LEVEL_DEBUG;
- if (slevel >= 0) check = slevel;
-
- val = asl_get((aslmsg)msg, ASL_KEY_LEVEL);
- if (val != NULL) check = atoi(val);
-
- if (check < ASL_LEVEL_EMERG) check = ASL_LEVEL_EMERG;
- else if (check > ASL_LEVEL_DEBUG) check = ASL_LEVEL_DEBUG;
- level = check;
-
- out = check;
-
- if (asl->aslfile != NULL) return (out | EVAL_ASLFILE);
-
- lmask = ASL_FILTER_MASK(level);
-
- if (!(asl->options & ASL_OPT_NO_REMOTE))
- {
- pthread_mutex_lock(&_asl_global.lock);
-
- if (_asl_global.rc_change_token >= 0)
- {
- /* initialize or re-check process-specific and master filters */
- check = 0;
- status = notify_check(_asl_global.rc_change_token, &check);
- if ((status == NOTIFY_STATUS_OK) && (check != 0))
- {
- if (_asl_global.master_token >= 0)
- {
- v64 = 0;
- status = notify_get_state(_asl_global.master_token, &v64);
- if (status == NOTIFY_STATUS_OK) _asl_global.master_filter = v64;
- }
-
- if (_asl_global.notify_token >= 0)
- {
- v64 = 0;
- status = notify_get_state(_asl_global.notify_token, &v64);
- if (status == NOTIFY_STATUS_OK) _asl_global.proc_filter = v64;
- }
- }
- }
-
- pthread_mutex_unlock(&_asl_global.lock);
- }
-
- filter = asl->filter & 0xff;
- tunnel = (asl->filter & ASL_FILTER_MASK_TUNNEL) >> 8;
-
- /* master filter overrides local filter */
- if (_asl_global.master_filter != 0)
- {
- filter = _asl_global.master_filter;
- tunnel = 1;
- }
-
- /* process-specific filter overrides local and master */
- if (_asl_global.proc_filter != 0)
- {
- filter = _asl_global.proc_filter;
- tunnel = 1;
- }
-
- if ((filter != 0) && ((filter & lmask) != 0))
- {
- out |= EVAL_SEND;
- if (tunnel != 0) out |= EVAL_TUNNEL;
- if (asl->fd_count > 0) out |= EVAL_FILE;
-
- return out;
- }
-
- if ((asl->options & ASL_OPT_SYSLOG_LEGACY) && (filter != 0) && ((filter & lmask) == 0))
- {
- return EVAL_IGNORE;
- }
-
- if (asl->fd_count > 0) return (out | EVAL_FILE);
-
- return EVAL_IGNORE;
-}
-
-#endif /* BUILDING_VARIANT */
-
-/*
- * _asl_lib_vlog
- * Internal routine used by asl_vlog.
- * msg: an aslmsg
- * eval: log level and send flags for the message
- * format: A formating string
- * ap: va_list for the format
- * returns 0 for success, non-zero for failure
- */
-static int
-_asl_lib_vlog(aslclient ac, uint32_t eval, aslmsg msg, const char *format, va_list ap)
-{
- int saved_errno = errno;
- int status;
- char *str, *fmt, estr[NL_TEXTMAX];
- uint32_t i, len, elen, expand;
- asl_client_t *asl;
-
- asl = (asl_client_t *)ac;
- if (asl == NULL)
- {
- /*
- * Initialize _asl_global so that asl_new will have global data.
- * Not strictly necessary, but helps performance.
- */
- asl = _asl_open_default();
- if (asl == NULL) return -1;
- }
-
- if (format == NULL) return -1;
-
- /* insert strerror for %m */
- len = 0;
- elen = 0;
-
- expand = 0;
- for (i = 0; format[i] != '\0'; i++)
- {
- if (format[i] == '%')
- {
- if (format[i+1] == '\0') len++;
- else if (format[i+1] == 'm')
- {
- expand = 1;
- strerror_r(saved_errno, estr, sizeof(estr));
- elen = strlen(estr);
- len += elen;
- i++;
- }
- else
- {
- len += 2;
- i++;
- }
- }
- else len++;
- }
-
- fmt = (char *)format;
-
- if (expand != 0)
- {
- fmt = malloc(len + 1);
- if (fmt == NULL)
- {
- if (estr != NULL) free(estr);
- return -1;
- }
-
- len = 0;
-
- for (i = 0; format[i] != '\0'; i++)
- {
- if (format[i] == '%')
- {
- if (format[i+1] == '\0')
- {
- }
- else if ((format[i+1] == 'm') && (elen != 0))
- {
- memcpy(fmt+len, estr, elen);
- len += elen;
- i++;
- }
- else
- {
- fmt[len++] = format[i++];
- fmt[len++] = format[i];
- }
- }
- else fmt[len++] = format[i];
- }
-
- fmt[len] = '\0';
- }
-
- vasprintf(&str, fmt, ap);
- if (expand != 0) free(fmt);
-
- if (str == NULL) return -1;
-
- status = _asl_send_message(ac, eval, (asl_msg_t *)msg, str);
- free(str);
-
- return status;
-}
-
-/*
- * asl_vlog
- * Similar to asl_log, but take a va_list instead of a list of arguments.
- * msg: an aslmsg
- * level: the log level of the associated message
- * format: A formating string
- * ap: va_list for the format
- * returns 0 for success, non-zero for failure
- */
-int
-asl_vlog(aslclient ac, aslmsg msg, int level, const char *format, va_list ap)
-{
- uint32_t eval = _asl_evaluate_send(ac, msg, level);
- if (eval == EVAL_IGNORE) return 0;
-
- return _asl_lib_vlog(ac, eval, msg, format, ap);
-}
-
-/*
- * _asl_lib_log
- * SPI used by ASL_PREFILTER_LOG. Converts format arguments to a va_list and
- * forwards the call to _asl_lib_vlog.
- * msg: an aslmsg
- * eval: log level and send flags for the message
- * format: A formating string
- * ... args for format
- * returns 0 for success, non-zero for failure
- */
-int
-_asl_lib_log(aslclient ac, uint32_t eval, aslmsg msg, const char *format, ...)
-{
- int status;
- if (eval == EVAL_IGNORE) return 0;
-
- va_list ap;
- va_start(ap, format);
- status = _asl_lib_vlog(ac, eval, msg, format, ap);
- va_end(ap);
-
- return status;
-}
-
-/*
- * asl_log
- * Processes an ASL log message.
- * msg: an aslmsg
- * level: the log level of the associated message
- * format: A formating string
- * ... args for format
- * returns 0 for success, non-zero for failure
- */
-int
-asl_log(aslclient ac, aslmsg msg, int level, const char *format, ...)
-{
- int status;
- uint32_t eval = _asl_evaluate_send(ac, msg, level);
- if (eval == EVAL_IGNORE) return 0;
-
- va_list ap;
- va_start(ap, format);
- status = _asl_lib_vlog(ac, eval, msg, format, ap);
- va_end(ap);
-
- return status;
-}
-
-#ifndef BUILDING_VARIANT
-
-/*
- * asl_get_filter: gets the values for the local, master, and remote filters,
- * and indicates which one is active.
- */
-int
-asl_get_filter(aslclient ac, int *local, int *master, int *remote, int *active)
-{
- asl_client_t *asl, *asl_default;
- int l, m, r, x;
- int status, check;
- uint64_t v64;
-
- l = 0;
- m = 0;
- r = 0;
- x = 0;
-
- asl_default = _asl_open_default();
-
- asl = (asl_client_t *)ac;
- if (asl == NULL) asl = asl_default;
- if (asl != NULL) l = asl->filter & 0xff;
-
- if ((asl_default != NULL) && (!(asl_default->options & ASL_OPT_NO_REMOTE)))
- {
- pthread_mutex_lock(&_asl_global.lock);
-
- if (_asl_global.rc_change_token >= 0)
- {
- /* initialize or re-check process-specific and master filters */
- check = 0;
- status = notify_check(_asl_global.rc_change_token, &check);
- if ((status == NOTIFY_STATUS_OK) && (check != 0))
- {
- if (_asl_global.master_token >= 0)
- {
- v64 = 0;
- status = notify_get_state(_asl_global.master_token, &v64);
- if (status == NOTIFY_STATUS_OK) _asl_global.master_filter = v64;
- }
-
- if (_asl_global.notify_token >= 0)
- {
- v64 = 0;
- status = notify_get_state(_asl_global.notify_token, &v64);
- if (status == NOTIFY_STATUS_OK) _asl_global.proc_filter = v64;
- }
- }
- }
-
- m = _asl_global.master_filter;
- if (m != 0) x = 1;
-
- r = _asl_global.proc_filter;
- if (r != 0) x = 2;
-
- pthread_mutex_unlock(&_asl_global.lock);
- }
-
- if (local != NULL) *local = l;
- if (master != NULL) *master = m;
- if (remote != NULL) *remote = r;
- if (active != NULL) *active = x;
-
- return 0;
-}
-
-static int
-_asl_send_message(aslclient ac, uint32_t eval, asl_msg_t *msg, const char *mstring)
-{
- uint32_t i, len, level, lmask, outstatus, filter, fd_write;
- uint64_t v64;
- const char *val;
- char *name, *x;
- time_t tick;
- struct timeval tval;
- int status, check;
- asl_client_t *asl;
- int use_global_lock;
- kern_return_t kstatus;
- char aux_val[64];
- char aux_host[_POSIX_HOST_NAME_MAX];
- asl_msg_t *aux;
-
- if (eval == EVAL_IGNORE) return 0;
-
- level = eval & LEVEL_MASK;
- eval &= EVAL_MASK;
-
- use_global_lock = 0;
- asl = (asl_client_t *)ac;
- if (asl == NULL)
- {
- asl = _asl_open_default();
- if (asl == NULL) return -1;
- use_global_lock = 1;
- }
-
- if (asl->aslfile != NULL) use_global_lock = 1;
-
- /*
- * Time, TimeNanoSec, Host, PID, UID, and GID values get set here.
- * Also sets Sender & Facility (if unset) and "ASLOption store" if remote control is active.
- */
- aux = asl_msg_new(ASL_TYPE_MSG);
-
- if (mstring != NULL) asl_msg_set_key_val(aux, ASL_KEY_MSG, mstring);
-
- snprintf(aux_val, sizeof(aux_val), "%u", level);
- asl_msg_set_key_val(aux, ASL_KEY_LEVEL, aux_val);
-
- memset(&tval, 0, sizeof(struct timeval));
-
- status = gettimeofday(&tval, NULL);
- if (status == 0)
- {
- snprintf(aux_val, sizeof(aux_val), "%lu", tval.tv_sec);
- asl_msg_set_key_val(aux, ASL_KEY_TIME, aux_val);
- snprintf(aux_val, sizeof(aux_val), "%d", tval.tv_usec * 1000);
- asl_msg_set_key_val(aux, ASL_KEY_TIME_NSEC, aux_val);
- }
- else
- {
- tick = time(NULL);
- snprintf(aux_val, sizeof(aux_val), "%lu", tick);
- asl_msg_set_key_val(aux, ASL_KEY_TIME, aux_val);
- }
-
- memset(&aux_host, 0, _POSIX_HOST_NAME_MAX);
- if (gethostname(aux_host, _POSIX_HOST_NAME_MAX) == 0)
- {
- asl_msg_set_key_val(aux, ASL_KEY_HOST, aux_host);
- }
-
- snprintf(aux_val, sizeof(aux_val), "%u", getpid());
- asl_msg_set_key_val(aux, ASL_KEY_PID, aux_val);
-
- snprintf(aux_val, sizeof(aux_val), "%d", getuid());
- asl_msg_set_key_val(aux, ASL_KEY_UID, aux_val);
-
- snprintf(aux_val, sizeof(aux_val), "%d", getgid());
- asl_msg_set_key_val(aux, ASL_KEY_GID, aux_val);
-
- /*
- * Set Sender if needed
- */
- status = asl_msg_lookup((asl_msg_t *)msg, ASL_KEY_SENDER, &val, NULL);
- if ((status != 0) || (val == NULL))
- {
- if ((ac != NULL) && (ac->name != NULL))
- {
- /* Use the Sender name from the client handle */
- asl_msg_set_key_val(aux, ASL_KEY_SENDER, ac->name);
- }
- else
- {
- /* Get the value for ASL_KEY_SENDER from cache */
- if (_asl_global.sender == NULL)
- {
- name = *(*_NSGetArgv());
- if (name != NULL)
- {
- x = strrchr(name, '/');
- if (x != NULL) x++;
- else x = name;
-
- pthread_mutex_lock(&_asl_global.lock);
- if (_asl_global.sender == NULL) _asl_global.sender = strdup(x);
- pthread_mutex_unlock(&_asl_global.lock);
- }
- }
-
- if (_asl_global.sender != NULL) asl_msg_set_key_val(aux, ASL_KEY_SENDER, _asl_global.sender);
- else asl_msg_set_key_val(aux, ASL_KEY_SENDER, "Unknown");
- }
- }
-
- /*
- * Set Facility
- */
- status = asl_msg_lookup((asl_msg_t *)msg, ASL_KEY_FACILITY, &val, NULL);
- if ((status != 0) || (val == NULL))
- {
- if ((ac != NULL) && (ac->facility != NULL))
- {
- /* Use the Facility name from the client handle */
- asl_msg_set_key_val(aux, ASL_KEY_FACILITY, ac->facility);
- }
- }
-
- /* Set "ASLOption store" if tunneling */
-
- if (eval & EVAL_TUNNEL)
- {
- val = asl_get((aslmsg)msg, ASL_KEY_OPTION);
- if (val == NULL)
- {
- asl_msg_set_key_val(aux, ASL_KEY_OPTION, ASL_OPT_STORE);
- }
- else
- {
- char *aux_option = NULL;
- asprintf(&aux_option, "%s %s", ASL_OPT_STORE, val);
- asl_msg_set_key_val(aux, ASL_KEY_OPTION, aux_option);
- free(aux_option);
- }
- }
-
- outstatus = -1;
-
- if (use_global_lock != 0) pthread_mutex_lock(&_asl_global.lock);
-
- aux = asl_msg_merge(aux, msg);
-
- /*
- * If there is an aslfile this is a stand-alone file client.
- * Just save to the file.
- */
- if (asl->aslfile != NULL)
- {
- outstatus = ASL_STATUS_FAILED;
-
- if (aux != NULL)
- {
- outstatus = asl_file_save(asl->aslfile, (aslmsg)aux, &(asl->aslfileid));
- asl->aslfileid++;
- }
-
- asl_msg_release(aux);
-
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
- return outstatus;
- }
-
- _asl_global_init();
- outstatus = 0;
-
- if ((_asl_global.server_port != MACH_PORT_NULL) && (eval & EVAL_SEND))
- {
- asl_string_t *send_str;
- const char *str;
- size_t vmsize;
-
- send_str = asl_msg_to_string_raw(ASL_STRING_MIG, aux, 0);
- len = asl_string_length(send_str);
- vmsize = asl_string_allocated_size(send_str);
- str = asl_string_free_return_bytes(send_str);
-
- if (len != 0)
- {
- /* send a mach message to syslogd */
- kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)str, len);
- if (kstatus != KERN_SUCCESS)
- {
- /* retry once if the call failed */
- _asl_global_reset();
- _asl_global_init();
- kstatus = _asl_server_message(_asl_global.server_port, (caddr_t)str, len);
- if (kstatus != KERN_SUCCESS)
- {
- _asl_global_reset();
- vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
- outstatus = -1;
- }
- }
- }
- }
-
- /* messages from syslog() get filtered on the way out to stderr */
- fd_write = 1;
- if ((asl->options & ASL_OPT_SYSLOG_LEGACY) && (filter != 0) && ((filter & lmask) == 0)) fd_write = 0;
-
- if ((fd_write != 0) && (asl->fd_count > 0))
- {
- if (aux != NULL)
- {
- /* write to file descriptors */
-
- for (i = 0; i < asl->fd_count; i++)
- {
- char *str;
-
- if (asl->fd_list[i] < 0) continue;
-
- len = 0;
- str = asl_format_message(aux, asl->fd_mfmt[i], asl->fd_tfmt[i], asl->fd_encoding[i], &len);
- if (str == NULL) continue;
-
- status = write(asl->fd_list[i], str, len - 1);
- if (status < 0)
- {
- asl->fd_list[i] = -1;
- outstatus = -1;
- }
-
- free(str);
- }
- }
- }
-
- asl_msg_release(aux);
-
- if (use_global_lock != 0) pthread_mutex_unlock(&_asl_global.lock);
-
- return outstatus;
-}
-
-/*
- * asl_send: send a message
- * This routine may be used instead of asl_log() or asl_vlog() if asl_set()
- * has been used to set all of a message's attributes.
- * eval: hints about what to do with the message
- * msg: an aslmsg
- * returns 0 for success, non-zero for failure
- */
-int
-asl_send(aslclient ac, aslmsg msg)
-{
- int status = 0;
- uint32_t eval = _asl_evaluate_send(ac, msg, -1);
- if (eval != 0) status = _asl_send_message(ac, eval, (asl_msg_t *)msg, NULL);
-
- return status;
-}
-
-static int
-_asl_aux_save_context(asl_aux_context_t *ctx)
-{
- if (ctx == NULL) return -1;
-
- pthread_mutex_lock(&_asl_global.lock);
-
- _asl_global.aux_ctx = (asl_aux_context_t **)reallocf(_asl_global.aux_ctx, (_asl_global.aux_count + 1) * sizeof(asl_aux_context_t *));
- if (_asl_global.aux_ctx == NULL)
- {
- _asl_global.aux_count = 0;
- return -1;
- }
-
- _asl_global.aux_ctx[_asl_global.aux_count++] = ctx;
-
- pthread_mutex_unlock(&_asl_global.lock);
-
- return 0;
-}
-
-/*
- * Creates an auxiliary file that may be used to save arbitrary data. The ASL message msg
- * will be saved at the time that the auxiliary file is created. The message will include
- * any keys and values found in msg, and it will include the title and Uniform Type
- * Identifier specified. Output parameter out_fd will contain the file descriptor of the
- * new auxiliary file.
- */
-static int
-_asl_auxiliary(asl_msg_t *msg, const char *title, const char *uti, const char *url, int *out_fd)
-{
- asl_msg_t *aux;
- asl_string_t *send_str;
- const char *str;
- fileport_t fileport;
- kern_return_t kstatus;
- size_t len, vmsize;
- uint32_t newurllen, where;
- int status, fd, fdpair[2];
- caddr_t newurl;
- dispatch_queue_t pipe_q;
- dispatch_io_t pipe_channel;
- dispatch_semaphore_t sem;
-
- aux = asl_msg_new(ASL_TYPE_MSG);
-
- if (title != NULL)
- {
- asl_msg_set_key_val(aux, ASL_KEY_AUX_TITLE, title);
- }
-
- if (uti == NULL)
- {
- asl_msg_set_key_val(aux, ASL_KEY_AUX_UTI, "public.data");
- }
- else
- {
- asl_msg_set_key_val(aux, ASL_KEY_AUX_UTI, uti);
- }
-
- if (url != NULL)
- {
- asl_msg_set_key_val(aux, ASL_KEY_AUX_URL, url);
- }
-
- aux = asl_msg_merge(aux, msg);
-
- /* if (out_fd == NULL), this is from asl_log_auxiliary_location */
- if (out_fd == NULL)
- {
- uint32_t eval = _asl_evaluate_send(NULL, (aslmsg)aux, -1);
- status = _asl_send_message(NULL, eval, aux, NULL);
- asl_msg_release(aux);
- return status;
- }
-
- where = asl_store_location();
-
- if (where == ASL_STORE_LOCATION_MEMORY)
- {
- /* create a pipe */
-
- asl_aux_context_t *ctx = (asl_aux_context_t *)calloc(1, sizeof(asl_aux_context_t));
- if (ctx == NULL) return -1;
-
- status = pipe(fdpair);
- if (status < 0)
- {
- free(ctx);
- return -1;
- }
-
- /* give read end to dispatch_io_read */
- fd = fdpair[0];
- sem = dispatch_semaphore_create(0);
- ctx->sem = sem;
- ctx->fd = fdpair[1];
-
- status = _asl_aux_save_context(ctx);
- if (status != 0)
- {
- close(fdpair[0]);
- close(fdpair[1]);
- dispatch_release(sem);
- free(ctx);
- return -1;
- }
-
- pipe_q = dispatch_queue_create("PipeQ", NULL);
- pipe_channel = dispatch_io_create(DISPATCH_IO_STREAM, fd, pipe_q, ^(int err){
- close(fd);
- });
-
- *out_fd = fdpair[1];
-
- dispatch_io_set_low_water(pipe_channel, SIZE_MAX);
-
- dispatch_io_read(pipe_channel, 0, SIZE_MAX, pipe_q, ^(bool done, dispatch_data_t pipedata, int err){
- if (err == 0)
- {
- size_t len = dispatch_data_get_size(pipedata);
- if (len > 0)
- {
- const char *bytes = NULL;
- char *encoded;
- uint32_t eval;
-
- dispatch_data_t md = dispatch_data_create_map(pipedata, (const void **)&bytes, &len);
- encoded = asl_core_encode_buffer(bytes, len);
- asl_msg_set_key_val(aux, ASL_KEY_AUX_DATA, encoded);
- free(encoded);
- eval = _asl_evaluate_send(NULL, (aslmsg)aux, -1);
- _asl_send_message(NULL, eval, aux, NULL);
- asl_msg_release(aux);
- dispatch_release(md);
- }
- }
-
- if (done)
- {
- dispatch_semaphore_signal(sem);
- dispatch_release(pipe_channel);
- dispatch_release(pipe_q);
- }
- });
-
- return 0;
- }
-
- _asl_global_init();
- if (_asl_global.server_port == MACH_PORT_NULL) return -1;
-
- send_str = asl_msg_to_string_raw(ASL_STRING_MIG, aux, 0);
- len = asl_string_length(send_str);
- vmsize = asl_string_allocated_size(send_str);
- str = asl_string_free_return_bytes(send_str);
-
- if (len == 0)
- {
- asl_msg_release(aux);
- vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
- return -1;
- }
-
- status = 0;
- fileport = MACH_PORT_NULL;
- status = KERN_SUCCESS;
-
- kstatus = _asl_server_create_aux_link(_asl_global.server_port, (caddr_t)str, len, &fileport, &newurl, &newurllen, &status);
- if (kstatus != KERN_SUCCESS)
- {
- /* retry once if the call failed */
- _asl_global_reset();
- _asl_global_init();
- kstatus = _asl_server_create_aux_link(_asl_global.server_port, (caddr_t)str, len, &fileport, &newurl, &newurllen, &status);
- if (kstatus != KERN_SUCCESS)
- {
- _asl_global_reset();
- vm_deallocate(mach_task_self(), (vm_address_t)str, vmsize);
- asl_msg_release(aux);
- return -1;
- }
- }
-
- if (status != 0)
- {
- asl_msg_release(aux);
- return status;
- }
-
- if (newurl != NULL)
- {
- asl_msg_set_key_val(aux, ASL_KEY_AUX_URL, newurl);
- vm_deallocate(mach_task_self(), (vm_address_t)newurl, newurllen);
- }
-
- if (fileport == MACH_PORT_NULL)
- {
- asl_msg_release(aux);
- return -1;
- }
-
- fd = fileport_makefd(fileport);
- mach_port_deallocate(mach_task_self(), fileport);
- if (fd < 0)
- {
- asl_msg_release(aux);
- status = -1;
- }
- else
- {
- asl_aux_context_t *ctx = (asl_aux_context_t *)calloc(1, sizeof(asl_aux_context_t));
- if (ctx == NULL)
- {
- status = -1;
- }
- else
- {
- *out_fd = fd;
-
- ctx->fd = fd;
- ctx->msg = aux;
-
- status = _asl_aux_save_context(ctx);
- }
- }
-
- return status;
-}
-
-int
-asl_create_auxiliary_file(aslmsg msg, const char *title, const char *uti, int *out_fd)
-{
- if (out_fd == NULL) return -1;
-
- return _asl_auxiliary((asl_msg_t *)msg, title, uti, NULL, out_fd);
-}
-
-int
-asl_log_auxiliary_location(aslmsg msg, const char *title, const char *uti, const char *url)
-{
- return _asl_auxiliary((asl_msg_t *)msg, title, uti, url, NULL);
-}
-
-/*
- * Close an auxiliary file.
- * Sends the cached auxiliary message to syslogd.
- */
-int
-asl_close_auxiliary_file(int fd)
-{
- int i, j, status;
- asl_msg_t *aux_msg;
- dispatch_semaphore_t aux_sem;
-
- pthread_mutex_lock(&(_asl_global.lock));
-
- aux_msg = NULL;
- status = -1;
-
- for (i = 0; i < _asl_global.aux_count; i++)
- {
- if (_asl_global.aux_ctx[i]->fd == fd)
- {
- status = 0;
-
- aux_msg = _asl_global.aux_ctx[i]->msg;
- aux_sem = _asl_global.aux_ctx[i]->sem;
-
- free(_asl_global.aux_ctx[i]);
-
- for (j = i + 1; j < _asl_global.aux_count; i++, j++)
- {
- _asl_global.aux_ctx[i] = _asl_global.aux_ctx[j];
- }
-
- _asl_global.aux_count--;
-
- if (_asl_global.aux_count == 0)
- {
- free(_asl_global.aux_ctx);
- _asl_global.aux_ctx = NULL;
- }
- else
- {
- _asl_global.aux_ctx = (asl_aux_context_t **)reallocf(_asl_global.aux_ctx, _asl_global.aux_count * sizeof(asl_aux_context_t *));
- if (_asl_global.aux_ctx == NULL)
- {
- _asl_global.aux_count = 0;
- status = -1;
- }
- }
-
- break;
- }
- }
-
- pthread_mutex_unlock(&(_asl_global.lock));
-
- close(fd);
-
- if (aux_msg != NULL)
- {
- uint32_t eval = _asl_evaluate_send(NULL, (aslmsg)aux_msg, -1);
- if (_asl_send_message(NULL, eval, aux_msg, NULL) != ASL_STATUS_OK) status = -1;
- asl_msg_release(aux_msg);
- }
-
- if (aux_sem != NULL)
- {
- dispatch_semaphore_wait(aux_sem, DISPATCH_TIME_FOREVER);
- dispatch_release(aux_sem);
- }
-
- return status;
-}
-
-/*
- * asl_search: Search for messages matching the criteria described
- * by the aslmsg. The caller should set the attributes to match using
- * asl_set_query() or asl_set(). The operatoin ASL_QUERY_OP_EQUAL is
- * used for attributes set with asl_set().
- * a: an aslmsg
- * returns: a set of messages that can be iterated over using aslresp_next(),
- * and the values can be retrieved using aslresp_get.
- */
-
-/*
- * This routine searches the ASL datastore on disk (/var/log/asl).
- * It is called my asl_search if syslogd is not running or if syslogd
- * indicates that an in-memory store is not being used.
- */
-static aslresponse
-_asl_search_store(aslclient ac, aslmsg a)
-{
- asl_search_result_t query, *out;
- asl_msg_t *q, *qlist[1];
- uint32_t status, op;
- uint64_t last_id, start_id;
- asl_store_t *store;
- const char *val;
-
- if (a == NULL) return NULL;
-
- q = (asl_msg_t *)a;
-
- /* check for "ASLMessageId >[=] n" and set start_id */
- start_id = 0;
- val = NULL;
-
- status = asl_msg_lookup(q, ASL_KEY_MSG_ID, &val, &op);
- if ((status == 0) && (val != NULL) && (op & ASL_QUERY_OP_GREATER))
- {
- if (op & ASL_QUERY_OP_EQUAL) start_id = atoll(val);
- else start_id = atoll(val) + 1;
- }
-
- store = NULL;
- status = asl_store_open_read(NULL, &store);
- if (status != 0) return NULL;
- if (store == NULL) return NULL;
-
- out = NULL;
- last_id = 0;
-
- qlist[0] = (asl_msg_t *)a;
- memset(&query, 0, sizeof(asl_search_result_t));
- query.count = 1;
- query.msg = qlist;
-
- status = asl_store_match(store, &query, &out, &last_id, start_id, 0, 1);
- asl_store_close(store);
-
- return out;
-}
-
-static uint32_t
-_asl_search_concat_results(asl_search_result_t *batch, asl_search_result_t **out)
-{
- uint32_t i, j;
-
- if (out == NULL) return ASL_STATUS_FAILED;
-
- /* nothing to do if batch is NULL or contains no messages */
- if (batch == NULL) return 0;
- if (batch->count == 0)
- {
- aslresponse_free(batch);
- return 0;
- }
-
- if (*out == NULL) *out = (asl_search_result_t *)calloc(1, sizeof(asl_search_result_t));
- if (*out == NULL)
- {
- aslresponse_free(batch);
- return ASL_STATUS_FAILED;
- }
-
- if ((*out)->count == 0)
- {
- (*out)->msg = (asl_msg_t **)calloc(batch->count, sizeof(asl_msg_t *));
- }
- else
- {
- (*out)->msg = (asl_msg_t **)reallocf((*out)->msg, ((*out)->count + batch->count) * sizeof(asl_msg_t *));
- }
-
- if ((*out)->msg == NULL)
- {
- aslresponse_free(batch);
- free(*out);
- *out = NULL;
- return ASL_STATUS_FAILED;
- }
-
- for (i = 0, j = (*out)->count; i < batch->count; i++, j++) (*out)->msg[j] = batch->msg[i];
-
- (*out)->count += batch->count;
- free(batch->msg);
- free(batch);
- return ASL_STATUS_OK;
-}
-
-static aslresponse
-_asl_search_memory(aslclient ac, aslmsg a)
-{
- asl_search_result_t *batch, *out;
- char *qstr, *str, *res;
- uint32_t len, reslen, status;
- uint64_t cmax, qmin;
- kern_return_t kstatus;
- security_token_t sec;
- caddr_t vmstr;
-
- if (a == NULL) return 0;
-
- _asl_global_init();
- if (_asl_global.server_port == MACH_PORT_NULL) return NULL;
-
- len = 0;
- qstr = asl_msg_to_string((asl_msg_t *)a, &len);
-
- str = NULL;
- if (qstr == NULL)
- {
- asprintf(&str, "0\n");
- len = 3;
- }
- else
- {
- asprintf(&str, "1\n%s\n", qstr);
- len += 3;
- free(qstr);
- }
-
- if (str == NULL) return NULL;
-
- /*
- * Fetch a batch of results each time through the loop.
- * Fetching small batches rebuces the load on syslogd.
- */
- out = NULL;
- qmin = 0;
- cmax = 0;
-
- forever
- {
- res = NULL;
- reslen = 0;
- sec.val[0] = -1;
- sec.val[1] = -1;
- status = ASL_STATUS_OK;
-
- kstatus = vm_allocate(mach_task_self(), (vm_address_t *)&vmstr, len, TRUE);
- if (kstatus != KERN_SUCCESS) return NULL;
-
- memmove(vmstr, str, len);
-
- status = 0;
- kstatus = _asl_server_query(_asl_global.server_port, vmstr, len, qmin, FETCH_BATCH, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec);
- if (kstatus != KERN_SUCCESS)
- {
- /* retry once if the call failed */
- _asl_global_reset();
- _asl_global_init();
- kstatus = _asl_server_query(_asl_global.server_port, vmstr, len, qmin, FETCH_BATCH, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec);
- if (kstatus != KERN_SUCCESS)
- {
- _asl_global_reset();
- break;
- }
- }
-
- if (res == NULL) break;
-
- batch = asl_list_from_string(res);
- vm_deallocate(mach_task_self(), (vm_address_t)res, reslen);
-
- status = _asl_search_concat_results(batch, &out);
- if (status != ASL_STATUS_OK) break;
- if ((out == NULL) || (out->count < FETCH_BATCH)) break;
-
- if (cmax >= qmin) qmin = cmax + 1;
- }
-
- free(str);
-
- return out;
-}
-
-int
-asl_store_location()
-{
- kern_return_t kstatus;
- char *res;
- uint32_t reslen, status;
- uint64_t cmax;
- security_token_t sec;
-
- _asl_global_init();
- if (_asl_global.server_port == MACH_PORT_NULL) return ASL_STORE_LOCATION_FILE;
-
- res = NULL;
- reslen = 0;
- cmax = 0;
- sec.val[0] = -1;
- sec.val[1] = -1;
- status = ASL_STATUS_OK;
-
- kstatus = _asl_server_query(_asl_global.server_port, NULL, 0, 0, -1, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec);
- if (kstatus != KERN_SUCCESS)
- {
- /* retry once if the call failed */
- _asl_global_reset();
- _asl_global_init();
- kstatus = _asl_server_query(_asl_global.server_port, NULL, 0, 0, -1, 0, (caddr_t *)&res, &reslen, &cmax, (int *)&status, &sec);
- }
-
- /* res should never be returned, but just to be certain we don't leak VM ... */
- if (res != NULL) vm_deallocate(mach_task_self(), (vm_address_t)res, reslen);
-
- if (kstatus != KERN_SUCCESS)
- {
- _asl_global_reset();
- return ASL_STORE_LOCATION_FILE;
- }
-
- if (status == ASL_STATUS_OK) return ASL_STORE_LOCATION_MEMORY;
- return ASL_STORE_LOCATION_FILE;
-}
-
-aslresponse
-asl_search(aslclient ac, aslmsg a)
-{
- int where;
- asl_search_result_t *out;
-
- _asl_global_init();
-
- where = asl_store_location();
- if (where == ASL_STORE_LOCATION_FILE) out = _asl_search_store(ac, a);
- else out = _asl_search_memory(ac, a);
-
- return out;
-}
-
-int
-asl_syslog_faciliy_name_to_num(const char *name)
-{
- if (name == NULL) return -1;
-
- if (strcaseeq(name, "auth")) return LOG_AUTH;
- if (strcaseeq(name, "authpriv")) return LOG_AUTHPRIV;
- if (strcaseeq(name, "cron")) return LOG_CRON;
- if (strcaseeq(name, "daemon")) return LOG_DAEMON;
- if (strcaseeq(name, "ftp")) return LOG_FTP;
- if (strcaseeq(name, "install")) return LOG_INSTALL;
- if (strcaseeq(name, "kern")) return LOG_KERN;
- if (strcaseeq(name, "lpr")) return LOG_LPR;
- if (strcaseeq(name, "mail")) return LOG_MAIL;
- if (strcaseeq(name, "netinfo")) return LOG_NETINFO;
- if (strcaseeq(name, "remoteauth")) return LOG_REMOTEAUTH;
- if (strcaseeq(name, "news")) return LOG_NEWS;
- if (strcaseeq(name, "security")) return LOG_AUTH;
- if (strcaseeq(name, "syslog")) return LOG_SYSLOG;
- if (strcaseeq(name, "user")) return LOG_USER;
- if (strcaseeq(name, "uucp")) return LOG_UUCP;
- if (strcaseeq(name, "local0")) return LOG_LOCAL0;
- if (strcaseeq(name, "local1")) return LOG_LOCAL1;
- if (strcaseeq(name, "local2")) return LOG_LOCAL2;
- if (strcaseeq(name, "local3")) return LOG_LOCAL3;
- if (strcaseeq(name, "local4")) return LOG_LOCAL4;
- if (strcaseeq(name, "local5")) return LOG_LOCAL5;
- if (strcaseeq(name, "local6")) return LOG_LOCAL6;
- if (strcaseeq(name, "local7")) return LOG_LOCAL7;
- if (strcaseeq(name, "launchd")) return LOG_LAUNCHD;
-
- return -1;
-}
-
-const char *
-asl_syslog_faciliy_num_to_name(int n)
-{
- if (n < 0) return NULL;
-
- if (n == LOG_AUTH) return "auth";
- if (n == LOG_AUTHPRIV) return "authpriv";
- if (n == LOG_CRON) return "cron";
- if (n == LOG_DAEMON) return "daemon";
- if (n == LOG_FTP) return "ftp";
- if (n == LOG_INSTALL) return "install";
- if (n == LOG_KERN) return "kern";
- if (n == LOG_LPR) return "lpr";
- if (n == LOG_MAIL) return "mail";
- if (n == LOG_NETINFO) return "netinfo";
- if (n == LOG_REMOTEAUTH) return "remoteauth";
- if (n == LOG_NEWS) return "news";
- if (n == LOG_AUTH) return "security";
- if (n == LOG_SYSLOG) return "syslog";
- if (n == LOG_USER) return "user";
- if (n == LOG_UUCP) return "uucp";
- if (n == LOG_LOCAL0) return "local0";
- if (n == LOG_LOCAL1) return "local1";
- if (n == LOG_LOCAL2) return "local2";
- if (n == LOG_LOCAL3) return "local3";
- if (n == LOG_LOCAL4) return "local4";
- if (n == LOG_LOCAL5) return "local5";
- if (n == LOG_LOCAL6) return "local6";
- if (n == LOG_LOCAL7) return "local7";
- if (n == LOG_LAUNCHD) return "launchd";
-
- return NULL;
-}
-
-/*
- * utility for converting a time string into a time_t
- * we only deal with the following formats:
- * Canonical form YYYY.MM.DD hh:mm:ss UTC
- * ctime() form Mth dd hh:mm:ss (e.g. Aug 25 09:54:37)
- * absolute form - # seconds since the epoch (e.g. 1095789191)
- * relative time - seconds before or after now (e.g. -300, +43200)
- * relative time - days/hours/minutes/seconds before or after now (e.g. -1d, +6h, +30m, -10s)
- */
-
-#define CANONICAL_TIME_REX "^[0-9][0-9][0-9][0-9].[01]?[0-9].[0-3]?[0-9][ ]+[0-2]?[0-9]:[0-5][0-9]:[0-5][0-9][ ]+UTC$"
-#define CTIME_REX "^[adfjmnos][aceopu][bcglnprtvy][ ]+[0-3]?[0-9][ ]+[0-2]?[0-9]:[0-5][0-9]:[0-5][0-9]$"
-#define ABSOLUTE_TIME_REX "^[0-9]+[s]?$"
-#define RELATIVE_TIME_REX "^[\\+-\\][0-9]+[smhdw]?$"
-
-#define SECONDS_PER_MINUTE 60
-#define SECONDS_PER_HOUR 3600
-#define SECONDS_PER_DAY 86400
-#define SECONDS_PER_WEEK 604800
-
-static regex_t rex_canon, rex_ctime, rex_abs, rex_rel;
-static int reg_status = 0;
-
-/*
- * We use the last letter in the month name to determine
- * the month number (0-11). There are two collisions:
- * Jan and Jun both end in n
- * Mar and Apr both end in r
- * In these cases we check the second letter.
- *
- * The MTH_LAST array maps the last letter to a number.
- */
-static const int8_t MTH_LAST[] = {-1, 1, 11, -1, -1, -1, 7, -1, -1, -1, -1, 6, -1, 5, -1, 8, -1, 3, -1, 9, -1, 10, -1, -1, 4, -1};
-
-static int
-_month_num(char *s)
-{
- int i;
- int8_t v8;
-
- v8 = -1;
- if (s[2] > 90) v8 = s[2] - 'a';
- else v8 = s[2] - 'A';
-
- if ((v8 < 0) || (v8 > 25)) return -1;
-
- v8 = MTH_LAST[v8];
- if (v8 < 0) return -1;
-
- i = v8;
- if ((i == 5) && ((s[1] == 'a') || (s[1] == 'A'))) return 0;
- if ((i == 3) && ((s[1] == 'a') || (s[1] == 'A'))) return 2;
- return i;
-}
-
-time_t
-asl_parse_time(const char *in)
-{
- int len, y;
- struct tm t;
- time_t tick, delta, factor;
- char *str, *p, *x;
- static dispatch_once_t once;
-
- if (in == NULL) return -1;
-
- dispatch_once(&once, ^{
- int status;
- int rflags = REG_EXTENDED | REG_NOSUB | REG_ICASE;
-
- memset(&rex_canon, 0, sizeof(regex_t));
- status = regcomp(&rex_canon, CANONICAL_TIME_REX, rflags);
- if (status != 0) reg_status = -1;
-
- memset(&rex_ctime, 0, sizeof(regex_t));
- status = regcomp(&rex_ctime, CTIME_REX, rflags);
- if (status != 0) reg_status = -1;
-
- memset(&rex_abs, 0, sizeof(regex_t));
- status = regcomp(&rex_abs, ABSOLUTE_TIME_REX, rflags);
- if (status != 0) reg_status = -1;
-
- memset(&rex_rel, 0, sizeof(regex_t));
- status = regcomp(&rex_rel, RELATIVE_TIME_REX, rflags);
- if (status != 0) reg_status = -1;
- });
-
- if (reg_status < 0) return -1;
-
- len = strlen(in) + 1;
-
- if (regexec(&rex_abs, in, 0, NULL, 0) == 0)
- {
- /*
- * Absolute time (number of seconds since the epoch)
- */
- str = strdup(in);
- if (str == NULL) return -1;
-
- if ((str[len-2] == 's') || (str[len-2] == 'S')) str[len-2] = '\0';
-
- tick = atol(str);
- free(str);
-
- return tick;
- }
- else if (regexec(&rex_rel, in, 0, NULL, 0) == 0)
- {
- /*
- * Reletive time (number of seconds before or after right now)
- */
- str = strdup(in);
- if (str == NULL) return -1;
-
- factor = 1;
-
- if ((str[len-2] == 's') || (str[len-2] == 'S'))
- {
- str[len-2] = '\0';
- }
- else if ((str[len-2] == 'm') || (str[len-2] == 'M'))
- {
- str[len-2] = '\0';
- factor = SECONDS_PER_MINUTE;
- }
- else if ((str[len-2] == 'h') || (str[len-2] == 'H'))
- {
- str[len-2] = '\0';
- factor = SECONDS_PER_HOUR;
- }
- else if ((str[len-2] == 'd') || (str[len-2] == 'D'))
- {
- str[len-2] = '\0';
- factor = SECONDS_PER_DAY;
- }
- else if ((str[len-2] == 'w') || (str[len-2] == 'W'))
- {
- str[len-2] = '\0';
- factor = SECONDS_PER_WEEK;
- }
-
- tick = time(NULL);
- delta = factor * atol(str);
- tick += delta;
-
- free(str);
-
- return tick;
- }
- else if (regexec(&rex_canon, in, 0, NULL, 0) == 0)
- {
- memset(&t, 0, sizeof(struct tm));
- str = strdup(in);
- if (str == NULL) return -1;
-
- /* Get year */
- x = str;
- p = strchr(x, '.');
- *p = '\0';
- t.tm_year = atoi(x) - 1900;
-
- /* Get month */
- x = p + 1;
- p = strchr(x, '.');
- *p = '\0';
- t.tm_mon = atoi(x) - 1;
-
- /* Get day */
- x = p + 1;
- p = strchr(x, ' ');
- *p = '\0';
- t.tm_mday = atoi(x);
-
- /* Get hour */
- for (x = p + 1; *x == ' '; x++);
- p = strchr(x, ':');
- *p = '\0';
- t.tm_hour = atoi(x);
-
- /* Get minutes */
- x = p + 1;
- p = strchr(x, ':');
- *p = '\0';
- t.tm_min = atoi(x);
-
- /* Get seconds */
- x = p + 1;
- p = strchr(x, ' ');
- *p = '\0';
- t.tm_sec = atoi(x);
-
- free(str);
- return timegm(&t);
- }
- else if (regexec(&rex_ctime, in, 0, NULL, 0) == 0)
- {
- /* We assume it's in the current year */
- memset(&t, 0, sizeof(struct tm));
- tick = time(NULL);
- gmtime_r(&tick, &t);
- y = t.tm_year;
-
- memset(&t, 0, sizeof(struct tm));
- str = strdup(in);
- if (str == NULL) return -1;
-
- t.tm_year = y;
- t.tm_mon = _month_num(str);
- if (t.tm_mon < 0) return -1;
-
- for (x = strchr(str, ' '); *x == ' '; x++);
- p = strchr(x, ' ');
- *p = '\0';
- t.tm_mday = atoi(x);
-
- /* Get hour */
- for (x = p + 1; *x == ' '; x++);
- p = strchr(x, ':');
- *p = '\0';
- t.tm_hour = atoi(x);
-
- /* Get minutes */
- x = p + 1;
- p = strchr(x, ':');
- *p = '\0';
- t.tm_min = atoi(x);
-
- /* Get seconds */
- x = p + 1;
- t.tm_sec = atoi(x);
-
- t.tm_isdst = -1;
-
- free(str);
- return mktime(&t);
- }
-
- return -1;
-}
-
-#endif /* BUILDING_VARIANT */
+++ /dev/null
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <ctype.h>
-#include <stdio.h>
-#include <asl_core.h>
-#include <asl_private.h>
-#include <string.h>
-#include <membership.h>
-#include <pthread.h>
-#include <libkern/OSAtomic.h>
-
-#define ASL_STRING_QUANTUM 256
-static const char *cvis_7_13 = "abtnvfr";
-
-/*
- * Message ID generation
- */
-static uint64_t _asl_core_msg_next_id = 1;
-static pthread_mutex_t core_lock = PTHREAD_MUTEX_INITIALIZER;
-
-#define mix(a, b, c) \
-{ \
- a -= b; a -= c; a ^= (c>>13); \
- b -= c; b -= a; b ^= (a<< 8); \
- c -= a; c -= b; c ^= (b>>13); \
- a -= b; a -= c; a ^= (c>>12); \
- b -= c; b -= a; b ^= (a<<16); \
- c -= a; c -= b; c ^= (b>> 5); \
- a -= b; a -= c; a ^= (c>> 3); \
- b -= c; b -= a; b ^= (a<<10); \
- c -= a; c -= b; c ^= (b>>15); \
-}
-
-/*
- * Hash is used to improve string search.
- */
-uint32_t
-asl_core_string_hash(const char *s, uint32_t inlen)
-{
- uint32_t a, b, c, l, len;
-
- if (s == NULL) return 0;
-
- l = inlen;
- if (l == 0)
- {
- if (s[0] == '\0') return 0;
- l = strlen(s);
- }
-
- len = l;
- a = b = 0x9e3779b9;
- c = 0;
-
- while (len >= 12)
- {
- a += (s[0] + ((uint32_t)s[1]<<8) + ((uint32_t)s[ 2]<<16) + ((uint32_t)s[ 3]<<24));
- b += (s[4] + ((uint32_t)s[5]<<8) + ((uint32_t)s[ 6]<<16) + ((uint32_t)s[ 7]<<24));
- c += (s[8] + ((uint32_t)s[9]<<8) + ((uint32_t)s[10]<<16) + ((uint32_t)s[11]<<24));
-
- mix(a, b, c);
-
- s += 12;
- len -= 12;
- }
-
- c += l;
- switch(len)
- {
- case 11: c += ((uint32_t)s[10]<<24);
- case 10: c += ((uint32_t)s[9]<<16);
- case 9 : c += ((uint32_t)s[8]<<8);
-
- case 8 : b += ((uint32_t)s[7]<<24);
- case 7 : b += ((uint32_t)s[6]<<16);
- case 6 : b += ((uint32_t)s[5]<<8);
- case 5 : b += s[4];
-
- case 4 : a += ((uint32_t)s[3]<<24);
- case 3 : a += ((uint32_t)s[2]<<16);
- case 2 : a += ((uint32_t)s[1]<<8);
- case 1 : a += s[0];
- }
-
- mix(a, b, c);
-
- if (c == 0) c = 1;
- return c;
-}
-
-const char *
-asl_core_error(uint32_t code)
-{
- switch (code)
- {
- case ASL_STATUS_OK: return "Operation Succeeded";
- case ASL_STATUS_INVALID_ARG: return "Invalid Argument";
- case ASL_STATUS_INVALID_STORE: return "Invalid Data Store";
- case ASL_STATUS_INVALID_STRING: return "Invalid String";
- case ASL_STATUS_INVALID_ID: return "Invalid ID Number";
- case ASL_STATUS_INVALID_MESSAGE: return "Invalid Message";
- case ASL_STATUS_NOT_FOUND: return "Not Found";
- case ASL_STATUS_READ_FAILED: return "Read Operation Failed";
- case ASL_STATUS_WRITE_FAILED: return "Write Operation Failed";
- case ASL_STATUS_NO_MEMORY: return "System Memory Allocation Failed";
- case ASL_STATUS_ACCESS_DENIED: return "Access Denied";
- case ASL_STATUS_READ_ONLY: return "Read Only Access";
- case ASL_STATUS_WRITE_ONLY: return "Write Only Access";
- case ASL_STATUS_MATCH_FAILED: return "Match Failed";
- case ASL_STATUS_NO_RECORDS: return "No More Records";
- }
-
- return "Operation Failed";
-}
-
-static uint32_t
-asl_core_check_user_access(int32_t msgu, int32_t readu)
-{
- /* -1 means anyone may read */
- if (msgu == -1) return ASL_STATUS_OK;
-
- /* Check for exact match */
- if (msgu == readu) return ASL_STATUS_OK;
-
- return ASL_STATUS_ACCESS_DENIED;
-}
-
-static uint32_t
-asl_core_check_group_access(int32_t msgg, int32_t readu, int32_t readg)
-{
- int check;
- uuid_t uu, gu;
-
- /* -1 means anyone may read */
- if (msgg == -1) return ASL_STATUS_OK;
-
- /* Check for exact match */
- if (msgg == readg) return ASL_STATUS_OK;
-
- /* Check if user (u) is in read group (msgg) */
- mbr_uid_to_uuid(readu, uu);
- mbr_gid_to_uuid(msgg, gu);
-
- check = 0;
- mbr_check_membership(uu, gu, &check);
- if (check != 0) return ASL_STATUS_OK;
-
- return ASL_STATUS_ACCESS_DENIED;
-}
-
-uint32_t
-asl_core_check_access(int32_t msgu, int32_t msgg, int32_t readu, int32_t readg, uint16_t flags)
-{
- uint16_t uset, gset;
-
- /* root (uid 0) may always read */
- if (readu == 0) return ASL_STATUS_OK;
-
- uset = flags & ASL_MSG_FLAG_READ_UID_SET;
- gset = flags & ASL_MSG_FLAG_READ_GID_SET;
-
- /* if no access controls are set, anyone may read */
- if ((uset | gset) == 0) return ASL_STATUS_OK;
-
- /* if only uid is set, then access is only by uid match */
- if ((uset != 0) && (gset == 0)) return asl_core_check_user_access(msgu, readu);
-
- /* if only gid is set, then access is only by gid match */
- if ((uset == 0) && (gset != 0)) return asl_core_check_group_access(msgg, readu, readg);
-
- /* both uid and gid are set - check user, then group */
- if ((asl_core_check_user_access(msgu, readu)) == ASL_STATUS_OK) return ASL_STATUS_OK;
- return asl_core_check_group_access(msgg, readu, readg);
-}
-
-uint64_t
-asl_core_htonq(uint64_t n)
-{
-#ifdef __BIG_ENDIAN__
- return n;
-#else
- u_int32_t t;
- union
- {
- u_int64_t q;
- u_int32_t l[2];
- } x;
-
- x.q = n;
- t = x.l[0];
- x.l[0] = htonl(x.l[1]);
- x.l[1] = htonl(t);
-
- return x.q;
-#endif
-}
-
-uint64_t
-asl_core_ntohq(uint64_t n)
-{
-#ifdef __BIG_ENDIAN__
- return n;
-#else
- u_int32_t t;
- union
- {
- u_int64_t q;
- u_int32_t l[2];
- } x;
-
- x.q = n;
- t = x.l[0];
- x.l[0] = ntohl(x.l[1]);
- x.l[1] = ntohl(t);
-
- return x.q;
-#endif
-}
-
-uint64_t
-asl_core_new_msg_id(uint64_t start)
-{
- uint64_t out;
-
- pthread_mutex_lock(&core_lock);
-
- if (start != 0) _asl_core_msg_next_id = start;
-
- out = _asl_core_msg_next_id;
- _asl_core_msg_next_id++;
-
- pthread_mutex_unlock(&core_lock);
-
- return out;
-}
-
-/*
- * asl_core_encode_buffer
- * encode arbitrary data as a C string without embedded zero (nul) characters
- *
- * The routine computes a histogram of the input buffer and finds
- * the two least frequently used non-nul chars (L[0] and L[1]).
- *
- * L[0] is used to stand in for nul.
- * L[1] is used as the escape character.
- * Occurrences of nul in the data are encoded as L[0]
- * Occurrences of L[0] in the data are encoded as the sequence L[1] 1.
- * Occurrences of L[1] in the data are encoded as the sequence L[1] 2.
- *
- * The output string is preceded by L[0] L[1], and is nul terminated.
- * The output length is 2 + n + N(L[0]) + N(L[1]) + 1
- * where N(x) is the number of occurrences of x in the input string.
- * The worst case occurs when all characters are equally frequent,
- * In that case the output size will less that 1% larger than the input.
- */
-char *
-asl_core_encode_buffer(const char *in, uint32_t len)
-{
- char *str;
- uint32_t i, j, k, outlen, breakit, min, hist[256];
- uint32_t lfu[2], save[2];
- uint8_t v;
-
- if (in == NULL) return NULL;
- if (len == 0) return NULL;
-
- memset(hist, 0, sizeof(hist));
- save[0] = 0;
- save[1] = 0;
-
- for (i = 0; i < len; i++)
- {
- v = in[i];
- hist[v]++;
- }
-
- for (j = 0; j < 2; j++)
- {
- lfu[j] = 1;
- min = hist[1];
-
- for (i = 2; i < 256; i++)
- {
- if (hist[i] < min)
- {
- lfu[j] = i;
- min = hist[i];
-
- /*
- * Stop if there are no occurances or character i in the input.
- * The minimum will never be less than zero.
- */
- if (min == 0) break;
-
- /*
- * When looking for the second least frequently used character,
- * stop scanning if we hit the same minimum as we saw in the first
- * pass. There will be no smaller values.
- */
- if ((j == 1) && (min == save[0])) break;
- }
- }
-
- save[j] = hist[lfu[j]];
- hist[lfu[j]] = (uint32_t)-1;
- }
-
- outlen = 2 + len + save[0] + save[1] + 1;
-
- str = malloc(outlen);
- if (str == NULL) return NULL;
-
- str[outlen - 1] = '\0';
-
- str[0] = lfu[0];
- str[1] = lfu[1];
-
- j = 2;
-
- for (i = 0; i < len; i++)
- {
- v = in[i];
- if (v == 0)
- {
- str[j++] = lfu[0];
- continue;
- }
-
- breakit = 0;
- for (k = 0; (k < 2) && (breakit == 0); k++)
- {
- if (v == lfu[k])
- {
- str[j++] = lfu[1];
- str[j++] = k + 1;
- breakit = 1;
- }
- }
-
- if (breakit == 1) continue;
-
- str[j++] = v;
- }
-
- return str;
-}
-
-/*
- * asl_core_decode_buffer
- * decode a string produced by asl_encode_buffer to recreate the original data
- */
-int32_t
-asl_core_decode_buffer(const char *in, char **buf, uint32_t *len)
-{
- uint8_t v;
- uint32_t i, j, n, outlen;
- uint8_t lfu[2];
- char *out;
-
- if (buf == NULL) return -1;
- if (len == NULL) return -1;
-
- lfu[0] = in[0];
- lfu[1] = in[1];
-
- outlen = 0;
-
- /* strip trailing nul */
- n = strlen(in);
-
- /* determine output length and check for invalid input */
- for (i = 2; i < n; i++)
- {
- v = in[i];
- if (v == lfu[1])
- {
- i++;
- if (i == n) return -1;
-
- v = in[i];
- if ((v < 1) || (v > 2)) return -1;
-
- outlen++;
- }
- else outlen++;
- }
-
- if (outlen == 0) return -1;
-
- out = malloc(outlen);
- if (out == NULL) return -1;
-
- j = 0;
- for (i = 2; i < n; i++)
- {
- v = in[i];
- if (v == lfu[0])
- {
- out[j++] = 0;
- }
- else if (v == lfu[1])
- {
- i++;
- v = in[i];
- out[j++] = lfu[v - 1];
- }
- else out[j++] = v;
- }
-
- *len = outlen;
- *buf = out;
- return 0;
-}
-
-/* asl_string_t support */
-
-asl_string_t *
-asl_string_new(uint32_t encoding)
-{
- asl_string_t *str = (asl_string_t *)calloc(1, sizeof(asl_string_t));
- if (str == NULL) return NULL;
-
- str->encoding = encoding;
- str->delta = ASL_STRING_QUANTUM;
- if (encoding & ASL_STRING_VM) str->delta = PAGE_SIZE;
- str->bufsize = 0;
- str->cursor = 0;
-
- if (encoding & ASL_STRING_LEN) asl_string_append_no_encoding(str, " 0 ");
- return str;
-}
-
-void
-asl_string_free(asl_string_t *str)
-{
- if (str == NULL) return;
-
- if (str->encoding & ASL_STRING_VM)
- {
- vm_deallocate(mach_task_self(), (vm_address_t)str->buf, str->bufsize);
- }
- else
- {
- free(str->buf);
- }
-
- free(str);
-}
-
-char *
-asl_string_free_return_bytes(asl_string_t *str)
-{
- char *out;
- if (str == NULL) return NULL;
-
- out = str->buf;
- free(str);
- return out;
-}
-
-char *
-asl_string_bytes(asl_string_t *str)
-{
- if (str == NULL) return NULL;
- return str->buf;
-}
-
-/* length includes trailing nul */
-size_t
-asl_string_length(asl_string_t *str)
-{
- if (str == NULL) return 0;
- if (str->cursor == 0) return 0;
-
- return str->cursor + 1;
-}
-
-size_t
-asl_string_allocated_size(asl_string_t *str)
-{
- if (str == NULL) return 0;
- return str->bufsize;
-}
-
-static int
-_asl_string_grow(asl_string_t *str, size_t len)
-{
- size_t newlen = 0;
-
- if (str == NULL) return -1;
- if (len == 0) return 0;
-
- if (str->bufsize == 0)
- {
- newlen = ((len + str->delta - 1) / str->delta) * str->delta;
- }
- else
- {
- /* used size is (str->cursor + 1) including tailiing nul */
- if (len <= (str->bufsize - (str->cursor + 1))) return 0;
-
- /* really this is ((str->cursor + 1) + len + (str->delta - 1)) */
- newlen = ((str->cursor + len + str->delta) / str->delta) * str->delta;
- }
-
- if (str->encoding & ASL_STRING_VM)
- {
- kern_return_t kstatus;
- vm_address_t new = 0;
-
- kstatus = vm_allocate(mach_task_self(), &new, newlen, TRUE);
- if (kstatus != KERN_SUCCESS)
- {
- new = 0;
- newlen = 0;
- return -1;
- }
-
- if (str->buf != NULL)
- {
- memcpy((void *)new, str->buf, str->bufsize);
- vm_deallocate(mach_task_self(), (vm_address_t)str->buf, str->bufsize);
- }
-
- str->buf = (char *)new;
- str->bufsize = newlen;
- }
- else
- {
- str->buf = reallocf(str->buf, newlen);
- if (str->buf == NULL)
- {
- str->cursor = 0;
- str->bufsize = 0;
- return -1;
- }
-
- str->bufsize = newlen;
- }
-
- return 0;
-}
-
-asl_string_t *
-asl_string_append_char_no_encoding(asl_string_t *str, const char c)
-{
- size_t len;
-
- if (str == NULL) return NULL;
-
- len = 1;
- if (str->bufsize == 0) len++;
-
- if (_asl_string_grow(str, len) < 0) return str;
-
- str->buf[str->cursor] = c;
- str->cursor++;
- str->buf[str->cursor] = '\0';
-
- if (str->encoding & ASL_STRING_LEN)
- {
- char tmp[11];
- snprintf(tmp, sizeof(tmp), "%10lu", str->cursor - 10);
- memcpy(str->buf, tmp, 10);
- }
-
- return str;
-}
-
-asl_string_t *
-asl_string_append_no_encoding(asl_string_t *str, const char *app)
-{
- size_t len, applen;
-
- if (str == NULL) return NULL;
- if (app == NULL) return str;
-
- applen = strlen(app);
- len = applen;
- if (str->bufsize == 0) len++;
-
- if (_asl_string_grow(str, len) < 0) return str;
-
- memcpy(str->buf + str->cursor, app, applen);
-
- str->cursor += applen;
- str->buf[str->cursor] = '\0';
-
- if (str->encoding & ASL_STRING_LEN)
- {
- char tmp[11];
- snprintf(tmp, sizeof(tmp), "%10lu", str->cursor - 10);
- memcpy(str->buf, tmp, 10);
- }
-
- return str;
-}
-
-static asl_string_t *
-asl_string_append_internal(asl_string_t *str, const char *app, int encode_space)
-{
- uint8_t x;
- const char *p;
-
- if (str == NULL) return NULL;
- if (app == NULL) return str;
-
- switch (str->encoding & ASL_ENCODE_MASK)
- {
- case ASL_ENCODE_NONE:
- {
- return asl_string_append_no_encoding(str, app);
- }
- case ASL_ENCODE_SAFE:
- {
- /* minor encoding to reduce the likelyhood of spoof attacks */
- const char *p;
-
- for (p = app; *p != '\0'; p++)
- {
- if ((*p == 10) || (*p == 13))
- {
- asl_string_append_no_encoding(str, "\n\t");
- }
- else if (*p == 8)
- {
- asl_string_append_no_encoding(str, "^H");
- }
- else
- {
- asl_string_append_char_no_encoding(str, *p);
- }
- }
-
- return str;
- }
- case ASL_ENCODE_ASL:
- {
- for (p = app; *p != '\0'; p++)
- {
- int meta = 0;
-
- x = *p;
-
- /* Meta chars get \M prefix */
- if (x >= 128)
- {
- /* except meta-space, which is \240 */
- if (x == 160)
- {
- asl_string_append_no_encoding(str, "\\240");
- continue;
- }
-
- asl_string_append_no_encoding(str, "\\M");
- x &= 0x7f;
- meta = 1;
- }
-
- /* space is either ' ' or \s */
- if (x == 32)
- {
- if (encode_space == 0)
- {
- asl_string_append_char_no_encoding(str, ' ');
- continue;
- }
-
- asl_string_append_no_encoding(str, "\\s");
- continue;
- }
-
- /* \ is escaped */
- if ((meta == 0) && (x == 92))
- {
- asl_string_append_no_encoding(str, "\\\\");
- continue;
- }
-
- /* [ and ] are escaped in ASL encoding */
- if ((str->encoding & ASL_ENCODE_ASL) && (meta == 0) && ((*p == 91) || (*p == 93)))
- {
- if (*p == '[') asl_string_append_no_encoding(str, "\\[");
- else asl_string_append_no_encoding(str, "\\]");
- continue;
- }
-
- /* DEL is \^? */
- if (x == 127)
- {
- if (meta == 0)
- {
- asl_string_append_char_no_encoding(str, '\\');
- }
-
- asl_string_append_no_encoding(str, "^?");
- continue;
- }
-
- /* 33-126 are printable (add a '-' prefix for meta) */
- if ((x >= 33) && (x <= 126))
- {
- if (meta == 1)
- {
- asl_string_append_char_no_encoding(str, '-');
- }
-
- asl_string_append_char_no_encoding(str, x);
- continue;
- }
-
- /* non-meta BEL, BS, HT, NL, VT, NP, CR (7-13) are \a, \b, \t, \n, \v, \f, and \r */
- if ((meta == 0) && (x >= 7) && (x <= 13))
- {
- asl_string_append_char_no_encoding(str, '\\');
- asl_string_append_char_no_encoding(str, cvis_7_13[x - 7]);
- continue;
- }
-
- /* 0 - 31 are ^@ - ^_ (non-meta get a leading \) */
- if (x <= 31)
- {
- if (meta == 0)
- {
- asl_string_append_char_no_encoding(str, '\\');
- }
-
- asl_string_append_char_no_encoding(str, '^');
- asl_string_append_char_no_encoding(str, 64 + x);
- continue;
- }
-
- asl_string_append_char_no_encoding(str, x);
- }
-
- return str;
- }
- case ASL_ENCODE_XML:
- {
- for (p = app; *p != '\0'; p++)
- {
- x = *p;
-
- if (x == '&')
- {
- asl_string_append_no_encoding(str, "&");
- }
- else if (x == '<')
- {
- asl_string_append_no_encoding(str, "<");
- }
- else if (x == '>')
- {
- asl_string_append_no_encoding(str, ">");
- }
- else if (x == '"')
- {
- asl_string_append_no_encoding(str, """);
- }
- else if (x == '\'')
- {
- asl_string_append_no_encoding(str, "'");
- }
- else if (iscntrl(x))
- {
- char tmp[8];
- snprintf(tmp, sizeof(tmp), "&#x%02hhx;", x);
- asl_string_append_no_encoding(str, tmp);
- }
- else
- {
- asl_string_append_char_no_encoding(str, x);
- }
- }
- }
- default:
- {
- return str;
- }
- }
-
- return str;
-}
-
-asl_string_t *
-asl_string_append(asl_string_t *str, const char *app)
-{
- return asl_string_append_internal(str, app, 0);
-}
-
-asl_string_t *
-asl_string_append_asl_key(asl_string_t *str, const char *app)
-{
- return asl_string_append_internal(str, app, 1);
-}
-
-asl_string_t *
-asl_string_append_op(asl_string_t *str, uint32_t op)
-{
- char opstr[8];
- uint32_t i;
-
- if (str == NULL) return NULL;
-
- if (op == ASL_QUERY_OP_NULL)
- {
- return asl_string_append_char_no_encoding(str, '.');
- }
-
- i = 0;
- if (op & ASL_QUERY_OP_CASEFOLD) opstr[i++] = 'C';
-
- if (op & ASL_QUERY_OP_REGEX) opstr[i++] = 'R';
-
- if (op & ASL_QUERY_OP_NUMERIC) opstr[i++] = 'N';
-
- if (op & ASL_QUERY_OP_PREFIX)
- {
- if (op & ASL_QUERY_OP_SUFFIX) opstr[i++] = 'S';
- else opstr[i++] = 'A';
- }
- if (op & ASL_QUERY_OP_SUFFIX) opstr[i++] = 'Z';
-
- switch (op & ASL_QUERY_OP_TRUE)
- {
- case ASL_QUERY_OP_EQUAL:
- opstr[i++] = '=';
- break;
- case ASL_QUERY_OP_GREATER:
- opstr[i++] = '>';
- break;
- case ASL_QUERY_OP_GREATER_EQUAL:
- opstr[i++] = '>';
- opstr[i++] = '=';
- break;
- case ASL_QUERY_OP_LESS:
- opstr[i++] = '<';
- break;
- case ASL_QUERY_OP_LESS_EQUAL:
- opstr[i++] = '<';
- opstr[i++] = '=';
- break;
- case ASL_QUERY_OP_NOT_EQUAL:
- opstr[i++] = '!';
- break;
- case ASL_QUERY_OP_TRUE:
- opstr[i++] = 'T';
- break;
- default:
- break;
- }
-
- if (i == 0)
- {
- return asl_string_append_char_no_encoding(str, '.');
- }
-
- opstr[i] = '\0';
- return asl_string_append_no_encoding(str, opstr);
-}
-
-asl_string_t *
-asl_string_append_xml_tag(asl_string_t *str, const char *tag, const char *s)
-{
- asl_string_append_no_encoding(str, "\t\t<");
- asl_string_append_no_encoding(str, tag);
- asl_string_append_no_encoding(str, ">");
- asl_string_append_no_encoding(str, s);
- asl_string_append_no_encoding(str, "</");
- asl_string_append_no_encoding(str, tag);
- asl_string_append_no_encoding(str, ">\n");
- return str;
-}
+++ /dev/null
-#ifndef __ASL_CORE_H__
-#define __ASL_CORE_H__
-
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <Availability.h>
-
-typedef struct
-{
- uint32_t encoding;
- size_t delta;
- size_t bufsize;
- size_t cursor;
- char *buf;
-} asl_string_t;
-
-#define ASL_STATUS_OK 0
-#define ASL_STATUS_INVALID_ARG 1
-#define ASL_STATUS_INVALID_STORE 2
-#define ASL_STATUS_INVALID_STRING 3
-#define ASL_STATUS_INVALID_ID 4
-#define ASL_STATUS_INVALID_MESSAGE 5
-#define ASL_STATUS_NOT_FOUND 6
-#define ASL_STATUS_READ_FAILED 7
-#define ASL_STATUS_WRITE_FAILED 8
-#define ASL_STATUS_NO_MEMORY 9
-#define ASL_STATUS_ACCESS_DENIED 10
-#define ASL_STATUS_READ_ONLY 11
-#define ASL_STATUS_WRITE_ONLY 12
-#define ASL_STATUS_MATCH_FAILED 13
-#define ASL_STATUS_NO_RECORDS 14
-#define ASL_STATUS_FAILED 9999
-
-#define ASL_REF_NULL 0xffffffffffffffffLL
-
-#define ASL_MSG_FLAG_READ_UID_SET 0x0001
-#define ASL_MSG_FLAG_READ_GID_SET 0x0002
-#define ASL_MSG_FLAG_SEARCH_MATCH 0x8000
-#define ASL_MSG_FLAG_SEARCH_CLEAR 0x7fff
-
-#define ASL_QUERY_MATCH_SLOW 0x00000000
-#define ASL_QUERY_MATCH_MSG_ID 0x00000001
-#define ASL_QUERY_MATCH_TIME 0x00000002
-#define ASL_QUERY_MATCH_NANO 0x00000004
-#define ASL_QUERY_MATCH_LEVEL 0x00000008
-#define ASL_QUERY_MATCH_PID 0x00000010
-#define ASL_QUERY_MATCH_UID 0x00000020
-#define ASL_QUERY_MATCH_GID 0x00000040
-#define ASL_QUERY_MATCH_RUID 0x00000080
-#define ASL_QUERY_MATCH_RGID 0x00000100
-#define ASL_QUERY_MATCH_REF_PID 0x00000200
-#define ASL_QUERY_MATCH_HOST 0x00000400
-#define ASL_QUERY_MATCH_SENDER 0x00000800
-#define ASL_QUERY_MATCH_FACILITY 0x00001000
-#define ASL_QUERY_MATCH_MESSAGE 0x00002000
-#define ASL_QUERY_MATCH_REF_PROC 0x00004000
-#define ASL_QUERY_MATCH_SESSION 0x00008000
-#define ASL_QUERY_MATCH_TRUE 0x80000000
-#define ASL_QUERY_MATCH_FALSE 0x40000000
-#define ASL_QUERY_MATCH_ERROR 0x20000000
-
-#define ASL_ENCODE_NONE 0
-#define ASL_ENCODE_SAFE 1
-#define ASL_ENCODE_ASL 2
-#define ASL_ENCODE_XML 3
-#define ASL_ENCODE_MASK 0x0000000f
-#define ASL_STRING_VM 0x80000000
-#define ASL_STRING_LEN 0x40000000
-
-#define ASL_STRING_MIG 0xc0000002
-
-uint32_t asl_core_string_hash(const char *str, uint32_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-const char *asl_core_error(uint32_t code) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_core_check_access(int32_t msgu, int32_t msgg, int32_t readu, int32_t readg, uint16_t flags) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint64_t asl_core_htonq(uint64_t n) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint64_t asl_core_ntohq(uint64_t n)__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint64_t asl_core_new_msg_id(uint64_t start) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-char *asl_core_encode_buffer(const char *in, uint32_t len) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
-int32_t asl_core_decode_buffer(const char *in, char **buf, uint32_t *len) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_5_0);
-
-asl_string_t *asl_string_new(uint32_t encoding) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-char *asl_string_free_return_bytes(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-void asl_string_free(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-char *asl_string_bytes(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-size_t asl_string_length(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-size_t asl_string_allocated_size(asl_string_t *str) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-asl_string_t *asl_string_append(asl_string_t *str, const char *app) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-asl_string_t *asl_string_append_asl_key(asl_string_t *str, const char *app) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-asl_string_t *asl_string_append_op(asl_string_t *str, uint32_t op) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-asl_string_t *asl_string_append_no_encoding(asl_string_t *str, const char *app) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-asl_string_t *asl_string_append_char_no_encoding(asl_string_t *str, const char c) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-asl_string_t *asl_string_append_xml_tag(asl_string_t *str, const char *tag, const char *s) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-
-#endif /* __ASL_CORE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <assert.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/event.h>
-#include <asl.h>
-#include <asl_private.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <dispatch/dispatch.h>
-
-/* asl.c */
-__private_extern__ void asl_client_release(asl_client_t *asl);
-__private_extern__ asl_client_t *asl_client_retain(asl_client_t *asl);
-
-#define BUF_SIZE 512
-
-static dispatch_queue_t redirect_serial_q;
-static dispatch_group_t read_source_group;
-
-typedef struct {
- int level;
- asl_client_t *asl;
- asl_msg_t *msg;
-
- /* Buffered reading */
- char *buf;
- char *w;
-
- dispatch_source_t read_source;
-} asl_redirect_t;
-
-static asl_redirect_t *redirect_descriptors = NULL;
-static int n_redirect_descriptors = 0;
-
-/* Read from the FD until there is no more to read and redirect to ASL.
- * Preconditions:
- * 1: called from the appropriate serial queue for operating on
- * redirect_descriptors
- * 2: descriptor corresponds to a valid entry in redirect_descriptors
- *
- * Return values:
- * If the pipe is closed, EOF is returned regardless of how many bytes
- * were processed. If the pipe is still open, the number of read bytes
- * is returned.
- */
-static inline int _read_redirect(int descriptor, int flush) {
- int total_read = 0;
- int nbytes;
- asl_redirect_t *aslr = &redirect_descriptors[descriptor];
-
- while ((nbytes = read(descriptor, aslr->w, BUF_SIZE - (aslr->w - aslr->buf) - 1)) > 0) {
- char *s, *p;
-
- /* Increment our returned number read */
- total_read += nbytes;
-
- /* Increment our write location */
- aslr->w += nbytes;
- aslr->w[0] = '\0';
-
- /* One line at a time */
- for (p = aslr->buf; p < aslr->w; p = s + 1) {
- /* Find null or \n */
- for (s=p; *s && *s != '\n'; s++);
-
- if (*s == '\n') {
- *s='\0';
- }
-
- if (s < aslr->w || aslr->buf == p) {
- /* Either the first of multiple messages or one message which is larger than our buffer */
- asl_log((aslclient)aslr->asl, (aslmsg)aslr->msg, aslr->level, "%s", p);
- } else {
- /* We reached the end of the buffer, move this chunk to the start. */
- memmove(aslr->buf, p, BUF_SIZE - (p - aslr->buf));
- aslr->w = aslr->buf + (s - p);
- break;
- }
- }
-
- if (p == aslr->w) {
- /* Start writing at the beginning in the case where we cleared the buffer */
- aslr->w = aslr->buf;
- }
- }
-
- /* Flush if requested or we're at EOF */
- if (flush || nbytes == 0) {
- if (aslr->w > aslr->buf) {
- *aslr->w = '\0';
- asl_log((aslclient)aslr->asl, (aslmsg)aslr->msg, aslr->level, "%s", aslr->buf);
- }
- }
-
- if (nbytes == 0)
- return EOF;
- return total_read;
-}
-
-static void read_from_source(void *_source) {
- dispatch_source_t source = (dispatch_source_t)_source;
- int descriptor = dispatch_source_get_handle(source);
- if (_read_redirect(descriptor, 0) == EOF) {
- dispatch_source_cancel(source);
- }
-}
-
-static void cancel_source(void *_source) {
- dispatch_source_t source = (dispatch_source_t)_source;
- int descriptor = dispatch_source_get_handle(source);
- asl_redirect_t *aslr = &redirect_descriptors[descriptor];
-
- /* Flush the buffer */
- _read_redirect(descriptor, 1);
-
- close(descriptor);
-
- asl_client_release(aslr->asl);
- asl_msg_release(aslr->msg);
- free(aslr->buf);
-
- memset(aslr, 0, sizeof(*aslr));
- dispatch_release(source);
- dispatch_group_leave(read_source_group);
-}
-
-
-static void redirect_atexit(void) {
- int i;
-
- /* stdout is linebuffered, so flush the buffer */
- if (redirect_descriptors[STDOUT_FILENO].buf)
- fflush(stdout);
-
- /* Cancel all of our dispatch sources, so they flush to ASL */
- for (i=0; i < n_redirect_descriptors; i++)
- if (redirect_descriptors[i].read_source)
- dispatch_source_cancel(redirect_descriptors[i].read_source);
-
- /* Wait at least three seconds for our sources to flush to ASL */
- dispatch_group_wait(read_source_group, dispatch_time(DISPATCH_TIME_NOW, 3LL * NSEC_PER_SEC));
-}
-
-static void asl_descriptor_init(void *ctx __unused)
-{
- assert((redirect_descriptors = calloc(16, sizeof(*redirect_descriptors))) != NULL);
- n_redirect_descriptors = 16;
-
- redirect_serial_q = dispatch_queue_create("com.apple.asl-redirect", NULL);
- assert(redirect_serial_q != NULL);
-
- read_source_group = dispatch_group_create();
- assert(read_source_group != NULL);
-
- atexit(redirect_atexit);
-}
-
-static int asl_log_from_descriptor(aslclient ac, aslmsg am, int level, int descriptor) {
- int err __block = 0;
- static dispatch_once_t once_control;
- dispatch_once_f(&once_control, NULL, asl_descriptor_init);
- asl_client_t *asl = (asl_client_t *)ac;
- asl_msg_t *msg = (asl_msg_t *)am;
-
- if (descriptor < 0)
- return EBADF;
-
- if (msg != NULL) {
- msg = asl_msg_copy(msg);
- if (msg == NULL)
- return ENOMEM;
- }
-
- dispatch_sync(redirect_serial_q, ^{
- dispatch_source_t read_source;
-
- /* Reallocate if we need more space */
- if (descriptor >= n_redirect_descriptors) {
- size_t new_n = 1 << (fls(descriptor) + 1);
- asl_redirect_t *new_array = realloc(redirect_descriptors, new_n * sizeof(*redirect_descriptors));
- if (!new_array) {
- err = errno;
- return;
- }
- redirect_descriptors = new_array;
- memset(redirect_descriptors + n_redirect_descriptors, 0, (new_n - n_redirect_descriptors) * sizeof(*redirect_descriptors));
- n_redirect_descriptors = new_n;
- }
-
- /* If we're already listening on it, return error. */
- if (redirect_descriptors[descriptor].buf != NULL) {
- err = EBADF;
- return;
- }
-
- /* Initialize our buffer */
- redirect_descriptors[descriptor].buf = (char *)malloc(BUF_SIZE);
- if (redirect_descriptors[descriptor].buf == NULL) {
- err = errno;
- return;
- }
- redirect_descriptors[descriptor].w = redirect_descriptors[descriptor].buf;
-
- /* Store our ASL settings */
- redirect_descriptors[descriptor].level = level;
- redirect_descriptors[descriptor].asl = asl_client_retain(asl);
- redirect_descriptors[descriptor].msg = msg;
-
- /* Don't block on reads from this descriptor */
- (void)fcntl(descriptor, F_SETFL, O_NONBLOCK);
-
- /* Start listening */
- read_source = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, descriptor, 0, redirect_serial_q);
- redirect_descriptors[descriptor].read_source = read_source;
- dispatch_set_context(read_source, read_source);
- dispatch_source_set_event_handler_f(read_source, read_from_source);
- dispatch_source_set_cancel_handler_f(read_source, cancel_source);
- dispatch_group_enter(read_source_group);
- dispatch_resume(read_source);
- });
-
- if (err) {
- asl_msg_release(msg);
- }
-
- return err;
-}
-
-int asl_log_descriptor(aslclient ac, aslmsg am, int level, int descriptor, uint32_t fd_type) {
- int pipepair[2];
- int retval;
- int oerrno = errno;
-
- if (fd_type == ASL_LOG_DESCRIPTOR_READ)
- return asl_log_from_descriptor(ac, am, level, descriptor);
-
- assert(fd_type == ASL_LOG_DESCRIPTOR_WRITE);
-
- /* Create pipe */
- if (pipe(pipepair) == -1) {
- retval = errno;
- errno = oerrno;
- return retval;
- }
-
- /* Close the read descriptor but not the write descriptor on exec */
- if (fcntl(pipepair[0], F_SETFD, FD_CLOEXEC) == -1) {
- retval = errno;
- errno = oerrno;
- return retval;
- }
-
- /* Replace the existing descriptor */
- if (dup2(pipepair[1], descriptor) == -1) {
- close(pipepair[0]);
- close(pipepair[1]);
- retval = errno;
- errno = oerrno;
- return retval;
- }
-
- /* If we capture STDOUT_FILENO, make sure we linebuffer stdout */
- if (descriptor == STDOUT_FILENO)
- setlinebuf(stdout);
-
- /* Close the duplicate descriptors since they've been reassigned */
- close(pipepair[1]);
-
- /* Hand off the read end of our pipe to asl_log_descriptor */
- return asl_log_from_descriptor(ac, am, level, pipepair[0]);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <asl_core.h>
-#include <asl_file.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/errno.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/acl.h>
-#include <membership.h>
-#include <time.h>
-#include <sys/time.h>
-#include <asl_private.h>
-#include <asl_legacy1.h>
-#include <TargetConditionals.h>
-
-extern time_t asl_parse_time(const char *str);
-extern int asl_msg_cmp(aslmsg a, aslmsg b);
-
-#define forever for(;;)
-#define MILLION 1000000
-
-/*
- * MSG and STR records have (at least) a type (uint16_t) and a length (uint32_t)
- * type and level are both 16 bit fields so that alignment isn't a pain.
- */
-#define RECORD_COMMON_LEN 6
-#define RECORD_TYPE_LEN 2
-#define BUFFER_OFFSET_KVCOUNT 56
-
-#define SCRATCH_BUFFER_SIZE (MSG_RECORD_FIXED_LENGTH + (20 * sizeof(uint64_t)))
-
-typedef struct
-{
- uint64_t next;
- uint64_t mid;
- uint64_t time;
- uint32_t nano;
- uint16_t level;
- uint16_t flags;
- uint32_t pid;
- uint32_t uid;
- uint32_t gid;
- uint32_t ruid;
- uint32_t rgid;
- uint32_t refpid;
- uint32_t kvcount;
- uint64_t host;
- uint64_t sender;
- uint64_t facility;
- uint64_t message;
- uint64_t refproc;
- uint64_t session;
- uint64_t prev;
-} file_record_t;
-
-typedef struct
-{
- asl_file_list_t *list;
- int dir;
-} asl_file_match_token_t;
-
-static uint16_t
-_asl_get_16(char *h)
-{
- uint16_t x;
-
- memcpy(&x, h, 2);
- return ntohs(x);
-}
-
-static void
-_asl_put_16(uint16_t i, char *h)
-{
- uint16_t x;
-
- x = htons(i);
- memcpy(h, &x, 2);
-}
-
-static uint32_t
-_asl_get_32(char *h)
-{
- uint32_t x;
-
- memcpy(&x, h, 4);
- return ntohl(x);
-}
-
-static void
-_asl_put_32(uint32_t i, char *h)
-{
- uint32_t x;
-
- x = htonl(i);
- memcpy(h, &x, 4);
-}
-
-static uint64_t
-_asl_get_64(char *h)
-{
- uint64_t x;
-
- memcpy(&x, h, 8);
- return asl_core_ntohq(x);
-}
-
-static void
-_asl_put_64(uint64_t i, char *h)
-{
- uint64_t x;
-
- x = asl_core_htonq(i);
- memcpy(h, &x, 8);
-}
-
-static uint32_t
-asl_file_read_uint32(asl_file_t *s, off_t off, uint32_t *out)
-{
- uint32_t status, val;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (s->store == NULL) return ASL_STATUS_INVALID_STORE;
- if ((off + sizeof(uint32_t)) > s->file_size) return ASL_STATUS_READ_FAILED;
-
- status = fseeko(s->store, off, SEEK_SET);
- if (status != 0) return ASL_STATUS_READ_FAILED;
-
- val = 0;
-
- status = fread(&val, sizeof(uint32_t), 1, s->store);
- if (status != 1) return ASL_STATUS_READ_FAILED;
-
- if (out != NULL) *out = ntohl(val);
- return ASL_STATUS_OK;
-}
-
-static uint32_t
-asl_file_read_uint64(asl_file_t *s, off_t off, uint64_t *out)
-{
- uint32_t status;
- uint64_t val;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (s->store == NULL) return ASL_STATUS_INVALID_STORE;
- if ((off + sizeof(uint64_t)) > s->file_size) return ASL_STATUS_READ_FAILED;
-
- status = fseeko(s->store, off, SEEK_SET);
- if (status != 0) return ASL_STATUS_READ_FAILED;
-
- val = 0;
-
- status = fread(&val, sizeof(uint64_t), 1, s->store);
- if (status != 1) return ASL_STATUS_READ_FAILED;
-
- if (out != NULL) *out = asl_core_ntohq(val);
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_file_close(asl_file_t *s)
-{
- file_string_t *x;
-
- if (s == NULL) return ASL_STATUS_OK;
-
- if (s->version == 1)
- {
- return asl_legacy1_close((asl_legacy1_t *)s->legacy);
- }
-
- while (s->string_list != NULL)
- {
- x = s->string_list->next;
- free(s->string_list);
- s->string_list = x;
- }
-
- if (s->store != NULL) fclose(s->store);
- if (s->scratch != NULL) free(s->scratch);
-
- memset(s, 0, sizeof(asl_file_t));
- free(s);
-
- return ASL_STATUS_OK;
-}
-
-__private_extern__ uint32_t
-asl_file_open_write_fd(int fd, asl_file_t **s)
-{
- time_t now;
- int status;
- char buf[DB_HEADER_LEN];
- asl_file_t *out;
-
- if (fd < 0) return ASL_STATUS_FAILED;
- if (s == NULL) return ASL_STATUS_FAILED;
-
- out = (asl_file_t *)calloc(1, sizeof(asl_file_t));
- if (out == NULL) return ASL_STATUS_NO_MEMORY;
-
- out->store = fdopen(fd, "w+");
- if (out->store == NULL)
- {
- free(out);
- return ASL_STATUS_FAILED;
- }
-
- memset(buf, 0, sizeof(buf));
- memcpy(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN);
-
- _asl_put_32(DB_VERSION, buf + DB_HEADER_VERS_OFFSET);
-
- now = time(NULL);
- out->dob = now;
- _asl_put_64(out->dob, buf + DB_HEADER_TIME_OFFSET);
-
- _asl_put_32(CACHE_SIZE, buf + DB_HEADER_CSIZE_OFFSET);
-
- status = fwrite(buf, sizeof(buf), 1, out->store);
- if (status != 1)
- {
- fclose(out->store);
- free(out);
- return ASL_STATUS_FAILED;
- }
-
- /* flush data */
- fflush(out->store);
-
- out->file_size = sizeof(buf);
-
- /* scratch buffer for file writes (we test for NULL before using it) */
- out->scratch = malloc(SCRATCH_BUFFER_SIZE);
-
- *s = out;
-
- return ASL_STATUS_OK;
-}
-
-__private_extern__ int
-asl_file_create(const char *path, uid_t uid, gid_t gid, mode_t mode)
-{
-#if TARGET_OS_EMBEDDED
- return open(path, O_RDWR | O_CREAT | O_EXCL, mode);
-#else
- acl_t acl;
- uuid_t uuid;
- acl_entry_t entry;
- acl_permset_t perms;
- int status;
- int fd = -1;
-
- /* -1 means don't set ACL for uid or gid */
- if ((uid == -1) && (gid == -1))
- {
- return open(path, O_RDWR | O_CREAT | O_EXCL, mode);
- }
-
- acl = acl_init(1);
-
- if ((gid != 0) && (gid != -1))
- {
- status = mbr_gid_to_uuid(gid, uuid);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_create_entry_np(&acl, &entry, ACL_FIRST_ENTRY);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_set_tag_type(entry, ACL_EXTENDED_ALLOW);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_set_qualifier(entry, &uuid);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_get_permset(entry, &perms);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_add_perm(perms, ACL_READ_DATA);
- if (status != 0) goto asl_file_create_return;
- }
-
- if ((uid != 0) && (uid != -1))
- {
- status = mbr_uid_to_uuid(uid, uuid);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_create_entry_np(&acl, &entry, ACL_FIRST_ENTRY);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_set_tag_type(entry, ACL_EXTENDED_ALLOW);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_set_qualifier(entry, &uuid);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_get_permset(entry, &perms);
- if (status != 0) goto asl_file_create_return;
-
- status = acl_add_perm(perms, ACL_READ_DATA);
- if (status != 0) goto asl_file_create_return;
- }
-
- fd = open(path, O_RDWR | O_CREAT | O_EXCL, mode);
- if (fd < 0) goto asl_file_create_return;
-
- status = acl_set_fd(fd, acl);
- if (status != 0)
- {
- close(fd);
- fd = -1;
- unlink(path);
- }
-
-asl_file_create_return:
-
- acl_free(acl);
- return fd;
-#endif
-}
-
-uint32_t
-asl_file_open_write(const char *path, mode_t mode, uid_t uid, gid_t gid, asl_file_t **s)
-{
- int i, status, fd;
- struct stat sb;
- char buf[DB_HEADER_LEN];
- asl_file_t *out;
- uint32_t aslstatus, vers, last_len;
- off_t off;
-
- memset(&sb, 0, sizeof(struct stat));
-
- status = stat(path, &sb);
- if (status == 0)
- {
- /* must be a plain file */
- if (!S_ISREG(sb.st_mode)) return ASL_STATUS_INVALID_STORE;
-
- if (sb.st_size == 0)
- {
- fd = open(path, O_RDWR | O_EXCL, mode);
- if (fd < 0) return ASL_STATUS_FAILED;
-
- return asl_file_open_write_fd(fd, s);
- }
- else
- {
- /* XXX Check that mode, uid, and gid are correct */
- out = (asl_file_t *)calloc(1, sizeof(asl_file_t));
- if (out == NULL) return ASL_STATUS_NO_MEMORY;
-
- out->store = fopen(path, "r+");
- if (out->store == NULL)
- {
- free(out);
- return ASL_STATUS_FAILED;
- }
-
- i = fread(buf, DB_HEADER_LEN, 1, out->store);
- if (i < 1)
- {
- asl_file_close(out);
- return ASL_STATUS_READ_FAILED;
- }
-
- /* check cookie */
- if (strncmp(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN))
- {
- asl_file_close(out);
- return ASL_STATUS_INVALID_STORE;
- }
-
- /* check version */
- vers = _asl_get_32(buf + DB_HEADER_VERS_OFFSET);
- if (vers != DB_VERSION)
- {
- asl_file_close(out);
- return ASL_STATUS_INVALID_STORE;
- }
-
- out->dob = _asl_get_64(buf + DB_HEADER_TIME_OFFSET);
- out->first = _asl_get_64(buf + DB_HEADER_FIRST_OFFSET);
- out->last = _asl_get_64(buf + DB_HEADER_LAST_OFFSET);
- out->file_size = (size_t)sb.st_size;
-
- /*
- * Detect bogus last pointer and check for odd-sized files.
- * Setting out->last to zero forces asl_file_read_set_position to
- * follow the linked list of records in the file to the last record.
- * It's slower, but it's better at preventing crashes in corrupt files.
- */
-
- /* records are at least MSG_RECORD_FIXED_LENGTH bytes */
- if ((out->last + MSG_RECORD_FIXED_LENGTH) > out->file_size)
- {
- out->last = 0;
- }
- else
- {
- /* read last record length and make sure the file is at least that large */
- off = out->last + RECORD_TYPE_LEN;
- status = asl_file_read_uint32(out, off, &last_len);
- if (status != ASL_STATUS_OK)
- {
- asl_file_close(out);
- return status;
- }
-
- if ((out->last + last_len) > out->file_size) out->last = 0;
- }
-
- aslstatus = asl_file_read_set_position(out, ASL_FILE_POSITION_LAST);
- if (aslstatus != ASL_STATUS_OK)
- {
- asl_file_close(out);
- return aslstatus;
- }
-
- out->prev = out->cursor;
- status = fseeko(out->store, 0, SEEK_END);
- if (status != 0)
- {
- asl_file_close(out);
- return ASL_STATUS_READ_FAILED;
- }
-
- out->file_size = (size_t)ftello(out->store);
-
- /* scratch buffer for file writes (we test for NULL before using it) */
- out->scratch = malloc(SCRATCH_BUFFER_SIZE);
-
- *s = out;
-
- return ASL_STATUS_OK;
- }
- }
- else if (errno != ENOENT)
- {
- /* unexpected status */
- return ASL_STATUS_FAILED;
- }
-
- /* the file does not exist */
- fd = asl_file_create(path, uid, gid, mode);
- if (fd < 0) return ASL_STATUS_FAILED;
-
- aslstatus = asl_file_open_write_fd(fd, s);
- if (aslstatus != ASL_STATUS_OK) unlink(path);
-
- return aslstatus;
-}
-
-uint32_t
-asl_file_compact(asl_file_t *s, const char *path, mode_t mode, uid_t uid, gid_t gid)
-{
- asl_file_t *new;
- struct stat sb;
- aslmsg m;
- uint64_t xid;
- uint32_t status;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (path == NULL) return ASL_STATUS_INVALID_ARG;
-
- if (s->version == 1) return ASL_STATUS_FAILED;
-
- memset(&sb, 0, sizeof(struct stat));
-
- if (stat(path, &sb) == 0) return ASL_STATUS_FAILED;
- if (errno != ENOENT) return ASL_STATUS_FAILED;
-
- status = asl_file_read_set_position(s, ASL_FILE_POSITION_FIRST);
- if (status != ASL_STATUS_OK) return status;
-
- new = NULL;
- status = asl_file_open_write(path, mode, uid, gid, &new);
- if (status != ASL_STATUS_OK) return status;
- new->flags = ASL_FILE_FLAG_UNLIMITED_CACHE | ASL_FILE_FLAG_PRESERVE_MSG_ID;
-
- while ((status == ASL_STATUS_OK) && (s->cursor != 0))
- {
- m = NULL;
- status = asl_file_fetch_next(s, &m);
- if (status != ASL_STATUS_OK) break;
-
- xid = 0;
- status = asl_file_save(new, m, &xid);
- asl_free(m);
- }
-
- asl_file_close(new);
- return status;
-}
-
-static uint32_t
-asl_file_string_encode(asl_file_t *s, const char *str, uint64_t *out)
-{
- uint32_t i, hash, len, x32;
- file_string_t *sp, *sx, *sl;
- uint64_t x64;
- uint8_t inls;
- uint16_t type;
- off_t off;
- char *p;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (str == NULL) return ASL_STATUS_INVALID_ARG;
-
- len = strlen(str);
-
- /* inline strings */
- if (len < 8)
- {
- /* inline string */
- inls = len;
- inls |= 0x80;
-
- x64 = 0;
- p = (char *)&x64;
- memcpy(p, &inls, 1);
- memcpy(p + 1, str, len);
- *out = asl_core_ntohq(x64);
- return ASL_STATUS_OK;
- }
-
- /* check the cache */
- hash = asl_core_string_hash(str, len);
-
- sp = NULL;
- for (sx = s->string_list; sx != NULL; sx = sx->next)
- {
- if ((hash == sx->hash) && (!strcmp(str, sx->str)))
- {
- /* Move this string to the head of the list */
- if (sp != NULL)
- {
- sl = s->string_list;
- sp->next = sx->next;
- sx->next = sl;
- s->string_list = sx;
- }
-
- *out = sx->where;
- return ASL_STATUS_OK;
- }
-
- sp = sx;
- }
-
- off = ftello(s->store);
-
- /* Type */
- type = htons(ASL_FILE_TYPE_STR);
- i = fwrite(&type, sizeof(uint16_t), 1, s->store);
- if (i != 1) return ASL_STATUS_WRITE_FAILED;
-
- /* Length (includes trailing nul) */
- x32 = htonl(len + 1);
- i = fwrite(&x32, sizeof(uint32_t), 1, s->store);
- if (i != 1) return ASL_STATUS_WRITE_FAILED;
-
- /* String data (nul terminated) */
- i = fwrite(str, len + 1, 1, s->store);
- if (i != 1) return ASL_STATUS_WRITE_FAILED;
-
- /* flush data */
- fflush(s->store);
-
- /* create file_string_t and insert into the cache */
- sx = (file_string_t *)calloc(1, offsetof(file_string_t, str) + len + 1);
- if (sx == NULL) return ASL_STATUS_NO_MEMORY;
-
- sx->where = off;
- sx->hash = hash;
- sx->next = s->string_list;
- memcpy(sx->str, str, len);
-
- s->string_list = sx;
-
- if (((s->flags & ASL_FILE_FLAG_UNLIMITED_CACHE) == 0) && (s->string_count == CACHE_SIZE))
- {
- /* drop last (lru) string from cache */
- sp = s->string_list;
- sx = sp->next;
-
- /* NB CACHE_SIZE must be > 1 */
- while (sx->next != NULL)
- {
- sp = sx;
- sx = sx->next;
- }
-
- sp->next = NULL;
- free(sx);
- }
- else
- {
- s->string_count++;
- }
-
- *out = off;
- return ASL_STATUS_OK;
-}
-
-/*
- * Encode an aslmsg as a record structure.
- * Creates and caches strings.
- */
-uint32_t
-asl_file_save(asl_file_t *s, aslmsg in, uint64_t *mid)
-{
- char *buf, *p;
- uint32_t i, len, x, status;
- file_record_t r;
- uint64_t k, v;
- uint64_t *kvlist;
- off_t off;
- asl_msg_t *msg;
- const char *key, *val;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (in == NULL) return ASL_STATUS_INVALID_MESSAGE;
-
- if (s->flags & ASL_FILE_FLAG_READ_ONLY) return ASL_STATUS_READ_ONLY;
-
- msg = (asl_msg_t *)in;
-
- memset(&r, 0, sizeof(file_record_t));
-
- r.flags = 0;
- r.level = ASL_LEVEL_DEBUG;
- r.pid = -1;
- r.uid = -2;
- r.gid = -2;
- r.ruid = -1;
- r.rgid = -1;
- r.time = 0;
- r.nano = 0;
- r.prev = s->prev;
- kvlist = NULL;
-
- key = NULL;
- val = NULL;
-
- for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL))
- {
- if (key == NULL)
- {
- continue;
- }
- else if (!strcmp(key, ASL_KEY_TIME))
- {
- if (val != NULL) r.time = asl_parse_time(val);
- }
- else if (!strcmp(key, ASL_KEY_TIME_NSEC))
- {
- if (val != NULL) r.nano = atoi(val);
- }
- else if (!strcmp(key, ASL_KEY_HOST))
- {
- if (val != NULL)
- {
- status = asl_file_string_encode(s, val, &(r.host));
- if (status != ASL_STATUS_OK)
- {
- if (kvlist != NULL) free(kvlist);
- return status;
- }
- }
- }
- else if (!strcmp(key, ASL_KEY_SENDER))
- {
- if (val != NULL)
- {
- status = asl_file_string_encode(s, val, &(r.sender));
- if (status != ASL_STATUS_OK)
- {
- if (kvlist != NULL) free(kvlist);
- return status;
- }
- }
- }
- else if (!strcmp(key, ASL_KEY_PID))
- {
- if (val != NULL) r.pid = atoi(val);
- }
- else if (!strcmp(key, ASL_KEY_REF_PID))
- {
- if (val != NULL) r.refpid = atoi(val);
- }
- else if (!strcmp(key, ASL_KEY_UID))
- {
- if (val != NULL) r.uid = atoi(val);
- }
- else if (!strcmp(key, ASL_KEY_GID))
- {
- if (val != NULL) r.gid = atoi(val);
- }
- else if (!strcmp(key, ASL_KEY_LEVEL))
- {
- if (val != NULL) r.level = atoi(val);
- }
- else if (!strcmp(key, ASL_KEY_MSG))
- {
- if (val != NULL)
- {
- status = asl_file_string_encode(s, val, &(r.message));
- if (status != ASL_STATUS_OK)
- {
- if (kvlist != NULL) free(kvlist);
- return status;
- }
- }
- }
- else if (!strcmp(key, ASL_KEY_FACILITY))
- {
- if (val != NULL)
- {
- status = asl_file_string_encode(s, val, &(r.facility));
- if (status != ASL_STATUS_OK)
- {
- if (kvlist != NULL) free(kvlist);
- return status;
- }
- }
- }
- else if (!strcmp(key, ASL_KEY_REF_PROC))
- {
- if (val != NULL)
- {
- status = asl_file_string_encode(s, val, &(r.refproc));
- if (status != ASL_STATUS_OK)
- {
- if (kvlist != NULL) free(kvlist);
- return status;
- }
- }
- }
- else if (!strcmp(key, ASL_KEY_SESSION))
- {
- if (val != NULL)
- {
- status = asl_file_string_encode(s, val, &(r.session));
- if (status != ASL_STATUS_OK)
- {
- if (kvlist != NULL) free(kvlist);
- return status;
- }
- }
- }
- else if (!strcmp(key, ASL_KEY_READ_UID))
- {
- if (((r.flags & ASL_MSG_FLAG_READ_UID_SET) == 0) && (val != NULL))
- {
- r.ruid = atoi(val);
- r.flags |= ASL_MSG_FLAG_READ_UID_SET;
- }
- }
- else if (!strcmp(key, ASL_KEY_READ_GID))
- {
- if (((r.flags & ASL_MSG_FLAG_READ_GID_SET) == 0) && (val != NULL))
- {
- r.rgid = atoi(val);
- r.flags |= ASL_MSG_FLAG_READ_GID_SET;
- }
- }
- else if (!strcmp(key, ASL_KEY_MSG_ID))
- {
- if (s->flags & ASL_FILE_FLAG_PRESERVE_MSG_ID) *mid = atoll(val);
- }
- else if (!strcmp(key, ASL_KEY_OPTION))
- {
- /* ignore - we don't save ASLOption */
- }
- else
- {
- status = asl_file_string_encode(s, key, &k);
- if (status != ASL_STATUS_OK)
- {
- if (kvlist != NULL) free(kvlist);
- return status;
- }
-
- v = 0;
- if (val != NULL)
- {
- status = asl_file_string_encode(s, val, &v);
- if (status != ASL_STATUS_OK)
- {
- if (kvlist != NULL) free(kvlist);
- return status;
- }
- }
-
- if (r.kvcount == 0)
- {
- kvlist = (uint64_t *)calloc(2, sizeof(uint64_t));
- }
- else
- {
- kvlist = (uint64_t *)reallocf(kvlist, (r.kvcount + 2) * sizeof(uint64_t));
- }
-
- if (kvlist == NULL)
- {
- return ASL_STATUS_NO_MEMORY;
- }
-
- kvlist[r.kvcount++] = k;
- kvlist[r.kvcount++] = v;
- }
- }
-
- len = MSG_RECORD_FIXED_LENGTH + (r.kvcount * sizeof(uint64_t));
- buf = NULL;
-
- /* use the scratch buffer if it exists and is large enough */
- if ((s->scratch != NULL) && (len <= SCRATCH_BUFFER_SIZE))
- {
- memset(s->scratch, 0, SCRATCH_BUFFER_SIZE);
- buf = s->scratch;
- }
- else
- {
- buf = calloc(1, len);
- }
-
- if (buf == NULL) return ASL_STATUS_NO_MEMORY;
-
- if (*mid != 0)
- {
- r.mid = *mid;
- }
- else
- {
- r.mid = asl_core_new_msg_id(0);
- *mid = r.mid;
- }
-
- p = buf;
-
- /* Type */
- _asl_put_16(ASL_FILE_TYPE_MSG, p);
- p += sizeof(uint16_t);
-
- /* Length of message (excludes type and length fields) */
- _asl_put_32(len - RECORD_COMMON_LEN, p);
- p += sizeof(uint32_t);
-
- /* Message data... */
-
- _asl_put_64(r.next, p);
- p += sizeof(uint64_t);
-
- _asl_put_64(r.mid, p);
- p += sizeof(uint64_t);
-
- _asl_put_64(r.time, p);
- p += sizeof(uint64_t);
-
- _asl_put_32(r.nano, p);
- p += sizeof(uint32_t);
-
- _asl_put_16(r.level, p);
- p += sizeof(uint16_t);
-
- _asl_put_16(r.flags, p);
- p += sizeof(uint16_t);
-
- _asl_put_32(r.pid, p);
- p += sizeof(uint32_t);
-
- _asl_put_32(r.uid, p);
- p += sizeof(uint32_t);
-
- _asl_put_32(r.gid, p);
- p += sizeof(uint32_t);
-
- _asl_put_32(r.ruid, p);
- p += sizeof(uint32_t);
-
- _asl_put_32(r.rgid, p);
- p += sizeof(uint32_t);
-
- _asl_put_32(r.refpid, p);
- p += sizeof(uint32_t);
-
- _asl_put_32(r.kvcount, p);
- p += sizeof(uint32_t);
-
- _asl_put_64(r.host, p);
- p += sizeof(uint64_t);
-
- _asl_put_64(r.sender, p);
- p += sizeof(uint64_t);
-
- _asl_put_64(r.facility, p);
- p += sizeof(uint64_t);
-
- _asl_put_64(r.message, p);
- p += sizeof(uint64_t);
-
- _asl_put_64(r.refproc, p);
- p += sizeof(uint64_t);
-
- _asl_put_64(r.session, p);
- p += sizeof(uint64_t);
-
- for (i = 0; i < r.kvcount; i++)
- {
- _asl_put_64(kvlist[i], p);
- p += sizeof(uint64_t);
- }
-
- _asl_put_64(r.prev, p);
- p += sizeof(uint64_t);
-
- free(kvlist);
- kvlist = NULL;
-
- /* write record at end of file */
- status = fseeko(s->store, 0, SEEK_END);
- if (status != 0) return ASL_STATUS_WRITE_FAILED;
-
- s->last = (uint64_t)ftello(s->store);
-
- v = asl_core_htonq(s->last);
-
- status = fwrite(buf, len, 1, s->store);
- fflush(s->store);
-
- /* free the buffer if it was allocated here */
- if (buf != s->scratch) free(buf);
-
- /* seek to "next" field of previous record, write last offset */
- off = s->prev + RECORD_COMMON_LEN;
- if (s->prev == 0) off = DB_HEADER_FIRST_OFFSET;
-
- status = fseeko(s->store, off, SEEK_SET);
- if (status != 0) return ASL_STATUS_WRITE_FAILED;
-
- status = fwrite(&v, sizeof(uint64_t), 1, s->store);
- if (status != 1) return ASL_STATUS_WRITE_FAILED;
-
- /* seek to DB_HEADER_LAST_OFFSET, write last record offset */
- off = DB_HEADER_LAST_OFFSET;
-
- status = fseeko(s->store, off, SEEK_SET);
- if (status != 0) return ASL_STATUS_WRITE_FAILED;
-
- status = fwrite(&v, sizeof(uint64_t), 1, s->store);
- if (status != 1) return ASL_STATUS_WRITE_FAILED;
-
- /* return to the end of the store (this is expected by other routines) */
- status = fseeko(s->store, 0, SEEK_END);
- if (status != 0) return ASL_STATUS_WRITE_FAILED;
-
- /* flush data */
- fflush(s->store);
-
- s->file_size = (size_t)ftello(s->store);
-
- s->prev = s->last;
-
- return ASL_STATUS_OK;
-}
-
-static uint32_t
-asl_file_fetch_object(asl_file_t *s, uint64_t where, char **out, uint32_t *outlen)
-{
- static char ils[9];
- char *p;
- uint32_t len;
- int status;
- uint64_t x64;
- uint8_t inls;
- uint16_t type;
- off_t off;
-
- *out = NULL;
- *outlen = 0;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (out == NULL) return ASL_STATUS_INVALID_ARG;
- if (where == 0) return ASL_STATUS_INVALID_ARG;
-
- inls = 0;
- x64 = asl_core_htonq(where);
- memcpy(&inls, &x64, 1);
- if (inls & 0x80)
- {
- /* inline string */
- inls &= 0x0f;
- if (inls > 7) return ASL_STATUS_INVALID_STORE;
-
- p = 1 + (char *)&x64;
- memset(ils, 0, sizeof(ils));
- memcpy(ils, p, inls);
- *out = strdup(ils);
- if (*out == NULL) return ASL_STATUS_NO_MEMORY;
-
- *outlen = inls;
- return ASL_STATUS_OK;
- }
-
- off = where;
- if ((off + sizeof(uint16_t) + sizeof(uint32_t)) > s->file_size) return ASL_STATUS_READ_FAILED;
-
- status = fseeko(s->store, off, SEEK_SET);
- if (status != 0) return ASL_STATUS_READ_FAILED;
-
- /* Type */
- status = fread(&type, sizeof(uint16_t), 1, s->store);
- if (status != 1) return ASL_STATUS_READ_FAILED;
- off += sizeof(uint16_t);
-
- /* Length */
- len = 0;
- status = fread(&len, sizeof(uint32_t), 1, s->store);
- if (status != 1) return ASL_STATUS_READ_FAILED;
- off += sizeof(uint32_t);
-
- len = ntohl(len);
- if ((off + len) > s->file_size) return ASL_STATUS_READ_FAILED;
-
- *out = calloc(1, len);
- if (*out == NULL) return ASL_STATUS_NO_MEMORY;
-
- status = fread(*out, len, 1, s->store);
- if (status != 1)
- {
- free(*out);
- return ASL_STATUS_READ_FAILED;
- }
-
- *outlen = len;
- return ASL_STATUS_OK;
-}
-
-static uint16_t
-asl_file_fetch_helper_16(asl_file_t *s, char **p, aslmsg m, const char *key)
-{
- uint16_t out;
- char str[256];
-
- out = _asl_get_16(*p);
- *p += sizeof(uint16_t);
-
- if ((m == NULL) || (key == NULL)) return out;
-
- snprintf(str, sizeof(str), "%hu", out);
- asl_set(m, key, str);
-
- return out;
-}
-
-static uint32_t
-asl_file_fetch_helper_32(asl_file_t *s, char **p, aslmsg m, const char *key, int ignore, uint32_t ignoreval)
-{
- uint32_t out, doit;
- char str[256];
-
- out = _asl_get_32(*p);
- *p += sizeof(uint32_t);
-
- if ((m == NULL) || (key == NULL)) return out;
-
- doit = 1;
- if ((ignore != 0) && (out == ignoreval)) doit = 0;
- if (doit != 0)
- {
- snprintf(str, sizeof(str), "%u", out);
- asl_set(m, key, str);
- }
-
- return out;
-}
-
-static uint64_t
-asl_file_fetch_helper_64(asl_file_t *s, char **p, aslmsg m, const char *key)
-{
- uint64_t out;
- char str[256];
-
- out = _asl_get_64(*p);
- *p += sizeof(uint64_t);
-
- if ((m == NULL) || (key == NULL)) return out;
-
- snprintf(str, sizeof(str), "%llu", out);
- asl_set(m, key, str);
-
- return out;
-}
-
-static uint64_t
-asl_file_fetch_helper_str(asl_file_t *s, char **p, aslmsg m, const char *key, uint32_t *err)
-{
- uint64_t out;
- char *val;
- uint32_t status, len;
-
- out = _asl_get_64(*p);
- *p += sizeof(uint64_t);
-
- val = NULL;
- len = 0;
- status = ASL_STATUS_OK;
- if (out != 0) status = asl_file_fetch_object(s, out, &val, &len);
-
- if (err != NULL) *err = status;
- if ((status == ASL_STATUS_OK) && (val != NULL))
- {
- asl_set(m, key, val);
- free(val);
- }
-
- return out;
-}
-
-static uint32_t
-asl_file_fetch_pos(asl_file_t *s, uint64_t where, int dir, aslmsg *msg)
-{
- char *buf, *p, *k, *v;
- file_record_t r;
- uint32_t i, status, len, buflen, kvn;
- uint64_t x64, kv;
- aslmsg out;
- off_t off;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (msg == NULL) return ASL_STATUS_INVALID_ARG;
- if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY;
-
- buf = NULL;
- buflen = 0;
- status = asl_file_fetch_object(s, where, &buf, &buflen);
- if ((status != ASL_STATUS_OK) || (buf == NULL))
- {
- s->cursor = 0;
- s->cursor_xid = 0;
- return status;
- }
-
- /* check buffer size */
- kvn = _asl_get_32(buf + BUFFER_OFFSET_KVCOUNT);
- if (buflen < (MSG_RECORD_FIXED_LENGTH - RECORD_COMMON_LEN + (kvn * sizeof(uint64_t))))
- {
- free(buf);
- s->cursor = 0;
- s->cursor_xid = 0;
- return ASL_STATUS_READ_FAILED;
- }
-
- out = asl_new(ASL_TYPE_MSG);
- if (out == NULL) return ASL_STATUS_NO_MEMORY;
-
- memset(&r, 0, sizeof(file_record_t));
- p = buf;
-
- r.next = asl_file_fetch_helper_64(s, &p, NULL, NULL);
- r.mid = asl_file_fetch_helper_64(s, &p, out, ASL_KEY_MSG_ID);
- r.time = asl_file_fetch_helper_64(s, &p, out, ASL_KEY_TIME);
- r.nano = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_TIME_NSEC, 0, 0);
- r.level = asl_file_fetch_helper_16(s, &p, out, ASL_KEY_LEVEL);
- r.flags = asl_file_fetch_helper_16(s, &p, NULL, NULL);
- r.pid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_PID, 0, 0);
- r.uid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_UID, 1, (uint32_t)-1);
- r.gid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_GID, 1, (uint32_t)-1);
- r.ruid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_READ_UID, 1, (uint32_t)-1);
- r.rgid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_READ_GID, 1, (uint32_t)-1);
- r.refpid = asl_file_fetch_helper_32(s, &p, out, ASL_KEY_REF_PID, 1, 0);
- r.kvcount = asl_file_fetch_helper_32(s, &p, NULL, NULL, 0, 0);
-
- status = ASL_STATUS_OK;
- r.host = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_HOST, &status); /* 68 */
- if (status == ASL_STATUS_OK) r.sender = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_SENDER, &status); /* 76 */
- if (status == ASL_STATUS_OK) r.facility = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_FACILITY, &status); /* 84 */
- if (status == ASL_STATUS_OK) r.message = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_MSG, &status); /* 92 */
- if (status == ASL_STATUS_OK) r.refproc = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_REF_PROC, &status); /* 100 */
- if (status == ASL_STATUS_OK) r.session = asl_file_fetch_helper_str(s, &p, out, ASL_KEY_SESSION, &status); /* 108 */
-
- if (status != ASL_STATUS_OK)
- {
- asl_free(out);
- free(buf);
- s->cursor = 0;
- s->cursor_xid = 0;
- return status;
- }
-
- kvn = r.kvcount / 2;
-
- for (i = 0; i < kvn; i++)
- {
- kv = _asl_get_64(p);
- p += sizeof(uint64_t);
- k = NULL;
- len = 0;
- status = asl_file_fetch_object(s, kv, &k, &len);
- if (status != ASL_STATUS_OK)
- {
- asl_free(out);
- free(buf);
- s->cursor = 0;
- s->cursor_xid = 0;
- return status;
- }
-
- kv = _asl_get_64(p);
- p += sizeof(uint64_t);
- v = NULL;
- len = 0;
-
- if (kv != 0)
- {
- status = asl_file_fetch_object(s, kv, &v, &len);
- if (status != ASL_STATUS_OK)
- {
- asl_free(out);
- free(buf);
- s->cursor = 0;
- s->cursor_xid = 0;
- return status;
- }
- }
-
- if ((status == ASL_STATUS_OK) && (k != NULL))
- {
- asl_set(out, k, v);
- if (v != NULL) free(v);
- free(k);
- }
- }
-
- r.prev = asl_file_fetch_helper_64(s, &p, NULL, NULL); /* 116 */
-
- free(buf);
-
- if (dir >= 0) s->cursor = r.next;
- else s->cursor = r.prev;
-
- s->cursor_xid = 0;
-
- if (s->cursor != 0)
- {
- off = s->cursor + RECORD_COMMON_LEN + sizeof(uint64_t);
- if (off > s->file_size)
- {
- asl_free(out);
- s->cursor = 0;
- s->cursor_xid = 0;
- /*
- * Next record offset is past the end of the file.
- * This is an error, but we allow it to fail quietly
- * so that the current record fetch succeeds.
- */
- return ASL_STATUS_OK;
- }
-
- status = fseeko(s->store, off, SEEK_SET);
- if (status != 0)
- {
- asl_free(out);
- s->cursor = 0;
- s->cursor_xid = 0;
- return ASL_STATUS_READ_FAILED;
- }
-
- status = fread(&x64, sizeof(uint64_t), 1, s->store);
- if (status != 1)
- {
- asl_free(out);
- s->cursor = 0;
- s->cursor_xid = 0;
- return ASL_STATUS_READ_FAILED;
- }
-
- s->cursor_xid = asl_core_ntohq(x64);
- }
-
- *msg = out;
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_file_open_read(const char *path, asl_file_t **s)
-{
- asl_file_t *out;
- FILE *f;
- int i;
- uint32_t status, vers, last_len;
- char buf[DB_HEADER_LEN];
- off_t off;
- asl_legacy1_t *legacy;
- struct stat sb;
-
- memset(&sb, 0, sizeof(struct stat));
- if (stat(path, &sb) != 0) return ASL_STATUS_FAILED;
-
- f = fopen(path, "r");
- if (f == NULL)
- {
- if (errno == EACCES) return ASL_STATUS_ACCESS_DENIED;
- return ASL_STATUS_FAILED;
- }
-
- i = fread(buf, DB_HEADER_LEN, 1, f);
- if (i < 1)
- {
- fclose(f);
- return ASL_STATUS_INVALID_STORE;
- }
-
- /* validate header */
- if (strncmp(buf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN))
- {
- fclose(f);
- return ASL_STATUS_INVALID_STORE;
- }
-
- legacy = NULL;
-
- vers = _asl_get_32(buf + DB_HEADER_VERS_OFFSET);
- if (vers == DB_VERSION_LEGACY_1)
- {
- fclose(f);
- status = asl_legacy1_open(path, &legacy);
- if (status != ASL_STATUS_OK) return status;
- }
-
- out = (asl_file_t *)calloc(1, sizeof(asl_file_t));
- if (out == NULL)
- {
- fclose(f);
- return ASL_STATUS_NO_MEMORY;
- }
-
- out->store = f;
- out->flags = ASL_FILE_FLAG_READ_ONLY;
- out->version = vers;
-
- if (legacy != NULL)
- {
- out->flags |= ASL_FILE_FLAG_LEGACY_STORE;
- out->legacy = (void *)legacy;
-
- *s = out;
- return ASL_STATUS_OK;
- }
-
- out->first = _asl_get_64(buf + DB_HEADER_FIRST_OFFSET);
- out->last = _asl_get_64(buf + DB_HEADER_LAST_OFFSET);
- out->file_size = (size_t)sb.st_size;
-
- /*
- * Detect bogus last pointer and check for odd-sized files.
- * Setting out->last to zero forces us to follow the linked
- * list of records in the file to the last record. That's
- * done in the set_position code. It's a bit slower, but it's
- * better at preventing crashes in corrupt files.
- */
-
- /* records are at least MSG_RECORD_FIXED_LENGTH bytes */
- if ((out->last + MSG_RECORD_FIXED_LENGTH) > out->file_size)
- {
- out->last = 0;
- }
- else
- {
- /* read last record length and make sure the file is at least that large */
- off = out->last + RECORD_TYPE_LEN;
- status = asl_file_read_uint32(out, off, &last_len);
- if (status != ASL_STATUS_OK)
- {
- fclose(out->store);
- free(out);
- return status;
- }
-
- if ((out->last + last_len) > out->file_size) out->last = 0;
- }
-
- out->cursor = out->first;
- if (out->cursor != 0)
- {
- off = out->cursor + RECORD_COMMON_LEN + sizeof(uint64_t);
- status = asl_file_read_uint64(out, off, &(out->cursor_xid));
- if (status != ASL_STATUS_OK)
- {
- fclose(out->store);
- free(out);
- return status;
- }
- }
-
- *s = out;
- return ASL_STATUS_OK;
-}
-
-static uint32_t
-asl_file_read_set_position_first(asl_file_t *s)
-{
- uint32_t status;
- off_t off;
-
- s->cursor = s->first;
- s->cursor_xid = 0;
-
- if (s->cursor == 0) return ASL_STATUS_OK;
-
- /* read ID of the first record */
- off = s->cursor + RECORD_COMMON_LEN + sizeof(uint64_t);
- status = asl_file_read_uint64(s, off, &(s->cursor_xid));
- return status;
-}
-
-static uint32_t
-asl_file_read_set_position_last(asl_file_t *s)
-{
- uint64_t next;
- uint32_t status;
- off_t off;
-
- /*
- * If the file has the offset of the last record, we just go there.
- * The last record offset was added to improve performance, so it may
- * or may not be there. If we don't have the last record offset, we
- * just iterate down the record links to find the last one.
- *
- * Note that s->last may be zero if the file is empty.
- */
-
- if (s->last != 0)
- {
- s->cursor = s->last;
- off = s->last + RECORD_COMMON_LEN + sizeof(uint64_t);
-
- /* read ID of the last record */
- status = asl_file_read_uint64(s, off, &(s->cursor_xid));
- return status;
- }
-
- /* start at the first record and iterate */
- s->cursor = s->first;
- s->cursor_xid = 0;
-
- forever
- {
- off = s->cursor + RECORD_COMMON_LEN;
- next = 0;
-
- /* read next offset */
- status = asl_file_read_uint64(s, off, &next);
- if (status != ASL_STATUS_OK) return status;
-
- /* detect bogus next pointer */
- if (((next + MSG_RECORD_FIXED_LENGTH) > s->file_size) || (next <= s->cursor)) next = 0;
-
- if (next == 0)
- {
- if (s->cursor == 0) return ASL_STATUS_OK;
-
- off = s->cursor + RECORD_COMMON_LEN + sizeof(uint64_t);
- status = asl_file_read_uint64(s, off, &(s->cursor_xid));
- return ASL_STATUS_OK;
- }
-
- s->cursor = next;
- }
-}
-
-uint32_t
-asl_file_read_set_position(asl_file_t *s, uint32_t pos)
-{
- uint64_t next;
- uint32_t len, status;
- off_t off;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (s->version == 1) return ASL_STATUS_FAILED;
-
- if (pos == ASL_FILE_POSITION_FIRST) return asl_file_read_set_position_first(s);
- if (pos == ASL_FILE_POSITION_LAST) return asl_file_read_set_position_last(s);
-
- off = 0;
-
- if (pos == ASL_FILE_POSITION_PREVIOUS)
- {
- if (s->cursor == s->first) return ASL_STATUS_NO_RECORDS;
- if (s->cursor == 0) return ASL_STATUS_NO_RECORDS;
-
- off = s->cursor + RECORD_TYPE_LEN;
- status = asl_file_read_uint32(s, off, &len);
- if (status != ASL_STATUS_OK) return status;
-
- /* set offset to read the "previous" field at the end of the record */
- off = s->cursor + RECORD_COMMON_LEN + len - sizeof(uint64_t);
- }
- else if (pos == ASL_FILE_POSITION_NEXT)
- {
- if (s->cursor == s->last) return ASL_STATUS_NO_RECORDS;
- if (s->cursor == 0) return ASL_STATUS_NO_RECORDS;
-
- /* set offset to read the "next" field in the current record */
- off = s->cursor + RECORD_COMMON_LEN;
- }
- else return ASL_STATUS_INVALID_ARG;
-
- s->cursor_xid = 0;
-
- /*
- * read offset of next / previous
- */
- next = 0;
- status = asl_file_read_uint64(s, off, &next);
- if (status != ASL_STATUS_OK) return ASL_STATUS_READ_FAILED;
-
- /* detect bogus next pointer */
- if ((next + MSG_RECORD_FIXED_LENGTH) > s->file_size) next = 0;
- else if ((pos == ASL_FILE_POSITION_PREVIOUS) && (next >= s->cursor)) next = 0;
- else if ((pos == ASL_FILE_POSITION_NEXT) && (next <= s->cursor)) next = 0;
-
- s->cursor = next;
- if (s->cursor == 0) return ASL_STATUS_NO_RECORDS;
-
- /* read ID of the record */
- off = s->cursor + RECORD_COMMON_LEN + sizeof(uint64_t);
- status = asl_file_read_uint64(s, off, &(s->cursor_xid));
- return status;
-}
-
-uint32_t
-asl_file_fetch_next(asl_file_t *s, aslmsg *msg)
-{
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (s->version == 1) return ASL_STATUS_FAILED;
-
- return asl_file_fetch_pos(s, s->cursor, 1, msg);
-}
-
-uint32_t
-asl_file_fetch_previous(asl_file_t *s, aslmsg *msg)
-{
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (s->version == 1) return ASL_STATUS_FAILED;
-
- return asl_file_fetch_pos(s, s->cursor, -1, msg);
-}
-
-uint32_t
-asl_file_fetch(asl_file_t *s, uint64_t mid, aslmsg *msg)
-{
- uint32_t status;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (msg == NULL) return ASL_STATUS_INVALID_ARG;
- if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY;
-
- if (s->version == 1)
- {
- return asl_legacy1_fetch((asl_legacy1_t *)s->legacy, mid, msg);
- }
-
- if (s->cursor_xid == 0)
- {
- status = asl_file_read_set_position(s, ASL_FILE_POSITION_FIRST);
- if (status != ASL_STATUS_OK) return status;
- if (s->cursor_xid == 0) return ASL_STATUS_INVALID_ID;
- }
-
- while (s->cursor_xid < mid)
- {
- status = asl_file_read_set_position(s, ASL_FILE_POSITION_NEXT);
- if (status != ASL_STATUS_OK) return status;
- if (s->cursor_xid > mid) return ASL_STATUS_INVALID_ID;
- if (s->cursor_xid == 0) return ASL_STATUS_INVALID_ID;
- }
-
- while (s->cursor_xid > mid)
- {
- status = asl_file_read_set_position(s, ASL_FILE_POSITION_PREVIOUS);
- if (status != ASL_STATUS_OK) return status;
- if (s->cursor_xid < mid) return ASL_STATUS_INVALID_ID;
- if (s->cursor_xid == 0) return ASL_STATUS_INVALID_ID;
- }
-
- if (s->cursor_xid != mid) return ASL_STATUS_INVALID_ID;
-
- return asl_file_fetch_pos(s, s->cursor, 1, msg);
-}
-
-__private_extern__ uint64_t
-asl_file_cursor(asl_file_t *s)
-{
- if (s == NULL) return 0;
- if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return 0;
- if (s->version == 1) return 0;
-
- return s->cursor_xid;
-}
-
-__private_extern__ uint32_t
-asl_file_match_start(asl_file_t *s, uint64_t start_id, int32_t direction)
-{
- uint32_t status, d;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (s->version == 1) return ASL_STATUS_INVALID_STORE;
- if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY;
-
- d = ASL_FILE_POSITION_NEXT;
- if (direction < 0) d = ASL_FILE_POSITION_PREVIOUS;
-
- /*
- * find starting point
- */
- status = ASL_STATUS_OK;
- if (direction >= 0) status = asl_file_read_set_position(s, ASL_FILE_POSITION_FIRST);
- else status = asl_file_read_set_position(s, ASL_FILE_POSITION_LAST);
- if (status != ASL_STATUS_OK) return status;
-
- while ((status == ASL_STATUS_OK) && (((direction >= 0) && (s->cursor_xid < start_id)) || ((direction < 0) && (s->cursor_xid > start_id))))
- {
- status = asl_file_read_set_position(s, d);
- }
-
- return status;
-}
-
-__private_extern__ uint32_t
-asl_file_match_next(asl_file_t *s, aslresponse query, aslmsg *msg, uint64_t *last_id, int32_t direction)
-{
- uint32_t status, d, i, do_match, did_match;
- aslmsg m;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (msg == NULL) return ASL_STATUS_INVALID_ARG;
- if (s->version == 1) return ASL_STATUS_INVALID_STORE;
- if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY;
- if (s->cursor == 0) return ASL_STATUS_NO_RECORDS;
-
- *msg = NULL;
- do_match = 1;
-
- d = ASL_FILE_POSITION_NEXT;
- if (direction < 0) d = ASL_FILE_POSITION_PREVIOUS;
-
- if ((query == NULL) || ((query != NULL) && (query->count == 0))) do_match = 0;
-
- m = NULL;
-
- *last_id = s->cursor_xid;
-
- status = asl_file_fetch_pos(s, s->cursor, direction, &m);
- if (status == ASL_STATUS_ACCESS_DENIED) return ASL_STATUS_MATCH_FAILED;
- if ((status == ASL_STATUS_INVALID_ARG) && (s->cursor == 0)) return ASL_STATUS_NO_RECORDS;
- if (status != ASL_STATUS_OK) return status;
-
- did_match = 1;
-
- if (do_match != 0)
- {
- did_match = 0;
-
- for (i = 0; (i < query->count) && (did_match == 0); i++)
- {
- did_match = asl_msg_cmp((aslmsg)(query->msg[i]), m);
- }
- }
-
- if (did_match != 0)
- {
- *msg = m;
- return ASL_STATUS_OK;
- }
-
- asl_free(m);
- return ASL_STATUS_MATCH_FAILED;
-}
-
-uint32_t
-asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction)
-{
- uint32_t status, d, i, do_match, did_match, rescount;
- aslmsg m;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (res == NULL) return ASL_STATUS_INVALID_ARG;
- if ((s->flags & ASL_FILE_FLAG_READ_ONLY) == 0) return ASL_STATUS_WRITE_ONLY;
-
- if (s->version == 1)
- {
- return asl_legacy1_match((asl_legacy1_t *)s->legacy, query, res, last_id, start_id, count, direction);
- }
-
- do_match = 1;
- rescount = 0;
-
- d = ASL_FILE_POSITION_NEXT;
- if (direction < 0) d = ASL_FILE_POSITION_PREVIOUS;
-
- if ((query == NULL) || ((query != NULL) && (query->count == 0))) do_match = 0;
-
- /*
- * find starting point
- */
- status = ASL_STATUS_OK;
- if (direction >= 0) status = asl_file_read_set_position(s, ASL_FILE_POSITION_FIRST);
- else status = asl_file_read_set_position(s, ASL_FILE_POSITION_LAST);
- if (status != ASL_STATUS_OK) return status;
-
- while ((status == ASL_STATUS_OK) && (((direction >= 0) && (s->cursor_xid < start_id)) || ((direction < 0) && (s->cursor_xid > start_id))))
- {
- status = asl_file_read_set_position(s, d);
- }
-
- /*
- * loop through records
- */
- forever
- {
- m = NULL;
- status = asl_file_fetch_pos(s, s->cursor, direction, &m);
- if (status == ASL_STATUS_ACCESS_DENIED) continue;
- if (status != ASL_STATUS_OK) break;
-
- *last_id = s->cursor_xid;
-
- did_match = 1;
-
- if (do_match != 0)
- {
- did_match = 0;
-
- for (i = 0; (i < query->count) && (did_match == 0); i++)
- {
- did_match = asl_msg_cmp((aslmsg)query->msg[i], m);
- }
- }
-
- if (did_match == 1)
- {
- /* append m to res */
- if (*res == NULL)
- {
- *res = (aslresponse)calloc(1, sizeof(aslresponse));
- if (*res == NULL) return ASL_STATUS_NO_MEMORY;
- (*res)->msg = (asl_msg_t **)calloc(1, sizeof(aslmsg));
- if ((*res)->msg == NULL)
- {
- free(*res);
- return ASL_STATUS_NO_MEMORY;
- }
- }
- else
- {
- (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(aslmsg));
- if ((*res)->msg == NULL)
- {
- free(*res);
- return ASL_STATUS_NO_MEMORY;
- }
- }
-
- (*res)->msg[(*res)->count] = (asl_msg_t *)m;
- (*res)->count++;
-
- rescount++;
- if ((count != 0) && (rescount >= count)) break;
- }
- else
- {
- asl_free(m);
- }
- }
-
- /* NOT REACHED */
- return ASL_STATUS_OK;
-}
-
-size_t
-asl_file_size(asl_file_t *s)
-{
- if (s == NULL) return 0;
- return s->file_size;
-}
-
-uint64_t
-asl_file_ctime(asl_file_t *s)
-{
- if (s == NULL) return 0;
- return s->dob;
-}
-
-void
-asl_file_list_close(asl_file_list_t *head)
-{
- asl_file_list_t *next;
-
- while (head != NULL)
- {
- next = head->next;
- asl_file_close(head->file);
- free(head);
- head = next;
- }
-}
-
-static void
-asl_file_list_free(asl_file_list_t *head)
-{
- asl_file_list_t *next;
-
- while (head != NULL)
- {
- next = head->next;
- free(head);
- head = next;
- }
-}
-
-static asl_file_list_t *
-asl_file_list_insert(asl_file_list_t *list, asl_file_t *f, int32_t dir)
-{
- asl_file_list_t *a, *b, *tmp;
-
- if (f == NULL) return list;
-
- tmp = (asl_file_list_t *)calloc(1, sizeof(asl_file_list_t));
- if (tmp == NULL) return NULL;
- tmp->file = f;
-
- if (list == NULL) return tmp;
-
- a = list;
- if (((dir < 0) && (f->cursor_xid > a->file->cursor_xid)) || ((dir >= 0) && (f->cursor_xid < a->file->cursor_xid)))
- {
- tmp->next = list;
- return tmp;
- }
-
- b = a->next;
- while (b != NULL)
- {
- if (((dir < 0) && (f->cursor_xid > b->file->cursor_xid)) || ((dir >= 0) && (f->cursor_xid < b->file->cursor_xid)))
- {
- tmp->next = b;
- a->next = tmp;
- return list;
- }
-
- a = b;
- b = a->next;
- }
-
- a->next = tmp;
- return list;
-}
-
-asl_file_list_t *
-asl_file_list_add(asl_file_list_t *list, asl_file_t *f)
-{
- asl_file_list_t *tmp;
-
- if (f == NULL) return list;
- if (f->version == 1) return list;
-
- tmp = (asl_file_list_t *)calloc(1, sizeof(asl_file_list_t));
- if (tmp == NULL) return NULL;
- tmp->file = f;
-
- tmp->next = list;
- return tmp;
-}
-
-void *
-asl_file_list_match_start(asl_file_list_t *list, uint64_t start_id, int32_t direction)
-{
- uint32_t status;
- asl_file_list_t *n;
- asl_file_match_token_t *out;
-
- if (list == NULL) return NULL;
-
- out = (asl_file_match_token_t *)calloc(1, sizeof(asl_file_match_token_t));
- if (out == NULL) return NULL;
-
- for (n = list; n != NULL; n = n->next)
- {
- /* init file for the search */
- status = asl_file_match_start(n->file, start_id, direction);
- if (status != ASL_STATUS_OK) continue;
- if (n->file->cursor_xid == 0) continue;
-
- out->list = asl_file_list_insert(out->list, n->file, direction);
- }
-
- out->dir = direction;
- return out;
-}
-
-uint32_t
-asl_file_list_match_next(void *token, aslresponse query, aslresponse *res, uint32_t count)
-{
- uint32_t status, rescount;
- asl_file_list_t *n;
- aslmsg m;
- asl_file_match_token_t *work;
- uint64_t last_id;
-
- if (token == NULL) return ASL_STATUS_OK;
- if (res == NULL) return ASL_STATUS_INVALID_ARG;
-
- work = (asl_file_match_token_t *)token;
-
- rescount = 0;
- last_id = 0;
-
- while ((work->list != NULL) && ((rescount < count) || (count == 0)))
- {
- m = NULL;
- status = asl_file_match_next(work->list->file, query, &m, &last_id, work->dir);
- if (m != NULL)
- {
- if (*res == NULL) *res = (aslresponse)calloc(1, sizeof(asl_search_result_t));
- if (*res == NULL)
- {
- asl_file_list_free(work->list);
- work->list = NULL;
- return ASL_STATUS_NO_MEMORY;
- }
-
- if ((*res)->msg == NULL) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(aslmsg));
- else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(aslmsg));
- if ((*res)->msg == NULL)
- {
- free(*res);
- *res = NULL;
- asl_file_list_free(work->list);
- work->list = NULL;
- return ASL_STATUS_NO_MEMORY;
- }
-
- (*res)->msg[(*res)->count] = (asl_msg_t *)m;
- (*res)->count++;
- rescount++;
- }
-
- if ((status != ASL_STATUS_OK) || (work->list->file->cursor_xid == 0))
- {
- n = work->list->next;
- free(work->list);
- work->list = n;
- }
-
- if (work->list != NULL)
- {
- n = work->list->next;
- if (n != NULL)
- {
- if (((work->dir < 0) && (work->list->file->cursor_xid <= n->file->cursor_xid)) || ((work->dir >= 0) && (work->list->file->cursor_xid > n->file->cursor_xid)))
- {
- n = work->list;
- work->list = work->list->next;
- n->next = NULL;
- work->list = asl_file_list_insert(work->list, n->file, work->dir);
- free(n);
- }
- }
- }
- }
-
- return ASL_STATUS_OK;
-}
-
-void
-asl_file_list_match_end(void *token)
-{
- asl_file_match_token_t *work;
-
- if (token == NULL) return;
-
- work = (asl_file_match_token_t *)token;
- asl_file_list_free(work->list);
- work->list = NULL;
-
- free(token);
-}
-
-uint32_t
-asl_file_list_match_timeout(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec)
-{
- uint32_t status, rescount;
- asl_file_list_t *files, *n;
- aslmsg m;
- struct timeval now, finish;
-
- if (list == NULL) return ASL_STATUS_INVALID_ARG;
- if (res == NULL) return ASL_STATUS_INVALID_ARG;
- if (last_id == NULL) return ASL_STATUS_INVALID_ARG;
-
- files = NULL;
-
- for (n = list; n != NULL; n = n->next)
- {
- /* init file for the search */
- status = asl_file_match_start(n->file, start_id, direction);
- if (status != ASL_STATUS_OK) continue;
- if (n->file->cursor_xid == 0) continue;
-
- files = asl_file_list_insert(files, n->file, direction);
- }
-
- if (files == NULL)
- {
- asl_file_list_free(files);
- return ASL_STATUS_OK;
- }
-
- /* start the timer if a timeout was specified */
- memset(&finish, 0, sizeof(struct timeval));
- if (usec != 0)
- {
- if (gettimeofday(&finish, NULL) == 0)
- {
- finish.tv_sec += (usec / MILLION);
- finish.tv_usec += (usec % MILLION);
- if (finish.tv_usec > MILLION)
- {
- finish.tv_usec -= MILLION;
- finish.tv_sec += 1;
- }
- }
- else
- {
- /* shouldn't happen, but if gettimeofday failed we just run without a timeout */
- memset(&finish, 0, sizeof(struct timeval));
- }
- }
-
- rescount = 0;
- while ((files != NULL) && ((rescount < count) || (count == 0)))
- {
- m = NULL;
- status = asl_file_match_next(files->file, query, &m, last_id, direction);
- if (m != NULL)
- {
- if (*res == NULL) *res = (aslresponse)calloc(1, sizeof(asl_search_result_t));
- if (*res == NULL)
- {
- asl_file_list_free(files);
- return ASL_STATUS_NO_MEMORY;
- }
-
- if ((*res)->msg == NULL) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(aslmsg));
- else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, ((*res)->count + 1) * sizeof(aslmsg));
- if ((*res)->msg == NULL)
- {
- free(*res);
- *res = NULL;
- asl_file_list_free(files);
- return ASL_STATUS_NO_MEMORY;
- }
-
- (*res)->msg[(*res)->count] = (asl_msg_t *)m;
- (*res)->count++;
- rescount++;
- }
-
- if (files->file->cursor_xid == 0)
- {
- n = files->next;
- free(files);
- files = n;
- }
-
- if (files != NULL)
- {
- n = files->next;
- if (n != NULL)
- {
- if (((direction < 0) && (files->file->cursor_xid <= n->file->cursor_xid)) || ((direction >= 0) && (files->file->cursor_xid > n->file->cursor_xid)))
- {
- n = files;
- files = files->next;
- n->next = NULL;
- files = asl_file_list_insert(files, n->file, direction);
- free(n);
- }
- }
- }
-
- /* check the timer */
- if ((finish.tv_sec != 0) && (gettimeofday(&now, NULL) == 0))
- {
- if ((now.tv_sec > finish.tv_sec) || ((now.tv_sec == finish.tv_sec) && (now.tv_usec > finish.tv_usec))) break;
- }
- }
-
- asl_file_list_free(files);
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_file_list_match(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction)
-{
- return asl_file_list_match_timeout(list, query, res, last_id, start_id, count, direction, 0);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __ASL_FILE_H__
-#define __ASL_FILE_H__
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <asl.h>
-#include <Availability.h>
-
-#define DB_HEADER_LEN 80
-#define DB_HEADER_COOKIE_OFFSET 0
-#define DB_HEADER_VERS_OFFSET 12
-#define DB_HEADER_FIRST_OFFSET 16
-#define DB_HEADER_TIME_OFFSET 24
-#define DB_HEADER_CSIZE_OFFSET 32
-#define DB_HEADER_LAST_OFFSET 36
-
-/*
- * Magic Cookie for database files.
- * MAXIMUM 12 CHARS! (DB_HEADER_VERS_OFFSET)
- */
-#define ASL_DB_COOKIE "ASL DB"
-#define ASL_DB_COOKIE_LEN 6
-#define DB_VERSION 2
-#define DB_VERSION_LEGACY_1 1
-
-#define ASL_FILE_FLAG_READ_ONLY 0x00000001
-#define ASL_FILE_FLAG_UNLIMITED_CACHE 0x00000002
-#define ASL_FILE_FLAG_PRESERVE_MSG_ID 0x00000004
-#define ASL_FILE_FLAG_LEGACY_STORE 0x00000008
-
-#define ASL_FILE_TYPE_MSG 0
-#define ASL_FILE_TYPE_STR 1
-
-#define ASL_FILE_POSITION_FIRST 0
-#define ASL_FILE_POSITION_PREVIOUS 1
-#define ASL_FILE_POSITION_NEXT 2
-#define ASL_FILE_POSITION_LAST 3
-
-/* NB CACHE_SIZE must be > 1 */
-#define CACHE_SIZE 256
-
-/* Size of the fixed-length part of a MSG record */
-#define MSG_RECORD_FIXED_LENGTH 122
-
-/*
- * The first record (header) in the database has the format:
- *
- * | 12 | 4 | 8 | 8 | 4 | 8 | 36 | (80 bytes)
- * | Cookie | Vers | First | Time | String cache size | Last | Zero |
- *
- * MSG records have the format:
- *
- * | 2 | 4 | 8 | 8 | 8 | 4 | 2 | 2 | 4 | 4 | 4 | 4 | 4 | 4 | 4
- * | 00 | Len | Next | ID | Time | Nano | Level | Flags | PID | UID | GID | RUID | RGID | RefPID | KV count ...
- *
- * | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | | 8
- * | Host | Sender | Facility | Message | RefProc | Session | Key0 | Val0 | ... | Previous |
- *
- * STR records have the format:
- *
- * | 2 | 4 | Len | (Len + 6 bytes)
- * | 01 | Len | Data+NUL |
- *
- */
-
-typedef struct file_string_s
-{
- uint64_t where;
- uint32_t hash;
- struct file_string_s *next;
- char str[];
-} file_string_t;
-
-typedef struct
-{
- uint32_t flags;
- uint32_t version;
- uint32_t string_count;
- file_string_t *string_list;
- uint64_t first;
- uint64_t last;
- uint64_t prev;
- uint64_t cursor;
- uint64_t cursor_xid;
- uint64_t dob;
- size_t file_size;
- FILE *store;
- void *legacy;
- char *scratch;
-} asl_file_t;
-
-typedef struct asl_file_list_s
-{
- asl_file_t *file;
- struct asl_file_list_s *next;
-} asl_file_list_t;
-
-asl_file_list_t *asl_file_list_add(asl_file_list_t *list, asl_file_t *f) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-void asl_file_list_close(asl_file_list_t *list) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-uint32_t asl_file_open_write(const char *path, mode_t mode, uid_t uid, gid_t gid, asl_file_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_file_close(asl_file_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-uint32_t asl_file_save(asl_file_t *s, aslmsg msg, uint64_t *mid) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-uint32_t asl_file_open_read(const char *path, asl_file_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_file_fetch(asl_file_t *s, uint64_t mid, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-uint32_t asl_file_read_set_position(asl_file_t *s, uint32_t pos) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_file_fetch_next(asl_file_t *s, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_file_fetch_previous(asl_file_t *s, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-uint32_t asl_file_match(asl_file_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_file_list_match_timeout(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2);
-uint32_t asl_file_list_match(asl_file_list_t *list, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-void *asl_file_list_match_start(asl_file_list_t *list, uint64_t start_id, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_file_list_match_next(void *token, aslresponse query, aslresponse *res, uint32_t count) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-void asl_file_list_match_end(void *token) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-size_t asl_file_size(asl_file_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint64_t asl_file_ctime(asl_file_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-uint32_t asl_file_compact(asl_file_t *s, const char *path, mode_t mode, uid_t uid, gid_t gid) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-#endif /* __ASL_FILE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-
-subsystem asl_ipc 114;
-serverprefix _;
-
-import <sys/types.h>;
-
-type ooline_data = ^ array [] of MACH_MSG_TYPE_BYTE
- ctype : caddr_t;
-
-routine _asl_server_query
-(
- server : mach_port_t;
- request : ooline_data, dealloc;
- startid : uint64_t;
- count : int;
- flags : int;
- out reply : ooline_data, dealloc;
- out lastid : uint64_t;
- out status : int;
- SecToken token : security_token_t
-);
-
-routine _asl_server_query_timeout
-(
- server : mach_port_t;
- request : ooline_data, dealloc;
- startid : uint64_t;
- count : int;
- flags : int;
- WaitTime timeout: natural_t;
- out reply : ooline_data, dealloc;
- out lastid : uint64_t;
- out status : int;
- SecToken token : security_token_t
-);
-
-routine _asl_server_prune
-(
- server : mach_port_t;
- request : ooline_data, dealloc;
- out status : int;
- SecToken token : security_token_t
-);
-
-routine _asl_server_create_aux_link
-(
- server : mach_port_t;
- message : ooline_data, dealloc;
- out fileport : mach_port_move_send_t;
- out url : ooline_data, dealloc;
- out status : int;
- ServerAuditToken token : audit_token_t
-);
-
-simpleroutine _asl_server_message
-(
- server : mach_port_t;
- message : ooline_data, dealloc;
- ServerAuditToken token : audit_token_t
-);
-
-simpleroutine _asl_server_register_direct_watch
-(
- server : mach_port_t;
- port : int;
- ServerAuditToken token : audit_token_t
-);
-
-simpleroutine _asl_server_cancel_direct_watch
-(
- server : mach_port_t;
- port : int;
- ServerAuditToken token : audit_token_t
-);
+++ /dev/null
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@ */
-
-#include <asl_core.h>
-#include <asl_legacy1.h>
-#include <asl_private.h>
-#include <stdlib.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/errno.h>
-#include <string.h>
-#include <membership.h>
-#include <mach/mach.h>
-#include <sys/syslimits.h>
-#include <sys/types.h>
-#include <time.h>
-#include <sys/mman.h>
-
-#define forever for(;;)
-
-#define FILE_MODE 0600
-
-#define DB_RECORD_LEN 80
-
-#define DB_HEADER_COOKIE_OFFSET 0
-#define DB_HEADER_VERS_OFFSET 12
-
-#define DB_TYPE_EMPTY 0
-#define DB_TYPE_HEADER 1
-#define DB_TYPE_MESSAGE 2
-#define DB_TYPE_KVLIST 3
-#define DB_TYPE_STRING 4
-#define DB_TYPE_STRCONT 5
-
-/*
- * Magic Cookie for database files.
- * MAXIMUM 12 CHARS! (DB_HEADER_VERS_OFFSET)
- */
-#define ASL_DB_COOKIE "ASL DB"
-#define ASL_DB_COOKIE_LEN 6
-
-#define ASL_INDEX_NULL 0xffffffff
-
-#define DB_HLEN_EMPTY 0
-#define DB_HLEN_HEADER 13
-#define DB_HLEN_MESSAGE 13
-#define DB_HLEN_KVLIST 9
-#define DB_HLEN_STRING 25
-#define DB_HLEN_STRCONT 5
-
-#define MSG_OFF_KEY_TYPE 0
-#define MSG_OFF_KEY_NEXT 1
-#define MSG_OFF_KEY_ID 5
-#define MSG_OFF_KEY_RUID 13
-#define MSG_OFF_KEY_RGID 17
-#define MSG_OFF_KEY_TIME 21
-#define MSG_OFF_KEY_HOST 29
-#define MSG_OFF_KEY_SENDER 37
-#define MSG_OFF_KEY_FACILITY 45
-#define MSG_OFF_KEY_LEVEL 53
-#define MSG_OFF_KEY_PID 57
-#define MSG_OFF_KEY_UID 61
-#define MSG_OFF_KEY_GID 65
-#define MSG_OFF_KEY_MSG 69
-#define MSG_OFF_KEY_FLAGS 77
-
-extern time_t asl_parse_time(const char *str);
-extern int asl_msg_cmp(aslmsg a, aslmsg b);
-
-#define asl_msg_list_t asl_search_result_t
-
-#define Q_NULL 100001
-#define Q_FAST 100002
-#define Q_SLOW 100003
-#define Q_FAIL 100004
-
-static uint64_t
-_asl_htonq(uint64_t n)
-{
-#ifdef __BIG_ENDIAN__
- return n;
-#else
- u_int32_t t;
- union
- {
- u_int64_t q;
- u_int32_t l[2];
- } x;
-
- x.q = n;
- t = x.l[0];
- x.l[0] = htonl(x.l[1]);
- x.l[1] = htonl(t);
-
- return x.q;
-#endif
-}
-
-static uint64_t
-_asl_ntohq(uint64_t n)
-{
-#ifdef __BIG_ENDIAN__
- return n;
-#else
- u_int32_t t;
- union
- {
- u_int64_t q;
- u_int32_t l[2];
- } x;
-
- x.q = n;
- t = x.l[0];
- x.l[0] = ntohl(x.l[1]);
- x.l[1] = ntohl(t);
-
- return x.q;
-#endif
-}
-
-static uint16_t
-_asl_get_16(char *h)
-{
- uint16_t x;
-
- memcpy(&x, h, 2);
- return ntohs(x);
-}
-
-static uint32_t
-_asl_get_32(char *h)
-{
- uint32_t x;
-
- memcpy(&x, h, 4);
- return ntohl(x);
-}
-
-static uint64_t
-_asl_get_64(char *h)
-{
- uint64_t x;
-
- memcpy(&x, h, 8);
- return _asl_ntohq(x);
-}
-
-#define header_get_next(h) _asl_get_32(h + 1)
-#define header_get_id(h) _asl_get_64(h + 5)
-#define header_get_hash(h) _asl_get_32(h + 17)
-
-/*
- * callback for sorting slotlist
- * primary sort is by xid
- * secondary sort is by slot, which happens when xid is 0
- * this allows us to quickly find xids (using binary search on the xid key)
- * it's also used to find slots quickly from record_chain_free()
- */
-static int
-slot_comp(const void *a, const void *b)
-{
- asl_legacy1_slot_info_t *ai, *bi;
-
- if (a == NULL)
- {
- if (b == NULL) return 0;
- return -1;
- }
-
- if (b == NULL) return 1;
-
- ai = (asl_legacy1_slot_info_t *)a;
- bi = (asl_legacy1_slot_info_t *)b;
-
- if (ai->xid < bi->xid) return -1;
-
- if (ai->xid == bi->xid)
- {
- if (ai->slot < bi->slot) return -1;
- if (ai->slot == bi->slot) return 0;
- return 1;
- }
-
- return 1;
-}
-
-/* find an xid in the slot list */
-static uint32_t
-slotlist_find(asl_legacy1_t *s, uint64_t xid, int32_t direction)
-{
- uint32_t top, bot, mid, range;
-
- if (s == NULL) return ASL_INDEX_NULL;
- if (s->slotlist_count == 0) return ASL_INDEX_NULL;
- if (xid == 0) return ASL_INDEX_NULL;
-
- top = s->slotlist_count - 1;
- bot = 0;
- mid = top / 2;
-
- range = top - bot;
- while (range > 1)
- {
- if (xid == s->slotlist[mid].xid) return mid;
- else if (xid < s->slotlist[mid].xid) top = mid;
- else bot = mid;
-
- range = top - bot;
- mid = bot + (range / 2);
- }
-
- if (xid == s->slotlist[top].xid) return top;
- if (xid == s->slotlist[bot].xid) return bot;
-
- if (direction == 0) return ASL_INDEX_NULL;
- if (direction < 0) return bot;
- return top;
-}
-
-static uint32_t
-slotlist_init(asl_legacy1_t *s, uint32_t count)
-{
- uint32_t i, si, status, hash, addslot;
- uint64_t xid;
- uint8_t t;
- size_t rcount;
- char tmp[DB_RECORD_LEN];
-
- /* Start at first slot after the header */
- status = fseek(s->db, DB_RECORD_LEN, SEEK_SET);
- if (status != 0) return ASL_STATUS_READ_FAILED;
-
- s->slotlist = (asl_legacy1_slot_info_t *)calloc(count, sizeof(asl_legacy1_slot_info_t));
- if (s->slotlist == NULL) return ASL_STATUS_NO_MEMORY;
-
- si = 0;
-
- for (i = 1; i < count; i++)
- {
- rcount = fread(tmp, DB_RECORD_LEN, 1, s->db);
- if (rcount != 1) return ASL_STATUS_READ_FAILED;
-
- t = tmp[0];
- addslot = 0;
- xid = 0;
- hash = 0;
-
- if (t == DB_TYPE_EMPTY) addslot = 1;
-
- if (t == DB_TYPE_STRING)
- {
- addslot = 1;
- xid = header_get_id(tmp);
- hash = header_get_hash(tmp);
- }
-
- if (t == DB_TYPE_MESSAGE)
- {
- addslot = 1;
- xid = header_get_id(tmp);
- }
-
- if (addslot == 1)
- {
- s->slotlist[si].type = t;
- s->slotlist[si].slot = i;
- s->slotlist[si].xid = xid;
- s->slotlist[si].hash = hash;
- si++;
- }
- }
-
- s->slotlist = (asl_legacy1_slot_info_t *)reallocf(s->slotlist, si * sizeof(asl_legacy1_slot_info_t));
- if (s->slotlist == NULL) return ASL_STATUS_NO_MEMORY;
- s->slotlist_count = si;
-
- /* slotlist is sorted by xid */
- qsort((void *)s->slotlist, s->slotlist_count, sizeof(asl_legacy1_slot_info_t), slot_comp);
-
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_legacy1_open(const char *path, asl_legacy1_t **out)
-{
- asl_legacy1_t *s;
- struct stat sb;
- int status;
- size_t rcount;
- char cbuf[DB_RECORD_LEN];
- off_t fsize;
- uint32_t count;
-
- memset(&sb, 0, sizeof(struct stat));
- status = stat(path, &sb);
- if (status < 0) return ASL_STATUS_FAILED;
-
- fsize = sb.st_size;
-
- s = (asl_legacy1_t *)calloc(1, sizeof(asl_legacy1_t));
- if (s == NULL) return ASL_STATUS_NO_MEMORY;
-
- s->db = fopen(path, "r");
- if (s->db == NULL)
- {
- free(s);
- return ASL_STATUS_INVALID_STORE;
- }
-
- memset(cbuf, 0, DB_RECORD_LEN);
- rcount = fread(cbuf, DB_RECORD_LEN, 1, s->db);
- if (rcount != 1)
- {
- fclose(s->db);
- free(s);
- return ASL_STATUS_READ_FAILED;
- }
-
- /* Check the database Magic Cookie */
- if (strncmp(cbuf, ASL_DB_COOKIE, ASL_DB_COOKIE_LEN))
- {
- fclose(s->db);
- free(s);
- return ASL_STATUS_INVALID_STORE;
- }
-
- count = fsize / DB_RECORD_LEN;
-
- status = slotlist_init(s, count);
-
- *out = s;
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_legacy1_close(asl_legacy1_t *s)
-{
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
-
- if (s->slotlist != NULL) free(s->slotlist);
- if (s->db != NULL) fclose(s->db);
- free(s);
-
- return ASL_STATUS_OK;
-}
-
-static uint32_t
-string_fetch_slot(asl_legacy1_t *s, uint32_t slot, char **out)
-{
- off_t offset;
- uint8_t type;
- uint32_t next, x, remaining;
- size_t rcount, len;
- int status;
- char *outstr, *p, tmp[DB_RECORD_LEN];
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (out == NULL) return ASL_STATUS_INVALID_ARG;
-
- *out = NULL;
- offset = slot * DB_RECORD_LEN;
- status = fseek(s->db, offset, SEEK_SET);
-
- if (status < 0) return ASL_STATUS_READ_FAILED;
-
- rcount = fread(tmp, DB_RECORD_LEN, 1, s->db);
- if (rcount != 1) return ASL_STATUS_READ_FAILED;
-
- type = tmp[0];
- if (type != DB_TYPE_STRING) return ASL_STATUS_INVALID_STRING;
-
- len = _asl_get_32(tmp + 21);
- if (len == 0) return ASL_STATUS_OK;
-
- next = header_get_next(tmp);
-
- outstr = calloc(1, len);
- if (outstr == NULL) return ASL_STATUS_NO_MEMORY;
-
- p = outstr;
- remaining = len;
-
- x = DB_RECORD_LEN - DB_HLEN_STRING;
- if (x > remaining) x = remaining;
-
- memcpy(p, tmp + DB_HLEN_STRING, x);
- p += x;
- remaining -= x;
-
- while ((next != 0) && (remaining > 0))
- {
- offset = next * DB_RECORD_LEN;
- status = fseek(s->db, offset, SEEK_SET);
-
- if (status < 0)
- {
- free(outstr);
- return ASL_STATUS_READ_FAILED;
- }
-
- rcount = fread(tmp, DB_RECORD_LEN, 1, s->db);
- if (rcount != 1)
- {
- free(outstr);
- return ASL_STATUS_READ_FAILED;
- }
-
- next = header_get_next(tmp);
-
- x = DB_RECORD_LEN - DB_HLEN_STRCONT;
- if (x > remaining) x = remaining;
-
- memcpy(p, tmp + DB_HLEN_STRCONT, x);
- p += x;
- remaining -= x;
- }
-
- if ((next != 0) || (remaining != 0))
- {
- free(outstr);
- return ASL_STATUS_READ_FAILED;
- }
-
- *out = outstr;
- return ASL_STATUS_OK;
-}
-
-static uint32_t
-string_fetch_sid(asl_legacy1_t *s, uint64_t sid, char **out)
-{
- uint32_t i, len, ref;
- uint64_t nsid;
- uint8_t inls;
- char *p;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (out == NULL) return ASL_STATUS_INVALID_ARG;
-
- *out = NULL;
- if (sid == ASL_REF_NULL) return ASL_STATUS_OK;
-
- ref = 0;
-
- inls = 0;
- nsid = _asl_htonq(sid);
- memcpy(&inls, &nsid, 1);
- if (inls & 0x80)
- {
- /* inline string */
- inls &= 0x0f;
- len = inls;
- *out = calloc(1, len);
- if (*out == NULL) return ASL_STATUS_NO_MEMORY;
- p = 1 + (char *)&nsid;
- memcpy(*out, p, len);
- return ASL_STATUS_OK;
- }
-
- /* Find the string in the database */
- i = slotlist_find(s, sid, 0);
- if (i == ASL_INDEX_NULL) return ASL_STATUS_NOT_FOUND;
-
- return string_fetch_slot(s, s->slotlist[i].slot, out);
-}
-
-static uint32_t
-asl_legacy1_fetch_helper_32(asl_legacy1_t *s, char **p, aslmsg m, const char *key, int ignore, uint32_t ignoreval)
-{
- uint32_t out, doit;
- char str[256];
-
- out = _asl_get_32(*p);
- *p += sizeof(uint32_t);
-
- if ((m == NULL) || (key == NULL)) return out;
-
- doit = 1;
- if ((ignore != 0) && (out == ignoreval)) doit = 0;
- if (doit != 0)
- {
- snprintf(str, sizeof(str), "%u", out);
- asl_set(m, key, str);
- }
-
- return out;
-}
-
-static uint64_t
-asl_legacy1_fetch_helper_64(asl_legacy1_t *s, char **p, aslmsg m, const char *key)
-{
- uint64_t out;
- char str[256];
-
- out = _asl_get_64(*p);
- *p += sizeof(uint64_t);
-
- if ((m == NULL) || (key == NULL)) return out;
-
- snprintf(str, sizeof(str), "%llu", out);
- asl_set(m, key, str);
-
- return out;
-}
-
-static uint64_t
-asl_legacy1_fetch_helper_str(asl_legacy1_t *s, char **p, aslmsg m, const char *key, uint32_t *err)
-{
- uint64_t out;
- char *val;
- uint32_t status;
-
- out = _asl_get_64(*p);
- *p += sizeof(uint64_t);
-
- val = NULL;
- status = ASL_STATUS_OK;
- if (out != 0) status = string_fetch_sid(s, out, &val);
-
- if (err != NULL) *err = status;
- if ((status == ASL_STATUS_OK) && (val != NULL))
- {
- asl_set(m, key, val);
- free(val);
- }
-
- return out;
-}
-
-static uint32_t
-msg_fetch(asl_legacy1_t *s, uint32_t slot, aslmsg *out)
-{
- off_t offset;
- uint32_t status, i, n, kvcount, next;
- uint16_t flags;
- uint64_t sid;
- size_t rcount;
- aslmsg msg;
- int fstatus;
- char *p, tmp[DB_RECORD_LEN], *key, *val;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (out == NULL) return ASL_STATUS_INVALID_ARG;
-
- *out = NULL;
-
- offset = slot * DB_RECORD_LEN;
- fstatus = fseek(s->db, offset, SEEK_SET);
-
- if (fstatus < 0) return ASL_STATUS_READ_FAILED;
-
- rcount = fread(tmp, DB_RECORD_LEN, 1, s->db);
- if (rcount != 1) return ASL_STATUS_READ_FAILED;
-
- flags = _asl_get_16(tmp + MSG_OFF_KEY_FLAGS);
-
- msg = asl_new(ASL_TYPE_MSG);
- if (msg == NULL) return ASL_STATUS_NO_MEMORY;
-
- p = tmp + 5;
-
- asl_legacy1_fetch_helper_64(s, &p, msg, ASL_KEY_MSG_ID);
- asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_READ_UID, 1, (uint32_t)-1);
- asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_READ_GID, 1, (uint32_t)-1);
- asl_legacy1_fetch_helper_64(s, &p, msg, ASL_KEY_TIME);
- asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_HOST, &status);
- asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_SENDER, &status);
- asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_FACILITY, &status);
- asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_LEVEL, 0, 0);
- asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_PID, 0, 0);
- asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_UID, 0, 0);
- asl_legacy1_fetch_helper_32(s, &p, msg, ASL_KEY_GID, 0, 0);
- asl_legacy1_fetch_helper_str(s, &p, msg, ASL_KEY_MSG, &status);
-
- next = header_get_next(tmp);
-
- kvcount = 0;
- n = 0;
-
- while (next != 0)
- {
- offset = next * DB_RECORD_LEN;
- fstatus = fseek(s->db, offset, SEEK_SET);
- if (fstatus < 0)
- {
- free(out);
- return ASL_STATUS_READ_FAILED;
- }
-
- rcount = fread(tmp, DB_RECORD_LEN, 1, s->db);
- if (rcount != 1)
- {
- free(out);
- return ASL_STATUS_READ_FAILED;
- }
-
- if (kvcount == 0) kvcount = _asl_get_32(tmp + 5);
-
- p = tmp + 9;
-
- for (i = 0; (i < 4) && (n < kvcount); i++)
- {
- key = NULL;
- sid = _asl_get_64(p);
- p += 8;
- status = string_fetch_sid(s, sid, &key);
-
- val = NULL;
- sid = _asl_get_64(p);
- p += 8;
- if (status == ASL_STATUS_OK) status = string_fetch_sid(s, sid, &val);
-
- if ((status == ASL_STATUS_OK) && (key != NULL)) asl_set(msg, key, val);
- if (key != NULL) free(key);
- if (val != NULL) free(val);
-
- n++;
- }
-
- next = header_get_next(tmp);
- }
-
- *out = msg;
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_legacy1_fetch(asl_legacy1_t *s, uint64_t msgid, aslmsg *out)
-{
- uint32_t i, status;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (msgid == ASL_REF_NULL) return ASL_STATUS_INVALID_ARG;
- if (out == NULL) return ASL_STATUS_INVALID_ARG;
-
- i = slotlist_find(s, msgid, 0);
- if (i == ASL_INDEX_NULL) return ASL_STATUS_INVALID_ID;
-
- /* read the message */
- status = msg_fetch(s, s->slotlist[i].slot, out);
- if (status != ASL_STATUS_OK) return status;
- if (*out == NULL) return ASL_STATUS_FAILED;
-
- return status;
-}
-
-static uint32_t
-next_search_slot(asl_legacy1_t *s, uint32_t last_si, int32_t direction)
-{
- uint32_t i;
-
- if (direction >= 0)
- {
- for (i = last_si + 1; i < s->slotlist_count; i++)
- {
- if (s->slotlist[i].type == DB_TYPE_MESSAGE) return i;
- }
-
- return ASL_INDEX_NULL;
- }
-
- if (last_si == 0) return ASL_INDEX_NULL;
- if (last_si > s->slotlist_count) return ASL_INDEX_NULL;
-
- for (i = last_si - 1; i > 0; i--)
- {
- if (s->slotlist[i].type == DB_TYPE_MESSAGE) return i;
- }
-
- if (s->slotlist[0].type == DB_TYPE_MESSAGE) return 0;
-
- return ASL_INDEX_NULL;
-}
-
-static void
-match_worker_cleanup(asl_msg_list_t **res)
-{
- uint32_t i;
-
- if (res != NULL)
- {
- for (i = 0; i < (*res)->count; i++) asl_free((aslmsg)(*res)->msg[i]);
- free(*res);
- }
-}
-
-/*
- * Input to asl_legacy1_match is a list of queries.
- * A record in the store matches if it matches any query (i.e. query list is "OR"ed)
- *
- * If counting up (direction is positive) find first record with ID > start_id.
- * Else if counting down (direction is negative) find first record with ID < start_id.
- *
- * Set match flag on.
- * If any query is NULL, set match flog off (skips matching below).
- * Else if all queries only check "standard" keys, set std flag to on.
- *
- * If all queries are marked as "never matches", return NULL.
- *
- * match loop:
- * fetch record (with std flag)
- * if match flag is off, decode record and add it to result.
- * else for each query:
- * if query is NULL (shouldn't happen) decode record and add it to result. Return to match loop.
- * else if query never matches, ignore it.
- * else decode record and use asl_cmp. If it succeeds, add record to result. Return to match loop.
- *
- * return results.
- */
-static uint32_t
-match_worker(asl_legacy1_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint64_t *last_id, uint64_t **idlist, uint32_t *idcount, uint64_t start_id, int32_t count, int32_t direction)
-{
- uint32_t mx, si, slot, i, qcount, match, didmatch, status;
- uint64_t xid;
- aslmsg msg;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if ((res == NULL) && (idlist == NULL)) return ASL_STATUS_INVALID_ARG;
- if (last_id == NULL) return ASL_STATUS_INVALID_ARG;
- if (idcount == NULL) return ASL_STATUS_INVALID_ARG;
-
- if (res != NULL) *res = NULL;
- if (idlist != NULL) *idlist = NULL;
-
- mx = 0;
-
- if (direction < 0) direction = -1;
- else direction = 1;
-
- si = ASL_INDEX_NULL;
- if ((direction == -1) && (start_id == ASL_REF_NULL)) si = s->slotlist_count;
- else si = slotlist_find(s, start_id, direction);
-
- si = next_search_slot(s, si, direction);
- if (si == ASL_INDEX_NULL) return ASL_STATUS_OK;
- if (si >= s->slotlist_count) return ASL_STATUS_FAILED;
-
- slot = s->slotlist[si].slot;
-
- match = 1;
- qcount = 0;
-
- if (query == NULL) match = 0;
- else if (query->count == 0) match = 0;
- else qcount = query->count;
-
- /*
- * initialize result list if we've been asked to return messages
- */
- if (res != NULL)
- {
- *res = (asl_msg_list_t *)calloc(1, sizeof(asl_msg_list_t));
- if (*res == NULL) return ASL_STATUS_NO_MEMORY;
- }
-
- status = ASL_STATUS_OK;
-
- /*
- * loop through records
- */
- *idcount = 0;
- while ((count == 0) || (*idcount < count))
- {
- if (si == ASL_INDEX_NULL) break;
- if (si >= s->slotlist_count) break;
-
- slot = s->slotlist[si].slot;
- xid = s->slotlist[si].xid;
-
- *last_id = xid;
-
- status = msg_fetch(s, slot, &msg);
-
- didmatch = 0;
- if (match == 0)
- {
- didmatch = 1;
- }
- else
- {
- for (i = 0; i < qcount; i++)
- {
- didmatch = asl_msg_cmp((aslmsg)(query->msg[i]), msg);
- if (didmatch == 1) break;
- }
- }
-
- if (didmatch == 1)
- {
- if ((*res)->count == 0) (*res)->msg = (asl_msg_t **)calloc(1, sizeof(asl_msg_t *));
- else (*res)->msg = (asl_msg_t **)reallocf((*res)->msg, (1 + (*res)->count) * sizeof(asl_msg_t *));
- if ((*res)->msg == NULL)
- {
- match_worker_cleanup(res);
- return ASL_STATUS_NO_MEMORY;
- }
-
- (*res)->msg[(*res)->count++] = (asl_msg_t *)msg;
- }
- else
- {
- asl_free(msg);
- }
-
- si = next_search_slot(s, si, direction);
- }
-
- return status;
-}
-
-uint32_t
-asl_legacy1_match(asl_legacy1_t *s, asl_msg_list_t *query, asl_msg_list_t **res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction)
-{
- uint32_t idcount;
-
- idcount = 0;
- return match_worker(s, query, res, last_id, NULL, &idcount, start_id, count, direction);
-}
+++ /dev/null
-#ifndef __ASL_LEGACY1_H__
-#define __ASL_LEGACY1_H__
-
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@ */
-
-/*
- * ASL Database VERSION 1 (LEGACY)
- *
- * Log messages are stored in 80 byte records of the form:
- *
- * | 1 | 4 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 4 | 4 | 4 | 4 | 8 | 2 | 1 | (80 bytes)
- * | Type | Next | ID | RUID | RGID | Time | Host | Sender | Facility | LEVEL | PID | UID | GID | Message | Flags | Zero |
- *
- * If there are no additional key/value pairs in the message, Next will be zero. If there are additional
- * key/value pairs in the database, Next is a record number for a record with the format:
- *
- * | 1 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 7 | (80 bytes)
- * | Type | Next | Count | Key1 | Val1 | Key2 | Val2 | Key3 | Val3 | Key4 | Val4 | Zero |
- *
- * Additional records will be chained using the Next field, with the count field left zero.
- *
- * Strings stored in records of the form:
- *
- * | 1 | 4 | 8 | 4 | 4 | 4 | 55 | (80 bytes)
- * | Type | Next | ID | Refcount | Hash | Length | String |
- *
- * If the string is longer than 55 bytes, Next is a record number for a record with the format:
- *
- * | 1 | 4 | 75 | (80 bytes)
- * | Type | Next | String |
- *
- * The first record (header) in the database has the format:
- *
- * | 12 | 4 | 8 | 56 | (80 bytes)
- * | Cookie | Vers | Max ID | Zero |
- *
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <asl.h>
-#include <Availability.h>
-
-typedef struct
-{
- uint8_t type;
- uint32_t slot;
- uint64_t xid;
- uint32_t hash;
-} asl_legacy1_slot_info_t;
-
-typedef struct
-{
- asl_legacy1_slot_info_t *slotlist;
- uint32_t slotlist_count;
- FILE *db;
-} asl_legacy1_t;
-
-uint32_t asl_legacy1_open(const char *path, asl_legacy1_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_legacy1_close(asl_legacy1_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_legacy1_fetch(asl_legacy1_t *s, uint64_t msgid, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_legacy1_match(asl_legacy1_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-#endif /*__ASL_LEGACY1_H__*/
+++ /dev/null
-/*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <string.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <unistd.h>
-#include <stdarg.h>
-#include <regex.h>
-#include <syslog.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-#include <asl.h>
-#include <asl_private.h>
-#include <asl_core.h>
-#include <sys/types.h>
-#include <libkern/OSAtomic.h>
-#include <assert.h>
-#include "asl_msg.h"
-
-#define TOKEN_NULL 0
-#define TOKEN_OPEN 1
-#define TOKEN_CLOSE 2
-#define TOKEN_WORD 3
-#define TOKEN_INT 4
-
-#define MFMT_RAW 0
-#define MFMT_STD 1
-#define MFMT_BSD 2
-#define MFMT_XML 3
-#define MFMT_STR 4
-#define MFMT_MSG 5
-
-#define SEC_PER_HOUR 3600
-
-#define forever for(;;)
-
-#define streq(A, B) (strcmp(A, B) == 0)
-#define streq_len(A, B, C) (strncmp(A, B, C) == 0)
-#define strneq(A, B) (strcmp(A, B) != 0)
-#define strcaseeq(A, B) (strcasecmp(A, B) == 0)
-#define strcaseneq(A, B) (strcasecmp(A, B) != 0)
-
-#ifndef ASL_KEY_OPTION
-#define ASL_KEY_OPTION "ASLOption"
-#endif
-
-#ifndef ASL_QUERY_OP_FALSE
-#define ASL_QUERY_OP_FALSE 0
-#endif
-
-#define AUX_0_TIME 0x00000001
-#define AUX_0_TIME_NSEC 0x00000002
-#define AUX_0_HOST 0x00000004
-#define AUX_0_SENDER 0x00000008
-#define AUX_0_FACILITY 0x00000010
-#define AUX_0_PID 0x00000020
-#define AUX_0_UID 0x00000040
-#define AUX_0_GID 0x00000080
-#define AUX_0_MSG 0x00000100
-#define AUX_0_OPTION 0x00000200
-#define AUX_0_LEVEL 0x00000400
-
-extern time_t asl_parse_time(const char *in);
-
-/* from asl_util.c */
-int asl_is_utf8(const char *str);
-uint8_t *asl_b64_encode(const uint8_t *buf, size_t len);
-
-static const char *ASLStandardKey[] =
-{
- ASL_KEY_TIME,
- ASL_KEY_TIME_NSEC,
- ASL_KEY_HOST,
- ASL_KEY_SENDER,
- ASL_KEY_FACILITY,
- ASL_KEY_PID,
- ASL_KEY_UID,
- ASL_KEY_GID,
- ASL_KEY_LEVEL,
- ASL_KEY_MSG,
- ASL_KEY_READ_UID,
- ASL_KEY_READ_GID,
- ASL_KEY_SESSION,
- ASL_KEY_REF_PID,
- ASL_KEY_REF_PROC,
- ASL_KEY_MSG_ID,
- ASL_KEY_EXPIRE_TIME,
- ASL_KEY_OPTION
-};
-
-static const char *MTStandardKey[] =
-{
- "com.apple.message.domain",
- "com.apple.message.domain_scope",
- "com.apple.message.result",
- "com.apple.message.signature",
- "com.apple.message.signature2",
- "com.apple.message.signature3",
- "com.apple.message.success",
- "com.apple.message.uuid",
- "com.apple.message.value",
- "com.apple.message.value2",
- "com.apple.message.value3",
- "com.apple.message.value4",
- "com.apple.message.value5"
-};
-
-static uint16_t
-_asl_msg_std_key(const char *s, uint32_t len)
-{
- if ((len > 18) && (streq_len(s, "com.apple.message.", 18)))
- {
- if (streq(s + 18, "domain")) return ASL_MT_KEY_DOMAIN;
- else if (streq(s + 18, "domain_scope")) return ASL_MT_KEY_SCOPE;
- else if (streq(s + 18, "result")) return ASL_MT_KEY_RESULT;
- else if (streq(s + 18, "signature")) return ASL_MT_KEY_SIG;
- else if (streq(s + 18, "signature2")) return ASL_MT_KEY_SIG2;
- else if (streq(s + 18, "signature3")) return ASL_MT_KEY_SIG3;
- else if (streq(s + 18, "success")) return ASL_MT_KEY_SUCCESS;
- else if (streq(s + 18, "uuid")) return ASL_MT_KEY_UUID;
- else if (streq(s + 18, "value")) return ASL_MT_KEY_VAL;
- else if (streq(s + 18, "value2")) return ASL_MT_KEY_VAL2;
- else if (streq(s + 18, "value3")) return ASL_MT_KEY_VAL3;
- else if (streq(s + 18, "value4")) return ASL_MT_KEY_VAL4;
- else if (streq(s + 18, "value5")) return ASL_MT_KEY_VAL5;
-
- return 0;
- }
-
- switch (len)
- {
- case 3:
- {
- if streq(s, ASL_KEY_PID) return ASL_STD_KEY_PID;
- else if streq(s, ASL_KEY_UID) return ASL_STD_KEY_UID;
- else if streq(s, ASL_KEY_GID) return ASL_STD_KEY_GID;
- }
- case 4:
- {
- if streq(s, ASL_KEY_TIME) return ASL_STD_KEY_TIME;
- else if streq(s, ASL_KEY_HOST) return ASL_STD_KEY_HOST;
- }
- case 5:
- {
- if streq(s, ASL_KEY_LEVEL) return ASL_STD_KEY_LEVEL;
- }
- case 6:
- {
- if streq(s, ASL_KEY_SENDER) return ASL_STD_KEY_SENDER;
- else if streq(s, ASL_KEY_REF_PID) return ASL_STD_KEY_REF_PID;
- }
- case 7:
- {
- if streq(s, ASL_KEY_MSG) return ASL_STD_KEY_MESSAGE;
- else if streq(s, ASL_KEY_SESSION) return ASL_STD_KEY_SESSION;
- else if streq(s, ASL_KEY_READ_UID) return ASL_STD_KEY_READ_UID;
- else if streq(s, ASL_KEY_READ_GID) return ASL_STD_KEY_READ_GID;
- else if streq(s, ASL_KEY_REF_PROC) return ASL_STD_KEY_REF_PROC;
- }
- case 8:
- {
- if streq(s, ASL_KEY_FACILITY) return ASL_STD_KEY_FACILITY;
- }
- case 9:
- {
- if streq(s, ASL_KEY_OPTION) return ASL_STD_KEY_OPTION;
- }
- case 11:
- {
- if streq(s, ASL_KEY_TIME_NSEC) return ASL_STD_KEY_NANO;
- }
- case 12:
- {
- if streq(s, ASL_KEY_MSG_ID) return ASL_STD_KEY_MSG_ID;
- }
- case 13:
- {
- if streq(s, ASL_KEY_EXPIRE_TIME) return ASL_STD_KEY_EXPIRE;
- }
- default:
- {
- return 0;
- }
- }
-
- return 0;
-}
-
-static asl_msg_t *
-_asl_msg_make_page()
-{
- asl_msg_t *out;
- int i;
-
- out = calloc(1, sizeof(asl_msg_t));
- if (out == NULL) return NULL;
-
- for (i = 0; i < ASL_MSG_PAGE_SLOTS; i++)
- {
- out->key[i] = ASL_MSG_SLOT_FREE;
- out->val[i] = ASL_MSG_SLOT_FREE;
- }
-
- return out;
-}
-
-static const char *
-_asl_msg_slot_key(asl_msg_t *page, uint32_t slot)
-{
- const char *out;
- uint16_t x;
-
- if (page == NULL) return NULL;
- if (slot >= ASL_MSG_PAGE_SLOTS) return NULL;
-
- if (page->key[slot] == ASL_MSG_SLOT_FREE) return NULL;
-
- switch (page->key[slot] & ASL_MSG_KV_MASK)
- {
- case ASL_MSG_KV_INLINE:
- {
- return page->data + page->key[slot];
- }
- case ASL_MSG_KV_DICT:
- {
- if ((page->key[slot] > ASL_STD_KEY_BASE) && (page->key[slot] <= ASL_STD_KEY_LAST))
- {
- x = page->key[slot] - ASL_STD_KEY_BASE - 1;
- return ASLStandardKey[x];
- }
- else if ((page->key[slot] > ASL_MT_KEY_BASE) && (page->key[slot] <= ASL_MT_KEY_LAST))
- {
- x = page->key[slot] - ASL_MT_KEY_BASE - 1;
- return MTStandardKey[x];
- }
-
- return NULL;
- }
- case ASL_MSG_KV_EXTERN:
- {
- x = page->key[slot] & ASL_MSG_OFFSET_MASK;
- memcpy(&out, page->data + x, sizeof(char *));
- return out;
- }
- }
-
- return NULL;
-}
-
-static const char *
-_asl_msg_slot_val(asl_msg_t *page, uint32_t slot)
-{
- const char *out;
- uint16_t x, type;
-
- if (page == NULL) return NULL;
- if (slot >= ASL_MSG_PAGE_SLOTS) return NULL;
-
- if (page->val[slot] == ASL_MSG_SLOT_FREE) return NULL;
-
- type = page->val[slot] & ASL_MSG_KV_MASK;
-
- if (type == ASL_MSG_KV_INLINE)
- {
- return page->data + page->val[slot];
- }
- else if (type == ASL_MSG_KV_EXTERN)
- {
- x = page->val[slot] & ASL_MSG_OFFSET_MASK;
- memcpy(&out, page->data + x, sizeof(char *));
- return out;
- }
-
- return NULL;
-}
-
-/*
- * asl_new: create a new log message.
- */
-asl_msg_t *
-asl_msg_new(uint32_t type)
-{
- asl_msg_t *out;
-
- out = _asl_msg_make_page();
- if (out == NULL) return NULL;
-
- out->type = type;
- out->refcount = 1;
-
- return out;
-}
-
-asl_msg_t *
-asl_msg_retain(asl_msg_t *msg)
-{
- int32_t new;
-
- if (msg == NULL) return NULL;
-
- new = OSAtomicIncrement32Barrier(&msg->refcount);
- assert(new >= 1);
-
- return msg;
-}
-
-static void
-_asl_msg_free(asl_msg_t *page)
-{
- uint32_t i;
- char *p;
-
- if (page == NULL) return;
-
- for (i = 0; i < ASL_MSG_PAGE_SLOTS; i++)
- {
- if ((page->key[i] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN)
- {
- memcpy(&p, page->data + (page->key[i] & ASL_MSG_OFFSET_MASK), sizeof(char *));
- free(p);
- }
-
- if ((page->val[i] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN)
- {
- memcpy(&p, page->data + (page->val[i] & ASL_MSG_OFFSET_MASK), sizeof(char *));
- free(p);
- }
- }
-
- free(page);
-}
-
-void
-asl_msg_release(asl_msg_t *msg)
-{
- int32_t new;
- asl_msg_t *next;
-
- if (msg == NULL) return;
-
- new = OSAtomicDecrement32Barrier(&msg->refcount);
- assert(new >= 0);
-
- if (new > 0) return;
-
- while (msg != NULL)
- {
- next = msg->next;
- _asl_msg_free(msg);
- msg = next;
- }
-}
-
-static uint32_t
-_asl_msg_index(asl_msg_t *msg, const char *key, uint32_t *oslot, asl_msg_t **opage)
-{
- uint32_t i, len, slot;
- uint16_t kx;
- asl_msg_t *page;
- const char *kp;
-
- if (msg == NULL) return IndexNull;
- if (key == NULL) return IndexNull;
-
- i = 0;
- slot = 0;
- if (oslot != NULL) *oslot = slot;
-
- page = msg;
- if (opage != NULL) *opage = page;
-
- len = strlen(key);
- kx = _asl_msg_std_key(key, len);
-
- forever
- {
- if (page->key[slot] != ASL_MSG_SLOT_FREE)
- {
- if (kx != 0)
- {
- if (page->key[slot] == kx) return i;
- }
- else if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_DICT)
- {
- /* page->key[slot] is a dictionary key, but key is not (kx == 0) so skip this slot */
- }
- else if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN)
- {
- memcpy(&kp, page->data + (page->key[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *));
- if (streq(key, kp)) return i;
- }
- else
- {
- kp = page->data + page->key[slot];
- if (streq(key, kp)) return i;
- }
- }
-
- i++;
- slot++;
- if (oslot != NULL) *oslot = slot;
-
- if (slot >= ASL_MSG_PAGE_SLOTS)
- {
- if (page->next == NULL) return IndexNull;
-
- slot = 0;
- if (oslot != NULL) *oslot = slot;
-
- page = page->next;
- if (opage != NULL) *opage = page;
- }
- }
-
- return IndexNull;
-}
-
-/*
- * asl_msg_key: iterate over entries
- * initial value of n should be 0
- * after that, the value of n should be previously returned value
- * sets the pointers for the next key, value, and op in the msgionary
- * returns IndexNull when there are no more entries
- */
-static uint32_t
-_asl_msg_fetch_internal(asl_msg_t *msg, uint32_t n, const char **keyout, const char **valout, uint32_t *opout, asl_msg_t **outpage, uint32_t *outslot)
-{
- uint32_t slot;
- asl_msg_t *page;
-
- if (msg == NULL) return IndexNull;
- if (outpage != NULL) *outpage = NULL;
- if (outslot != NULL) *outslot = IndexNull;
-
- slot = n;
- page = msg;
-
- while (slot >= ASL_MSG_PAGE_SLOTS)
- {
- if (page->next == NULL) return IndexNull;
- page = page->next;
- slot -= ASL_MSG_PAGE_SLOTS;
- }
-
- while (page->key[slot] == ASL_MSG_SLOT_FREE)
- {
- slot++;
- n++;
-
- if (slot >= ASL_MSG_PAGE_SLOTS)
- {
- if (page->next == NULL) return IndexNull;
- page = page->next;
- slot = 0;
- }
- }
-
- n++;
-
- if (keyout != NULL) *keyout = _asl_msg_slot_key(page, slot);
- if (valout != NULL) *valout = _asl_msg_slot_val(page, slot);
- if (opout != NULL) *opout = page->op[slot];
-
- if (outpage != NULL) *outpage = page;
- if (outslot != NULL) *outslot = slot;
-
- return n;
-}
-
-uint32_t
-asl_msg_fetch(asl_msg_t *msg, uint32_t n, const char **keyout, const char **valout, uint32_t *opout)
-{
- return _asl_msg_fetch_internal(msg, n, keyout, valout, opout, NULL, NULL);
-}
-
-static int
-_asl_msg_new_key_val_op(asl_msg_t *msg, const char *key, const char *val, uint32_t op)
-{
- uint32_t slot, keylen, vallen, total;
- uint16_t kx;
- asl_msg_t *page, *last;
- char *extkey, *extval;
-
- if (msg == NULL) return -1;
- if (key == NULL) return -1;
-
- extkey = NULL;
- extval = NULL;
-
- keylen = strlen(key);
- kx = _asl_msg_std_key(key, keylen);
-
- if (kx == 0) keylen++;
- else keylen = 0;
-
- total = keylen;
-
- vallen = 0;
- if (val != NULL)
- {
- vallen = strlen(val) + 1;
- total += vallen;
- }
-
- /* check if one or both of key and value must be "external" (in its own malloced space) */
- if (keylen > ASL_MSG_PAGE_DATA_SIZE)
- {
- extkey = strdup(key);
- keylen = sizeof(char *);
- }
-
- if (vallen > ASL_MSG_PAGE_DATA_SIZE)
- {
- extval = strdup(val);
- vallen = sizeof(char *);
- }
-
- total = keylen + vallen;
- if ((total > ASL_MSG_PAGE_DATA_SIZE) && (extval == NULL) && (keylen > 0))
- {
- extval = strdup(val);
- vallen = sizeof(char *);
- total = keylen + vallen;
- }
-
- if ((total > ASL_MSG_PAGE_DATA_SIZE) && (extkey == NULL))
- {
- extkey = strdup(key);
- keylen = sizeof(char *);
- total = keylen + vallen;
- }
-
- if (total > ASL_MSG_PAGE_DATA_SIZE)
- {
- /* can't happen, but... */
- if (extkey != NULL) free(extkey);
- if (extval != NULL) free(extval);
- return -1;
- }
-
- /* find a page with space for the key and value and a free slot*/
- slot = 0;
- last = msg;
-
- for (page = msg; page != NULL; page = page->next)
- {
- last = page;
-
- if (total <= (ASL_MSG_PAGE_DATA_SIZE - page->data_size))
- {
- /* check for a free slot */
- for (slot = 0; (slot < ASL_MSG_PAGE_SLOTS) && (page->key[slot] != ASL_MSG_SLOT_FREE); slot++);
- if (slot < ASL_MSG_PAGE_SLOTS) break;
- }
- }
-
- if (page == NULL)
- {
- /* allocate a new page and attach it */
- page = _asl_msg_make_page();
- if (page == NULL)
- {
- if (extkey != NULL) free(extkey);
- if (extval != NULL) free(extval);
- return -1;
- }
-
- last->next = page;
- slot = 0;
- }
-
- /* copy key or external key pointer into page data */
- if (kx != 0)
- {
- page->key[slot] = kx;
- }
- else if (extkey == NULL)
- {
- page->key[slot] = page->data_size;
- memcpy(page->data + page->data_size, key, keylen);
- }
- else
- {
- page->key[slot] = page->data_size | ASL_MSG_KV_EXTERN;
- memcpy(page->data + page->data_size, &extkey, keylen);
- }
-
- page->data_size += keylen;
-
- /* copy val or external val pointer into page data */
- page->val[slot] = ASL_MSG_SLOT_FREE;
-
- if (val != NULL)
- {
- if (extval == NULL)
- {
- page->val[slot] = page->data_size;
- memcpy(page->data + page->data_size, val, vallen);
- }
- else
- {
- page->val[slot] = page->data_size | ASL_MSG_KV_EXTERN;
- memcpy(page->data + page->data_size, &extval, vallen);
- }
-
- page->data_size += vallen;
- }
-
- /* set op */
- page->op[slot] = op;
-
- /* update page count */
- page->count++;
-
- return 0;
-}
-
-/*
- * Most of the code in asl_msg_set_key_val_op is concerned with trying to re-use
- * space in an asl_msg_t page when given a new value for an existing key.
- * If the key is new, we just call _asl_msg_new_key_val_op.
- *
- * Note that queries can have duplicate keys, so for ASL_TYPE_QUERY we just
- * call through to _asl_msg_new_key_val_op.
- */
-static int
-_asl_msg_set_kvo(asl_msg_t *msg, const char *key, const char *val, uint32_t op)
-{
- uint32_t i, slot, newexternal;
- asl_msg_t *page;
- uint32_t intvallen, extvallen, newvallen;
- char *intval, *extval, *newval;
-
- if (msg == NULL) return -1;
- if (key == NULL) return -1;
-
- slot = IndexNull;
- page = NULL;
-
- if ((msg->type == ASL_TYPE_QUERY) || (IndexNull == _asl_msg_index(msg, key, &slot, &page)))
- {
- /* add key */
- return _asl_msg_new_key_val_op(msg, key, val, op);
- }
-
- intval = NULL;
- intvallen = 0;
-
- extval = NULL;
- extvallen = 0;
-
- if (page->val[slot] != ASL_MSG_SLOT_FREE)
- {
- if ((page->val[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN)
- {
- i = page->val[slot] & ASL_MSG_OFFSET_MASK;
- memcpy(&extval, page->data + i, sizeof(char *));
- extvallen = sizeof(char *);
- }
- else
- {
- intval = page->data + page->val[slot];
- intvallen = strlen(intval) + 1;
- }
- }
-
- /* replace val and op for existing entry */
-
- /* easy case - remove val */
- if (val == NULL)
- {
- if (extval != NULL) free(extval);
- page->val[slot] = ASL_MSG_SLOT_FREE;
- if (op != IndexNull) page->op[slot] = op;
- return 0;
- }
-
- /* trivial case - internal val doesn't change */
- if ((intval != NULL) && (streq(val, intval)))
- {
- if (op != IndexNull) page->op[slot] = op;
- return 0;
- }
-
- /* trivial case - external val doesn't change */
- if ((extval != NULL) && (streq(val, extval)))
- {
- if (op != IndexNull) page->op[slot] = op;
- return 0;
- }
-
- /*
- * special case: we generally don't compress out holes in the data
- * space, but if this is the last string in the currently used data space
- * we can just back up the data_size and reset page->val[slot]
- */
- i = page->val[slot] & ASL_MSG_OFFSET_MASK;
- if ((intval != NULL) && ((i + intvallen) == page->data_size))
- {
- page->val[slot] = ASL_MSG_SLOT_FREE;
- page->data_size -= intvallen;
- intval = NULL;
- intvallen = 0;
- }
- else if ((extval != NULL) && ((i + extvallen) == page->data_size))
- {
- page->val[slot] = ASL_MSG_SLOT_FREE;
- page->data_size -= extvallen;
- free(extval);
- extval = NULL;
- extvallen = 0;
- }
-
- /* val changes - see if it needs to be external */
- newvallen = strlen(val) + 1;
- newexternal = 0;
-
- if (newvallen > ASL_MSG_PAGE_DATA_SIZE)
- {
- newexternal = 1;
- newvallen = sizeof(char *);
- }
-
- /* check if there is room to change val in place */
- if (((extval != NULL) && (newvallen <= extvallen)) || ((extval == NULL) && (newvallen <= intvallen)))
- {
- if (extval != NULL) free(extval);
- extval = NULL;
-
- /* we can re-use the space of the old value */
- i = page->val[slot] & ASL_MSG_OFFSET_MASK;
-
- if (newexternal == 1)
- {
- /* create an external val and copy in the new pointer */
- newval = strdup(val);
- if (newval == NULL) return -1;
-
- page->val[slot] = i | ASL_MSG_KV_EXTERN;
- memcpy(page->data + i, &newval, sizeof(char *));
- }
- else
- {
- /* new internal value */
- page->val[slot] = i;
- memcpy(page->data + i, val, newvallen);
- }
-
- if (op != IndexNull) page->op[slot] = op;
- return 0;
- }
-
- /* we're done with the old value if it is external - free it now */
- if (extval != NULL) free(extval);
- extval = NULL;
-
- if (newvallen <= (ASL_MSG_PAGE_DATA_SIZE - page->data_size))
- {
- /* can't re-use the old space, but there's room on the page */
- i = page->data_size;
- page->data_size += newvallen;
-
- if (newexternal == 1)
- {
- /* create an external val and copy in the new pointer */
- newval = strdup(val);
- if (newval == NULL) return -1;
-
- page->val[slot] = i | ASL_MSG_KV_EXTERN;
- memcpy(page->data + i, &newval, sizeof(char *));
- }
- else
- {
- /* new internal value */
- page->val[slot] = i;
- memcpy(page->data + i, val, newvallen);
- }
-
- if (op != IndexNull) page->op[slot] = op;
- return 0;
-
- }
-
- /* no room on this page - free up existing entry and treat this as a new entry */
- if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN)
- {
- memcpy(&extval, page->data + (page->key[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *));
- free(extval);
- }
-
- page->key[slot] = ASL_MSG_SLOT_FREE;
- page->val[slot] = ASL_MSG_SLOT_FREE;
- page->op[slot] = 0;
-
- return _asl_msg_new_key_val_op(msg, key, val, op);
-}
-
-int
-asl_msg_set_key_val_op(asl_msg_t *msg, const char *key, const char *val, uint32_t op)
-{
- char *special, buf[512];
- uint32_t i, len;
- int status;
-
- /* Special case handling */
- special = NULL;
-
- /* convert "Level" values to "0" through "7" */
- if (streq(key, ASL_KEY_LEVEL))
- {
- if (val == NULL) val = "7";
- else if ((val[0] >= '0') && (val[0] <= '7') && (val[1] == '\0')) /* do nothing */;
- else if (strcaseeq(val, ASL_STRING_EMERG)) val = "0";
- else if (strcaseeq(val, ASL_STRING_ALERT)) val = "1";
- else if (strcaseeq(val, ASL_STRING_CRIT)) val = "2";
- else if (strcaseeq(val, ASL_STRING_ERR)) val = "3";
- else if (strcaseeq(val, ASL_STRING_WARNING)) val = "4";
- else if (strcaseeq(val, ASL_STRING_NOTICE)) val = "5";
- else if (strcaseeq(val, ASL_STRING_INFO)) val = "6";
- else if (strcaseeq(val, ASL_STRING_DEBUG)) val = "7";
- else val = "7";
- }
-
- /* strip trailing newlines from "Message" values */
- if ((streq(key, ASL_KEY_MSG)) && (val != NULL))
- {
- len = strlen(val);
- i = len;
- while ((i > 0) && (val[i - 1] == '\n')) i--;
- if (i == 0) val = NULL;
- else if (i < len)
- {
- /* use buf if it is big enough, else malloc a temporary buffer */
- if (i < sizeof(buf))
- {
- memcpy(buf, val, i);
- buf[i] = 0;
- val = (const char *)buf;
- }
- else
- {
- special = malloc(i + 1);
- if (special == NULL) return -1;
- memcpy(special, val, i);
- special[i] = 0;
- val = (const char *)special;
- }
- }
- }
-
- status = _asl_msg_set_kvo(msg, key, val, op);
-
- if (special != NULL) free(special);
- return status;
-}
-
-int
-asl_msg_set_key_val(asl_msg_t *msg, const char *key, const char *val)
-{
- return asl_msg_set_key_val_op(msg, key, val, 0);
-}
-
-/*
- * Merge a key / val into a message (only ASL_TYPE_MSG).
- * Adds the key / val if the key is not found.
- * Does not replace the value if the key is found.
- */
-static void
-_asl_msg_merge_key_val(asl_msg_t *msg, const char *key, const char *val)
-{
- uint32_t i, slot;
- asl_msg_t *page;
-
- if (msg == NULL) return;
- if (key == NULL) return;
-
- slot = IndexNull;
- page = NULL;
-
- i = _asl_msg_index(msg, key, &slot, &page);
- if (i != IndexNull) return;
-
- asl_msg_set_key_val_op(msg, key, val, 0);
-}
-
-/*
- * Merge msg into target (does not replace existing keys).
- * Creates a new asl_msg_t if target is NULL.
- * Returns target.
- */
-asl_msg_t *
-asl_msg_merge(asl_msg_t *target, asl_msg_t *msg)
-{
- uint32_t x, slot, op, isnew = 0;
- const char *key, *val;
- asl_msg_t *page;
-
- if (msg == NULL) return target;
-
- if (target == NULL)
- {
- isnew = 1;
- target = asl_msg_new(ASL_TYPE_MSG);
- }
-
- for (x = _asl_msg_fetch_internal(msg, 0, &key, &val, &op, &page, &slot); x != IndexNull; x = _asl_msg_fetch_internal(msg, x, &key, &val, &op, &page, &slot))
- {
- if (isnew == 1) asl_msg_set_key_val_op(target, key, val, 0);
- else _asl_msg_merge_key_val(target, key, val);
- }
-
- return target;
-}
-
-/*
- * Copy msg.
- */
-asl_msg_t *
-asl_msg_copy(asl_msg_t *msg)
-{
- return asl_msg_merge(NULL, msg);
-}
-
-/*
- * asl_msg_unset
- * Frees external key and val strings, but does not try to reclaim data space.
- */
-void
-asl_msg_unset(asl_msg_t *msg, const char *key)
-{
- uint32_t i, slot;
- asl_msg_t *page;
- char *ext;
-
- if (msg == NULL) return;
- if (key == NULL) return;
-
- slot = IndexNull;
- page = NULL;
-
- i = _asl_msg_index(msg, key, &slot, &page);
- if (i == IndexNull) return;
-
- if ((page->key[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN)
- {
- memcpy(&ext, page->data + (page->key[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *));
- free(ext);
- }
-
- if ((page->val[slot] & ASL_MSG_KV_MASK) == ASL_MSG_KV_EXTERN)
- {
- memcpy(&ext, page->data + (page->val[slot] & ASL_MSG_OFFSET_MASK), sizeof(char *));
- free(ext);
- }
-
- page->key[slot] = ASL_MSG_SLOT_FREE;
- page->val[slot] = ASL_MSG_SLOT_FREE;
- page->op[slot] = 0;
-
- page->count--;
-}
-
-int
-asl_msg_lookup(asl_msg_t *msg, const char *key, const char **valout, uint32_t *opout)
-{
- uint32_t i, slot;
- asl_msg_t *page;
-
- slot = IndexNull;
- page = NULL;
-
- i = _asl_msg_index(msg, key, &slot, &page);
- if (i == IndexNull) return -1;
-
- if (valout != NULL) *valout = _asl_msg_slot_val(page, slot);
- if (opout != NULL) *opout = page->op[slot];
-
- return 0;
-}
-
-uint32_t
-asl_msg_type(asl_msg_t *msg)
-{
- if (msg == NULL) return 0;
- return msg->type;
-}
-
-uint32_t
-asl_msg_count(asl_msg_t *msg)
-{
- uint32_t total;
-
- total = 0;
-
- for (; msg != NULL; msg = msg->next) total += msg->count;
- return total;
-}
-
-/*
- * Compare messages
- */
-static int
-_asl_msg_equal(asl_msg_t *a, asl_msg_t *b)
-{
- uint32_t x, oa, ob;
- const char *key, *va, *vb;
-
- if (asl_msg_count(a) != asl_msg_count(b)) return 0;
-
- key = NULL;
- va = NULL;
- oa = 0;
-
-
- for (x = asl_msg_fetch(a, 0, &key, &va, &oa); x != IndexNull; x = asl_msg_fetch(a, x, &key, &va, &oa))
- {
- if (asl_msg_lookup(b, key, &vb, &ob) != 0) return 0;
- if (strcmp(va, vb)) return 0;
- if ((a->type == ASL_TYPE_QUERY) && (oa != ob)) return 0;
- }
-
- return 1;
-}
-
-static int
-_asl_isanumber(const char *s)
-{
- int i;
-
- if (s == NULL) return 0;
-
- i = 0;
- if ((s[0] == '-') || (s[0] == '+')) i = 1;
-
- if (s[i] == '\0') return 0;
-
- for (; s[i] != '\0'; i++)
- {
- if (!isdigit(s[i])) return 0;
- }
-
- return 1;
-}
-
-static int
-_asl_msg_basic_test(uint32_t op, const char *q, const char *m, uint32_t n)
-{
- int cmp;
- uint32_t t;
- int64_t nq, nm;
- int rflags;
- regex_t rex;
-
- t = op & ASL_QUERY_OP_TRUE;
-
- /* NULL value from query or message string fails */
- if ((q == NULL) || (m == NULL)) return (t & ASL_QUERY_OP_NOT_EQUAL);
-
- if (op & ASL_QUERY_OP_REGEX)
- {
- /* greater than or less than make no sense in substring search */
- if ((t == ASL_QUERY_OP_GREATER) || (t == ASL_QUERY_OP_LESS)) return 0;
-
- memset(&rex, 0, sizeof(regex_t));
-
- rflags = REG_EXTENDED | REG_NOSUB;
- if (op & ASL_QUERY_OP_CASEFOLD) rflags |= REG_ICASE;
-
- /* A bad reqular expression matches nothing */
- if (regcomp(&rex, q, rflags) != 0) return (t & ASL_QUERY_OP_NOT_EQUAL);
-
- cmp = regexec(&rex, m, 0, NULL, 0);
- regfree(&rex);
-
- if (t == ASL_QUERY_OP_NOT_EQUAL) return (cmp != 0);
- return (cmp == 0);
- }
-
- if (op & ASL_QUERY_OP_NUMERIC)
- {
- if (_asl_isanumber(q) == 0) return (t == ASL_QUERY_OP_NOT_EQUAL);
- if (_asl_isanumber(m) == 0) return (t == ASL_QUERY_OP_NOT_EQUAL);
-
- nq = atoll(q);
- nm = atoll(m);
-
- switch (t)
- {
- case ASL_QUERY_OP_EQUAL: return (nm == nq);
- case ASL_QUERY_OP_GREATER: return (nm > nq);
- case ASL_QUERY_OP_GREATER_EQUAL: return (nm >= nq);
- case ASL_QUERY_OP_LESS: return (nm < nq);
- case ASL_QUERY_OP_LESS_EQUAL: return (nm <= nq);
- case ASL_QUERY_OP_NOT_EQUAL: return (nm != nq);
- default: return (t == ASL_QUERY_OP_NOT_EQUAL);
- }
- }
-
- cmp = 0;
- if (op & ASL_QUERY_OP_CASEFOLD)
- {
- if (n == 0) cmp = strcasecmp(m, q);
- else cmp = strncasecmp(m, q, n);
- }
- else
- {
- if (n == 0) cmp = strcmp(m, q);
- else cmp = strncmp(m, q, n);
- }
-
- switch (t)
- {
- case ASL_QUERY_OP_EQUAL: return (cmp == 0);
- case ASL_QUERY_OP_GREATER: return (cmp > 0);
- case ASL_QUERY_OP_GREATER_EQUAL: return (cmp >= 0);
- case ASL_QUERY_OP_LESS: return (cmp < 0);
- case ASL_QUERY_OP_LESS_EQUAL: return (cmp <= 0);
- case ASL_QUERY_OP_NOT_EQUAL: return (cmp != 0);
- }
-
- return (t == ASL_QUERY_OP_NOT_EQUAL);
-}
-
-static int
-_asl_msg_test_substring(uint32_t op, const char *q, const char *m)
-{
- uint32_t t, i, d, lm, lq, match, newop;
-
- t = op & ASL_QUERY_OP_TRUE;
-
- lm = 0;
- if (m != NULL) lm = strlen(m);
-
- lq = 0;
- if (q != NULL) lq = strlen(q);
-
- /* NULL is a substring of any string */
- if (lq == 0) return (t & ASL_QUERY_OP_EQUAL);
-
- /* A long string is defined to be not equal to a short string */
- if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL);
-
- /* greater than or less than make no sense in substring search */
- if ((t == ASL_QUERY_OP_GREATER) || (t == ASL_QUERY_OP_LESS)) return 0;
-
- /*
- * We scan the string doing an equality test.
- * If the input test is equality, we stop as soon as we hit a match.
- * Otherwise we keep scanning the whole message string.
- */
- newop = op & 0xff0;
- newop |= ASL_QUERY_OP_EQUAL;
-
- match = 0;
- d = lm - lq;
- for (i = 0; i <= d; i++)
- {
- if (_asl_msg_basic_test(newop, q, m + i, lq) != 0)
- {
- if (t & ASL_QUERY_OP_EQUAL) return 1;
- match++;
- }
- }
-
- /* If the input test was for equality, no matches were found */
- if (t & ASL_QUERY_OP_EQUAL) return 0;
-
- /* The input test was for not equal. Return true if no matches were found */
- return (match == 0);
-}
-
-static int
-_asl_msg_test_prefix(uint32_t op, const char *q, const char *m)
-{
- uint32_t lm, lq, t;
-
- t = op & ASL_QUERY_OP_TRUE;
-
- lm = 0;
- if (m != NULL) lm = strlen(m);
-
- lq = 0;
- if (q != NULL) lq = strlen(q);
-
- /* NULL is a prefix of any string */
- if (lq == 0) return (t & ASL_QUERY_OP_EQUAL);
-
- /* A long string is defined to be not equal to a short string */
- if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL);
-
- /* Compare two equal-length strings */
- return _asl_msg_basic_test(op, q, m, lq);
-}
-
-static int
-_asl_msg_test_suffix(uint32_t op, const char *q, const char *m)
-{
- uint32_t lm, lq, d, t;
-
- t = op & ASL_QUERY_OP_TRUE;
-
- lm = 0;
- if (m != NULL) lm = strlen(m);
-
- lq = 0;
- if (q != NULL) lq = strlen(q);
-
- /* NULL is a suffix of any string */
- if (lq == 0) return (t & ASL_QUERY_OP_EQUAL);
-
- /* A long string is defined to be not equal to a short string */
- if (lq > lm) return (t == ASL_QUERY_OP_NOT_EQUAL);
-
- /* Compare two equal-length strings */
- d = lm - lq;
- return _asl_msg_basic_test(op, q, m + d, lq);
-}
-
-/*
- * Splits out prefix, suffix, and substring tests.
- * Sends the rest to _asl_msg_basic_test().
- */
-static int
-_asl_msg_test_expression(uint32_t op, const char *q, const char *m)
-{
- uint32_t t;
-
- t = op & ASL_QUERY_OP_TRUE;
- if (t == ASL_QUERY_OP_TRUE) return 1;
-
- if (op & ASL_QUERY_OP_PREFIX)
- {
- if (op & ASL_QUERY_OP_SUFFIX) return _asl_msg_test_substring(op, q, m);
- return _asl_msg_test_prefix(op, q, m);
- }
- if (op & ASL_QUERY_OP_SUFFIX) return _asl_msg_test_suffix(op, q, m);
-
- return _asl_msg_basic_test(op, q, m, 0);
-}
-
-/*
- * Special case for comparing time values.
- * If both inputs are time strings, this compares the time
- * value in seconds. Otherwise it just does normal matching.
- */
-static int
-_asl_msg_test_time_expression(uint32_t op, const char *q, const char *m)
-{
- time_t tq, tm;
- uint32_t t;
-
- if ((op & ASL_QUERY_OP_PREFIX) || (op & ASL_QUERY_OP_SUFFIX) || (op & ASL_QUERY_OP_REGEX)) return _asl_msg_test_expression(op, q, m);
- if ((q == NULL) || (m == NULL)) return _asl_msg_test_expression(op, q, m);
-
- tq = asl_parse_time(q);
- if (tq < 0) return _asl_msg_test_expression(op, q, m);
-
- tm = asl_parse_time(m);
- if (tm < 0) return _asl_msg_test_expression(op, q, m);
-
- t = op & ASL_QUERY_OP_TRUE;
-
- switch (t)
- {
- case ASL_QUERY_OP_FALSE:
- {
- return 0;
- }
- case ASL_QUERY_OP_EQUAL:
- {
- if (tm == tq) return 1;
- return 0;
- }
- case ASL_QUERY_OP_GREATER:
- {
- if (tm > tq) return 1;
- return 0;
- }
- case ASL_QUERY_OP_GREATER_EQUAL:
- {
- if (tm >= tq) return 1;
- return 0;
- }
- case ASL_QUERY_OP_LESS:
- {
- if (tm < tq) return 1;
- return 0;
- }
- case ASL_QUERY_OP_LESS_EQUAL:
- {
- if (tm <= tq) return 1;
- return 0;
- }
- case ASL_QUERY_OP_NOT_EQUAL:
- {
- if (tm != tq) return 1;
- return 0;
- }
- case ASL_QUERY_OP_TRUE:
- {
- return 1;
- }
- }
-
- /* NOTREACHED */
- return 0;
-}
-
-/* test a query against a message */
-static int
-_asl_msg_test(asl_msg_t *q, asl_msg_t *m)
-{
- uint32_t i, t, x, op;
- int cmp;
- const char *kq, *vq, *vm;
-
- /*
- * Check each simple expression (key op val) separately.
- * The query suceeds (returns 1) if all simple expressions
- * succeed (i.e. AND the simple expressions).
- */
-
- kq = NULL;
- vq = NULL;
- op = 0;
-
- for (x = asl_msg_fetch(q, 0, &kq, &vq, &op); x != IndexNull; x = asl_msg_fetch(q, x, &kq, &vq, &op))
- {
- /* Find query key in the message */
- vm = NULL;
- i = asl_msg_lookup(m, kq, &vm, NULL);
-
- /* ASL_QUERY_OP_TRUE tests if key is present in the message */
- t = op & ASL_QUERY_OP_TRUE;
- if (t == ASL_QUERY_OP_TRUE)
- {
- if (i != 0) return 0;
- continue;
- }
-
- /* ASL_QUERY_OP_FALSE tests if the key is NOT present in the message */
- if (t == ASL_QUERY_OP_FALSE)
- {
- if (i == 0) return 0;
- continue;
- }
-
- if (i != 0)
- {
- /* the message does NOT have query key - fail unless we are testing not equal */
- if (t == ASL_QUERY_OP_NOT_EQUAL) continue;
- return 0;
- }
-
- cmp = 1;
- if (streq(kq, ASL_KEY_TIME))
- {
- cmp = _asl_msg_test_time_expression(op, vq, vm);
- }
- else
- {
- cmp = _asl_msg_test_expression(op, vq, vm);
- }
-
- if (cmp == 0) return 0;
- }
-
- return 1;
-}
-
-int
-asl_msg_cmp(asl_msg_t *a, asl_msg_t *b)
-{
-
- if (a == NULL) return 0;
- if (b == NULL) return 0;
-
- if (a->type == b->type) return _asl_msg_equal(a, b);
- if (a->type == ASL_TYPE_QUERY) return _asl_msg_test(a, b);
- return _asl_msg_test(b, a);
-}
-
-
-static char *
-_asl_time_string(const char *fmt, const char *str)
-{
- time_t tick, off;
- struct tm stm;
- char *ltime;
- char *out;
- char ltbuf[32];
- out = NULL;
- time_t min;
- const char *p = fmt;
-
- tick = 0;
- if (str != NULL) tick = asl_parse_time(str);
-
- /* default format is local time zone */
- if ((fmt == NULL) || (!strcasecmp(fmt, "lcl")) || (!strcasecmp(fmt, "local")))
- {
- ltime = ctime_r(&tick, ltbuf);
- if (ltime == NULL) return NULL;
- ltime[19] = '\0';
- asprintf(&out, "%s", ltime + 4);
- return out;
- }
-
- if ((!strcasecmp(fmt, "sec")) || (!strcasecmp(fmt, "raw")))
- {
- asprintf(&out, "%lu", tick);
- return out;
- }
-
- if (!strcasecmp(fmt, "j"))
- {
- if (NULL == localtime_r(&tick, &stm)) return NULL;
- asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec);
- return out;
- }
-
- if ((!strcasecmp(fmt, "utc")) || (!strcasecmp(fmt, "zulu")))
- {
- if (NULL == gmtime_r(&tick, &stm)) return NULL;
- asprintf(&out, "%d-%02d-%02d %02d:%02d:%02dZ", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec);
- return out;
- }
-
- if ((fmt[1] == '\0') && (((fmt[0] >= 'a') && (fmt[0] <= 'z')) || ((fmt[0] >= 'A') && (fmt[0] <= 'Z'))))
- {
- char z = fmt[0];
- if (z >= 'a') z -= 32;
-
- if (z == 'Z') off = 0;
- else if ((z >= 'A') && (z <= 'I')) off = ((z - 'A') + 1) * SEC_PER_HOUR;
- else if ((z >= 'K') && (z <= 'M')) off = (z - 'A') * SEC_PER_HOUR;
- else if ((z >= 'N') && (z <= 'Y')) off = ('M' - z) * SEC_PER_HOUR;
- else return NULL;
- }
- else
- {
- if ((*p == '-') || (*p == '+')) p++;
- if ((*p) >= '0' && (*p <= '9'))
- {
- off = atoi(p);
- if (fmt[0] == '-') off *= -1;
- off *= SEC_PER_HOUR;
-
- p = strchr(p, ':');
- if (p != NULL)
- {
- min = atoi(p + 1);
- if (fmt[0] == '-') min *= -1;
- min *= 60;
- off += min;
- }
- }
- else
- {
- return NULL;
- }
- }
-
- tick += off;
-
- memset(&stm, 0, sizeof (struct tm));
- if (NULL == gmtime_r(&tick, &stm)) return NULL;
-
- if ((fmt[0] >= 'A') && (fmt[0] <= 'Z'))
- {
- asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d%c", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, fmt[0]);
- }
- else if ((fmt[0] >= 'a') && (fmt[0] <= 'z'))
- {
- asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d%c", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, fmt[0] - 32);
- }
- else if ((fmt[0] >= '0') && (fmt[0] <= '9'))
- {
- asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d+%s", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, fmt);
- }
- else
- {
- asprintf(&out, "%d-%02d-%02d %02d:%02d:%02d%s", stm.tm_year + 1900, stm.tm_mon + 1, stm.tm_mday, stm.tm_hour, stm.tm_min, stm.tm_sec, fmt);
- }
-
- return out;
-}
-
-/* called from asl_format_message and _asl_send_message */
-__private_extern__ asl_string_t *
-asl_msg_to_string_raw(uint32_t encoding, asl_msg_t *msg, const char *tfmt)
-{
- uint32_t i, x, count;
- char *vtime;
- const char *key, *val;
- asl_string_t *str;
-
- if (msg == NULL) return NULL;
-
- count = asl_msg_count(msg);
- if (count == 0) return NULL;
-
- str = asl_string_new(encoding);
- if (str == NULL) return NULL;
-
- key = NULL;
- val = NULL;
- i = 0;
-
- for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL))
- {
- if (key == NULL) continue;
-
- if (i > 0) asl_string_append_char_no_encoding(str, ' ');
-
- asl_string_append_char_no_encoding(str, '[');
- asl_string_append_asl_key(str, key);
-
- if (!strcmp(key, ASL_KEY_TIME))
- {
- asl_string_append_char_no_encoding(str, ' ');
- vtime = NULL;
-
- if (val != NULL) vtime = _asl_time_string(tfmt, val);
-
- if (vtime != NULL)
- {
- asl_string_append_no_encoding(str, vtime);
- free(vtime);
- }
- else
- {
- asl_string_append_char_no_encoding(str, '0');
- }
- }
- else if (val != NULL)
- {
- asl_string_append_char_no_encoding(str, ' ');
- asl_string_append(str, val);
- }
-
- asl_string_append_char_no_encoding(str, ']');
-
- i++;
- }
-
- return str;
-}
-
-static asl_string_t *
-_asl_string_append_asl_msg(asl_string_t *str, asl_msg_t *msg)
-{
- const char *key, *val;
- uint32_t i, op, n;
-
- if (msg == NULL) return str;
-
- if (msg->type == ASL_TYPE_QUERY) asl_string_append(str, "Q ");
-
- i = 0;
- n = 0;
-
- forever
- {
- key = NULL;
- val = NULL;
-
- i = asl_msg_fetch(msg, i, &key, &val, &op);
- if (key != NULL)
- {
- if (n != 0) asl_string_append_char_no_encoding(str, ' ');
- n++;
-
- asl_string_append_char_no_encoding(str, '[');
-
- if (msg->type == ASL_TYPE_QUERY)
- {
- asl_string_append_op(str, op);
- asl_string_append_char_no_encoding(str, ' ');
- }
-
- asl_string_append_asl_key(str, key);
-
- if (val != NULL)
- {
- asl_string_append_char_no_encoding(str, ' ');
- asl_string_append(str, val);
- }
-
- asl_string_append_char_no_encoding(str, ']');
- }
-
- if (i == IndexNull) break;
- }
-
- return str;
-}
-
-char *
-asl_msg_to_string(asl_msg_t *msg, uint32_t *len)
-{
- char *out;
- asl_string_t *str = asl_string_new(ASL_ENCODE_ASL);
- if (str == NULL) return NULL;
-
- str = _asl_string_append_asl_msg(str, msg);
- *len = asl_string_length(str);
- out = asl_string_free_return_bytes(str);
- return out;
-}
-
-static uint32_t
-_asl_msg_op_from_string(char *o)
-{
- uint32_t op, i;
-
- op = ASL_QUERY_OP_NULL;
-
- if (o == NULL) return op;
-
- for (i = 0; o[i] != '\0'; i++)
- {
- if (o[i] == '.') return ASL_QUERY_OP_NULL;
- if (o[i] == 'C') op |= ASL_QUERY_OP_CASEFOLD;
- if (o[i] == 'R') op |= ASL_QUERY_OP_REGEX;
- if (o[i] == 'N') op |= ASL_QUERY_OP_NUMERIC;
- if (o[i] == 'S') op |= ASL_QUERY_OP_SUBSTRING;
- if (o[i] == 'A') op |= ASL_QUERY_OP_PREFIX;
- if (o[i] == 'Z') op |= ASL_QUERY_OP_SUFFIX;
- if (o[i] == '<') op |= ASL_QUERY_OP_LESS;
- if (o[i] == '>') op |= ASL_QUERY_OP_GREATER;
- if (o[i] == '=') op |= ASL_QUERY_OP_EQUAL;
- if (o[i] == '!') op |= ASL_QUERY_OP_NOT_EQUAL;
- if (o[i] == 'T') op |= ASL_QUERY_OP_TRUE;
- }
-
- return op;
-}
-
-static char *
-_asl_msg_get_next_word(char **p, uint32_t *tt, uint32_t spacedel)
-{
- char *str, *out, c, oval;
- uint32_t i, len, n, outlen;
-
- *tt = TOKEN_NULL;
-
- if (p == NULL) return NULL;
- if (*p == NULL) return NULL;
- if (**p == '\0') return NULL;
-
- /* skip one space if it's there (word separator) */
- if (**p == ' ') (*p)++;
-
- /* skip leading white space */
- if (spacedel != 0)
- {
- while ((**p == ' ') || (**p == '\t')) (*p)++;
- }
-
- if (**p == '\0') return NULL;
- if (**p == '\n') return NULL;
-
- str = *p;
-
- /* opening [ */
- if (**p == '[')
- {
- *tt = TOKEN_OPEN;
-
- (*p)++;
- out = malloc(2);
- if (out == NULL) return NULL;
-
- out[0] = '[';
- out[1] = '\0';
- return out;
- }
-
- /* scan for token and calulate it's length (input and decoded output len) */
- len = 0;
- outlen = 0;
-
- forever
- {
- c = str[len];
-
- /* stop scanning when we hit a delimiter */
- if (((spacedel != 0) && (c == ' ')) || (c == ']') || (c == '\0')) break;
-
- if (c == '\\')
- {
- len++;
- c = str[len];
- if ((c == 'a') || (c == 'b') || (c == 't') || (c == 'n') || (c == 'v') || (c == 'f') || (c == 'r') || (c == 's') || (c == '[') || (c == '\\') || (c == ']'))
- {
- }
- else if (c == '^')
- {
- if (str[++len] == '\0') return NULL;
- }
- else if (c == 'M')
- {
- if (str[++len] == '\0') return NULL;
- if (str[++len] == '\0') return NULL;
- }
- else if ((c >= '0') && (c <= '3'))
- {
- if (str[++len] == '\0') return NULL;
- if (str[++len] == '\0') return NULL;
- }
- else
- {
- return NULL;
- }
- }
-
- len++;
- outlen++;
- }
-
- (*p) += len;
-
- if ((len == 0) && (**p == ']'))
- {
- *tt = TOKEN_CLOSE;
- (*p)++;
- out = malloc(2);
- if (out == NULL) return NULL;
-
- out[0] = ']';
- out[1] = '\0';
- return out;
- }
-
- *tt = TOKEN_INT;
-
- out = malloc(outlen + 1);
- if (out == NULL) return NULL;
-
- n = 0;
- for (i = 0; i < len; i++)
- {
- c = str[i];
-
- if (c == '\\')
- {
- *tt = TOKEN_WORD;
-
- i++;
- c = str[i];
- if (c == 'a')
- {
- out[n++] = '\a';
- }
- else if (c == 'b')
- {
- out[n++] = '\b';
- }
- else if (c == 't')
- {
- out[n++] = '\t';
- }
- else if (c == 'n')
- {
- out[n++] = '\n';
- }
- else if (c == 'v')
- {
- out[n++] = '\v';
- }
- else if (c == 'f')
- {
- out[n++] = '\f';
- }
- else if (c == 'r')
- {
- out[n++] = '\r';
- }
- else if (c == 's')
- {
- out[n++] = ' ';
- }
- else if (c == '[')
- {
- out[n++] = '[';
- }
- else if (c == '\\')
- {
- out[n++] = '\\';
- }
- else if (c == ']')
- {
- out[n++] = ']';
- }
- else if (c == '^')
- {
- i++;
- if (str[i] == '?') out[n++] = 127;
- else out[n++] = str[i] - 64;
- }
- else if (c == 'M')
- {
- i++;
- c = str[i];
- if (c == '^')
- {
- i++;
- if (str[i] == '?') out[n++] = 255;
- else out[n++] = str[i] + 64;
- }
- else if (c == '-')
- {
- i++;
- out[n++] = str[i] + 128;
- }
- else
- {
- *tt = TOKEN_NULL;
- free(out);
- return NULL;
- }
-
- }
- else if ((c >= '0') && (c <= '3'))
- {
- oval = (c - '0') * 64;
-
- i++;
- c = str[i];
- if ((c < '0') || (c > '7'))
- {
- *tt = TOKEN_NULL;
- free(out);
- return NULL;
- }
-
- oval += ((c - '0') * 8);
-
- i++;
- c = str[i];
- if ((c < '0') || (c > '7'))
- {
- *tt = TOKEN_NULL;
- free(out);
- return NULL;
- }
-
- oval += (c - '0');
-
- out[n++] = oval;
- }
- else
- {
- *tt = TOKEN_NULL;
- free(out);
- return NULL;
- }
- }
- else
- {
-
- if ((c < '0') || (c > '9')) *tt = TOKEN_WORD;
- out[n++] = c;
- }
- }
-
- out[n] = '\0';
-
- return out;
-}
-
-asl_msg_t *
-asl_msg_from_string(const char *buf)
-{
- uint32_t tt, type, op;
- char *k, *v, *o, *p;
- asl_msg_t *out;
-
- if (buf == NULL) return NULL;
-
- type = ASL_TYPE_MSG;
- p = (char *)buf;
-
- k = _asl_msg_get_next_word(&p, &tt, 1);
- if (k == NULL) return NULL;
-
- if (streq(k, "Q"))
- {
- type = ASL_TYPE_QUERY;
- free(k);
-
- k = _asl_msg_get_next_word(&p, &tt, 1);
- }
- else if (tt == TOKEN_INT)
- {
- /* Leading integer is a string length - skip it */
- free(k);
- k = _asl_msg_get_next_word(&p, &tt, 1);
- if (k == NULL) return NULL;
- }
-
- out = asl_msg_new(ASL_TYPE_MSG);
- if (out == NULL) return NULL;
-
- out->type = type;
-
- /* OPEN WORD [WORD [WORD]] CLOSE */
- while (k != NULL)
- {
- op = ASL_QUERY_OP_NULL;
-
- if (tt != TOKEN_OPEN)
- {
- asl_msg_release(out);
- return NULL;
- }
-
- free(k);
-
- /* get op for query type */
- if (type == ASL_TYPE_QUERY)
- {
- o = _asl_msg_get_next_word(&p, &tt, 1);
- if ((o == NULL) || (tt != TOKEN_WORD))
- {
- if (o != NULL) free(o);
- asl_msg_release(out);
- return NULL;
- }
-
- op = _asl_msg_op_from_string(o);
- free(o);
- }
-
- k = _asl_msg_get_next_word(&p, &tt, 1);
- if (tt == TOKEN_INT) tt = TOKEN_WORD;
- if ((k == NULL) || (tt != TOKEN_WORD))
- {
- if (k != NULL) free(k);
- asl_msg_release(out);
- return NULL;
- }
-
- v = _asl_msg_get_next_word(&p, &tt, 0);
- if (tt == TOKEN_INT) tt = TOKEN_WORD;
- if (v == NULL)
- {
- asl_msg_set_key_val_op(out, k, NULL, op);
- free(k);
- break;
- }
-
- if (tt == TOKEN_CLOSE)
- {
- asl_msg_set_key_val_op(out, k, NULL, op);
- }
- else if (tt == TOKEN_WORD)
- {
- asl_msg_set_key_val_op(out, k, v, op);
- }
- else
- {
- if (k != NULL) free(k);
- if (v != NULL) free(v);
- asl_msg_release(out);
- return NULL;
- }
-
- if (k != NULL) free(k);
- if (v != NULL) free(v);
-
- if (tt != TOKEN_CLOSE)
- {
- k = _asl_msg_get_next_word(&p, &tt, 1);
- if (k == NULL) break;
-
- if (tt != TOKEN_CLOSE)
- {
- asl_msg_release(out);
- return NULL;
- }
-
- free(k);
- }
-
- k = _asl_msg_get_next_word(&p, &tt, 1);
- if (k == NULL) break;
- }
-
- return out;
-}
-
-char *
-asl_list_to_string(asl_search_result_t *list, uint32_t *len)
-{
- uint32_t i;
- char tmp[16];
- char *out;
- asl_string_t *str = asl_string_new(ASL_ENCODE_ASL);
- if (str == NULL) return NULL;
-
- if (list == NULL) return NULL;
- if (list->count == 0) return NULL;
- if (list->msg == NULL) return NULL;
-
- snprintf(tmp, sizeof(tmp), "%u", list->count);
- asl_string_append(str, tmp);
- asl_string_append_char_no_encoding(str, '\n');
-
- for (i = 0; i < list->count; i++)
- {
- _asl_string_append_asl_msg(str, list->msg[i]);
- asl_string_append_char_no_encoding(str, '\n');
- }
-
- *len = asl_string_length(str);
- out = asl_string_free_return_bytes(str);
- return out;
-}
-
-asl_search_result_t *
-asl_list_from_string(const char *buf)
-{
- uint32_t i, n;
- const char *p;
- asl_search_result_t *out;
- asl_msg_t *m;
-
- if (buf == NULL) return NULL;
- p = buf;
-
- n = atoi(buf);
- if (n == 0) return NULL;
-
- out = (asl_search_result_t *)calloc(1, sizeof(asl_search_result_t));
- if (out == NULL) return NULL;
-
- out->msg = (asl_msg_t **)calloc(n, sizeof(asl_msg_t *));
- if (out->msg == NULL)
- {
- free(out);
- return NULL;
- }
-
- for (i = 0; i < n; i++)
- {
- p = strchr(p, '\n');
- if (p == NULL)
- {
- aslresponse_free((aslresponse)out);
- return NULL;
- }
-
- p++;
-
- m = asl_msg_from_string(p);
- if (m == NULL)
- {
- aslresponse_free((aslresponse)out);
- return NULL;
- }
-
- out->msg[i] = (asl_msg_t *)m;
- out->count += 1;
- }
-
- return out;
-}
-
-static const char *
-_asl_level_string(int level)
-{
- if (level == ASL_LEVEL_EMERG) return ASL_STRING_EMERG;
- if (level == ASL_LEVEL_ALERT) return ASL_STRING_ALERT;
- if (level == ASL_LEVEL_CRIT) return ASL_STRING_CRIT;
- if (level == ASL_LEVEL_ERR) return ASL_STRING_ERR;
- if (level == ASL_LEVEL_WARNING) return ASL_STRING_WARNING;
- if (level == ASL_LEVEL_NOTICE) return ASL_STRING_NOTICE;
- if (level == ASL_LEVEL_INFO) return ASL_STRING_INFO;
- if (level == ASL_LEVEL_DEBUG) return ASL_STRING_DEBUG;
- return "unknown";
-}
-
-/*
- * Find the value for a key in a message and append a formatted value to str.
- * kf may be a simple (no embedded white space) key, or one of (key) or ((key)(format)).
- * WARNING: modifies kf!
- */
-static asl_string_t *
-_asl_string_append_value_for_key_format(asl_string_t *str, asl_msg_t *msg, char *kf, const char *tfmt)
-{
- uint32_t i, get_fmt;
- char *key, *fmt;
- const char *mval;
-
- if (str == NULL) return NULL;
- if (msg == NULL) return str;
- if (kf == NULL) return str;
-
- key = NULL;
- fmt = NULL;
- get_fmt = 0;
-
- for (i = 0; kf[i] != '\0'; i++)
- {
- if (kf[i] == ')')
- {
- kf[i] = '\0';
- get_fmt = 1;
- }
- else if (kf[i] != '(')
- {
- if (key == NULL) key = kf + i;
- else if ((get_fmt == 1) && (fmt == NULL)) fmt = kf + i;
- }
- }
-
- if (key == NULL) return str;
-
- asl_msg_lookup(msg, key, &mval, NULL);
- if (mval == NULL) return str;
-
- if (!strcmp(key, ASL_KEY_TIME))
- {
- char *fval = NULL;
-
- /* format in $((Time)(fmt)) overrides tfmt */
- if (fmt == NULL)
- {
- fval = _asl_time_string(tfmt, mval);
- }
- else
- {
- fval = _asl_time_string(fmt, mval);
- }
-
- if (fval != NULL)
- {
- asl_string_append_no_encoding(str, fval);
- free(fval);
- }
- else
- {
- asl_string_append_char_no_encoding(str, '0');
- }
-
- return str;
- }
-
- /* Level: num str */
- if (!strcmp(key, ASL_KEY_LEVEL))
- {
- if (fmt == NULL)
- {
- asl_string_append_no_encoding(str, mval);
- }
- else if (!strcmp(fmt, "str"))
- {
- mval = _asl_level_string(atoi(mval));
- asl_string_append_no_encoding(str, mval);
- }
- else
- {
- asl_string_append_no_encoding(str, mval);
- }
-
- return str;
- }
-
- return asl_string_append(str, mval);
-}
-
-/*
- * format a message for printing
- * out parameter len returns string length including trailing NUL
- */
-char *
-asl_format_message(asl_msg_t *msg, const char *mfmt, const char *tfmt, uint32_t text_encoding, uint32_t *len)
-{
- char *out, *vtime, *k, c, skey[512];
- const char *vhost, *vpid, *vsender, *vmessage, *vlevel, *vrefproc, *vrefpid, *v, *key, *val;
- int i, j, l, mf, paren, oval, level;
- uint32_t x, cursor;
- asl_string_t *str;
- uint8_t *b64;
-
- out = NULL;
- *len = 0;
-
- if (msg == NULL) return NULL;
-
- mf = MFMT_RAW;
-
- if (mfmt == NULL) mf = MFMT_RAW;
- else if (!strcmp(mfmt, ASL_MSG_FMT_RAW)) mf = MFMT_RAW;
- else if (!strcmp(mfmt, ASL_MSG_FMT_STD)) mf = MFMT_STD;
- else if (!strcmp(mfmt, ASL_MSG_FMT_BSD)) mf = MFMT_BSD;
- else if (!strcmp(mfmt, ASL_MSG_FMT_XML)) mf = MFMT_XML;
- else if (!strcmp(mfmt, ASL_MSG_FMT_MSG)) mf = MFMT_MSG;
- else mf = MFMT_STR;
-
- if (mf == MFMT_RAW)
- {
- str = asl_msg_to_string_raw(text_encoding, msg, tfmt);
- asl_string_append_char_no_encoding(str, '\n');
-
- *len = asl_string_length(str);
- out = asl_string_free_return_bytes(str);
- return out;
- }
-
- if (mf == MFMT_MSG)
- {
- vmessage = NULL;
-
- if (asl_msg_lookup(msg, ASL_KEY_MSG, &vmessage, NULL) != 0) return NULL;
-
- str = asl_string_new(text_encoding);
- if (str == NULL) return NULL;
-
- asl_string_append(str, vmessage);
- asl_string_append_char_no_encoding(str, '\n');
-
- *len = asl_string_length(str);
- out = asl_string_free_return_bytes(str);
- return out;
- }
-
- if ((mf == MFMT_STD) || (mf == MFMT_BSD))
- {
- /* COMMON: Mth dd hh:mm:ss host sender[pid] (refproc[refpid])*/
- /* BSD: <COMMON>: message */
- /* STD: <COMMON> <Level>: message */
-
- v = NULL;
- vhost = NULL;
- vsender = NULL;
- vpid = NULL;
- vmessage = NULL;
- vlevel = NULL;
- vrefproc = NULL;
- vrefpid = NULL;
-
- asl_msg_lookup(msg, ASL_KEY_TIME, &v, NULL);
- vtime = _asl_time_string(tfmt, v);
-
- level = 7;
- asl_msg_lookup(msg, ASL_KEY_LEVEL, &vlevel, NULL);
- if (vlevel != NULL) level = atoi(vlevel);
-
- asl_msg_lookup(msg, ASL_KEY_HOST, &vhost, NULL);
- if (vhost == NULL) vhost = "unknown";
-
- asl_msg_lookup(msg, ASL_KEY_SENDER, &vsender, NULL);
- if (vsender == NULL) vsender = "unknown";
-
- asl_msg_lookup(msg, ASL_KEY_PID, &vpid, NULL);
- asl_msg_lookup(msg, ASL_KEY_MSG, &vmessage, NULL);
- asl_msg_lookup(msg, ASL_KEY_REF_PROC, &vrefproc, NULL);
- asl_msg_lookup(msg, ASL_KEY_REF_PID, &vrefpid, NULL);
-
- /* COMMON */
- str = asl_string_new(text_encoding);
- if (str == NULL) return NULL;
-
- if (vtime != NULL)
- {
- asl_string_append(str, vtime);
- free(vtime);
- }
- else
- {
- asl_string_append_char_no_encoding(str, '0');
- }
-
- asl_string_append_char_no_encoding(str, ' ');
- asl_string_append(str, vhost);
- asl_string_append_char_no_encoding(str, ' ');
- asl_string_append(str, vsender);
-
- if ((vpid != NULL) && (strcmp(vpid, "-1")))
- {
- asl_string_append_char_no_encoding(str, '[');
- asl_string_append(str, vpid);
- asl_string_append_char_no_encoding(str, ']');
- }
-
- if ((vrefproc != NULL) || (vrefpid != NULL)) asl_string_append_no_encoding(str, " (");
-
- if (vrefproc != NULL) asl_string_append(str, vrefproc);
- if (vrefpid != NULL)
- {
- asl_string_append_char_no_encoding(str, '[');
- asl_string_append(str, vrefpid);
- asl_string_append_char_no_encoding(str, ']');
- }
-
- if ((vrefproc != NULL) || (vrefpid != NULL)) asl_string_append_char_no_encoding(str, ')');
-
- if (mf == MFMT_STD)
- {
- asl_string_append_no_encoding(str, " <");
- asl_string_append(str, _asl_level_string(level));
- asl_string_append_char_no_encoding(str, '>');
- }
-
- asl_string_append_no_encoding(str, ": ");
- if (vmessage != NULL) asl_string_append(str, vmessage);
- asl_string_append_char_no_encoding(str, '\n');
-
- *len = asl_string_length(str);
- out = asl_string_free_return_bytes(str);
- return out;
- }
-
- if (mf == MFMT_XML)
- {
- str = asl_string_new(text_encoding);
- if (str == NULL) return NULL;
-
- asl_string_append_char_no_encoding(str, '\t');
- asl_string_append(str, "<dict>");
- asl_string_append_char_no_encoding(str, '\n');
-
- for (x = asl_msg_fetch(msg, 0, &key, &val, NULL); x != IndexNull; x = asl_msg_fetch(msg, x, &key, &val, NULL))
- {
- if (asl_is_utf8(key) == 1)
- {
- asl_string_append_xml_tag(str, "key", key);
- if (!strcmp(key, ASL_KEY_TIME))
- {
- vtime = _asl_time_string(tfmt, val);
- if (vtime != NULL)
- {
- asl_string_append_xml_tag(str, "string", vtime);
- free(vtime);
- }
- else
- {
- asl_string_append_xml_tag(str, "string", "0");
- }
- }
- else
- {
- if (asl_is_utf8(val) == 1) asl_string_append_xml_tag(str, "string", val);
- else
- {
- b64 = asl_b64_encode((uint8_t *)val, strlen(val));
- asl_string_append_xml_tag(str, "data", (char *)b64);
- free(b64);
- }
- }
- }
- }
-
- asl_string_append_char_no_encoding(str, '\t');
- asl_string_append(str, "</dict>");
- asl_string_append_char_no_encoding(str, '\n');
-
- *len = asl_string_length(str);
- out = asl_string_free_return_bytes(str);
- return out;
- }
-
- /*
- * Custom format
- * The format string may contain arbitrary characters.
- * Keys are identified by $Key or $(Key). The value for
- * that key is substituted. If there are alterate formats
- * for the value (for example a time may be formatted as
- * raw seconds, in UTC, or a local timezone), then the
- * key may be $((Key)(Format)). "\$" prints a plain "$".
- */
-
- str = asl_string_new(text_encoding);
- if (str == NULL) return NULL;
-
- /*
- * We need enough space to copy any keys found in mfmt.
- * The key obviously can't be longer than strlen(mfmt),
- * in fact, keys must be shorter, since there's at least a '$'
- * in front of the key, so we allocate a buffer with strlen(mfmt).
- * If strlen(mfmt) <= sizeof(skey), we use skey to avoid a malloc.
- */
-
- x = strlen(mfmt);
- if (x <= sizeof(skey))
- {
- k = skey;
- }
- else
- {
- k = malloc(x);
- if (k == NULL) return NULL;
- }
-
- cursor = 0;
-
- for (i = 0; mfmt[i] != '\0'; i++)
- {
- if (mfmt[i] == '$')
- {
- paren = 0;
-
- /* scan key, (key) or ((key)(format)) */
- for (j = i + 1; mfmt[j] != 0; j++)
- {
- if (mfmt[j] == '(')
- {
- paren++;
- }
- else if (mfmt[j] == ')')
- {
- if (paren > 0) paren--;
- if (paren == 0)
- {
- j++;
- break;
- }
- }
- else if (((mfmt[j] == ' ') || (mfmt[j] == '\t')) && (paren == 0)) break;
- }
-
- /* mfmt[i + 1] is the first char of the key or a '('. mfmt[j] is one char past the end. */
- l = j - (i + 1);
- memcpy(k, mfmt+i+1, l);
- k[l] = '\0';
- _asl_string_append_value_for_key_format(str, msg, k, tfmt);
-
- i = j - 1;
- continue;
- }
-
- if (mfmt[i] == '\\')
- {
- i++;
- if (mfmt[i] == '$') asl_string_append_char_no_encoding(str, '$');
- else if (mfmt[i] == 'e') asl_string_append_char_no_encoding(str, '\e');
- else if (mfmt[i] == 's') asl_string_append_char_no_encoding(str, ' ');
- else if (mfmt[i] == 'a') asl_string_append_char_no_encoding(str, '\a');
- else if (mfmt[i] == 'b') asl_string_append_char_no_encoding(str, '\b');
- else if (mfmt[i] == 'f') asl_string_append_char_no_encoding(str, '\f');
- else if (mfmt[i] == 'n') asl_string_append_char_no_encoding(str, '\n');
- else if (mfmt[i] == 'r') asl_string_append_char_no_encoding(str, '\r');
- else if (mfmt[i] == 't') asl_string_append_char_no_encoding(str, '\t');
- else if (mfmt[i] == 'v') asl_string_append_char_no_encoding(str, '\v');
- else if (mfmt[i] == '\'') asl_string_append_char_no_encoding(str, '\'');
- else if (mfmt[i] == '\\') asl_string_append_char_no_encoding(str, '\\');
- else if (isdigit(mfmt[i]))
- {
- oval = mfmt[i] - '0';
- if (isdigit(mfmt[i+1]))
- {
- i++;
- oval = (oval * 8) + (mfmt[i] - '0');
- if (isdigit(mfmt[i+1]))
- {
- i++;
- oval = (oval * 8) + (mfmt[i] - '0');
- }
- }
- c = oval;
- asl_string_append_char_no_encoding(str, c);
- }
- continue;
- }
-
- if (mfmt[i] == '\0') break;
- asl_string_append_char_no_encoding(str, mfmt[i]);
- }
-
- if (k != skey) free(k);
-
- asl_string_append_char_no_encoding(str, '\n');
-
- *len = asl_string_length(str);
- out = asl_string_free_return_bytes(str);
- return out;
-}
-
-/*
- * OLD ASLMSG COMPATIBILITY
- */
-const char *
-asl_key(aslmsg msg, uint32_t n)
-{
- uint32_t slot, i;
- asl_msg_t *page;
-
- i = 0;
- for (page = (asl_msg_t *)msg; page != NULL; page = page->next)
- {
- for (slot = 0; slot < ASL_MSG_PAGE_SLOTS; slot++)
- {
- if (page->key[slot] != ASL_MSG_SLOT_FREE)
- {
- if (i == n) return _asl_msg_slot_key(page, slot);
- i++;
- }
- }
- }
-
- return NULL;
-}
-
-aslmsg
-asl_new(uint32_t type)
-{
- return (aslmsg)asl_msg_new(type);
-}
-
-int
-asl_set(aslmsg msg, const char *key, const char *value)
-{
- return asl_msg_set_key_val_op((asl_msg_t *)msg, key, value, IndexNull);
-}
-
-int
-asl_set_query(aslmsg msg, const char *key, const char *value, uint32_t op)
-{
- return asl_msg_set_key_val_op((asl_msg_t *)msg, key, value, op);
-}
-
-int
-asl_unset(aslmsg msg, const char *key)
-{
- asl_msg_unset((asl_msg_t *)msg, key);
- return 0;
-}
-
-const char *
-asl_get(aslmsg msg, const char *key)
-{
- const char *val;
- int status;
-
- val = NULL;
- status = asl_msg_lookup((asl_msg_t *)msg, key, &val, NULL);
- if (status != 0) return NULL;
- return val;
-}
-
-void
-asl_free(aslmsg msg)
-{
- asl_msg_release((asl_msg_t *)msg);
-}
-
-/* aslresponse */
-
-/*
- * aslresponse_next: Iterate over responses returned from asl_search()
- * a: a response returned from asl_search();
- * returns: The next log message (an aslmsg) or NULL on failure
- */
-aslmsg
-aslresponse_next(aslresponse r)
-{
- asl_search_result_t *res;
- asl_msg_t *m;
-
- res = (asl_search_result_t *)r;
- if (res == NULL) return NULL;
-
- if (res->curr >= res->count) return NULL;
- m = res->msg[res->curr];
- res->curr++;
-
- return (aslmsg)m;
-}
-
-/*
- * aslresponse_free: Free a response returned from asl_search()
- * a: a response returned from asl_search()
- */
-void
-aslresponse_free(aslresponse r)
-{
- asl_search_result_t *res;
- uint32_t i;
-
- res = (asl_search_result_t *)r;
- if (res == NULL) return;
-
- for (i = 0; i < res->count; i++) asl_msg_release(res->msg[i]);
- free(res->msg);
- free(res);
-}
+++ /dev/null
-/*
- * Copyright (c) 2009-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __ASL_MSG_H__
-#define __ASL_MSG_H__
-
-#include <stdint.h>
-#include <asl_private.h>
-
-#define IndexNull ((uint32_t)-1)
-
-#define ASL_MSG_PAGE_DATA_SIZE 800
-#define ASL_MSG_PAGE_SLOTS 24
-
-#define ASL_MSG_OFFSET_MASK 0x3fff
-#define ASL_MSG_KV_MASK 0xc000
-#define ASL_MSG_KV_INLINE 0x0000
-#define ASL_MSG_KV_DICT 0x8000
-#define ASL_MSG_KV_EXTERN 0x4000
-
-#define ASL_MSG_SLOT_FREE 0xffff
-
-#define ASL_STD_KEY_BASE 0x8000
-#define ASL_STD_KEY_TIME 0x8001
-#define ASL_STD_KEY_NANO 0x8002
-#define ASL_STD_KEY_HOST 0x8003
-#define ASL_STD_KEY_SENDER 0x8004
-#define ASL_STD_KEY_FACILITY 0x8005
-#define ASL_STD_KEY_PID 0x8006
-#define ASL_STD_KEY_UID 0x8007
-#define ASL_STD_KEY_GID 0x8008
-#define ASL_STD_KEY_LEVEL 0x8009
-#define ASL_STD_KEY_MESSAGE 0x800a
-#define ASL_STD_KEY_READ_UID 0x800b
-#define ASL_STD_KEY_READ_GID 0x800c
-#define ASL_STD_KEY_SESSION 0x800d
-#define ASL_STD_KEY_REF_PID 0x800e
-#define ASL_STD_KEY_REF_PROC 0x800f
-#define ASL_STD_KEY_MSG_ID 0x8010
-#define ASL_STD_KEY_EXPIRE 0x8011
-#define ASL_STD_KEY_OPTION 0x8012
-#define ASL_STD_KEY_LAST ASL_STD_KEY_OPTION
-
-#define ASL_MT_KEY_BASE 0x8100
-#define ASL_MT_KEY_DOMAIN 0x8101
-#define ASL_MT_KEY_SCOPE 0x8102
-#define ASL_MT_KEY_RESULT 0x8103
-#define ASL_MT_KEY_SIG 0x8104
-#define ASL_MT_KEY_SIG2 0x8105
-#define ASL_MT_KEY_SIG3 0x8106
-#define ASL_MT_KEY_SUCCESS 0x8107
-#define ASL_MT_KEY_UUID 0x8108
-#define ASL_MT_KEY_VAL 0x8109
-#define ASL_MT_KEY_VAL2 0x810a
-#define ASL_MT_KEY_VAL3 0x810b
-#define ASL_MT_KEY_VAL4 0x810c
-#define ASL_MT_KEY_VAL5 0x810d
-#define ASL_MT_KEY_LAST ASL_MT_KEY_VAL5
-
-#define ASL_PRIVATE_KEY_BASE 0x8200
-
-typedef struct asl_msg_s
-{
- uint32_t type;
- int32_t refcount;
- uint32_t count;
- uint32_t data_size;
- struct asl_msg_s *next;
- uint16_t key[ASL_MSG_PAGE_SLOTS];
- uint16_t val[ASL_MSG_PAGE_SLOTS];
- uint32_t op[ASL_MSG_PAGE_SLOTS];
- char data[ASL_MSG_PAGE_DATA_SIZE];
-} asl_msg_t;
-
-typedef struct __aslresponse
-{
- uint32_t count;
- uint32_t curr;
- asl_msg_t **msg;
-} asl_msg_list_t;
-
-#define asl_search_result_t asl_msg_list_t
-
-asl_msg_t *asl_msg_new(uint32_t type) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-asl_msg_t *asl_msg_retain(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-void asl_msg_release(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-
-int asl_msg_set_key_val(asl_msg_t *msg, const char *key, const char *val) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-int asl_msg_set_key_val_op(asl_msg_t *msg, const char *key, const char *val, uint32_t op) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-void asl_msg_unset(asl_msg_t *msg, const char *key) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-
-asl_msg_t *asl_msg_copy(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-asl_msg_t *asl_msg_merge(asl_msg_t *target, asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_5_1);
-
-int asl_msg_lookup(asl_msg_t *msg, const char *key, const char **valout, uint32_t *opout) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-uint32_t asl_msg_fetch(asl_msg_t *msg, uint32_t n, const char **keyout, const char **valout, uint32_t *opout) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-
-uint32_t asl_msg_type(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-uint32_t asl_msg_count(asl_msg_t *msg) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-
-char *asl_msg_to_string(asl_msg_t *in, uint32_t *len) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
-char *asl_list_to_string(asl_search_result_t *, uint32_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-asl_search_result_t *asl_list_from_string(const char *buf) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-char *asl_format_message(asl_msg_t *msg, const char *msg_fmt, const char *time_fmt, uint32_t text_encoding, uint32_t *outlen) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-#endif /* __ASL_MSG_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __ASL_PRIVATE_H__
-#define __ASL_PRIVATE_H__
-
-#include <stdint.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include "asl_file.h"
-#include "asl_msg.h"
-#include <Availability.h>
-
-#define ASL_QUERY_OP_NULL 0x00000
-
-#define NOTIFY_SYSTEM_MASTER "com.apple.system.syslog.master"
-#define NOTIFY_SYSTEM_ASL_FILTER "com.apple.system.syslog.asl_filter"
-#define NOTIFY_PREFIX_SYSTEM "com.apple.system.syslog"
-#define NOTIFY_PREFIX_USER "user.syslog"
-#define NOTIFY_RC "com.apple.asl.remote"
-
-#define ASL_MSG_FMT_RAW "raw"
-#define ASL_MSG_FMT_STD "std"
-#define ASL_MSG_FMT_BSD "bsd"
-#define ASL_MSG_FMT_XML "xml"
-#define ASL_MSG_FMT_MSG "msg"
-
-#define ASL_TIME_FMT_SEC "sec"
-#define ASL_TIME_FMT_UTC "utc"
-#define ASL_TIME_FMT_LCL "lcl"
-
-#define ASL_OPT_IGNORE "ignore"
-#define ASL_OPT_STORE "store"
-
-#define ASL_STORE_LOCATION_FILE 0
-#define ASL_STORE_LOCATION_MEMORY 1
-
-#define ASL_OPT_SYSLOG_LEGACY 0x00010000
-
-/* SPI to enable ASL filter tunneling using asl_set_filter() */
-#define ASL_FILTER_MASK_TUNNEL 0x100
-
-typedef struct __aslclient
-{
- uint32_t options;
- struct sockaddr_un server;
- int sock;
- pid_t pid;
- uid_t uid;
- gid_t gid;
- char *name;
- char *facility;
- uint32_t filter;
- int notify_token;
- int notify_master_token;
- uint32_t fd_count;
- int *fd_list;
- char **fd_mfmt;
- char **fd_tfmt;
- uint32_t *fd_encoding;
- asl_file_t *aslfile;
- uint64_t aslfileid;
- uint32_t reserved1;
- void *reserved2;
- int32_t refcount;
-} asl_client_t;
-
-__BEGIN_DECLS
-
-int asl_add_output(aslclient asl, int fd, const char *msg_fmt, const char *time_fmt, uint32_t text_encoding) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int asl_remove_output(aslclient asl, int fd) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int asl_store_location() __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-int asl_get_filter(aslclient asl, int *local, int *master, int *remote, int *active) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-char *asl_remote_notify_name() __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-
-__END_DECLS
-
-#endif /* __ASL_PRIVATE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <dirent.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <asl.h>
-#include <asl_private.h>
-#include <asl_core.h>
-#include <asl_store.h>
-#include <notify.h>
-
-extern time_t asl_parse_time(const char *str);
-extern uint64_t asl_file_cursor(asl_file_t *s);
-extern uint32_t asl_file_match_start(asl_file_t *s, uint64_t start_id, int32_t direction);
-extern uint32_t asl_file_match_next(asl_file_t *s, aslresponse query, asl_msg_t **msg, uint64_t *last_id, int32_t direction, int32_t ruid, int32_t rgid);
-extern int asl_file_create(const char *path, uid_t uid, gid_t gid, mode_t mode);
-
-#define SECONDS_PER_DAY 86400
-
-/*
- * The ASL Store is organized as a set of files in a common directory.
- * Files are prefixed by the date (YYYY.MM.DD) of their contents.
- *
- * Messages with no access controls are saved in YYYY.MM.DD.asl
- * Messages with access limited to UID uuu are saved in YYYY.MM.DD.Uuuu.asl
- * Messages with access limited to GID ggg are saved in YYYY.MM.DD.Gggg.asl
- * Messages with access limited to UID uuu and GID ggg are saved in YYYY.MM.DD.Uuuu.Gggg.asl
- *
- * Messages that have a value for ASLExpireTime are saved in BB.YYYY.MM.DD.asl
- * where the timestamp is the "Best Before" date of the file. Access controls
- * are implemented as above with Uuuu and Gggg in the file name. Note that the
- * Best Before files are for the last day of the month, so a single file contains
- * messages that expire in that month.
- *
- * An external tool runs daily and deletes "old" files.
- */
-
-static time_t
-_asl_start_today()
-{
- time_t now;
- struct tm ctm;
-
- memset(&ctm, 0, sizeof(struct tm));
- now = time(NULL);
-
- if (localtime_r((const time_t *)&now, &ctm) == NULL) return 0;
-
- ctm.tm_sec = 0;
- ctm.tm_min = 0;
- ctm.tm_hour = 0;
-
- return mktime(&ctm);
-}
-
-/*
- * The base directory contains a data file which stores
- * the last record ID.
- *
- * | MAX_ID (uint64_t) |
- *
- */
-uint32_t
-asl_store_open_write(const char *basedir, asl_store_t **s)
-{
- asl_store_t *out;
- struct stat sb;
- uint32_t i, flags;
- char *path;
- FILE *sd;
- uint64_t last_id;
- time_t start;
-
- if (s == NULL) return ASL_STATUS_INVALID_ARG;
-
- start = _asl_start_today();
- if (start == 0) return ASL_STATUS_FAILED;
-
- if (basedir == NULL) basedir = PATH_ASL_STORE;
-
- memset(&sb, 0, sizeof(struct stat));
- if (stat(basedir, &sb) != 0) return ASL_STATUS_INVALID_STORE;
- if (!S_ISDIR(sb.st_mode)) return ASL_STATUS_INVALID_STORE;
-
- path = NULL;
- asprintf(&path, "%s/%s", basedir, FILE_ASL_STORE_DATA);
- if (path == NULL) return ASL_STATUS_NO_MEMORY;
-
- sd = NULL;
-
- memset(&sb, 0, sizeof(struct stat));
- if (stat(path, &sb) != 0)
- {
- if (errno != ENOENT)
- {
- free(path);
- return ASL_STATUS_FAILED;
- }
-
- sd = fopen(path, "w+");
- free(path);
-
- if (sd == NULL) return ASL_STATUS_FAILED;
-
- last_id = 0;
-
- /* Create new StoreData file (8 bytes ID + 4 bytes flags) */
-
- if (fwrite(&last_id, sizeof(uint64_t), 1, sd) != 1)
- {
- fclose(sd);
- return ASL_STATUS_WRITE_FAILED;
- }
-
- flags = 0;
- if (fwrite(&flags, sizeof(uint32_t), 1, sd) != 1)
- {
- fclose(sd);
- return ASL_STATUS_WRITE_FAILED;
- }
-
- /* flush data */
- fflush(sd);
- }
- else
- {
- sd = fopen(path, "r+");
- free(path);
-
- if (sd == NULL) return ASL_STATUS_FAILED;
- if (fread(&last_id, sizeof(uint64_t), 1, sd) != 1)
- {
- fclose(sd);
- return ASL_STATUS_READ_FAILED;
- }
-
- last_id = asl_core_ntohq(last_id);
- }
-
- out = (asl_store_t *)calloc(1, sizeof(asl_store_t));
- if (out == NULL)
- {
- fclose(sd);
- return ASL_STATUS_NO_MEMORY;
- }
-
- if (basedir == NULL) out->base_dir = strdup(PATH_ASL_STORE);
- else out->base_dir = strdup(basedir);
-
- if (out->base_dir == NULL)
- {
- fclose(sd);
- free(out);
- return ASL_STATUS_NO_MEMORY;
- }
-
- out->start_today = start;
- out->start_tomorrow = out->start_today + SECONDS_PER_DAY;
- out->storedata = sd;
- out->next_id = last_id + 1;
-
- for (i = 0; i < FILE_CACHE_SIZE; i++)
- {
- memset(&out->file_cache[i], 0, sizeof(asl_cached_file_t));
- out->file_cache[i].u = -1;
- out->file_cache[i].g = -1;
- }
-
- *s = out;
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_store_statistics(asl_store_t *s, aslmsg *msg)
-{
- aslmsg out;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (msg == NULL) return ASL_STATUS_INVALID_ARG;
-
- out = asl_new(ASL_TYPE_MSG);
- if (out == NULL) return ASL_STATUS_NO_MEMORY;
-
- /* does nothing for now */
-
- *msg = out;
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_store_open_read(const char *basedir, asl_store_t **s)
-{
- asl_store_t *out;
- struct stat sb;
-
- if (s == NULL) return ASL_STATUS_INVALID_ARG;
-
- if (basedir == NULL) basedir = PATH_ASL_STORE;
-
- memset(&sb, 0, sizeof(struct stat));
- if (stat(basedir, &sb) != 0) return ASL_STATUS_INVALID_STORE;
- if (!S_ISDIR(sb.st_mode)) return ASL_STATUS_INVALID_STORE;
-
- out = (asl_store_t *)calloc(1, sizeof(asl_store_t));
- if (out == NULL) return ASL_STATUS_NO_MEMORY;
-
- if (basedir == NULL) out->base_dir = strdup(PATH_ASL_STORE);
- else out->base_dir = strdup(basedir);
-
- if (out->base_dir == NULL)
- {
- free(out);
- return ASL_STATUS_NO_MEMORY;
- }
-
- *s = out;
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_store_max_file_size(asl_store_t *s, size_t max)
-{
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
-
- s->max_file_size = max;
- return ASL_STATUS_OK;
-}
-
-__private_extern__ void
-asl_store_file_closeall(asl_store_t *s)
-{
- uint32_t i;
-
- if (s == NULL) return;
-
- for (i = 0; i < FILE_CACHE_SIZE; i++)
- {
- if (s->file_cache[i].f != NULL) asl_file_close(s->file_cache[i].f);
- s->file_cache[i].f = NULL;
- if (s->file_cache[i].path != NULL) free(s->file_cache[i].path);
- s->file_cache[i].path = NULL;
- s->file_cache[i].u = -1;
- s->file_cache[i].g = -1;
- s->file_cache[i].bb = 0;
- s->file_cache[i].ts = 0;
- }
-}
-
-uint32_t
-asl_store_close(asl_store_t *s)
-{
- if (s == NULL) return ASL_STATUS_OK;
-
- if (s->base_dir != NULL) free(s->base_dir);
- s->base_dir = NULL;
- asl_store_file_closeall(s);
- if (s->storedata != NULL) fclose(s->storedata);
-
- free(s);
-
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_store_signal_sweep(asl_store_t *s)
-{
- char *str;
- int semfd;
- uint64_t xid;
- uint32_t status;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
-
- asprintf(&str, "%s/%s", s->base_dir, FILE_ASL_STORE_SWEEP_SEMAPHORE);
- if (str == NULL) return ASL_STATUS_NO_MEMORY;
-
- semfd = open(str, O_WRONLY | O_CREAT | O_NONBLOCK, 0644);
- free(str);
-
- if (semfd < 0) return ASL_STATUS_WRITE_FAILED;
-
- status = ASL_STATUS_OK;
-
- /* write the current message ID in the SweepStore file */
- xid = asl_core_htonq(s->next_id - 1);
- if (write(semfd, &xid, sizeof(uint64_t)) != sizeof(uint64_t)) status = ASL_STATUS_WRITE_FAILED;
-
- close(semfd);
- return status;
-}
-
-/*
- * Sweep the file cache.
- * Close any files that have not been used in the last FILE_CACHE_TTL seconds.
- * Returns least recently used or unused cache slot.
- */
-static uint32_t
-asl_store_file_cache_lru(asl_store_t *s, time_t now, uint32_t ignorex)
-{
- time_t min;
- uint32_t i, x;
-
- if (s == NULL) return 0;
-
- x = 0;
- min = now - FILE_CACHE_TTL;
-
- for (i = 0; i < FILE_CACHE_SIZE; i++)
- {
- if ((i != ignorex) && (s->file_cache[i].ts < min))
- {
- asl_file_close(s->file_cache[i].f);
- s->file_cache[i].f = NULL;
- if (s->file_cache[i].path != NULL) free(s->file_cache[i].path);
- s->file_cache[i].path = NULL;
- s->file_cache[i].u = -1;
- s->file_cache[i].g = -1;
- s->file_cache[i].bb = 0;
- s->file_cache[i].ts = 0;
- }
-
- if (s->file_cache[i].ts < s->file_cache[x].ts) x = i;
- }
-
- return x;
-}
-
-uint32_t
-asl_store_sweep_file_cache(asl_store_t *s)
-{
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
-
- asl_store_file_cache_lru(s, time(NULL), FILE_CACHE_SIZE);
- return ASL_STATUS_OK;
-}
-
-static char *
-asl_store_make_ug_path(const char *dir, const char *base, const char *ext, uid_t ruid, gid_t rgid, uid_t *u, gid_t *g, mode_t *m)
-{
- char *path = NULL;
-
- *u = 0;
- *g = 0;
- *m = 0644;
-
- if (ruid == -1)
- {
- if (rgid == -1)
- {
- if (ext == NULL) asprintf(&path, "%s/%s", dir, base);
- else asprintf(&path, "%s/%s.%s", dir, base, ext);
- }
- else
- {
- *g = rgid;
- *m = 0600;
- if (ext == NULL) asprintf(&path, "%s/%s.G%d", dir, base, *g);
- else asprintf(&path, "%s/%s.G%d.%s", dir, base, *g, ext);
- }
- }
- else
- {
- *u = ruid;
- if (rgid == -1)
- {
- *m = 0600;
- if (ext == NULL) asprintf(&path, "%s/%s.U%d", dir, base, *u);
- else asprintf(&path, "%s/%s.U%d.%s", dir, base, *u, ext);
- }
- else
- {
- *g = rgid;
- *m = 0600;
- if (ext == NULL) asprintf(&path, "%s/%s.U%d.G%d", dir, base, *u, *g);
- else asprintf(&path, "%s/%s.U%d.G%u.%s", dir, base, *u, *g, ext);
- }
- }
-
- return path;
-}
-
-static uint32_t
-asl_store_file_open_write(asl_store_t *s, char *tstring, int32_t ruid, int32_t rgid, time_t bb, asl_file_t **f, time_t now, uint32_t check_cache)
-{
- char *path;
- mode_t m;
- int32_t i, x;
- uid_t u;
- gid_t g;
- uint32_t status;
- asl_file_t *out;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
-
- /* see if the file is already open and in the cache */
- for (i = 0; i < FILE_CACHE_SIZE; i++)
- {
- if ((s->file_cache[i].u == ruid) && (s->file_cache[i].g == rgid) && (s->file_cache[i].bb == bb) && (s->file_cache[i].f != NULL))
- {
- s->file_cache[i].ts = now;
- *f = s->file_cache[i].f;
- if (check_cache == 1) asl_store_file_cache_lru(s, now, i);
- return ASL_STATUS_OK;
- }
- }
-
- u = 0;
- g = 0;
- m = 0644;
- path = asl_store_make_ug_path(s->base_dir, tstring, "asl", (uid_t)ruid, (gid_t)rgid, &u, &g, &m);
- if (path == NULL) return ASL_STATUS_NO_MEMORY;
-
- out = NULL;
- status = asl_file_open_write(path, m, u, g, &out);
- if (status != ASL_STATUS_OK)
- {
- free(path);
- return status;
- }
-
- x = asl_store_file_cache_lru(s, now, FILE_CACHE_SIZE);
- if (s->file_cache[x].f != NULL) asl_file_close(s->file_cache[x].f);
- if (s->file_cache[x].path != NULL) free(s->file_cache[x].path);
-
- s->file_cache[x].f = out;
- s->file_cache[x].path = path;
- s->file_cache[x].u = ruid;
- s->file_cache[x].g = rgid;
- s->file_cache[x].bb = bb;
- s->file_cache[x].ts = time(NULL);
-
- *f = out;
-
- return ASL_STATUS_OK;
-}
-
-__private_extern__ char *
-asl_store_file_path(asl_store_t *s, asl_file_t *f)
-{
- uint32_t i;
-
- if (s == NULL) return NULL;
-
- for (i = 0; i < FILE_CACHE_SIZE; i++)
- {
- if (s->file_cache[i].f == f)
- {
- if (s->file_cache[i].path == NULL) return NULL;
- return strdup(s->file_cache[i].path);
- }
- }
-
- return NULL;
-}
-
-__private_extern__ void
-asl_store_file_close(asl_store_t *s, asl_file_t *f)
-{
- uint32_t i;
-
- if (s == NULL) return;
- if (f == NULL) return;
-
- for (i = 0; i < FILE_CACHE_SIZE; i++)
- {
- if (s->file_cache[i].f == f)
- {
- asl_file_close(s->file_cache[i].f);
- s->file_cache[i].f = NULL;
- if (s->file_cache[i].path != NULL) free(s->file_cache[i].path);
- s->file_cache[i].path = NULL;
- s->file_cache[i].u = -1;
- s->file_cache[i].g = -1;
- s->file_cache[i].bb = 0;
- s->file_cache[i].ts = 0;
- return;
- }
- }
-}
-
-uint32_t
-asl_store_save(asl_store_t *s, aslmsg msg)
-{
- struct tm ctm;
- time_t msg_time, now, bb;
- char *path, *tmp_path, *tstring, *scratch;
- const char *val;
- uid_t ruid;
- gid_t rgid;
- asl_file_t *f;
- uint32_t status, check_cache, signal_sweep, len;
- uint64_t xid, ftime;
- size_t fsize;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (msg == NULL) return ASL_STATUS_INVALID_ARG;
-
- now = time(NULL);
-
- check_cache = 0;
- if ((s->last_write + FILE_CACHE_TTL) <= now) check_cache = 1;
-
- signal_sweep = 0;
-
- msg_time = 0;
- val = asl_get(msg, ASL_KEY_TIME);
- if (val == NULL) msg_time = now;
- else msg_time = asl_parse_time(val);
-
- if (msg_time >= s->start_tomorrow)
- {
- if (now >= s->start_tomorrow)
- {
- /* new day begins */
- check_cache = 0;
- signal_sweep = 1;
- asl_store_file_closeall(s);
-
- /*
- * _asl_start_today should never fail, but if it does,
- * just push forward one day. That will probably be correct, and if
- * it isn't, the next message that gets saved will push it ahead again
- * until we get to the right date.
- */
- s->start_today = _asl_start_today();
- if (s->start_today == 0) s->start_today = s->start_tomorrow;
-
- s->start_tomorrow = s->start_today + SECONDS_PER_DAY;
- }
- }
-
- val = asl_get(msg, ASL_KEY_READ_UID);
- ruid = -1;
- if (val != NULL) ruid = atoi(val);
-
- val = asl_get(msg, ASL_KEY_READ_GID);
- rgid = -1;
- if (val != NULL) rgid = atoi(val);
-
- bb = 0;
- val = asl_get(msg, ASL_KEY_EXPIRE_TIME);
- if (val != NULL)
- {
- bb = 1;
- msg_time = asl_parse_time(val);
- }
-
- if (fseeko(s->storedata, 0, SEEK_SET) != 0) return ASL_STATUS_WRITE_FAILED;
-
- xid = asl_core_htonq(s->next_id);
- if (fwrite(&xid, sizeof(uint64_t), 1, s->storedata) != 1) return ASL_STATUS_WRITE_FAILED;
-
- /* flush data */
- fflush(s->storedata);
-
- xid = s->next_id;
- s->next_id++;
-
- s->last_write = now;
-
- if (localtime_r((const time_t *)&msg_time, &ctm) == NULL) return ASL_STATUS_FAILED;
-
- tstring = NULL;
- if (bb == 1)
- {
- /*
- * This supports 12 monthly "Best Before" buckets.
- * We advance the actual expiry time to day zero of the following month.
- * mktime() is clever enough to know that you actually mean the last day
- * of the previous month. What we get back from localtime is the last
- * day of the month in which the message expires, which we use in the name.
- */
- ctm.tm_sec = 0;
- ctm.tm_min = 0;
- ctm.tm_hour = 0;
- ctm.tm_mday = 0;
- ctm.tm_mon += 1;
-
- bb = mktime(&ctm);
-
- if (localtime_r((const time_t *)&bb, &ctm) == NULL) return ASL_STATUS_FAILED;
- asprintf(&tstring, "BB.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
- }
- else
- {
- asprintf(&tstring, "%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
- }
-
- if (tstring == NULL) return ASL_STATUS_NO_MEMORY;
-
- status = asl_store_file_open_write(s, tstring, ruid, rgid, bb, &f, now, check_cache);
- free(tstring);
- tstring = NULL;
-
- if (status != ASL_STATUS_OK) return status;
-
- status = asl_file_save(f, msg, &xid);
- if (status != ASL_STATUS_OK) return status;
-
- fsize = asl_file_size(f);
- ftime = asl_file_ctime(f);
-
- /* if file is larger than max_file_size, rename it and touch semaphore file in the store */
- if ((s->max_file_size != 0) && (fsize > s->max_file_size))
- {
- signal_sweep = 1;
- status = ASL_STATUS_OK;
-
- path = asl_store_file_path(s, f);
-
- asl_store_file_close(s, f);
-
- if (path != NULL)
- {
- tmp_path = NULL;
-
- len = strlen(path);
- if ((len >= 4) && (!strcmp(path + len - 4, ".asl")))
- {
- /* rename xxxxxxx.asl to xxxxxxx.timestamp.asl */
- scratch = strdup(path);
- if (scratch != NULL)
- {
- scratch[len - 4] = '\0';
- asprintf(&tmp_path, "%s.%llu.asl", scratch, ftime);
- free(scratch);
-
- }
- }
- else
- {
- /* append timestamp */
- asprintf(&tmp_path, "%s.%llu", path, ftime);
- }
-
- if (tmp_path == NULL)
- {
- status = ASL_STATUS_NO_MEMORY;
- }
- else
- {
- if (rename(path, tmp_path) != 0) status = ASL_STATUS_FAILED;
- free(tmp_path);
- }
-
- free(path);
- }
- }
-
- if (signal_sweep != 0) asl_store_signal_sweep(s);
-
- return status;
-}
-
-static uint32_t
-asl_store_mkdir(asl_store_t *s, const char *dir, mode_t m)
-{
- char *tstring = NULL;
- int status;
- struct stat sb;
-
- asprintf(&tstring, "%s/%s", s->base_dir, dir);
- if (tstring == NULL) return ASL_STATUS_NO_MEMORY;
-
- memset(&sb, 0, sizeof(struct stat));
- status = stat(tstring, &sb);
-
- if (status == 0)
- {
- /* must be a directory */
- if (!S_ISDIR(sb.st_mode))
- {
- free(tstring);
- return ASL_STATUS_INVALID_STORE;
- }
- }
- else
- {
- if (errno == ENOENT)
- {
- /* doesn't exist - create it */
- if (mkdir(tstring, m) != 0)
- {
- free(tstring);
- return ASL_STATUS_WRITE_FAILED;
- }
- }
- else
- {
- /* stat failed for some other reason */
- free(tstring);
- return ASL_STATUS_FAILED;
- }
- }
-
- free(tstring);
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_store_open_aux(asl_store_t *s, aslmsg msg, int *out_fd, char **url)
-{
- struct tm ctm;
- time_t msg_time, bb;
- char *path, *dir, *tstring;
- const char *val;
- uid_t ruid, u;
- gid_t rgid, g;
- mode_t m;
- uint32_t status;
- uint64_t fid;
- int fd;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (msg == NULL) return ASL_STATUS_INVALID_ARG;
- if (out_fd == NULL) return ASL_STATUS_INVALID_ARG;
- if (url == NULL) return ASL_STATUS_INVALID_ARG;
-
- msg_time = time(NULL);
-
- val = asl_get(msg, ASL_KEY_READ_UID);
- ruid = -1;
- if (val != NULL) ruid = atoi(val);
-
- val = asl_get(msg, ASL_KEY_READ_GID);
- rgid = -1;
- if (val != NULL) rgid = atoi(val);
-
- bb = 0;
- val = asl_get(msg, ASL_KEY_EXPIRE_TIME);
- if (val != NULL)
- {
- bb = 1;
- msg_time = asl_parse_time(val);
- }
-
- if (localtime_r((const time_t *)&msg_time, &ctm) == NULL) return ASL_STATUS_FAILED;
-
- dir = NULL;
- if (bb == 1)
- {
- /*
- * This supports 12 monthly "Best Before" buckets.
- * We advance the actual expiry time to day zero of the following month.
- * mktime() is clever enough to know that you actually mean the last day
- * of the previous month. What we get back from localtime is the last
- * day of the month in which the message expires, which we use in the name.
- */
- ctm.tm_sec = 0;
- ctm.tm_min = 0;
- ctm.tm_hour = 0;
- ctm.tm_mday = 0;
- ctm.tm_mon += 1;
-
- bb = mktime(&ctm);
-
- if (localtime_r((const time_t *)&bb, &ctm) == NULL) return ASL_STATUS_FAILED;
- asprintf(&dir, "BB.AUX.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
- }
- else
- {
- asprintf(&dir, "AUX.%d.%02d.%02d", ctm.tm_year + 1900, ctm.tm_mon + 1, ctm.tm_mday);
- }
-
- if (dir == NULL) return ASL_STATUS_NO_MEMORY;
-
- status = asl_store_mkdir(s, dir, 0755);
- if (status != ASL_STATUS_OK)
- {
- free(dir);
- return status;
- }
-
- fid = s->next_id;
- s->next_id++;
- tstring = NULL;
-
- asprintf(&tstring, "%s/%llu", dir, fid);
- free(dir);
- if (tstring == NULL) return ASL_STATUS_NO_MEMORY;
-
- u = 0;
- g = 0;
- m = 0644;
- path = asl_store_make_ug_path(s->base_dir, tstring, NULL, ruid, rgid, &u, &g, &m);
- free(tstring);
- if (path == NULL) return ASL_STATUS_NO_MEMORY;
-
- fd = asl_file_create(path, u, g, m);
- if (fd < 0)
- {
- free(path);
- *out_fd = -1;
- return ASL_STATUS_WRITE_FAILED;
- }
-
- /* URL is file://<path> */
- *url = NULL;
- asprintf(url, "file://%s", path);
- free(path);
-
- *out_fd = fd;
-
- return status;
-}
-
-uint32_t
-asl_store_match_timeout(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec)
-{
- DIR *dp;
- struct dirent *dent;
- uint32_t status;
- asl_file_t *f;
- char *path;
- asl_file_list_t *files;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (res == NULL) return ASL_STATUS_INVALID_ARG;
-
- files = NULL;
-
- /*
- * Open all readable files
- */
- dp = opendir(s->base_dir);
- if (dp == NULL) return ASL_STATUS_READ_FAILED;
-
- while ((dent = readdir(dp)) != NULL)
- {
- if (dent->d_name[0] == '.') continue;
-
- path = NULL;
- asprintf(&path, "%s/%s", s->base_dir, dent->d_name);
-
- /* NB asl_file_open_read will fail if path is NULL, if the file is not an ASL store file, or if it isn't readable */
- status = asl_file_open_read(path, &f);
- if (path != NULL) free(path);
- if ((status != ASL_STATUS_OK) || (f == NULL)) continue;
-
- files = asl_file_list_add(files, f);
- }
-
- closedir(dp);
-
- status = asl_file_list_match_timeout(files, query, res, last_id, start_id, count, direction, usec);
- asl_file_list_close(files);
- return status;
-}
-
-uint32_t
-asl_store_match(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction)
-{
- return asl_store_match_timeout(s, query, res, last_id, start_id, count, direction, 0);
-}
-
-uint32_t
-asl_store_match_start(asl_store_t *s, uint64_t start_id, int32_t direction)
-{
- DIR *dp;
- struct dirent *dent;
- uint32_t status;
- asl_file_t *f;
- char *path;
- asl_file_list_t *files;
-
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
-
- if (s->work != NULL) asl_file_list_match_end(s->work);
- s->work = NULL;
-
- files = NULL;
-
- /*
- * Open all readable files
- */
- dp = opendir(s->base_dir);
- if (dp == NULL) return ASL_STATUS_READ_FAILED;
-
- while ((dent = readdir(dp)) != NULL)
- {
- if (dent->d_name[0] == '.') continue;
-
- path = NULL;
- asprintf(&path, "%s/%s", s->base_dir, dent->d_name);
-
- /* NB asl_file_open_read will fail if path is NULL, if the file is not an ASL store file, or if it isn't readable */
- status = asl_file_open_read(path, &f);
- if (path != NULL) free(path);
- if ((status != ASL_STATUS_OK) || (f == NULL)) continue;
-
- files = asl_file_list_add(files, f);
- }
-
- closedir(dp);
-
- s->work = asl_file_list_match_start(files, start_id, direction);
- if (s->work == NULL) return ASL_STATUS_FAILED;
-
- return ASL_STATUS_OK;
-}
-
-uint32_t
-asl_store_match_next(asl_store_t *s, aslresponse query, aslresponse *res, uint32_t count)
-{
- if (s == NULL) return ASL_STATUS_INVALID_STORE;
- if (s->work == NULL) return ASL_STATUS_OK;
-
- return asl_file_list_match_next(s->work, query, res, count);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __ASL_STORE_H__
-#define __ASL_STORE_H__
-
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/time.h>
-#include <asl.h>
-#include "asl_file.h"
-#include <Availability.h>
-
-#define PATH_ASL_STORE "/var/log/asl"
-#define PATH_ASL_ARCHIVE "/var/log/asl.archive"
-#define FILE_ASL_STORE_DATA "StoreData"
-#define FILE_ASL_STORE_SWEEP_SEMAPHORE "SweepStore"
-
-#define FILE_CACHE_SIZE 64
-#define FILE_CACHE_TTL 300
-
-typedef struct
-{
- time_t ts;
- uid_t u;
- gid_t g;
- time_t bb;
- char *path;
- asl_file_t *f;
-} asl_cached_file_t;
-
-typedef struct
-{
- char *base_dir;
- FILE *storedata;
- uint64_t next_id;
- asl_cached_file_t file_cache[FILE_CACHE_SIZE];
- void *work;
- time_t start_today;
- time_t start_tomorrow;
- time_t last_write;
- size_t max_file_size;
-} asl_store_t;
-
-uint32_t asl_store_open_write(const char *basedir, asl_store_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_store_open_read(const char *basedir, asl_store_t **s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_store_close(asl_store_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_store_statistics(asl_store_t *s, aslmsg *msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-uint32_t asl_store_save(asl_store_t *s, aslmsg msg) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-uint32_t asl_store_match(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_store_match_timeout(asl_store_t *s, aslresponse query, aslresponse *res, uint64_t *last_id, uint64_t start_id, uint32_t count, int32_t direction, uint32_t usec) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2);
-
-uint32_t asl_store_match_start(asl_store_t *s, uint64_t start_id, int32_t direction) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_store_match_next(asl_store_t *s, aslresponse query, aslresponse *res, uint32_t count) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-uint32_t asl_store_max_file_size(asl_store_t *s, size_t max) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_store_signal_sweep(asl_store_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-uint32_t asl_store_sweep_file_cache(asl_store_t *s) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2);
-
-uint32_t asl_store_open_aux(asl_store_t *s, aslmsg msg, int *fd, char **url) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-
-#endif /* __ASL_STORE_H__ */
+++ /dev/null
-/*
- * Copyright (c) 2006-2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License."
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * These routines needs to be separate from asl.c, so that dyld can build
- * and suck in these without the rest of asl.
- */
-
-#include <string.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/un.h>
-#include <fcntl.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <unistd.h>
-
-static uint8_t *b64charset = (uint8_t *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-__private_extern__ const char *
-_asl_escape(unsigned char c)
-{
- switch(c)
- {
- case '\\':
- return "\\\\";
- case '[':
- return "\\[";
- case ']':
- return "\\]";
- case '\n':
- return "\\n";
- }
- return NULL;
-}
-
-static int
-asl_is_utf8_char(const unsigned char *p, int *state, int *ctype)
-{
- switch (*state)
- {
- case 0:
- {
- *ctype = 0;
-
- if (*p >= 0x80)
- {
- *state = 1;
- if ((*p >= 0xc2) && (*p <= 0xdf)) *ctype = 1;
- else if (*p == 0xe0) *ctype = 2;
- else if ((*p >= 0xe1) && (*p <= 0xef)) *ctype = 3;
- else if (*p == 0xf0) *ctype = 4;
- else if ((*p >= 0xf1) && (*p <= 0xf3)) *ctype = 5;
- else if (*p == 0xf4) *ctype = 6;
- else return 0;
- }
-
- break;
- }
-
- case 1:
- {
- switch (*ctype)
- {
- case 1:
- {
- if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
- else return 0;
- break;
- }
-
- case 2:
- {
- if ((*p >= 0xa0) && (*p <= 0xbf)) *state = 2;
- else return 0;
- break;
- }
-
- case 3:
- {
- if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2;
- else return 0;
- break;
- }
-
- case 4:
- {
- if ((*p >= 0x90) && (*p <= 0xbf)) *state = 2;
- else return 0;
- break;
- }
-
- case 5:
- {
- if ((*p >= 0x80) && (*p <= 0xbf)) *state = 2;
- else return 0;
- break;
- }
-
- case 6:
- {
- if ((*p >= 0x80) && (*p <= 0x8f)) *state = 2;
- else return 0;
- break;
- }
-
- default: return 0;
- }
-
- break;
- }
-
- case 2:
- {
- if ((*ctype >= 2) && (*ctype <= 3))
- {
- if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
- else return 0;
- }
- else if ((*ctype >= 4) && (*ctype <= 6))
- {
- if ((*p >= 0x80) && (*p <= 0xbf)) *state = 3;
- else return 0;
- }
- else
- {
- return 0;
- }
-
- break;
- }
-
- case 3:
- {
- if ((*ctype >= 4) && (*ctype <= 6))
- {
- if ((*p >= 0x80) && (*p <= 0xbf)) *state = 0;
- else return 0;
- }
- else
- {
- return 0;
- }
-
- break;
- }
-
- default: return 0;
- }
-
- return 1;
-}
-
-__private_extern__ int
-asl_is_utf8(const char *str)
-{
- const unsigned char *p;
- int flag = 1;
- int state = 0;
- int ctype = 0;
-
- if (str == NULL) return flag;
-
- for (p = (const unsigned char *)str; (*p != '\0') && (flag == 1); p++)
- {
- flag = asl_is_utf8_char(p, &state, &ctype);
- }
-
- return flag;
-}
-
-__private_extern__ uint8_t *
-asl_b64_encode(const uint8_t *buf, size_t len)
-{
- uint8_t *out;
- uint8_t b;
- size_t i0, i1, i2, j, outlen;
-
- if (buf == NULL) return NULL;
- if (len == 0) return NULL;
-
- outlen = ((len + 2) / 3) * 4;
- out = (uint8_t *)malloc(outlen + 1);
- if (out == NULL)
- {
- errno = ENOMEM;
- return NULL;
- }
-
- out[outlen] = 0;
-
- i0 = 0;
- i1 = 1;
- i2 = 2;
- j = 0;
-
- while (i2 < len)
- {
- b = buf[i0] >> 2;
- out[j++] = b64charset[b];
-
- b = ((buf[i0] & 0x03) << 4) | (buf[i1] >> 4);
- out[j++] = b64charset[b];
-
- b = ((buf[i1] & 0x0f) << 2) | ((buf[i2] & 0xc0) >> 6);
- out[j++] = b64charset[b];
-
- b = buf[i2] & 0x3f;
- out[j++] = b64charset[b];
-
- i0 += 3;
- i1 = i0 + 1;
- i2 = i1 + 1;
- }
-
- if (i0 < len)
- {
- b = buf[i0] >> 2;
- out[j++] = b64charset[b];
-
- b = (buf[i0] & 0x03) << 4;
-
- if (i1 < len) b |= (buf[i1] >> 4);
- out[j++] = b64charset[b];
-
- if (i1 >= len)
- {
- out[j++] = '=';
- out[j++] = '=';
- return out;
- }
-
- b = (buf[i1] & 0x0f) << 2;
- out[j++] = b64charset[b];
- out[j++] = '=';
- }
-
- return out;
-}
+++ /dev/null
-#include <dispatch/dispatch.h>
-#include <uuid/uuid.h>
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#include <mach-o/loader.h>
-#include <mach-o/fat.h>
-#include <mach-o/arch.h>
-#include <mach-o/getsect.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <execinfo.h>
-#include <stdio.h>
-#include <dlfcn.h>
-#include <asl.h>
-#include <errno.h>
-#include <pthread.h>
-#include "assumes.h"
-
-#define OSX_ASSUME_LOG_REDIRECT_SECT_NAME "__osx_log_func"
-#define osx_atomic_cmpxchg(p, o, n) __sync_bool_compare_and_swap((p), (o), (n))
-
-static bool _osx_should_abort_on_assumes = false;
-
-static const char *
-_osx_basename(const char *p)
-{
- return ((strrchr(p, '/') ? : p - 1) + 1);
-}
-
-static void
-_osx_get_build(char *build, size_t sz)
-{
- /* Get the build every time. We used to cache it, but if PID 1 experiences
- * an assumes() failure before the build has been set, that would mean that
- * all future failures would get bad build info. So we fetch it every time.
- * Since assumes() failures are on the slow path anyway, not a huge deal.
- */
- int mib[] = { CTL_KERN, KERN_OSVERSION };
-
- size_t oldsz = sz;
- int r = sysctl(mib, 2, build, &sz, NULL, 0);
- if (r == 0 && sz == 1) {
- (void)strlcpy(build, "99Z999", oldsz);
- }
-}
-
-static void
-_osx_get_image_uuid(void *hdr, uuid_t uuid)
-{
-#if __LP64__
- struct mach_header_64 *hdr32or64 = (struct mach_header_64 *)hdr;
-#else
- struct mach_header *hdr32or64 = (struct mach_header *)hdr;
-#endif /* __LP64__ */
-
- size_t i = 0;
- size_t next = sizeof(*hdr32or64);
- struct load_command *cur = NULL;
- for (i = 0; i < hdr32or64->ncmds; i++) {
- cur = (struct load_command *)((uintptr_t)hdr32or64 + next);
- if (cur->cmd == LC_UUID) {
- struct uuid_command *cmd = (struct uuid_command *)cur;
- uuid_copy(uuid, cmd->uuid);
- break;
- }
-
- next += cur->cmdsize;
- }
-
- if (i == hdr32or64->ncmds) {
- uuid_clear(uuid);
- }
-}
-
-static void
-_osx_abort_on_assumes_once(void)
-{
- /* Embedded boot-args can get pretty long. Let's just hope this is big
- * enough.
- */
- char bootargs[2048];
- size_t len = sizeof(bootargs) - 1;
-
- if (sysctlbyname("kern.bootargs", bootargs, &len, NULL, 0) == 0) {
- if (strnstr(bootargs, "-osx_assumes_fatal", len)) {
- _osx_should_abort_on_assumes = true;
- }
- }
-}
-
-static bool
-_osx_abort_on_assumes(void)
-{
- static pthread_once_t once = PTHREAD_ONCE_INIT;
- bool result = false;
-
- if (getpid() != 1) {
- if (getenv("OSX_ASSUMES_FATAL")) {
- result = true;
- } else {
- pthread_once(&once, _osx_abort_on_assumes_once);
- result = _osx_should_abort_on_assumes;
- }
- } else {
- if (getenv("OSX_ASSUMES_FATAL_PID1")) {
- result = true;
- }
- }
-
- return result;
-}
-
-#if __LP64__
-static osx_redirect_t
-_osx_find_log_redirect_func(struct mach_header_64 *hdr)
-{
- osx_redirect_t result = NULL;
-
- char name[128];
- unsigned long size = 0;
- uint8_t *data = getsectiondata(hdr, "__TEXT", OSX_ASSUME_LOG_REDIRECT_SECT_NAME, &size);
- if (data && size < sizeof(name) - 2) {
- /* Ensure NUL termination. */
- (void)strlcpy(name, (const char *)data, size + 1);
- result = dlsym(RTLD_DEFAULT, name);
- }
-
- return result;
-}
-#else
-static osx_redirect_t
-_osx_find_log_redirect_func(struct mach_header *hdr)
-{
- osx_redirect_t result = NULL;
-
- char name[128];
- unsigned long size = 0;
- uint8_t *data = getsectiondata(hdr, "__TEXT", OSX_ASSUME_LOG_REDIRECT_SECT_NAME, &size);
- if (data && size < sizeof(name) - 2) {
- (void)strlcpy(name, (const char *)data, size + 1);
- result = dlsym(RTLD_DEFAULT, name);
- }
-
- return result;
-}
-#endif
-
-static bool
-_osx_log_redirect(void *hdr, const char *msg)
-{
- bool result = false;
-
- osx_redirect_t redirect_func = _osx_find_log_redirect_func(hdr);
- if (redirect_func) {
- result = redirect_func(msg);
- }
-
- return result;
-}
-
-__attribute__((always_inline))
-static void
-_osx_construct_message(const char *prefix, uint64_t code, aslmsg asl_message, Dl_info *info, char *buff, size_t sz)
-{
- const char *image_name = NULL;
- uintptr_t offset = 0;
- uuid_string_t uuid_str;
-
- void *ret = __builtin_return_address(0);
- if (dladdr(ret, info)) {
- uuid_t uuid;
- _osx_get_image_uuid(info->dli_fbase, uuid);
-
- uuid_unparse(uuid, uuid_str);
- image_name = _osx_basename(info->dli_fname);
-
- offset = ret - info->dli_fbase;
- }
-
- char name[256];
- (void)snprintf(name, sizeof(name), "com.apple.assumes.%s", image_name);
-
- char sig[64];
- (void)snprintf(sig, sizeof(sig), "%s:%lu", uuid_str, offset);
-
- char result[24];
- (void)snprintf(result, sizeof(result), "0x%llx", code);
-
- char build[16];
- size_t bsz = sizeof(build);
- _osx_get_build(build, bsz);
-
- (void)snprintf(buff, sz, "%s: %s: %s + %lu [%s]: %s", prefix, build, image_name, offset, uuid_str, result);
-
- (void)asl_set(asl_message, "com.apple.message.domain", name);
- (void)asl_set(asl_message, "com.apple.message.signature", sig);
- (void)asl_set(asl_message, "com.apple.message.value", result);
-}
-
-void
-_osx_assumes_log(uint64_t code)
-{
- aslmsg asl_message = asl_new(ASL_TYPE_MSG);
- if (asl_message) {
- Dl_info info;
- char message[256];
- _osx_construct_message("Bug", code, asl_message, &info, message, sizeof(message));
- if (!_osx_log_redirect(info.dli_fbase, message)) {
- /* MessageTracer messages aren't logged to the regular syslog store,
- * so we log the message without any MessageTracer attributes so
- * that we can see it in our regular syslog.
- */
- (void)asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s", message);
- (void)asl_log(NULL, asl_message, ASL_LEVEL_ERR, "%s", message);
- }
-
- asl_free(asl_message);
- }
-
- if (_osx_abort_on_assumes()) {
- __builtin_trap();
- }
-}
-
-char *
-_osx_assert_log(uint64_t code)
-{
- char *result = NULL;
-
- aslmsg asl_message = asl_new(ASL_TYPE_MSG);
- if (asl_message) {
- Dl_info info;
- char message[256];
- _osx_construct_message("Fatal bug", code, asl_message, &info, message, sizeof(message));
- if (!_osx_log_redirect(info.dli_fbase, message)) {
- (void)asl_log(NULL, NULL, ASL_LEVEL_ERR, "%s", message);
- (void)asl_log(NULL, asl_message, ASL_LEVEL_ERR, "%s", message);
- }
-
- asl_free(asl_message);
- result = strdup(message);
- }
-
-#if LIBC_NO_LIBCRASHREPORTERCLIENT
- /* There is no crash report information facility on embedded, which is
- * really regrettable. Fortunately, all we need to capture is the value
- * which tripped up the assertion. We can just stuff that into the thread's
- * name.
- */
- char name[64];
- (void)pthread_getname_np(pthread_self(), name, sizeof(name));
-
- char newname[64];
- if (strlen(name) == 0) {
- (void)snprintf(newname, sizeof(newname), "[Fatal bug: 0x%llx]", code);
- } else {
- (void)snprintf(newname, sizeof(newname), "%s [Fatal bug: 0x%llx]", name, code);
- }
-
- (void)pthread_setname_np(newname);
-#endif
-
- return result;
-}
-
-void
-_osx_assumes_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code)
-{
- aslmsg asl_message = asl_new(ASL_TYPE_MSG);
- if (asl_message) {
- Dl_info info;
- char message[256];
- _osx_construct_message("Bug", code, asl_message, &info, message, sizeof(message));
-
- (void)callout(asl_message, ctx, message);
- asl_free(asl_message);
- }
-
- if (_osx_abort_on_assumes()) {
- __builtin_trap();
- }
-}
-
-char *
-_osx_assert_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code)
-{
- char *result = NULL;
-
- aslmsg asl_message = asl_new(ASL_TYPE_MSG);
- if (asl_message) {
- Dl_info info;
- char message[256];
- _osx_construct_message("Fatal bug", code, asl_message, &info, message, sizeof(message));
-
- (void)callout(asl_message, ctx, message);
- asl_free(asl_message);
- result = strdup(message);
- }
-}
-
-extern void
-_osx_avoid_tail_call(void)
-{
- // no-op
-}
#ifndef __OSX_ASSUMES_H__
#define __OSX_ASSUMES_H__
-#include <sys/cdefs.h>
+/* The interfaces in this file have been replaced by those in os/assumes.h.
+ * Use the os_*() variants instead of these. The posix_assumes_*() macros have
+ * moved to os/assumes.h.
+ */
+#include <os/assumes.h>
__BEGIN_DECLS
-#include <Availability.h>
-#include <TargetConditionals.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <stdbool.h>
-#include <asl.h>
-
-#if __GNUC__
-#define osx_fastpath(x) ((typeof(x))__builtin_expect((long)(x), ~0l))
-#define osx_slowpath(x) ((typeof(x))__builtin_expect((long)(x), 0l))
-#define osx_constant(x) __builtin_constant_p((x))
-#define osx_hardware_trap() __builtin_trap()
-
-#define __OSX_COMPILETIME_ASSERT__(e) ({ \
- char __compile_time_assert__[(e) ? 1 : -1]; \
- (void)__compile_time_assert__; \
-})
-#else
-#define osx_fastpath(x) (x)
-#define osx_slowpath(x) (x)
-#define osx_constant(x) ((long)0)
-#define osx_hardware_trap() abort()
-
-#define __OSX_COMPILETIME_ASSERT__(e) (e)
-#endif /* __GNUC__ */
-
-typedef bool (*osx_redirect_t)(const char *);
-
-/* The asl_message argument is an aslmsg that, when given to asl_log(), will
- * direct the message to the MessageTracer diagnostic messages store rather than
- * the default system log store.
- */
-typedef bool (*osx_log_callout_t)(aslmsg asl_message, void *ctx, const char *);
-
-#if TARGET_OS_IPHONE
-#define osx_set_crash_message(arg) /* no-op */
-#else
-#include <CrashReporterClient.h>
-#define osx_set_crash_message(arg) _crc_make_setter(message, (arg))
-#endif
-
-#define osx_assumes(e) ({ \
- typeof(e) _e = osx_fastpath(e); /* Force evaluation of 'e' */ \
- if (!_e) { \
- if (osx_constant(e)) { \
- __OSX_COMPILETIME_ASSERT__(e); \
- } \
- _osx_assumes_log((uint64_t)(uintptr_t)_e); \
- _osx_avoid_tail_call(); \
- } \
- _e; \
-})
-
-#define osx_assumes_zero(e) ({ \
- typeof(e) _e = osx_slowpath(e); \
- if (_e) { \
- if (osx_constant(e)) { \
- __OSX_COMPILETIME_ASSERT__(!e); \
- } \
- _osx_assumes_log((uint64_t)(uintptr_t)_e); \
- _osx_avoid_tail_call(); \
- } \
- _e; \
-})
-
-/* This variant is for use with old-style POSIX APIs that return -1 on failure
- * and set errno. If the return code is -1, the value logged will be as though
- * osx_assumes_zero(errno) was used. It encapsulates the following pattern:
- *
- * int tubes[2];
- * if (pipe(tubes) == -1) {
- * (void)osx_assumes_zero(errno);
- * }
- */
-#define posix_assumes_zero(e) ({ \
- typeof(e) _e = osx_slowpath(e); \
- if (_e == (typeof(e))-1) { \
- _osx_assumes_log((uint64_t)(uintptr_t)errno); \
- _osx_avoid_tail_call(); \
- } \
- _e; \
-})
-
-#define osx_assert(e) ({ \
- typeof(e) _e = osx_fastpath(e); \
- if (!_e) { \
- if (osx_constant(e)) { \
- __OSX_COMPILETIME_ASSERT__(e); \
- } \
-\
- char *message = _osx_assert_log((uint64_t)(uintptr_t)_e); \
- osx_set_crash_message(message); \
- osx_hardware_trap(); \
- free(message); \
- } \
-})
-
-#define osx_assert_zero(e) ({ \
- typeof(e) _e = osx_slowpath(e); \
- if (_e) { \
- if (osx_constant(e)) { \
- __OSX_COMPILETIME_ASSERT__(!e); \
- } \
-\
- char *message = _osx_assert_log((uint64_t)(uintptr_t)_e); \
- osx_set_crash_message(message); \
- osx_hardware_trap(); \
- free(message); \
- } \
-})
-
-#define posix_assert_zero(e) ({ \
- typeof(e) _e = osx_slowpath(e); \
- if (_e == (typeof(e))-1) { \
- char *message = _osx_assert_log((uint64_t)(uintptr_t)errno); \
- osx_set_crash_message(message); \
- osx_hardware_trap(); \
- free(message); \
- } \
-})
-
-/* These are for defining your own assumes()-like wrapper calls so that you can
- * log additional information, such as the about-PID, sender, etc. They're
- * generally not useful for direct inclusion in your code.
- */
-#define osx_assumes_ctx(f, ctx, e) ({ \
- typeof(e) _e = osx_fastpath(e); \
- if (!_e) { \
- if (osx_constant(e)) { \
- __OSX_COMPILETIME_ASSERT__(e); \
- } \
- _osx_assumes_log_ctx(f, ctx, (uintptr_t)_e); \
- _osx_avoid_tail_call(); \
- } \
- _e; \
-})
-
-#define osx_assumes_zero_ctx(f, ctx, e) ({ \
- typeof(e) _e = osx_slowpath(e); \
- if (_e) { \
- if (osx_constant(e)) { \
- __OSX_COMPILETIME_ASSERT__(!e); \
- } \
- _osx_assumes_log_ctx((f), (ctx), (uintptr_t)_e); \
- _osx_avoid_tail_call(); \
- } \
- _e; \
-})
-
-#define posix_assumes_zero_ctx(f, ctx, e) ({ \
- typeof(e) _e = osx_slowpath(e); \
- if (_e == (typeof(e))-1) { \
- _osx_assumes_log_ctx((f), (ctx), (uintptr_t)errno); \
- _osx_avoid_tail_call(); \
- } \
- _e; \
-})
-
-#define osx_assert_ctx(f, ctx, e) ({ \
- typeof(e) _e = osx_fastpath(e); \
- if (!_e) { \
- if (osx_constant(e)) { \
- __OSX_COMPILETIME_ASSERT__(e); \
- } \
-\
- char *message = _osx_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)_e); \
- osx_set_crash_message(message); \
- osx_hardware_trap(); \
- free(message); \
- } \
-})
-
-#define osx_assert_zero_ctx(f, ctx, e) ({ \
- typeof(e) _e = osx_slowpath(e); \
- if (_e) { \
- if (osx_constant(e)) { \
- __OSX_COMPILETIME_ASSERT__(!e); \
- } \
-\
- char *message = _osx_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)_e); \
- osx_set_crash_message(message); \
- osx_hardware_trap(); \
- free(message); \
- } \
-})
-
-#define posix_assert_zero_ctx(f, ctx, e) ({ \
- typeof(e) _e = osx_slowpath(e); \
- if (_e == (typeof(e))-1) { \
- char *message = _osx_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)errno); \
- osx_set_crash_message(message); \
- osx_hardware_trap(); \
- free(message); \
- } \
-})
+#define osx_fastpath(x) os_fastpath(x)
+#define osx_slowpath(x) os_slowpath(x)
+#define osx_constant(x) os_constant(x)
+#define osx_hardware_trap() os_hardware_trap()
+#define __OSX_COMPILETIME_ASSERT__(e) __OS_COMPILETIME_ASSERT__((e))
+
+typedef os_redirect_t osx_redirect_t;
+typedef os_log_callout_t osx_log_callout_t;
+
+#define osx_set_crash_message(arg) os_set_crash_message(arg)
+
+#define osx_assumes(e) os_assumes((e))
+#define osx_assumes_zero(e) os_assumes_zero((e))
+
+#define osx_assert(e) os_assert((e))
+#define osx_assert_zero(e) os_assert_zero((e))
+
+#define osx_assumes_ctx(f, ctx, e) os_assumes_ctx((f), (ctx), (e))
+#define osx_assumes_zero_ctx(f, ctx, e) os_assumes_zero_ctx((f), (ctx), (e))
+
+#define osx_assert_ctx(f, ctx, e) os_assert_ctx((f), (ctx), (e))
+#define osx_assert_zero_ctx(f, ctx, e) os_assert_zero_ctx((f), (ctx), (e))
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3)
extern void
image,
(uintptr_t)addr,
symbol,
- symbol_offset) + 1;
+ symbol_offset);
}
char** backtrace_symbols(void* const* buffer, int size) {
}
ptrs[i] = (char*)strs;
- strs += chk;
+ strs += chk + 1; // Step over the '\0'
}
free(info);
+++ /dev/null
-/*
- * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* cache control */
-
-#include <stdlib.h>
-#include <stddef.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <libkern/OSCacheControl.h>
-
-
-int
-sys_cache_control(int function, void *start, size_t len)
-{
- int status = 0;
-
- switch( function ) {
-
- case kCacheFunctionPrepareForExecution:
- sys_icache_invalidate(start, len);
- break;
-
- case kCacheFunctionFlushDcache:
- sys_dcache_flush(start, len);
- break;
-
- default:
- status = ENOTSUP;
- }
-
- return status;
-}
_
.T&
c s s s s
-c s s s s
c c | c c c
c c | c c c
l c | c c c
.Pp
.Bl -tag -width 6n
.Pp
+.It Li _CS_DARWIN_USER_DIR
+Provides the path to a user's folder. The directory will be created if it
+does not already exist.
+.Pp
+This directory is created with access permissions of 0755 and restricted by
+the
+.Xr umask 2
+of the calling process and is not intended to be used for
+sensitive or temporary file storage, as all users can see files created here.
+If the user's umask allows it, files created here will be world readable,
+which could lead to information disclosure.
+.Pp
+.It Li _CS_DARWIN_USER_TEMP_DIR
+Provides the path to a user's temporary items directory. The directory will be
+created it if does not already exist. This directory is created with access
+permissions of 0700 and restricted by the
+.Xr umask 2
+of the calling process and is a good location for temporary files.
+.Pp
+By default, files in this location may be cleaned (removed) by the system if
+they are not accessed in 3 days.
+.Pp
+.It Li _CS_DARWIN_USER_CACHE_DIR
+Provides the path to the user's cache directory. The directory will be created
+if it does not already exist. This directory is created with access permissions
+of 0700 and restricted by the
+.Xr umask 2
+of the calling process and is a good location for user cache data as it will not
+be automatically cleaned by the system.
+.Pp
+Files in this location will be removed during safe boot.
+.Pp
.It Li _CS_PATH
Return a value for the
.Ev PATH
/* ===== (mostly) Standard DES Tables ==================== */
#ifndef BUILDING_VARIANT
-static unsigned char IP[] = { /* initial permutation */
+static const unsigned char IP[] = { /* initial permutation */
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
/* The final permutation is the inverse of IP - no table is necessary */
-static unsigned char ExpandTr[] = { /* expansion operation */
+static const unsigned char ExpandTr[] = { /* expansion operation */
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
28, 29, 30, 31, 32, 1,
};
-static unsigned char PC1[] = { /* permuted choice table 1 */
+static const unsigned char PC1[] = { /* permuted choice table 1 */
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
21, 13, 5, 28, 20, 12, 4,
};
-static unsigned char Rotates[] = { /* PC1 rotation schedule */
+static const unsigned char Rotates[] = { /* PC1 rotation schedule */
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
};
/* note: each "row" of PC2 is left-padded with bits that make it invertible */
-static unsigned char PC2[] = { /* permuted choice table 2 */
+static const unsigned char PC2[] = { /* permuted choice table 2 */
9, 18, 14, 17, 11, 24, 1, 5,
22, 25, 3, 28, 15, 6, 21, 10,
35, 38, 23, 19, 12, 4, 26, 8,
},
};
-static unsigned char P32Tr[] = { /* 32-bit permutation function */
+static const unsigned char P32Tr[] = { /* 32-bit permutation function */
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
22, 11, 4, 25,
};
-static unsigned char CIFP[] = { /* compressed/interleaved permutation */
+static const unsigned char CIFP[] = { /* compressed/interleaved permutation */
1, 2, 3, 4, 17, 18, 19, 20,
5, 6, 7, 8, 21, 22, 23, 24,
9, 10, 11, 12, 25, 26, 27, 28,
45, 46, 47, 48, 61, 62, 63, 64,
};
-static unsigned char itoa64[] = /* 0..63 => ascii-64 */
+static const unsigned char itoa64[] = /* 0..63 => ascii-64 */
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
/* ===== Tables that are initialized at run time ==================== */
-static unsigned char a64toi[128]; /* ascii-64 => 0..63 */
+/* ascii-64 => 0..63 */
+static const unsigned char a64toi[128] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0, 0, 0, 0, 0, 0,
+ 0, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 0, 0, 0, 0, 0,
+ 0, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52,
+ 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 0, 0, 0, 0, 0,
+};
/* Initial key schedule permutation */
// static C_block PC1ROT[64/CHUNKBITS][1<<CHUNKBITS];
register int i, j;
register long k;
register int tableno;
- static unsigned char perm[64], tmp32[32]; /* "static" for speed */
-
- /*
- * table that converts chars "./0-9A-Za-z"to integers 0-63.
- */
- for (i = 0; i < 64; i++)
- a64toi[itoa64[i]] = i;
+ unsigned char perm[64] = {0};
/*
* PC1ROT - bit reverse, then PC1, then Rotate, then PC2.
*/
- for (i = 0; i < 64; i++)
- perm[i] = 0;
for (i = 0; i < 64; i++) {
if ((k = PC2[i]) == 0)
continue;
perm[i] = P32Tr[ExpandTr[i]-1];
for (tableno = 0; tableno < 8; tableno++) {
for (j = 0; j < 64; j++) {
+ unsigned char tmp32[32] = { 0 };
k = (((j >> 0) &01) << 5)|
(((j >> 1) &01) << 3)|
(((j >> 2) &01) << 2)|
(((k >> 2)&01) << 1)|
(((k >> 1)&01) << 2)|
(((k >> 0)&01) << 3);
- for (i = 0; i < 32; i++)
- tmp32[i] = 0;
for (i = 0; i < 4; i++)
tmp32[4 * tableno + i] = (k >> i) & 01;
k = 0;
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.Ft void
.Fn rewinddir "DIR *dirp"
.Ft void
-.Fn seekdir "DIR *dirp" "long loc"
+.Fn seekdir "DIR *dirp" "long loc"
.Ft long
.Fn telldir "DIR *dirp"
.Sh DESCRIPTION
with it,
and returns a pointer to be used to identify the
.Em directory stream
-in subsequent operations. The pointer
-.Dv NULL
-is returned if
+in subsequent operations.
+In the event of an error, NULL
+is returned and
+.Va errno
+will be set to reflect if
.Fa dirname
cannot be accessed or if it cannot
.Xr malloc 3
The
.Fn readdir
function
-returns a pointer to the next directory entry. It returns
+returns a pointer to the next directory entry.
+It returns
.Dv NULL
-upon reaching the end of the directory or detecting an invalid
-.Fn seekdir
-operation.
+upon reaching the end of the directory or on error.
+In the event of an error,
+.Va errno
+will be set to any of the values documented for the
+.Xr getdirentries 2
+system call.
.Pp
+The
.Fn readdir_r
+function
provides the same functionality as
.Fn readdir ,
but the caller must provide a directory
.Fa entry
-buffer to store the results in. If the read succeeds,
+buffer to store the results in.
+If the read succeeds,
.Fa result
is pointed at the
.Fa entry ;
.Fa result
is set to
.Dv NULL .
+The
.Fn readdir_r
+function
returns 0 on success or an error number to indicate failure.
.Pp
The
.Dv DIR
pointer (e.g.,
.Fa dirp )
-from which they are derived. If the directory is closed and then
+from which they are derived.
+If the directory is closed and then
reopened, prior values returned by
.Fn telldir
will no longer be valid.
.Pp
Sample code which searches a directory for entry ``name'' is:
.Bd -literal -offset indent
-len = strlen(name);
dirp = opendir(".");
-while ((dp = readdir(dirp)) != NULL)
- if (dp->d_namlen == len && !strcmp(dp->d_name, name)) {
+if (dirp == NULL)
+ return (ERROR);
+len = strlen(name);
+while ((dp = readdir(dirp)) != NULL) {
+ if (dp->d_namlen == len && strcmp(dp->d_name, name) == 0) {
(void)closedir(dirp);
- return FOUND;
+ return (FOUND);
}
+}
(void)closedir(dirp);
-return NOT_FOUND;
+return (NOT_FOUND);
.Ed
.Sh LEGACY SYNOPSIS
.Fd #include <sys/types.h>
static int gettype(char *, char **);
struct disklabel *
-getdiskbyname(name)
- const char *name;
+getdiskbyname(const char *name)
{
- static struct disklabel disk;
- register struct disklabel *dp = &disk;
- register struct partition *pp;
+ static struct disklabel *dp = NULL;
+ struct partition *pp;
char *buf;
char *db_array[2] = { _PATH_DISKTAB, 0 };
char *cp, *cq; /* can't be register */
if (cgetent(&buf, db_array, (char *) name) < 0)
return NULL;
- bzero((char *)&disk, sizeof(disk));
+ if (dp == NULL) {
+ dp = malloc(sizeof(struct disklabel));
+ if (dp == NULL) {
+ return NULL;
+ }
+ }
+ memset(dp, 0, sizeof(struct disklabel));
+
/*
* typename
*/
.\" @(#)fts.3 8.5 (Berkeley) 4/16/94
.\" $FreeBSD: src/lib/libc/gen/fts.3,v 1.13 2001/09/20 12:32:45 ru Exp $
.\"
-.Dd May 20, 2008
+.Dd Sept 24, 2012
.Dt FTS 3
.Os
.Sh NAME
The options are selected by
.Em or Ns 'ing
the following values:
-.Bl -tag -width "FTS_PHYSICAL"
+.Bl -tag -width "FTS_NOSTAT_TYPE"
.It Dv FTS_COMFOLLOW
This option causes any symbolic link specified as a root path to be
followed immediately whether or not
.Fa statp
field) for each file visited.
This option relaxes that requirement as a performance optimization,
-allowing the
+not calling
+.Xr stat 2
+whenever possible.
+If
+.Xr stat 2
+doesn't need to be called, the
.Nm
-functions to set the
+functions will set the
.Fa fts_info
field to
-.Dv FTS_NSOK
-and leave the contents of the
+.Dv FTS_NSOK ;
+otherwise
+.Fa fts_info
+will be set to the correct file information value corresponding to the
+.Xr stat 2
+information.
+In any case, the
.Fa statp
-field undefined.
+field will always be undefined.
+Note that because
+.Nm
+detects directory cycles and dangling symbolic links,
+.Xr stat 2
+is always called for directories and is called for symbolic links when
+.Dv FTS_LOGICAL
+is set.
+.It Dv FTS_NOSTAT_TYPE
+Like
+.Dv FTS_NOSTAT
+but if the file type is returned by
+.Xr readdir 3 ,
+the corresponding file information value is returned in
+.Fa fts_info
+instead of
+.Dv FTS_NSOK .
.It Dv FTS_PHYSICAL
This option causes the
.Nm
/*
- * Copyright (c) 1999, 2000, 2003, 2005, 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 1999, 2000, 2003, 2005, 2008, 2012 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#define F_STATDIRSYM (1 << F_SHIFT) /* only stat directories and symlinks (and unknowns) */
#define F_ALWAYSSTAT (2 << F_SHIFT) /* always stat */
#define F_STATDIR (3 << F_SHIFT) /* only stat directories (and unknowns) */
+#define F_D_TYPE (4 << F_SHIFT) /* only stat directories but use d_type */
+#define F_D_TYPESYM (5 << F_SHIFT) /* only stat directories and symlinks but use d_type */
static FTS *
__fts_open(argv, sp)
errno = EINVAL;
return (NULL);
}
+ if (options & FTS_NOSTAT_TYPE) options |= FTS_NOSTAT;
/* Allocate/initialize the stream */
if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
errno = EINVAL;
return (NULL);
}
+ if (options & FTS_NOSTAT_TYPE) options |= FTS_NOSTAT;
/* Allocate/initialize the stream */
if ((sp = malloc((u_int)sizeof(FTS))) == NULL)
if (instr == FTS_FOLLOW &&
(p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) {
p->fts_info = fts_stat(sp, p, 1);
- if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR))
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
if ((p->fts_symfd = open(".", O_RDONLY, 0)) < 0) {
p->fts_errno = errno;
p->fts_info = FTS_ERR;
- } else
+ } else {
p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ }
return (p);
}
if (p->fts_info == FTS_D) {
/* If skipped or crossed mount point, do post-order visit. */
if (instr == FTS_SKIP ||
- ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev) {
+ (ISSET(FTS_XDEV) && p->fts_dev != sp->fts_dev)) {
if (p->fts_flags & FTS_SYMFOLLOW)
(void)close(p->fts_symfd);
if (sp->fts_child) {
}
p->fts_info = FTS_DP;
return (p);
- }
+ }
/* Rebuild if only read the names and now traversing. */
if (sp->fts_child && sp->fts_options & FTS_NAMEONLY) {
/* Move to the next node on this level. */
next: tmp = p;
- if (p = p->fts_link) {
+ if ((p = p->fts_link)) {
/*
* If reached the top, return to the original directory, and
* load the paths for the next root.
}
if (p->fts_instr == FTS_FOLLOW) {
p->fts_info = fts_stat(sp, p, 1);
- if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR))
+ if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) {
if ((p->fts_symfd =
open(".", O_RDONLY, 0)) < 0) {
p->fts_errno = errno;
p->fts_info = FTS_ERR;
- } else
+ } else {
p->fts_flags |= FTS_SYMFOLLOW;
+ }
+ }
p->fts_instr = FTS_NOINSTR;
}
/* Move up to the parent node. */
p = tmp->fts_parent;
- free(tmp);
if (p->fts_level == FTS_ROOTPARENTLEVEL) {
/*
* Done; free everything up and set errno to 0 so the user
* can distinguish between error and EOF.
*/
+ free(tmp);
free(p);
errno = 0;
return (sp->fts_cur = NULL);
return (NULL);
}
}
+ free(tmp);
p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP;
return (sp->fts_cur = p);
}
if (type == BNAMES)
dostat = F_NOSTAT;
+ else if (ISSET(FTS_NOSTAT_TYPE))
+ dostat = ISSET(FTS_PHYSICAL) ? F_D_TYPE : F_D_TYPESYM;
else if (ISSET(FTS_NOSTAT))
dostat = ISSET(FTS_PHYSICAL) ? F_STATDIR : F_STATDIRSYM;
else
/* Read the directory, attaching each entry to the `link' pointer. */
adjaddr = NULL;
- for (head = tail = NULL, nitems = 0; dp = readdir(dirp);) {
+ for (head = tail = NULL, nitems = 0; (dp = readdir(dirp)) ; ) {
if (!ISSET(FTS_SEEDOT) && ISDOT(dp->d_name))
continue;
case (F_ALWAYSSTAT | DT_LNK):
case (F_ALWAYSSTAT | DT_SOCK):
case (F_ALWAYSSTAT | DT_WHT):
+ case (F_D_TYPE | DT_UNKNOWN):
+ case (F_D_TYPE | DT_DIR):
+ case (F_D_TYPESYM | DT_UNKNOWN):
+ case (F_D_TYPESYM | DT_DIR):
+ case (F_D_TYPESYM | DT_LNK):
/* Build a file name for fts_stat to stat. */
if (ISSET(FTS_NOCHDIR)) {
p->fts_accpath = p->fts_path;
/* Stat it. */
p->fts_info = fts_stat(sp, p, 0);
break;
+ case (F_D_TYPE | DT_FIFO):
+ case (F_D_TYPE | DT_CHR):
+ case (F_D_TYPE | DT_BLK):
+ case (F_D_TYPE | DT_SOCK):
+ case (F_D_TYPESYM | DT_FIFO):
+ case (F_D_TYPESYM | DT_CHR):
+ case (F_D_TYPESYM | DT_BLK):
+ case (F_D_TYPESYM | DT_SOCK):
+ p->fts_info = FTS_DEFAULT;
+ goto common_no_stat;
+ case (F_D_TYPE | DT_REG):
+ case (F_D_TYPESYM | DT_REG):
+ p->fts_info = FTS_F;
+ goto common_no_stat;
+ case (F_D_TYPE | DT_LNK):
+ p->fts_info = FTS_SL;
+ goto common_no_stat;
+ case (F_D_TYPE | DT_WHT):
+ case (F_D_TYPESYM | DT_WHT):
+ p->fts_info = FTS_W;
+ goto common_no_stat;
default:
/* No stat necessary */
+ p->fts_info = FTS_NSOK;
+common_no_stat:
p->fts_accpath =
ISSET(FTS_NOCHDIR) ? p->fts_path : p->fts_name;
- p->fts_info = FTS_NSOK;
break;
}
}
register FTSENT *p;
/* Free a linked list of structures. */
- while (p = head) {
+ while ((p = head)) {
head = head->fts_link;
free(p);
}
* Allow essentially unlimited paths; find, rm, ls should all work on any tree.
* Most systems will allow creation of paths much longer than MAXPATHLEN, even
* though the kernel won't resolve them. Add the size (not just what's needed)
- * plus 256 bytes so don't realloc the path 2 bytes at a time.
+ * plus 256 bytes so don't realloc the path 2 bytes at a time.
*/
static int
fts_palloc(sp, more)
static void check_env_var(void) {
char *mode = getenv("COMMAND_MODE");
-
+
if (mode) {
if (!strcasecmp(mode, "legacy")) {
unix2003_mode = false;
char *op = NULL;
- if (op = strpbrk(mode, "!^&|")) {
+ if ((op = strpbrk(mode, "!^&|"))) {
if (*op == '!') {
if (op != mode) goto syn_error;
return !compat_mode(function, mode +1);
/* XXX char tmp[] would be better for left_arg, but
we are not sure what the max size should be... is
alloca(3) frowned on? */
- int left_sz = 1 + (op - mode);
+ size_t left_sz = 1 + (op - mode);
char *left_arg = malloc(left_sz);
strlcpy(left_arg, mode, left_sz);
bool left = compat_mode(function, left_arg);
.It Fa ty_name
The name of the character-special file.
.It Fa ty_getty
-The name of the command invoked by
-.Xr init 8
+The name of the command invoked
to initialize tty line characteristics.
.It Fa ty_type
The name of the default terminal type connected to this tty line.
The possible flags are as follows:
.Bl -tag -width TTY_NETWORK
.It Dv TTY_ON
-Enables logins (i.e.,
-.Xr init 8
-will start the command referenced by
-.Fa ty_getty
-on this entry).
+Enables logins
.It Dv TTY_SECURE
Allow users with a uid of 0 to login on this terminal.
.It Dv TTY_DIALUP
.Xr termcap 5 ,
.Xr ttys 5 ,
.Xr getty 8 ,
-.Xr init 8
.Sh HISTORY
The
.Fn getttyent ,
char fmt[NAME_MAX + 17];
};
-static char brapat[] = "\\[(.*)]";
+static const char *brapat = "\\[(.*)]";
static regex_t brapreg;
-static char decpat[] = "^([0-9]+)-([0-9]+)$";
+static const char *decpat = "^([0-9]+)-([0-9]+)$";
static regex_t decpreg;
-static char hexpat[] = "^0x([0-9a-f]+)-0x([0-9a-f]+)$";
+static const char *hexpat = "^0x([0-9a-f]+)-0x([0-9a-f]+)$";
static regex_t hexpreg;
static struct seq *seq = NULL;
static int slot;
struct ttyent *
-getttyent()
+getttyent(void)
{
static struct ttyent tty;
- static struct ttyent nonexistent = {
+ static const struct ttyent nonexistent = {
"\01", /* this shouldn't match anything */
NULL,
NULL,
* entries until we catch up.
*/
slot++;
- return &nonexistent;
+ return (struct ttyent *)&nonexistent;
}
if (seq->count > 0) {
* /etc/shells.
*/
-static char *okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
+static const char * const okshells[] = { _PATH_BSHELL, _PATH_CSHELL, NULL };
static char **curshell, **shells, *strings;
static char **initshells(void);
* Get a list of shells from _PATH_SHELLS, if it exists.
*/
char *
-getusershell()
+getusershell(void)
{
char *ret;
}
void
-endusershell()
+endusershell(void)
{
-
if (shells != NULL)
free(shells);
shells = NULL;
}
void
-setusershell()
+setusershell(void)
{
-
curshell = initshells();
}
static char **
-initshells()
+initshells(void)
{
register char **sp, *cp;
register FILE *fp;
free(strings);
strings = NULL;
if ((fp = fopen(_PATH_SHELLS, "r")) == NULL)
- return (okshells);
+ return ((char **)okshells);
if (fstat(fileno(fp), &statb) == -1) {
(void)fclose(fp);
- return (okshells);
+ return ((char **)okshells);
}
if ((strings = malloc((u_int)statb.st_size)) == NULL) {
(void)fclose(fp);
- return (okshells);
+ return ((char **)okshells);
}
shells = calloc((unsigned)statb.st_size / 3, sizeof (char *));
if (shells == NULL) {
(void)fclose(fp);
free(strings);
strings = NULL;
- return (okshells);
+ return ((char **)okshells);
}
sp = shells;
cp = strings;
+++ /dev/null
-/*
- * Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <math.h>
-
-/* 3BSD compatibility function */
-#undef isinf
-int
-isinf(double d)
-{
- return __inline_isinfd(d);
-}
+++ /dev/null
-/*
- * Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <math.h>
-
-/* 3BSD compatibility function */
-#undef isnan
-int
-isnan(double d)
-{
- return __inline_isnand(d);
-}
+++ /dev/null
-/*
- * Copyright (c) 1999, 2006, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/* Author: Bertrand Serlet, August 1999 */
-
-/*
- Multithread enhancements for "tiny" allocations introduced February 2008.
- These are in the spirit of "Hoard". See:
- Berger, E.D.; McKinley, K.S.; Blumofe, R.D.; Wilson, P.R. (2000).
- "Hoard: a scalable memory allocator for multithreaded applications".
- ACM SIGPLAN Notices 35 (11): 117-128. Berger2000.
- <http://portal.acm.org/citation.cfm?id=356989.357000>
- Retrieved on 2008-02-22.
-*/
-
-/* gcc -g -O3 magazine_malloc.c malloc.c -o libmagmalloc.dylib -I. \
- -I/System/Library/Frameworks/System.framework/PrivateHeaders/ -funit-at-a-time \
- -dynamiclib -Wall -arch x86_64 -arch i386 -arch ppc */
-
-#include <TargetConditionals.h>
-
-#include "scalable_malloc.h"
-#include "malloc_printf.h"
-#include "_simple.h"
-#include "magmallocProvider.h"
-
-#include <pthread_internals.h> /* for pthread_lock_t SPI */
-#include <pthread.h> /* for pthread API */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <mach/vm_statistics.h>
-#include <mach/mach_init.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-#include <sys/param.h>
-
-#if defined(__i386__) || defined(__x86_64__)
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#define _COMM_PAGE_VERSION_REQD 9
-#undef __APPLE_API_PRIVATE
-#else
-#include <sys/sysctl.h>
-#endif
-
-#include <libkern/OSAtomic.h>
-#include <mach-o/dyld.h> /* for NSVersionOfLinkTimeLibrary() */
-#include <mach-o/dyld_priv.h> /* for _dyld_get_image_slide() */
-#include <crt_externs.h> /* for _NSGetMachExecuteHeader() */
-#include <mach/vm_param.h>
-#include <sys/vmparam.h>
-
-#include <CrashReporterClient.h>
-
-/********************* DEFINITIONS ************************/
-
-#define DEBUG_MALLOC 0 // set to one to debug malloc itself
-
-#define DEBUG_CLIENT 0 // set to one to debug malloc client
-
-#define DEBUG_MADVISE 0
-
-// <rdar://problem/10397726>
-#define RELAXED_INVARIANT_CHECKS 1
-
-#if DEBUG_MALLOC
-#warning DEBUG_MALLOC ENABLED
-# define INLINE
-# define ALWAYSINLINE
-# define CHECK_MAGAZINE_PTR_LOCKED(szone, mag_ptr, fun) \
-do { \
- if (__is_threaded && TRY_LOCK(mag_ptr->magazine_lock)) { \
- malloc_printf("*** magazine_lock was not set %p in %s\n", \
- mag_ptr->magazine_lock, fun); \
- } \
-} while (0)
-#else
-# define INLINE __inline__
-# define ALWAYSINLINE __attribute__((always_inline))
-# define CHECK_MAGAZINE_PTR_LOCKED(szone, mag_ptr, fun) {}
-#endif
-
-# define NOINLINE __attribute__((noinline))
-
-#if defined(__i386__) || defined(__x86_64__)
-#define CACHE_ALIGN __attribute__ ((aligned (128) )) /* Future-proofing at 128B */
-#elif defined(__ppc__) || defined(__ppc64__)
-#define CACHE_ALIGN __attribute__ ((aligned (128) ))
-#else
-#define CACHE_ALIGN
-#endif
-
-#if !__LP64__
-#define ASLR_INTERNAL 1
-#endif
-
-/*
- * Access to global variables is slow, so optimise our handling of vm_page_size
- * and vm_page_shift.
- */
-#define _vm_page_size vm_page_size /* to get to the originals */
-#define _vm_page_shift vm_page_shift
-#define vm_page_size 4096 /* our normal working sizes */
-#define vm_page_shift 12
-
-/*
- * msize - a type to refer to the number of quanta of a tiny or small
- * allocation. A tiny block with an msize of 3 would be 3 << SHIFT_TINY_QUANTUM
- * bytes in size.
- */
-typedef unsigned short msize_t;
-
-typedef union {
- void *p;
- uintptr_t u;
-} ptr_union;
-
-typedef struct {
- ptr_union previous;
- ptr_union next;
-} free_list_t;
-
-typedef unsigned int grain_t; // N.B. wide enough to index all free slots
-
-typedef int mag_index_t;
-
-#define CHECK_REGIONS (1 << 31)
-#define DISABLE_ASLR (1 << 30)
-
-#define MAX_RECORDER_BUFFER 256
-
-/********************* DEFINITIONS for tiny ************************/
-
-/*
- * Memory in the Tiny range is allocated from regions (heaps) pointed to by the
- * szone's hashed_regions pointer.
- *
- * Each region is laid out as a heap, followed by a header block, all within
- * a 1MB (2^20) block. This means there are 64520 16-byte blocks and the header
- * is 16138 bytes, making the total 1048458 bytes, leaving 118 bytes unused.
- *
- * The header block is arranged as in struct tiny_region defined just below, and
- * consists of two bitfields (or bit arrays) interleaved 32 bits by 32 bits.
- *
- * Each bitfield comprises NUM_TINY_BLOCKS bits, and refers to the corresponding
- * TINY_QUANTUM block within the heap.
- *
- * The bitfields are used to encode the state of memory within the heap. The header bit indicates
- * that the corresponding quantum is the first quantum in a block (either in use or free). The
- * in-use bit is set for the header if the block has been handed out (allocated). If the header
- * bit is not set, the in-use bit is invalid.
- *
- * The szone maintains an array of NUM_TINY_SLOTS freelists, each of which is used to hold
- * free objects of the corresponding quantum size.
- *
- * A free block is laid out depending on its size, in order to fit all free
- * blocks in 16 bytes, on both 32 and 64 bit platforms. One quantum blocks do
- * not store their size in the block, instead relying on the header information
- * to determine their size. Blocks of two or more quanta have room to store
- * their size in the block, and store it both after the 'next' pointer, and in
- * the last 2 bytes of the block.
- *
- * 1-quantum block
- * Offset (32-bit mode) (64-bit mode)
- * 0x0 0x0 : previous
- * 0x4 0x08 : next
- * end end
- *
- * >1-quantum block
- * Offset (32-bit mode) (64-bit mode)
- * 0x0 0x0 : previous
- * 0x4 0x08 : next
- * 0x8 0x10 : size (in quantum counts)
- * end - 2 end - 2 : size (in quantum counts)
- * end end
- *
- * All fields are pointer-sized, except for the size which is an unsigned short.
- *
- */
-
-#define SHIFT_TINY_QUANTUM 4 // Required for AltiVec
-#define TINY_QUANTUM (1 << SHIFT_TINY_QUANTUM)
-
-#define FOLLOWING_TINY_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM))
-
-#ifdef __LP64__
-#define NUM_TINY_SLOTS 64 // number of slots for free-lists
-#else
-#define NUM_TINY_SLOTS 32 // number of slots for free-lists
-#endif
-
-#define NUM_TINY_BLOCKS 64520
-#define SHIFT_TINY_CEIL_BLOCKS 16 // ceil(log2(NUM_TINY_BLOCKS))
-#define NUM_TINY_CEIL_BLOCKS (1 << SHIFT_TINY_CEIL_BLOCKS)
-#define TINY_BLOCKS_ALIGN (SHIFT_TINY_CEIL_BLOCKS + SHIFT_TINY_QUANTUM) // 20
-
-#define TINY_ENTROPY_BITS 15
-#define TINY_ENTROPY_MASK ((1 << TINY_ENTROPY_BITS) - 1)
-
-/*
- * Avoid having so much entropy that the end of a valid tiny allocation
- * might overrun the end of the tiny region.
- */
-#if TINY_ENTROPY_MASK + NUM_TINY_SLOTS > NUM_TINY_BLOCKS
-#error Too many entropy bits for tiny region requested
-#endif
-
-/*
- * Enough room for the data, followed by the bit arrays (2-bits per block)
- * plus rounding to the nearest page.
- */
-#define CEIL_NUM_TINY_BLOCKS_WORDS (((NUM_TINY_BLOCKS + 31) & ~31) >> 5)
-#define TINY_METADATA_SIZE (sizeof(region_trailer_t) + sizeof(tiny_header_inuse_pair_t) * CEIL_NUM_TINY_BLOCKS_WORDS)
-#define TINY_REGION_SIZE \
- ((NUM_TINY_BLOCKS * TINY_QUANTUM + TINY_METADATA_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1))
-
-#define TINY_METADATA_START (NUM_TINY_BLOCKS * TINY_QUANTUM)
-
-/*
- * Beginning and end pointers for a region's heap.
- */
-#define TINY_REGION_ADDRESS(region) ((void *)(region))
-#define TINY_REGION_END(region) ((void *)(((uintptr_t)(region)) + (NUM_TINY_BLOCKS * TINY_QUANTUM)))
-
-/*
- * Locate the heap base for a pointer known to be within a tiny region.
- */
-#define TINY_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << TINY_BLOCKS_ALIGN) - 1)))
-
-/*
- * Convert between byte and msize units.
- */
-#define TINY_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_TINY_QUANTUM)
-#define TINY_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_TINY_QUANTUM)
-
-#ifdef __LP64__
-# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[8])
-#else
-# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[4])
-#endif
-#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1]
-
-/*
- * Layout of a tiny region
- */
-typedef uint32_t tiny_block_t[4]; // assert(TINY_QUANTUM == sizeof(tiny_block_t))
-
-typedef struct tiny_header_inuse_pair
-{
- uint32_t header;
- uint32_t inuse;
-} tiny_header_inuse_pair_t;
-
-typedef struct region_trailer
-{
- struct region_trailer *prev;
- struct region_trailer *next;
- boolean_t recirc_suitable;
- boolean_t failedREUSE;
- volatile int pinned_to_depot;
- unsigned bytes_used;
- mag_index_t mag_index;
-} region_trailer_t;
-
-typedef struct tiny_region
-{
- tiny_block_t blocks[NUM_TINY_BLOCKS];
-
- region_trailer_t trailer;
-
- // The interleaved bit arrays comprising the header and inuse bitfields.
- // The unused bits of each component in the last pair will be initialized to sentinel values.
- tiny_header_inuse_pair_t pairs[CEIL_NUM_TINY_BLOCKS_WORDS];
-
- uint8_t pad[TINY_REGION_SIZE - (NUM_TINY_BLOCKS * sizeof(tiny_block_t)) - TINY_METADATA_SIZE];
-} *tiny_region_t;
-
-/*
- * Per-region meta data for tiny allocator
- */
-#define REGION_TRAILER_FOR_TINY_REGION(r) (&(((tiny_region_t)(r))->trailer))
-#define MAGAZINE_INDEX_FOR_TINY_REGION(r) (REGION_TRAILER_FOR_TINY_REGION(r)->mag_index)
-#define BYTES_USED_FOR_TINY_REGION(r) (REGION_TRAILER_FOR_TINY_REGION(r)->bytes_used)
-
-/*
- * Locate the block header for a pointer known to be within a tiny region.
- */
-#define TINY_BLOCK_HEADER_FOR_PTR(_p) ((void *)&(((tiny_region_t)TINY_REGION_FOR_PTR(_p))->pairs))
-
-/*
- * Locate the inuse map for a given block header pointer.
- */
-#define TINY_INUSE_FOR_HEADER(_h) ((void *)&(((tiny_header_inuse_pair_t *)(_h))->inuse))
-
-/*
- * Compute the bitmap index for a pointer known to be within a tiny region.
- */
-#define TINY_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_CEIL_BLOCKS - 1))
-
-#define TINY_CACHE 1 // This governs a last-free cache of 1 that bypasses the free-list
-
-#if ! TINY_CACHE
-#warning TINY_CACHE turned off
-#endif
-
-#define TINY_REGION_PAYLOAD_BYTES (NUM_TINY_BLOCKS * TINY_QUANTUM)
-
-/********************* DEFINITIONS for small ************************/
-
-/*
- * Memory in the Small range is allocated from regions (heaps) pointed to by the szone's hashed_regions
- * pointer.
- *
- * Each region is laid out as a heap, followed by the metadata array, all within an 8MB (2^23) block.
- * The array is arranged as an array of shorts, one for each SMALL_QUANTUM in the heap.
- * This means there are 16320 512-blocks and the array is 16320*2 bytes, which totals 8388480, leaving
- * 128 bytes unused.
- *
- * The MSB of each short is set for the first quantum in a free block. The low 15 bits encode the
- * block size (in SMALL_QUANTUM units), or are zero if the quantum is not the first in a block.
- *
- * The szone maintains an array of 32 freelists, each of which is used to hold free objects
- * of the corresponding quantum size.
- *
- * A free block is laid out as:
- *
- * Offset (32-bit mode) (64-bit mode)
- * 0x0 0x0 : previous
- * 0x4 0x08 : next
- * 0x8 0x10 : size (in quantum counts)
- * end - 2 end - 2 : size (in quantum counts)
- * end end
- *
- * All fields are pointer-sized, except for the size which is an unsigned short.
- *
- */
-
-#define SMALL_IS_FREE (1 << 15)
-
-#define SHIFT_SMALL_QUANTUM (SHIFT_TINY_QUANTUM + 5) // 9
-#define SMALL_QUANTUM (1 << SHIFT_SMALL_QUANTUM) // 512 bytes
-
-#define FOLLOWING_SMALL_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_SMALL_QUANTUM))
-
-/*
- * The number of slots in the free-list for small blocks. To avoid going to
- * vm system as often on large memory machines, increase the number of free list
- * spots above some amount of RAM installed in the system.
- */
-#define NUM_SMALL_SLOTS 32
-#define NUM_SMALL_SLOTS_LARGEMEM 256
-#define SMALL_BITMAP_WORDS 8
-
-/*
- * We can only represent up to 1<<15 for msize; but we choose to stay even below that to avoid the
- * convention msize=0 => msize = (1<<15)
- */
-#define NUM_SMALL_BLOCKS 16320
-#define SHIFT_SMALL_CEIL_BLOCKS 14 // ceil(log2(NUM_SMALL_BLOCKs))
-#define NUM_SMALL_CEIL_BLOCKS (1 << SHIFT_SMALL_CEIL_BLOCKS)
-#define SMALL_BLOCKS_ALIGN (SHIFT_SMALL_CEIL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23
-
-#define SMALL_ENTROPY_BITS 13
-#define SMALL_ENTROPY_MASK ((1 << SMALL_ENTROPY_BITS) - 1)
-
-/*
- * Avoid having so much entropy that the end of a valid small allocation
- * might overrun the end of the small region.
- */
-#if SMALL_ENTROPY_MASK + NUM_SMALL_SLOTS > NUM_SMALL_BLOCKS
-#error Too many entropy bits for small region requested
-#endif
-
-#define SMALL_METADATA_SIZE (sizeof(region_trailer_t) + NUM_SMALL_BLOCKS * sizeof(msize_t))
-#define SMALL_REGION_SIZE \
- ((NUM_SMALL_BLOCKS * SMALL_QUANTUM + SMALL_METADATA_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1))
-
-#define SMALL_METADATA_START (NUM_SMALL_BLOCKS * SMALL_QUANTUM)
-
-/*
- * Beginning and end pointers for a region's heap.
- */
-#define SMALL_REGION_ADDRESS(region) ((unsigned char *)region)
-#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region) + (NUM_SMALL_BLOCKS * SMALL_QUANTUM))
-
-/*
- * Locate the heap base for a pointer known to be within a small region.
- */
-#define SMALL_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << SMALL_BLOCKS_ALIGN) - 1)))
-
-/*
- * Convert between byte and msize units.
- */
-#define SMALL_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_SMALL_QUANTUM)
-#define SMALL_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_SMALL_QUANTUM)
-
-#define SMALL_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1]
-
-/*
- * Layout of a small region
- */
-typedef uint32_t small_block_t[SMALL_QUANTUM/sizeof(uint32_t)];
-
-typedef struct small_region
-{
- small_block_t blocks[NUM_SMALL_BLOCKS];
-
- region_trailer_t trailer;
-
- msize_t small_meta_words[NUM_SMALL_BLOCKS];
-
- uint8_t pad[SMALL_REGION_SIZE - (NUM_SMALL_BLOCKS * sizeof(small_block_t)) - SMALL_METADATA_SIZE];
-} *small_region_t;
-
-/*
- * Per-region meta data for small allocator
- */
-#define REGION_TRAILER_FOR_SMALL_REGION(r) (&(((small_region_t)(r))->trailer))
-#define MAGAZINE_INDEX_FOR_SMALL_REGION(r) (REGION_TRAILER_FOR_SMALL_REGION(r)->mag_index)
-#define BYTES_USED_FOR_SMALL_REGION(r) (REGION_TRAILER_FOR_SMALL_REGION(r)->bytes_used)
-
-/*
- * Locate the metadata base for a pointer known to be within a small region.
- */
-#define SMALL_META_HEADER_FOR_PTR(_p) (((small_region_t)SMALL_REGION_FOR_PTR(_p))->small_meta_words)
-
-/*
- * Compute the metadata index for a pointer known to be within a small region.
- */
-#define SMALL_META_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_CEIL_BLOCKS - 1))
-
-/*
- * Find the metadata word for a pointer known to be within a small region.
- */
-#define SMALL_METADATA_FOR_PTR(_p) (SMALL_META_HEADER_FOR_PTR(_p) + SMALL_META_INDEX_FOR_PTR(_p))
-
-/*
- * Determine whether a pointer known to be within a small region points to memory which is free.
- */
-#define SMALL_PTR_IS_FREE(_p) (*SMALL_METADATA_FOR_PTR(_p) & SMALL_IS_FREE)
-
-/*
- * Extract the msize value for a pointer known to be within a small region.
- */
-#define SMALL_PTR_SIZE(_p) (*SMALL_METADATA_FOR_PTR(_p) & ~SMALL_IS_FREE)
-
-#define SMALL_CACHE 1
-#if !SMALL_CACHE
-#warning SMALL_CACHE turned off
-#endif
-
-#define SMALL_REGION_PAYLOAD_BYTES (NUM_SMALL_BLOCKS * SMALL_QUANTUM)
-
-/************************* DEFINITIONS for large ****************************/
-
-#define LARGE_THRESHOLD (15 * 1024) // strictly above this use "large"
-#define LARGE_THRESHOLD_LARGEMEM (127 * 1024)
-
-#if (LARGE_THRESHOLD > NUM_SMALL_SLOTS * SMALL_QUANTUM)
-#error LARGE_THRESHOLD should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM
-#endif
-
-#if (LARGE_THRESHOLD_LARGEMEM > NUM_SMALL_SLOTS_LARGEMEM * SMALL_QUANTUM)
-#error LARGE_THRESHOLD_LARGEMEM should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM
-#endif
-
-/*
- * When all memory is touched after a copy, vm_copy() is always a lose
- * But if the memory is only read, vm_copy() wins over memmove() at 3 or 4 pages
- * (on a G3/300MHz)
- *
- * This must be larger than LARGE_THRESHOLD
- */
-#define VM_COPY_THRESHOLD (40 * 1024)
-#define VM_COPY_THRESHOLD_LARGEMEM (128 * 1024)
-
-typedef struct {
- vm_address_t address;
- vm_size_t size;
- boolean_t did_madvise_reusable;
-} large_entry_t;
-
-#if !TARGET_OS_EMBEDDED
-#define LARGE_CACHE 1
-#else
-#define LARGE_CACHE 0
-#endif
-#if !LARGE_CACHE
-#warning LARGE_CACHE turned off
-#endif
-#if defined(__LP64__)
-#define LARGE_ENTRY_CACHE_SIZE 16
-#define LARGE_CACHE_SIZE_LIMIT ((vm_size_t)0x80000000) /* 2Gb */
-#else
-#define LARGE_ENTRY_CACHE_SIZE 8
-#define LARGE_CACHE_SIZE_LIMIT ((vm_size_t)0x02000000) /* 32Mb */
-#endif
-#define LARGE_CACHE_SIZE_ENTRY_LIMIT (LARGE_CACHE_SIZE_LIMIT/LARGE_ENTRY_CACHE_SIZE)
-
-#define SZONE_FLOTSAM_THRESHOLD_LOW (1024 * 512)
-#define SZONE_FLOTSAM_THRESHOLD_HIGH (1024 * 1024)
-
-/*******************************************************************************
- * Definitions for region hash
- ******************************************************************************/
-
-typedef void * region_t;
-typedef region_t * rgnhdl_t; /* A pointer into hashed_regions array. */
-
-#define INITIAL_NUM_REGIONS_SHIFT 6 // log2(INITIAL_NUM_REGIONS)
-#define INITIAL_NUM_REGIONS (1 << INITIAL_NUM_REGIONS_SHIFT) // Must be a power of 2!
-#define HASHRING_OPEN_ENTRY ((region_t) 0) // Initial value and sentinel marking end of collision chain
-#define HASHRING_REGION_DEALLOCATED ((region_t)-1) // Region at this slot reclaimed by OS
-#define HASH_BLOCKS_ALIGN TINY_BLOCKS_ALIGN // MIN( TINY_BLOCKS_ALIGN, SMALL_BLOCKS_ALIGN, ... )
-
-typedef struct region_hash_generation {
- size_t num_regions_allocated;
- size_t num_regions_allocated_shift; // log2(num_regions_allocated)
- region_t *hashed_regions; // hashed by location
- struct region_hash_generation *nextgen;
-} region_hash_generation_t;
-
-/*******************************************************************************
- * Per-processor magazine for tiny and small allocators
- ******************************************************************************/
-
-typedef struct { // vm_allocate()'d, so the array of magazines is page-aligned to begin with.
- // Take magazine_lock first, Depot lock when needed for recirc, then szone->{tiny,small}_regions_lock when needed for alloc
- pthread_lock_t magazine_lock CACHE_ALIGN;
- // Protection for the crtical section that does allocate_pages outside the magazine_lock
- volatile boolean_t alloc_underway;
-
- // One element deep "death row", optimizes malloc/free/malloc for identical size.
- void *mag_last_free; // low SHIFT_{TINY,SMALL}_QUANTUM bits indicate the msize
- region_t mag_last_free_rgn; // holds the region for mag_last_free
-
- free_list_t *mag_free_list[256]; // assert( 256 >= MAX( NUM_TINY_SLOTS, NUM_SMALL_SLOTS_LARGEMEM ))
- unsigned mag_bitmap[8]; // assert( sizeof(mag_bitmap) << 3 >= sizeof(mag_free_list)/sizeof(free_list_t) )
-
- // the first and last free region in the last block are treated as big blocks in use that are not accounted for
- size_t mag_bytes_free_at_end;
- size_t mag_bytes_free_at_start;
- region_t mag_last_region; // Valid iff mag_bytes_free_at_end || mag_bytes_free_at_start > 0
-
- // bean counting ...
- unsigned mag_num_objects;
- size_t mag_num_bytes_in_objects;
- size_t num_bytes_in_magazine;
-
- // recirculation list -- invariant: all regions owned by this magazine that meet the emptiness criteria
- // are located nearer to the head of the list than any region that doesn't satisfy that criteria.
- // Doubly linked list for efficient extraction.
- unsigned recirculation_entries;
- region_trailer_t *firstNode;
- region_trailer_t *lastNode;
-
-#if __LP64__
- uint64_t pad[48]; // So sizeof(magazine_t) is 2560 bytes. FIXME: assert this at compile time
-#else
- uint32_t pad[12]; // So sizeof(magazine_t) is 1280 bytes. FIXME: assert this at compile time
-#endif
-} magazine_t;
-
-#define TINY_MAX_MAGAZINES 32 /* MUST BE A POWER OF 2! */
-#define TINY_MAGAZINE_PAGED_SIZE \
- (((sizeof(magazine_t) * (TINY_MAX_MAGAZINES + 1)) + vm_page_size - 1) &\
- ~ (vm_page_size - 1)) /* + 1 for the Depot */
-
-#define SMALL_MAX_MAGAZINES 32 /* MUST BE A POWER OF 2! */
-#define SMALL_MAGAZINE_PAGED_SIZE \
- (((sizeof(magazine_t) * (SMALL_MAX_MAGAZINES + 1)) + vm_page_size - 1) &\
- ~ (vm_page_size - 1)) /* + 1 for the Depot */
-
-#define DEPOT_MAGAZINE_INDEX -1
-
-/****************************** zone itself ***********************************/
-
-/*
- * Note that objects whose adddress are held in pointers here must be pursued
- * individually in the {tiny,small}_in_use_enumeration() routines. See for
- * example the treatment of region_hash_generation and tiny_magazines below.
- */
-
-typedef struct szone_s { // vm_allocate()'d, so page-aligned to begin with.
- malloc_zone_t basic_zone; // first page will be given read-only protection
- uint8_t pad[vm_page_size - sizeof(malloc_zone_t)];
-
- pthread_key_t cpu_id_key; // remainder of structure is R/W (contains no function pointers)
- unsigned debug_flags;
- void *log_address;
-
- /* Regions for tiny objects */
- pthread_lock_t tiny_regions_lock CACHE_ALIGN;
- size_t num_tiny_regions;
- size_t num_tiny_regions_dealloc;
- region_hash_generation_t *tiny_region_generation;
- region_hash_generation_t trg[2];
-
- int num_tiny_magazines;
- unsigned num_tiny_magazines_mask;
- int num_tiny_magazines_mask_shift;
- magazine_t *tiny_magazines; // array of per-processor magazines
-
-#if TARGET_OS_EMBEDDED
- uintptr_t last_tiny_advise;
-#endif
-
- /* Regions for small objects */
- pthread_lock_t small_regions_lock CACHE_ALIGN;
- size_t num_small_regions;
- size_t num_small_regions_dealloc;
- region_hash_generation_t *small_region_generation;
- region_hash_generation_t srg[2];
-
- unsigned num_small_slots; // determined by physmem size
-
- int num_small_magazines;
- unsigned num_small_magazines_mask;
- int num_small_magazines_mask_shift;
- magazine_t *small_magazines; // array of per-processor magazines
-
-#if TARGET_OS_EMBEDDED
- uintptr_t last_small_advise;
-#endif
-
- /* large objects: all the rest */
- pthread_lock_t large_szone_lock CACHE_ALIGN; // One customer at a time for large
- unsigned num_large_objects_in_use;
- unsigned num_large_entries;
- large_entry_t *large_entries; // hashed by location; null entries don't count
- size_t num_bytes_in_large_objects;
-
-#if LARGE_CACHE
- int large_entry_cache_oldest;
- int large_entry_cache_newest;
- large_entry_t large_entry_cache[LARGE_ENTRY_CACHE_SIZE]; // "death row" for large malloc/free
- boolean_t large_legacy_reset_mprotect;
- size_t large_entry_cache_reserve_bytes;
- size_t large_entry_cache_reserve_limit;
- size_t large_entry_cache_bytes; // total size of death row, bytes
-#endif
-
- /* flag and limits pertaining to altered malloc behavior for systems with
- large amounts of physical memory */
- unsigned is_largemem;
- unsigned large_threshold;
- unsigned vm_copy_threshold;
-
- /* security cookie */
- uintptr_t cookie;
-
- /* Initial region list */
- region_t initial_tiny_regions[INITIAL_NUM_REGIONS];
- region_t initial_small_regions[INITIAL_NUM_REGIONS];
-
- /* The purgeable zone constructed by create_purgeable_zone() would like to hand off tiny and small
- * allocations to the default scalable zone. Record the latter as the "helper" zone here. */
- struct szone_s *helper_zone;
-
- boolean_t flotsam_enabled;
-} szone_t;
-
-#define SZONE_PAGED_SIZE ((sizeof(szone_t) + vm_page_size - 1) & ~ (vm_page_size - 1))
-
-#if DEBUG_MALLOC || DEBUG_CLIENT
-static void szone_sleep(void);
-#endif
-__private_extern__ void malloc_error_break(void);
-
-// msg prints after fmt, ...
-static NOINLINE void szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...)
- __printflike(5, 6);
-
-static void protect(void *address, size_t size, unsigned protection, unsigned debug_flags);
-static void *allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags,
- int vm_page_label);
-static void *allocate_pages_securely(szone_t *szone, size_t size, unsigned char align,
- int vm_page_label);
-static void deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags);
-#if TARGET_OS_EMBEDDED
-static int madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi, uintptr_t *last);
-#else
-static int madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi);
-#endif
-static kern_return_t _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr);
-
-static INLINE mag_index_t mag_get_thread_index(szone_t *szone) ALWAYSINLINE;
-static magazine_t *mag_lock_zine_for_region_trailer(szone_t *szone, magazine_t *magazines, region_trailer_t *trailer,
- mag_index_t mag_index);
-
-static INLINE rgnhdl_t hash_lookup_region_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r)
- ALWAYSINLINE;
-static void hash_region_insert_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r);
-static region_t *hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries);
-static region_t *hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size,
- size_t *mutable_shift, size_t *new_size);
-
-static INLINE uintptr_t free_list_gen_checksum(uintptr_t ptr) ALWAYSINLINE;
-static INLINE uintptr_t free_list_checksum_ptr(szone_t *szone, void *p) ALWAYSINLINE;
-static INLINE void *free_list_unchecksum_ptr(szone_t *szone, ptr_union *ptr) ALWAYSINLINE;
-static unsigned free_list_count(szone_t *szone, free_list_t *ptr);
-
-static INLINE void recirc_list_extract(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) ALWAYSINLINE;
-static INLINE void recirc_list_splice_last(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) ALWAYSINLINE;
-static INLINE void recirc_list_splice_first(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node) ALWAYSINLINE;
-
-static INLINE void BITARRAY_SET(uint32_t *bits, msize_t index) ALWAYSINLINE;
-static INLINE void BITARRAY_CLR(uint32_t *bits, msize_t index) ALWAYSINLINE;
-static INLINE boolean_t BITARRAY_BIT(uint32_t *bits, msize_t index) ALWAYSINLINE;
-
-static msize_t get_tiny_free_size(const void *ptr);
-static msize_t get_tiny_previous_free_msize(const void *ptr);
-static INLINE msize_t get_tiny_meta_header(const void *ptr, boolean_t *is_free) ALWAYSINLINE;
-static INLINE void set_tiny_meta_header_in_use(const void *ptr, msize_t msize) ALWAYSINLINE;
-static INLINE void set_tiny_meta_header_in_use_1(const void *ptr) ALWAYSINLINE;
-static INLINE void set_tiny_meta_header_middle(const void *ptr) ALWAYSINLINE;
-static INLINE void set_tiny_meta_header_free(const void *ptr, msize_t msize) ALWAYSINLINE;
-static INLINE boolean_t tiny_meta_header_is_free(const void *ptr) ALWAYSINLINE;
-static INLINE void *tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) ALWAYSINLINE;
-
-static void tiny_free_list_add_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize);
-static void tiny_free_list_remove_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize);
-static INLINE region_t tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE;
-
-static void tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr);
-static int tiny_free_detach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r);
-static size_t tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r);
-static void tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r);
-static region_t tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node);
-static boolean_t tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index);
-static region_t tiny_find_msize_region(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize);
-static boolean_t tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize);
-
-static INLINE boolean_t tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region,
- void *ptr, msize_t msize) ALWAYSINLINE;
-static void *tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index,
- msize_t msize, void *fresh_region);
-static boolean_t tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size);
-static boolean_t tiny_check_region(szone_t *szone, region_t region);
-static kern_return_t tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone,
- memory_reader_t reader, vm_range_recorder_t recorder);
-static void *tiny_malloc_from_free_list(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index,
- msize_t msize);
-static INLINE void *tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE;
-static INLINE void free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size) ALWAYSINLINE;
-static void print_tiny_free_list(szone_t *szone);
-static void print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end);
-static boolean_t tiny_free_list_check(szone_t *szone, grain_t slot);
-
-static INLINE void small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize) ALWAYSINLINE;
-static INLINE void small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) ALWAYSINLINE;
-static INLINE void small_meta_header_set_middle(msize_t *meta_headers, msize_t index) ALWAYSINLINE;
-static void small_free_list_add_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize);
-static void small_free_list_remove_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize);
-static INLINE region_t small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE;
-
-static void small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr);
-static int small_free_detach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r);
-static size_t small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r);
-static void small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r);
-static region_t small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node);
-static boolean_t small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index);
-static region_t small_find_msize_region(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize);
-static boolean_t small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize);
-static INLINE boolean_t small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region,
- void *ptr, msize_t msize) ALWAYSINLINE;
-static void *small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index,
- msize_t msize, void *fresh_region);
-static boolean_t small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size);
-static boolean_t small_check_region(szone_t *szone, region_t region);
-static kern_return_t small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone,
- memory_reader_t reader, vm_range_recorder_t recorder);
-static void *small_malloc_from_free_list(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index,
- msize_t msize);
-static INLINE void *small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE;
-static INLINE void free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size) ALWAYSINLINE;
-static void print_small_free_list(szone_t *szone);
-static void print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end);
-static boolean_t small_free_list_check(szone_t *szone, grain_t grain);
-
-#if DEBUG_MALLOC
-static void large_debug_print(szone_t *szone);
-#endif
-static large_entry_t *large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr);
-static void large_entry_insert_no_lock(szone_t *szone, large_entry_t range);
-static INLINE void large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) ALWAYSINLINE;
-static INLINE large_entry_t *large_entries_alloc_no_lock(szone_t *szone, unsigned num) ALWAYSINLINE;
-static void large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num,
- vm_range_t *range_to_deallocate);
-static large_entry_t *large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate);
-static vm_range_t large_entry_free_no_lock(szone_t *szone, large_entry_t *entry);
-static NOINLINE kern_return_t large_in_use_enumerator(task_t task, void *context,
- unsigned type_mask, vm_address_t large_entries_address,
- unsigned num_entries, memory_reader_t reader,
- vm_range_recorder_t recorder);
-static void *large_malloc(szone_t *szone, size_t num_pages, unsigned char alignment, boolean_t cleared_requested);
-static NOINLINE void free_large(szone_t *szone, void *ptr);
-static INLINE int large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE;
-
-/*
- * Mark these NOINLINE to avoid bloating the purgeable zone call backs
- */
-static NOINLINE void szone_free(szone_t *szone, void *ptr);
-static NOINLINE void *szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested);
-static NOINLINE void *szone_malloc(szone_t *szone, size_t size);
-static NOINLINE void *szone_calloc(szone_t *szone, size_t num_items, size_t size);
-static NOINLINE void *szone_valloc(szone_t *szone, size_t size);
-static NOINLINE size_t szone_size_try_large(szone_t *szone, const void *ptr);
-static NOINLINE size_t szone_size(szone_t *szone, const void *ptr);
-static NOINLINE void *szone_realloc(szone_t *szone, void *ptr, size_t new_size);
-static NOINLINE void *szone_memalign(szone_t *szone, size_t alignment, size_t size);
-static NOINLINE void szone_free_definite_size(szone_t *szone, void *ptr, size_t size);
-static NOINLINE unsigned szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count);
-static NOINLINE void szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count);
-static void szone_destroy(szone_t *szone);
-static NOINLINE size_t szone_good_size(szone_t *szone, size_t size);
-
-static NOINLINE boolean_t szone_check_all(szone_t *szone, const char *function);
-static boolean_t szone_check(szone_t *szone);
-static kern_return_t szone_ptr_in_use_enumerator(task_t task, void *context,
- unsigned type_mask, vm_address_t zone_address,
- memory_reader_t reader, vm_range_recorder_t recorder);
-static NOINLINE void szone_print(szone_t *szone, boolean_t verbose);
-static void szone_log(malloc_zone_t *zone, void *log_address);
-static void szone_force_lock(szone_t *szone);
-static void szone_force_unlock(szone_t *szone);
-static boolean_t szone_locked(szone_t *szone);
-
-static void szone_statistics(szone_t *szone, malloc_statistics_t *stats);
-
-static void purgeable_free(szone_t *szone, void *ptr);
-static void *purgeable_malloc(szone_t *szone, size_t size);
-static void *purgeable_calloc(szone_t *szone, size_t num_items, size_t size);
-static void *purgeable_valloc(szone_t *szone, size_t size);
-static size_t purgeable_size(szone_t *szone, const void *ptr);
-static void *purgeable_realloc(szone_t *szone, void *ptr, size_t new_size);
-static void *purgeable_memalign(szone_t *szone, size_t alignment, size_t size);
-static void purgeable_free_definite_size(szone_t *szone, void *ptr, size_t size);
-static unsigned purgeable_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count);
-static void purgeable_batch_free(szone_t *szone, void **to_be_freed, unsigned count);
-static void purgeable_destroy(szone_t *szone);
-static size_t purgeable_good_size(szone_t *szone, size_t size);
-
-static boolean_t purgeable_check(szone_t *szone);
-static kern_return_t purgeable_ptr_in_use_enumerator(task_t task, void *context,
- unsigned type_mask, vm_address_t zone_address,
- memory_reader_t reader, vm_range_recorder_t recorder);
-static void purgeable_print(szone_t *szone, boolean_t verbose);
-static void purgeable_log(malloc_zone_t *zone, void *log_address);
-static void purgeable_force_lock(szone_t *szone);
-static void purgeable_force_unlock(szone_t *szone);
-static boolean_t purgeable_locked(szone_t *szone);
-
-static void purgeable_statistics(szone_t *szone, malloc_statistics_t *stats);
-
-static void *frozen_malloc(szone_t *zone, size_t new_size);
-static void *frozen_calloc(szone_t *zone, size_t num_items, size_t size);
-static void *frozen_valloc(szone_t *zone, size_t new_size);
-static void *frozen_realloc(szone_t *zone, void *ptr, size_t new_size);
-static void frozen_free(szone_t *zone, void *ptr);
-static void frozen_destroy(szone_t *zone);
-
-static volatile uintptr_t entropic_address = 0;
-static volatile uintptr_t entropic_limit = 0;
-#define ENTROPIC_KABILLION 0x10000000 /* 256Mb */
-
-__private_extern__ uint64_t malloc_entropy[2];
-
-#define SZONE_LOCK(szone) \
- do { \
- LOCK(szone->large_szone_lock); \
- } while (0)
-
-#define SZONE_UNLOCK(szone) \
- do { \
- UNLOCK(szone->large_szone_lock); \
- } while (0)
-
-#define SZONE_TRY_LOCK(szone) \
- TRY_LOCK(szone->large_szone_lock);
-
-#define SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr) \
- do { \
- LOCK(mag_ptr->magazine_lock); \
- } while(0)
-
-#define SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr) \
- do { \
- UNLOCK(mag_ptr->magazine_lock); \
- } while(0)
-
-#define SZONE_MAGAZINE_PTR_TRY_LOCK(szone, mag_ptr) \
- TRY_LOCK(mag_ptr->magazine_lock);
-
-#if DEBUG_MALLOC
-# define LOG(szone,ptr) \
- (szone->log_address && (((uintptr_t)szone->log_address == -1) || \
- (szone->log_address == (void *)(ptr))))
-#else
-# define LOG(szone,ptr) 0
-#endif
-
-#if DEBUG_MALLOC || DEBUG_CLIENT
-# define CHECK(szone,fun) \
- if ((szone)->debug_flags & CHECK_REGIONS) \
- szone_check_all(szone, fun)
-#else
-# define CHECK(szone,fun) \
- do {} while (0)
-#endif
-
-/********************* VERY LOW LEVEL UTILITIES ************************/
-
-static void
-szone_sleep(void)
-{
- if (getenv("MallocErrorStop")) {
- _malloc_printf(ASL_LEVEL_NOTICE, "*** sending SIGSTOP to help debug\n");
- kill(getpid(), SIGSTOP);
- } else if (getenv("MallocErrorSleep")) {
- _malloc_printf(ASL_LEVEL_NOTICE, "*** sleeping to help debug\n");
- sleep(3600); // to help debug
- }
-}
-
-// msg prints after fmt, ...
-static NOINLINE void
-szone_error(szone_t *szone, int is_corruption, const char *msg, const void *ptr, const char *fmt, ...)
-{
- va_list ap;
- _SIMPLE_STRING b = _simple_salloc();
-
- if (szone) SZONE_UNLOCK(szone); // FIXME: unlock magazine and region locks?
- if (b) {
- if (fmt) {
- va_start(ap, fmt);
- _simple_vsprintf(b, fmt, ap);
- va_end(ap);
- }
- if (ptr) {
- _simple_sprintf(b, "*** error for object %p: %s\n", ptr, msg);
- } else {
- _simple_sprintf(b, "*** error: %s\n", msg);
- }
- malloc_printf("%s*** set a breakpoint in malloc_error_break to debug\n", _simple_string(b));
- } else {
- /*
- * Should only get here if vm_allocate() can't get a single page of
- * memory, implying _simple_asl_log() would also fail. So we just
- * print to the file descriptor.
- */
- if (fmt) {
- va_start(ap, fmt);
- _malloc_vprintf(MALLOC_PRINTF_NOLOG, fmt, ap);
- va_end(ap);
- }
- if (ptr) {
- _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error for object %p: %s\n", ptr, msg);
- } else {
- _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error: %s\n", msg);
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG, "*** set a breakpoint in malloc_error_break to debug\n");
- }
- malloc_error_break();
-#if DEBUG_MALLOC
- szone_print(szone, 1);
-#endif
- szone_sleep();
- // Call abort() if this is a memory corruption error and the abort on
- // corruption flag is set, or if any error should abort.
- if ((is_corruption && (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_CORRUPTION)) ||
- (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_ERROR)) {
- CRSetCrashLogMessage(b ? _simple_string(b) : msg);
- abort();
- } else if (b) {
- _simple_sfree(b);
- }
-}
-
-static void
-protect(void *address, size_t size, unsigned protection, unsigned debug_flags)
-{
- kern_return_t err;
-
- if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_PRELUDE)) {
- err = mprotect((void *)((uintptr_t)address - vm_page_size), vm_page_size, protection);
- if (err) {
- malloc_printf("*** can't protect(%p) region for prelude guard page at %p\n",
- protection,(uintptr_t)address - (1 << vm_page_shift));
- }
- }
- if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE)) {
- err = mprotect((void *)((uintptr_t)address + size), vm_page_size, protection);
- if (err) {
- malloc_printf("*** can't protect(%p) region for postlude guard page at %p\n",
- protection, (uintptr_t)address + size);
- }
- }
-}
-
-static void *
-allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label)
-{
- // align specifies a desired alignment (as a log) or 0 if no alignment requested
- void *vm_addr;
- uintptr_t addr = 0, aligned_address;
- boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES;
- boolean_t purgeable = debug_flags & SCALABLE_MALLOC_PURGEABLE;
- size_t allocation_size = round_page(size);
- size_t delta;
- int alloc_flags = VM_MAKE_TAG(vm_page_label);
-
- if (align) add_guard_pages = 0; // too cumbersome to deal with that
- if (!allocation_size) allocation_size = 1 << vm_page_shift;
- if (add_guard_pages) allocation_size += 2 * (1 << vm_page_shift);
- if (align) allocation_size += (size_t)1 << align;
- if (purgeable) alloc_flags |= VM_FLAGS_PURGABLE;
-
- if (allocation_size < size) // size_t arithmetic wrapped!
- return NULL;
-
- vm_addr = mmap(0 /* addr */,
- allocation_size /* size */,
- PROT_READ | PROT_WRITE /* prot */,
- MAP_ANON | MAP_PRIVATE /* flags */,
- alloc_flags /* fd being used to pass "purgeable" and "vm_page_label" */,
- 0 /* offset */);
- if ((uintptr_t)vm_addr == -1) {
- szone_error(szone, 0, "can't allocate region", NULL, "*** mmap(size=%lu) failed (error code=%d)\n",
- allocation_size, errno);
- return NULL;
- }
- addr = (uintptr_t)vm_addr;
-
- if (align) {
- aligned_address = (addr + ((uintptr_t)1 << align) - 1) & ~ (((uintptr_t)1 << align) - 1);
- if (aligned_address != addr) {
- delta = aligned_address - addr;
- if (munmap((void *)addr, delta) == -1)
- malloc_printf("*** munmap unaligned header failed with %d\n", errno);
- addr = aligned_address;
- allocation_size -= delta;
- }
- if (allocation_size > size) {
- if (munmap((void *)(addr + size), allocation_size - size) == -1)
- malloc_printf("*** munmap unaligned footer failed with %d\n", errno);
- }
- }
- if (add_guard_pages) {
- addr += (uintptr_t)1 << vm_page_shift;
- protect((void *)addr, size, PROT_NONE, debug_flags);
- }
- return (void *)addr;
-}
-
-static void *
-allocate_pages_securely(szone_t *szone, size_t size, unsigned char align, int vm_page_label)
-{
- // align specifies a desired alignment (as a log) or 0 if no alignment requested
- void *vm_addr;
- uintptr_t addr, aligned_address;
- size_t delta, allocation_size = MAX(round_page(size), vm_page_size);
- int alloc_flags = VM_MAKE_TAG(vm_page_label);
-
- if (szone->debug_flags & DISABLE_ASLR)
- return allocate_pages(szone, size, align, 0, vm_page_label);
-
- if (align)
- allocation_size += (size_t)1 << align;
-
- if (allocation_size < size) // size_t arithmetic wrapped!
- return NULL;
-
-retry:
- vm_addr = mmap((void *)entropic_address /* kernel finds next available range at or above this address */,
- allocation_size /* size */,
- PROT_READ | PROT_WRITE /* prot */,
- MAP_ANON | MAP_PRIVATE /* flags */,
- alloc_flags /* fd being used to pass "vm_page_label" */,
- 0 /* offset */);
- if (MAP_FAILED == vm_addr) {
- szone_error(szone, 0, "can't allocate region securely", NULL, "*** mmap(size=%lu) failed (error code=%d)\n",
- size, errno);
- return NULL;
- }
- addr = (uintptr_t)vm_addr;
-
- // Don't allow allocation to rise above entropic_limit (for tidiness).
- if (addr + allocation_size > entropic_limit) { // Exhausted current range?
- uintptr_t t = entropic_address;
- uintptr_t u = t - ENTROPIC_KABILLION;
-
- if (u < t) { // provided we don't wrap, unmap and retry, in the expanded entropic range
- munmap((void *)addr, allocation_size);
- (void)__sync_bool_compare_and_swap(&entropic_address, t, u); // Just one reduction please
- goto retry;
- }
- // fall through to use what we got
- }
-
- if (addr < entropic_address) { // mmap wrapped to find this allocation, expand the entropic range
- uintptr_t t = entropic_address;
- uintptr_t u = t - ENTROPIC_KABILLION;
- if (u < t)
- (void)__sync_bool_compare_and_swap(&entropic_address, t, u); // Just one reduction please
- // fall through to use what we got
- }
-
- // unmap any excess address range used for alignment padding
- if (align) {
- aligned_address = (addr + ((uintptr_t)1 << align) - 1) & ~ (((uintptr_t)1 << align) - 1);
- if (aligned_address != addr) {
- delta = aligned_address - addr;
- if (munmap((void *)addr, delta) == -1)
- malloc_printf("*** munmap unaligned header failed with %d\n", errno);
- addr = aligned_address;
- allocation_size -= delta;
- }
- if (allocation_size > size) {
- if (munmap((void *)(addr + size), allocation_size - size) == -1)
- malloc_printf("*** munmap unaligned footer failed with %d\n", errno);
- }
- }
- return (void *)addr;
-}
-
-static void
-deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags)
-{
- int err;
- boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES;
-
- if (add_guard_pages) {
- addr = (void *)((uintptr_t)addr - (1 << vm_page_shift));
- size += 2 * (1 << vm_page_shift);
- }
- err = munmap(addr, size);
- if ((err == -1) && szone)
- szone_error(szone, 0, "Can't deallocate_pages region", addr, NULL);
-}
-
-static int
-#if TARGET_OS_EMBEDDED
-madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi, uintptr_t *last)
-#else
-madvise_free_range(szone_t *szone, region_t r, uintptr_t pgLo, uintptr_t pgHi)
-#endif
-{
- if (pgHi > pgLo) {
- size_t len = pgHi - pgLo;
-
-#if DEBUG_MALLOC
- if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE)
- memset((void *)pgLo, 0xed, len); // Scribble on MADV_FREEd memory
-#endif
-
-#if TARGET_OS_EMBEDDED
- if (last) {
- if (*last == pgLo)
- return 0;
-
- *last = pgLo;
- }
-#endif
-
- MAGMALLOC_MADVFREEREGION((void *)szone, (void *)r, (void *)pgLo, len); // DTrace USDT Probe
-#if TARGET_OS_EMBEDDED
- if (-1 == madvise((void *)pgLo, len, MADV_FREE)) {
-#else
- if (-1 == madvise((void *)pgLo, len, MADV_FREE_REUSABLE)) {
-#endif
- /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */
-#if DEBUG_MADVISE
- szone_error(szone, 0, "madvise_free_range madvise(..., MADV_FREE_REUSABLE) failed",
- (void *)pgLo, "length=%d\n", len);
-#endif
- }
- }
- return 0;
-}
-
-static kern_return_t
-_szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr)
-{
- *ptr = (void *)address;
- return 0;
-}
-
-// Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...]
-// pthread_t's are page aligned, (sometimes even in ascending sequence). These hash well.
-// See Knuth TAOCP, Vol. 3.
-#if __LP64__
-#define HASH_SELF() \
- ((((uintptr_t)pthread_self()) >> vm_page_shift) * 11400714819323198549ULL) >> (64 - szone->num_tiny_magazines_mask_shift)
-#else
-#define HASH_SELF() \
- ((((uintptr_t)pthread_self()) >> vm_page_shift) * 2654435761UL) >> (32 - szone->num_tiny_magazines_mask_shift)
-#endif
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
-/*
- * These commpage routines provide fast access to the logical cpu number
- * of the calling processor assuming no pre-emption occurs.
- */
-
-static INLINE mag_index_t
-mag_get_thread_index(szone_t *szone)
-{
- if (!__is_threaded)
- return 0;
- else
- return cpu_number() & (TINY_MAX_MAGAZINES - 1);
-}
-
-#else
-#warning deriving magazine index from pthread_self() [want processor number]
-
-static INLINE mag_index_t
-mag_get_thread_index(szone_t *szone)
-{
- if (!__is_threaded)
- return 0;
- else if ((pthread_key_t) -1 == szone->cpu_id_key) { // In case pthread_key_create() failed.
- return HASH_SELF();
- } else {
- mag_index_t idx = (mag_index_t)(intptr_t)pthread_getspecific(szone->cpu_id_key);
-
- // Has this thread been hinted with a non-zero value [i.e. 1 + cpuid()] ?
- // If so, bump down the hint to a zero-based magazine index and return it.
- if (idx) {
- return idx - 1;
- } else {
- // No hint available. Contruct a magazine index for this thread ...
- idx = HASH_SELF();
-
- // bump up the hint to exclude zero and try to memorize it ...
- pthread_setspecific(szone->cpu_id_key, (const void *)((uintptr_t)idx + 1));
-
- // and return the (zero-based) magazine index.
- return idx;
- }
- }
-}
-#endif
-
-static magazine_t *
-mag_lock_zine_for_region_trailer(szone_t *szone, magazine_t *magazines, region_trailer_t *trailer, mag_index_t mag_index)
-{
- mag_index_t refreshed_index;
- magazine_t *mag_ptr = &(magazines[mag_index]);
-
- // Take the lock on entry.
- SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr);
-
- // Now in the time it took to acquire the lock, the region may have migrated
- // from one magazine to another. In which case the magazine lock we obtained
- // (namely magazines[mag_index].mag_lock) is stale. If so, keep on tryin' ...
- while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone, mag_ptr);
-
- mag_index = refreshed_index;
- mag_ptr = &(magazines[mag_index]);
- SZONE_MAGAZINE_PTR_LOCK(szone, mag_ptr);
- }
-
- return mag_ptr;
-}
-
-/*******************************************************************************
- * Region hash implementation
- *
- * This is essentially a duplicate of the existing Large allocator hash, minus
- * the ability to remove entries. The two should be combined eventually.
- ******************************************************************************/
-#pragma mark region hash
-
-/*
- * hash_lookup_region_no_lock - Scan a hash ring looking for an entry for a
- * given region.
- *
- * FIXME: If consecutive queries of the same region are likely, a one-entry
- * cache would likely be a significant performance win here.
- */
-static INLINE rgnhdl_t
-hash_lookup_region_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) {
- size_t index, hash_index;
- rgnhdl_t entry;
-
- if (!num_entries)
- return 0;
-
- // Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...]
- // Since the values of (((uintptr_t)r >> HASH_BLOCKS_ALIGN) are (roughly) an ascending sequence of integers,
- // this hash works really well. See Knuth TAOCP, Vol. 3.
-#if __LP64__
- index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 11400714819323198549ULL) >> (64 - shift);
-#else
- index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 2654435761UL) >> (32 - shift);
-#endif
- do {
- entry = regions + index;
- if (*entry == 0)
- return 0;
- if (*entry == r)
- return entry;
- if (++index == num_entries)
- index = 0;
- } while (index != hash_index);
- return 0;
-}
-
-/*
- * hash_region_insert_no_lock - Insert a region into the hash ring.
- */
-static void
-hash_region_insert_no_lock(region_t *regions, size_t num_entries, size_t shift, region_t r) {
- size_t index, hash_index;
- rgnhdl_t entry;
-
- // Multiplicative hash where the multiplier is a prime near (ULONG_MAX / phi). [phi = 1.618033...]
- // Since the values of (((uintptr_t)r >> HASH_BLOCKS_ALIGN) are (roughly) an ascending sequence of integers,
- // this hash works really well. See Knuth TAOCP, Vol. 3.
-#if __LP64__
- index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 11400714819323198549ULL) >> (64 - shift);
-#else
- index = hash_index = (((uintptr_t)r >> HASH_BLOCKS_ALIGN) * 2654435761UL) >> (32 - shift);
-#endif
- do {
- entry = regions + index;
- if (*entry == HASHRING_OPEN_ENTRY || *entry == HASHRING_REGION_DEALLOCATED) {
- *entry = r;
- return;
- }
- if (++index == num_entries)
- index = 0;
- } while (index != hash_index);
-}
-
-/*
- * hash_regions_alloc_no_lock - Allocate space for a number of entries. This
- * must be a VM allocation as to avoid recursing between allocating a new small
- * region, and asking the small region to allocate space for the new list of
- * regions.
- */
-static region_t *
-hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries)
-{
- size_t size = num_entries * sizeof(region_t);
-
- return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC);
-}
-
-/*
- * hash_regions_grow_no_lock - Grow the hash ring, and rehash the entries.
- * Return the new region and new size to update the szone. Do not deallocate
- * the old entries since someone may still be allocating them.
- */
-static region_t *
-hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, size_t *mutable_shift,
- size_t *new_size)
-{
- // double in size and allocate memory for the regions
- *new_size = old_size + old_size;
- *mutable_shift = *mutable_shift + 1;
- region_t *new_regions = hash_regions_alloc_no_lock(szone, *new_size);
-
- // rehash the entries into the new list
- size_t index;
- for (index = 0; index < old_size; ++index) {
- region_t r = regions[index];
- if (r != HASHRING_OPEN_ENTRY && r != HASHRING_REGION_DEALLOCATED)
- hash_region_insert_no_lock(new_regions, *new_size, *mutable_shift, r);
- }
- return new_regions;
-}
-
-/********************* FREE LIST UTILITIES ************************/
-
-// A free list entry is comprised of a pair of pointers, previous and next.
-// These are used to implement a doubly-linked list, which permits efficient
-// extraction.
-//
-// Because the free list entries are previously freed objects, a misbehaved
-// program may write to a pointer after it has called free() on that pointer,
-// either by dereference or buffer overflow from an adjacent pointer. This write
-// would then corrupt the free list's previous and next pointers, leading to a
-// crash. In order to detect this case, we take advantage of the fact that
-// malloc'd pointers are known to be at least 16 byte aligned, and thus have
-// at least 4 trailing zero bits.
-//
-// When an entry is added to the free list, a checksum of the previous and next
-// pointers is calculated and written to the high four bits of the respective
-// pointers. Upon detection of an invalid checksum, an error is logged and NULL
-// is returned. Since all code which un-checksums pointers checks for a NULL
-// return, a potentially crashing or malicious dereference is avoided at the
-// cost of leaking the corrupted block, and any subsequent blocks on the free
-// list of that size.
-
-static NOINLINE void
-free_list_checksum_botch(szone_t *szone, free_list_t *ptr)
-{
- szone_error(szone, 1, "incorrect checksum for freed object "
- "- object was probably modified after being freed.", ptr, NULL);
-}
-
-static INLINE uintptr_t free_list_gen_checksum(uintptr_t ptr)
-{
- uint8_t chk;
-
- chk = (unsigned char)(ptr >> 0);
- chk += (unsigned char)(ptr >> 8);
- chk += (unsigned char)(ptr >> 16);
- chk += (unsigned char)(ptr >> 24);
-#if __LP64__
- chk += (unsigned char)(ptr >> 32);
- chk += (unsigned char)(ptr >> 40);
- chk += (unsigned char)(ptr >> 48);
- chk += (unsigned char)(ptr >> 56);
-#endif
-
- return chk & (uintptr_t)0xF;
-}
-
-#define NYBBLE 4
-#if __LP64__
-#define ANTI_NYBBLE (64 - NYBBLE)
-#else
-#define ANTI_NYBBLE (32 - NYBBLE)
-#endif
-
-static INLINE uintptr_t
-free_list_checksum_ptr(szone_t *szone, void *ptr)
-{
- uintptr_t p = (uintptr_t)ptr;
- return (p >> NYBBLE) | (free_list_gen_checksum(p ^ szone->cookie) << ANTI_NYBBLE); // compiles to rotate instruction
-}
-
-static INLINE void *
-free_list_unchecksum_ptr(szone_t *szone, ptr_union *ptr)
-{
- ptr_union p;
- uintptr_t t = ptr->u;
-
- t = (t << NYBBLE) | (t >> ANTI_NYBBLE); // compiles to rotate instruction
- p.u = t & ~(uintptr_t)0xF;
-
- if ((t & (uintptr_t)0xF) != free_list_gen_checksum(p.u ^ szone->cookie))
- {
- free_list_checksum_botch(szone, (free_list_t *)ptr);
- return NULL;
- }
- return p.p;
-}
-
-#undef ANTI_NYBBLE
-#undef NYBBLE
-
-static unsigned
-free_list_count(szone_t *szone, free_list_t *ptr)
-{
- unsigned count = 0;
-
- while (ptr) {
- count++;
- ptr = free_list_unchecksum_ptr(szone, &ptr->next);
- }
- return count;
-}
-
-static INLINE void
-recirc_list_extract(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node)
-{
- // excise node from list
- if (NULL == node->prev)
- mag_ptr->firstNode = node->next;
- else
- node->prev->next = node->next;
-
- if (NULL == node->next)
- mag_ptr->lastNode = node->prev;
- else
- node->next->prev = node->prev;
-
- mag_ptr->recirculation_entries--;
-}
-
-static INLINE void
-recirc_list_splice_last(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node)
-{
- if (NULL == mag_ptr->lastNode) {
- mag_ptr->firstNode = node;
- node->prev = NULL;
- } else {
- node->prev = mag_ptr->lastNode;
- mag_ptr->lastNode->next = node;
- }
- mag_ptr->lastNode = node;
- node->next = NULL;
- node->recirc_suitable = FALSE;
- mag_ptr->recirculation_entries++;
-}
-
-static INLINE void
-recirc_list_splice_first(szone_t *szone, magazine_t *mag_ptr, region_trailer_t *node)
-{
- if (NULL == mag_ptr->firstNode) {
- mag_ptr->lastNode = node;
- node->next = NULL;
- } else {
- node->next = mag_ptr->firstNode;
- mag_ptr->firstNode->prev = node;
- }
- mag_ptr->firstNode = node;
- node->prev = NULL;
- node->recirc_suitable = FALSE;
- mag_ptr->recirculation_entries++;
-}
-
-/* Macros used to manipulate the uint32_t quantity mag_bitmap. */
-
-/* BITMAPV variants are used by tiny. */
-#if defined(__LP64__)
-// assert(NUM_SLOTS == 64) in which case (slot >> 5) is either 0 or 1
-#define BITMAPV_SET(bitmap,slot) (bitmap[(slot) >> 5] |= 1 << ((slot) & 31))
-#define BITMAPV_CLR(bitmap,slot) (bitmap[(slot) >> 5] &= ~ (1 << ((slot) & 31)))
-#define BITMAPV_BIT(bitmap,slot) ((bitmap[(slot) >> 5] >> ((slot) & 31)) & 1)
-#define BITMAPV_CTZ(bitmap) (__builtin_ctzl(bitmap))
-#else
-// assert(NUM_SLOTS == 32) in which case (slot >> 5) is always 0, so code it that way
-#define BITMAPV_SET(bitmap,slot) (bitmap[0] |= 1 << (slot))
-#define BITMAPV_CLR(bitmap,slot) (bitmap[0] &= ~ (1 << (slot)))
-#define BITMAPV_BIT(bitmap,slot) ((bitmap[0] >> (slot)) & 1)
-#define BITMAPV_CTZ(bitmap) (__builtin_ctz(bitmap))
-#endif
-
-/* BITMAPN is used by small. (slot >> 5) takes on values from 0 to 7. */
-#define BITMAPN_SET(bitmap,slot) (bitmap[(slot) >> 5] |= 1 << ((slot) & 31))
-#define BITMAPN_CLR(bitmap,slot) (bitmap[(slot) >> 5] &= ~ (1 << ((slot) & 31)))
-#define BITMAPN_BIT(bitmap,slot) ((bitmap[(slot) >> 5] >> ((slot) & 31)) & 1)
-
-/* returns bit # of least-significant one bit, starting at 0 (undefined if !bitmap) */
-#define BITMAP32_CTZ(bitmap) (__builtin_ctz(bitmap[0]))
-
-/********************* TINY FREE LIST UTILITIES ************************/
-
-// We encode the meta-headers as follows:
-// Each quantum has an associated set of 2 bits:
-// block_header when 1 says this block is the beginning of a block
-// in_use when 1 says this block is in use
-// so a block in use of size 3 is 1-1 0-X 0-X
-// for a free block TINY_FREE_SIZE(ptr) carries the size and the bits are 1-0 X-X X-X
-// for a block middle the bits are 0-0
-
-// We store the meta-header bit arrays by interleaving them 32 bits at a time.
-// Initial 32 bits of block_header, followed by initial 32 bits of in_use, followed
-// by next 32 bits of block_header, followed by next 32 bits of in_use, etc.
-// This localizes memory references thereby reducing cache and TLB pressures.
-
-static INLINE void
-BITARRAY_SET(uint32_t *bits, msize_t index)
-{
- // index >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array
- // (index >> 5) << 1 identifies the uint32_t allowing for the actual interleaving
- bits[(index >> 5) << 1] |= (1 << (index & 31));
-}
-
-static INLINE void
-BITARRAY_CLR(uint32_t *bits, msize_t index)
-{
- bits[(index >> 5) << 1] &= ~(1 << (index & 31));
-}
-
-static INLINE boolean_t
-BITARRAY_BIT(uint32_t *bits, msize_t index)
-{
- return ((bits[(index >> 5) << 1]) >> (index & 31)) & 1;
-}
-
-#if 0
-static INLINE void bitarray_mclr(uint32_t *bits, unsigned start, unsigned end) ALWAYSINLINE;
-
-static INLINE void
-bitarray_mclr(uint32_t *bits, unsigned start, unsigned end)
-{
- // start >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array
- // (start >> 5) << 1 identifies the uint32_t allowing for the actual interleaving
- uint32_t *addr = bits + ((start >> 5) << 1);
-
- uint32_t span = end - start;
- start = start & 31;
- end = start + span;
-
- if (end > 31) {
- addr[0] &= (0xFFFFFFFFU >> (31 - start)) >> 1;
- addr[2] &= (0xFFFFFFFFU << (end - 32));
- } else {
- unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1;
- mask |= (0xFFFFFFFFU << end);
- addr[0] &= mask;
- }
-}
-#endif
-
-/*
- * Obtain the size of a free tiny block (in msize_t units).
- */
-static msize_t
-get_tiny_free_size(const void *ptr)
-{
- void *next_block = (void *)((uintptr_t)ptr + TINY_QUANTUM);
- void *region_end = TINY_REGION_END(TINY_REGION_FOR_PTR(ptr));
-
- // check whether the next block is outside the tiny region or a block header
- // if so, then the size of this block is one, and there is no stored size.
- if (next_block < region_end)
- {
- uint32_t *next_header = TINY_BLOCK_HEADER_FOR_PTR(next_block);
- msize_t next_index = TINY_INDEX_FOR_PTR(next_block);
-
- if (!BITARRAY_BIT(next_header, next_index))
- return TINY_FREE_SIZE(ptr);
- }
- return 1;
-}
-
-/*
- * Get the size of the previous free block, which is stored in the last two
- * bytes of the block. If the previous block is not free, then the result is
- * undefined.
- */
-static msize_t
-get_tiny_previous_free_msize(const void *ptr)
-{
- // check whether the previous block is in the tiny region and a block header
- // if so, then the size of the previous block is one, and there is no stored
- // size.
- if (ptr != TINY_REGION_FOR_PTR(ptr))
- {
- void *prev_block = (void *)((uintptr_t)ptr - TINY_QUANTUM);
- uint32_t *prev_header = TINY_BLOCK_HEADER_FOR_PTR(prev_block);
- msize_t prev_index = TINY_INDEX_FOR_PTR(prev_block);
- if (BITARRAY_BIT(prev_header, prev_index))
- return 1;
- return TINY_PREVIOUS_MSIZE(ptr);
- }
- // don't read possibly unmapped memory before the beginning of the region
- return 0;
-}
-
-static INLINE msize_t
-get_tiny_meta_header(const void *ptr, boolean_t *is_free)
-{
- // returns msize and is_free
- // may return 0 for the msize component (meaning 65536)
- uint32_t *block_header;
- msize_t index;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- index = TINY_INDEX_FOR_PTR(ptr);
-
- msize_t midx = (index >> 5) << 1;
- uint32_t mask = 1 << (index & 31);
- *is_free = 0;
- if (0 == (block_header[midx] & mask)) // if (!BITARRAY_BIT(block_header, index))
- return 0;
- if (0 == (block_header[midx + 1] & mask)) { // if (!BITARRAY_BIT(in_use, index))
- *is_free = 1;
- return get_tiny_free_size(ptr);
- }
-
- // index >> 5 identifies the uint32_t to manipulate in the conceptually contiguous bits array
- // (index >> 5) << 1 identifies the uint32_t allowing for the actual interleaving
-#if defined(__LP64__)
- // The return value, msize, is computed as the distance to the next 1 bit in block_header.
- // That's guaranteed to be somewhwere in the next 64 bits. And those bits could span three
- // uint32_t block_header elements. Collect the bits into a single uint64_t and measure up with ffsl.
- uint32_t *addr = ((uint32_t *)block_header) + ((index >> 5) << 1);
- uint32_t bitidx = index & 31;
- uint64_t word_lo = addr[0];
- uint64_t word_mid = addr[2];
- uint64_t word_hi = addr[4];
- uint64_t word_lomid = (word_lo >> bitidx) | (word_mid << (32 - bitidx));
- uint64_t word = bitidx ? word_lomid | (word_hi << (64 - bitidx)) : word_lomid;
- uint32_t result = __builtin_ffsl(word >> 1);
-#else
- // The return value, msize, is computed as the distance to the next 1 bit in block_header.
- // That's guaranteed to be somwhwere in the next 32 bits. And those bits could span two
- // uint32_t block_header elements. Collect the bits into a single uint32_t and measure up with ffs.
- uint32_t *addr = ((uint32_t *)block_header) + ((index >> 5) << 1);
- uint32_t bitidx = index & 31;
- uint32_t word = bitidx ? (addr[0] >> bitidx) | (addr[2] << (32 - bitidx)) : addr[0];
- uint32_t result = __builtin_ffs(word >> 1);
-#endif
- return result;
-}
-
-static INLINE void
-set_tiny_meta_header_in_use(const void *ptr, msize_t msize)
-{
- uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- msize_t index = TINY_INDEX_FOR_PTR(ptr);
- msize_t clr_msize = msize - 1;
- msize_t midx = (index >> 5) << 1;
- uint32_t val = (1 << (index & 31));
-
-#if DEBUG_MALLOC
- if (msize >= NUM_TINY_SLOTS)
- malloc_printf("set_tiny_meta_header_in_use() invariant broken %p %d\n", ptr, msize);
- if ((unsigned)index + (unsigned)msize > 0x10000)
- malloc_printf("set_tiny_meta_header_in_use() invariant broken (2) %p %d\n", ptr, msize);
-#endif
-
- block_header[midx] |= val; // BITARRAY_SET(block_header, index);
- block_header[midx + 1] |= val; // BITARRAY_SET(in_use, index);
-
- // bitarray_mclr(block_header, index, end_bit);
- // bitarray_mclr(in_use, index, end_bit);
-
- index++;
- midx = (index >> 5) << 1;
-
- unsigned start = index & 31;
- unsigned end = start + clr_msize;
-
-#if defined(__LP64__)
- if (end > 63) {
- unsigned mask0 = (0xFFFFFFFFU >> (31 - start)) >> 1;
- unsigned mask1 = (0xFFFFFFFFU << (end - 64));
- block_header[midx + 0] &= mask0; // clear header
- block_header[midx + 1] &= mask0; // clear in_use
- block_header[midx + 2] = 0; // clear header
- block_header[midx + 3] = 0; // clear in_use
- block_header[midx + 4] &= mask1; // clear header
- block_header[midx + 5] &= mask1; // clear in_use
- } else
-#endif
- if (end > 31) {
- unsigned mask0 = (0xFFFFFFFFU >> (31 - start)) >> 1;
- unsigned mask1 = (0xFFFFFFFFU << (end - 32));
- block_header[midx + 0] &= mask0;
- block_header[midx + 1] &= mask0;
- block_header[midx + 2] &= mask1;
- block_header[midx + 3] &= mask1;
- } else {
- unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1;
- mask |= (0xFFFFFFFFU << end);
- block_header[midx + 0] &= mask;
- block_header[midx + 1] &= mask;
- }
-
- // we set the block_header bit for the following block to reaffirm next block is a block
- index += clr_msize;
- midx = (index >> 5) << 1;
- val = (1 << (index & 31));
- block_header[midx] |= val; // BITARRAY_SET(block_header, (index+clr_msize));
-#if DEBUG_MALLOC
- {
- boolean_t ff;
- msize_t mf;
-
- mf = get_tiny_meta_header(ptr, &ff);
- if (msize != mf) {
- malloc_printf("setting header for tiny in_use %p : %d\n", ptr, msize);
- malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff);
- }
- }
-#endif
-}
-
-static INLINE void
-set_tiny_meta_header_in_use_1(const void *ptr) // As above with msize == 1
-{
- uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- msize_t index = TINY_INDEX_FOR_PTR(ptr);
- msize_t midx = (index >> 5) << 1;
- uint32_t val = (1 << (index & 31));
-
- block_header[midx] |= val; // BITARRAY_SET(block_header, index);
- block_header[midx + 1] |= val; // BITARRAY_SET(in_use, index);
-
- index++;
- midx = (index >> 5) << 1;
- val = (1 << (index & 31));
-
- block_header[midx] |= val; // BITARRAY_SET(block_header, (index+clr_msize))
-}
-
-static INLINE void
-set_tiny_meta_header_middle(const void *ptr)
-{
- // indicates this block is in the middle of an in use block
- uint32_t *block_header;
- uint32_t *in_use;
- msize_t index;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- index = TINY_INDEX_FOR_PTR(ptr);
-
- BITARRAY_CLR(block_header, index);
- BITARRAY_CLR(in_use, index);
-}
-
-static INLINE void
-set_tiny_meta_header_free(const void *ptr, msize_t msize)
-{
- // !msize is acceptable and means 65536
- uint32_t *block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- msize_t index = TINY_INDEX_FOR_PTR(ptr);
- msize_t midx = (index >> 5) << 1;
- uint32_t val = (1 << (index & 31));
-
-#if DEBUG_MALLOC
- if ((unsigned)index + (unsigned)msize > 0x10000) {
- malloc_printf("setting header for tiny free %p msize too large: %d\n", ptr, msize);
- }
-#endif
-
- block_header[midx] |= val; // BITARRAY_SET(block_header, index);
- block_header[midx + 1] &= ~val; // BITARRAY_CLR(in_use, index);
-
- // mark the end of this block if msize is > 1. For msize == 0, the whole
- // region is free, so there is no following block. For msize == 1, there is
- // no space to write the size on 64 bit systems. The size for 1 quantum
- // blocks is computed from the metadata bitmaps.
- if (msize > 1) {
- void *follower = FOLLOWING_TINY_PTR(ptr, msize);
- TINY_PREVIOUS_MSIZE(follower) = msize;
- TINY_FREE_SIZE(ptr) = msize;
- }
- if (msize == 0) {
- TINY_FREE_SIZE(ptr) = msize;
- }
-#if DEBUG_MALLOC
- boolean_t ff;
- msize_t mf = get_tiny_meta_header(ptr, &ff);
- if ((msize != mf) || !ff) {
- malloc_printf("setting header for tiny free %p : %u\n", ptr, msize);
- malloc_printf("reading header for tiny %p : %u %u\n", ptr, mf, ff);
- }
-#endif
-}
-
-static INLINE boolean_t
-tiny_meta_header_is_free(const void *ptr)
-{
- uint32_t *block_header;
- uint32_t *in_use;
- msize_t index;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- index = TINY_INDEX_FOR_PTR(ptr);
- if (!BITARRAY_BIT(block_header, index))
- return 0;
- return !BITARRAY_BIT(in_use, index);
-}
-
-static INLINE void *
-tiny_previous_preceding_free(void *ptr, msize_t *prev_msize)
-{
- // returns the previous block, assuming and verifying it's free
- uint32_t *block_header;
- uint32_t *in_use;
- msize_t index;
- msize_t previous_msize;
- msize_t previous_index;
- void *previous_ptr;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- index = TINY_INDEX_FOR_PTR(ptr);
-
- if (!index)
- return NULL;
- if ((previous_msize = get_tiny_previous_free_msize(ptr)) > index)
- return NULL;
-
- previous_index = index - previous_msize;
- previous_ptr = (void *)((uintptr_t)TINY_REGION_FOR_PTR(ptr) + TINY_BYTES_FOR_MSIZE(previous_index));
- if (!BITARRAY_BIT(block_header, previous_index))
- return NULL;
- if (BITARRAY_BIT(in_use, previous_index))
- return NULL;
- if (get_tiny_free_size(previous_ptr) != previous_msize)
- return NULL;
-
- // conservative check did match true check
- *prev_msize = previous_msize;
- return previous_ptr;
-}
-
-/*
- * Adds an item to the proper free list, and also marks the meta-header of the
- * block properly.
- * Assumes szone has been locked
- */
-static void
-tiny_free_list_add_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize)
-{
- grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1;
- free_list_t *free_ptr = ptr;
- free_list_t *free_head = tiny_mag_ptr->mag_free_list[slot];
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize);
- }
- if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) {
- szone_error(szone, 1, "tiny_free_list_add_ptr: Unaligned ptr", ptr, NULL);
- }
-#endif
- set_tiny_meta_header_free(ptr, msize);
- if (free_head) {
-#if DEBUG_MALLOC
- if (free_list_unchecksum_ptr(szone, &free_head->previous)) {
- szone_error(szone, 1, "tiny_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr,
- "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, (void *)free_head, free_head->previous.p);
- }
- if (! tiny_meta_header_is_free(free_head)) {
- szone_error(szone, 1, "tiny_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr,
- "ptr=%p slot=%d free_head=%p\n", ptr, slot, (void *)free_head);
- }
-#endif
- free_head->previous.u = free_list_checksum_ptr(szone, free_ptr);
- } else {
- BITMAPV_SET(tiny_mag_ptr->mag_bitmap, slot);
- }
- free_ptr->previous.u = free_list_checksum_ptr(szone, NULL);
- free_ptr->next.u = free_list_checksum_ptr(szone, free_head);
-
- tiny_mag_ptr->mag_free_list[slot] = free_ptr;
-}
-
-/*
- * Removes the item pointed to by ptr in the proper free list.
- * Assumes szone has been locked
- */
-static void
-tiny_free_list_remove_ptr(szone_t *szone, magazine_t *tiny_mag_ptr, void *ptr, msize_t msize)
-{
- grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1;
- free_list_t *free_ptr = ptr, *next, *previous;
-
- next = free_list_unchecksum_ptr(szone, &free_ptr->next);
- previous = free_list_unchecksum_ptr(szone, &free_ptr->previous);
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize);
- }
-#endif
- if (!previous) {
- // The block to remove is the head of the free list
-#if DEBUG_MALLOC
- if (tiny_mag_ptr->mag_free_list[slot] != ptr) {
- szone_error(szone, 1, "tiny_free_list_remove_ptr: Internal invariant broken (tiny_mag_ptr->mag_free_list[slot])", ptr,
- "ptr=%p slot=%d msize=%d tiny_mag_ptr->mag_free_list[slot]=%p\n",
- ptr, slot, msize, (void *)tiny_mag_ptr->mag_free_list[slot]);
- return;
- }
-#endif
- tiny_mag_ptr->mag_free_list[slot] = next;
- if (!next) BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot);
- } else {
- // We know free_ptr is already checksummed, so we don't need to do it
- // again.
- previous->next = free_ptr->next;
- }
- if (next) {
- // We know free_ptr is already checksummed, so we don't need to do it
- // again.
- next->previous = free_ptr->previous;
- }
-}
-
-/*
- * tiny_region_for_ptr_no_lock - Returns the tiny region containing the pointer,
- * or NULL if not found.
- */
-static INLINE region_t
-tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr)
-{
- rgnhdl_t r = hash_lookup_region_no_lock(szone->tiny_region_generation->hashed_regions,
- szone->tiny_region_generation->num_regions_allocated,
- szone->tiny_region_generation->num_regions_allocated_shift,
- TINY_REGION_FOR_PTR(ptr));
- return r ? *r : r;
-}
-
-static void
-tiny_finalize_region(szone_t *szone, magazine_t *tiny_mag_ptr) {
- void *last_block, *previous_block;
- uint32_t *last_header;
- msize_t last_msize, previous_msize, last_index;
-
- // It is possible that the block prior to the last block in the region has
- // been free'd, but was not coalesced with the free bytes at the end of the
- // block, since we treat the bytes at the end of the region as "in use" in
- // the meta headers. Attempt to coalesce the last block with the previous
- // block, so we don't violate the "no consecutive free blocks" invariant.
- //
- // FIXME: Need to investigate how much work would be required to increase
- // 'mag_bytes_free_at_end' when freeing the preceding block, rather
- // than performing this workaround.
- //
-
- if (tiny_mag_ptr->mag_bytes_free_at_end) {
- last_block = (void *)
- ((uintptr_t)TINY_REGION_END(tiny_mag_ptr->mag_last_region) - tiny_mag_ptr->mag_bytes_free_at_end);
- last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end);
- last_header = TINY_BLOCK_HEADER_FOR_PTR(last_block);
- last_index = TINY_INDEX_FOR_PTR(last_block);
-
- // Before anything we transform any remaining mag_bytes_free_at_end into a
- // regular free block. We take special care here to update the bitfield
- // information, since we are bypassing the normal free codepath. If there
- // is more than one quanta worth of memory in mag_bytes_free_at_end, then
- // there will be two block headers:
- // 1) header for the free space at end, msize = 1
- // 2) header inserted by set_tiny_meta_header_in_use after block
- // We must clear the second one so that when the free block's size is
- // queried, we do not think the block is only 1 quantum in size because
- // of the second set header bit.
- if (last_index != (NUM_TINY_BLOCKS - 1))
- BITARRAY_CLR(last_header, (last_index + 1));
-
- previous_block = tiny_previous_preceding_free(last_block, &previous_msize);
- if (previous_block) {
- set_tiny_meta_header_middle(last_block);
- tiny_free_list_remove_ptr(szone, tiny_mag_ptr, previous_block, previous_msize);
- last_block = previous_block;
- last_msize += previous_msize;
- }
-
- // splice last_block into the free list
- tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize);
- tiny_mag_ptr->mag_bytes_free_at_end = 0;
- }
-
-#if ASLR_INTERNAL
- // Coalesce the big free block at start with any following free blocks
- if (tiny_mag_ptr->mag_bytes_free_at_start) {
- last_block = TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region);
- last_msize = TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start);
-
- void *next_block = (void *) ((uintptr_t)last_block + tiny_mag_ptr->mag_bytes_free_at_start);
-
- // clear the in use bit we were using to mark the end of the big start block
- set_tiny_meta_header_middle((uintptr_t)next_block - TINY_QUANTUM);
-
- // Coalesce the big start block with any following free blocks
- if (tiny_meta_header_is_free(next_block)) {
- msize_t next_msize = get_tiny_free_size(next_block);
- set_tiny_meta_header_middle(next_block);
- tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize);
- last_msize += next_msize;
- }
-
- // splice last_block into the free list
- tiny_free_list_add_ptr(szone, tiny_mag_ptr, last_block, last_msize);
- tiny_mag_ptr->mag_bytes_free_at_start = 0;
- }
-#endif
-
- tiny_mag_ptr->mag_last_region = NULL;
-}
-
-static int
-tiny_free_detach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r) {
- uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r);
- uintptr_t current = start;
- uintptr_t limit = (uintptr_t)TINY_REGION_END(r);
- boolean_t is_free;
- msize_t msize;
- int total_alloc = 0;
-
- while (current < limit) {
- msize = get_tiny_meta_header((void *)current, &is_free);
- if (is_free && !msize && (current == start)) {
- // first block is all free
- break;
- }
- if (!msize) {
-#if DEBUG_MALLOC
- malloc_printf("*** tiny_free_detach_region error with %p: msize=%d is_free =%d\n",
- (void *)current, msize, is_free);
-#endif
- break;
- }
- if (is_free) {
- tiny_free_list_remove_ptr(szone, tiny_mag_ptr, (void *)current, msize);
- } else {
- total_alloc++;
- }
- current += TINY_BYTES_FOR_MSIZE(msize);
- }
- return total_alloc;
-}
-
-static size_t
-tiny_free_reattach_region(szone_t *szone, magazine_t *tiny_mag_ptr, region_t r) {
- uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r);
- uintptr_t current = start;
- uintptr_t limit = (uintptr_t)TINY_REGION_END(r);
- boolean_t is_free;
- msize_t msize;
- size_t total_alloc = 0;
-
- while (current < limit) {
- msize = get_tiny_meta_header((void *)current, &is_free);
- if (is_free && !msize && (current == start)) {
- // first block is all free
- break;
- }
- if (!msize) {
-#if DEBUG_MALLOC
- malloc_printf("*** tiny_free_reattach_region error with %p: msize=%d is_free =%d\n",
- (void *)current, msize, is_free);
-#endif
- break;
- }
- if (is_free) {
- tiny_free_list_add_ptr(szone, tiny_mag_ptr, (void *)current, msize);
- } else {
- total_alloc += TINY_BYTES_FOR_MSIZE(msize);
- }
- current += TINY_BYTES_FOR_MSIZE(msize);
- }
- return total_alloc;
-}
-
-typedef struct {
- uint8_t pnum, size;
-} tiny_pg_pair_t;
-
-static void NOINLINE /* want private stack frame for automatic array */
-tiny_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) {
- uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(r);
- uintptr_t current = start;
- uintptr_t limit = (uintptr_t)TINY_REGION_END(r);
- boolean_t is_free;
- msize_t msize;
- tiny_pg_pair_t advisory[((TINY_REGION_PAYLOAD_BYTES + vm_page_size - 1) >> vm_page_shift) >> 1]; // 256bytes stack allocated
- int advisories = 0;
-
- // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list
- // management data.
- while (current < limit) {
- msize = get_tiny_meta_header((void *)current, &is_free);
- if (is_free && !msize && (current == start)) {
- // first block is all free
-#if DEBUG_MALLOC
- malloc_printf("*** tiny_free_scan_madvise_free first block is all free! %p: msize=%d is_free =%d\n",
- (void *)current, msize, is_free);
-#endif
- uintptr_t pgLo = round_page(start + sizeof(free_list_t) + sizeof(msize_t));
- uintptr_t pgHi = trunc_page(start + TINY_REGION_SIZE - sizeof(msize_t));
-
- if (pgLo < pgHi) {
- advisory[advisories].pnum = (pgLo - start) >> vm_page_shift;
- advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift;
- advisories++;
- }
- break;
- }
- if (!msize) {
-#if DEBUG_MALLOC
- malloc_printf("*** tiny_free_scan_madvise_free error with %p: msize=%d is_free =%d\n",
- (void *)current, msize, is_free);
-#endif
- break;
- }
- if (is_free) {
- uintptr_t pgLo = round_page(current + sizeof(free_list_t) + sizeof(msize_t));
- uintptr_t pgHi = trunc_page(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t));
-
- if (pgLo < pgHi) {
- advisory[advisories].pnum = (pgLo - start) >> vm_page_shift;
- advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift;
- advisories++;
- }
- }
- current += TINY_BYTES_FOR_MSIZE(msize);
- }
-
- if (advisories > 0) {
- int i;
-
- // So long as the following hold for this region:
- // (1) No malloc()'s are ever performed from the depot (hence free pages remain free,)
- // (2) The region is not handed over to a per-CPU magazine (where malloc()'s could be performed),
- // (3) The entire region is not mumap()'d (so the madvise's are applied to the intended addresses),
- // then the madvise opportunities collected just above can be applied outside all locks.
- // (1) is ensured by design, (2) and (3) are ensured by bumping the globally visible counter node->pinned_to_depot.
-
- OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot));
- SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr);
- for (i = 0; i < advisories; ++i) {
- uintptr_t addr = (advisory[i].pnum << vm_page_shift) + start;
- size_t size = advisory[i].size << vm_page_shift;
-
-#if TARGET_OS_EMBEDDED
- madvise_free_range(szone, r, addr, addr + size, NULL);
-#else
- madvise_free_range(szone, r, addr, addr + size);
-#endif
- }
- SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr);
- OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_TINY_REGION(r)->pinned_to_depot));
- }
-}
-
-static region_t
-tiny_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node)
-{
- if (0 < node->bytes_used ||
- 0 < node->pinned_to_depot ||
- depot_ptr->recirculation_entries < (szone->num_tiny_magazines * 2)) {
- return NULL;
- }
-
- // disconnect node from Depot
- recirc_list_extract(szone, depot_ptr, node);
-
- // Iterate the region pulling its free entries off the (locked) Depot's free list
- region_t sparse_region = TINY_REGION_FOR_PTR(node);
- int objects_in_use = tiny_free_detach_region(szone, depot_ptr, sparse_region);
-
- if (0 == objects_in_use) {
- // Invalidate the hash table entry for this region with HASHRING_REGION_DEALLOCATED.
- // Using HASHRING_REGION_DEALLOCATED preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not.
- rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->tiny_region_generation->hashed_regions,
- szone->tiny_region_generation->num_regions_allocated,
- szone->tiny_region_generation->num_regions_allocated_shift, sparse_region);
- if (NULL == pSlot) {
- szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region);
- return NULL;
- }
- *pSlot = HASHRING_REGION_DEALLOCATED;
- depot_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES;
- __sync_fetch_and_add( &(szone->num_tiny_regions_dealloc), 1); // Atomically increment num_tiny_regions_dealloc
-
- // Caller will transfer ownership of the region back to the OS with no locks held
- MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, TINY_REGION_SIZE); // DTrace USDT Probe
- return sparse_region;
- } else {
- szone_error(szone, 1, "tiny_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use);
- return NULL;
- }
-}
-
-static boolean_t
-tiny_free_do_recirc_to_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index)
-{
- // The entire magazine crossed the "emptiness threshold". Transfer a region
- // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e
- // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list.
- region_trailer_t *node = tiny_mag_ptr->firstNode;
-
- while (node && !node->recirc_suitable) {
- node = node->next;
- }
-
- if (NULL == node) {
-#if DEBUG_MALLOC
- malloc_printf("*** tiny_free_do_recirc_to_depot end of list\n");
-#endif
- return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- }
-
- region_t sparse_region = TINY_REGION_FOR_PTR(node);
-
- // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start
- if (sparse_region == tiny_mag_ptr->mag_last_region && (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start)) {
- tiny_finalize_region(szone, tiny_mag_ptr);
- }
-
- // disconnect "suitable" node from magazine
- recirc_list_extract(szone, tiny_mag_ptr, node);
-
- // Iterate the region pulling its free entries off its (locked) magazine's free list
- int objects_in_use = tiny_free_detach_region(szone, tiny_mag_ptr, sparse_region);
- magazine_t *depot_ptr = &(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]);
-
- // hand over the region to the (locked) Depot
- SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr);
- // this will cause tiny_free_list_add_ptr called by tiny_free_reattach_region to use
- // the depot as its target magazine, rather than magazine formerly associated with sparse_region
- MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX;
- node->pinned_to_depot = 0;
-
- // Iterate the region putting its free entries on Depot's free list
- size_t bytes_inplay = tiny_free_reattach_region(szone, depot_ptr, sparse_region);
-
- tiny_mag_ptr->mag_num_bytes_in_objects -= bytes_inplay;
- tiny_mag_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES;
- tiny_mag_ptr->mag_num_objects -= objects_in_use;
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr); // Unlock the originating magazine
-
- depot_ptr->mag_num_bytes_in_objects += bytes_inplay;
- depot_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES;
- depot_ptr->mag_num_objects += objects_in_use;
-
- // connect to Depot as last node
- recirc_list_splice_last(szone, depot_ptr, node);
-
- MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE,
- (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe
-
- // Mark free'd dirty pages with MADV_FREE to reduce memory pressure
- tiny_free_scan_madvise_free(szone, depot_ptr, sparse_region);
-
- // If the region is entirely empty vm_deallocate() it outside the depot lock
- region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, depot_ptr, node);
- SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr);
- if (r_dealloc)
- deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0);
- return FALSE; // Caller need not unlock the originating magazine
-}
-
-static region_t
-tiny_find_msize_region(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize)
-{
- free_list_t *ptr;
- grain_t slot = msize - 1;
- free_list_t **free_list = tiny_mag_ptr->mag_free_list;
- free_list_t **the_slot = free_list + slot;
- free_list_t **limit;
-#if defined(__LP64__)
- uint64_t bitmap;
-#else
- uint32_t bitmap;
-#endif
- // Assumes we've locked the magazine
- CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__);
-
- // Look for an exact match by checking the freelist for this msize.
- ptr = *the_slot;
- if (ptr)
- return TINY_REGION_FOR_PTR(ptr);
-
- // Mask off the bits representing slots holding free blocks smaller than the
- // size we need. If there are no larger free blocks, try allocating from
- // the free space at the end of the tiny region.
-#if defined(__LP64__)
- bitmap = ((uint64_t *)(tiny_mag_ptr->mag_bitmap))[0] & ~ ((1ULL << slot) - 1);
-#else
- bitmap = tiny_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1);
-#endif
- if (!bitmap)
- return NULL;
-
- slot = BITMAPV_CTZ(bitmap);
- limit = free_list + NUM_TINY_SLOTS - 1;
- free_list += slot;
-
- if (free_list < limit) {
- ptr = *free_list;
- if (ptr)
- return TINY_REGION_FOR_PTR(ptr);
- else {
- /* Shouldn't happen. Fall through to look at last slot. */
-#if DEBUG_MALLOC
- malloc_printf("in tiny_find_msize_region(), mag_bitmap out of sync, slot=%d\n",slot);
-#endif
- }
- }
-
- // We are now looking at the last slot, which contains blocks equal to, or
- // due to coalescing of free blocks, larger than (NUM_TINY_SLOTS - 1) * tiny quantum size.
- ptr = *limit;
- if (ptr)
- return TINY_REGION_FOR_PTR(ptr);
-
- return NULL;
-}
-
-static boolean_t
-tiny_get_region_from_depot(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize)
-{
- magazine_t *depot_ptr = &(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX]);
-
- /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */
- if (szone->num_tiny_magazines == 1) // Uniprocessor, single magazine, so no recirculation necessary
- return 0;
-
-#if DEBUG_MALLOC
- if (DEPOT_MAGAZINE_INDEX == mag_index) {
- szone_error(szone, 1, "tiny_get_region_from_depot called for magazine index -1", NULL, NULL);
- return 0;
- }
-#endif
-
- SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr);
-
- // Appropriate a Depot'd region that can satisfy requested msize.
- region_trailer_t *node;
- region_t sparse_region;
-
- while (1) {
- sparse_region = tiny_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize);
- if (NULL == sparse_region) { // Depot empty?
- SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr);
- return 0;
- }
-
- node = REGION_TRAILER_FOR_TINY_REGION(sparse_region);
- if (0 >= node->pinned_to_depot)
- break;
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr);
- pthread_yield_np();
- SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr);
- }
-
- // disconnect node from Depot
- recirc_list_extract(szone, depot_ptr, node);
-
- // Iterate the region pulling its free entries off the (locked) Depot's free list
- int objects_in_use = tiny_free_detach_region(szone, depot_ptr, sparse_region);
-
- // Transfer ownership of the region
- MAGAZINE_INDEX_FOR_TINY_REGION(sparse_region) = mag_index;
- node->pinned_to_depot = 0;
-
- // Iterate the region putting its free entries on its new (locked) magazine's free list
- size_t bytes_inplay = tiny_free_reattach_region(szone, tiny_mag_ptr, sparse_region);
-
- depot_ptr->mag_num_bytes_in_objects -= bytes_inplay;
- depot_ptr->num_bytes_in_magazine -= TINY_REGION_PAYLOAD_BYTES;
- depot_ptr->mag_num_objects -= objects_in_use;
-
- tiny_mag_ptr->mag_num_bytes_in_objects += bytes_inplay;
- tiny_mag_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES;
- tiny_mag_ptr->mag_num_objects += objects_in_use;
-
- // connect to magazine as first node
- recirc_list_splice_first(szone, tiny_mag_ptr, node);
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr);
-
- // madvise() outside the Depot lock
-#if TARGET_OS_EMBEDDED
- if (node->failedREUSE) {
-#else
- if (node->failedREUSE ||
- -1 == madvise((void *)sparse_region, TINY_REGION_PAYLOAD_BYTES, MADV_FREE_REUSE)) {
-#endif
- /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */
-#if DEBUG_MADVISE
- szone_error(szone, 0, "tiny_get_region_from_depot madvise(..., MADV_FREE_REUSE) failed",
- sparse_region, "length=%d\n", TINY_REGION_PAYLOAD_BYTES);
-#endif
- node->failedREUSE = TRUE;
- }
-
- MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, TINY_REGION_SIZE,
- (int)BYTES_USED_FOR_TINY_REGION(sparse_region)); // DTrace USDT Probe
-
- return 1;
-}
-
-#define K 1.5 // headroom measured in number of 1Mb regions
-#define DENSITY_THRESHOLD(a) \
- ((a) - ((a) >> 2)) // "Emptiness" f = 0.25, so "Density" is (1 - f)*a. Generally: ((a) - ((a) >> -log2(f)))
-
-static INLINE boolean_t
-tiny_free_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, region_t region, void *ptr,
- msize_t msize)
-{
- void *original_ptr = ptr;
- size_t original_size = TINY_BYTES_FOR_MSIZE(msize);
- void *next_block = ((unsigned char *)ptr + original_size);
- msize_t previous_msize, next_msize;
- void *previous;
- free_list_t *big_free_block;
- free_list_t *after_next_block;
- free_list_t *before_next_block;
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
- if (!msize) {
- szone_error(szone, 1, "trying to free tiny block that is too small", ptr,
- "in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
-
- // We try to coalesce this block with the preceeding one
- previous = tiny_previous_preceding_free(ptr, &previous_msize);
- if (previous) {
-#if DEBUG_MALLOC
- if (LOG(szone, ptr) || LOG(szone,previous)) {
- malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous);
- }
-#endif
-
- // clear the meta_header since this is no longer the start of a block
- set_tiny_meta_header_middle(ptr);
- tiny_free_list_remove_ptr(szone, tiny_mag_ptr, previous, previous_msize);
- ptr = previous;
- msize += previous_msize;
- }
- // We try to coalesce with the next block
- if ((next_block < TINY_REGION_END(region)) && tiny_meta_header_is_free(next_block)) {
- next_msize = get_tiny_free_size(next_block);
-#if DEBUG_MALLOC
- if (LOG(szone, ptr) || LOG(szone, next_block)) {
- malloc_printf("in tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n",
- ptr, msize, next_block, next_msize);
- }
-#endif
- // If we are coalescing with the next block, and the next block is in
- // the last slot of the free list, then we optimize this case here to
- // avoid removing next_block from the slot (NUM_TINY_SLOTS - 1) and then adding ptr back
- // to slot (NUM_TINY_SLOTS - 1).
- if (next_msize >= NUM_TINY_SLOTS) {
- msize += next_msize;
-
- big_free_block = (free_list_t *)next_block;
- after_next_block = free_list_unchecksum_ptr(szone, &big_free_block->next);
- before_next_block = free_list_unchecksum_ptr(szone, &big_free_block->previous);
-
- if (!before_next_block) {
- tiny_mag_ptr->mag_free_list[NUM_TINY_SLOTS-1] = ptr;
- } else {
- before_next_block->next.u = free_list_checksum_ptr(szone, ptr);
- }
-
- if (after_next_block) {
- after_next_block->previous.u = free_list_checksum_ptr(szone, ptr);
- }
-
- // we don't need to checksum these since they are already checksummed
- ((free_list_t *)ptr)->previous = big_free_block->previous;
- ((free_list_t *)ptr)->next = big_free_block->next;
-
- // clear the meta_header to enable coalescing backwards
- set_tiny_meta_header_middle(big_free_block);
- set_tiny_meta_header_free(ptr, msize);
-
- goto tiny_free_ending;
- }
- tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize);
- set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards
- msize += next_msize;
- }
-
- // The tiny cache already scribbles free blocks as they go through the
- // cache whenever msize < TINY_QUANTUM , so we do not need to do it here.
- if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize && (msize >= TINY_QUANTUM))
- memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize));
-
- tiny_free_list_add_ptr(szone, tiny_mag_ptr, ptr, msize);
-
- tiny_free_ending:
-
- tiny_mag_ptr->mag_num_objects--;
- // we use original_size and not msize to avoid double counting the coalesced blocks
- tiny_mag_ptr->mag_num_bytes_in_objects -= original_size;
-
- // Update this region's bytes in use count
- region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(region);
- size_t bytes_used = node->bytes_used - original_size;
- node->bytes_used = bytes_used;
-
-#if !TARGET_OS_EMBEDDED // Always madvise for embedded platforms
- /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */
- if (szone->num_tiny_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary
- /* NOTHING */
- } else if (DEPOT_MAGAZINE_INDEX != mag_index) {
- // Emptiness discriminant
- if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) {
- /* Region has crossed threshold from density to sparsity. Mark it "suitable" on the
- recirculation candidates list. */
- node->recirc_suitable = TRUE;
- } else {
- /* After this free, we've found the region is still dense, so it must have been even more so before
- the free. That implies the region is already correctly marked. Do nothing. */
- }
-
- // Has the entire magazine crossed the "emptiness threshold"? If so, transfer a region
- // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e
- // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list.
- size_t a = tiny_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine
- size_t u = tiny_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine
-
- if (a - u > ((3 * TINY_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) {
- return tiny_free_do_recirc_to_depot(szone, tiny_mag_ptr, mag_index);
- }
-
- } else {
-#endif
- // Freed to Depot. N.B. Lock on tiny_magazines[DEPOT_MAGAZINE_INDEX] is already held
- // Calcuate the first page in the coalesced block that would be safe to mark MADV_FREE
- uintptr_t safe_ptr = (uintptr_t)ptr + sizeof(free_list_t) + sizeof(msize_t);
- uintptr_t round_safe = round_page(safe_ptr);
-
- // Calcuate the last page in the coalesced block that would be safe to mark MADV_FREE
- uintptr_t safe_extent = (uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t);
- uintptr_t trunc_extent = trunc_page(safe_extent);
-
- // The newly freed block may complete a span of bytes that cover a page. Mark it with MADV_FREE.
- if (round_safe < trunc_extent) { // Safe area covers a page (perhaps many)
- uintptr_t lo = trunc_page((uintptr_t)original_ptr);
- uintptr_t hi = round_page((uintptr_t)original_ptr + original_size);
-
- tiny_free_list_remove_ptr(szone, tiny_mag_ptr, ptr, msize);
- set_tiny_meta_header_in_use(ptr, msize);
-
- OSAtomicIncrement32Barrier(&(node->pinned_to_depot));
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
-#if TARGET_OS_EMBEDDED
- madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi), &szone->last_tiny_advise);
-#else
- madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi));
-#endif
- SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr);
- OSAtomicDecrement32Barrier(&(node->pinned_to_depot));
-
- set_tiny_meta_header_free(ptr, msize);
- tiny_free_list_add_ptr(szone, tiny_mag_ptr, ptr, msize);
- }
-
-#if !TARGET_OS_EMBEDDED
- if (0 < bytes_used || 0 < node->pinned_to_depot) {
- /* Depot'd region is still live. Leave it in place on the Depot's recirculation list
- so as to avoid thrashing between the Depot's free list and a magazines's free list
- with detach_region/reattach_region */
- } else {
- /* Depot'd region is just now empty. Consider return to OS. */
- region_t r_dealloc = tiny_free_try_depot_unmap_no_lock(szone, tiny_mag_ptr, node);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- if (r_dealloc)
- deallocate_pages(szone, r_dealloc, TINY_REGION_SIZE, 0);
- return FALSE; // Caller need not unlock
- }
- }
-#endif
-
- return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr)
-}
-
-// Allocates from the last region or a freshly allocated region
-static void *
-tiny_malloc_from_region_no_lock(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index,
- msize_t msize, void * aligned_address)
-{
- void *ptr;
-
- // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at_start
- if (tiny_mag_ptr->mag_bytes_free_at_end || tiny_mag_ptr->mag_bytes_free_at_start)
- tiny_finalize_region(szone, tiny_mag_ptr);
-
- // We set the unused bits of the header in the last pair to be all ones, and those of the inuse to zeroes.
- ((tiny_region_t)aligned_address)->pairs[CEIL_NUM_TINY_BLOCKS_WORDS-1].header =
- (NUM_TINY_BLOCKS & 31) ? (0xFFFFFFFFU << (NUM_TINY_BLOCKS & 31)) : 0;
- ((tiny_region_t)aligned_address)->pairs[CEIL_NUM_TINY_BLOCKS_WORDS-1].inuse = 0;
-
- // Here find the only place in tinyland that (infrequently) takes the tiny_regions_lock.
- // Only one thread at a time should be permitted to assess the density of the hash
- // ring and adjust if needed.
- // Only one thread at a time should be permitted to insert its new region on
- // the hash ring.
- // It is safe for all other threads to read the hash ring (hashed_regions) and
- // the associated sizes (num_regions_allocated and num_tiny_regions).
-
- LOCK(szone->tiny_regions_lock);
-
- // Check to see if the hash ring of tiny regions needs to grow. Try to
- // avoid the hash ring becoming too dense.
- if (szone->tiny_region_generation->num_regions_allocated < (2 * szone->num_tiny_regions)) {
- region_t *new_regions;
- size_t new_size;
- size_t new_shift = szone->tiny_region_generation->num_regions_allocated_shift; // In/Out parameter
- new_regions = hash_regions_grow_no_lock(szone, szone->tiny_region_generation->hashed_regions,
- szone->tiny_region_generation->num_regions_allocated,
- &new_shift,
- &new_size);
- // Do not deallocate the current hashed_regions allocation since someone may
- // be iterating it. Instead, just leak it.
-
- // Prepare to advance to the "next generation" of the hash ring.
- szone->tiny_region_generation->nextgen->hashed_regions = new_regions;
- szone->tiny_region_generation->nextgen->num_regions_allocated = new_size;
- szone->tiny_region_generation->nextgen->num_regions_allocated_shift = new_shift;
-
- // Throw the switch to atomically advance to the next generation.
- szone->tiny_region_generation = szone->tiny_region_generation->nextgen;
- // Ensure everyone sees the advance.
- OSMemoryBarrier();
- }
- // Tag the region at "aligned_address" as belonging to us,
- // and so put it under the protection of the magazine lock we are holding.
- // Do this before advertising "aligned_address" on the hash ring(!)
- MAGAZINE_INDEX_FOR_TINY_REGION(aligned_address) = mag_index;
-
- // Insert the new region into the hash ring, and update malloc statistics
- hash_region_insert_no_lock(szone->tiny_region_generation->hashed_regions,
- szone->tiny_region_generation->num_regions_allocated,
- szone->tiny_region_generation->num_regions_allocated_shift,
- aligned_address);
-
- szone->num_tiny_regions++;
- UNLOCK(szone->tiny_regions_lock);
-
- tiny_mag_ptr->mag_last_region = aligned_address;
- BYTES_USED_FOR_TINY_REGION(aligned_address) = TINY_BYTES_FOR_MSIZE(msize);
-#if ASLR_INTERNAL
- int offset_msize = malloc_entropy[0] & TINY_ENTROPY_MASK;
-#if DEBUG_MALLOC
- if (getenv("MallocASLRForce")) offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & TINY_ENTROPY_MASK;
- if (getenv("MallocASLRPrint")) malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize);
-#endif
-#else
- int offset_msize = 0;
-#endif
- ptr = (void *)((uintptr_t) aligned_address + TINY_BYTES_FOR_MSIZE(offset_msize));
- set_tiny_meta_header_in_use(ptr, msize);
- tiny_mag_ptr->mag_num_objects++;
- tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(msize);
- tiny_mag_ptr->num_bytes_in_magazine += TINY_REGION_PAYLOAD_BYTES;
-
- // We put a header on the last block so that it appears in use (for coalescing, etc...)
- set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(msize)));
- tiny_mag_ptr->mag_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize - offset_msize);
-
-#if ASLR_INTERNAL
- // Put a header on the previous block for same reason
- tiny_mag_ptr->mag_bytes_free_at_start = TINY_BYTES_FOR_MSIZE(offset_msize);
- if (offset_msize) {
- set_tiny_meta_header_in_use_1((void *)((uintptr_t)ptr - TINY_QUANTUM));
- }
-#else
- tiny_mag_ptr->mag_bytes_free_at_start = 0;
-#endif
-
- // connect to magazine as last node
- recirc_list_splice_last(szone, tiny_mag_ptr, REGION_TRAILER_FOR_TINY_REGION(aligned_address));
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_from_region_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
- return ptr;
-}
-
-static INLINE void *
-tiny_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size)
-{
- msize_t new_msize = TINY_MSIZE_FOR_BYTES(new_good_size);
- msize_t mshrinkage = TINY_MSIZE_FOR_BYTES(old_size) - new_msize;
-
- if (mshrinkage) {
- void *q = (void *)((uintptr_t)ptr + TINY_BYTES_FOR_MSIZE(new_msize));
- magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines,
- REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)),
- MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)));
-
- // Mark q as block header and in-use, thus creating two blocks.
- set_tiny_meta_header_in_use(q, mshrinkage);
- tiny_mag_ptr->mag_num_objects++;
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr);
- szone_free(szone, q); // avoid inlining free_tiny(szone, q, ...);
- }
- return ptr;
-}
-
-static INLINE boolean_t
-tiny_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size)
-{
- // returns 1 on success
- msize_t index;
- msize_t old_msize;
- unsigned next_index;
- void *next_block;
- boolean_t is_free;
- msize_t next_msize, coalesced_msize, leftover_msize;
- void *leftover;
-
- index = TINY_INDEX_FOR_PTR(ptr);
- old_msize = TINY_MSIZE_FOR_BYTES(old_size);
- next_index = index + old_msize;
-
- if (next_index >= NUM_TINY_BLOCKS) {
- return 0;
- }
- next_block = (char *)ptr + old_size;
-
- magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines,
- REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)),
- MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr)));
-
- /*
- * Look for a free block immediately afterwards. If it's large enough, we can consume (part of)
- * it.
- */
- is_free = tiny_meta_header_is_free(next_block);
- if (!is_free) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr);
- return 0; // next_block is in use;
- }
- next_msize = get_tiny_free_size(next_block);
- if (old_size + TINY_BYTES_FOR_MSIZE(next_msize) < new_size) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr);
- return 0; // even with next block, not enough
- }
- /*
- * The following block is big enough; pull it from its freelist and chop off enough to satisfy
- * our needs.
- */
- tiny_free_list_remove_ptr(szone, tiny_mag_ptr, next_block, next_msize);
- set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards
- coalesced_msize = TINY_MSIZE_FOR_BYTES(new_size - old_size + TINY_QUANTUM - 1);
- leftover_msize = next_msize - coalesced_msize;
- if (leftover_msize) {
- /* there's some left, so put the remainder back */
- leftover = (void *)((uintptr_t)next_block + TINY_BYTES_FOR_MSIZE(coalesced_msize));
-
- tiny_free_list_add_ptr(szone, tiny_mag_ptr, leftover, leftover_msize);
- }
- set_tiny_meta_header_in_use(ptr, old_msize + coalesced_msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_try_realloc_in_place(), ptr=%p, msize=%d\n", ptr, old_msize + coalesced_msize);
- }
-#endif
- tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(coalesced_msize);
-
- // Update this region's bytes in use count
- region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr));
- size_t bytes_used = node->bytes_used + TINY_BYTES_FOR_MSIZE(coalesced_msize);
- node->bytes_used = bytes_used;
-
- // Emptiness discriminant
- if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) {
- /* After this reallocation the region is still sparse, so it must have been even more so before
- the reallocation. That implies the region is already correctly marked. Do nothing. */
- } else {
- /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the
- recirculation candidates list. */
- node->recirc_suitable = FALSE;
- }
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone,tiny_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- return 1;
-}
-
-static boolean_t
-tiny_check_region(szone_t *szone, region_t region)
-{
- uintptr_t start, ptr, region_end;
- boolean_t prev_free = 0;
- boolean_t is_free;
- msize_t msize;
- free_list_t *free_head;
- void *follower, *previous, *next;
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(region);
- magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]);
-
- // Assumes locked
- CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__);
-
- /* establish region limits */
- start = (uintptr_t)TINY_REGION_ADDRESS(region);
- ptr = start;
- if (region == tiny_mag_ptr->mag_last_region) {
- ptr += tiny_mag_ptr->mag_bytes_free_at_start;
-
- /*
- * Check the leading block's integrity here also.
- */
- if (tiny_mag_ptr->mag_bytes_free_at_start) {
- msize = get_tiny_meta_header((void *)(ptr - TINY_QUANTUM), &is_free);
- if (is_free || (msize != 1)) {
- malloc_printf("*** invariant broken for leader block %p - %d %d\n", ptr - TINY_QUANTUM, msize, is_free);
- }
- }
- }
- region_end = (uintptr_t)TINY_REGION_END(region);
-
- /*
- * The last region may have a trailing chunk which has not been converted into inuse/freelist
- * blocks yet.
- */
- if (region == tiny_mag_ptr->mag_last_region)
- region_end -= tiny_mag_ptr->mag_bytes_free_at_end;
-
- /*
- * Scan blocks within the region.
- */
- while (ptr < region_end) {
- /*
- * If the first block is free, and its size is 65536 (msize = 0) then the entire region is
- * free.
- */
- msize = get_tiny_meta_header((void *)ptr, &is_free);
- if (is_free && !msize && (ptr == start)) {
- return 1;
- }
-
- /*
- * If the block's size is 65536 (msize = 0) then since we're not the first entry the size is
- * corrupt.
- */
- if (!msize) {
- malloc_printf("*** invariant broken for tiny block %p this msize=%d - size is too small\n",
- ptr, msize);
- return 0;
- }
-
- if (!is_free) {
- /*
- * In use blocks cannot be more than (NUM_TINY_SLOTS - 1) quanta large.
- */
- prev_free = 0;
- if (msize > (NUM_TINY_SLOTS - 1)) {
- malloc_printf("*** invariant broken for %p this tiny msize=%d - size is too large\n",
- ptr, msize);
- return 0;
- }
- /* move to next block */
- ptr += TINY_BYTES_FOR_MSIZE(msize);
- } else {
-#if !RELAXED_INVARIANT_CHECKS
- /*
- * Free blocks must have been coalesced, we cannot have a free block following another
- * free block.
- */
- if (prev_free) {
- malloc_printf("*** invariant broken for free block %p this tiny msize=%d: two free blocks in a row\n",
- ptr, msize);
- return 0;
- }
-#endif // RELAXED_INVARIANT_CHECKS
- prev_free = 1;
- /*
- * Check the integrity of this block's entry in its freelist.
- */
- free_head = (free_list_t *)ptr;
- previous = free_list_unchecksum_ptr(szone, &free_head->previous);
- next = free_list_unchecksum_ptr(szone, &free_head->next);
- if (previous && !tiny_meta_header_is_free(previous)) {
- malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n",
- ptr, previous);
- return 0;
- }
- if (next && !tiny_meta_header_is_free(next)) {
- malloc_printf("*** invariant broken for %p (next in free list %p is not a free pointer)\n",
- ptr, next);
- return 0;
- }
- /*
- * Check the free block's trailing size value.
- */
- follower = FOLLOWING_TINY_PTR(ptr, msize);
- if (((uintptr_t)follower != region_end) && (get_tiny_previous_free_msize(follower) != msize)) {
- malloc_printf("*** invariant broken for tiny free %p followed by %p in region [%p-%p] "
- "(end marker incorrect) should be %d; in fact %d\n",
- ptr, follower, TINY_REGION_ADDRESS(region), region_end, msize, get_tiny_previous_free_msize(follower));
- return 0;
- }
- /* move to next block */
- ptr = (uintptr_t)follower;
- }
- }
- /*
- * Ensure that we scanned the entire region
- */
- if (ptr != region_end) {
- malloc_printf("*** invariant broken for region end %p - %p\n", ptr, region_end);
- return 0;
- }
- /*
- * Check the trailing block's integrity.
- */
- if (region == tiny_mag_ptr->mag_last_region) {
- if (tiny_mag_ptr->mag_bytes_free_at_end) {
- msize = get_tiny_meta_header((void *)ptr, &is_free);
- if (is_free || (msize != 1)) {
- malloc_printf("*** invariant broken for blocker block %p - %d %d\n", ptr, msize, is_free);
- }
- }
- }
- return 1;
-}
-
-static kern_return_t
-tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone,
- memory_reader_t reader, vm_range_recorder_t recorder)
-{
- size_t num_regions;
- size_t index;
- region_t *regions;
- vm_range_t buffer[MAX_RECORDER_BUFFER];
- unsigned count = 0;
- kern_return_t err;
- region_t region;
- vm_range_t range;
- vm_range_t admin_range;
- vm_range_t ptr_range;
- unsigned char *mapped_region;
- uint32_t *block_header;
- uint32_t *in_use;
- unsigned block_index;
- unsigned block_limit;
- boolean_t is_free;
- msize_t msize;
- void *mapped_ptr;
- unsigned bit;
- magazine_t *tiny_mag_base = NULL;
-
- region_hash_generation_t *trg_ptr;
- err = reader(task, (vm_address_t)szone->tiny_region_generation, sizeof(region_hash_generation_t), (void **)&trg_ptr);
- if (err) return err;
-
- num_regions = trg_ptr->num_regions_allocated;
- err = reader(task, (vm_address_t)trg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions);
- if (err) return err;
-
- if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) {
- // Map in all active magazines. Do this outside the iteration over regions.
- err = reader(task, (vm_address_t)(szone->tiny_magazines),
- szone->num_tiny_magazines*sizeof(magazine_t),(void **)&tiny_mag_base);
- if (err) return err;
- }
-
- for (index = 0; index < num_regions; ++index) {
- region = regions[index];
- if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) {
- range.address = (vm_address_t)TINY_REGION_ADDRESS(region);
- range.size = (vm_size_t)TINY_REGION_SIZE;
- if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) {
- admin_range.address = range.address + TINY_METADATA_START;
- admin_range.size = TINY_METADATA_SIZE;
- recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1);
- }
- if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) {
- ptr_range.address = range.address;
- ptr_range.size = NUM_TINY_BLOCKS * TINY_QUANTUM;
- recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1);
- }
- if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) {
- void *mag_last_free;
- vm_address_t mag_last_free_ptr = 0;
- msize_t mag_last_free_msize = 0;
-
- err = reader(task, range.address, range.size, (void **)&mapped_region);
- if (err)
- return err;
-
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(mapped_region);
- magazine_t *tiny_mag_ptr = tiny_mag_base + mag_index;
-
- if (DEPOT_MAGAZINE_INDEX != mag_index) {
- mag_last_free = tiny_mag_ptr->mag_last_free;
- if (mag_last_free) {
- mag_last_free_ptr = (uintptr_t) mag_last_free & ~(TINY_QUANTUM - 1);
- mag_last_free_msize = (uintptr_t) mag_last_free & (TINY_QUANTUM - 1);
- }
- } else {
- for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) {
- if ((void *)range.address == (tiny_mag_base + mag_index)->mag_last_free_rgn) {
- mag_last_free = (tiny_mag_base + mag_index)->mag_last_free;
- if (mag_last_free) {
- mag_last_free_ptr = (uintptr_t) mag_last_free & ~(TINY_QUANTUM - 1);
- mag_last_free_msize = (uintptr_t) mag_last_free & (TINY_QUANTUM - 1);
- }
- }
- }
- }
-
- block_header = (uint32_t *)(mapped_region + TINY_METADATA_START + sizeof(region_trailer_t));
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- block_index = 0;
- block_limit = NUM_TINY_BLOCKS;
- if (region == tiny_mag_ptr->mag_last_region) {
- block_index += TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_start);
- block_limit -= TINY_MSIZE_FOR_BYTES(tiny_mag_ptr->mag_bytes_free_at_end);
- }
-
- while (block_index < block_limit) {
- vm_size_t block_offset = TINY_BYTES_FOR_MSIZE(block_index);
- is_free = !BITARRAY_BIT(in_use, block_index);
- if (is_free) {
- mapped_ptr = mapped_region + block_offset;
-
- // mapped_region, the address at which 'range' in 'task' has been
- // mapped into our process, is not necessarily aligned to
- // TINY_BLOCKS_ALIGN.
- //
- // Since the code in get_tiny_free_size() assumes the pointer came
- // from a properly aligned tiny region, and mapped_region is not
- // necessarily aligned, then do the size calculation directly.
- // If the next bit is set in the header bitmap, then the size is one
- // quantum. Otherwise, read the size field.
- if (!BITARRAY_BIT(block_header, (block_index+1)))
- msize = TINY_FREE_SIZE(mapped_ptr);
- else
- msize = 1;
-
- } else if (range.address + block_offset != mag_last_free_ptr) {
- msize = 1;
- bit = block_index + 1;
- while (! BITARRAY_BIT(block_header, bit)) {
- bit++;
- msize ++;
- }
- buffer[count].address = range.address + block_offset;
- buffer[count].size = TINY_BYTES_FOR_MSIZE(msize);
- count++;
- if (count >= MAX_RECORDER_BUFFER) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
- count = 0;
- }
- } else {
- // Block is not free but it matches mag_last_free_ptr so even
- // though it is not marked free in the bitmap, we treat it as if
- // it is and move on
- msize = mag_last_free_msize;
- }
-
- if (!msize)
- return KERN_FAILURE; // Somethings amiss. Avoid looping at this block_index.
-
- block_index += msize;
- }
- if (count) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
- count = 0;
- }
- }
- }
- }
- return 0;
-}
-
-static void *
-tiny_malloc_from_free_list(szone_t *szone, magazine_t *tiny_mag_ptr, mag_index_t mag_index, msize_t msize)
-{
- free_list_t *ptr;
- msize_t this_msize;
- grain_t slot = msize - 1;
- free_list_t **free_list = tiny_mag_ptr->mag_free_list;
- free_list_t **the_slot = free_list + slot;
- free_list_t *next;
- free_list_t **limit;
-#if defined(__LP64__)
- uint64_t bitmap;
-#else
- uint32_t bitmap;
-#endif
- msize_t leftover_msize;
- free_list_t *leftover_ptr;
-
- // Assumes we've locked the region
- CHECK_MAGAZINE_PTR_LOCKED(szone, tiny_mag_ptr, __PRETTY_FUNCTION__);
-
- // Look for an exact match by checking the freelist for this msize.
- //
- ptr = *the_slot;
- if (ptr) {
- next = free_list_unchecksum_ptr(szone, &ptr->next);
- if (next) {
- next->previous = ptr->previous;
- } else {
- BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot);
- }
- *the_slot = next;
- this_msize = msize;
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize);
- }
-#endif
- goto return_tiny_alloc;
- }
-
- // Mask off the bits representing slots holding free blocks smaller than the
- // size we need. If there are no larger free blocks, try allocating from
- // the free space at the end of the tiny region.
-#if defined(__LP64__)
- bitmap = ((uint64_t *)(tiny_mag_ptr->mag_bitmap))[0] & ~ ((1ULL << slot) - 1);
-#else
- bitmap = tiny_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1);
-#endif
- if (!bitmap)
- goto try_tiny_malloc_from_end;
-
- slot = BITMAPV_CTZ(bitmap);
- limit = free_list + NUM_TINY_SLOTS - 1;
- free_list += slot;
-
- if (free_list < limit) {
- ptr = *free_list;
- if (ptr) {
- next = free_list_unchecksum_ptr(szone, &ptr->next);
- *free_list = next;
- if (next) {
- next->previous = ptr->previous;
- } else {
- BITMAPV_CLR(tiny_mag_ptr->mag_bitmap, slot);
- }
- this_msize = get_tiny_free_size(ptr);
- goto add_leftover_and_proceed;
- }
-#if DEBUG_MALLOC
- malloc_printf("in tiny_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n",slot);
-#endif
- }
-
- // We are now looking at the last slot, which contains blocks equal to, or
- // due to coalescing of free blocks, larger than (NUM_TINY_SLOTS - 1) * tiny quantum size.
- // If the last freelist is not empty, and the head contains a block that is
- // larger than our request, then the remainder is put back on the free list.
- ptr = *limit;
- if (ptr) {
- this_msize = get_tiny_free_size(ptr);
- next = free_list_unchecksum_ptr(szone, &ptr->next);
- if (this_msize - msize >= NUM_TINY_SLOTS) {
- // the leftover will go back to the free list, so we optimize by
- // modifying the free list rather than a pop and push of the head
- leftover_msize = this_msize - msize;
- leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize));
- *limit = leftover_ptr;
- if (next) {
- next->previous.u = free_list_checksum_ptr(szone, leftover_ptr);
- }
- leftover_ptr->previous = ptr->previous;
- leftover_ptr->next = ptr->next;
- set_tiny_meta_header_free(leftover_ptr, leftover_msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n",
- ptr, msize, this_msize);
- }
-#endif
- this_msize = msize;
- goto return_tiny_alloc;
- }
- if (next) {
- next->previous = ptr->previous;
- }
- *limit = next;
- goto add_leftover_and_proceed;
- /* NOTREACHED */
- }
-
-try_tiny_malloc_from_end:
- // Let's see if we can use tiny_mag_ptr->mag_bytes_free_at_end
- if (tiny_mag_ptr->mag_bytes_free_at_end >= TINY_BYTES_FOR_MSIZE(msize)) {
- ptr = (free_list_t *)((uintptr_t)TINY_REGION_END(tiny_mag_ptr->mag_last_region) -
- tiny_mag_ptr->mag_bytes_free_at_end);
- tiny_mag_ptr->mag_bytes_free_at_end -= TINY_BYTES_FOR_MSIZE(msize);
- if (tiny_mag_ptr->mag_bytes_free_at_end) {
- // let's add an in use block after ptr to serve as boundary
- set_tiny_meta_header_in_use_1((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize));
- }
- this_msize = msize;
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
- goto return_tiny_alloc;
- }
-#if ASLR_INTERNAL
- // Try from start if nothing left at end
- if (tiny_mag_ptr->mag_bytes_free_at_start >= TINY_BYTES_FOR_MSIZE(msize)) {
- ptr = (free_list_t *)(TINY_REGION_ADDRESS(tiny_mag_ptr->mag_last_region) +
- tiny_mag_ptr->mag_bytes_free_at_start - TINY_BYTES_FOR_MSIZE(msize));
- tiny_mag_ptr->mag_bytes_free_at_start -= TINY_BYTES_FOR_MSIZE(msize);
- if (tiny_mag_ptr->mag_bytes_free_at_start) {
- // let's add an in use block before ptr to serve as boundary
- set_tiny_meta_header_in_use_1((unsigned char *)ptr - TINY_QUANTUM);
- }
- this_msize = msize;
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), from start ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
- goto return_tiny_alloc;
- }
-#endif
- return NULL;
-
-add_leftover_and_proceed:
- if (!this_msize || (this_msize > msize)) {
- leftover_msize = this_msize - msize;
- leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize));
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize);
- }
-#endif
- tiny_free_list_add_ptr(szone, tiny_mag_ptr, leftover_ptr, leftover_msize);
- this_msize = msize;
- }
-
-return_tiny_alloc:
- tiny_mag_ptr->mag_num_objects++;
- tiny_mag_ptr->mag_num_bytes_in_objects += TINY_BYTES_FOR_MSIZE(this_msize);
-
- // Update this region's bytes in use count
- region_trailer_t *node = REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr));
- size_t bytes_used = node->bytes_used + TINY_BYTES_FOR_MSIZE(this_msize);
- node->bytes_used = bytes_used;
-
- // Emptiness discriminant
- if (bytes_used < DENSITY_THRESHOLD(TINY_REGION_PAYLOAD_BYTES)) {
- /* After this allocation the region is still sparse, so it must have been even more so before
- the allocation. That implies the region is already correctly marked. Do nothing. */
- } else {
- /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the
- recirculation candidates list. */
- node->recirc_suitable = FALSE;
- }
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize);
- }
-#endif
- if (this_msize > 1)
- set_tiny_meta_header_in_use(ptr, this_msize);
- else
- set_tiny_meta_header_in_use_1(ptr);
- return ptr;
-}
-#undef DENSITY_THRESHOLD
-#undef K
-
-static INLINE void *
-tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested)
-{
- void *ptr;
- mag_index_t mag_index = mag_get_thread_index(szone);
- magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]);
-
-#if DEBUG_MALLOC
- if (DEPOT_MAGAZINE_INDEX == mag_index) {
- szone_error(szone, 1, "malloc called for magazine index -1", NULL, NULL);
- return(NULL);
- }
-
- if (!msize) {
- szone_error(szone, 1, "invariant broken (!msize) in allocation (region)", NULL, NULL);
- return(NULL);
- }
-#endif
-
- SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr);
-
-#if TINY_CACHE
- ptr = tiny_mag_ptr->mag_last_free;
-
- if ((((uintptr_t)ptr) & (TINY_QUANTUM - 1)) == msize) {
- // we have a winner
- tiny_mag_ptr->mag_last_free = NULL;
- tiny_mag_ptr->mag_last_free_rgn = NULL;
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- ptr = (void *)((uintptr_t)ptr & ~ (TINY_QUANTUM - 1));
- if (cleared_requested) {
- memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize));
- }
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_should_clear(), tiny cache ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
- return ptr;
- }
-#endif /* TINY_CACHE */
-
- while (1) {
- ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize);
- if (ptr) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- if (cleared_requested) {
- memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize));
- }
- return ptr;
- }
-
- if (tiny_get_region_from_depot(szone, tiny_mag_ptr, mag_index, msize)) {
- ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize);
- if (ptr) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- if (cleared_requested) {
- memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize));
- }
- return ptr;
- }
- }
-
- // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc().
- // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first
- // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section.
- // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the
- // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation,
- // and retry-ing threads succeed in the code just above.
- if (!tiny_mag_ptr->alloc_underway) {
- void *fresh_region;
-
- // time to create a new region (do this outside the magazine lock)
- tiny_mag_ptr->alloc_underway = TRUE;
- OSMemoryBarrier();
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- fresh_region = allocate_pages_securely(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, VM_MEMORY_MALLOC_TINY);
- SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr);
-
- MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, TINY_REGION_SIZE); // DTrace USDT Probe
-
- if (!fresh_region) { // out of memory!
- tiny_mag_ptr->alloc_underway = FALSE;
- OSMemoryBarrier();
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- return NULL;
- }
-
- ptr = tiny_malloc_from_region_no_lock(szone, tiny_mag_ptr, mag_index, msize, fresh_region);
-
- // we don't clear because this freshly allocated space is pristine
- tiny_mag_ptr->alloc_underway = FALSE;
- OSMemoryBarrier();
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- return ptr;
- } else {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- pthread_yield_np();
- SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr);
- }
- }
- /* NOTREACHED */
-}
-
-static NOINLINE void
-free_tiny_botch(szone_t *szone, free_list_t *ptr)
-{
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr));
- magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- szone_error(szone, 1, "double free", ptr, NULL);
-}
-
-static INLINE void
-free_tiny(szone_t *szone, void *ptr, region_t tiny_region, size_t known_size)
-{
- msize_t msize;
- boolean_t is_free;
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region);
- magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]);
-
- // ptr is known to be in tiny_region
- if (known_size) {
- msize = TINY_MSIZE_FOR_BYTES(known_size + TINY_QUANTUM - 1);
- } else {
- msize = get_tiny_meta_header(ptr, &is_free);
- if (is_free) {
- free_tiny_botch(szone, ptr);
- return;
- }
- }
-#if DEBUG_MALLOC
- if (!msize) {
- malloc_printf("*** free_tiny() block in use is too large: %p\n", ptr);
- return;
- }
-#endif
-
- SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr);
-
-#if TINY_CACHE
- // Depot does not participate in TINY_CACHE since it can't be directly malloc()'d
- if (DEPOT_MAGAZINE_INDEX != mag_index) {
- if (msize < TINY_QUANTUM) { // to see if the bits fit in the last 4 bits
- void *ptr2 = tiny_mag_ptr->mag_last_free; // Might be NULL
- region_t rgn2 = tiny_mag_ptr->mag_last_free_rgn;
-
- /* check that we don't already have this pointer in the cache */
- if (ptr == (void *)((uintptr_t)ptr2 & ~ (TINY_QUANTUM - 1))) {
- free_tiny_botch(szone, ptr);
- return;
- }
-
- if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize)
- memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize));
-
- tiny_mag_ptr->mag_last_free = (void *)(((uintptr_t)ptr) | msize);
- tiny_mag_ptr->mag_last_free_rgn = tiny_region;
-
- if (!ptr2) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- return;
- }
-
- msize = (uintptr_t)ptr2 & (TINY_QUANTUM - 1);
- ptr = (void *)(((uintptr_t)ptr2) & ~(TINY_QUANTUM - 1));
- tiny_region = rgn2;
- }
- }
-#endif /* TINY_CACHE */
-
- // Now in the time it took to acquire the lock, the region may have migrated
- // from one magazine to another. I.e. trailer->mag_index is volatile.
- // In which case the magazine lock we obtained (namely magazines[mag_index].mag_lock)
- // is stale. If so, keep on tryin' ...
- region_trailer_t *trailer = REGION_TRAILER_FOR_TINY_REGION(tiny_region);
- mag_index_t refreshed_index;
-
- while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
-
- mag_index = refreshed_index;
- tiny_mag_ptr = &(szone->tiny_magazines[mag_index]);
- SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr);
- }
-
- if (tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize))
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
-
- CHECK(szone, __PRETTY_FUNCTION__);
-}
-
-static void
-print_tiny_free_list(szone_t *szone)
-{
- free_list_t *ptr;
- _SIMPLE_STRING b = _simple_salloc();
- mag_index_t mag_index;
-
- if (b) {
- _simple_sappend(b, "tiny free sizes:\n");
- for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) {
- grain_t slot = 0;
- _simple_sprintf(b,"\tMagazine %d: ", mag_index);
- while (slot < NUM_TINY_SLOTS) {
- ptr = szone->tiny_magazines[mag_index].mag_free_list[slot];
- if (ptr) {
- _simple_sprintf(b, "%s%y[%d]; ", (slot == NUM_TINY_SLOTS-1) ? ">=" : "",
- (slot+1)*TINY_QUANTUM, free_list_count(szone, ptr));
- }
- slot++;
- }
- _simple_sappend(b,"\n");
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-
-static void
-print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end)
-{
- unsigned counts[1024];
- unsigned in_use = 0;
- uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(region);
- uintptr_t current = start + bytes_at_end;
- uintptr_t limit = (uintptr_t)TINY_REGION_END(region) - bytes_at_end;
- boolean_t is_free;
- msize_t msize;
- unsigned ci;
- _SIMPLE_STRING b;
- uintptr_t pgTot = 0;
-
- if (region == HASHRING_REGION_DEALLOCATED) {
- if ((b = _simple_salloc()) != NULL) {
- _simple_sprintf(b, "Tiny region [unknown address] was returned to the OS\n");
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
- return;
- }
-
- memset(counts, 0, sizeof(counts));
- while (current < limit) {
- msize = get_tiny_meta_header((void *)current, &is_free);
- if (is_free & !msize && (current == start)) {
- // first block is all free
- uintptr_t pgLo = round_page(start + sizeof(free_list_t) + sizeof(msize_t));
- uintptr_t pgHi = trunc_page(start + TINY_REGION_SIZE - sizeof(msize_t));
-
- if (pgLo < pgHi) {
- pgTot += (pgHi - pgLo);
- }
- break;
- }
- if (!msize) {
- malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize);
- break;
- }
- if (!is_free) {
- // block in use
- if (msize > NUM_TINY_SLOTS)
- malloc_printf("*** error at %p msize for in_use is %d\n", (void *)current, msize);
- if (msize < 1024)
- counts[msize]++;
- in_use++;
- } else {
- uintptr_t pgLo = round_page(current + sizeof(free_list_t) + sizeof(msize_t));
- uintptr_t pgHi = trunc_page(current + TINY_BYTES_FOR_MSIZE(msize) - sizeof(msize_t));
-
- if (pgLo < pgHi) {
- pgTot += (pgHi - pgLo);
- }
- }
- current += TINY_BYTES_FOR_MSIZE(msize);
- }
- if ((b = _simple_salloc()) != NULL) {
- _simple_sprintf(b, "Tiny region [%p-%p, %y] \t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE);
- _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_TINY_REGION(region));
- _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_TINY_REGION(region));
- if (bytes_at_end || bytes_at_start)
- _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start);
- if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_TINY_REGION(region)) {
- _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot);
- } else {
- _simple_sprintf(b, "Fragments subject to reclamation=%ly", pgTot);
- }
- if (verbose && in_use) {
- _simple_sappend(b, "\n\tSizes in use: ");
- for (ci = 0; ci < 1024; ci++)
- if (counts[ci])
- _simple_sprintf(b, "%d[%d] ", TINY_BYTES_FOR_MSIZE(ci), counts[ci]);
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-
-static boolean_t
-tiny_free_list_check(szone_t *szone, grain_t slot)
-{
- mag_index_t mag_index;
-
- for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) {
- magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]);
- SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr);
-
- unsigned count = 0;
- free_list_t *ptr = szone->tiny_magazines[mag_index].mag_free_list[slot];
- boolean_t is_free;
- free_list_t *previous = NULL;
-
- while (ptr) {
- is_free = tiny_meta_header_is_free(ptr);
- if (! is_free) {
- malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- return 0;
- }
- if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) {
- malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- return 0;
- }
- if (!tiny_region_for_ptr_no_lock(szone, ptr)) {
- malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- return 0;
- }
- if (free_list_unchecksum_ptr(szone, &ptr->previous) != previous) {
- malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- return 0;
- }
- previous = ptr;
- ptr = free_list_unchecksum_ptr(szone, &ptr->next);
- count++;
- }
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- }
- return 1;
-}
-
-/********************* SMALL FREE LIST UTILITIES ************************/
-
-/*
- * Mark a block as free. Only the first quantum of a block is marked thusly,
- * the remainder are marked "middle".
- */
-static INLINE void
-small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize)
-{
- meta_headers[index] = msize | SMALL_IS_FREE;
-}
-
-/*
- * Mark a block as in use. Only the first quantum of a block is marked thusly,
- * the remainder are marked "middle".
- */
-static INLINE void
-small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize)
-{
- meta_headers[index] = msize;
-}
-
-/*
- * Mark a quantum as being the second or later in a block.
- */
-static INLINE void
-small_meta_header_set_middle(msize_t *meta_headers, msize_t index)
-{
- meta_headers[index] = 0;
-}
-
-/*
- * Adds an item to the proper free list, and also marks the meta-header of the
- * block properly.
- * Assumes szone has been locked
- */
-static void
-small_free_list_add_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize)
-{
- grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1;
- free_list_t *free_ptr = ptr;
- free_list_t *free_head = small_mag_ptr->mag_free_list[slot];
- void *follower;
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize);
- }
- if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) {
- szone_error(szone, 1, "small_free_list_add_ptr: Unaligned ptr", ptr, NULL);
- }
-#endif
- small_meta_header_set_is_free(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), msize);
-
- if (free_head) {
-#if DEBUG_MALLOC
- if (free_list_unchecksum_ptr(szone, &free_head->previous)) {
- szone_error(szone, 1, "small_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr,
- "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, (void *)free_head, free_head->previous.p);
- }
- if (!SMALL_PTR_IS_FREE(free_head)) {
- szone_error(szone, 1, "small_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr,
- "ptr=%p slot=%d free_head=%p\n", ptr, slot, (void *)free_head);
- }
-#endif
- free_head->previous.u = free_list_checksum_ptr(szone, free_ptr);
- } else {
- BITMAPN_SET(small_mag_ptr->mag_bitmap, slot);
- }
- free_ptr->previous.u = free_list_checksum_ptr(szone, NULL);
- free_ptr->next.u = free_list_checksum_ptr(szone, free_head);
-
- small_mag_ptr->mag_free_list[slot] = free_ptr;
-
- // Store msize at the end of the block denoted by "ptr" (i.e. at a negative offset from "follower")
- follower = (void *)((uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(msize));
- SMALL_PREVIOUS_MSIZE(follower) = msize;
-}
-
-/*
- * Removes the item pointed to by ptr in the proper free list.
- * Assumes szone has been locked
- */
-static void
-small_free_list_remove_ptr(szone_t *szone, magazine_t *small_mag_ptr, void *ptr, msize_t msize)
-{
- grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1;
- free_list_t *free_ptr = ptr, *next, *previous;
-
- next = free_list_unchecksum_ptr(szone, &free_ptr->next);
- previous = free_list_unchecksum_ptr(szone, &free_ptr->previous);
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize);
- }
-#endif
-
- if (!previous) {
- // The block to remove is the head of the free list
-#if DEBUG_MALLOC
- if (small_mag_ptr->mag_free_list[slot] != ptr) {
- szone_error(szone, 1, "small_free_list_remove_ptr: Internal invariant broken (small_mag_ptr->mag_free_list[slot])", ptr,
- "ptr=%p slot=%d msize=%d small_mag_ptr->mag_free_list[slot]=%p\n",
- ptr, slot, msize, (void *)small_mag_ptr->mag_free_list[slot]);
- return;
- }
-#endif
- small_mag_ptr->mag_free_list[slot] = next;
- if (!next) BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot);
- } else {
- // We know free_ptr is already checksummed, so we don't need to do it
- // again.
- previous->next = free_ptr->next;
- }
- if (next) {
- // We know free_ptr is already checksummed, so we don't need to do it
- // again.
- next->previous = free_ptr->previous;
- }
-}
-
-/*
- * small_region_for_ptr_no_lock - Returns the small region containing the pointer,
- * or NULL if not found.
- */
-static INLINE region_t
-small_region_for_ptr_no_lock(szone_t *szone, const void *ptr)
-{
- rgnhdl_t r = hash_lookup_region_no_lock(szone->small_region_generation->hashed_regions,
- szone->small_region_generation->num_regions_allocated,
- szone->small_region_generation->num_regions_allocated_shift,
- SMALL_REGION_FOR_PTR(ptr));
- return r ? *r : r;
-}
-
-static void
-small_finalize_region(szone_t *szone, magazine_t *small_mag_ptr) {
- void *last_block, *previous_block;
- msize_t last_msize, previous_msize, last_index;
-
- // It is possible that the block prior to the last block in the region has
- // been free'd, but was not coalesced with the free bytes at the end of the
- // block, since we treat the bytes at the end of the region as "in use" in
- // the meta headers. Attempt to coalesce the last block with the previous
- // block, so we don't violate the "no consecutive free blocks" invariant.
- //
- // FIXME: If we could calculate the previous small free size in the same
- // manner as tiny_previous_preceding_free, it would eliminate the
- // index & previous msize checks, which are a guard against reading
- // bogus data out of in-use or written-on-freed memory.
- //
- // FIXME: Need to investigate how much work would be required to increase
- // 'mag_bytes_free_at_end' when freeing the preceding block, rather
- // than performing this workaround.
- //
- if (small_mag_ptr->mag_bytes_free_at_end) {
- last_block = SMALL_REGION_END(small_mag_ptr->mag_last_region) - small_mag_ptr->mag_bytes_free_at_end;
- last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end);
-
- last_index = SMALL_META_INDEX_FOR_PTR(last_block);
- previous_msize = SMALL_PREVIOUS_MSIZE(last_block);
-
- if (last_index && (previous_msize <= last_index)) {
- previous_block = (void *)((uintptr_t)last_block - SMALL_BYTES_FOR_MSIZE(previous_msize));
- if (*SMALL_METADATA_FOR_PTR(previous_block) == (previous_msize | SMALL_IS_FREE)) {
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(last_block);
-
- small_meta_header_set_middle(meta_headers, last_index);
- small_free_list_remove_ptr(szone, small_mag_ptr, previous_block, previous_msize);
- last_block = (void *)((uintptr_t)last_block - SMALL_BYTES_FOR_MSIZE(previous_msize));
- last_msize += previous_msize;
- }
- }
-
- // splice last_block into the free list
- small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize);
- small_mag_ptr->mag_bytes_free_at_end = 0;
- }
-
-#if ASLR_INTERNAL
- if (small_mag_ptr->mag_bytes_free_at_start) {
- last_block = SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region);
- last_msize = SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start);
-
- void *next_block = (void *) ((uintptr_t)last_block + small_mag_ptr->mag_bytes_free_at_start);
- if (SMALL_PTR_IS_FREE(next_block)) {
- msize_t next_msize = SMALL_PTR_SIZE(next_block);
-
- small_meta_header_set_middle(SMALL_META_HEADER_FOR_PTR(next_block), SMALL_META_INDEX_FOR_PTR(next_block));
- small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize);
- last_msize += next_msize;
- }
-
- // splice last_block into the free list
- small_free_list_add_ptr(szone, small_mag_ptr, last_block, last_msize);
- small_mag_ptr->mag_bytes_free_at_start = 0;
- }
-#endif
-
- // TODO: Will we ever need to coalesce the blocks at the beginning and end when we finalize?
-
- small_mag_ptr->mag_last_region = NULL;
-}
-
-static int
-small_free_detach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r) {
- unsigned char *ptr = SMALL_REGION_ADDRESS(r);
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
- uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r);
- uintptr_t current = start;
- uintptr_t limit = (uintptr_t)SMALL_REGION_END(r);
- int total_alloc = 0;
-
- while (current < limit) {
- unsigned index = SMALL_META_INDEX_FOR_PTR(current);
- msize_t msize_and_free = meta_headers[index];
- boolean_t is_free = msize_and_free & SMALL_IS_FREE;
- msize_t msize = msize_and_free & ~ SMALL_IS_FREE;
-
- if (!msize) {
-#if DEBUG_MALLOC
- malloc_printf("*** small_free_detach_region error with %p: msize=%d is_free =%d\n",
- (void *)current, msize, is_free);
-#endif
- break;
- }
- if (is_free) {
- small_free_list_remove_ptr(szone, small_mag_ptr, (void *)current, msize);
- } else {
- total_alloc++;
- }
- current += SMALL_BYTES_FOR_MSIZE(msize);
- }
- return total_alloc;
-}
-
-static size_t
-small_free_reattach_region(szone_t *szone, magazine_t *small_mag_ptr, region_t r) {
- unsigned char *ptr = SMALL_REGION_ADDRESS(r);
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
- uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r);
- uintptr_t current = start;
- uintptr_t limit = (uintptr_t)SMALL_REGION_END(r);
- size_t total_alloc = 0;
-
- while (current < limit) {
- unsigned index = SMALL_META_INDEX_FOR_PTR(current);
- msize_t msize_and_free = meta_headers[index];
- boolean_t is_free = msize_and_free & SMALL_IS_FREE;
- msize_t msize = msize_and_free & ~ SMALL_IS_FREE;
-
- if (!msize) {
-#if DEBUG_MALLOC
- malloc_printf("*** small_free_reattach_region error with %p: msize=%d is_free =%d\n",
- (void *)current, msize, is_free);
-#endif
- break;
- }
- if (is_free) {
- small_free_list_add_ptr(szone, small_mag_ptr, (void *)current, msize);
- } else {
- total_alloc += SMALL_BYTES_FOR_MSIZE(msize);
- }
- current += SMALL_BYTES_FOR_MSIZE(msize);
- }
- return total_alloc;
-}
-
-typedef struct {
- uint16_t pnum, size;
-} small_pg_pair_t;
-
-static void NOINLINE /* want private stack frame for automatic array */
-small_free_scan_madvise_free(szone_t *szone, magazine_t *depot_ptr, region_t r) {
- uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(r);
- uintptr_t current = start;
- uintptr_t limit = (uintptr_t)SMALL_REGION_END(r);
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(start);
- small_pg_pair_t advisory[((SMALL_REGION_PAYLOAD_BYTES + vm_page_size - 1) >> vm_page_shift) >> 1]; // 4096bytes stack allocated
- int advisories = 0;
-
- // Scan the metadata identifying blocks which span one or more pages. Mark the pages MADV_FREE taking care to preserve free list
- // management data.
- while (current < limit) {
- unsigned index = SMALL_META_INDEX_FOR_PTR(current);
- msize_t msize_and_free = meta_headers[index];
- boolean_t is_free = msize_and_free & SMALL_IS_FREE;
- msize_t msize = msize_and_free & ~ SMALL_IS_FREE;
-
- if (is_free && !msize && (current == start)) {
-#if DEBUG_MALLOC
- // first block is all free
- malloc_printf("*** small_free_scan_madvise_free first block is all free! %p: msize=%d is_free =%d\n",
- (void *)current, msize, is_free);
-#endif
- uintptr_t pgLo = round_page(start + sizeof(free_list_t) + sizeof(msize_t));
- uintptr_t pgHi = trunc_page(start + SMALL_REGION_SIZE - sizeof(msize_t));
-
- if (pgLo < pgHi) {
- advisory[advisories].pnum = (pgLo - start) >> vm_page_shift;
- advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift;
- advisories++;
- }
- break;
- }
- if (!msize) {
-#if DEBUG_MALLOC
- malloc_printf("*** small_free_scan_madvise_free error with %p: msize=%d is_free =%d\n",
- (void *)current, msize, is_free);
-#endif
- break;
- }
- if (is_free) {
- uintptr_t pgLo = round_page(current + sizeof(free_list_t) + sizeof(msize_t));
- uintptr_t pgHi = trunc_page(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t));
-
- if (pgLo < pgHi) {
- advisory[advisories].pnum = (pgLo - start) >> vm_page_shift;
- advisory[advisories].size = (pgHi - pgLo) >> vm_page_shift;
- advisories++;
- }
- }
- current += SMALL_BYTES_FOR_MSIZE(msize);
- }
-
- if (advisories > 0) {
- int i;
-
- OSAtomicIncrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot));
- SZONE_MAGAZINE_PTR_UNLOCK(szone, depot_ptr);
- for (i = 0; i < advisories; ++i) {
- uintptr_t addr = (advisory[i].pnum << vm_page_shift) + start;
- size_t size = advisory[i].size << vm_page_shift;
-
-#if TARGET_OS_EMBEDDED
- madvise_free_range(szone, r, addr, addr + size, NULL);
-#else
- madvise_free_range(szone, r, addr, addr + size);
-#endif
- }
- SZONE_MAGAZINE_PTR_LOCK(szone, depot_ptr);
- OSAtomicDecrement32Barrier(&(REGION_TRAILER_FOR_SMALL_REGION(r)->pinned_to_depot));
- }
-}
-
-static region_t
-small_free_try_depot_unmap_no_lock(szone_t *szone, magazine_t *depot_ptr, region_trailer_t *node)
-{
- if (0 < node->bytes_used ||
- 0 < node->pinned_to_depot ||
- depot_ptr->recirculation_entries < (szone->num_small_magazines * 2)) {
- return NULL;
- }
-
- // disconnect first node from Depot
- recirc_list_extract(szone, depot_ptr, node);
-
- // Iterate the region pulling its free entries off the (locked) Depot's free list
- region_t sparse_region = SMALL_REGION_FOR_PTR(node);
- int objects_in_use = small_free_detach_region(szone, depot_ptr, sparse_region);
-
- if (0 == objects_in_use) {
- // Invalidate the hash table entry for this region with HASHRING_REGION_DEALLOCATED.
- // Using HASHRING_REGION_DEALLOCATED preserves the collision chain, using HASHRING_OPEN_ENTRY (0) would not.
- rgnhdl_t pSlot = hash_lookup_region_no_lock(szone->small_region_generation->hashed_regions,
- szone->small_region_generation->num_regions_allocated,
- szone->small_region_generation->num_regions_allocated_shift, sparse_region);
- if (NULL == pSlot) {
- szone_error(szone, 1, "small_free_try_depot_unmap_no_lock hash lookup failed:", NULL, "%p\n", sparse_region);
- return NULL;
- }
- *pSlot = HASHRING_REGION_DEALLOCATED;
- depot_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES;
- __sync_fetch_and_add( &(szone->num_small_regions_dealloc), 1); // Atomically increment num_small_regions_dealloc
-
- // Caller will transfer ownership of the region back to the OS with no locks held
- MAGMALLOC_DEALLOCREGION((void *)szone, (void *)sparse_region, SMALL_REGION_SIZE); // DTrace USDT Probe
- return sparse_region;
-
- } else {
- szone_error(szone, 1, "small_free_try_depot_unmap_no_lock objects_in_use not zero:", NULL, "%d\n", objects_in_use);
- return NULL;
- }
-}
-
-static boolean_t
-small_free_do_recirc_to_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index)
-{
- // The entire magazine crossed the "emptiness threshold". Transfer a region
- // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e
- // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list.
- region_trailer_t *node = small_mag_ptr->firstNode;
-
- while (node && !node->recirc_suitable) {
- node = node->next;
- }
-
- if (NULL == node) {
-#if DEBUG_MALLOC
- malloc_printf("*** small_free_do_recirc_to_depot end of list\n");
-#endif
- return TRUE; // Caller must SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- }
-
- region_t sparse_region = SMALL_REGION_FOR_PTR(node);
-
- // Deal with unclaimed memory -- mag_bytes_free_at_end or mag_bytes_free_at start
- if (sparse_region == small_mag_ptr->mag_last_region && (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start)) {
- small_finalize_region(szone, small_mag_ptr);
- }
-
- // disconnect "suitable" node from magazine
- recirc_list_extract(szone, small_mag_ptr, node);
-
- // Iterate the region pulling its free entries off its (locked) magazine's free list
- int objects_in_use = small_free_detach_region(szone, small_mag_ptr, sparse_region);
- magazine_t *depot_ptr = &(szone->small_magazines[DEPOT_MAGAZINE_INDEX]);
-
- // hand over the region to the (locked) Depot
- SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr);
- // this will cause small_free_list_add_ptr called by small_free_reattach_region to use
- // the depot as its target magazine, rather than magazine formerly associated with sparse_region
- MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = DEPOT_MAGAZINE_INDEX;
- node->pinned_to_depot = 0;
-
- // Iterate the region putting its free entries on Depot's free list
- size_t bytes_inplay = small_free_reattach_region(szone, depot_ptr, sparse_region);
-
- small_mag_ptr->mag_num_bytes_in_objects -= bytes_inplay;
- small_mag_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES;
- small_mag_ptr->mag_num_objects -= objects_in_use;
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr); // Unlock the originating magazine
-
- depot_ptr->mag_num_bytes_in_objects += bytes_inplay;
- depot_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES;
- depot_ptr->mag_num_objects += objects_in_use;
-
- // connect to Depot as last node
- recirc_list_splice_last(szone, depot_ptr, node);
-
- MAGMALLOC_RECIRCREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE,
- (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe
-
- // Mark free'd dirty pages with MADV_FREE to reduce memory pressure
- small_free_scan_madvise_free(szone, depot_ptr, sparse_region);
-
- // If the region is entirely empty vm_deallocate() it outside the depot lock
- region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, depot_ptr, node);
- SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr);
- if (r_dealloc)
- deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0);
- return FALSE; // Caller need not unlock the originating magazine
-}
-
-static region_t
-small_find_msize_region(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize)
-{
- free_list_t *ptr;
- grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1;
- free_list_t **free_list = small_mag_ptr->mag_free_list;
- free_list_t **the_slot = free_list + slot;
- free_list_t **limit;
- unsigned bitmap;
-
- // Assumes we've locked the magazine
- CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__);
-
- // Look for an exact match by checking the freelist for this msize.
- ptr = *the_slot;
- if (ptr)
- return SMALL_REGION_FOR_PTR(ptr);
-
- // Mask off the bits representing slots holding free blocks smaller than
- // the size we need.
- if (szone->is_largemem) {
- // BITMAPN_CTZ implementation
- unsigned idx = slot >> 5;
- bitmap = 0;
- unsigned mask = ~ ((1 << (slot & 31)) - 1);
- for ( ; idx < SMALL_BITMAP_WORDS; ++idx ) {
- bitmap = small_mag_ptr->mag_bitmap[idx] & mask;
- if (bitmap != 0)
- break;
- mask = ~0U;
- }
- // Check for fallthrough: No bits set in bitmap
- if ((bitmap == 0) && (idx == SMALL_BITMAP_WORDS))
- return NULL;
-
- // Start looking at the first set bit, plus 32 bits for every word of
- // zeroes or entries that were too small.
- slot = BITMAP32_CTZ((&bitmap)) + (idx * 32);
- } else {
- bitmap = small_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1);
- if (!bitmap)
- return NULL;
-
- slot = BITMAP32_CTZ((&bitmap));
- }
- limit = free_list + szone->num_small_slots - 1;
- free_list += slot;
-
- if (free_list < limit) {
- ptr = *free_list;
- if (ptr)
- return SMALL_REGION_FOR_PTR(ptr);
- else {
- /* Shouldn't happen. Fall through to look at last slot. */
-#if DEBUG_MALLOC
- malloc_printf("in small_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n",slot);
-#endif
- }
- }
-
- // We are now looking at the last slot, which contains blocks equal to, or
- // due to coalescing of free blocks, larger than (num_small_slots - 1) * (small quantum size).
- ptr = *limit;
- if (ptr)
- return SMALL_REGION_FOR_PTR(ptr);
-
- return NULL;
-}
-
-static boolean_t
-small_get_region_from_depot(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize)
-{
- magazine_t *depot_ptr = &(szone->small_magazines[DEPOT_MAGAZINE_INDEX]);
-
- /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */
- if (szone->num_small_magazines == 1) // Uniprocessor, single magazine, so no recirculation necessary
- return 0;
-
-#if DEBUG_MALLOC
- if (DEPOT_MAGAZINE_INDEX == mag_index) {
- szone_error(szone, 1, "small_get_region_from_depot called for magazine index -1", NULL, NULL);
- return 0;
- }
-#endif
-
- SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr);
-
- // Appropriate a Depot'd region that can satisfy requested msize.
- region_trailer_t *node;
- region_t sparse_region;
-
- while (1) {
- sparse_region = small_find_msize_region(szone, depot_ptr, DEPOT_MAGAZINE_INDEX, msize);
- if (NULL == sparse_region) { // Depot empty?
- SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr);
- return 0;
- }
-
- node = REGION_TRAILER_FOR_SMALL_REGION(sparse_region);
- if (0 >= node->pinned_to_depot)
- break;
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr);
- pthread_yield_np();
- SZONE_MAGAZINE_PTR_LOCK(szone,depot_ptr);
- }
-
- // disconnect node from Depot
- recirc_list_extract(szone, depot_ptr, node);
-
- // Iterate the region pulling its free entries off the (locked) Depot's free list
- int objects_in_use = small_free_detach_region(szone, depot_ptr, sparse_region);
-
- // Transfer ownership of the region
- MAGAZINE_INDEX_FOR_SMALL_REGION(sparse_region) = mag_index;
- node->pinned_to_depot = 0;
-
- // Iterate the region putting its free entries on its new (locked) magazine's free list
- size_t bytes_inplay = small_free_reattach_region(szone, small_mag_ptr, sparse_region);
-
- depot_ptr->mag_num_bytes_in_objects -= bytes_inplay;
- depot_ptr->num_bytes_in_magazine -= SMALL_REGION_PAYLOAD_BYTES;
- depot_ptr->mag_num_objects -= objects_in_use;
-
- small_mag_ptr->mag_num_bytes_in_objects += bytes_inplay;
- small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES;
- small_mag_ptr->mag_num_objects += objects_in_use;
-
- // connect to magazine as first node
- recirc_list_splice_first(szone, small_mag_ptr, node);
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone,depot_ptr);
-
- // madvise() outside the Depot lock
-#if TARGET_OS_EMBEDDED
- if (node->failedREUSE) {
-#else
- if (node->failedREUSE ||
- -1 == madvise((void *)sparse_region, SMALL_REGION_PAYLOAD_BYTES, MADV_FREE_REUSE)) {
-#endif
- /* -1 return: VM map entry change makes this unfit for reuse. Something evil lurks. */
-#if DEBUG_MADVISE
- szone_error(szone, 0, "small_get_region_from_depot madvise(..., MADV_FREE_REUSE) failed",
- sparse_region, "length=%d\n", SMALL_REGION_PAYLOAD_BYTES);
-#endif
- node->failedREUSE = TRUE;
- }
-
- MAGMALLOC_DEPOTREGION((void *)szone, (int)mag_index, (void *)sparse_region, SMALL_REGION_SIZE,
- (int)BYTES_USED_FOR_SMALL_REGION(sparse_region)); // DTrace USDT Probe
-
- return 1;
-}
-
-#define K 1.5 // headroom measured in number of 8Mb regions
-#define DENSITY_THRESHOLD(a) \
- ((a) - ((a) >> 2)) // "Emptiness" f = 0.25, so "Density" is (1 - f)*a. Generally: ((a) - ((a) >> -log2(f)))
-
-static INLINE boolean_t
-small_free_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, region_t region, void *ptr, msize_t msize)
-{
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
- unsigned index = SMALL_META_INDEX_FOR_PTR(ptr);
- void *original_ptr = ptr;
- size_t original_size = SMALL_BYTES_FOR_MSIZE(msize);
- unsigned char *next_block = ((unsigned char *)ptr + original_size);
- msize_t next_index = index + msize;
- msize_t previous_msize, next_msize;
- void *previous;
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
- if (!msize) {
- szone_error(szone, 1, "trying to free small block that is too small", ptr,
- "in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
-
- // We try to coalesce this block with the preceeding one
- if (index && (SMALL_PREVIOUS_MSIZE(ptr) <= index)) {
- previous_msize = SMALL_PREVIOUS_MSIZE(ptr);
- if (meta_headers[index - previous_msize] == (previous_msize | SMALL_IS_FREE)) {
- previous = (void *)((uintptr_t)ptr - SMALL_BYTES_FOR_MSIZE(previous_msize));
- // previous is really to be coalesced
-#if DEBUG_MALLOC
- if (LOG(szone, ptr) || LOG(szone,previous)) {
- malloc_printf("in small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous);
- }
-#endif
- small_free_list_remove_ptr(szone, small_mag_ptr, previous, previous_msize);
- small_meta_header_set_middle(meta_headers, index);
- ptr = previous;
- msize += previous_msize;
- index -= previous_msize;
- }
- }
- // We try to coalesce with the next block
- if ((next_block < SMALL_REGION_END(region)) && (meta_headers[next_index] & SMALL_IS_FREE)) {
- // next block is free, we coalesce
- next_msize = meta_headers[next_index] & ~ SMALL_IS_FREE;
-#if DEBUG_MALLOC
- if (LOG(szone,ptr))
- malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n",
- ptr, msize, next_block, next_msize);
-#endif
- small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize);
- small_meta_header_set_middle(meta_headers, next_index);
- msize += next_msize;
- }
- if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) {
- if (!msize) {
- szone_error(szone, 1, "incorrect size information - block header was damaged", ptr, NULL);
- } else {
- memset(ptr, 0x55, SMALL_BYTES_FOR_MSIZE(msize));
- }
- }
- small_free_list_add_ptr(szone, small_mag_ptr, ptr, msize);
- small_mag_ptr->mag_num_objects--;
- // we use original_size and not msize to avoid double counting the coalesced blocks
- small_mag_ptr->mag_num_bytes_in_objects -= original_size;
-
- // Update this region's bytes in use count
- region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(region);
- size_t bytes_used = node->bytes_used - original_size;
- node->bytes_used = bytes_used;
-
-#if !TARGET_OS_EMBEDDED // Always madvise for embedded platforms
- /* FIXME: Would Uniprocessor benefit from recirc and MADV_FREE? */
- if (szone->num_small_magazines == 1) { // Uniprocessor, single magazine, so no recirculation necessary
- /* NOTHING */
- } else if (DEPOT_MAGAZINE_INDEX != mag_index) {
- // Emptiness discriminant
- if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) {
- /* Region has crossed threshold from density to sparsity. Mark it "suitable" on the
- recirculation candidates list. */
- node->recirc_suitable = TRUE;
- } else {
- /* After this free, we've found the region is still dense, so it must have been even more so before
- the free. That implies the region is already correctly marked. Do nothing. */
- }
-
- // Has the entire magazine crossed the "emptiness threshold"? If so, transfer a region
- // from this magazine to the Depot. Choose a region that itself has crossed the emptiness threshold (i.e
- // is at least fraction "f" empty.) Such a region will be marked "suitable" on the recirculation list.
-
- size_t a = small_mag_ptr->num_bytes_in_magazine; // Total bytes allocated to this magazine
- size_t u = small_mag_ptr->mag_num_bytes_in_objects; // In use (malloc'd) from this magaqzine
-
- if (a - u > ((3 * SMALL_REGION_PAYLOAD_BYTES) / 2) && u < DENSITY_THRESHOLD(a)) {
- return small_free_do_recirc_to_depot(szone, small_mag_ptr, mag_index);
- }
-
- } else {
-#endif
- // Freed to Depot. N.B. Lock on small_magazines[DEPOT_MAGAZINE_INDEX] is already held
- // Calcuate the first page in the coalesced block that would be safe to mark MADV_FREE
- uintptr_t safe_ptr = (uintptr_t)ptr + sizeof(free_list_t) + sizeof(msize_t);
- uintptr_t round_safe = round_page(safe_ptr);
-
- // Calcuate the last page in the coalesced block that would be safe to mark MADV_FREE
- uintptr_t safe_extent = (uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t);
- uintptr_t trunc_extent = trunc_page(safe_extent);
-
- // The newly freed block may complete a span of bytes that cover one or more pages. Mark the span with MADV_FREE.
- if (round_safe < trunc_extent) { // Safe area covers a page (perhaps many)
- uintptr_t lo = trunc_page((uintptr_t)original_ptr);
- uintptr_t hi = round_page((uintptr_t)original_ptr + original_size);
-
- small_free_list_remove_ptr(szone, small_mag_ptr, ptr, msize);
- small_meta_header_set_in_use(meta_headers, index, msize);
-
- OSAtomicIncrement32Barrier(&(node->pinned_to_depot));
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
-#if TARGET_OS_EMBEDDED
- madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi), &szone->last_small_advise);
-#else
- madvise_free_range(szone, region, MAX(round_safe, lo), MIN(trunc_extent, hi));
-#endif
- SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr);
- OSAtomicDecrement32Barrier(&(node->pinned_to_depot));
-
- small_meta_header_set_is_free(meta_headers, index, msize);
- small_free_list_add_ptr(szone, small_mag_ptr, ptr, msize);
- }
-
-#if !TARGET_OS_EMBEDDED
- if (0 < bytes_used || 0 < node->pinned_to_depot) {
- /* Depot'd region is still live. Leave it in place on the Depot's recirculation list
- so as to avoid thrashing between the Depot's free list and a magazines's free list
- with detach_region/reattach_region */
- } else {
- /* Depot'd region is just now empty. Consider return to OS. */
- region_t r_dealloc = small_free_try_depot_unmap_no_lock(szone, small_mag_ptr, node);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- if (r_dealloc)
- deallocate_pages(szone, r_dealloc, SMALL_REGION_SIZE, 0);
- return FALSE; // Caller need not unlock
- }
- }
-#endif
-
- return TRUE; // Caller must do SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr)
-}
-
-// Allocates from the last region or a freshly allocated region
-static void *
-small_malloc_from_region_no_lock(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index,
- msize_t msize, void *aligned_address)
-{
- void *ptr;
-
- // Before anything we transform the mag_bytes_free_at_end or mag_bytes_free_at_start - if any - to a regular free block
- /* FIXME: last_block needs to be coalesced with previous entry if free, <rdar://5462322> */
- if (small_mag_ptr->mag_bytes_free_at_end || small_mag_ptr->mag_bytes_free_at_start)
- small_finalize_region(szone, small_mag_ptr);
-
- // Here find the only place in smallville that (infrequently) takes the small_regions_lock.
- // Only one thread at a time should be permitted to assess the density of the hash
- // ring and adjust if needed.
- // Only one thread at a time should be permitted to insert its new region on
- // the hash ring.
- // It is safe for all other threads to read the hash ring (hashed_regions) and
- // the associated sizes (num_regions_allocated and num_small_regions).
-
- LOCK(szone->small_regions_lock);
- // Check to see if the hash ring of small regions needs to grow. Try to
- // avoid the hash ring becoming too dense.
- if (szone->small_region_generation->num_regions_allocated < (2 * szone->num_small_regions)) {
- region_t *new_regions;
- size_t new_size;
- size_t new_shift = szone->small_region_generation->num_regions_allocated_shift; // In/Out parameter
- new_regions = hash_regions_grow_no_lock(szone, szone->small_region_generation->hashed_regions,
- szone->small_region_generation->num_regions_allocated,
- &new_shift,
- &new_size);
- // Do not deallocate the current hashed_regions allocation since someone
- // may be iterating it. Instead, just leak it.
-
- // Prepare to advance to the "next generation" of the hash ring.
- szone->small_region_generation->nextgen->hashed_regions = new_regions;
- szone->small_region_generation->nextgen->num_regions_allocated = new_size;
- szone->small_region_generation->nextgen->num_regions_allocated_shift = new_shift;
-
- // Throw the switch to atomically advance to the next generation.
- szone->small_region_generation = szone->small_region_generation->nextgen;
- // Ensure everyone sees the advance.
- OSMemoryBarrier();
- }
- // Tag the region at "aligned_address" as belonging to us,
- // and so put it under the protection of the magazine lock we are holding.
- // Do this before advertising "aligned_address" on the hash ring(!)
- MAGAZINE_INDEX_FOR_SMALL_REGION(aligned_address) = mag_index;
-
- // Insert the new region into the hash ring, and update malloc statistics
- hash_region_insert_no_lock(szone->small_region_generation->hashed_regions,
- szone->small_region_generation->num_regions_allocated,
- szone->small_region_generation->num_regions_allocated_shift,
- aligned_address);
-
- szone->num_small_regions++;
-
- UNLOCK(szone->small_regions_lock);
-
- small_mag_ptr->mag_last_region = aligned_address;
- BYTES_USED_FOR_SMALL_REGION(aligned_address) = SMALL_BYTES_FOR_MSIZE(msize);
-#if ASLR_INTERNAL
- int offset_msize = malloc_entropy[1] & SMALL_ENTROPY_MASK;
-#if DEBUG_MALLOC
- if (getenv("MallocASLRForce")) offset_msize = strtol(getenv("MallocASLRForce"), NULL, 0) & SMALL_ENTROPY_MASK;
- if (getenv("MallocASLRPrint")) malloc_printf("Region: %p offset: %d\n", aligned_address, offset_msize);
-#endif
-#else
- int offset_msize = 0;
-#endif
- ptr = (void *)((uintptr_t) aligned_address + SMALL_BYTES_FOR_MSIZE(offset_msize));
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize, msize);
- small_mag_ptr->mag_num_objects++;
- small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(msize);
- small_mag_ptr->num_bytes_in_magazine += SMALL_REGION_PAYLOAD_BYTES;
-
- // add a big free block at the end
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), offset_msize + msize, NUM_SMALL_BLOCKS - msize - offset_msize);
- small_mag_ptr->mag_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(NUM_SMALL_BLOCKS - msize - offset_msize);
-
-#if ASLR_INTERNAL
- // add a big free block at the start
- small_mag_ptr->mag_bytes_free_at_start = SMALL_BYTES_FOR_MSIZE(offset_msize);
- if (offset_msize) {
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, offset_msize);
- }
-#else
- small_mag_ptr->mag_bytes_free_at_start = 0;
-#endif
-
- // connect to magazine as last node
- recirc_list_splice_last(szone, small_mag_ptr, REGION_TRAILER_FOR_SMALL_REGION(aligned_address));
-
- return ptr;
-}
-
-static INLINE void *
-small_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size)
-{
- msize_t new_msize = SMALL_MSIZE_FOR_BYTES(new_good_size);
- msize_t mshrinkage = SMALL_MSIZE_FOR_BYTES(old_size) - new_msize;
-
- if (mshrinkage) {
- void *q = (void *)((uintptr_t)ptr + SMALL_BYTES_FOR_MSIZE(new_msize));
- magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines,
- REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)),
- MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)));
-
- // Mark q as block header and in-use, thus creating two blocks.
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), new_msize);
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), mshrinkage);
- small_mag_ptr->mag_num_objects++;
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone,small_mag_ptr);
- szone_free(szone, q); // avoid inlining free_small(szone, q, ...);
- }
-
- return ptr;
-}
-
-static INLINE boolean_t
-small_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size)
-{
- // returns 1 on success
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
- unsigned index;
- msize_t old_msize, new_msize;
- unsigned next_index;
- void *next_block;
- msize_t next_msize_and_free;
- boolean_t is_free;
- msize_t next_msize, leftover_msize;
- void *leftover;
-
- index = SMALL_META_INDEX_FOR_PTR(ptr);
- old_msize = SMALL_MSIZE_FOR_BYTES(old_size);
- new_msize = SMALL_MSIZE_FOR_BYTES(new_size + SMALL_QUANTUM - 1);
- next_index = index + old_msize;
-
- if (next_index >= NUM_SMALL_BLOCKS) {
- return 0;
- }
- next_block = (char *)ptr + old_size;
-
-#if DEBUG_MALLOC
- if ((uintptr_t)next_block & (SMALL_QUANTUM - 1)) {
- szone_error(szone, 1, "internal invariant broken in realloc(next_block)", next_block, NULL);
- }
- if (meta_headers[index] != old_msize)
- malloc_printf("*** small_try_realloc_in_place incorrect old %d %d\n",
- meta_headers[index], old_msize);
-#endif
-
- magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines,
- REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)),
- MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr)));
-
- /*
- * Look for a free block immediately afterwards. If it's large enough, we can consume (part of)
- * it.
- */
- next_msize_and_free = meta_headers[next_index];
- is_free = next_msize_and_free & SMALL_IS_FREE;
- if (!is_free) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- return 0; // next_block is in use;
- }
- next_msize = next_msize_and_free & ~ SMALL_IS_FREE;
- if (old_msize + next_msize < new_msize) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- return 0; // even with next block, not enough
- }
- /*
- * The following block is big enough; pull it from its freelist and chop off enough to satisfy
- * our needs.
- */
- small_free_list_remove_ptr(szone, small_mag_ptr, next_block, next_msize);
- small_meta_header_set_middle(meta_headers, next_index);
- leftover_msize = old_msize + next_msize - new_msize;
- if (leftover_msize) {
- /* there's some left, so put the remainder back */
- leftover = (unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(new_msize);
-
- small_free_list_add_ptr(szone, small_mag_ptr, leftover, leftover_msize);
- }
-#if DEBUG_MALLOC
- if (SMALL_BYTES_FOR_MSIZE(new_msize) > szone->large_threshold) {
- malloc_printf("*** realloc in place for %p exceeded msize=%d\n", new_msize);
- }
-#endif
- small_meta_header_set_in_use(meta_headers, index, new_msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in small_try_realloc_in_place(), ptr=%p, msize=%d\n", ptr, *SMALL_METADATA_FOR_PTR(ptr));
- }
-#endif
- small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(new_msize - old_msize);
-
- // Update this region's bytes in use count
- region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr));
- size_t bytes_used = node->bytes_used + SMALL_BYTES_FOR_MSIZE(new_msize - old_msize);
- node->bytes_used = bytes_used;
-
- // Emptiness discriminant
- if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) {
- /* After this reallocation the region is still sparse, so it must have been even more so before
- the reallocation. That implies the region is already correctly marked. Do nothing. */
- } else {
- /* Region has crossed threshold from sparsity to density. Mark it not "suitable" on the
- recirculation candidates list. */
- node->recirc_suitable = FALSE;
- }
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- return 1;
-}
-
-static boolean_t
-small_check_region(szone_t *szone, region_t region)
-{
- unsigned char *ptr = SMALL_REGION_ADDRESS(region);
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
- unsigned char *region_end = SMALL_REGION_END(region);
- msize_t prev_free = 0;
- unsigned index;
- msize_t msize_and_free;
- msize_t msize;
- free_list_t *free_head;
- void *previous, *next;
- msize_t *follower;
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr));
- magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]);
-
- // Assumes locked
- CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__);
-
- if (region == small_mag_ptr->mag_last_region) {
- ptr += small_mag_ptr->mag_bytes_free_at_start;
- region_end -= small_mag_ptr->mag_bytes_free_at_end;
- }
-
- while (ptr < region_end) {
- index = SMALL_META_INDEX_FOR_PTR(ptr);
- msize_and_free = meta_headers[index];
- if (!(msize_and_free & SMALL_IS_FREE)) {
- // block is in use
- msize = msize_and_free;
- if (!msize) {
- malloc_printf("*** invariant broken: null msize ptr=%p num_small_regions=%d end=%p\n",
- ptr, szone->num_small_regions, region_end);
- return 0;
- }
-#if !RELAXED_INVARIANT_CHECKS
- if (SMALL_BYTES_FOR_MSIZE(msize) > szone->large_threshold) {
- malloc_printf("*** invariant broken for %p this small msize=%d - size is too large\n",
- ptr, msize_and_free);
- return 0;
- }
-#endif // RELAXED_INVARIANT_CHECKS
- ptr += SMALL_BYTES_FOR_MSIZE(msize);
- prev_free = 0;
- } else {
- // free pointer
- msize = msize_and_free & ~ SMALL_IS_FREE;
- free_head = (free_list_t *)ptr;
- follower = (msize_t *)FOLLOWING_SMALL_PTR(ptr, msize);
- if (!msize) {
- malloc_printf("*** invariant broken for free block %p this msize=%d\n", ptr, msize);
- return 0;
- }
-#if !RELAXED_INVARIANT_CHECKS
- if (prev_free) {
- malloc_printf("*** invariant broken for %p (2 free in a row)\n", ptr);
- return 0;
- }
-#endif
- previous = free_list_unchecksum_ptr(szone, &free_head->previous);
- next = free_list_unchecksum_ptr(szone, &free_head->next);
- if (previous && !SMALL_PTR_IS_FREE(previous)) {
- malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n",
- ptr, free_head->previous);
- return 0;
- }
- if (next && !SMALL_PTR_IS_FREE(next)) {
- malloc_printf("*** invariant broken for %p (next is not a free pointer)\n", ptr);
- return 0;
- }
- if (SMALL_PREVIOUS_MSIZE(follower) != msize) {
- malloc_printf("*** invariant broken for small free %p followed by %p in region [%p-%p] "
- "(end marker incorrect) should be %d; in fact %d\n",
- ptr, follower, SMALL_REGION_ADDRESS(region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower));
- return 0;
- }
- ptr = (unsigned char *)follower;
- prev_free = SMALL_IS_FREE;
- }
- }
- return 1;
-}
-
-static kern_return_t
-small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone,
- memory_reader_t reader, vm_range_recorder_t recorder)
-{
- size_t num_regions;
- size_t index;
- region_t *regions;
- vm_range_t buffer[MAX_RECORDER_BUFFER];
- unsigned count = 0;
- kern_return_t err;
- region_t region;
- vm_range_t range;
- vm_range_t admin_range;
- vm_range_t ptr_range;
- unsigned char *mapped_region;
- msize_t *block_header;
- unsigned block_index;
- unsigned block_limit;
- msize_t msize_and_free;
- msize_t msize;
- magazine_t *small_mag_base = NULL;
-
- region_hash_generation_t *srg_ptr;
- err = reader(task, (vm_address_t)szone->small_region_generation, sizeof(region_hash_generation_t), (void **)&srg_ptr);
- if (err) return err;
-
- num_regions = srg_ptr->num_regions_allocated;
- err = reader(task, (vm_address_t)srg_ptr->hashed_regions, sizeof(region_t) * num_regions, (void **)®ions);
- if (err) return err;
-
- if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) {
- // Map in all active magazines. Do this outside the iteration over regions.
- err = reader(task, (vm_address_t)(szone->small_magazines),
- szone->num_small_magazines*sizeof(magazine_t),(void **)&small_mag_base);
- if (err) return err;
- }
-
- for (index = 0; index < num_regions; ++index) {
- region = regions[index];
- if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) {
- range.address = (vm_address_t)SMALL_REGION_ADDRESS(region);
- range.size = SMALL_REGION_SIZE;
- if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) {
- admin_range.address = range.address + SMALL_METADATA_START;
- admin_range.size = SMALL_METADATA_SIZE;
- recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1);
- }
- if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) {
- ptr_range.address = range.address;
- ptr_range.size = NUM_SMALL_BLOCKS * SMALL_QUANTUM;
- recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1);
- }
- if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) {
- void *mag_last_free;
- vm_address_t mag_last_free_ptr = 0;
- msize_t mag_last_free_msize = 0;
-
- err = reader(task, range.address, range.size, (void **)&mapped_region);
- if (err)
- return err;
-
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(mapped_region);
- magazine_t *small_mag_ptr = small_mag_base + mag_index;
-
- if (DEPOT_MAGAZINE_INDEX != mag_index) {
- mag_last_free = small_mag_ptr->mag_last_free;
- if (mag_last_free) {
- mag_last_free_ptr = (uintptr_t) mag_last_free & ~(SMALL_QUANTUM - 1);
- mag_last_free_msize = (uintptr_t) mag_last_free & (SMALL_QUANTUM - 1);
- }
- } else {
- for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) {
- if ((void *)range.address == (small_mag_base + mag_index)->mag_last_free_rgn) {
- mag_last_free = (small_mag_base + mag_index)->mag_last_free;
- if (mag_last_free) {
- mag_last_free_ptr = (uintptr_t) mag_last_free & ~(SMALL_QUANTUM - 1);
- mag_last_free_msize = (uintptr_t) mag_last_free & (SMALL_QUANTUM - 1);
- }
- }
- }
- }
-
- block_header = (msize_t *)(mapped_region + SMALL_METADATA_START + sizeof(region_trailer_t));
- block_index = 0;
- block_limit = NUM_SMALL_BLOCKS;
- if (region == small_mag_ptr->mag_last_region) {
- block_index += SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start);
- block_limit -= SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end);
- }
- while (block_index < block_limit) {
- msize_and_free = block_header[block_index];
- msize = msize_and_free & ~ SMALL_IS_FREE;
- if (! (msize_and_free & SMALL_IS_FREE) &&
- range.address + SMALL_BYTES_FOR_MSIZE(block_index) != mag_last_free_ptr) {
- // Block in use
- buffer[count].address = range.address + SMALL_BYTES_FOR_MSIZE(block_index);
- buffer[count].size = SMALL_BYTES_FOR_MSIZE(msize);
- count++;
- if (count >= MAX_RECORDER_BUFFER) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
- count = 0;
- }
- }
-
- if (!msize)
- return KERN_FAILURE; // Somethings amiss. Avoid looping at this block_index.
-
- block_index += msize;
- }
- if (count) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
- count = 0;
- }
- }
- }
- }
- return 0;
-}
-
-static void *
-small_malloc_from_free_list(szone_t *szone, magazine_t *small_mag_ptr, mag_index_t mag_index, msize_t msize)
-{
- free_list_t *ptr;
- msize_t this_msize;
- grain_t slot = (msize <= szone->num_small_slots) ? msize - 1 : szone->num_small_slots - 1;
- free_list_t **free_list = small_mag_ptr->mag_free_list;
- free_list_t **the_slot = free_list + slot;
- free_list_t *next;
- free_list_t **limit;
- unsigned bitmap;
- msize_t leftover_msize;
- free_list_t *leftover_ptr;
-
- // Assumes we've locked the region
- CHECK_MAGAZINE_PTR_LOCKED(szone, small_mag_ptr, __PRETTY_FUNCTION__);
-
- // Look for an exact match by checking the freelist for this msize.
- //
- ptr = *the_slot;
- if (ptr) {
- next = free_list_unchecksum_ptr(szone, &ptr->next);
- if (next) {
- next->previous = ptr->previous;
- } else {
- BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot);
- }
- *the_slot = next;
- this_msize = msize;
- goto return_small_alloc;
- }
-
- // Mask off the bits representing slots holding free blocks smaller than
- // the size we need. If there are no larger free blocks, try allocating
- // from the free space at the end of the small region.
- if (szone->is_largemem) {
- // BITMAPN_CTZ implementation
- unsigned idx = slot >> 5;
- bitmap = 0;
- unsigned mask = ~ ((1 << (slot & 31)) - 1);
- for ( ; idx < SMALL_BITMAP_WORDS; ++idx ) {
- bitmap = small_mag_ptr->mag_bitmap[idx] & mask;
- if (bitmap != 0)
- break;
- mask = ~0U;
- }
- // Check for fallthrough: No bits set in bitmap
- if ((bitmap == 0) && (idx == SMALL_BITMAP_WORDS))
- goto try_small_from_end;
-
- // Start looking at the first set bit, plus 32 bits for every word of
- // zeroes or entries that were too small.
- slot = BITMAP32_CTZ((&bitmap)) + (idx * 32);
- } else {
- bitmap = small_mag_ptr->mag_bitmap[0] & ~ ((1 << slot) - 1);
- if (!bitmap)
- goto try_small_from_end;
-
- slot = BITMAP32_CTZ((&bitmap));
- }
- // FIXME: Explain use of - 1 here, last slot has special meaning
- limit = free_list + szone->num_small_slots - 1;
- free_list += slot;
-
- if (free_list < limit) {
- ptr = *free_list;
- if (ptr) {
-
- next = free_list_unchecksum_ptr(szone, &ptr->next);
- *free_list = next;
- if (next) {
- next->previous = ptr->previous;
- } else {
- BITMAPN_CLR(small_mag_ptr->mag_bitmap, slot);
- }
- this_msize = SMALL_PTR_SIZE(ptr);
- goto add_leftover_and_proceed;
- }
-#if DEBUG_MALLOC
- malloc_printf("in small_malloc_from_free_list(), mag_bitmap out of sync, slot=%d\n",slot);
-#endif
- }
-
- // We are now looking at the last slot, which contains blocks equal to, or
- // due to coalescing of free blocks, larger than (num_small_slots - 1) * (small quantum size).
- // If the last freelist is not empty, and the head contains a block that is
- // larger than our request, then the remainder is put back on the free list.
- //
- ptr = *limit;
- if (ptr) {
- this_msize = SMALL_PTR_SIZE(ptr);
- next = free_list_unchecksum_ptr(szone, &ptr->next);
- if (this_msize - msize >= szone->num_small_slots) {
- // the leftover will go back to the free list, so we optimize by
- // modifying the free list rather than a pop and push of the head
- leftover_msize = this_msize - msize;
- leftover_ptr = (free_list_t *)((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize));
- *limit = leftover_ptr;
- if (next) {
- next->previous.u = free_list_checksum_ptr(szone, leftover_ptr);
- }
- leftover_ptr->previous = ptr->previous;
- leftover_ptr->next = ptr->next;
- small_meta_header_set_is_free(SMALL_META_HEADER_FOR_PTR(leftover_ptr),
- SMALL_META_INDEX_FOR_PTR(leftover_ptr), leftover_msize);
- // Store msize at the end of the block denoted by "leftover_ptr" (i.e. at a negative offset from follower)
- SMALL_PREVIOUS_MSIZE(FOLLOWING_SMALL_PTR(leftover_ptr, leftover_msize)) = leftover_msize; // Access is safe
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in small_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize);
- }
-#endif
- this_msize = msize;
- goto return_small_alloc;
- }
- if (next) {
- next->previous = ptr->previous;
- }
- *limit = next;
- goto add_leftover_and_proceed;
- }
-
-try_small_from_end:
- // Let's see if we can use small_mag_ptr->mag_bytes_free_at_end
- if (small_mag_ptr->mag_bytes_free_at_end >= SMALL_BYTES_FOR_MSIZE(msize)) {
- ptr = (free_list_t *)(SMALL_REGION_END(small_mag_ptr->mag_last_region) -
- small_mag_ptr->mag_bytes_free_at_end);
- small_mag_ptr->mag_bytes_free_at_end -= SMALL_BYTES_FOR_MSIZE(msize);
- if (small_mag_ptr->mag_bytes_free_at_end) {
- // let's mark this block as in use to serve as boundary
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr),
- SMALL_META_INDEX_FOR_PTR((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)),
- SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_end));
- }
- this_msize = msize;
- goto return_small_alloc;
- }
-#if ASLR_INTERNAL
- // Try from start if nothing left at end
- if (small_mag_ptr->mag_bytes_free_at_start >= SMALL_BYTES_FOR_MSIZE(msize)) {
- ptr = (free_list_t *)(SMALL_REGION_ADDRESS(small_mag_ptr->mag_last_region) +
- small_mag_ptr->mag_bytes_free_at_start - SMALL_BYTES_FOR_MSIZE(msize));
- small_mag_ptr->mag_bytes_free_at_start -= SMALL_BYTES_FOR_MSIZE(msize);
- if (small_mag_ptr->mag_bytes_free_at_start) {
- // let's mark this block as in use to serve as boundary
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), 0, SMALL_MSIZE_FOR_BYTES(small_mag_ptr->mag_bytes_free_at_start));
- }
- this_msize = msize;
- goto return_small_alloc;
- }
-#endif
- return NULL;
-
-add_leftover_and_proceed:
- if (this_msize > msize) {
- leftover_msize = this_msize - msize;
- leftover_ptr = (free_list_t *)((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize));
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize);
- }
-#endif
- small_free_list_add_ptr(szone, small_mag_ptr, leftover_ptr, leftover_msize);
- this_msize = msize;
- }
-
-return_small_alloc:
- small_mag_ptr->mag_num_objects++;
- small_mag_ptr->mag_num_bytes_in_objects += SMALL_BYTES_FOR_MSIZE(this_msize);
-
- // Update this region's bytes in use count
- region_trailer_t *node = REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr));
- size_t bytes_used = node->bytes_used + SMALL_BYTES_FOR_MSIZE(this_msize);
- node->bytes_used = bytes_used;
-
- // Emptiness discriminant
- if (bytes_used < DENSITY_THRESHOLD(SMALL_REGION_PAYLOAD_BYTES)) {
- /* After this allocation the region is still sparse, so it must have been even more so before
- the allocation. That implies the region is already correctly marked. Do nothing. */
- } else {
- /* Region has crossed threshold from sparsity to density. Mark in not "suitable" on the
- recirculation candidates list. */
- node->recirc_suitable = FALSE;
- }
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in small_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize);
- }
-#endif
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(ptr), SMALL_META_INDEX_FOR_PTR(ptr), this_msize);
- return ptr;
-}
-#undef DENSITY_THRESHOLD
-#undef K
-
-static INLINE void *
-small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested)
-{
- void *ptr;
- mag_index_t mag_index = mag_get_thread_index(szone);
- magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]);
-
- SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr);
-
-#if SMALL_CACHE
- ptr = (void *)small_mag_ptr->mag_last_free;
-
- if ((((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) == msize) {
- // we have a winner
- small_mag_ptr->mag_last_free = NULL;
- small_mag_ptr->mag_last_free_rgn = NULL;
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- ptr = (void *)((uintptr_t)ptr & ~ (SMALL_QUANTUM - 1));
- if (cleared_requested) {
- memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize));
- }
- return ptr;
- }
-#endif /* SMALL_CACHE */
-
- while(1) {
- ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize);
- if (ptr) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- if (cleared_requested) {
- memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize));
- }
- return ptr;
- }
-
- if (small_get_region_from_depot(szone, small_mag_ptr, mag_index, msize)) {
- ptr = small_malloc_from_free_list(szone, small_mag_ptr, mag_index, msize);
- if (ptr) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- if (cleared_requested) {
- memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize));
- }
- return ptr;
- }
- }
-
- // The magazine is exhausted. A new region (heap) must be allocated to satisfy this call to malloc().
- // The allocation, an mmap() system call, will be performed outside the magazine spin locks by the first
- // thread that suffers the exhaustion. That thread sets "alloc_underway" and enters a critical section.
- // Threads arriving here later are excluded from the critical section, yield the CPU, and then retry the
- // allocation. After some time the magazine is resupplied, the original thread leaves with its allocation,
- // and retry-ing threads succeed in the code just above.
- if (!small_mag_ptr->alloc_underway) {
- void *fresh_region;
-
- // time to create a new region (do this outside the magazine lock)
- small_mag_ptr->alloc_underway = TRUE;
- OSMemoryBarrier();
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- fresh_region = allocate_pages_securely(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN, VM_MEMORY_MALLOC_SMALL);
- SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr);
-
- MAGMALLOC_ALLOCREGION((void *)szone, (int)mag_index, fresh_region, SMALL_REGION_SIZE); // DTrace USDT Probe
-
- if (!fresh_region) { // out of memory!
- small_mag_ptr->alloc_underway = FALSE;
- OSMemoryBarrier();
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- return NULL;
- }
-
- ptr = small_malloc_from_region_no_lock(szone, small_mag_ptr, mag_index, msize, fresh_region);
-
- // we don't clear because this freshly allocated space is pristine
- small_mag_ptr->alloc_underway = FALSE;
- OSMemoryBarrier();
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- return ptr;
- } else {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- pthread_yield_np();
- SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr);
- }
- }
- /* NOTREACHED */
-}
-
-static NOINLINE void
-free_small_botch(szone_t *szone, free_list_t *ptr)
-{
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr));
- magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- szone_error(szone, 1, "double free", ptr, NULL);
-}
-
-static INLINE void
-free_small(szone_t *szone, void *ptr, region_t small_region, size_t known_size)
-{
- msize_t msize;
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr));
- magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]);
-
- // ptr is known to be in small_region
- if (known_size) {
- msize = SMALL_MSIZE_FOR_BYTES(known_size + SMALL_QUANTUM - 1);
- } else {
- msize = SMALL_PTR_SIZE(ptr);
- if (SMALL_PTR_IS_FREE(ptr)) {
- free_small_botch(szone, ptr);
- return;
- }
- }
-
- SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr);
-
-#if SMALL_CACHE
- // Depot does not participate in SMALL_CACHE since it can't be directly malloc()'d
- if (DEPOT_MAGAZINE_INDEX != mag_index) {
-
- void *ptr2 = small_mag_ptr->mag_last_free; // Might be NULL
- region_t rgn2 = small_mag_ptr->mag_last_free_rgn;
-
- /* check that we don't already have this pointer in the cache */
- if (ptr == (void *)((uintptr_t)ptr2 & ~ (SMALL_QUANTUM - 1))) {
- free_small_botch(szone, ptr);
- return;
- }
-
- if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize)
- memset(ptr, 0x55, SMALL_BYTES_FOR_MSIZE(msize));
-
- small_mag_ptr->mag_last_free = (void *)(((uintptr_t)ptr) | msize);
- small_mag_ptr->mag_last_free_rgn = small_region;
-
- if (!ptr2) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- CHECK(szone, __PRETTY_FUNCTION__);
- return;
- }
-
- msize = (uintptr_t)ptr2 & (SMALL_QUANTUM - 1);
- ptr = (void *)(((uintptr_t)ptr2) & ~(SMALL_QUANTUM - 1));
- small_region = rgn2;
- }
-#endif /* SMALL_CACHE */
-
- // Now in the time it took to acquire the lock, the region may have migrated
- // from one magazine to another. I.e. trailer->mag_index is volatile.
- // In which case the magazine lock we obtained (namely magazines[mag_index].mag_lock)
- // is stale. If so, keep on tryin' ...
- region_trailer_t *trailer = REGION_TRAILER_FOR_SMALL_REGION(small_region);
- mag_index_t refreshed_index;
-
- while (mag_index != (refreshed_index = trailer->mag_index)) { // Note assignment
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
-
- mag_index = refreshed_index;
- small_mag_ptr = &(szone->small_magazines[mag_index]);
- SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr);
- }
-
- if (small_free_no_lock(szone, small_mag_ptr, mag_index, small_region, ptr, msize))
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
-
- CHECK(szone, __PRETTY_FUNCTION__);
-}
-
-static void
-print_small_free_list(szone_t *szone)
-{
- free_list_t *ptr;
- _SIMPLE_STRING b = _simple_salloc();
- mag_index_t mag_index;
-
- if (b) {
- _simple_sappend(b, "small free sizes:\n");
- for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) {
- grain_t slot = 0;
- _simple_sprintf(b,"\tMagazine %d: ", mag_index);
- while (slot < szone->num_small_slots) {
- ptr = szone->small_magazines[mag_index].mag_free_list[slot];
- if (ptr) {
- _simple_sprintf(b, "%s%y[%d]; ", (slot == szone->num_small_slots-1) ? ">=" : "",
- (slot + 1) * SMALL_QUANTUM, free_list_count(szone, ptr));
- }
- slot++;
- }
- _simple_sappend(b,"\n");
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-
-static void
-print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_start, size_t bytes_at_end)
-{
- unsigned counts[1024];
- unsigned in_use = 0;
- uintptr_t start = (uintptr_t)SMALL_REGION_ADDRESS(region);
- uintptr_t current = start + bytes_at_start;
- uintptr_t limit = (uintptr_t)SMALL_REGION_END(region) - bytes_at_end;
- msize_t msize_and_free;
- msize_t msize;
- unsigned ci;
- _SIMPLE_STRING b;
- uintptr_t pgTot = 0;
-
- if (region == HASHRING_REGION_DEALLOCATED) {
- if ((b = _simple_salloc()) != NULL) {
- _simple_sprintf(b, "Small region [unknown address] was returned to the OS\n");
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
- return;
- }
-
- memset(counts, 0, sizeof(counts));
- while (current < limit) {
- msize_and_free = *SMALL_METADATA_FOR_PTR(current);
- msize = msize_and_free & ~ SMALL_IS_FREE;
- if (!msize) {
- malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize);
- break;
- }
- if (!(msize_and_free & SMALL_IS_FREE)) {
- // block in use
- if (msize < 1024)
- counts[msize]++;
- in_use++;
- } else {
- uintptr_t pgLo = round_page(current + sizeof(free_list_t) + sizeof(msize_t));
- uintptr_t pgHi = trunc_page(current + SMALL_BYTES_FOR_MSIZE(msize) - sizeof(msize_t));
-
- if (pgLo < pgHi) {
- pgTot += (pgHi - pgLo);
- }
- }
- current += SMALL_BYTES_FOR_MSIZE(msize);
- }
- if ((b = _simple_salloc()) != NULL) {
- _simple_sprintf(b, "Small region [%p-%p, %y] \t", (void *)start, SMALL_REGION_END(region), (int)SMALL_REGION_SIZE);
- _simple_sprintf(b, "Magazine=%d \t", MAGAZINE_INDEX_FOR_SMALL_REGION(region));
- _simple_sprintf(b, "Allocations in use=%d \t Bytes in use=%ly \t", in_use, BYTES_USED_FOR_SMALL_REGION(region));
- if (bytes_at_end || bytes_at_start)
- _simple_sprintf(b, "Untouched=%ly ", bytes_at_end + bytes_at_start);
- if (DEPOT_MAGAZINE_INDEX == MAGAZINE_INDEX_FOR_SMALL_REGION(region)) {
- _simple_sprintf(b, "Advised MADV_FREE=%ly", pgTot);
- } else {
- _simple_sprintf(b, "Fragments subject to reclamation=%ly", pgTot);
- }
- if (verbose && in_use) {
- _simple_sappend(b, "\n\tSizes in use: ");
- for (ci = 0; ci < 1024; ci++)
- if (counts[ci])
- _simple_sprintf(b, "%d[%d] ", SMALL_BYTES_FOR_MSIZE(ci), counts[ci]);
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-
-static boolean_t
-small_free_list_check(szone_t *szone, grain_t slot)
-{
- mag_index_t mag_index;
-
- for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) {
- magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]);
- SZONE_MAGAZINE_PTR_LOCK(szone, small_mag_ptr);
-
- unsigned count = 0;
- free_list_t *ptr = szone->small_magazines[mag_index].mag_free_list[slot];
- msize_t msize_and_free;
- free_list_t *previous = NULL;
-
- while (ptr) {
- msize_and_free = *SMALL_METADATA_FOR_PTR(ptr);
- if (!(msize_and_free & SMALL_IS_FREE)) {
- malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- return 0;
- }
- if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) {
- malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- return 0;
- }
- if (!small_region_for_ptr_no_lock(szone, ptr)) {
- malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- return 0;
- }
- if (free_list_unchecksum_ptr(szone, &ptr->previous) != previous) {
- malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- return 0;
- }
- previous = ptr;
- ptr = free_list_unchecksum_ptr(szone, &ptr->next);
- count++;
- }
-
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- }
- return 1;
-}
-
-/*******************************************************************************
- * Large allocator implementation
- ******************************************************************************/
-#pragma mark large allocator
-
-#if DEBUG_MALLOC
-
-static void
-large_debug_print(szone_t *szone)
-{
- unsigned index;
- large_entry_t *range;
- _SIMPLE_STRING b = _simple_salloc();
-
- if (b) {
- for (index = 0, range = szone->large_entries; index < szone->num_large_entries; index++, range++)
- if (range->address)
- _simple_sprintf(b, "%d: %p(%y); ", index, range->address, range->size);
-
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-#endif
-
-/*
- * Scan the hash ring looking for an entry for the given pointer.
- */
-static large_entry_t *
-large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr)
-{
- // result only valid with lock held
- unsigned num_large_entries = szone->num_large_entries;
- unsigned hash_index;
- unsigned index;
- large_entry_t *range;
-
- if (!num_large_entries)
- return NULL;
-
- hash_index = ((uintptr_t)ptr >> vm_page_shift) % num_large_entries;
- index = hash_index;
-
- do {
- range = szone->large_entries + index;
- if (range->address == (vm_address_t)ptr)
- return range;
- if (0 == range->address)
- return NULL; // end of chain
- index++;
- if (index == num_large_entries)
- index = 0;
- } while (index != hash_index);
-
- return NULL;
-}
-
-static void
-large_entry_insert_no_lock(szone_t *szone, large_entry_t range)
-{
- unsigned num_large_entries = szone->num_large_entries;
- unsigned hash_index = (((uintptr_t)(range.address)) >> vm_page_shift) % num_large_entries;
- unsigned index = hash_index;
- large_entry_t *entry;
-
- // assert(szone->num_large_objects_in_use < szone->num_large_entries); /* must be called with room to spare */
-
- do {
- entry = szone->large_entries + index;
- if (0 == entry->address) {
- *entry = range;
- return; // end of chain
- }
- index++;
- if (index == num_large_entries)
- index = 0;
- } while (index != hash_index);
-
- // assert(0); /* must not fallthrough! */
-}
-
-// FIXME: can't we simply swap the (now empty) entry with the last entry on the collision chain for this hash slot?
-static INLINE void
-large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry)
-{
- unsigned num_large_entries = szone->num_large_entries;
- unsigned hash_index = entry - szone->large_entries;
- unsigned index = hash_index;
- large_entry_t range;
-
- // assert(entry->address == 0) /* caller must have cleared *entry */
-
- do {
- index++;
- if (index == num_large_entries)
- index = 0;
- range = szone->large_entries[index];
- if (0 == range.address)
- return;
- szone->large_entries[index].address = (vm_address_t)0;
- szone->large_entries[index].size = 0;
- szone->large_entries[index].did_madvise_reusable = FALSE;
- large_entry_insert_no_lock(szone, range); // this will reinsert in the
- // proper place
- } while (index != hash_index);
-
- // assert(0); /* since entry->address == 0, must not fallthrough! */
-}
-
-// FIXME: num should probably be a size_t, since you can theoretically allocate
-// more than 2^32-1 large_threshold objects in 64 bit.
-static INLINE large_entry_t *
-large_entries_alloc_no_lock(szone_t *szone, unsigned num)
-{
- size_t size = num * sizeof(large_entry_t);
-
- // Note that we allocate memory (via a system call) under a spin lock
- // That is certainly evil, however it's very rare in the lifetime of a process
- // The alternative would slow down the normal case
- return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC_LARGE);
-}
-
-static void
-large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate)
-{
- size_t size = num * sizeof(large_entry_t);
-
- range_to_deallocate->address = (vm_address_t)entries;
- range_to_deallocate->size = round_page(size);
-}
-
-static large_entry_t *
-large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate)
-{
- // sets range_to_deallocate
- unsigned old_num_entries = szone->num_large_entries;
- large_entry_t *old_entries = szone->large_entries;
- // always an odd number for good hashing
- unsigned new_num_entries = (old_num_entries) ? old_num_entries * 2 + 1 :
- ((vm_page_size / sizeof(large_entry_t)) - 1);
- large_entry_t *new_entries = large_entries_alloc_no_lock(szone, new_num_entries);
- unsigned index = old_num_entries;
- large_entry_t oldRange;
-
- // if the allocation of new entries failed, bail
- if (new_entries == NULL)
- return NULL;
-
- szone->num_large_entries = new_num_entries;
- szone->large_entries = new_entries;
-
- /* rehash entries into the new list */
- while (index--) {
- oldRange = old_entries[index];
- if (oldRange.address) {
- large_entry_insert_no_lock(szone, oldRange);
- }
- }
-
- if (old_entries) {
- large_entries_free_no_lock(szone, old_entries, old_num_entries, range_to_deallocate);
- } else {
- range_to_deallocate->address = (vm_address_t)0;
- range_to_deallocate->size = 0;
- }
-
- return new_entries;
-}
-
-// frees the specific entry in the size table
-// returns a range to truly deallocate
-static vm_range_t
-large_entry_free_no_lock(szone_t *szone, large_entry_t *entry)
-{
- vm_range_t range;
-
- range.address = entry->address;
- range.size = entry->size;
-
- if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) {
- protect((void *)range.address, range.size, PROT_READ | PROT_WRITE, szone->debug_flags);
- range.address -= vm_page_size;
- range.size += 2 * vm_page_size;
- }
-
- entry->address = 0;
- entry->size = 0;
- entry->did_madvise_reusable = FALSE;
- large_entries_rehash_after_entry_no_lock(szone, entry);
-
-#if DEBUG_MALLOC
- if (large_entry_for_pointer_no_lock(szone, (void *)range.address)) {
- malloc_printf("*** freed entry %p still in use; num_large_entries=%d\n",
- range.address, szone->num_large_entries);
- large_debug_print(szone);
- szone_sleep();
- }
-#endif
- return range;
-}
-
-static NOINLINE kern_return_t
-large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address,
- unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder)
-{
- unsigned index = 0;
- vm_range_t buffer[MAX_RECORDER_BUFFER];
- unsigned count = 0;
- large_entry_t *entries;
- kern_return_t err;
- vm_range_t range;
- large_entry_t entry;
-
- err = reader(task, large_entries_address, sizeof(large_entry_t) * num_entries, (void **)&entries);
- if (err)
- return err;
-
- index = num_entries;
- if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) {
- range.address = large_entries_address;
- range.size = round_page(num_entries * sizeof(large_entry_t));
- recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &range, 1);
- }
- if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE)) {
- while (index--) {
- entry = entries[index];
- if (entry.address) {
- range.address = entry.address;
- range.size = entry.size;
- buffer[count++] = range;
- if (count >= MAX_RECORDER_BUFFER) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE,
- buffer, count);
- count = 0;
- }
- }
- }
- }
- if (count) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE,
- buffer, count);
- }
- return 0;
-}
-
-static void *
-large_malloc(szone_t *szone, size_t num_pages, unsigned char alignment,
- boolean_t cleared_requested)
-{
- void *addr;
- vm_range_t range_to_deallocate;
- size_t size;
- large_entry_t large_entry;
-
- if (!num_pages)
- num_pages = 1; // minimal allocation size for this szone
- size = (size_t)num_pages << vm_page_shift;
- range_to_deallocate.size = 0;
- range_to_deallocate.address = 0;
-
-#if LARGE_CACHE
- if (size < LARGE_CACHE_SIZE_ENTRY_LIMIT) { // Look for a large_entry_t on the death-row cache?
- SZONE_LOCK(szone);
-
- int i, best = -1, idx = szone->large_entry_cache_newest, stop_idx = szone->large_entry_cache_oldest;
- size_t best_size = SIZE_T_MAX;
-
- while (1) { // Scan large_entry_cache for best fit, starting with most recent entry
- size_t this_size = szone->large_entry_cache[idx].size;
- addr = (void *)szone->large_entry_cache[idx].address;
-
- if (0 == alignment || 0 == (((uintptr_t) addr) & (((uintptr_t) 1 << alignment) - 1))) {
- if (size == this_size) { // size match!
- best = idx;
- best_size = this_size;
- break;
- }
-
- if (size <= this_size && this_size < best_size) { // improved fit?
- best = idx;
- best_size = this_size;
- }
- }
-
- if (idx == stop_idx) // exhausted live ring?
- break;
-
- if (idx)
- idx--; // bump idx down
- else
- idx = LARGE_ENTRY_CACHE_SIZE - 1; // wrap idx
- }
-
- if (best > -1 && (best_size - size) < size) { //limit fragmentation to 50%
- addr = (void *)szone->large_entry_cache[best].address;
- boolean_t was_madvised_reusable = szone->large_entry_cache[best].did_madvise_reusable;
-
- // Compact live ring to fill entry now vacated at large_entry_cache[best]
- // while preserving time-order
- if (szone->large_entry_cache_oldest < szone->large_entry_cache_newest) {
-
- // Ring hasn't wrapped. Fill in from right.
- for (i = best; i < szone->large_entry_cache_newest; ++i)
- szone->large_entry_cache[i] = szone->large_entry_cache[i + 1];
-
- szone->large_entry_cache_newest--; // Pull in right endpoint.
-
- } else if (szone->large_entry_cache_newest < szone->large_entry_cache_oldest) {
-
- // Ring has wrapped. Arrange to fill in from the contiguous side.
- if (best <= szone->large_entry_cache_newest) {
- // Fill from right.
- for (i = best; i < szone->large_entry_cache_newest; ++i)
- szone->large_entry_cache[i] = szone->large_entry_cache[i + 1];
-
- if (0 < szone->large_entry_cache_newest)
- szone->large_entry_cache_newest--;
- else
- szone->large_entry_cache_newest = LARGE_ENTRY_CACHE_SIZE - 1;
- } else {
- // Fill from left.
- for ( i = best; i > szone->large_entry_cache_oldest; --i)
- szone->large_entry_cache[i] = szone->large_entry_cache[i - 1];
-
- if (szone->large_entry_cache_oldest < LARGE_ENTRY_CACHE_SIZE - 1)
- szone->large_entry_cache_oldest++;
- else
- szone->large_entry_cache_oldest = 0;
- }
-
- } else {
- // By trichotomy, large_entry_cache_newest == large_entry_cache_oldest.
- // That implies best == large_entry_cache_newest == large_entry_cache_oldest
- // and the ring is now empty.
- szone->large_entry_cache[best].address = 0;
- szone->large_entry_cache[best].size = 0;
- szone->large_entry_cache[best].did_madvise_reusable = FALSE;
- }
-
- if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) {
- // density of hash table too high; grow table
- // we do that under lock to avoid a race
- large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate);
- if (entries == NULL) {
- SZONE_UNLOCK(szone);
- return NULL;
- }
- }
-
- large_entry.address = (vm_address_t)addr;
- large_entry.size = best_size;
- large_entry.did_madvise_reusable = FALSE;
- large_entry_insert_no_lock(szone, large_entry);
-
- szone->num_large_objects_in_use ++;
- szone->num_bytes_in_large_objects += best_size;
- if (!was_madvised_reusable)
- szone->large_entry_cache_reserve_bytes -= best_size;
-
- szone->large_entry_cache_bytes -= best_size;
-
- if (szone->flotsam_enabled && szone->large_entry_cache_bytes < SZONE_FLOTSAM_THRESHOLD_LOW) {
- szone->flotsam_enabled = FALSE;
- }
-
- SZONE_UNLOCK(szone);
-
- if (range_to_deallocate.size) {
- // we deallocate outside the lock
- deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0);
- }
-
- // Perform the madvise() outside the lock.
- // Typically the madvise() is successful and we'll quickly return from this routine.
- // In the unusual case of failure, reacquire the lock to unwind.
-#if TARGET_OS_EMBEDDED
- // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large
- // cache block twice without MADV_FREE_REUSE in between.
-#endif
- if (was_madvised_reusable && -1 == madvise(addr, size, MADV_FREE_REUSE)) {
- /* -1 return: VM map entry change makes this unfit for reuse. */
-#if DEBUG_MADVISE
- szone_error(szone, 0, "large_malloc madvise(..., MADV_FREE_REUSE) failed",
- addr, "length=%d\n", size);
-#endif
-
- SZONE_LOCK(szone);
- szone->num_large_objects_in_use--;
- szone->num_bytes_in_large_objects -= large_entry.size;
-
- // Re-acquire "entry" after interval just above where we let go the lock.
- large_entry_t *entry = large_entry_for_pointer_no_lock(szone, addr);
- if (NULL == entry) {
- szone_error(szone, 1, "entry for pointer being discarded from death-row vanished", addr, NULL);
- SZONE_UNLOCK(szone);
- } else {
-
- range_to_deallocate = large_entry_free_no_lock(szone, entry);
- SZONE_UNLOCK(szone);
-
- if (range_to_deallocate.size) {
- // we deallocate outside the lock
- deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0);
- }
- }
- /* Fall through to allocate_pages() afresh. */
- } else {
- if (cleared_requested) {
- memset(addr, 0, size);
- }
-
- return addr;
- }
- } else {
- SZONE_UNLOCK(szone);
- }
- }
-
- range_to_deallocate.size = 0;
- range_to_deallocate.address = 0;
-#endif /* LARGE_CACHE */
-
- addr = allocate_pages(szone, size, alignment, szone->debug_flags, VM_MEMORY_MALLOC_LARGE);
- if (addr == NULL) {
- return NULL;
- }
-
- SZONE_LOCK(szone);
- if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) {
- // density of hash table too high; grow table
- // we do that under lock to avoid a race
- large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate);
- if (entries == NULL) {
- SZONE_UNLOCK(szone);
- return NULL;
- }
- }
-
- large_entry.address = (vm_address_t)addr;
- large_entry.size = size;
- large_entry.did_madvise_reusable = FALSE;
- large_entry_insert_no_lock(szone, large_entry);
-
- szone->num_large_objects_in_use ++;
- szone->num_bytes_in_large_objects += size;
- SZONE_UNLOCK(szone);
-
- if (range_to_deallocate.size) {
- // we deallocate outside the lock
- deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0);
- }
- return addr;
-}
-
-static NOINLINE void
-free_large(szone_t *szone, void *ptr)
-{
- // We have established ptr is page-aligned and neither tiny nor small
- large_entry_t *entry;
- vm_range_t vm_range_to_deallocate;
-
- SZONE_LOCK(szone);
- entry = large_entry_for_pointer_no_lock(szone, ptr);
- if (entry) {
-#if LARGE_CACHE
-#ifndef MADV_CAN_REUSE
-#define MADV_CAN_REUSE 9 /* per Francois, for testing until xnu is resubmitted to B&I */
-#endif
- if (entry->size < LARGE_CACHE_SIZE_ENTRY_LIMIT &&
- -1 != madvise((void *)(entry->address), entry->size, MADV_CAN_REUSE)) { // Put the large_entry_t on the death-row cache?
- int idx = szone->large_entry_cache_newest, stop_idx = szone->large_entry_cache_oldest;
- large_entry_t this_entry = *entry; // Make a local copy, "entry" is volatile when lock is let go.
- boolean_t reusable = TRUE;
- boolean_t should_madvise = szone->large_entry_cache_reserve_bytes + this_entry.size > szone->large_entry_cache_reserve_limit;
-
- // Already freed?
- // [Note that repeated entries in death-row risk vending the same entry subsequently
- // to two different malloc() calls. By checking here the (illegal) double free
- // is accommodated, matching the behavior of the previous implementation.]
- while (1) { // Scan large_entry_cache starting with most recent entry
- if (szone->large_entry_cache[idx].address == entry->address) {
- szone_error(szone, 1, "pointer being freed already on death-row", ptr, NULL);
- SZONE_UNLOCK(szone);
- return;
- }
-
- if (idx == stop_idx) // exhausted live ring?
- break;
-
- if (idx)
- idx--; // bump idx down
- else
- idx = LARGE_ENTRY_CACHE_SIZE - 1; // wrap idx
- }
-
- SZONE_UNLOCK(szone);
-
- if (szone->debug_flags & SCALABLE_MALLOC_PURGEABLE) { // Are we a purgable zone?
- int state = VM_PURGABLE_NONVOLATILE; // restore to default condition
-
- if (KERN_SUCCESS != vm_purgable_control(mach_task_self(), this_entry.address, VM_PURGABLE_SET_STATE, &state)) {
- malloc_printf("*** can't vm_purgable_control(..., VM_PURGABLE_SET_STATE) for large freed block at %p\n",
- this_entry.address);
- reusable = FALSE;
- }
- }
-
- if (szone->large_legacy_reset_mprotect) { // Linked for Leopard?
- // Accomodate Leopard apps that (illegally) mprotect() their own guard pages on large malloc'd allocations
- int err = mprotect((void *)(this_entry.address), this_entry.size, PROT_READ | PROT_WRITE);
- if (err) {
- malloc_printf("*** can't reset protection for large freed block at %p\n", this_entry.address);
- reusable = FALSE;
- }
- }
-
- // madvise(..., MADV_REUSABLE) death-row arrivals if hoarding would exceed large_entry_cache_reserve_limit
- if (should_madvise) {
- // Issue madvise to avoid paging out the dirtied free()'d pages in "entry"
- MAGMALLOC_MADVFREEREGION((void *)szone, (void *)0, (void *)(this_entry.address), this_entry.size); // DTrace USDT Probe
-
-#if TARGET_OS_EMBEDDED
- // Ok to do this madvise on embedded because we won't call MADV_FREE_REUSABLE on a large
- // cache block twice without MADV_FREE_REUSE in between.
-#endif
- if (-1 == madvise((void *)(this_entry.address), this_entry.size, MADV_FREE_REUSABLE)) {
- /* -1 return: VM map entry change makes this unfit for reuse. */
-#if DEBUG_MADVISE
- szone_error(szone, 0, "free_large madvise(..., MADV_FREE_REUSABLE) failed",
- (void *)this_entry.address, "length=%d\n", this_entry.size);
-#endif
- reusable = FALSE;
- }
- }
-
- SZONE_LOCK(szone);
-
- // Re-acquire "entry" after interval just above where we let go the lock.
- entry = large_entry_for_pointer_no_lock(szone, ptr);
- if (NULL == entry) {
- szone_error(szone, 1, "entry for pointer being freed from death-row vanished", ptr, NULL);
- SZONE_UNLOCK(szone);
- return;
- }
-
- // Add "entry" to death-row ring
- if (reusable) {
- int idx = szone->large_entry_cache_newest; // Most recently occupied
- vm_address_t addr;
- size_t adjsize;
-
- if (szone->large_entry_cache_newest == szone->large_entry_cache_oldest &&
- 0 == szone->large_entry_cache[idx].address) {
- // Ring is empty, idx is good as it stands
- addr = 0;
- adjsize = 0;
- } else {
- // Extend the queue to the "right" by bumping up large_entry_cache_newest
- if (idx == LARGE_ENTRY_CACHE_SIZE - 1)
- idx = 0; // Wrap index
- else
- idx++; // Bump index
-
- if (idx == szone->large_entry_cache_oldest) { // Fully occupied
- // Drop this entry from the cache and deallocate the VM
- addr = szone->large_entry_cache[idx].address;
- adjsize = szone->large_entry_cache[idx].size;
- szone->large_entry_cache_bytes -= adjsize;
- if (!szone->large_entry_cache[idx].did_madvise_reusable)
- szone->large_entry_cache_reserve_bytes -= adjsize;
- } else {
- // Using an unoccupied cache slot
- addr = 0;
- adjsize = 0;
- }
- }
-
- if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE))
- memset((void *)(entry->address), 0x55, entry->size);
-
- entry->did_madvise_reusable = should_madvise; // Was madvise()'d above?
- if (!should_madvise) // Entered on death-row without madvise() => up the hoard total
- szone->large_entry_cache_reserve_bytes += entry->size;
-
- szone->large_entry_cache_bytes += entry->size;
-
- if (!szone->flotsam_enabled && szone->large_entry_cache_bytes > SZONE_FLOTSAM_THRESHOLD_HIGH) {
- szone->flotsam_enabled = TRUE;
- }
-
- szone->large_entry_cache[idx] = *entry;
- szone->large_entry_cache_newest = idx;
-
- szone->num_large_objects_in_use--;
- szone->num_bytes_in_large_objects -= entry->size;
-
- (void)large_entry_free_no_lock(szone, entry);
-
- if (0 == addr) {
- SZONE_UNLOCK(szone);
- return;
- }
-
- // Fall through to drop large_entry_cache_oldest from the cache,
- // and then deallocate its pages.
-
- // Trim the queue on the "left" by bumping up large_entry_cache_oldest
- if (szone->large_entry_cache_oldest == LARGE_ENTRY_CACHE_SIZE - 1)
- szone->large_entry_cache_oldest = 0;
- else
- szone->large_entry_cache_oldest++;
-
- // we deallocate_pages, including guard pages, outside the lock
- SZONE_UNLOCK(szone);
- deallocate_pages(szone, (void *)addr, (size_t)adjsize, 0);
- return;
- } else {
- /* fall through to discard an allocation that is not reusable */
- }
- }
-#endif /* LARGE_CACHE */
-
- szone->num_large_objects_in_use--;
- szone->num_bytes_in_large_objects -= entry->size;
-
- vm_range_to_deallocate = large_entry_free_no_lock(szone, entry);
- } else {
-#if DEBUG_MALLOC
- large_debug_print(szone);
-#endif
- szone_error(szone, 1, "pointer being freed was not allocated", ptr, NULL);
- SZONE_UNLOCK(szone);
- return;
- }
- SZONE_UNLOCK(szone); // we release the lock asap
- CHECK(szone, __PRETTY_FUNCTION__);
-
- // we deallocate_pages, including guard pages, outside the lock
- if (vm_range_to_deallocate.address) {
-#if DEBUG_MALLOC
- // FIXME: large_entry_for_pointer_no_lock() needs the lock held ...
- if (large_entry_for_pointer_no_lock(szone, (void *)vm_range_to_deallocate.address)) {
- malloc_printf("*** invariant broken: %p still in use num_large_entries=%d\n",
- vm_range_to_deallocate.address, szone->num_large_entries);
- large_debug_print(szone);
- szone_sleep();
- }
-#endif
- deallocate_pages(szone, (void *)vm_range_to_deallocate.address, (size_t)vm_range_to_deallocate.size, 0);
- }
-}
-
-static INLINE void *
-large_try_shrink_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_good_size)
-{
- size_t shrinkage = old_size - new_good_size;
-
- if (shrinkage) {
- SZONE_LOCK(szone);
- /* contract existing large entry */
- large_entry_t *large_entry = large_entry_for_pointer_no_lock(szone, ptr);
- if (!large_entry) {
- szone_error(szone, 1, "large entry reallocated is not properly in table", ptr, NULL);
- SZONE_UNLOCK(szone);
- return ptr;
- }
-
- large_entry->address = (vm_address_t)ptr;
- large_entry->size = new_good_size;
- szone->num_bytes_in_large_objects -= shrinkage;
- SZONE_UNLOCK(szone); // we release the lock asap
-
- deallocate_pages(szone, (void *)((uintptr_t)ptr + new_good_size), shrinkage, 0);
- }
- return ptr;
-}
-
-static INLINE int
-large_try_realloc_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size)
-{
- vm_address_t addr = (vm_address_t)ptr + old_size;
- large_entry_t *large_entry;
- kern_return_t err;
-
- SZONE_LOCK(szone);
- large_entry = large_entry_for_pointer_no_lock(szone, (void *)addr);
- SZONE_UNLOCK(szone);
-
- if (large_entry) { // check if "addr = ptr + old_size" is already spoken for
- return 0; // large pointer already exists in table - extension is not going to work
- }
-
- new_size = round_page(new_size);
- /*
- * Ask for allocation at a specific address, and mark as realloc
- * to request coalescing with previous realloc'ed extensions.
- */
- err = vm_allocate(mach_task_self(), &addr, new_size - old_size, VM_MAKE_TAG(VM_MEMORY_REALLOC));
- if (err != KERN_SUCCESS) {
- return 0;
- }
-
- SZONE_LOCK(szone);
- /* extend existing large entry */
- large_entry = large_entry_for_pointer_no_lock(szone, ptr);
- if (!large_entry) {
- szone_error(szone, 1, "large entry reallocated is not properly in table", ptr, NULL);
- SZONE_UNLOCK(szone);
- return 0; // Bail, leaking "addr"
- }
-
- large_entry->address = (vm_address_t)ptr;
- large_entry->size = new_size;
- szone->num_bytes_in_large_objects += new_size - old_size;
- SZONE_UNLOCK(szone); // we release the lock asap
-
- return 1;
-}
-
-/********************* Zone call backs ************************/
-/*
- * Mark these NOINLINE to avoid bloating the purgeable zone call backs
- */
-static NOINLINE void
-szone_free(szone_t *szone, void *ptr)
-{
- region_t tiny_region;
- region_t small_region;
-
-#if DEBUG_MALLOC
- if (LOG(szone, ptr))
- malloc_printf("in szone_free with %p\n", ptr);
-#endif
- if (!ptr)
- return;
- /*
- * Try to free to a tiny region.
- */
- if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) {
- szone_error(szone, 1, "Non-aligned pointer being freed", ptr, NULL);
- return;
- }
- if ((tiny_region = tiny_region_for_ptr_no_lock(szone, ptr)) != NULL) {
- if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) {
- szone_error(szone, 1, "Pointer to metadata being freed", ptr, NULL);
- return;
- }
- free_tiny(szone, ptr, tiny_region, 0);
- return;
- }
-
- /*
- * Try to free to a small region.
- */
- if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) {
- szone_error(szone, 1, "Non-aligned pointer being freed (2)", ptr, NULL);
- return;
- }
- if ((small_region = small_region_for_ptr_no_lock(szone, ptr)) != NULL) {
- if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) {
- szone_error(szone, 1, "Pointer to metadata being freed (2)", ptr, NULL);
- return;
- }
- free_small(szone, ptr, small_region, 0);
- return;
- }
-
- /* check that it's a legal large allocation */
- if ((uintptr_t)ptr & (vm_page_size - 1)) {
- szone_error(szone, 1, "non-page-aligned, non-allocated pointer being freed", ptr, NULL);
- return;
- }
- free_large(szone, ptr);
-}
-
-static NOINLINE void
-szone_free_definite_size(szone_t *szone, void *ptr, size_t size)
-{
-#if DEBUG_MALLOC
- if (LOG(szone, ptr))
- malloc_printf("in szone_free_definite_size with %p\n", ptr);
-
- if (0 == size) {
- szone_error(szone, 1, "pointer of size zero being freed", ptr, NULL);
- return;
- }
-
-#endif
- if (!ptr)
- return;
-
- /*
- * Try to free to a tiny region.
- */
- if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) {
- szone_error(szone, 1, "Non-aligned pointer being freed", ptr, NULL);
- return;
- }
- if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) {
- if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) {
- szone_error(szone, 1, "Pointer to metadata being freed", ptr, NULL);
- return;
- }
- free_tiny(szone, ptr, TINY_REGION_FOR_PTR(ptr), size);
- return;
- }
-
- /*
- * Try to free to a small region.
- */
- if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) {
- szone_error(szone, 1, "Non-aligned pointer being freed (2)", ptr, NULL);
- return;
- }
- if (size <= szone->large_threshold) {
- if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) {
- szone_error(szone, 1, "Pointer to metadata being freed (2)", ptr, NULL);
- return;
- }
- free_small(szone, ptr, SMALL_REGION_FOR_PTR(ptr), size);
- return;
- }
-
- /* check that it's a legal large allocation */
- if ((uintptr_t)ptr & (vm_page_size - 1)) {
- szone_error(szone, 1, "non-page-aligned, non-allocated pointer being freed", ptr, NULL);
- return;
- }
- free_large(szone, ptr);
-}
-
-static NOINLINE void *
-szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested)
-{
- void *ptr;
- msize_t msize;
-
- if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) {
- // think tiny
- msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
- if (!msize)
- msize = 1;
- ptr = tiny_malloc_should_clear(szone, msize, cleared_requested);
- } else if (size <= szone->large_threshold) {
- // think small
- msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1);
- if (!msize)
- msize = 1;
- ptr = small_malloc_should_clear(szone, msize, cleared_requested);
- } else {
- // large
- size_t num_pages = round_page(size) >> vm_page_shift;
- if (num_pages == 0) /* Overflowed */
- ptr = 0;
- else
- ptr = large_malloc(szone, num_pages, 0, cleared_requested);
- }
-#if DEBUG_MALLOC
- if (LOG(szone, ptr))
- malloc_printf("szone_malloc returned %p\n", ptr);
-#endif
- /*
- * If requested, scribble on allocated memory.
- */
- if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && ptr && !cleared_requested && size)
- memset(ptr, 0xaa, size);
-
- return ptr;
-}
-
-static NOINLINE void *
-szone_malloc(szone_t *szone, size_t size) {
- return szone_malloc_should_clear(szone, size, 0);
-}
-
-static NOINLINE void *
-szone_calloc(szone_t *szone, size_t num_items, size_t size)
-{
- size_t total_bytes = num_items * size;
-
- // Check for overflow of integer multiplication
- if (num_items > 1) {
-#if __LP64__ /* size_t is uint64_t */
- if ((num_items | size) & 0xffffffff00000000ul) {
- // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic
- __uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size);
- if ((uint64_t)(product >> 64)) // compiles to test on upper register of register pair
- return NULL;
- }
-#else /* size_t is uint32_t */
- if ((num_items | size) & 0xffff0000ul) {
- // num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic
- uint64_t product = ((uint64_t)num_items) * ((uint64_t)size);
- if ((uint32_t)(product >> 32)) // compiles to test on upper register of register pair
- return NULL;
- }
-#endif
- }
-
- return szone_malloc_should_clear(szone, total_bytes, 1);
-}
-
-static NOINLINE void *
-szone_valloc(szone_t *szone, size_t size)
-{
- void *ptr;
-
- if (size <= szone->large_threshold) {
- ptr = szone_memalign(szone, vm_page_size, size);
- } else {
- size_t num_pages;
-
- num_pages = round_page(size) >> vm_page_shift;
- ptr = large_malloc(szone, num_pages, 0, 0);
- }
-
-#if DEBUG_MALLOC
- if (LOG(szone, ptr))
- malloc_printf("szone_valloc returned %p\n", ptr);
-#endif
- return ptr;
-}
-
-/* Isolate PIC-base load (for __is_threaded) here. */
-static NOINLINE size_t
-szone_size_try_large(szone_t *szone, const void *ptr)
-{
- size_t size = 0;
- large_entry_t *entry;
-
- SZONE_LOCK(szone);
- entry = large_entry_for_pointer_no_lock(szone, ptr);
- if (entry) {
- size = entry->size;
- }
- SZONE_UNLOCK(szone);
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("szone_size for %p returned %d\n", ptr, (unsigned)size);
- }
-#endif
- return size;
-}
-
-static NOINLINE size_t
-szone_size(szone_t *szone, const void *ptr)
-{
- boolean_t is_free;
- msize_t msize, msize_and_free;
-
- if (!ptr)
- return 0;
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("in szone_size for %p (szone=%p)\n", ptr, szone);
- }
-#endif
-
- /*
- * Look for it in a tiny region.
- */
- if ((uintptr_t)ptr & (TINY_QUANTUM - 1))
- return 0;
- if (tiny_region_for_ptr_no_lock(szone, ptr)) {
- if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS)
- return 0;
- msize = get_tiny_meta_header(ptr, &is_free);
- if (is_free)
- return 0;
-#if TINY_CACHE
- {
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(ptr));
- if (DEPOT_MAGAZINE_INDEX != mag_index) {
- magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]);
-
- if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~ (TINY_QUANTUM - 1)))
- return 0;
- } else {
- for (mag_index = 0; mag_index < szone->num_tiny_magazines; mag_index++) {
- magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]);
-
- if (msize < TINY_QUANTUM && ptr == (void *)((uintptr_t)(tiny_mag_ptr->mag_last_free) & ~ (TINY_QUANTUM - 1)))
- return 0;
- }
- }
- }
-#endif
- return TINY_BYTES_FOR_MSIZE(msize);
- }
-
- /*
- * Look for it in a small region.
- */
- if ((uintptr_t)ptr & (SMALL_QUANTUM - 1))
- return 0;
- if (small_region_for_ptr_no_lock(szone, ptr)) {
- if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS)
- return 0;
- msize_and_free = *SMALL_METADATA_FOR_PTR(ptr);
- if (msize_and_free & SMALL_IS_FREE)
- return 0;
-#if SMALL_CACHE
- {
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(ptr));
- if (DEPOT_MAGAZINE_INDEX != mag_index) {
- magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]);
-
- if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~ (SMALL_QUANTUM - 1)))
- return 0;
- } else {
- for (mag_index = 0; mag_index < szone->num_small_magazines; mag_index++) {
- magazine_t *small_mag_ptr = &(szone->small_magazines[mag_index]);
-
- if (ptr == (void *)((uintptr_t)(small_mag_ptr->mag_last_free) & ~ (SMALL_QUANTUM - 1)))
- return 0;
- }
- }
- }
-#endif
- return SMALL_BYTES_FOR_MSIZE(msize_and_free);
- }
-
- /*
- * If not page-aligned, it cannot have come from a large allocation.
- */
- if ((uintptr_t)ptr & (vm_page_size - 1))
- return 0;
-
- /*
- * Look for it in a large entry.
- */
- return szone_size_try_large(szone, ptr);
-}
-
-static NOINLINE void *
-szone_realloc(szone_t *szone, void *ptr, size_t new_size)
-{
- size_t old_size, new_good_size, valid_size;
- void *new_ptr;
-
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("in szone_realloc for %p, %d\n", ptr, (unsigned)new_size);
- }
-#endif
- if (NULL == ptr) {
- // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size.
- return szone_malloc(szone, new_size);
- } else if (0 == new_size) {
- // If size is 0 and ptr is not a null pointer, the object pointed to is freed.
- szone_free(szone, ptr);
- // If size is 0, either a null pointer or a unique pointer that can be successfully passed
- // to free() shall be returned.
- return szone_malloc(szone, 1);
- }
-
- old_size = szone_size(szone, ptr);
- if (!old_size) {
- szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL);
- return NULL;
- }
-
- new_good_size = szone_good_size(szone, new_size);
- if (new_good_size == old_size) { // Existing allocation is best fit evar?
- return ptr;
- }
-
- /*
- * If the new size suits the tiny allocator and the pointer being resized
- * belongs to a tiny region, try to reallocate in-place.
- */
- if (new_good_size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) {
- if (old_size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) {
- if (new_good_size <= (old_size >> 1)) {
- /*
- * Serious shrinkage (more than half). free() the excess.
- */
- return tiny_try_shrink_in_place(szone, ptr, old_size, new_good_size);
- } else if (new_good_size <= old_size) {
- /*
- * new_good_size smaller than old_size but not by much (less than half).
- * Avoid thrashing at the expense of some wasted storage.
- */
- return ptr;
- } else if (tiny_try_realloc_in_place(szone, ptr, old_size, new_good_size)) { // try to grow the allocation
- return ptr;
- }
- }
-
- /*
- * Else if the new size suits the small allocator and the pointer being resized
- * belongs to a small region, and we're not protecting the small allocations
- * try to reallocate in-place.
- */
- } else if (new_good_size <= szone->large_threshold) {
- if ((NUM_TINY_SLOTS - 1) * TINY_QUANTUM < old_size && old_size <= szone->large_threshold) {
- if (new_good_size <= (old_size >> 1)) {
- return small_try_shrink_in_place(szone, ptr, old_size, new_good_size);
- } else if (new_good_size <= old_size) {
- return ptr;
- } else if (small_try_realloc_in_place(szone, ptr, old_size, new_good_size)) {
- return ptr;
- }
- }
- /*
- * Else if the allocation's a large allocation, try to reallocate in-place there.
- */
- } else if (!(szone->debug_flags & SCALABLE_MALLOC_PURGEABLE) && // purgeable needs fresh allocation
- (old_size > szone->large_threshold) &&
- (new_good_size > szone->large_threshold)) {
- if (new_good_size <= (old_size >> 1)) {
- return large_try_shrink_in_place(szone, ptr, old_size, new_good_size);
- } else if (new_good_size <= old_size) {
- return ptr;
- } else if (large_try_realloc_in_place(szone, ptr, old_size, new_good_size)) {
- return ptr;
- }
- }
-
- /*
- * Can't reallocate in place for whatever reason; allocate a new buffer and copy.
- */
- if (new_good_size <= (old_size >> 1)) {
- /* Serious shrinkage (more than half). FALL THROUGH to alloc/copy/free. */
- } else if (new_good_size <= old_size) {
- return ptr;
- }
-
- new_ptr = szone_malloc(szone, new_size);
- if (new_ptr == NULL)
- return NULL;
-
- /*
- * If the allocation's large enough, try to copy using VM. If that fails, or
- * if it's too small, just copy by hand.
- */
- valid_size = MIN(old_size, new_size);
- if ((valid_size < szone->vm_copy_threshold) ||
- vm_copy(mach_task_self(), (vm_address_t)ptr, valid_size, (vm_address_t)new_ptr))
- memcpy(new_ptr, ptr, valid_size);
- szone_free(szone, ptr);
-
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size);
- }
-#endif
- return new_ptr;
-}
-
-static NOINLINE void *
-szone_memalign(szone_t *szone, size_t alignment, size_t size)
-{
- if ((size + alignment) < size) // size_t arithmetic wrapped!
- return NULL;
-
- // alignment is gauranteed a power of 2 at least as large as sizeof(void *), hence non-zero.
- // Since size + alignment didn't wrap, 0 <= size + alignment - 1 < size + alignment
- size_t span = size + alignment - 1;
-
- if (alignment <= TINY_QUANTUM) {
- return szone_malloc(szone, size); // Trivially satisfied by tiny, small, or large
-
- } else if (span <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) {
- msize_t mspan = TINY_MSIZE_FOR_BYTES(span + TINY_QUANTUM - 1);
- void *p = szone_malloc(szone, span); // avoids inlining tiny_malloc_should_clear(szone, mspan, 0);
-
- if (NULL == p)
- return NULL;
-
- size_t offset = ((uintptr_t) p) & (alignment - 1); // p % alignment
- size_t pad = (0 == offset) ? 0 : alignment - offset; // p + pad achieves desired alignment
-
- msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
- msize_t mpad = TINY_MSIZE_FOR_BYTES(pad + TINY_QUANTUM - 1);
- msize_t mwaste = mspan - msize - mpad; // excess blocks
-
- if (mpad > 0) {
- void *q = (void *)(((uintptr_t) p) + pad);
-
- // Mark q as a block header and in-use, thus creating two blocks.
- magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines,
- REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)),
- MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)));
- set_tiny_meta_header_in_use(q, msize);
- tiny_mag_ptr->mag_num_objects++;
-
- // set_tiny_meta_header_in_use() "reaffirms" the block_header on the *following* block, so
- // now set its in_use bit as well. But only if its within the original allocation made above.
- if (mwaste > 0)
- BITARRAY_SET(TINY_INUSE_FOR_HEADER(TINY_BLOCK_HEADER_FOR_PTR(q)), TINY_INDEX_FOR_PTR(q) + msize);
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
-
- // Give up mpad blocks beginning at p to the tiny free list
- // region_t r = TINY_REGION_FOR_PTR(p);
- szone_free(szone, p); // avoids inlining free_tiny(szone, p, &r);
-
- p = q; // advance p to the desired alignment
- }
-
- if (mwaste > 0) {
- void *q = (void *)(((uintptr_t) p) + TINY_BYTES_FOR_MSIZE(msize));
- // Mark q as block header and in-use, thus creating two blocks.
- magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines,
- REGION_TRAILER_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)),
- MAGAZINE_INDEX_FOR_TINY_REGION(TINY_REGION_FOR_PTR(p)));
- set_tiny_meta_header_in_use(q, mwaste);
- tiny_mag_ptr->mag_num_objects++;
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
-
- // Give up mwaste blocks beginning at q to the tiny free list
- // region_t r = TINY_REGION_FOR_PTR(q);
- szone_free(szone, q); // avoids inlining free_tiny(szone, q, &r);
- }
-
- return p; // p has the desired size and alignment, and can later be free()'d
-
- } else if ((NUM_TINY_SLOTS - 1)*TINY_QUANTUM < size && alignment <= SMALL_QUANTUM) {
- return szone_malloc(szone, size); // Trivially satisfied by small or large
-
- } else if (span <= szone->large_threshold) {
-
- if (size <= (NUM_TINY_SLOTS - 1)*TINY_QUANTUM) {
- size = (NUM_TINY_SLOTS - 1)*TINY_QUANTUM + TINY_QUANTUM; // ensure block allocated by small does not have a tiny-possible size
- span = size + alignment - 1;
- }
-
- msize_t mspan = SMALL_MSIZE_FOR_BYTES(span + SMALL_QUANTUM - 1);
- void *p = szone_malloc(szone, span); // avoid inlining small_malloc_should_clear(szone, mspan, 0);
-
- if (NULL == p)
- return NULL;
-
- size_t offset = ((uintptr_t) p) & (alignment - 1); // p % alignment
- size_t pad = (0 == offset) ? 0 : alignment - offset; // p + pad achieves desired alignment
-
- msize_t msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1);
- msize_t mpad = SMALL_MSIZE_FOR_BYTES(pad + SMALL_QUANTUM - 1);
- msize_t mwaste = mspan - msize - mpad; // excess blocks
-
- if (mpad > 0) {
- void *q = (void *)(((uintptr_t) p) + pad);
-
- // Mark q as block header and in-use, thus creating two blocks.
- magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines,
- REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)),
- MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)));
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(p), SMALL_META_INDEX_FOR_PTR(p), mpad);
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), msize + mwaste);
- small_mag_ptr->mag_num_objects++;
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
-
- // Give up mpad blocks beginning at p to the small free list
- // region_t r = SMALL_REGION_FOR_PTR(p);
- szone_free(szone, p); // avoid inlining free_small(szone, p, &r);
-
- p = q; // advance p to the desired alignment
- }
- if (mwaste > 0) {
- void *q = (void *)(((uintptr_t) p) + SMALL_BYTES_FOR_MSIZE(msize));
- // Mark q as block header and in-use, thus creating two blocks.
- magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines,
- REGION_TRAILER_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)),
- MAGAZINE_INDEX_FOR_SMALL_REGION(SMALL_REGION_FOR_PTR(p)));
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(p), SMALL_META_INDEX_FOR_PTR(p), msize);
- small_meta_header_set_in_use(SMALL_META_HEADER_FOR_PTR(q), SMALL_META_INDEX_FOR_PTR(q), mwaste);
- small_mag_ptr->mag_num_objects++;
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
-
- // Give up mwaste blocks beginning at q to the small free list
- // region_t r = SMALL_REGION_FOR_PTR(q);
- szone_free(szone, q); // avoid inlining free_small(szone, q, &r);
- }
-
- return p; // p has the desired size and alignment, and can later be free()'d
-
- } else if (szone->large_threshold < size && alignment <= vm_page_size) {
- return szone_malloc(szone, size); // Trivially satisfied by large
-
- } else {
- // ensure block allocated by large does not have a small-possible size
- size_t num_pages = round_page(MAX(szone->large_threshold + 1, size)) >> vm_page_shift;
- void *p;
-
- if (num_pages == 0) /* Overflowed */
- p = NULL;
- else
- p = large_malloc(szone, num_pages, MAX(vm_page_shift, __builtin_ctz(alignment)), 0);
-
- return p;
- }
- /* NOTREACHED */
-}
-
-// given a size, returns the number of pointers allocated capable of holding
-// that size, up to the limit specified by the 'count' argument. These pointers
-// are stored in the 'results' array, which must be allocated by the caller.
-// may return zero, since this function is only a best attempt at allocating
-// the pointers. clients should be prepared to call malloc for any additional
-// blocks they need.
-static NOINLINE unsigned
-szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count)
-{
- msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
- unsigned found = 0;
- mag_index_t mag_index = mag_get_thread_index(szone);
- magazine_t *tiny_mag_ptr = &(szone->tiny_magazines[mag_index]);
-
- // only bother implementing this for tiny
- if (size > (NUM_TINY_SLOTS - 1)*TINY_QUANTUM)
- return 0;
- // make sure to return objects at least one quantum in size
- if (!msize)
- msize = 1;
-
- CHECK(szone, __PRETTY_FUNCTION__);
-
- // We must lock the zone now, since tiny_malloc_from_free_list assumes that
- // the caller has done so.
- SZONE_MAGAZINE_PTR_LOCK(szone, tiny_mag_ptr);
-
- // with the zone locked, allocate objects from the free list until all
- // sufficiently large objects have been exhausted, or we have met our quota
- // of objects to allocate.
- while (found < count) {
- void *ptr = tiny_malloc_from_free_list(szone, tiny_mag_ptr, mag_index, msize);
- if (!ptr)
- break;
-
- *results++ = ptr;
- found++;
- }
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- return found;
-}
-
-/* Try caching the tiny_region and checking if the next ptr hits there. */
-static NOINLINE void
-szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count)
-{
- unsigned cc = 0;
- void *ptr;
- region_t tiny_region = NULL;
- boolean_t is_free;
- msize_t msize;
- magazine_t *tiny_mag_ptr = NULL;
- mag_index_t mag_index = -1;
-
- // frees all the pointers in to_be_freed
- // note that to_be_freed may be overwritten during the process
- if (!count)
- return;
-
- CHECK(szone, __PRETTY_FUNCTION__);
- while (cc < count) {
- ptr = to_be_freed[cc];
- if (ptr) {
- if (NULL == tiny_region || tiny_region != TINY_REGION_FOR_PTR(ptr)) { // region same as last iteration?
- if (tiny_mag_ptr) { // non-NULL iff magazine lock taken
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- tiny_mag_ptr = NULL;
- }
-
- tiny_region = tiny_region_for_ptr_no_lock(szone, ptr);
-
- if (tiny_region) {
- tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines,
- REGION_TRAILER_FOR_TINY_REGION(tiny_region),
- MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region));
- mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(tiny_region);
- }
- }
- if (tiny_region) {
- // this is a tiny pointer
- if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS)
- break; // pointer to metadata; let the standard free deal with it
- msize = get_tiny_meta_header(ptr, &is_free);
- if (is_free)
- break; // a double free; let the standard free deal with it
-
- if (!tiny_free_no_lock(szone, tiny_mag_ptr, mag_index, tiny_region, ptr, msize)) {
- // Arrange to re-acquire magazine lock
- tiny_mag_ptr = NULL;
- tiny_region = NULL;
- }
- to_be_freed[cc] = NULL;
- } else {
- // No region in this zone claims ptr; let the standard free deal with it
- break;
- }
- }
- cc++;
- }
-
- if (tiny_mag_ptr) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- tiny_mag_ptr = NULL;
- }
-
- CHECK(szone, __PRETTY_FUNCTION__);
- while (count--) {
- ptr = to_be_freed[count];
- if (ptr)
- szone_free(szone, ptr);
- }
-}
-
-// FIXME: Suppose one of the locks is held?
-static void
-szone_destroy(szone_t *szone)
-{
- size_t index;
- large_entry_t *large;
- vm_range_t range_to_deallocate;
-
-#if LARGE_CACHE
- SZONE_LOCK(szone);
-
- /* disable any memory pressure responder */
- szone->flotsam_enabled = FALSE;
-
- // stack allocated copy of the death-row cache
- int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest;
- large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE];
-
- memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache));
-
- szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0;
- szone->large_entry_cache[0].address = 0x0;
- szone->large_entry_cache[0].size = 0;
- szone->large_entry_cache_bytes = 0;
- szone->large_entry_cache_reserve_bytes = 0;
-
- SZONE_UNLOCK(szone);
-
- // deallocate the death-row cache outside the zone lock
- while (idx != idx_max) {
- deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0);
- if (++idx == LARGE_ENTRY_CACHE_SIZE) idx = 0;
- }
- if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) {
- deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0);
- }
-#endif
-
- /* destroy large entries */
- index = szone->num_large_entries;
- while (index--) {
- large = szone->large_entries + index;
- if (large->address) {
- // we deallocate_pages, including guard pages
- deallocate_pages(szone, (void *)(large->address), large->size, szone->debug_flags);
- }
- }
- large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate);
- if (range_to_deallocate.size)
- deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0);
-
- /* destroy tiny regions */
- for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index)
- if ((HASHRING_OPEN_ENTRY != szone->tiny_region_generation->hashed_regions[index]) &&
- (HASHRING_REGION_DEALLOCATED != szone->tiny_region_generation->hashed_regions[index]))
- deallocate_pages(szone, szone->tiny_region_generation->hashed_regions[index], TINY_REGION_SIZE, 0);
-
- /* destroy small regions */
- for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index)
- if ((HASHRING_OPEN_ENTRY != szone->small_region_generation->hashed_regions[index]) &&
- (HASHRING_REGION_DEALLOCATED != szone->small_region_generation->hashed_regions[index]))
- deallocate_pages(szone, szone->small_region_generation->hashed_regions[index], SMALL_REGION_SIZE, 0);
-
- /* destroy region hash rings, if any */
- if (szone->tiny_region_generation->hashed_regions != szone->initial_tiny_regions) {
- size_t size = round_page(szone->tiny_region_generation->num_regions_allocated * sizeof(region_t));
- deallocate_pages(szone, szone->tiny_region_generation->hashed_regions, size, 0);
- }
- if (szone->small_region_generation->hashed_regions != szone->initial_small_regions) {
- size_t size = round_page(szone->small_region_generation->num_regions_allocated * sizeof(region_t));
- deallocate_pages(szone, szone->small_region_generation->hashed_regions, size, 0);
- }
-
- /* Now destroy the separate szone region */
- if (szone->cpu_id_key != (pthread_key_t) -1)
- (void)pthread_key_delete(szone->cpu_id_key);
- deallocate_pages(szone, (void *)&(szone->tiny_magazines[-1]), TINY_MAGAZINE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES);
- deallocate_pages(szone, (void *)&(szone->small_magazines[-1]), SMALL_MAGAZINE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES);
- deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0);
-}
-
-static NOINLINE size_t
-szone_good_size(szone_t *szone, size_t size)
-{
- msize_t msize;
-
- // Find a good size for this tiny allocation.
- if (size <= (NUM_TINY_SLOTS - 1) * TINY_QUANTUM) {
- msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
- if (!msize)
- msize = 1;
- return TINY_BYTES_FOR_MSIZE(msize);
- }
-
- // Find a good size for this small allocation.
- if (size <= szone->large_threshold) {
- msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1);
- if (!msize)
- msize = 1;
- return SMALL_BYTES_FOR_MSIZE(msize);
- }
-
- // Check for integer overflow on the size, since unlike the two cases above,
- // there is no upper bound on allocation size at this point.
- if (size > round_page(size))
- return (size_t)(-1LL);
-
-#if DEBUG_MALLOC
- // It is not acceptable to see a size of zero here, since that means we
- // failed to catch a request for zero bytes in the tiny check, or the size
- // overflowed to zero during some arithmetic.
- if (size == 0)
- malloc_printf("szone_good_size() invariant broken %y\n", size);
-#endif
- return round_page(size);
-}
-
-unsigned szone_check_counter = 0;
-unsigned szone_check_start = 0;
-unsigned szone_check_modulo = 1;
-
-static NOINLINE boolean_t
-szone_check_all(szone_t *szone, const char *function)
-{
- size_t index;
-
- /* check tiny regions - chould check region count */
- for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) {
- region_t tiny = szone->tiny_region_generation->hashed_regions[index];
-
- if (HASHRING_REGION_DEALLOCATED == tiny)
- continue;
-
- if (tiny) {
- magazine_t *tiny_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->tiny_magazines,
- REGION_TRAILER_FOR_TINY_REGION(tiny), MAGAZINE_INDEX_FOR_TINY_REGION(tiny));
-
- if (!tiny_check_region(szone, tiny)) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- szone->debug_flags &= ~ CHECK_REGIONS;
- szone_error(szone, 1, "check: tiny region incorrect", NULL,
- "*** tiny region %ld incorrect szone_check_all(%s) counter=%d\n",
- index, function, szone_check_counter);
- return 0;
- }
- SZONE_MAGAZINE_PTR_UNLOCK(szone, tiny_mag_ptr);
- }
- }
- /* check tiny free lists */
- for (index = 0; index < NUM_TINY_SLOTS; ++index) {
- if (!tiny_free_list_check(szone, index)) {
- szone->debug_flags &= ~ CHECK_REGIONS;
- szone_error(szone, 1, "check: tiny free list incorrect", NULL,
- "*** tiny free list incorrect (slot=%ld) szone_check_all(%s) counter=%d\n",
- index, function, szone_check_counter);
- return 0;
- }
- }
-
- /* check small regions - could check region count */
- for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) {
- region_t small = szone->small_region_generation->hashed_regions[index];
-
- if (HASHRING_REGION_DEALLOCATED == small)
- continue;
-
- if (small) {
- magazine_t *small_mag_ptr = mag_lock_zine_for_region_trailer(szone, szone->small_magazines,
- REGION_TRAILER_FOR_SMALL_REGION(small), MAGAZINE_INDEX_FOR_SMALL_REGION(small));
-
- if (!small_check_region(szone, small)) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- szone->debug_flags &= ~ CHECK_REGIONS;
- szone_error(szone, 1, "check: small region incorrect", NULL,
- "*** small region %ld incorrect szone_check_all(%s) counter=%d\n",
- index, function, szone_check_counter);
- return 0;
- }
- SZONE_MAGAZINE_PTR_UNLOCK(szone, small_mag_ptr);
- }
- }
- /* check small free lists */
- for (index = 0; index < szone->num_small_slots; ++index) {
- if (!small_free_list_check(szone, index)) {
- szone->debug_flags &= ~ CHECK_REGIONS;
- szone_error(szone, 1, "check: small free list incorrect", NULL,
- "*** small free list incorrect (slot=%ld) szone_check_all(%s) counter=%d\n",
- index, function, szone_check_counter);
- return 0;
- }
- }
-
- return 1;
-}
-
-static boolean_t
-szone_check(szone_t *szone)
-{
- if ((++szone_check_counter % 10000) == 0)
- _malloc_printf(ASL_LEVEL_NOTICE, "at szone_check counter=%d\n", szone_check_counter);
-
- if (szone_check_counter < szone_check_start)
- return 1;
-
- if (szone_check_counter % szone_check_modulo)
- return 1;
-
- return szone_check_all(szone, "");
-}
-
-static kern_return_t
-szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address,
- memory_reader_t reader, vm_range_recorder_t recorder)
-{
- szone_t *szone;
- kern_return_t err;
-
- if (!reader) reader = _szone_default_reader;
-
- err = reader(task, zone_address, sizeof(szone_t), (void **)&szone);
- if (err) return err;
-
- err = tiny_in_use_enumerator(task, context, type_mask, szone, reader, recorder);
- if (err) return err;
-
- err = small_in_use_enumerator(task, context, type_mask, szone, reader, recorder);
- if (err) return err;
-
- err = large_in_use_enumerator(task, context, type_mask,
- (vm_address_t)szone->large_entries, szone->num_large_entries, reader, recorder);
- return err;
-}
-
-// Following method is deprecated: use scalable_zone_statistics instead
-void
-scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count)
-{
- szone_t *szone = (void *)zone;
- unsigned info[13];
-
- // We do not lock to facilitate debug
-
- size_t s = 0;
- unsigned t = 0;
- size_t u = 0;
- mag_index_t mag_index;
-
- for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) {
- s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start;
- s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end;
- t += szone->tiny_magazines[mag_index].mag_num_objects;
- u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects;
- }
-
- info[4] = t;
- info[5] = u;
-
- for (t = 0, u = 0, mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) {
- s += szone->small_magazines[mag_index].mag_bytes_free_at_start;
- s += szone->small_magazines[mag_index].mag_bytes_free_at_end;
- t += szone->small_magazines[mag_index].mag_num_objects;
- u += szone->small_magazines[mag_index].mag_num_bytes_in_objects;
- }
-
- info[6] = t;
- info[7] = u;
-
- info[8] = szone->num_large_objects_in_use;
- info[9] = szone->num_bytes_in_large_objects;
-
- info[10] = 0; // DEPRECATED szone->num_huge_entries;
- info[11] = 0; // DEPRECATED szone->num_bytes_in_huge_objects;
-
- info[12] = szone->debug_flags;
-
- info[0] = info[4] + info[6] + info[8] + info[10];
- info[1] = info[5] + info[7] + info[9] + info[11];
-
- info[3] = (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE +
- (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE + info[9] + info[11];
-
- info[2] = info[3] - s;
- memcpy(info_to_fill, info, sizeof(unsigned)*count);
-}
-
-// FIXME: consistent picture requires locking!
-static NOINLINE void
-szone_print(szone_t *szone, boolean_t verbose)
-{
- unsigned info[13];
- size_t index;
- region_t region;
-
- scalable_zone_info((void *)szone, info, 13);
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "Scalable zone %p: inUse=%u(%y) touched=%y allocated=%y flags=%d\n",
- szone, info[0], info[1], info[2], info[3], info[12]);
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "\ttiny=%u(%y) small=%u(%y) large=%u(%y) huge=%u(%y)\n",
- info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11]);
- // tiny
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "%lu tiny regions:\n", szone->num_tiny_regions);
- if (szone->num_tiny_regions_dealloc)
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "[%lu tiny regions have been vm_deallocate'd]\n", szone->num_tiny_regions_dealloc);
- for (index = 0; index < szone->tiny_region_generation->num_regions_allocated; ++index) {
- region = szone->tiny_region_generation->hashed_regions[index];
- if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) {
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_TINY_REGION(region);
- print_tiny_region(verbose, region,
- (region == szone->tiny_magazines[mag_index].mag_last_region) ?
- szone->tiny_magazines[mag_index].mag_bytes_free_at_start : 0,
- (region == szone->tiny_magazines[mag_index].mag_last_region) ?
- szone->tiny_magazines[mag_index].mag_bytes_free_at_end : 0);
- }
- }
- if (verbose)
- print_tiny_free_list(szone);
- // small
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "%lu small regions:\n", szone->num_small_regions);
- if (szone->num_small_regions_dealloc)
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "[%lu small regions have been vm_deallocate'd]\n", szone->num_small_regions_dealloc);
- for (index = 0; index < szone->small_region_generation->num_regions_allocated; ++index) {
- region = szone->small_region_generation->hashed_regions[index];
- if (HASHRING_OPEN_ENTRY != region && HASHRING_REGION_DEALLOCATED != region) {
- mag_index_t mag_index = MAGAZINE_INDEX_FOR_SMALL_REGION(region);
- print_small_region(szone, verbose, region,
- (region == szone->small_magazines[mag_index].mag_last_region) ?
- szone->small_magazines[mag_index].mag_bytes_free_at_start : 0,
- (region == szone->small_magazines[mag_index].mag_last_region) ?
- szone->small_magazines[mag_index].mag_bytes_free_at_end : 0);
- }
- }
- if (verbose)
- print_small_free_list(szone);
-}
-
-static void
-szone_log(malloc_zone_t *zone, void *log_address)
-{
- szone_t *szone = (szone_t *)zone;
-
- szone->log_address = log_address;
-}
-
-static void
-szone_force_lock(szone_t *szone)
-{
- mag_index_t i;
-
- for (i = 0; i < szone->num_tiny_magazines; ++i) {
- SZONE_MAGAZINE_PTR_LOCK(szone, (&(szone->tiny_magazines[i])));
- }
- SZONE_MAGAZINE_PTR_LOCK(szone, (&(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX])));
-
- for (i = 0; i < szone->num_small_magazines; ++i) {
- SZONE_MAGAZINE_PTR_LOCK(szone, (&(szone->small_magazines[i])));
- }
- SZONE_MAGAZINE_PTR_LOCK(szone, (&(szone->small_magazines[DEPOT_MAGAZINE_INDEX])));
-
- SZONE_LOCK(szone);
-}
-
-static void
-szone_force_unlock(szone_t *szone)
-{
- mag_index_t i;
-
- SZONE_UNLOCK(szone);
-
- for (i = -1; i < szone->num_small_magazines; ++i) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->small_magazines[i])));
- }
-
- for (i = -1; i < szone->num_tiny_magazines; ++i) {
- SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->tiny_magazines[i])));
- }
-}
-
-static boolean_t
-szone_locked(szone_t *szone)
-{
- mag_index_t i;
- int tookLock;
-
- tookLock = SZONE_TRY_LOCK(szone);
- if (tookLock == 0)
- return 1;
- SZONE_UNLOCK(szone);
-
- for (i = -1; i < szone->num_small_magazines; ++i) {
- tookLock = SZONE_MAGAZINE_PTR_TRY_LOCK(szone, (&(szone->small_magazines[i])));
- if (tookLock == 0)
- return 1;
- SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->small_magazines[i])));
- }
-
- for (i = -1; i < szone->num_tiny_magazines; ++i) {
- tookLock = SZONE_MAGAZINE_PTR_TRY_LOCK(szone, (&(szone->tiny_magazines[i])));
- if (tookLock == 0)
- return 1;
- SZONE_MAGAZINE_PTR_UNLOCK(szone, (&(szone->tiny_magazines[i])));
- }
- return 0;
-}
-
-static size_t
-szone_pressure_relief(szone_t *szone, size_t goal)
-{
-#if LARGE_CACHE
- if (!szone->flotsam_enabled)
- return 0;
-
- SZONE_LOCK(szone);
-
- // stack allocated copy of the death-row cache
- int idx = szone->large_entry_cache_oldest, idx_max = szone->large_entry_cache_newest;
- large_entry_t local_entry_cache[LARGE_ENTRY_CACHE_SIZE];
-
- memcpy((void *)local_entry_cache, (void *)szone->large_entry_cache, sizeof(local_entry_cache));
-
- szone->large_entry_cache_oldest = szone->large_entry_cache_newest = 0;
- szone->large_entry_cache[0].address = 0x0;
- szone->large_entry_cache[0].size = 0;
- szone->large_entry_cache_bytes = 0;
- szone->large_entry_cache_reserve_bytes = 0;
-
- szone->flotsam_enabled = FALSE;
-
- SZONE_UNLOCK(szone);
-
- // deallocate the death-row cache outside the zone lock
- size_t total = 0;
- while (idx != idx_max) {
- deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0);
- total += local_entry_cache[idx].size;
- if (++idx == LARGE_ENTRY_CACHE_SIZE) idx = 0;
- }
- if (0 != local_entry_cache[idx].address && 0 != local_entry_cache[idx].size) {
- deallocate_pages(szone, (void *) local_entry_cache[idx].address, local_entry_cache[idx].size, 0);
- total += local_entry_cache[idx].size;
- }
- MAGMALLOC_PRESSURERELIEF((void *)szone, goal, total); // DTrace USDT Probe
- return total;
-#else
- return 0;
-#endif
-}
-
-boolean_t
-scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone)
-{
- szone_t *szone = (szone_t *)zone;
-
- switch (subzone) {
- case 0:
- {
- size_t s = 0;
- unsigned t = 0;
- size_t u = 0;
- mag_index_t mag_index;
-
- for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) {
- s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start;
- s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end;
- t += szone->tiny_magazines[mag_index].mag_num_objects;
- u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects;
- }
-
- stats->blocks_in_use = t;
- stats->size_in_use = u;
- stats->size_allocated = (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE;
- stats->max_size_in_use = stats->size_allocated - s;
- return 1;
- }
- case 1:
- {
- size_t s = 0;
- unsigned t = 0;
- size_t u = 0;
- mag_index_t mag_index;
-
- for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) {
- s += szone->small_magazines[mag_index].mag_bytes_free_at_start;
- s += szone->small_magazines[mag_index].mag_bytes_free_at_end;
- t += szone->small_magazines[mag_index].mag_num_objects;
- u += szone->small_magazines[mag_index].mag_num_bytes_in_objects;
- }
-
- stats->blocks_in_use = t;
- stats->size_in_use = u;
- stats->size_allocated = (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE;
- stats->max_size_in_use = stats->size_allocated - s;
- return 1;
- }
- case 2:
- stats->blocks_in_use = szone->num_large_objects_in_use;
- stats->size_in_use = szone->num_bytes_in_large_objects;
- stats->max_size_in_use = stats->size_allocated = stats->size_in_use;
- return 1;
- case 3:
- stats->blocks_in_use = 0; // DEPRECATED szone->num_huge_entries;
- stats->size_in_use = 0; // DEPRECATED szone->num_bytes_in_huge_objects;
- stats->max_size_in_use = stats->size_allocated = 0;
- return 1;
- }
- return 0;
-}
-
-static void
-szone_statistics(szone_t *szone, malloc_statistics_t *stats)
-{
- size_t large;
-
- size_t s = 0;
- unsigned t = 0;
- size_t u = 0;
- mag_index_t mag_index;
-
- for (mag_index = -1; mag_index < szone->num_tiny_magazines; mag_index++) {
- s += szone->tiny_magazines[mag_index].mag_bytes_free_at_start;
- s += szone->tiny_magazines[mag_index].mag_bytes_free_at_end;
- t += szone->tiny_magazines[mag_index].mag_num_objects;
- u += szone->tiny_magazines[mag_index].mag_num_bytes_in_objects;
- }
-
- for (mag_index = -1; mag_index < szone->num_small_magazines; mag_index++) {
- s += szone->small_magazines[mag_index].mag_bytes_free_at_start;
- s += szone->small_magazines[mag_index].mag_bytes_free_at_end;
- t += szone->small_magazines[mag_index].mag_num_objects;
- u += szone->small_magazines[mag_index].mag_num_bytes_in_objects;
- }
-
- large = szone->num_bytes_in_large_objects + 0; // DEPRECATED szone->num_bytes_in_huge_objects;
-
- stats->blocks_in_use = t + szone->num_large_objects_in_use + 0; // DEPRECATED szone->num_huge_entries;
- stats->size_in_use = u + large;
- stats->max_size_in_use = stats->size_allocated =
- (szone->num_tiny_regions - szone->num_tiny_regions_dealloc) * TINY_REGION_SIZE +
- (szone->num_small_regions - szone->num_small_regions_dealloc) * SMALL_REGION_SIZE + large;
- // Now we account for the untouched areas
- stats->max_size_in_use -= s;
-}
-
-static void *
-legacy_zeroing_large_malloc(szone_t *szone, size_t size) {
- if (size > LARGE_THRESHOLD) // Leopard and earlier returned a ZFOD range, so ...
- return szone_calloc(szone, 1, size); // Clear to zero always, ham-handedly touching in each page
- else
- return szone_malloc(szone, size);
-}
-
-static void *
-legacy_zeroing_large_valloc(szone_t *szone, size_t size) {
- void *p = szone_valloc(szone, size);
-
- // Leopard and earlier returned a ZFOD range, so ...
- memset(p, 0, size); // Clear to zero always, ham-handedly touching in each page
- return p;
-}
-
-void zeroify_scalable_zone(malloc_zone_t *zone)
-{
- szone_t *szone = (szone_t *)zone;
-
- if (szone) {
- mprotect(szone, sizeof(szone->basic_zone), PROT_READ | PROT_WRITE);
- szone->basic_zone.malloc = (void *)legacy_zeroing_large_malloc;
- szone->basic_zone.valloc = (void *)legacy_zeroing_large_valloc;
- mprotect(szone, sizeof(szone->basic_zone), PROT_READ);
- }
-}
-
-static const struct malloc_introspection_t szone_introspect = {
- (void *)szone_ptr_in_use_enumerator,
- (void *)szone_good_size,
- (void *)szone_check,
- (void *)szone_print,
- szone_log,
- (void *)szone_force_lock,
- (void *)szone_force_unlock,
- (void *)szone_statistics,
- (void *)szone_locked,
- NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */
-}; // marked as const to spare the DATA section
-
-malloc_zone_t *
-create_scalable_zone(size_t initial_size, unsigned debug_flags)
-{
- szone_t *szone;
- uint64_t hw_memsize = 0;
-
- /*
- * Sanity-check our build-time assumptions about the size of a page.
- * Since we have sized various things assuming the default page size,
- * attempting to determine it dynamically is not useful.
- */
- if ((vm_page_size != _vm_page_size) || (vm_page_shift != _vm_page_shift)) {
- malloc_printf("*** FATAL ERROR - machine page size does not match our assumptions.\n");
- exit(-1);
- }
-
-#if defined(__i386__) || defined(__x86_64__)
- if (_COMM_PAGE_VERSION_REQD > (*((short *) _COMM_PAGE_VERSION))) { // _COMM_PAGE_CPU_NUMBER must be present at runtime
- malloc_printf("*** ERROR - comm page version mismatch.\n");
- exit(-1);
- }
-#endif
-
- /* get memory for the zone. */
- szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC);
- if (!szone)
- return NULL;
-
- /* set up the szone structure */
-#if 0
-#warning CHECK_REGIONS enabled
- debug_flags |= CHECK_REGIONS;
-#endif
-#if 0
-#warning LOG enabled
- szone->log_address = ~0;
-#endif
- szone->trg[0].nextgen = &(szone->trg[1]);
- szone->trg[1].nextgen = &(szone->trg[0]);
- szone->tiny_region_generation = &(szone->trg[0]);
-
- szone->tiny_region_generation->hashed_regions = szone->initial_tiny_regions;
- szone->tiny_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS;
- szone->tiny_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT;
-
- szone->srg[0].nextgen = &(szone->srg[1]);
- szone->srg[1].nextgen = &(szone->srg[0]);
- szone->small_region_generation = &(szone->srg[0]);
-
- szone->small_region_generation->hashed_regions = szone->initial_small_regions;
- szone->small_region_generation->num_regions_allocated = INITIAL_NUM_REGIONS;
- szone->small_region_generation->num_regions_allocated_shift = INITIAL_NUM_REGIONS_SHIFT;
-
-
- /*
- * Initialize variables that size the free list for SMALL allocations based
- * upon the amount of memory in the system. Switch to a larger number of
- * free list entries at 1GB.
- */
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- if ((hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE) >= (1ULL << 30))
-#else
- size_t uint64_t_size = sizeof(hw_memsize);
-
- if (0 == sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0) &&
- hw_memsize >= (1ULL << 30))
-#endif
- {
- szone->is_largemem = 1;
- szone->num_small_slots = NUM_SMALL_SLOTS_LARGEMEM;
- szone->large_threshold = LARGE_THRESHOLD_LARGEMEM;
- szone->vm_copy_threshold = VM_COPY_THRESHOLD_LARGEMEM;
- } else {
- szone->is_largemem = 0;
- szone->num_small_slots = NUM_SMALL_SLOTS;
- szone->large_threshold = LARGE_THRESHOLD;
- szone->vm_copy_threshold = VM_COPY_THRESHOLD;
- }
-#if LARGE_CACHE
- szone->large_entry_cache_reserve_limit =
- hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%]
-
- /* <rdar://problem/6610904> Reset protection when returning a previous large allocation? */
- int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System");
- if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 112) /* CFSystemVersionSnowLeopard */)
- szone->large_legacy_reset_mprotect = TRUE;
- else
- szone->large_legacy_reset_mprotect = FALSE;
-#endif
-
- // Initialize the security token.
- szone->cookie = (uintptr_t)malloc_entropy[0];
-
- // Prepare ASLR
-#if __i386__ || __LP64__ || TARGET_OS_EMBEDDED
-#if __i386__
- uintptr_t stackbase = 0x8fe00000;
- int entropic_bits = 3;
-#elif __LP64__
- uintptr_t stackbase = USRSTACK64;
- int entropic_bits = 16;
-#else
- uintptr_t stackbase = USRSTACK;
- int entropic_bits = 3;
-#endif
- if (0 != _dyld_get_image_slide((const struct mach_header*)_NSGetMachExecuteHeader())) {
- if (0 == entropic_address) {
- uintptr_t t = stackbase - MAXSSIZ - ((uintptr_t) (malloc_entropy[1] & ((1 << entropic_bits) - 1)) << SMALL_BLOCKS_ALIGN);
- (void)__sync_bool_compare_and_swap(&entropic_limit, 0, t); // Just one initialization please
- (void)__sync_bool_compare_and_swap(&entropic_address, 0, t - ENTROPIC_KABILLION); // Just one initialization please
- }
- debug_flags &= ~DISABLE_ASLR;
- } else {
- debug_flags |= DISABLE_ASLR;
- }
-
-#else
- debug_flags |= DISABLE_ASLR;
-#endif
-
- szone->basic_zone.version = 8;
- szone->basic_zone.size = (void *)szone_size;
- szone->basic_zone.malloc = (void *)szone_malloc;
- szone->basic_zone.calloc = (void *)szone_calloc;
- szone->basic_zone.valloc = (void *)szone_valloc;
- szone->basic_zone.free = (void *)szone_free;
- szone->basic_zone.realloc = (void *)szone_realloc;
- szone->basic_zone.destroy = (void *)szone_destroy;
- szone->basic_zone.batch_malloc = (void *)szone_batch_malloc;
- szone->basic_zone.batch_free = (void *)szone_batch_free;
- szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect;
- szone->basic_zone.memalign = (void *)szone_memalign;
- szone->basic_zone.free_definite_size = (void *)szone_free_definite_size;
- szone->basic_zone.pressure_relief = (void *)szone_pressure_relief;
-
- szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */
- szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */
- mprotect(szone, sizeof(szone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */
-
- szone->debug_flags = debug_flags;
- LOCK_INIT(szone->large_szone_lock);
-
-#if defined(__ppc__) || defined(__ppc64__)
- /*
- * In the interest of compatibility for PPC applications executing via Rosetta,
- * arrange to zero-fill allocations as occurred by side effect in Leopard and earlier.
- */
- zeroify_scalable_zone((malloc_zone_t *)szone);
-#endif
-
-#if defined(__i386__) || defined(__x86_64__)
- szone->cpu_id_key = (pthread_key_t) -1; // Unused. _COMM_PAGE_CPU_NUMBER preferred.
-#else
- int err;
- if ((err = pthread_key_create(&(szone->cpu_id_key), NULL))) {
- malloc_printf("*** ERROR -pthread_key_create failure err=%d.\n", err);
- szone->cpu_id_key = (pthread_key_t) -1;
- }
-#endif
-
- // Query the number of configured processors.
- // Uniprocessor case gets just one tiny and one small magazine (whose index is zero). This gives
- // the same behavior as the original scalable malloc. MP gets per-CPU magazines
- // that scale (way) better.
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- int nproc = *(uint8_t *)(uintptr_t)_COMM_PAGE_NCPUS;
-#else
- int nproc = sysconf(_SC_NPROCESSORS_CONF);
-#endif
- szone->num_tiny_magazines = (nproc > 1) ? MIN(nproc, TINY_MAX_MAGAZINES) : 1;
-
- // FIXME vm_allocate() based on number of configured CPUs
- magazine_t *tiny_magazines = allocate_pages(NULL, TINY_MAGAZINE_PAGED_SIZE, 0,
- SCALABLE_MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC);
- if (NULL == tiny_magazines)
- return NULL;
-
- szone->tiny_magazines = &(tiny_magazines[1]); // szone->tiny_magazines[-1] is the Depot
-
- // The magazines are indexed in [0 .. (num_tiny_magazines - 1)]
- // Find the smallest power of 2 that exceeds (num_tiny_magazines - 1)
- szone->num_tiny_magazines_mask_shift = 0;
- int i = 1;
- while( i <= (szone->num_tiny_magazines - 1) ) {
- szone->num_tiny_magazines_mask_shift++;
- i <<= 1;
- }
-
- // Now if i <= TINY_MAX_MAGAZINES we'll never access tiny_magazines[] out of bounds.
- if (i > TINY_MAX_MAGAZINES) {
- malloc_printf("*** FATAL ERROR - magazine mask exceeds allocated magazines.\n");
- exit(-1);
- }
-
- // Reduce i by 1 to obtain a mask covering [0 .. (num_tiny_magazines - 1)]
- szone->num_tiny_magazines_mask = i - 1; // A mask used for hashing to a magazine index (and a safety aid)
-#if TARGET_OS_EMBEDDED
- szone->last_tiny_advise = 0;
-#endif
-
- // Init the tiny_magazine locks
- LOCK_INIT(szone->tiny_regions_lock);
- LOCK_INIT(szone->tiny_magazines[DEPOT_MAGAZINE_INDEX].magazine_lock);
- for (i = 0; i < szone->num_tiny_magazines; ++i) {
- LOCK_INIT(szone->tiny_magazines[i].magazine_lock);
- }
-
- szone->num_small_magazines = (nproc > 1) ? MIN(nproc, SMALL_MAX_MAGAZINES) : 1;
-
- // FIXME vm_allocate() based on number of configured CPUs
- magazine_t *small_magazines = allocate_pages(NULL, SMALL_MAGAZINE_PAGED_SIZE, 0,
- SCALABLE_MALLOC_ADD_GUARD_PAGES, VM_MEMORY_MALLOC);
- if (NULL == small_magazines)
- return NULL;
-
- szone->small_magazines = &(small_magazines[1]); // szone->small_magazines[-1] is the Depot
-
- // The magazines are indexed in [0 .. (num_small_magazines - 1)]
- // Find the smallest power of 2 that exceeds (num_small_magazines - 1)
- szone->num_small_magazines_mask_shift = 0;
- while( i <= (szone->num_small_magazines - 1) ) {
- szone->num_small_magazines_mask_shift++;
- i <<= 1;
- }
-
- // Now if i <= SMALL_MAX_MAGAZINES we'll never access small_magazines[] out of bounds.
- if (i > SMALL_MAX_MAGAZINES) {
- malloc_printf("*** FATAL ERROR - magazine mask exceeds allocated magazines.\n");
- exit(-1);
- }
-
- // Reduce i by 1 to obtain a mask covering [0 .. (num_small_magazines - 1)]
- szone->num_small_magazines_mask = i - 1; // A mask used for hashing to a magazine index (and a safety aid)
-#if TARGET_OS_EMBEDDED
- szone->last_small_advise = 0;
-#endif
-
- // Init the small_magazine locks
- LOCK_INIT(szone->small_regions_lock);
- LOCK_INIT(szone->small_magazines[DEPOT_MAGAZINE_INDEX].magazine_lock);
- for (i = 0; i < szone->num_small_magazines; ++i) {
- LOCK_INIT(szone->small_magazines[i].magazine_lock);
- }
-
- CHECK(szone, __PRETTY_FUNCTION__);
- return (malloc_zone_t *)szone;
-}
-
-//
-// purgeable zones have their own "large" allocation pool, but share "tiny" and "large"
-// heaps with a helper_zone identified in the call to create_purgeable_zone()
-//
-static size_t
-purgeable_size(szone_t *szone, const void *ptr)
-{
- // Only claim our large allocations, leave the shared tiny/small for the helper zone to claim.
- return szone_size_try_large(szone, ptr);
-}
-
-static void *
-purgeable_malloc(szone_t *szone, size_t size) {
- if (size <= szone->large_threshold)
- return szone_malloc(szone->helper_zone, size);
- else
- return szone_malloc(szone, size);
-}
-
-static void *
-purgeable_calloc(szone_t *szone, size_t num_items, size_t size)
-{
- size_t total_bytes = num_items * size;
-
- // Check for overflow of integer multiplication
- if (num_items > 1) {
-#if __LP64__ /* size_t is uint64_t */
- if ((num_items | size) & 0xffffffff00000000ul) {
- // num_items or size equals or exceeds sqrt(2^64) == 2^32, appeal to wider arithmetic
- __uint128_t product = ((__uint128_t)num_items) * ((__uint128_t)size);
- if ((uint64_t)(product >> 64)) // compiles to test on upper register of register pair
- return NULL;
- }
-#else /* size_t is uint32_t */
- if ((num_items | size) & 0xffff0000ul) {
- // num_items or size equals or exceeds sqrt(2^32) == 2^16, appeal to wider arithmetic
- uint64_t product = ((uint64_t)num_items) * ((uint64_t)size);
- if ((uint32_t)(product >> 32)) // compiles to test on upper register of register pair
- return NULL;
- }
-#endif
- }
-
- if (total_bytes <= szone->large_threshold)
- return szone_calloc(szone->helper_zone, 1, total_bytes);
- else
- return szone_calloc(szone, 1, total_bytes);
-}
-
-static void *
-purgeable_valloc(szone_t *szone, size_t size)
-{
- if (size <= szone->large_threshold)
- return szone_valloc(szone->helper_zone, size);
- else
- return szone_valloc(szone, size);
-}
-
-static void
-purgeable_free(szone_t *szone, void *ptr)
-{
- large_entry_t *entry;
-
- SZONE_LOCK(szone);
- entry = large_entry_for_pointer_no_lock(szone, ptr);
- SZONE_UNLOCK(szone);
- if (entry) {
- return free_large(szone, ptr);
- } else {
- return szone_free(szone->helper_zone, ptr);
- }
-}
-
-static void
-purgeable_free_definite_size(szone_t *szone, void *ptr, size_t size)
-{
- if (size <= szone->large_threshold)
- return szone_free_definite_size(szone->helper_zone, ptr, size);
- else
- return szone_free_definite_size(szone, ptr, size);
-}
-
-static void *
-purgeable_realloc(szone_t *szone, void *ptr, size_t new_size)
-{
- size_t old_size;
-
- if (NULL == ptr) {
- // If ptr is a null pointer, realloc() shall be equivalent to malloc() for the specified size.
- return purgeable_malloc(szone, new_size);
- } else if (0 == new_size) {
- // If size is 0 and ptr is not a null pointer, the object pointed to is freed.
- purgeable_free(szone, ptr);
- // If size is 0, either a null pointer or a unique pointer that can be successfully passed
- // to free() shall be returned.
- return purgeable_malloc(szone, 1);
- }
-
- old_size = purgeable_size(szone, ptr); // Now ptr can be safely size()'d
- if (!old_size)
- old_size = szone_size(szone->helper_zone, ptr);
-
- if (!old_size) {
- szone_error(szone, 1, "pointer being reallocated was not allocated", ptr, NULL);
- return NULL;
- }
-
- // Distinguish 4 cases: {oldsize, newsize} x { <= , > large_threshold }
- // and deal with the allocation crossing from the purgeable zone to the helper zone and vice versa.
- if (old_size <= szone->large_threshold) {
- if (new_size <= szone->large_threshold)
- return szone_realloc(szone->helper_zone, ptr, new_size);
- else {
- // allocation crosses from helper to purgeable zone
- void * new_ptr = purgeable_malloc(szone, new_size);
- if (new_ptr) {
- memcpy(new_ptr, ptr, old_size);
- szone_free_definite_size(szone->helper_zone, ptr, old_size);
- }
- return new_ptr; // in state VM_PURGABLE_NONVOLATILE
- }
- } else {
- if (new_size <= szone->large_threshold) {
- // allocation crosses from purgeable to helper zone
- void * new_ptr = szone_malloc(szone->helper_zone, new_size);
- if (new_ptr) {
- memcpy(new_ptr, ptr, new_size);
- purgeable_free_definite_size(szone, ptr, old_size);
- }
- return new_ptr;
- } else {
- void * new_ptr = purgeable_malloc(szone, new_size);
- if (new_ptr) {
- memcpy(new_ptr, ptr, MIN(old_size, new_size));
- purgeable_free_definite_size(szone, ptr, old_size);
- }
- return new_ptr; // in state VM_PURGABLE_NONVOLATILE
- }
- }
- /* NOTREACHED */
-}
-
-static void
-purgeable_destroy(szone_t *szone)
-{
- /* destroy large entries */
- size_t index = szone->num_large_entries;
- large_entry_t *large;
- vm_range_t range_to_deallocate;
-
- while (index--) {
- large = szone->large_entries + index;
- if (large->address) {
- // we deallocate_pages, including guard pages
- deallocate_pages(szone, (void *)(large->address), large->size, szone->debug_flags);
- }
- }
- large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate);
- if (range_to_deallocate.size)
- deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0);
-
- /* Now destroy the separate szone region */
- deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, 0);
-}
-
-static unsigned
-purgeable_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count)
-{
- return szone_batch_malloc(szone->helper_zone, size, results, count);
-}
-
-static void
-purgeable_batch_free(szone_t *szone, void **to_be_freed, unsigned count)
-{
- return szone_batch_free(szone->helper_zone, to_be_freed, count);
-}
-
-static void *
-purgeable_memalign(szone_t *szone, size_t alignment, size_t size)
-{
- if (size <= szone->large_threshold)
- return szone_memalign(szone->helper_zone, alignment, size);
- else
- return szone_memalign(szone, alignment, size);
-}
-
-static kern_return_t
-purgeable_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address,
- memory_reader_t reader, vm_range_recorder_t recorder)
-{
- szone_t *szone;
- kern_return_t err;
-
- if (!reader) reader = _szone_default_reader;
-
- err = reader(task, zone_address, sizeof(szone_t), (void **)&szone);
- if (err) return err;
-
- err = large_in_use_enumerator(task, context, type_mask,
- (vm_address_t)szone->large_entries, szone->num_large_entries, reader, recorder);
- return err;
-}
-
-static size_t
-purgeable_good_size(szone_t *szone, size_t size)
-{
- if (size <= szone->large_threshold)
- return szone_good_size(szone->helper_zone, size);
- else
- return szone_good_size(szone, size);
-}
-
-static boolean_t
-purgeable_check(szone_t *szone)
-{
- return 1;
-}
-
-static void
-purgeable_print(szone_t *szone, boolean_t verbose)
-{
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "Scalable zone %p: inUse=%u(%y) flags=%d\n",
- szone, szone->num_large_objects_in_use, szone->num_bytes_in_large_objects, szone->debug_flags);
-}
-
-static void
-purgeable_log(malloc_zone_t *zone, void *log_address)
-{
- szone_t *szone = (szone_t *)zone;
-
- szone->log_address = log_address;
-}
-
-static void
-purgeable_force_lock(szone_t *szone)
-{
- SZONE_LOCK(szone);
-}
-
-static void
-purgeable_force_unlock(szone_t *szone)
-{
- SZONE_UNLOCK(szone);
-}
-
-static void
-purgeable_statistics(szone_t *szone, malloc_statistics_t *stats)
-{
- stats->blocks_in_use = szone->num_large_objects_in_use;
- stats->size_in_use = stats->max_size_in_use = stats->size_allocated = szone->num_bytes_in_large_objects;
-}
-
-static boolean_t
-purgeable_locked(szone_t *szone)
-{
- int tookLock;
-
- tookLock = SZONE_TRY_LOCK(szone);
- if (tookLock == 0)
- return 1;
- SZONE_UNLOCK(szone);
- return 0;
-}
-
-static size_t
-purgeable_pressure_relief(szone_t *szone, size_t goal)
-{
- return szone_pressure_relief(szone, goal) + szone_pressure_relief(szone->helper_zone, goal);
-}
-
-static const struct malloc_introspection_t purgeable_introspect = {
- (void *)purgeable_ptr_in_use_enumerator,
- (void *)purgeable_good_size,
- (void *)purgeable_check,
- (void *)purgeable_print,
- purgeable_log,
- (void *)purgeable_force_lock,
- (void *)purgeable_force_unlock,
- (void *)purgeable_statistics,
- (void *)purgeable_locked,
- NULL, NULL, NULL, NULL, /* Zone enumeration version 7 and forward. */
-}; // marked as const to spare the DATA section
-
-__private_extern__ malloc_zone_t *
-create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags)
-{
- szone_t *szone;
- uint64_t hw_memsize = 0;
-
- /* get memory for the zone. */
- szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0, 0, VM_MEMORY_MALLOC);
- if (!szone)
- return NULL;
-
- /* set up the szone structure */
-#if 0
-#warning LOG enabled
- szone->log_address = ~0;
-#endif
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- hw_memsize = *(uint64_t *)(uintptr_t)_COMM_PAGE_MEMORY_SIZE;
-#else
- size_t uint64_t_size = sizeof(hw_memsize);
-
- sysctlbyname("hw.memsize", &hw_memsize, &uint64_t_size, 0, 0);
-#endif
- /* Purgeable zone does not participate in the adaptive "largemem" sizing. */
- szone->is_largemem = 0;
- szone->large_threshold = LARGE_THRESHOLD;
- szone->vm_copy_threshold = VM_COPY_THRESHOLD;
-
-#if LARGE_CACHE
- szone->large_entry_cache_reserve_limit =
- hw_memsize >> 10; // madvise(..., MADV_REUSABLE) death-row arrivals above this threshold [~0.1%]
-
- /* <rdar://problem/6610904> Reset protection when returning a previous large allocation? */
- int32_t libSystemVersion = NSVersionOfLinkTimeLibrary("System");
- if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 112) /* CFSystemVersionSnowLeopard */)
- szone->large_legacy_reset_mprotect = TRUE;
- else
- szone->large_legacy_reset_mprotect = FALSE;
-#endif
-
- szone->basic_zone.version = 8;
- szone->basic_zone.size = (void *)purgeable_size;
- szone->basic_zone.malloc = (void *)purgeable_malloc;
- szone->basic_zone.calloc = (void *)purgeable_calloc;
- szone->basic_zone.valloc = (void *)purgeable_valloc;
- szone->basic_zone.free = (void *)purgeable_free;
- szone->basic_zone.realloc = (void *)purgeable_realloc;
- szone->basic_zone.destroy = (void *)purgeable_destroy;
- szone->basic_zone.batch_malloc = (void *)purgeable_batch_malloc;
- szone->basic_zone.batch_free = (void *)purgeable_batch_free;
- szone->basic_zone.introspect = (struct malloc_introspection_t *)&purgeable_introspect;
- szone->basic_zone.memalign = (void *)purgeable_memalign;
- szone->basic_zone.free_definite_size = (void *)purgeable_free_definite_size;
- szone->basic_zone.pressure_relief = (void *)purgeable_pressure_relief;
-
- szone->basic_zone.reserved1 = 0; /* Set to zero once and for all as required by CFAllocator. */
- szone->basic_zone.reserved2 = 0; /* Set to zero once and for all as required by CFAllocator. */
- mprotect(szone, sizeof(szone->basic_zone), PROT_READ); /* Prevent overwriting the function pointers in basic_zone. */
-
- szone->debug_flags = debug_flags | SCALABLE_MALLOC_PURGEABLE;
-
- /* Purgeable zone does not support SCALABLE_MALLOC_ADD_GUARD_PAGES. */
- if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) {
- _malloc_printf(ASL_LEVEL_INFO, "purgeable zone does not support guard pages\n");
- szone->debug_flags &= ~SCALABLE_MALLOC_ADD_GUARD_PAGES;
- }
-
- LOCK_INIT(szone->large_szone_lock);
-
- szone->helper_zone = (struct szone_s *)malloc_default_zone;
-
- CHECK(szone, __PRETTY_FUNCTION__);
- return (malloc_zone_t *)szone;
-}
-
-/*
- * For use by CheckFix: create a new zone whose behavior is, apart from
- * the use of death-row and per-CPU magazines, that of Leopard.
- */
-static NOINLINE void *
-legacy_valloc(szone_t *szone, size_t size)
-{
- void *ptr;
- size_t num_pages;
-
- num_pages = round_page(size) >> vm_page_shift;
- ptr = large_malloc(szone, num_pages, 0, TRUE);
-#if DEBUG_MALLOC
- if (LOG(szone, ptr))
- malloc_printf("legacy_valloc returned %p\n", ptr);
-#endif
- return ptr;
-}
-
-__private_extern__ malloc_zone_t *
-create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags)
-{
- malloc_zone_t *mzone = create_scalable_zone(initial_size, debug_flags);
- szone_t *szone = (szone_t *)mzone;
-
- if (!szone)
- return NULL;
-
- szone->is_largemem = 0;
- szone->num_small_slots = NUM_SMALL_SLOTS;
- szone->large_threshold = LARGE_THRESHOLD;
- szone->vm_copy_threshold = VM_COPY_THRESHOLD;
-
- mprotect(szone, sizeof(szone->basic_zone), PROT_READ | PROT_WRITE);
- szone->basic_zone.valloc = (void *)legacy_valloc;
- szone->basic_zone.free_definite_size = NULL;
- mprotect(szone, sizeof(szone->basic_zone), PROT_READ);
-
- return mzone;
-}
-
-/********* Support code for emacs unexec ************/
-
-/* History of freezedry version numbers:
- *
- * 1) Old malloc (before the scalable malloc implementation in this file
- * existed).
- * 2) Original freezedrying code for scalable malloc. This code was apparently
- * based on the old freezedrying code and was fundamentally flawed in its
- * assumption that tracking allocated memory regions was adequate to fake
- * operations on freezedried memory. This doesn't work, since scalable
- * malloc does not store flags in front of large page-aligned allocations.
- * 3) Original szone-based freezedrying code.
- * 4) Fresher malloc with tiny zone
- * 5) 32/64bit compatible malloc
- * 6) Metadata within 1MB and 8MB region for tiny and small
- *
- * No version backward compatibility is provided, but the version number does
- * make it possible for malloc_jumpstart() to return an error if the application
- * was freezedried with an older version of malloc.
- */
-#define MALLOC_FREEZEDRY_VERSION 6
-
-typedef struct {
- unsigned version;
- unsigned nszones;
- szone_t *szones;
-} malloc_frozen;
-
-static void *
-frozen_malloc(szone_t *zone, size_t new_size)
-{
- return malloc(new_size);
-}
-
-static void *
-frozen_calloc(szone_t *zone, size_t num_items, size_t size)
-{
- return calloc(num_items, size);
-}
-
-static void *
-frozen_valloc(szone_t *zone, size_t new_size)
-{
- return valloc(new_size);
-}
-
-static void *
-frozen_realloc(szone_t *zone, void *ptr, size_t new_size)
-{
- size_t old_size = szone_size(zone, ptr);
- void *new_ptr;
-
- if (new_size <= old_size) {
- return ptr;
- }
- new_ptr = malloc(new_size);
- if (old_size > 0) {
- memcpy(new_ptr, ptr, old_size);
- }
- return new_ptr;
-}
-
-static void
-frozen_free(szone_t *zone, void *ptr)
-{
-}
-
-static void
-frozen_destroy(szone_t *zone)
-{
-}
-
-/********* Pseudo-private API for emacs unexec ************/
-
-/*
- * malloc_freezedry() records all of the szones in use, so that they can be
- * partially reconstituted by malloc_jumpstart(). Due to the differences
- * between reconstituted memory regions and those created by the szone code,
- * care is taken not to reallocate from the freezedried memory, except in the
- * case of a non-growing realloc().
- *
- * Due to the flexibility provided by the zone registration mechanism, it is
- * impossible to implement generic freezedrying for any zone type. This code
- * only handles applications that use the szone allocator, so malloc_freezedry()
- * returns 0 (error) if any non-szone zones are encountered.
- */
-
-uintptr_t
-malloc_freezedry(void)
-{
- extern unsigned malloc_num_zones;
- extern malloc_zone_t **malloc_zones;
- malloc_frozen *data;
- unsigned i;
-
- /* Allocate space in which to store the freezedry state. */
- data = (malloc_frozen *) malloc(sizeof(malloc_frozen));
-
- /* Set freezedry version number so that malloc_jumpstart() can check for compatibility. */
- data->version = MALLOC_FREEZEDRY_VERSION;
-
- /* Allocate the array of szone pointers. */
- data->nszones = malloc_num_zones;
- data->szones = (szone_t *) calloc(malloc_num_zones, sizeof(szone_t));
-
- /*
- * Fill in the array of szone structures. They are copied rather than
- * referenced, since the originals are likely to be clobbered during malloc
- * initialization.
- */
- for (i = 0; i < malloc_num_zones; i++) {
- if (strcmp(malloc_zones[i]->zone_name, "DefaultMallocZone")) {
- /* Unknown zone type. */
- free(data->szones);
- free(data);
- return 0;
- }
- memcpy(&data->szones[i], malloc_zones[i], sizeof(szone_t));
- }
-
- return((uintptr_t)data);
-}
-
-int
-malloc_jumpstart(uintptr_t cookie)
-{
- malloc_frozen *data = (malloc_frozen *)cookie;
- unsigned i;
-
- if (data->version != MALLOC_FREEZEDRY_VERSION) {
- /* Unsupported freezedry version. */
- return 1;
- }
-
- for (i = 0; i < data->nszones; i++) {
- /* Set function pointers. Even the functions that stay the same must be
- * set, since there are no guarantees that they will be mapped to the
- * same addresses. */
- data->szones[i].basic_zone.size = (void *) szone_size;
- data->szones[i].basic_zone.malloc = (void *) frozen_malloc;
- data->szones[i].basic_zone.calloc = (void *) frozen_calloc;
- data->szones[i].basic_zone.valloc = (void *) frozen_valloc;
- data->szones[i].basic_zone.free = (void *) frozen_free;
- data->szones[i].basic_zone.realloc = (void *) frozen_realloc;
- data->szones[i].basic_zone.destroy = (void *) frozen_destroy;
- data->szones[i].basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect;
-
- /* Register the freezedried zone. */
- malloc_zone_register(&data->szones[i].basic_zone);
- }
-
- return 0;
-}
+++ /dev/null
-provider magmalloc {
- probe refreshIndex(void *, int, int);
- probe depotRegion(void *, int, void *, int, int);
- probe recircRegion(void *, int, void *, int, int);
- probe allocRegion(void *, int, void *, int);
- probe deallocRegion(void *, void *, int);
- probe madvfreeRegion(void *, void *, void *, int);
- probe pressureRelief(void *, int, int);
- probe mallocErrorBreak();
-};
-
-#pragma D attributes Evolving/Evolving/ISA provider magmalloc provider
-#pragma D attributes Private/Private/Unknown provider magmalloc module
-#pragma D attributes Private/Private/Unknown provider magmalloc function
-#pragma D attributes Evolving/Evolving/ISA provider magmalloc name
-#pragma D attributes Evolving/Evolving/ISA provider magmalloc args
-
+++ /dev/null
-.\" Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
-.\"
-.\" @APPLE_LICENSE_HEADER_START@
-.\"
-.\" The contents of this file constitute Original Code as defined in and
-.\" are subject to the Apple Public Source License Version 1.1 (the
-.\" "License"). You may not use this file except in compliance with the
-.\" License. Please obtain a copy of the License at
-.\" http://www.apple.com/publicsource and read it before using this file.
-.\"
-.\" This Original Code and all software distributed under the License are
-.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
-.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
-.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
-.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
-.\" License for the specific language governing rights and limitations
-.\" under the License.
-.\"
-.\" @APPLE_LICENSE_HEADER_END@
-.\"
-.Dd Aug 13, 2008
-.Dt MALLOC 3
-.Os
-.Sh NAME
-.Nm calloc ,
-.Nm free ,
-.Nm malloc ,
-.Nm realloc ,
-.Nm reallocf ,
-.Nm valloc
-.Nd memory allocation
-.Sh SYNOPSIS
-.In stdlib.h
-.Ft void *
-.Fo calloc
-.Fa "size_t count"
-.Fa "size_t size"
-.Fc
-.Ft void
-.Fo free
-.Fa "void *ptr"
-.Fc
-.Ft void *
-.Fo malloc
-.Fa "size_t size"
-.Fc
-.Ft void *
-.Fo realloc
-.Fa "void *ptr"
-.Fa "size_t size"
-.Fc
-.Ft void *
-.Fo reallocf
-.Fa "void *ptr"
-.Fa "size_t size"
-.Fc
-.Ft void *
-.Fo valloc
-.Fa "size_t size"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn malloc ,
-.Fn calloc ,
-.Fn valloc ,
-.Fn realloc ,
-and
-.Fn reallocf
-functions allocate memory.
-The allocated memory is aligned such that it can be used for any data type,
-including AltiVec- and SSE-related types.
-The
-.Fn free
-function frees allocations that were created via the preceding allocation
-functions.
-.Pp
-The
-.Fn malloc
-function allocates
-.Fa size
-bytes of memory and returns a pointer to the allocated memory.
-.Pp
-The
-.Fn calloc
-function contiguously allocates enough space for
-.Fa count
-objects that are
-.Fa size
-bytes of memory each and returns a pointer to the allocated memory.
-The allocated memory is filled with bytes of value zero.
-.Pp
-The
-.Fn valloc
-function allocates
-.Fa size
-bytes of memory and returns a pointer to the allocated memory.
-The allocated memory is aligned on a page boundary.
-.Pp
-The
-.Fn realloc
-function tries to change the size of the allocation pointed to by
-.Fa ptr
-to
-.Fa size ,
-and returns
-.Fa ptr .
-If there is not enough room to enlarge the memory allocation pointed to by
-.Fa ptr ,
-.Fn realloc
-creates a new allocation, copies as much of the old data pointed to by
-.Fa ptr
-as will fit to the new allocation, frees the old allocation, and returns a
-pointer to the allocated memory.
-If
-.Fa ptr
-is
-.Dv NULL ,
-.Fn realloc
-is identical to a call to
-.Fn malloc
-for
-.Fa size
-bytes.
-If
-.Fa size
-is zero and
-.Fa ptr
-is not
-.Dv NULL ,
-a new, minimum sized object is allocated and the original object is freed.
-When extending a region allocated with calloc(3), realloc(3) does not guarantee
-that the additional memory is also zero-filled.
-.Pp
-The
-.Fn reallocf
-function is identical to the
-.Fn realloc
-function, except that it
-will free the passed pointer when the requested memory cannot be allocated.
-This is a
-.Fx
-specific API designed to ease the problems with traditional coding styles
-for realloc causing memory leaks in libraries.
-.Pp
-The
-.Fn free
-function deallocates the memory allocation pointed to by
-.Fa ptr . If
-.Fa ptr
-is a NULL pointer, no operation is performed.
-.Sh RETURN VALUES
-If successful,
-.Fn calloc ,
-.Fn malloc ,
-.Fn realloc ,
-.Fn reallocf ,
-and
-.Fn valloc
-functions return a pointer to allocated memory.
-If there is an error, they return a
-.Dv NULL
-pointer and set
-.Va errno
-to
-.Er ENOMEM .
-.Pp
-For
-.Fn realloc ,
-the input pointer is still valid if reallocation failed.
-For
-.Fn reallocf ,
-the input pointer will have been freed if reallocation failed.
-.Pp
-The
-.Fn free
-function does not return a value.
-.Sh DEBUGGING ALLOCATION ERRORS
-A number of facilities are provided to aid in debugging allocation errors in
-applications.
-These facilities are primarily controlled via environment variables.
-The recognized environment variables and their meanings are documented below.
-.Sh ENVIRONMENT
-The following environment variables change the behavior of the
-allocation-related functions.
-.Bl -tag -width ".Ev MallocStackLoggingNoCompact"
-.It Ev MallocLogFile <f>
-Create/append messages to the given file path
-.Fa <f>
-instead of writing to the standard error.
-.It Ev MallocGuardEdges
-If set, add a guard page before and after each large block.
-.It Ev MallocDoNotProtectPrelude
-If set, do not add a guard page before large blocks,
-even if the
-.Ev MallocGuardEdges
-environment variable is set.
-.It Ev MallocDoNotProtectPostlude
-If set, do not add a guard page after large blocks,
-even if the
-.Ev MallocGuardEdges
-environment variable is set.
-.It Ev MallocStackLogging
-If set, record all stacks, so that tools like
-.Nm leaks
-can be used.
-.It Ev MallocStackLoggingNoCompact
-If set, record all stacks in a manner that is compatible with the
-.Nm malloc_history
-program.
-.It Ev MallocStackLoggingDirectory
-If set, records stack logs to the directory specified instead of saving them to the default location (/tmp).
-.It Ev MallocScribble
-If set, fill memory that has been allocated with 0xaa bytes.
-This increases the likelihood that a program making assumptions about the contents of
-freshly allocated memory will fail.
-Also if set, fill memory that has been deallocated with 0x55 bytes.
-This increases the likelihood that a program will fail due to accessing memory
-that is no longer allocated.
-.It Ev MallocCheckHeapStart <s>
-If set, specifies the number of allocations
-.Fa <s>
-to wait before begining periodic heap checks every
-.Fa <n>
-as specified by
-.Ev MallocCheckHeapEach .
-If
-.Ev MallocCheckHeapStart
-is set but
-.Ev MallocCheckHeapEach
-is not specified, the default check repetition is 1000.
-.It Ev MallocCheckHeapEach <n>
-If set, run a consistency check on the heap every
-.Fa <n>
-operations.
-.Ev MallocCheckHeapEach
-is only meaningful if
-.Ev MallocCheckHeapStart
-is also set.
-.It Ev MallocCheckHeapSleep <t>
-Sets the number of seconds to sleep (waiting for a debugger to attach) when
-.Ev MallocCheckHeapStart
-is set and a heap corruption is detected.
-The default is 100 seconds.
-Setting this to zero means not to sleep at all.
-Setting this to a negative number means to sleep (for the positive number of
-seconds) only the very first time a heap corruption is detected.
-.It Ev MallocCheckHeapAbort <b>
-When
-.Ev MallocCheckHeapStart
-is set and this is set to a non-zero value, causes
-.Xr abort 3
-to be called if a heap corruption is detected, instead of any sleeping.
-.It Ev MallocErrorAbort
-If set, causes
-.Xr abort 3
-to be called if an error was encountered in
-.Xr malloc 3
-or
-.Xr free 3
-, such as a calling
-.Xr free 3
-on a pointer previously freed.
-.It Ev MallocCorruptionAbort
-Similar to
-.Ev
-MallocErrorAbort
-but will not abort in out of memory conditions, making it more useful to catch
-only those errors which will cause memory corruption.
-MallocCorruptionAbort is always set on 64-bit processes.
-.It Ev MallocHelp
-If set, print a list of environment variables that are paid heed to by the
-allocation-related functions, along with short descriptions.
-The list should correspond to this documentation.
-.El
-.Sh DIAGNOSTIC MESSAGES
-.Sh SEE ALSO
-.Xr leaks 1 ,
-.Xr malloc_history 1 ,
-.Xr abort 3 ,
-.Xr malloc_size 3 ,
-.Xr malloc_zone_malloc 3 ,
-.Xr posix_memalign 3 ,
-.Xr libgmalloc 3
+++ /dev/null
-/*
- * Copyright (c) 1999, 2006-2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <pthread_internals.h>
-#include "magmallocProvider.h"
-#include <mach-o/dyld.h> /* for NSVersionOfLinkTimeLibrary() */
-
-#import <stdlib.h>
-#import <stdio.h>
-#import <string.h>
-#import <unistd.h>
-#import <malloc/malloc.h>
-#import <fcntl.h>
-#import <crt_externs.h>
-#import <errno.h>
-#import <pthread_internals.h>
-#import <limits.h>
-#import <dlfcn.h>
-#import <mach/mach_vm.h>
-#import <mach/mach_init.h>
-#import <sys/mman.h>
-
-#import "scalable_malloc.h"
-#import "stack_logging.h"
-#import "malloc_printf.h"
-#import "_simple.h"
-#import "CrashReporterClient.h"
-
-/*
- * MALLOC_ABSOLUTE_MAX_SIZE - There are many instances of addition to a
- * user-specified size_t, which can cause overflow (and subsequent crashes)
- * for values near SIZE_T_MAX. Rather than add extra "if" checks everywhere
- * this occurs, it is easier to just set an absolute maximum request size,
- * and immediately return an error if the requested size exceeds this maximum.
- * Of course, values less than this absolute max can fail later if the value
- * is still too large for the available memory. The largest value added
- * seems to be PAGE_SIZE (in the macro round_page()), so to be safe, we set
- * the maximum to be 2 * PAGE_SIZE less than SIZE_T_MAX.
- */
-#define MALLOC_ABSOLUTE_MAX_SIZE (SIZE_T_MAX - (2 * PAGE_SIZE))
-
-#define USE_SLEEP_RATHER_THAN_ABORT 0
-
-typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip);
-
-__private_extern__ pthread_lock_t _malloc_lock = 0; // initialized in __libc_init
-
-/* The following variables are exported for the benefit of performance tools
- *
- * It should always be safe to first read malloc_num_zones, then read
- * malloc_zones without taking the lock, if only iteration is required and
- * provided that when malloc_destroy_zone is called all prior operations on that
- * zone are complete and no further calls referencing that zone can be made.
- */
-unsigned malloc_num_zones = 0;
-unsigned malloc_num_zones_allocated = 0;
-malloc_zone_t **malloc_zones = 0;
-malloc_logger_t *malloc_logger = NULL;
-
-unsigned malloc_debug_flags = 0;
-
-unsigned malloc_check_start = 0; // 0 means don't check
-unsigned malloc_check_counter = 0;
-unsigned malloc_check_each = 1000;
-
-/* global flag to suppress ASL logging e.g. for syslogd */
-int _malloc_no_asl_log = 0;
-
-static int malloc_check_sleep = 100; // default 100 second sleep
-static int malloc_check_abort = 0; // default is to sleep, not abort
-
-static int malloc_debug_file = STDERR_FILENO;
-/*
- * State indicated by malloc_def_zone_state
- * 0 - the default zone has not yet been created
- * 1 - a Malloc* environment variable has been set
- * 2 - the default zone has been created and an environment variable scan done
- * 3 - a new default zone has been created and another environment variable scan
- */
-__private_extern__ int malloc_def_zone_state = 0;
-
-static const char Malloc_Facility[] = "com.apple.Libsystem.malloc";
-
-#define MALLOC_LOCK() LOCK(_malloc_lock)
-#define MALLOC_UNLOCK() UNLOCK(_malloc_lock)
-
-/*
- * Counters that coordinate zone destruction (in malloc_zone_unregister) with
- * find_registered_zone (here abbreviated as FRZ).
- */
-static int counterAlice = 0, counterBob = 0;
-static int *pFRZCounterLive= &counterAlice, *pFRZCounterDrain = &counterBob;
-
-#define MALLOC_LOG_TYPE_ALLOCATE stack_logging_type_alloc
-#define MALLOC_LOG_TYPE_DEALLOCATE stack_logging_type_dealloc
-#define MALLOC_LOG_TYPE_HAS_ZONE stack_logging_flag_zone
-#define MALLOC_LOG_TYPE_CLEARED stack_logging_flag_cleared
-
-/********* Utilities ************/
-__private_extern__ uint64_t malloc_entropy[2] = {0, 0};
-
-void __malloc_entropy_setup(const char *apple[]) __attribute__ ((visibility ("hidden")));
-
-static int
-__entropy_from_kernel(const char *str)
-{
- unsigned long long val;
- char tmp[20], *p;
- int idx = 0;
-
- /* Skip over key to the first value */
- str = strchr(str, '=');
- if (str == NULL)
- return 0;
- str++;
-
- while (str && idx < sizeof(malloc_entropy)/sizeof(malloc_entropy[0])) {
- strlcpy(tmp, str, 20);
- p = strchr(tmp, ',');
- if (p) *p = '\0';
- val = strtoull(tmp, NULL, 0);
- malloc_entropy[idx] = (uint64_t)val;
- idx++;
- if ((str = strchr(str, ',')) != NULL)
- str++;
- }
- return idx;
-}
-
-void
-__malloc_entropy_setup(const char *apple[])
-{
- const char **p;
- for (p = apple; p && *p; p++) {
- if (strstr(*p, "malloc_entropy") == *p) {
- if (sizeof(malloc_entropy)/sizeof(malloc_entropy[0]) == __entropy_from_kernel(*p))
- return;
- else
- break;
- }
- }
-
- malloc_entropy[0] = ((uint64_t)arc4random()) << 32 | ((uint64_t)arc4random());
- malloc_entropy[1] = ((uint64_t)arc4random()) << 32 | ((uint64_t)arc4random());
- return;
-}
-
-static inline malloc_zone_t * find_registered_zone(const void *, size_t *) __attribute__((always_inline));
-static inline malloc_zone_t *
-find_registered_zone(const void *ptr, size_t *returned_size) {
- // Returns a zone which contains ptr, else NULL
-
- if (0 == malloc_num_zones) {
- if (returned_size) *returned_size = 0;
- return NULL;
- }
-
- // The default zone is registered in malloc_zones[0]. There's no danger that it will ever be unregistered.
- // So don't advance the FRZ counter yet.
- malloc_zone_t *zone = malloc_zones[0];
- size_t size = zone->size(zone, ptr);
- if (size) { // Claimed by this zone?
- if (returned_size) *returned_size = size;
- return zone;
- }
-
- int *pFRZCounter = pFRZCounterLive; // Capture pointer to the counter of the moment
- __sync_fetch_and_add(pFRZCounter, 1); // Advance this counter -- our thread is in FRZ
-
- unsigned index;
- unsigned limit = malloc_num_zones;
- malloc_zone_t **zones = &malloc_zones[1];
-
- for (index = 1; index < limit; ++index, ++zones) {
- zone = *zones;
- size = zone->size(zone, ptr);
- if (size) { // Claimed by this zone?
- if (returned_size) *returned_size = size;
- __sync_fetch_and_sub(pFRZCounter, 1); // our thread is leaving FRZ
- return zone;
- }
- }
- // Unclaimed by any zone.
- if (returned_size) *returned_size = 0;
- __sync_fetch_and_sub(pFRZCounter, 1); // our thread is leaving FRZ
- return NULL;
-}
-
-__private_extern__ __attribute__((noinline)) void
-malloc_error_break(void) {
- // Provides a non-inlined place for various malloc error procedures to call
- // that will be called after an error message appears. It does not make
- // sense for developers to call this function, so it is marked
- // __private_extern__ to prevent it from becoming API.
- MAGMALLOC_MALLOCERRORBREAK(); // DTrace USDT probe
-}
-
-__private_extern__ boolean_t __stack_logging_locked();
-
-__private_extern__ __attribute__((noinline)) __attribute__((used)) int
-malloc_gdb_po_unsafe(void) {
- // In order to implement "po" other data formatters in gdb, the debugger
- // calls functions that call malloc. The debugger will only run one thread
- // of the program in this case, so if another thread is holding a zone lock,
- // gdb may deadlock in this case.
- //
- // Iterate over the zones in malloc_zones, and call "trylock" on the zone
- // lock. If trylock succeeds, unlock it, otherwise return "locked". Returns
- // 0 == safe, 1 == locked/unsafe.
-
- if (__stack_logging_locked())
- return 1;
-
- malloc_zone_t **zones = malloc_zones;
- unsigned i, e = malloc_num_zones;
-
- for (i = 0; i != e; ++i) {
- malloc_zone_t *zone = zones[i];
-
- // Version must be >= 5 to look at the new introspection field.
- if (zone->version < 5)
- continue;
-
- if (zone->introspect->zone_locked && zone->introspect->zone_locked(zone))
- return 1;
- }
- return 0;
-}
-
-/********* Creation and destruction ************/
-
-static void set_flags_from_environment(void);
-
-static void
-malloc_zone_register_while_locked(malloc_zone_t *zone) {
- size_t protect_size;
- unsigned i;
-
- /* scan the list of zones, to see if this zone is already registered. If
- * so, print an error message and return. */
- for (i = 0; i != malloc_num_zones; ++i)
- if (zone == malloc_zones[i]) {
- _malloc_printf(ASL_LEVEL_ERR, "Attempted to register zone more than once: %p\n", zone);
- return;
- }
-
- if (malloc_num_zones == malloc_num_zones_allocated) {
- size_t malloc_zones_size = malloc_num_zones * sizeof(malloc_zone_t *);
- size_t alloc_size = malloc_zones_size + vm_page_size;
-
- malloc_zone_t **new_zones = mmap(0, alloc_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, VM_MAKE_TAG(VM_MEMORY_MALLOC), 0);
-
- /* If there were previously allocated malloc zones, we need to copy them
- * out of the previous array and into the new zones array */
- if (malloc_zones)
- memcpy(new_zones, malloc_zones, malloc_zones_size);
-
- /* Update the malloc_zones pointer, which we leak if it was previously
- * allocated, and the number of zones allocated */
- protect_size = alloc_size;
- malloc_zones = new_zones;
- malloc_num_zones_allocated = alloc_size / sizeof(malloc_zone_t *);
- } else {
- /* If we don't need to reallocate zones, we need to briefly change the
- * page protection the malloc zones to allow writes */
- protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *);
- mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE);
- }
- malloc_zones[malloc_num_zones++] = zone;
-
- /* Finally, now that the zone is registered, disallow write access to the
- * malloc_zones array */
- mprotect(malloc_zones, protect_size, PROT_READ);
- //_malloc_printf(ASL_LEVEL_INFO, "Registered malloc_zone %p in malloc_zones %p [%u zones, %u bytes]\n", zone, malloc_zones, malloc_num_zones, protect_size);
-}
-
-static void
-_malloc_initialize(void) {
- MALLOC_LOCK();
- if (malloc_def_zone_state < 2) {
- unsigned n;
- malloc_zone_t *zone;
-
- malloc_def_zone_state += 2;
- set_flags_from_environment(); // will only set flags up to two times
- n = malloc_num_zones;
- zone = create_scalable_zone(0, malloc_debug_flags);
- malloc_zone_register_while_locked(zone);
- malloc_set_zone_name(zone, "DefaultMallocZone");
- if (n != 0) { // make the default first, for efficiency
- unsigned protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *);
- malloc_zone_t *hold = malloc_zones[0];
-
- if(hold->zone_name && strcmp(hold->zone_name, "DefaultMallocZone") == 0) {
- malloc_set_zone_name(hold, NULL);
- }
-
- mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE);
- malloc_zones[0] = malloc_zones[n];
- malloc_zones[n] = hold;
- mprotect(malloc_zones, protect_size, PROT_READ);
- }
- // _malloc_printf(ASL_LEVEL_INFO, "%d registered zones\n", malloc_num_zones);
- // _malloc_printf(ASL_LEVEL_INFO, "malloc_zones is at %p; malloc_num_zones is at %p\n", (unsigned)&malloc_zones, (unsigned)&malloc_num_zones);
- }
- MALLOC_UNLOCK();
-}
-
-static inline malloc_zone_t *inline_malloc_default_zone(void) __attribute__((always_inline));
-static inline malloc_zone_t *
-inline_malloc_default_zone(void) {
- if (malloc_def_zone_state < 2) _malloc_initialize();
- // _malloc_printf(ASL_LEVEL_INFO, "In inline_malloc_default_zone with %d %d\n", malloc_num_zones, malloc_has_debug_zone);
- return malloc_zones[0];
-}
-
-malloc_zone_t *
-malloc_default_zone(void) {
- return inline_malloc_default_zone();
-}
-
-static inline malloc_zone_t *inline_malloc_default_scalable_zone(void) __attribute__((always_inline));
-static inline malloc_zone_t *
-inline_malloc_default_scalable_zone(void) {
- unsigned index;
-
- if (malloc_def_zone_state < 2) _malloc_initialize();
- // _malloc_printf(ASL_LEVEL_INFO, "In inline_malloc_default_scalable_zone with %d %d\n", malloc_num_zones, malloc_has_debug_zone);
-
- MALLOC_LOCK();
- for (index = 0; index < malloc_num_zones; ++index) {
- malloc_zone_t *z = malloc_zones[index];
-
- if(z->zone_name && strcmp(z->zone_name, "DefaultMallocZone") == 0) {
- MALLOC_UNLOCK();
- return z;
- }
- }
- MALLOC_UNLOCK();
-
- malloc_printf("*** malloc_default_scalable_zone() failed to find 'DefaultMallocZone'\n");
- return NULL; // FIXME: abort() instead?
-}
-
-malloc_zone_t *
-malloc_default_purgeable_zone(void) {
- static malloc_zone_t *dpz;
-
- if (!dpz) {
- //
- // PR_7288598: Must pass a *scalable* zone (szone) as the helper for create_purgeable_zone().
- // Take care that the zone so obtained is not subject to interposing.
- //
- malloc_zone_t *tmp = create_purgeable_zone(0, inline_malloc_default_scalable_zone(), malloc_debug_flags);
- malloc_zone_register(tmp);
- malloc_set_zone_name(tmp, "DefaultPurgeableMallocZone");
- if (!__sync_bool_compare_and_swap(&dpz, NULL, tmp))
- malloc_destroy_zone(tmp);
- }
- return dpz;
-}
-
-// For debugging, allow stack logging to both memory and disk to compare their results.
-static void
-stack_logging_log_stack_debug(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip)
-{
- __disk_stack_logging_log_stack(type_flags, zone_ptr, size, ptr_arg, return_val, num_hot_to_skip);
- stack_logging_log_stack(type_flags, zone_ptr, size, ptr_arg, return_val, num_hot_to_skip);
-}
-
-static void
-set_flags_from_environment(void) {
- const char *flag;
- int fd;
- char **env = * _NSGetEnviron();
- char **p;
- char *c;
-
- if (malloc_debug_file != STDERR_FILENO) {
- close(malloc_debug_file);
- malloc_debug_file = STDERR_FILENO;
- }
-#if __LP64__
- malloc_debug_flags = SCALABLE_MALLOC_ABORT_ON_CORRUPTION; // Set always on 64-bit processes
-#else
- int libSystemVersion = NSVersionOfLinkTimeLibrary("System");
- if ((-1 != libSystemVersion) && ((libSystemVersion >> 16) < 126) /* Lion or greater */)
- malloc_debug_flags = 0;
- else
- malloc_debug_flags = SCALABLE_MALLOC_ABORT_ON_CORRUPTION;
-#endif
- stack_logging_enable_logging = 0;
- stack_logging_dontcompact = 0;
- malloc_logger = NULL;
- malloc_check_start = 0;
- malloc_check_each = 1000;
- malloc_check_abort = 0;
- malloc_check_sleep = 100;
- /*
- * Given that all environment variables start with "Malloc" we optimize by scanning quickly
- * first the environment, therefore avoiding repeated calls to getenv().
- * If we are setu/gid these flags are ignored to prevent a malicious invoker from changing
- * our behaviour.
- */
- for (p = env; (c = *p) != NULL; ++p) {
- if (!strncmp(c, "Malloc", 6)) {
- if (issetugid())
- return;
- break;
- }
- }
- if (c == NULL)
- return;
- flag = getenv("MallocLogFile");
- if (flag) {
- fd = open(flag, O_WRONLY|O_APPEND|O_CREAT, 0644);
- if (fd >= 0) {
- malloc_debug_file = fd;
- fcntl(fd, F_SETFD, 0); // clear close-on-exec flag XXX why?
- } else {
- malloc_printf("Could not open %s, using stderr\n", flag);
- }
- }
- if (getenv("MallocGuardEdges")) {
- malloc_debug_flags |= SCALABLE_MALLOC_ADD_GUARD_PAGES;
- _malloc_printf(ASL_LEVEL_INFO, "protecting edges\n");
- if (getenv("MallocDoNotProtectPrelude")) {
- malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_PRELUDE;
- _malloc_printf(ASL_LEVEL_INFO, "... but not protecting prelude guard page\n");
- }
- if (getenv("MallocDoNotProtectPostlude")) {
- malloc_debug_flags |= SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE;
- _malloc_printf(ASL_LEVEL_INFO, "... but not protecting postlude guard page\n");
- }
- }
- flag = getenv("MallocStackLogging");
- if (!flag) {
- flag = getenv("MallocStackLoggingNoCompact");
- stack_logging_dontcompact = 1;
- }
- // For debugging, the MallocStackLogging or MallocStackLoggingNoCompact environment variables can be set to
- // values of "memory", "disk", or "both" to control which stack logging mechanism to use. Those strings appear
- // in the flag variable, and the strtoul() call below will return 0, so then we can do string comparison on the
- // value of flag. The default stack logging now is disk stack logging, since memory stack logging is not 64-bit-aware.
- if (flag) {
- unsigned long val = strtoul(flag, NULL, 0);
- if (val == 1) val = 0;
- if (val == -1) val = 0;
- if (val) {
- malloc_logger = (void *)val;
- _malloc_printf(ASL_LEVEL_INFO, "recording stacks using recorder %p\n", malloc_logger);
- } else if (strcmp(flag,"memory") == 0) {
- malloc_logger = (malloc_logger_t *)stack_logging_log_stack;
- _malloc_printf(ASL_LEVEL_INFO, "recording malloc stacks in memory using standard recorder\n");
- } else if (strcmp(flag,"both") == 0) {
- malloc_logger = stack_logging_log_stack_debug;
- _malloc_printf(ASL_LEVEL_INFO, "recording malloc stacks to both memory and disk for comparison debugging\n");
- } else { // the default is to log to disk
- malloc_logger = __disk_stack_logging_log_stack;
- _malloc_printf(ASL_LEVEL_INFO, "recording malloc stacks to disk using standard recorder\n");
- }
- stack_logging_enable_logging = 1;
- if (stack_logging_dontcompact) {
- if (malloc_logger == __disk_stack_logging_log_stack) {
- _malloc_printf(ASL_LEVEL_INFO, "stack logging compaction turned off; size of log files on disk can increase rapidly\n");
- } else {
- _malloc_printf(ASL_LEVEL_INFO, "stack logging compaction turned off; VM can increase rapidly\n");
- }
- }
- }
- if (getenv("MallocScribble")) {
- malloc_debug_flags |= SCALABLE_MALLOC_DO_SCRIBBLE;
- _malloc_printf(ASL_LEVEL_INFO, "enabling scribbling to detect mods to free blocks\n");
- }
- if (getenv("MallocErrorAbort")) {
- malloc_debug_flags |= SCALABLE_MALLOC_ABORT_ON_ERROR;
- _malloc_printf(ASL_LEVEL_INFO, "enabling abort() on bad malloc or free\n");
- }
-#if __LP64__
- /* initialization above forces SCALABLE_MALLOC_ABORT_ON_CORRUPTION of 64-bit processes */
-#else
- flag = getenv("MallocCorruptionAbort");
- if (flag && (flag[0] == '0')) { // Set from an environment variable in 32-bit processes
- malloc_debug_flags &= ~SCALABLE_MALLOC_ABORT_ON_CORRUPTION;
- } else if (flag) {
- malloc_debug_flags |= SCALABLE_MALLOC_ABORT_ON_CORRUPTION;
- }
-#endif
- flag = getenv("MallocCheckHeapStart");
- if (flag) {
- malloc_check_start = strtoul(flag, NULL, 0);
- if (malloc_check_start == 0) malloc_check_start = 1;
- if (malloc_check_start == -1) malloc_check_start = 1;
- flag = getenv("MallocCheckHeapEach");
- if (flag) {
- malloc_check_each = strtoul(flag, NULL, 0);
- if (malloc_check_each == 0) malloc_check_each = 1;
- if (malloc_check_each == -1) malloc_check_each = 1;
- }
- _malloc_printf(ASL_LEVEL_INFO, "checks heap after %dth operation and each %d operations\n", malloc_check_start, malloc_check_each);
- flag = getenv("MallocCheckHeapAbort");
- if (flag)
- malloc_check_abort = strtol(flag, NULL, 0);
- if (malloc_check_abort)
- _malloc_printf(ASL_LEVEL_INFO, "will abort on heap corruption\n");
- else {
- flag = getenv("MallocCheckHeapSleep");
- if (flag)
- malloc_check_sleep = strtol(flag, NULL, 0);
- if (malloc_check_sleep > 0)
- _malloc_printf(ASL_LEVEL_INFO, "will sleep for %d seconds on heap corruption\n", malloc_check_sleep);
- else if (malloc_check_sleep < 0)
- _malloc_printf(ASL_LEVEL_INFO, "will sleep once for %d seconds on heap corruption\n", -malloc_check_sleep);
- else
- _malloc_printf(ASL_LEVEL_INFO, "no sleep on heap corruption\n");
- }
- }
- if (getenv("MallocHelp")) {
- _malloc_printf(ASL_LEVEL_INFO,
- "environment variables that can be set for debug:\n"
- "- MallocLogFile <f> to create/append messages to file <f> instead of stderr\n"
- "- MallocGuardEdges to add 2 guard pages for each large block\n"
- "- MallocDoNotProtectPrelude to disable protection (when previous flag set)\n"
- "- MallocDoNotProtectPostlude to disable protection (when previous flag set)\n"
- "- MallocStackLogging to record all stacks. Tools like leaks can then be applied\n"
- "- MallocStackLoggingNoCompact to record all stacks. Needed for malloc_history\n"
- "- MallocStackLoggingDirectory to set location of stack logs, which can grow large; default is /tmp\n"
- "- MallocScribble to detect writing on free blocks and missing initializers:\n"
- " 0x55 is written upon free and 0xaa is written on allocation\n"
- "- MallocCheckHeapStart <n> to start checking the heap after <n> operations\n"
- "- MallocCheckHeapEach <s> to repeat the checking of the heap after <s> operations\n"
- "- MallocCheckHeapSleep <t> to sleep <t> seconds on heap corruption\n"
- "- MallocCheckHeapAbort <b> to abort on heap corruption if <b> is non-zero\n"
- "- MallocCorruptionAbort to abort on malloc errors, but not on out of memory for 32-bit processes\n"
- " MallocCorruptionAbort is always set on 64-bit processes\n"
- "- MallocErrorAbort to abort on any malloc error, including out of memory\n"
- "- MallocHelp - this help!\n");
- }
-}
-
-malloc_zone_t *
-malloc_create_zone(vm_size_t start_size, unsigned flags)
-{
- malloc_zone_t *zone;
-
- /* start_size doesn't seemed to actually be used, but we test anyways */
- if (start_size > MALLOC_ABSOLUTE_MAX_SIZE) {
- return NULL;
- }
- if (malloc_def_zone_state < 2) _malloc_initialize();
- zone = create_scalable_zone(start_size, flags | malloc_debug_flags);
- malloc_zone_register(zone);
- return zone;
-}
-
-/*
- * For use by CheckFix: establish a new default zone whose behavior is, apart from
- * the use of death-row and per-CPU magazines, that of Leopard.
- */
-void
-malloc_create_legacy_default_zone(void)
-{
- malloc_zone_t *zone;
- int i;
-
- if (malloc_def_zone_state < 2) _malloc_initialize();
- zone = create_legacy_scalable_zone(0, malloc_debug_flags);
-
- MALLOC_LOCK();
- malloc_zone_register_while_locked(zone);
-
- //
- // Establish the legacy scalable zone just created as the default zone.
- //
- malloc_zone_t *hold = malloc_zones[0];
- if(hold->zone_name && strcmp(hold->zone_name, "DefaultMallocZone") == 0) {
- malloc_set_zone_name(hold, NULL);
- }
- malloc_set_zone_name(zone, "DefaultMallocZone");
-
- unsigned protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *);
- mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE);
-
- // assert(zone == malloc_zones[malloc_num_zones - 1];
- for (i = malloc_num_zones - 1; i > 0; --i) {
- malloc_zones[i] = malloc_zones[i - 1];
- }
- malloc_zones[0] = zone;
-
- mprotect(malloc_zones, protect_size, PROT_READ);
- MALLOC_UNLOCK();
-}
-
-void
-malloc_destroy_zone(malloc_zone_t *zone) {
- malloc_set_zone_name(zone, NULL); // Deallocate zone name wherever it may reside PR_7701095
- malloc_zone_unregister(zone);
- zone->destroy(zone);
-}
-
-/********* Block creation and manipulation ************/
-
-static void
-internal_check(void) {
- static vm_address_t *frames = NULL;
- static unsigned num_frames;
- if (malloc_zone_check(NULL)) {
- if (!frames) vm_allocate(mach_task_self(), (void *)&frames, vm_page_size, 1);
- thread_stack_pcs(frames, vm_page_size/sizeof(vm_address_t) - 1, &num_frames);
- } else {
- _SIMPLE_STRING b = _simple_salloc();
- if (b)
- _simple_sprintf(b, "*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1);
- else
- _malloc_printf(MALLOC_PRINTF_NOLOG, "*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1);
- malloc_printf("*** MallocCheckHeap: FAILED check at %dth operation\n", malloc_check_counter-1);
- if (frames) {
- unsigned index = 1;
- if (b) {
- _simple_sappend(b, "Stack for last operation where the malloc check succeeded: ");
- while (index < num_frames) _simple_sprintf(b, "%p ", frames[index++]);
- malloc_printf("%s\n(Use 'atos' for a symbolic stack)\n", _simple_string(b));
- } else {
- /*
- * Should only get here if vm_allocate() can't get a single page of
- * memory, implying _simple_asl_log() would also fail. So we just
- * print to the file descriptor.
- */
- _malloc_printf(MALLOC_PRINTF_NOLOG, "Stack for last operation where the malloc check succeeded: ");
- while (index < num_frames) _malloc_printf(MALLOC_PRINTF_NOLOG, "%p ", frames[index++]);
- _malloc_printf(MALLOC_PRINTF_NOLOG, "\n(Use 'atos' for a symbolic stack)\n");
- }
- }
- if (malloc_check_each > 1) {
- unsigned recomm_each = (malloc_check_each > 10) ? malloc_check_each/10 : 1;
- unsigned recomm_start = (malloc_check_counter > malloc_check_each+1) ? malloc_check_counter-1-malloc_check_each : 1;
- malloc_printf("*** Recommend using 'setenv MallocCheckHeapStart %d; setenv MallocCheckHeapEach %d' to narrow down failure\n", recomm_start, recomm_each);
- }
- if (malloc_check_abort) {
- CRSetCrashLogMessage(b ? _simple_string(b) : "*** MallocCheckHeap: FAILED check");
- abort();
- } else if (b)
- _simple_sfree(b);
- if (malloc_check_sleep > 0) {
- _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping for %d seconds to leave time to attach\n",
- malloc_check_sleep);
- sleep(malloc_check_sleep);
- } else if (malloc_check_sleep < 0) {
- _malloc_printf(ASL_LEVEL_NOTICE, "*** Sleeping once for %d seconds to leave time to attach\n",
- -malloc_check_sleep);
- sleep(-malloc_check_sleep);
- malloc_check_sleep = 0;
- }
- }
- malloc_check_start += malloc_check_each;
-}
-
-void *
-malloc_zone_malloc(malloc_zone_t *zone, size_t size) {
- void *ptr;
- if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
- internal_check();
- }
- if (size > MALLOC_ABSOLUTE_MAX_SIZE) {
- return NULL;
- }
- ptr = zone->malloc(zone, size);
- if (malloc_logger)
- malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0);
- return ptr;
-}
-
-void *
-malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size) {
- void *ptr;
- if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
- internal_check();
- }
- if (size > MALLOC_ABSOLUTE_MAX_SIZE) {
- return NULL;
- }
- ptr = zone->calloc(zone, num_items, size);
- if (malloc_logger)
- malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE | MALLOC_LOG_TYPE_CLEARED, (uintptr_t)zone, (uintptr_t)(num_items * size), 0,
- (uintptr_t)ptr, 0);
- return ptr;
-}
-
-void *
-malloc_zone_valloc(malloc_zone_t *zone, size_t size) {
- void *ptr;
- if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
- internal_check();
- }
- if (size > MALLOC_ABSOLUTE_MAX_SIZE) {
- return NULL;
- }
- ptr = zone->valloc(zone, size);
- if (malloc_logger)
- malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0);
- return ptr;
-}
-
-void *
-malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size) {
- void *new_ptr;
- if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
- internal_check();
- }
- if (size > MALLOC_ABSOLUTE_MAX_SIZE) {
- return NULL;
- }
- new_ptr = zone->realloc(zone, ptr, size);
- if (malloc_logger)
- malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, (uintptr_t)size,
- (uintptr_t)new_ptr, 0);
- return new_ptr;
-}
-
-void
-malloc_zone_free(malloc_zone_t *zone, void *ptr) {
- if (malloc_logger)
- malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0);
- if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
- internal_check();
- }
- zone->free(zone, ptr);
-}
-
-static void
-malloc_zone_free_definite_size(malloc_zone_t *zone, void *ptr, size_t size) {
- if (malloc_logger)
- malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)ptr, 0, 0, 0);
- if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
- internal_check();
- }
- zone->free_definite_size(zone, ptr, size);
-}
-
-malloc_zone_t *
-malloc_zone_from_ptr(const void *ptr) {
- if (!ptr)
- return NULL;
- else
- return find_registered_zone(ptr, NULL);
-}
-
-void *
-malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) {
- void *ptr;
- if (zone->version < 5) // Version must be >= 5 to look at the new memalign field.
- return NULL;
- if (!(zone->memalign))
- return NULL;
- if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
- internal_check();
- }
- if (size > MALLOC_ABSOLUTE_MAX_SIZE) {
- return NULL;
- }
- if (alignment < sizeof( void *) || // excludes 0 == alignment
- 0 != (alignment & (alignment - 1))) { // relies on sizeof(void *) being a power of two.
- return NULL;
- }
- ptr = zone->memalign(zone, alignment, size);
- if (malloc_logger)
- malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)ptr, 0);
- return ptr;
-}
-
-/********* Functions for zone implementors ************/
-
-void
-malloc_zone_register(malloc_zone_t *zone) {
- MALLOC_LOCK();
- malloc_zone_register_while_locked(zone);
- MALLOC_UNLOCK();
-}
-
-void
-malloc_zone_unregister(malloc_zone_t *z) {
- unsigned index;
-
- if (malloc_num_zones == 0)
- return;
-
- MALLOC_LOCK();
- for (index = 0; index < malloc_num_zones; ++index) {
- if (z != malloc_zones[index])
- continue;
-
- // Modify the page to be allow write access, so that we can update the
- // malloc_zones array.
- size_t protect_size = malloc_num_zones_allocated * sizeof(malloc_zone_t *);
- mprotect(malloc_zones, protect_size, PROT_READ | PROT_WRITE);
-
- // If we found a match, replace it with the entry at the end of the list, shrink the list,
- // and leave the end of the list intact to avoid racing with find_registered_zone().
-
- malloc_zones[index] = malloc_zones[malloc_num_zones - 1];
- --malloc_num_zones;
-
- mprotect(malloc_zones, protect_size, PROT_READ);
-
- // Exchange the roles of the FRZ counters. The counter that has captured the number of threads presently
- // executing *inside* find_regiatered_zone is swapped with the counter drained to zero last time through.
- // The former is then allowed to drain to zero while this thread yields.
- int *p = pFRZCounterLive;
- pFRZCounterLive = pFRZCounterDrain;
- pFRZCounterDrain = p;
- __sync_synchronize(); // Full memory barrier
-
- while (0 != *pFRZCounterDrain) { pthread_yield_np(); }
-
- MALLOC_UNLOCK();
-
- return;
- }
- MALLOC_UNLOCK();
- malloc_printf("*** malloc_zone_unregister() failed for %p\n", z);
-}
-
-void
-malloc_set_zone_name(malloc_zone_t *z, const char *name) {
- char *newName;
-
- mprotect(z, sizeof(malloc_zone_t), PROT_READ | PROT_WRITE);
- if (z->zone_name) {
- free((char *)z->zone_name);
- z->zone_name = NULL;
- }
- if (name) {
- size_t buflen = strlen(name) + 1;
- newName = malloc_zone_malloc(z, buflen);
- if (newName) {
- strlcpy(newName, name, buflen);
- z->zone_name = (const char *)newName;
- } else {
- z->zone_name = NULL;
- }
- }
- mprotect(z, sizeof(malloc_zone_t), PROT_READ);
-}
-
-const char *
-malloc_get_zone_name(malloc_zone_t *zone) {
- return zone->zone_name;
-}
-
-/*
- * XXX malloc_printf now uses _simple_*printf. It only deals with a
- * subset of printf format specifiers, but it doesn't call malloc.
- */
-
-__private_extern__ void
-_malloc_vprintf(int flags, const char *format, va_list ap)
-{
- _SIMPLE_STRING b;
-
- if (_malloc_no_asl_log || (flags & MALLOC_PRINTF_NOLOG) || (b = _simple_salloc()) == NULL) {
- if (!(flags & MALLOC_PRINTF_NOPREFIX)) {
- if (__is_threaded) {
- /* XXX somewhat rude 'knowing' that pthread_t is a pointer */
- _simple_dprintf(malloc_debug_file, "%s(%d,%p) malloc: ", getprogname(), getpid(), (void *)pthread_self());
- } else {
- _simple_dprintf(malloc_debug_file, "%s(%d) malloc: ", getprogname(), getpid());
- }
- }
- _simple_vdprintf(malloc_debug_file, format, ap);
- return;
- }
- if (!(flags & MALLOC_PRINTF_NOPREFIX)) {
- if (__is_threaded) {
- /* XXX somewhat rude 'knowing' that pthread_t is a pointer */
- _simple_sprintf(b, "%s(%d,%p) malloc: ", getprogname(), getpid(), (void *)pthread_self());
- } else {
- _simple_sprintf(b, "%s(%d) malloc: ", getprogname(), getpid());
- }
- }
- _simple_vsprintf(b, format, ap);
- _simple_put(b, malloc_debug_file);
- _simple_asl_log(flags & MALLOC_PRINTF_LEVEL_MASK, Malloc_Facility, _simple_string(b));
- _simple_sfree(b);
-}
-
-__private_extern__ void
-_malloc_printf(int flags, const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- _malloc_vprintf(flags, format, ap);
- va_end(ap);
-}
-
-void
-malloc_printf(const char *format, ...)
-{
- va_list ap;
-
- va_start(ap, format);
- _malloc_vprintf(ASL_LEVEL_ERR, format, ap);
- va_end(ap);
-}
-
-/********* Generic ANSI callouts ************/
-
-void *
-malloc(size_t size) {
- void *retval;
- retval = malloc_zone_malloc(inline_malloc_default_zone(), size);
- if (retval == NULL) {
- errno = ENOMEM;
- }
- return retval;
-}
-
-void *
-calloc(size_t num_items, size_t size) {
- void *retval;
- retval = malloc_zone_calloc(inline_malloc_default_zone(), num_items, size);
- if (retval == NULL) {
- errno = ENOMEM;
- }
- return retval;
-}
-
-void
-free(void *ptr) {
- malloc_zone_t *zone;
- size_t size;
- if (!ptr)
- return;
- zone = find_registered_zone(ptr, &size);
- if (!zone) {
- malloc_printf("*** error for object %p: pointer being freed was not allocated\n"
- "*** set a breakpoint in malloc_error_break to debug\n", ptr);
- malloc_error_break();
- if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION|SCALABLE_MALLOC_ABORT_ON_ERROR))) {
- _SIMPLE_STRING b = _simple_salloc();
- if (b) {
- _simple_sprintf(b, "*** error for object %p: pointer being freed was not allocated\n", ptr);
- CRSetCrashLogMessage(_simple_string(b));
- } else {
- CRSetCrashLogMessage("*** error: pointer being freed was not allocated\n");
- }
- abort();
- }
- } else if (zone->version >= 6 && zone->free_definite_size)
- malloc_zone_free_definite_size(zone, ptr, size);
- else
- malloc_zone_free(zone, ptr);
-}
-
-void *
-realloc(void *in_ptr, size_t new_size) {
- void *retval = NULL;
- void *old_ptr;
- malloc_zone_t *zone;
- size_t old_size = 0;
-
- // SUSv3: "If size is 0 and ptr is not a null pointer, the object
- // pointed to is freed. If the space cannot be allocated, the object
- // shall remain unchanged." Also "If size is 0, either a null pointer
- // or a unique pointer that can be successfully passed to free() shall
- // be returned." We choose to allocate a minimum size object by calling
- // malloc_zone_malloc with zero size, which matches "If ptr is a null
- // pointer, realloc() shall be equivalent to malloc() for the specified
- // size." So we only free the original memory if the allocation succeeds.
- old_ptr = (new_size == 0) ? NULL : in_ptr;
- if (!old_ptr) {
- retval = malloc_zone_malloc(inline_malloc_default_zone(), new_size);
- } else {
- zone = find_registered_zone(old_ptr, &old_size);
- if (!zone) {
- malloc_printf("*** error for object %p: pointer being realloc'd was not allocated\n"
- "*** set a breakpoint in malloc_error_break to debug\n", old_ptr);
- malloc_error_break();
- if ((malloc_debug_flags & (SCALABLE_MALLOC_ABORT_ON_CORRUPTION|SCALABLE_MALLOC_ABORT_ON_ERROR))) {
- _SIMPLE_STRING b = _simple_salloc();
- if (b) {
- _simple_sprintf(b, "*** error for object %p: pointer being realloc'd was not allocated\n", old_ptr);
- CRSetCrashLogMessage(_simple_string(b));
- } else {
- CRSetCrashLogMessage("*** error: pointer being realloc'd was not allocated\n");
- }
- abort();
- }
- } else {
- retval = malloc_zone_realloc(zone, old_ptr, new_size);
- }
- }
- if (retval == NULL) {
- errno = ENOMEM;
- } else if (new_size == 0) {
- free(in_ptr);
- }
- return retval;
-}
-
-void *
-valloc(size_t size) {
- void *retval;
- malloc_zone_t *zone = inline_malloc_default_zone();
- retval = malloc_zone_valloc(zone, size);
- if (retval == NULL) {
- errno = ENOMEM;
- }
- return retval;
-}
-
-extern void
-vfree(void *ptr) {
- free(ptr);
-}
-
-size_t
-malloc_size(const void *ptr) {
- size_t size = 0;
-
- if (!ptr)
- return size;
-
- (void)find_registered_zone(ptr, &size);
- return size;
-}
-
-size_t
-malloc_good_size (size_t size) {
- malloc_zone_t *zone = inline_malloc_default_zone();
- return zone->introspect->good_size(zone, size);
-}
-
-/*
- * The posix_memalign() function shall allocate size bytes aligned on a boundary specified by alignment,
- * and shall return a pointer to the allocated memory in memptr.
- * The value of alignment shall be a multiple of sizeof( void *), that is also a power of two.
- * Upon successful completion, the value pointed to by memptr shall be a multiple of alignment.
- *
- * Upon successful completion, posix_memalign() shall return zero; otherwise,
- * an error number shall be returned to indicate the error.
- *
- * The posix_memalign() function shall fail if:
- * EINVAL
- * The value of the alignment parameter is not a power of two multiple of sizeof( void *).
- * ENOMEM
- * There is insufficient memory available with the requested alignment.
- */
-
-int
-posix_memalign(void **memptr, size_t alignment, size_t size)
-{
- void *retval;
-
- /* POSIX is silent on NULL == memptr !?! */
-
- retval = malloc_zone_memalign(inline_malloc_default_zone(), alignment, size);
- if (retval == NULL) {
- // To avoid testing the alignment constraints redundantly, we'll rely on the
- // test made in malloc_zone_memalign to vet each request. Only if that test fails
- // and returns NULL, do we arrive here to detect the bogus alignment and give the
- // required EINVAL return.
- if (alignment < sizeof( void *) || // excludes 0 == alignment
- 0 != (alignment & (alignment - 1))) { // relies on sizeof(void *) being a power of two.
- return EINVAL;
- }
- return ENOMEM;
- } else {
- *memptr = retval; // Set iff allocation succeeded
- return 0;
- }
-}
-
-static malloc_zone_t *
-find_registered_purgeable_zone(void *ptr) {
- if (!ptr)
- return NULL;
-
- /*
- * Look for a zone which contains ptr. If that zone does not have the purgeable malloc flag
- * set, or the allocation is too small, do nothing. Otherwise, set the allocation volatile.
- * FIXME: for performance reasons, we should probably keep a separate list of purgeable zones
- * and only search those.
- */
- size_t size = 0;
- malloc_zone_t *zone = find_registered_zone(ptr, &size);
-
- /* FIXME: would really like a zone->introspect->flags->purgeable check, but haven't determined
- * binary compatibility impact of changing the introspect struct yet. */
- if (!zone)
- return NULL;
-
- /* Check to make sure pointer is page aligned and size is multiple of page size */
- if ((size < vm_page_size) || ((size % vm_page_size) != 0))
- return NULL;
-
- return zone;
-}
-
-void
-malloc_make_purgeable(void *ptr) {
- malloc_zone_t *zone = find_registered_purgeable_zone(ptr);
- if (!zone)
- return;
-
- int state = VM_PURGABLE_VOLATILE;
- vm_purgable_control(mach_task_self(), (vm_address_t)ptr, VM_PURGABLE_SET_STATE, &state);
- return;
-}
-
-/* Returns true if ptr is valid. Ignore the return value from vm_purgeable_control and only report
- * state. */
-int
-malloc_make_nonpurgeable(void *ptr) {
- malloc_zone_t *zone = find_registered_purgeable_zone(ptr);
- if (!zone)
- return 0;
-
- int state = VM_PURGABLE_NONVOLATILE;
- vm_purgable_control(mach_task_self(), (vm_address_t)ptr, VM_PURGABLE_SET_STATE, &state);
-
- if (state == VM_PURGABLE_EMPTY)
- return EFAULT;
-
- return 0;
-}
-
-size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal)
-{
- if (!zone) {
- unsigned index = 0;
- size_t total = 0;
-
- // Take lock to defend against malloc_destroy_zone()
- MALLOC_LOCK();
- while (index < malloc_num_zones) {
- zone = malloc_zones[index++];
- if (zone->version < 8)
- continue;
- if (NULL == zone->pressure_relief)
- continue;
- if (0 == goal) /* Greedy */
- total += zone->pressure_relief(zone, 0);
- else if (goal > total)
- total += zone->pressure_relief(zone, goal - total);
- else /* total >= goal */
- break;
- }
- MALLOC_UNLOCK();
- return total;
- } else {
- // Assumes zone is not destroyed for the duration of this call
- if (zone->version < 8)
- return 0;
- if (NULL == zone->pressure_relief)
- return 0;
- return zone->pressure_relief(zone, goal);
- }
-}
-
-/********* Batch methods ************/
-
-unsigned
-malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested) {
- unsigned (*batch_malloc)(malloc_zone_t *, size_t, void **, unsigned) = zone-> batch_malloc;
- if (! batch_malloc)
- return 0;
- if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
- internal_check();
- }
- unsigned batched = batch_malloc(zone, size, results, num_requested);
- if (malloc_logger) {
- unsigned index = 0;
- while (index < batched) {
- malloc_logger(MALLOC_LOG_TYPE_ALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)size, 0, (uintptr_t)results[index], 0);
- index++;
- }
- }
- return batched;
-}
-
-void
-malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num) {
- if (malloc_check_start && (malloc_check_counter++ >= malloc_check_start)) {
- internal_check();
- }
- if (malloc_logger) {
- unsigned index = 0;
- while (index < num) {
- malloc_logger(MALLOC_LOG_TYPE_DEALLOCATE | MALLOC_LOG_TYPE_HAS_ZONE, (uintptr_t)zone, (uintptr_t)to_be_freed[index], 0, 0, 0);
- index++;
- }
- }
- void (*batch_free)(malloc_zone_t *, void **, unsigned) = zone-> batch_free;
- if (batch_free) {
- batch_free(zone, to_be_freed, num);
- } else {
- void (*free_fun)(malloc_zone_t *, void *) = zone->free;
- while (num--) {
- void *ptr = *to_be_freed++;
- free_fun(zone, ptr);
- }
- }
-}
-
-/********* Functions for performance tools ************/
-
-static kern_return_t
-_malloc_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) {
- *ptr = (void *)address;
- return 0;
-}
-
-kern_return_t
-malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count) {
- // Note that the 2 following addresses are not correct if the address of the target is different from your own. This notably occurs if the address of System.framework is slid (e.g. different than at B & I )
- vm_address_t remote_malloc_zones = (vm_address_t)&malloc_zones;
- vm_address_t remote_malloc_num_zones = (vm_address_t)&malloc_num_zones;
- kern_return_t err;
- vm_address_t zones_address;
- vm_address_t *zones_address_ref;
- unsigned num_zones;
- unsigned *num_zones_ref;
- if (!reader) reader = _malloc_default_reader;
- // printf("Read malloc_zones at address %p should be %p\n", &malloc_zones, malloc_zones);
- err = reader(task, remote_malloc_zones, sizeof(void *), (void **)&zones_address_ref);
- // printf("Read malloc_zones[%p]=%p\n", remote_malloc_zones, *zones_address_ref);
- if (err) {
- malloc_printf("*** malloc_get_all_zones: error reading zones_address at %p\n", (unsigned)remote_malloc_zones);
- return err;
- }
- zones_address = *zones_address_ref;
- // printf("Reading num_zones at address %p\n", remote_malloc_num_zones);
- err = reader(task, remote_malloc_num_zones, sizeof(unsigned), (void **)&num_zones_ref);
- if (err) {
- malloc_printf("*** malloc_get_all_zones: error reading num_zones at %p\n", (unsigned)remote_malloc_num_zones);
- return err;
- }
- num_zones = *num_zones_ref;
- // printf("Read malloc_num_zones[%p]=%d\n", remote_malloc_num_zones, num_zones);
- *count = num_zones;
- // printf("malloc_get_all_zones succesfully found %d zones\n", num_zones);
- err = reader(task, zones_address, sizeof(malloc_zone_t *) * num_zones, (void **)addresses);
- if (err) {
- malloc_printf("*** malloc_get_all_zones: error reading zones at %p\n", &zones_address);
- return err;
- }
- // printf("malloc_get_all_zones succesfully read %d zones\n", num_zones);
- return err;
-}
-
-/********* Debug helpers ************/
-
-void
-malloc_zone_print_ptr_info(void *ptr) {
- malloc_zone_t *zone;
- if (!ptr) return;
- zone = malloc_zone_from_ptr(ptr);
- if (zone) {
- printf("ptr %p in registered zone %p\n", ptr, zone);
- } else {
- printf("ptr %p not in heap\n", ptr);
- }
-}
-
-boolean_t
-malloc_zone_check(malloc_zone_t *zone) {
- boolean_t ok = 1;
- if (!zone) {
- unsigned index = 0;
- while (index < malloc_num_zones) {
- zone = malloc_zones[index++];
- if (!zone->introspect->check(zone)) ok = 0;
- }
- } else {
- ok = zone->introspect->check(zone);
- }
- return ok;
-}
-
-void
-malloc_zone_print(malloc_zone_t *zone, boolean_t verbose) {
- if (!zone) {
- unsigned index = 0;
- while (index < malloc_num_zones) {
- zone = malloc_zones[index++];
- zone->introspect->print(zone, verbose);
- }
- } else {
- zone->introspect->print(zone, verbose);
- }
-}
-
-void
-malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats) {
- if (!zone) {
- memset(stats, 0, sizeof(*stats));
- unsigned index = 0;
- while (index < malloc_num_zones) {
- zone = malloc_zones[index++];
- malloc_statistics_t this_stats;
- zone->introspect->statistics(zone, &this_stats);
- stats->blocks_in_use += this_stats.blocks_in_use;
- stats->size_in_use += this_stats.size_in_use;
- stats->max_size_in_use += this_stats.max_size_in_use;
- stats->size_allocated += this_stats.size_allocated;
- }
- } else {
- zone->introspect->statistics(zone, stats);
- }
-}
-
-void
-malloc_zone_log(malloc_zone_t *zone, void *address) {
- if (!zone) {
- unsigned index = 0;
- while (index < malloc_num_zones) {
- zone = malloc_zones[index++];
- zone->introspect->log(zone, address);
- }
- } else {
- zone->introspect->log(zone, address);
- }
-}
-
-/********* Misc other entry points ************/
-
-static void
-DefaultMallocError(int x) {
-#if USE_SLEEP_RATHER_THAN_ABORT
- malloc_printf("*** error %d\n", x);
- sleep(3600);
-#else
- _SIMPLE_STRING b = _simple_salloc();
- if (b) {
- _simple_sprintf(b, "*** error %d", x);
- malloc_printf("%s\n", _simple_string(b));
- CRSetCrashLogMessage(_simple_string(b));
- } else {
- _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error %d", x);
- CRSetCrashLogMessage("*** DefaultMallocError called");
- }
- abort();
-#endif
-}
-
-void (*
-malloc_error(void (*func)(int)))(int) {
- return DefaultMallocError;
-}
-
-/* Stack logging fork-handling prototypes */
-extern void __stack_logging_fork_prepare();
-extern void __stack_logging_fork_parent();
-extern void __stack_logging_fork_child();
-extern void __stack_logging_early_finished();
-
-void
-_malloc_fork_prepare() {
- /* Prepare the malloc module for a fork by insuring that no thread is in a malloc critical section */
- unsigned index = 0;
- MALLOC_LOCK();
- while (index < malloc_num_zones) {
- malloc_zone_t *zone = malloc_zones[index++];
- zone->introspect->force_lock(zone);
- }
- __stack_logging_fork_prepare();
-}
-
-void
-_malloc_fork_parent() {
- /* Called in the parent process after a fork() to resume normal operation. */
- unsigned index = 0;
- __stack_logging_fork_parent();
- MALLOC_UNLOCK();
- while (index < malloc_num_zones) {
- malloc_zone_t *zone = malloc_zones[index++];
- zone->introspect->force_unlock(zone);
- }
-}
-
-void
-_malloc_fork_child() {
- /* Called in the child process after a fork() to resume normal operation. In the MTASK case we also have to change memory inheritance so that the child does not share memory with the parent. */
- unsigned index = 0;
- __stack_logging_fork_child();
- MALLOC_UNLOCK();
- while (index < malloc_num_zones) {
- malloc_zone_t *zone = malloc_zones[index++];
- zone->introspect->force_unlock(zone);
- }
-}
-
-/*
- * A Glibc-like mstats() interface.
- *
- * Note that this interface really isn't very good, as it doesn't understand
- * that we may have multiple allocators running at once. We just massage
- * the result from malloc_zone_statistics in any case.
- */
-struct mstats
-mstats(void)
-{
- malloc_statistics_t s;
- struct mstats m;
-
- malloc_zone_statistics(NULL, &s);
- m.bytes_total = s.size_allocated;
- m.chunks_used = s.blocks_in_use;
- m.bytes_used = s.size_in_use;
- m.chunks_free = 0;
- m.bytes_free = m.bytes_total - m.bytes_used; /* isn't this somewhat obvious? */
-
- return(m);
-}
-
-boolean_t
-malloc_zone_enable_discharge_checking(malloc_zone_t *zone)
-{
- if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields.
- return FALSE;
- if (NULL == zone->introspect->enable_discharge_checking)
- return FALSE;
- return zone->introspect->enable_discharge_checking(zone);
-}
-
-void
-malloc_zone_disable_discharge_checking(malloc_zone_t *zone)
-{
- if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields.
- return;
- if (NULL == zone->introspect->disable_discharge_checking)
- return;
- zone->introspect->disable_discharge_checking(zone);
-}
-
-void
-malloc_zone_discharge(malloc_zone_t *zone, void *memory)
-{
- if (NULL == zone)
- zone = malloc_zone_from_ptr(memory);
- if (NULL == zone)
- return;
- if (zone->version < 7) // Version must be >= 7 to look at the new discharge checking fields.
- return;
- if (NULL == zone->introspect->discharge)
- return;
- zone->introspect->discharge(zone, memory);
-}
-
-void
-malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info))
-{
- if (!zone) {
- unsigned index = 0;
- while (index < malloc_num_zones) {
- zone = malloc_zones[index++];
- if (zone->version < 7)
- continue;
- if (NULL == zone->introspect->enumerate_discharged_pointers)
- continue;
- zone->introspect->enumerate_discharged_pointers(zone, report_discharged);
- }
- } else {
- if (zone->version < 7)
- return;
- if (NULL == zone->introspect->enumerate_discharged_pointers)
- return;
- zone->introspect->enumerate_discharged_pointers(zone, report_discharged);
- }
-}
-
-/***************** OBSOLETE ENTRY POINTS ********************/
-
-#if PHASE_OUT_OLD_MALLOC
-#error PHASE OUT THE FOLLOWING FUNCTIONS
-#else
-#warning PHASE OUT THE FOLLOWING FUNCTIONS
-#endif
-
-void
-set_malloc_singlethreaded(boolean_t single) {
- static boolean_t warned = 0;
- if (!warned) {
-#if PHASE_OUT_OLD_MALLOC
- malloc_printf("*** OBSOLETE: set_malloc_singlethreaded(%d)\n", single);
-#endif
- warned = 1;
- }
-}
-
-void
-malloc_singlethreaded() {
- static boolean_t warned = 0;
- if (!warned) {
- malloc_printf("*** OBSOLETE: malloc_singlethreaded()\n");
- warned = 1;
- }
-}
-
-int
-malloc_debug(int level) {
- malloc_printf("*** OBSOLETE: malloc_debug()\n");
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#import <stdarg.h>
-
-extern void malloc_printf(const char *fmt, ...);
-
-#define MALLOC_PRINTF_LEVEL_MASK 0x0f
-#define MALLOC_PRINTF_NOLOG 0x10
-#define MALLOC_PRINTF_NOPREFIX 0x20
-
-extern void _malloc_printf(int flags, const char *fmt, ...);
-extern void _malloc_vprintf(int flags, const char *fmt, va_list ap);
+++ /dev/null
-.\" Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
-.\"
-.\" @APPLE_LICENSE_HEADER_START@
-.\"
-.\" The contents of this file constitute Original Code as defined in and
-.\" are subject to the Apple Public Source License Version 1.1 (the
-.\" "License"). You may not use this file except in compliance with the
-.\" License. Please obtain a copy of the License at
-.\" http://www.apple.com/publicsource and read it before using this file.
-.\"
-.\" This Original Code and all software distributed under the License are
-.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
-.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
-.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
-.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
-.\" License for the specific language governing rights and limitations
-.\" under the License.
-.\"
-.\" @APPLE_LICENSE_HEADER_END@
-.\"
-.Dd May 23, 2006
-.Dt MALLOC_SIZE 3
-.Os
-.Sh NAME
-.Nm malloc_good_size ,
-.Nm malloc_size
-.Nd memory allocation information
-.Sh SYNOPSIS
-.In malloc/malloc.h
-.Ft size_t
-.Fo malloc_good_size
-.Fa "size_t size"
-.Fc
-.Ft size_t
-.Fo malloc_size
-.Fa "const void *ptr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn malloc_size
-function returns the size of the memory block
-that backs the allocation pointed to by
-.Fa ptr .
-The memory block size is always at least as large
-as the allocation it backs, and may be larger.
-.Pp
-The
-.Fn malloc_good_size
-function rounds
-.Fa size
-up to a value that the allocator implementation can allocate
-without adding any padding;
-it then returns that rounded-up value.
-.Sh SEE ALSO
-.Xr malloc 3
+++ /dev/null
-.\" Copyright (c) 2008 Apple, Inc. All rights reserved.
-.\"
-.\" @APPLE_LICENSE_HEADER_START@
-.\"
-.\" The contents of this file constitute Original Code as defined in and
-.\" are subject to the Apple Public Source License Version 1.1 (the
-.\" "License"). You may not use this file except in compliance with the
-.\" License. Please obtain a copy of the License at
-.\" http://www.apple.com/publicsource and read it before using this file.
-.\"
-.\" This Original Code and all software distributed under the License are
-.\" distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
-.\" EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
-.\" INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
-.\" FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
-.\" License for the specific language governing rights and limitations
-.\" under the License.
-.\"
-.\" @APPLE_LICENSE_HEADER_END@
-.\"
-.Dd Aug 13, 2008
-.Dt MALLOC_ZONE_MALLOC 3
-.Os
-.Sh NAME
-.Nm malloc_create_zone ,
-.Nm malloc_destroy_zone ,
-.Nm malloc_default_zone ,
-.Nm malloc_zone_from_ptr ,
-.Nm malloc_zone_malloc ,
-.Nm malloc_zone_calloc ,
-.Nm malloc_zone_valloc ,
-.Nm malloc_zone_realloc ,
-.Nm malloc_zone_memalign ,
-.Nm malloc_zone_free
-.Nd zone-based memory allocation
-.Sh SYNOPSIS
-.In malloc/malloc.h
-.Ft malloc_zone_t *
-.Fo malloc_create_zone
-.Fa "vm_size_t start_size"
-.Fa "unsigned flags"
-.Fc
-.Ft void
-.Fo malloc_destroy_zone
-.Fa "malloc_zone_t *zone"
-.Fc
-.Ft malloc_zone_t *
-.Fo malloc_default_zone
-.Fa void
-.Fc
-.Ft malloc_zone_t *
-.Fo malloc_zone_from_ptr
-.Fa "const void *ptr"
-.Fc
-.Ft void *
-.Fo malloc_zone_malloc
-.Fa "malloc_zone_t *zone"
-.Fa "size_t size"
-.Fc
-.Ft void *
-.Fo malloc_zone_calloc
-.Fa "malloc_zone_t *zone"
-.Fa "size_t num_items"
-.Fa "size_t size"
-.Fc
-.Ft void *
-.Fo malloc_zone_valloc
-.Fa "malloc_zone_t *zone"
-.Fa "size_t size"
-.Fc
-.Ft void *
-.Fo malloc_zone_realloc
-.Fa "malloc_zone_t *zone"
-.Fa "void *ptr"
-.Fa "size_t size"
-.Fc
-.Ft void *
-.Fo malloc_zone_memalign
-.Fa "malloc_zone_t *zone"
-.Fa "size_t alignment"
-.Fa "size_t size"
-.Fc
-.Ft void
-.Fo malloc_zone_free
-.Fa "malloc_zone_t *zone"
-.Fa "void *ptr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn malloc_create_zone
-function creates a malloc zone, advising an initial allocation of
-.Fa start_size
-bytes, and specifying
-.Fa flags
-The returned malloc zone can be used to provide custom allocation and
-deallocation behavior, and to retrieve additional information about the
-allocations in that zone.
-At present there are no client settable flag values recognized by malloc_create_zone(),
-the flags argument should always be passed as zero.
-.Pp
-The
-.Fn malloc_destroy_zone
-function deallocates all memory associated with objects in
-.Fa zone
-as well as
-.Fa zone
-itself.
-.Pp
-The
-.Fn malloc_default_zone
-function returns the default system malloc zone, used by
-.Xr malloc 3 ,
-and
-.Xr free 3 .
-.Pp
-The
-.Fn malloc_zone_from_ptr
-function returns a pointer to the malloc zone which contains
-.Fa ptr
-or NULL, if the pointer does not point to an allocated object in any current
-malloc zone.
-.Pp
-The
-.Fn malloc_zone_malloc ,
-.Fn malloc_zone_calloc ,
-.Fn malloc_zone_valloc ,
-.Fn malloc_zone_realloc ,
-.Fn malloc_zone_memalign ,
-and
-.Fn malloc_zone_free
-perform the same task on
-.Fa zone
-as their non-prefixed variants,
-.Xr malloc 3 ,
-.Xr calloc 3 ,
-.Xr valloc 3 ,
-.Xr realloc 3 ,
-.Xr posix_memalign 3 ,
-and
-.Xr free 3 perform on the default system malloc zone.
-.Sh RETURN VALUES
-The
-.Fn malloc_create_zone ,
-.Fn malloc_default_zone ,
-and
-.Fn malloc_zone_from_ptr
-functions return a pointer to a malloc_zone_t structure, or NULL if there was
-an error.
-.Pp
-The
-.Fn malloc_zone_malloc ,
-.Fn malloc_zone_calloc ,
-.Fn malloc_zone_valloc ,
-.Fn malloc_zone_realloc ,
-and
-.Fn malloc_zone_memalign
-functions return a pointer to allocated memory. If there is an error, they
-return a NULL pointer. They are not required to set
-.Va errno .
-.El
-.Sh SEE ALSO
-.Xr malloc 3 ,
-.Xr posix_memalign 3
#include <mach/mach_error.h>
#include <mach/mach_time.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-
+#include <TargetConditionals.h>
#if __DARWIN_UNIX03
-#include "pthread_internals.h"
#include <mach/clock.h>
+#include <pthread.h>
+#include <mach/mach.h>
+#include <mach/mach_error.h>
-#ifndef BUILDING_VARIANT
+#if !defined(BUILDING_VARIANT) && !TARGET_IPHONE_SIMULATOR
semaphore_t clock_sem = MACH_PORT_NULL;
mach_port_t clock_port = MACH_PORT_NULL;
-void _init_clock_port() {
+void _init_clock_port(void);
+
+void _init_clock_port(void) {
kern_return_t kr;
mach_port_t host = mach_host_self();
extern int __unix_conforming;
#ifdef VARIANT_CANCELABLE
-extern void _pthread_testcancel(pthread_t thread, int isconforming);
extern int __semwait_signal(int cond_sem, int mutex_sem, int timeout, int relative, __int64_t tv_sec, __int32_t tv_nsec);
#define SEMWAIT_SIGNAL __semwait_signal
#else /* !VARIANT_CANCELABLE */
__unix_conforming = 1;
#ifdef VARIANT_CANCELABLE
- _pthread_testcancel(pthread_self(), 1);
+ pthread_testcancel();
#endif /* VARIANT_CANCELABLE */
if ((requested_time == NULL) || (requested_time->tv_sec < 0) || (requested_time->tv_nsec >= NSEC_PER_SEC)) {
* answer from the lesser side. So if our estimate is too large
* we need to decrease it until it is smaller.
*/
- while(backmul.high > temp.high || backmul.high == temp.high && backmul.low > temp.low) {
+ while(backmul.high > temp.high || (backmul.high == temp.high && backmul.low > temp.low)) {
sub128_128(&backmul, &divisor128);
uapprox--;
}
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#if defined(__i386__) || defined(__x86_64__)
-
-#include <stdlib.h>
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-#define PLAT_CAP_MASK (kHasMMX | kHasSSE | kHasSSE2 | kHasSSE3 | kCache32 | kCache64 | kCache128 | kFastThreadLocalStorage | kHasSupplementalSSE3 | k64Bit | kHasSSE4_1 | kHasSSE4_2 | kHasAES | kInOrderPipeline | kSlow | kUP)
-
-inline static int __get_cpu_capabilities() {
- return *((int32_t*)_COMM_PAGE_CPU_CAPABILITIES);
-}
-
-inline static int num_cpus(int capabilities) {
- return (capabilities & kNumCPUs) >> kNumCPUsShift;
-}
-
-/* TODO: If 8151810 is fixed (or full support for visibility("internal") is added), change this to visibility("internal") */
-void __attribute__((visibility("hidden"))) *find_platform_function(const platfunc_descriptor *descriptors[]) {
- int cap = __get_cpu_capabilities(),
- have_cpus = num_cpus(cap);
-
- for (int i = 0; descriptors[i] != 0; i++) {
- int musthave_cpus = num_cpus(descriptors[i]->musthave),
- canthave_cpus = num_cpus(descriptors[i]->canthave);
- uint32_t musthave = descriptors[i]->musthave & PLAT_CAP_MASK,
- canthave = descriptors[i]->canthave & PLAT_CAP_MASK;
- /* First check that the CPU supports all the features that are in musthave */
- if ((musthave & cap) != musthave)
- continue;
- /* Now check that the CPU doesn't have any of the features that are in canthave */
- if ((canthave & cap) != 0)
- continue;
- /* Special case check for the number of CPUs. */
- /* TODO: Should there be a way to specify < or > num cpus? */
- if (musthave_cpus != 0 && have_cpus != musthave_cpus)
- continue;
- if (canthave_cpus != 0 && have_cpus == canthave_cpus)
- continue;
- /* otherwise, we have found our preferred implementation */
- return descriptors[i]->address;
- }
-
- /* We didn't find an acceptable implementation. (bug in data structures!) */
- return NULL;
-}
-
-#endif
+++ /dev/null
-/*
- * Copyright (c) 2003-2010 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#if defined(__i386__) || defined(__x86_64__)
-
-#ifndef _I386_PLATFUNC_H
-#define _I386_PLATFUNC_H
-
-#ifndef __ASSEMBLER__
-#include <stdint.h>
-#endif /* __ASSEMBLER__ */
-
-// This is a shared macro which calls PLATFUNC_VARIANT_NAME which has different
-// implementations in __ASSEMBLER__ and !__ASSEMBLER__
-#define PLATFUNC_DESCRIPTOR_NAME(name, variant) \
- PLATFUNC_VARIANT_NAME(platfunc_ ## name, variant)
-
-#ifdef __ASSEMBLER__
-
-/* When trying to acquire a spinlock or mutex, we will spin in
- * user mode for awhile, before entering the kernel to relinquish.
- * MP_SPIN_TRIES is the initial value of _COMM_PAGE_SPIN_COUNT.
- * The idea is that _COMM_PAGE_SPIN_COUNT will be adjusted up or
- * down as the machine is plugged in/out, etc.
- * At present spinlocks do not use _COMM_PAGE_SPIN_COUNT.
- * They use MP_SPIN_TRIES directly.
- */
-#define MP_SPIN_TRIES 1000
-
-#define PLATFUNC_VARIANT_NAME(name, variant) _ ## name ## $VARIANT$ ## variant
-
-#if defined (__i386__)
-#define PLATFUNC_DESCRIPTOR_FIELD_POINTER .long
-#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) \
- .long PLATFUNC_DESCRIPTOR_NAME(name, variant)
-#elif defined (__x86_64__)
-#define PLATFUNC_DESCRIPTOR_FIELD_POINTER .quad
-#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) \
- .quad PLATFUNC_DESCRIPTOR_NAME(name, variant)
-#else
-#error unsupported architecture
-#endif
-
-#ifdef VARIANT_DYLD
-
-#define PLATFUNC_FUNCTION_START_GENERIC(name, variant, codetype, alignment) \
- PLATFUNC_FUNCTION_START(name, variant, codetype, alignment) \
- .globl _ ## name ;\
- _ ## name ## :
-
-#define PLATFUNC_DESCRIPTOR(name, variant, must, cant)
-
-#else /* VARIANT_DYLD */
-
-#define PLATFUNC_FUNCTION_START_GENERIC PLATFUNC_FUNCTION_START
-
-#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) \
- .const_data ;\
- .private_extern PLATFUNC_DESCRIPTOR_NAME(name, variant) ;\
- PLATFUNC_DESCRIPTOR_NAME(name, variant) ## : ;\
- PLATFUNC_DESCRIPTOR_FIELD_POINTER PLATFUNC_VARIANT_NAME(name, variant) ;\
- .long must ;\
- .long cant ;\
- .text
-
-#endif /* VARIANT_DYLD */
-
-#define PLATFUNC_FUNCTION_START(name, variant, codetype, alignment) \
- .text ;\
- .align alignment, 0x90 ;\
- .private_extern PLATFUNC_VARIANT_NAME(name, variant) ;\
- PLATFUNC_VARIANT_NAME(name, variant) ## :
-
-#else /* __ASSEMBLER__ */
-
-#define PLATFUNC_VARIANT_NAME(name, variant) name ## $VARIANT$ ## variant
-#define PLATFUNC_DESCRIPTOR_PROTOTYPE(name, variant) extern const platfunc_descriptor PLATFUNC_DESCRIPTOR_NAME(name, variant);
-#define PLATFUNC_DESCRIPTOR_REFERENCE(name, variant) &PLATFUNC_DESCRIPTOR_NAME(name, variant)
-
-#define PLATFUNC_DESCRIPTOR(name, variant, must, cant) \
- extern void PLATFUNC_VARIANT_NAME(name, variant) (void); \
- const platfunc_descriptor PLATFUNC_DESCRIPTOR_NAME(name, variant) = { \
- .address = PLATFUNC_VARIANT_NAME(name, variant), \
- .musthave = must, \
- .canthave = cant \
- }
-
-/*
- * Each potential platfunc routine is described by one of these.
- * Note that the PLATFUNC_DESCRIPTOR macro (above), used in
- * assembly language, must agree with this.
- */
-
-typedef struct platfunc_descriptor {
- void *address; // address of code
- uint32_t musthave; // _cpu_capability bits we must have
- uint32_t canthave; // _cpu_capability bits we can't have
-} platfunc_descriptor;
-
-void *find_platform_function(const platfunc_descriptor *descriptors[]);
-
-#endif /* __ASSEMBLER__ */
-
-#endif /* _I386_PLATFUNC_H */
-
-#endif /* __i386__ || __x86_64__ */
+++ /dev/null
-/*
- * Copyright (c) 1999, 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/* Author: Bertrand Serlet, August 1999 */
-
-#include "scalable_malloc.h"
-#include "malloc_printf.h"
-#include "_simple.h"
-
-#include <pthread_internals.h>
-
-#include <unistd.h>
-#include <libc.h>
-#include <mach/vm_statistics.h>
-#include <mach/mach_init.h>
-#include <sys/types.h>
-#include <sys/mman.h>
-
-/********************* DEFINITIONS ************************/
-
-#define DEBUG_MALLOC 0 // set to one to debug malloc itself
-
-#define DEBUG_CLIENT 0 // set to one to help debug a nasty memory smasher
-
-#if DEBUG_MALLOC
-#warning DEBUG_MALLOC ENABLED
-# define INLINE
-# define ALWAYSINLINE
-# define CHECK_LOCKED(szone, fun) \
-do { \
- if (__is_threaded && TRY_LOCK(szone->lock)) { \
- malloc_printf("*** lock was not set %p in %s\n", szone->lock, fun); \
- } \
-} while (0)
-#else
-# define INLINE __inline__
-# define ALWAYSINLINE __attribute__((always_inline))
-# define CHECK_LOCKED(szone, fun) {}
-#endif
-
-/*
- * Access to global variables is slow, so optimise our handling of vm_page_size
- * and vm_page_shift.
- */
-#define _vm_page_size vm_page_size /* to get to the originals */
-#define _vm_page_shift vm_page_shift
-#define vm_page_size 4096 /* our normal working sizes */
-#define vm_page_shift 12
-
-typedef unsigned short msize_t; // a size in multiples of SHIFT_SMALL_QUANTUM or SHIFT_TINY_QUANTUM
-
-typedef union {
- void *p;
- uintptr_t u;
-} ptr_union;
-
-typedef struct {
- ptr_union previous;
- ptr_union next;
-} free_list_t;
-
-typedef struct {
- uintptr_t address_and_num_pages;
- // this type represents both an address and a number of pages
- // the low bits are the number of pages; the high bits are the address
- // note that the exact number of bits used for depends on the page size
- // also, this cannot represent pointers larger than 1 << (vm_page_shift * 2)
-} compact_range_t;
-
-typedef unsigned char grain_t;
-
-#define CHECK_REGIONS (1 << 31)
-
-#define MAX_RECORDER_BUFFER 256
-
-/********************* DEFINITIONS for tiny ************************/
-
-/*
- * Memory in the Tiny range is allocated from regions (heaps) pointed to by the szone's tiny_regions
- * pointer.
- *
- * Each region is laid out as a heap, followed by a header block, all within
- * a 1MB (2^20) block. This means there are 64520 16-byte blocks and the header is
- * 16138 bytes, making the total 1048458 bytes, leaving 118 bytes unused.
- * The header block is arranged:
- *
- * 0xfc080
- * header bits
- * 0xfe001
- * 0xffffffff pad word
- * 0xfe005
- * in-use bits
- * 0xfff86
- * pad word (not written)
- * 0xfff8a-0xfffff
- * unused
- *
- * Each bitfield comprises NUM_TINY_BLOCKS bits, and refers to the corresponding TINY_QUANTUM block
- * within the heap.
- *
- * The bitfields are used to encode the state of memory within the heap. The header bit indicates
- * that the corresponding quantum is the first quantum in a block (either in use or free). The
- * in-use bit is set for the header if the block has been handed out (allocated). If the header
- * bit is not set, the in-use bit is invalid.
- *
- * The szone maintains an array of 32 freelists, each of which is used to hold
- * free objects of the corresponding quantum size.
- *
- * A free block is laid out depending on its size, in order to fit all free
- * blocks in 16 bytes, on both 32 and 64 bit platforms. One quantum blocks do
- * not store their size in the block, instead relying on the header information
- * to determine their size. Blocks of two or more quanta have room to store
- * their size in the block, and store it both after the 'next' pointer, and in
- * the last 2 bytes of the block.
- *
- * 1-quantum block
- * Offset (32-bit mode) (64-bit mode)
- * 0x0 0x0 : previous
- * 0x4 0x08 : next
- * end end
- *
- * >1-quantum block
- * Offset (32-bit mode) (64-bit mode)
- * 0x0 0x0 : previous
- * 0x4 0x08 : next
- * 0x8 0x10 : size (in quantum counts)
- * end - 2 end - 2 : size (in quantum counts)
- * end end
- *
- * All fields are pointer-sized, except for the size which is an unsigned short.
- *
- */
-
-#define SHIFT_TINY_QUANTUM 4 // Required for AltiVec
-#define TINY_QUANTUM (1 << SHIFT_TINY_QUANTUM)
-
-#define FOLLOWING_TINY_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_TINY_QUANTUM))
-
-#define NUM_TINY_SLOTS 32 // number of slots for free-lists
-
-#define NUM_TINY_BLOCKS 64520
-#define SHIFT_TINY_CEIL_BLOCKS 16 // ceil(log2(NUM_TINY_BLOCKS))
-#define NUM_TINY_CEIL_BLOCKS (1 << SHIFT_TINY_CEIL_BLOCKS)
-#define TINY_BLOCKS_ALIGN (SHIFT_TINY_CEIL_BLOCKS + SHIFT_TINY_QUANTUM)
-
-/*
- * Enough room for the data, followed by the bit arrays (2-bits per block) plus 2 words of padding
- * as our bitmap operators overflow, plus rounding to the nearest page.
- */
-#define TINY_HEADER_SIZE ((NUM_TINY_BLOCKS >> 2) + 8)
-#define TINY_REGION_SIZE ((NUM_TINY_BLOCKS * TINY_QUANTUM + TINY_HEADER_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1))
-
-/*
- * Beginning and end pointers for a region's heap.
- */
-#define TINY_REGION_ADDRESS(region) ((void *)(region))
-#define TINY_REGION_END(region) (TINY_REGION_ADDRESS(region) + (NUM_TINY_BLOCKS * TINY_QUANTUM))
-
-/*
- * Locate the heap base for a pointer known to be within a tiny region.
- */
-#define TINY_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << TINY_BLOCKS_ALIGN) - 1)))
-
-/*
- * Convert between byte and msize units.
- */
-#define TINY_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_TINY_QUANTUM)
-#define TINY_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_TINY_QUANTUM)
-
-#ifdef __LP64__
-# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[8])
-#else
-# define TINY_FREE_SIZE(ptr) (((msize_t *)(ptr))[4])
-#endif
-#define TINY_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1]
-
-/*
- * Locate the block header for a pointer known to be within a tiny region.
- */
-#define TINY_HEADER_START (NUM_TINY_BLOCKS * TINY_QUANTUM)
-#define TINY_BLOCK_HEADER_FOR_PTR(_p) ((void *)((uintptr_t)TINY_REGION_FOR_PTR(_p) + TINY_HEADER_START))
-
-/*
- * Locate the inuse map for a given block header pointer.
- */
-#define TINY_INUSE_FOR_HEADER(_h) ((void *)((uintptr_t)(_h) + (NUM_TINY_BLOCKS >> 3) + 4))
-
-/*
- * Compute the bitmap index for a pointer known to be within a tiny region.
- */
-#define TINY_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_TINY_QUANTUM) & (NUM_TINY_CEIL_BLOCKS - 1))
-
-#define TINY_CACHE 1 // This governs a last-free cache of 1 that bypasses the free-list
-
-#if ! TINY_CACHE
-#warning TINY_CACHE turned off
-#endif
-
-/********************* DEFINITIONS for small ************************/
-
-/*
- * Memory in the Small range is allocated from regions (heaps) pointed to by the szone's small_regions
- * pointer.
- *
- * Each region is laid out as a heap, followed by the metadata array, all within an 8MB (2^23) block.
- * The array is arranged as an array of shorts, one for each SMALL_QUANTUM in the heap.
- * This means there are 16320 512-blocks and the array is 16320*2 bytes, which totals 8388480, leaving
- * 128 bytes unused.
- *
- * The MSB of each short is set for the first quantum in a free block. The low 15 bits encode the
- * block size (in SMALL_QUANTUM units), or are zero if the quantum is not the first in a block.
- *
- * The szone maintains an array of 32 freelists, each of which is used to hold free objects
- * of the corresponding quantum size.
- *
- * A free block is laid out as:
- *
- * Offset (32-bit mode) (64-bit mode)
- * 0x0 0x0 : previous
- * 0x4 0x08 : next
- * 0x8 0x10 : size (in quantum counts)
- * end - 2 end - 2 : size (in quantum counts)
- * end end
- *
- * All fields are pointer-sized, except for the size which is an unsigned short.
- *
- */
-
-#define SMALL_IS_FREE (1 << 15)
-
-#define SHIFT_SMALL_QUANTUM (SHIFT_TINY_QUANTUM + 5) // 9
-#define SMALL_QUANTUM (1 << SHIFT_SMALL_QUANTUM) // 512 bytes
-
-#define FOLLOWING_SMALL_PTR(ptr,msize) (((unsigned char *)(ptr)) + ((msize) << SHIFT_SMALL_QUANTUM))
-
-#define NUM_SMALL_SLOTS 32 // number of slots for free-lists
-
-/*
- * We can only represent up to 1<<15 for msize; but we choose to stay even below that to avoid the
- * convention msize=0 => msize = (1<<15)
- */
-#define NUM_SMALL_BLOCKS 16320
-#define SHIFT_SMALL_CEIL_BLOCKS 14 // ceil(log2(NUM_SMALL_BLOCKs))
-#define NUM_SMALL_CEIL_BLOCKS (1 << SHIFT_SMALL_CEIL_BLOCKS)
-#define SMALL_BLOCKS_ALIGN (SHIFT_SMALL_CEIL_BLOCKS + SHIFT_SMALL_QUANTUM) // 23
-#define SMALL_ARRAY_SIZE (NUM_SMALL_BLOCKS * 2)
-#define SMALL_REGION_SIZE ((NUM_SMALL_BLOCKS * SMALL_QUANTUM + SMALL_ARRAY_SIZE + vm_page_size - 1) & ~ (vm_page_size - 1)) // data + meta data
-
-#define SMALL_PREVIOUS_MSIZE(ptr) ((msize_t *)(ptr))[-1]
-
-/*
- * Convert between byte and msize units.
- */
-#define SMALL_BYTES_FOR_MSIZE(_m) ((_m) << SHIFT_SMALL_QUANTUM)
-#define SMALL_MSIZE_FOR_BYTES(_b) ((_b) >> SHIFT_SMALL_QUANTUM)
-
-
-#define SMALL_REGION_ADDRESS(region) ((unsigned char *)region)
-#define SMALL_REGION_END(region) (SMALL_REGION_ADDRESS(region) + (NUM_SMALL_BLOCKS * SMALL_QUANTUM))
-
-/*
- * Locate the heap base for a pointer known to be within a small region.
- */
-#define SMALL_REGION_FOR_PTR(_p) ((void *)((uintptr_t)(_p) & ~((1 << SMALL_BLOCKS_ALIGN) - 1)))
-
-/*
- * Locate the metadata base for a pointer known to be within a small region.
- */
-#define SMALL_HEADER_START (NUM_SMALL_BLOCKS * SMALL_QUANTUM)
-#define SMALL_META_HEADER_FOR_PTR(_p) ((msize_t *)((uintptr_t)SMALL_REGION_FOR_PTR(_p) + SMALL_HEADER_START))
-
-/*
- * Compute the metadata index for a pointer known to be within a small region.
- */
-#define SMALL_META_INDEX_FOR_PTR(_p) (((uintptr_t)(_p) >> SHIFT_SMALL_QUANTUM) & (NUM_SMALL_CEIL_BLOCKS - 1))
-
-/*
- * Find the metadata word for a pointer known to be within a small region.
- */
-#define SMALL_METADATA_FOR_PTR(_p) (SMALL_META_HEADER_FOR_PTR(_p) + SMALL_META_INDEX_FOR_PTR(_p))
-
-/*
- * Determine whether a pointer known to be within a small region points to memory which is free.
- */
-#define SMALL_PTR_IS_FREE(_p) (*SMALL_METADATA_FOR_PTR(_p) & SMALL_IS_FREE)
-
-/*
- * Extract the msize value for a pointer known to be within a small region.
- */
-#define SMALL_PTR_SIZE(_p) (*SMALL_METADATA_FOR_PTR(_p) & ~SMALL_IS_FREE)
-
-#define PROTECT_SMALL 0 // Should be 0: 1 is too slow for normal use
-
-#define SMALL_CACHE 1
-#if !SMALL_CACHE
-#warning SMALL_CACHE turned off
-#endif
-
-/********************* DEFINITIONS for large and huge ***********************/
-
-#define LARGE_THRESHOLD (15 * 1024) // at or above this use "large"
-
-#if (LARGE_THRESHOLD > NUM_SMALL_SLOTS * SMALL_QUANTUM)
-#error LARGE_THRESHOLD should always be less than NUM_SMALL_SLOTS * SMALL_QUANTUM
-#endif
-
-#define VM_COPY_THRESHOLD (40 * 1024)
- // When all memory is touched after a copy, vm_copy() is always a lose
- // But if the memory is only read, vm_copy() wins over memmove() at 3 or 4 pages (on a G3/300MHz)
- // This must be larger than LARGE_THRESHOLD
-
-/*
- * Given a large_entry, return the address of the allocated block.
- */
-#define LARGE_ENTRY_ADDRESS(entry) \
- (void *)(((entry).address_and_num_pages >> vm_page_shift) << vm_page_shift)
-
-/*
- * Given a large entry, return the number of pages or bytes in the allocated block.
- */
-#define LARGE_ENTRY_NUM_PAGES(entry) \
- ((entry).address_and_num_pages & (vm_page_size - 1))
-#define LARGE_ENTRY_SIZE(entry) \
- (LARGE_ENTRY_NUM_PAGES(entry) << vm_page_shift)
-
-/*
- * Compare a pointer with a large entry.
- */
-#define LARGE_ENTRY_MATCHES(entry,ptr) \
- ((((entry).address_and_num_pages - (uintptr_t)(ptr)) >> vm_page_shift) == 0)
-
-#define LARGE_ENTRY_IS_EMPTY(entry) (((entry).address_and_num_pages) == 0)
-
-typedef compact_range_t large_entry_t;
-typedef vm_range_t huge_entry_t;
-
-/*******************************************************************************
- * Definitions for region hash
- ******************************************************************************/
-
-typedef void * region_t;
-
-#define INITIAL_NUM_REGIONS 63 // Must be odd to hash well
-
-/********************* zone itself ************************/
-
-typedef struct {
- malloc_zone_t basic_zone;
- pthread_lock_t lock;
- unsigned debug_flags;
- void *log_address;
-
- /* Regions for tiny objects */
- size_t num_tiny_regions;
- size_t num_tiny_regions_allocated;
- region_t *tiny_regions; // hashed by location
- region_t *last_tiny_region;
- void *last_tiny_free; // low SHIFT_TINY_QUANTUM indicate the msize
- unsigned tiny_bitmap; // cache of the 32 free lists
- free_list_t *tiny_free_list[NUM_TINY_SLOTS]; // 31 free lists for 1*TINY_QUANTUM to 31*TINY_QUANTUM plus 1 for larger than 32*SMALL_QUANTUM
- size_t tiny_bytes_free_at_end; // the last free region in the last block is treated as a big block in use that is not accounted for
- unsigned num_tiny_objects;
- size_t num_bytes_in_tiny_objects;
-
- /* Regions for small objects */
- size_t num_small_regions;
- size_t num_small_regions_allocated;
- region_t *small_regions; // hashed by location
- region_t *last_small_region;
- void *last_small_free; // low SHIFT_SMALL_QUANTUM indicate the msize
- unsigned small_bitmap; // cache of the free list
- free_list_t *small_free_list[NUM_SMALL_SLOTS];
- size_t small_bytes_free_at_end; // the last free region in the last block is treated as a big block in use that is not accounted for
- unsigned num_small_objects;
- size_t num_bytes_in_small_objects;
-
- /* large objects: vm_page_shift <= log2(size) < 2 *vm_page_shift */
- unsigned num_large_objects_in_use;
- unsigned num_large_entries;
- large_entry_t *large_entries; // hashed by location; null entries don't count
- size_t num_bytes_in_large_objects;
-
- /* huge objects: log2(size) >= 2 *vm_page_shift */
- unsigned num_huge_entries;
- huge_entry_t *huge_entries;
- size_t num_bytes_in_huge_objects;
-
- /* Initial region list */
- region_t initial_tiny_regions[INITIAL_NUM_REGIONS];
- region_t initial_small_regions[INITIAL_NUM_REGIONS];
-} szone_t;
-
-#define SZONE_PAGED_SIZE ((sizeof(szone_t) + vm_page_size - 1) & ~ (vm_page_size - 1))
-
-#if DEBUG_MALLOC || DEBUG_CLIENT
-static void szone_sleep(void);
-#endif
-__private_extern__ void malloc_error_break(void);
-
-// msg prints after fmt, ...
-static void szone_error(szone_t *szone, const char *msg, const void *ptr, const char *fmt, ...) __printflike(4, 5);
-
-static void protect(void *address, size_t size, unsigned protection, unsigned debug_flags);
-static void *allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label);
-static void deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags);
-static kern_return_t _szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr);
-
-static INLINE void free_list_checksum(szone_t *szone, free_list_t *ptr, const char *msg) ALWAYSINLINE;
-static INLINE void free_list_set_checksum(szone_t *szone, free_list_t *ptr) ALWAYSINLINE;
-static INLINE uintptr_t free_list_checksum_ptr(void *p) ALWAYSINLINE;
-static INLINE void * free_list_unchecksum_ptr(ptr_union ptr) ALWAYSINLINE;
-static unsigned free_list_count(const free_list_t *ptr);
-
-static INLINE msize_t get_tiny_meta_header(const void *ptr, boolean_t *is_free) ALWAYSINLINE;
-static INLINE void set_tiny_meta_header_in_use(const void *ptr, msize_t msize) ALWAYSINLINE;
-static INLINE void set_tiny_meta_header_middle(const void *ptr) ALWAYSINLINE;
-static INLINE void set_tiny_meta_header_free(const void *ptr, msize_t msize) ALWAYSINLINE;
-static INLINE boolean_t tiny_meta_header_is_free(const void *ptr) ALWAYSINLINE;
-static INLINE void *tiny_previous_preceding_free(void *ptr, msize_t *prev_msize) ALWAYSINLINE;
-static void tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize);
-static void tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize);
-static INLINE region_t *tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE;
-static INLINE void tiny_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) ALWAYSINLINE;
-static void *tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize);
-static INLINE boolean_t try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE;
-static boolean_t tiny_check_region(szone_t *szone, region_t region);
-static kern_return_t tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder);
-static void *tiny_malloc_from_free_list(szone_t *szone, msize_t msize);
-static INLINE void *tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE;
-static INLINE void free_tiny(szone_t *szone, void *ptr, region_t *tiny_region) ALWAYSINLINE;
-static void print_tiny_free_list(szone_t *szone);
-static void print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_end);
-static boolean_t tiny_free_list_check(szone_t *szone, grain_t slot);
-
-static INLINE void small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize) ALWAYSINLINE;
-static INLINE void small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize) ALWAYSINLINE;
-static INLINE void small_meta_header_set_middle(msize_t *meta_headers, msize_t index) ALWAYSINLINE;
-static void small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize);
-static void small_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize);
-static INLINE region_t *small_region_for_ptr_no_lock(szone_t *szone, const void *ptr) ALWAYSINLINE;
-static INLINE void small_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize) ALWAYSINLINE;
-static void *small_malloc_from_region_no_lock(szone_t *szone, msize_t msize);
-static INLINE boolean_t try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE;
-static boolean_t szone_check_small_region(szone_t *szone, region_t region);
-static kern_return_t small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder);
-static void *small_malloc_from_free_list(szone_t *szone, msize_t msize);
-static INLINE void *small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested) ALWAYSINLINE;
-static INLINE void *small_malloc_cleared_no_lock(szone_t *szone, msize_t msize) ALWAYSINLINE;
-static INLINE void free_small(szone_t *szone, void *ptr, region_t *small_region) ALWAYSINLINE;
-static void print_small_free_list(szone_t *szone);
-static void print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_end);
-static boolean_t small_free_list_check(szone_t *szone, grain_t grain);
-
-static region_t * hash_lookup_region_no_lock(region_t *regions, size_t num_entries, region_t r);
-static void hash_region_insert_no_lock(region_t *regions, size_t num_entries, region_t r);
-static region_t * hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries);
-static region_t * hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size, size_t *new_size);
-
-#if DEBUG_MALLOC
-static void large_debug_print(szone_t *szone);
-#endif
-static large_entry_t *large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr);
-static void large_entry_insert_no_lock(szone_t *szone, large_entry_t range);
-static INLINE void large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry) ALWAYSINLINE;
-static INLINE large_entry_t *large_entries_alloc_no_lock(szone_t *szone, unsigned num) ALWAYSINLINE;
-static void large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate);
-static large_entry_t * large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate);
-static vm_range_t large_free_no_lock(szone_t *szone, large_entry_t *entry);
-static kern_return_t large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder);
-static huge_entry_t *huge_entry_for_pointer_no_lock(szone_t *szone, const void *ptr);
-static boolean_t huge_entry_append(szone_t *szone, huge_entry_t huge);
-static kern_return_t huge_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t huge_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder);
-static void *large_and_huge_malloc(szone_t *szone, size_t num_pages);
-static INLINE void free_large_or_huge(szone_t *szone, void *ptr) ALWAYSINLINE;
-static INLINE int try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size) ALWAYSINLINE;
-
-static void szone_free(szone_t *szone, void *ptr);
-static INLINE void *szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested) ALWAYSINLINE;
-static void *szone_malloc(szone_t *szone, size_t size);
-static void *szone_calloc(szone_t *szone, size_t num_items, size_t size);
-static void *szone_valloc(szone_t *szone, size_t size);
-static size_t szone_size(szone_t *szone, const void *ptr);
-static void *szone_realloc(szone_t *szone, void *ptr, size_t new_size);
-static unsigned szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count);
-static void szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count);
-static void szone_destroy(szone_t *szone);
-static size_t szone_good_size(szone_t *szone, size_t size);
-
-static boolean_t szone_check_all(szone_t *szone, const char *function);
-static boolean_t szone_check(szone_t *szone);
-static kern_return_t szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder);
-static void szone_print(szone_t *szone, boolean_t verbose);
-static void szone_log(malloc_zone_t *zone, void *log_address);
-static void szone_force_lock(szone_t *szone);
-static void szone_force_unlock(szone_t *szone);
-
-static void szone_statistics(szone_t *szone, malloc_statistics_t *stats);
-
-static void *frozen_malloc(szone_t *zone, size_t new_size);
-static void *frozen_calloc(szone_t *zone, size_t num_items, size_t size);
-static void *frozen_valloc(szone_t *zone, size_t new_size);
-static void *frozen_realloc(szone_t *zone, void *ptr, size_t new_size);
-static void frozen_free(szone_t *zone, void *ptr);
-static void frozen_destroy(szone_t *zone);
-
-#if DEBUG_MALLOC
-# define LOG(szone,ptr) \
- (szone->log_address && (((uintptr_t)szone->log_address == -1) || (szone->log_address == (void *)(ptr))))
-#else
-# define LOG(szone,ptr) 0
-#endif
-
-#define SZONE_LOCK(szone) \
- do { \
- LOCK(szone->lock); \
- } while (0)
-
-#define SZONE_UNLOCK(szone) \
- do { \
- UNLOCK(szone->lock); \
- } while (0)
-
-#define LOCK_AND_NOTE_LOCKED(szone,locked) \
-do { \
- CHECK(szone, __PRETTY_FUNCTION__); \
- locked = 1; SZONE_LOCK(szone); \
-} while (0)
-
-#if DEBUG_MALLOC || DEBUG_CLIENT
-# define CHECK(szone,fun) \
- if ((szone)->debug_flags & CHECK_REGIONS) szone_check_all(szone, fun)
-#else
-# define CHECK(szone,fun) do {} while (0)
-#endif
-
-/********************* VERY LOW LEVEL UTILITIES ************************/
-
-#if DEBUG_MALLOC || DEBUG_CLIENT
-static void
-szone_sleep(void)
-{
-
- if (getenv("MallocErrorSleep")) {
- _malloc_printf(ASL_LEVEL_NOTICE, "*** sleeping to help debug\n");
- sleep(3600); // to help debug
- }
-}
-#endif
-
-// msg prints after fmt, ...
-static __attribute__((noinline)) void
-szone_error(szone_t *szone, const char *msg, const void *ptr, const char *fmt, ...)
-{
- va_list ap;
- _SIMPLE_STRING b = _simple_salloc();
-
- if (szone) SZONE_UNLOCK(szone);
- if (b) {
- if (fmt) {
- va_start(ap, fmt);
- _simple_vsprintf(b, fmt, ap);
- va_end(ap);
- }
- if (ptr) {
- _simple_sprintf(b, "*** error for object %p: %s\n", ptr, msg);
- } else {
- _simple_sprintf(b, "*** error: %s\n", msg);
- }
- malloc_printf("%s*** set a breakpoint in malloc_error_break to debug\n", _simple_string(b));
- _simple_sfree(b);
- } else {
- /*
- * Should only get here if vm_allocate() can't get a single page of
- * memory, implying _simple_asl_log() would also fail. So we just
- * print to the file descriptor.
- */
- if (fmt) {
- va_start(ap, fmt);
- _malloc_vprintf(MALLOC_PRINTF_NOLOG, fmt, ap);
- va_end(ap);
- }
- if (ptr) {
- _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error for object %p: %s\n", ptr, msg);
- } else {
- _malloc_printf(MALLOC_PRINTF_NOLOG, "*** error: %s\n", msg);
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG, "*** set a breakpoint in malloc_error_break to debug\n");
- }
- malloc_error_break();
-#if DEBUG_MALLOC
- szone_print(szone, 1);
- szone_sleep();
-#endif
-#if DEBUG_CLIENT
- szone_sleep();
-#endif
- if (szone->debug_flags & SCALABLE_MALLOC_ABORT_ON_ERROR) abort();
-}
-
-static void
-protect(void *address, size_t size, unsigned protection, unsigned debug_flags)
-{
- kern_return_t err;
-
- if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_PRELUDE)) {
- err = vm_protect(mach_task_self(), (vm_address_t)(uintptr_t)address - vm_page_size, vm_page_size, 0, protection);
- if (err) {
- malloc_printf("*** can't protect(%p) region for prelude guard page at %p\n",
- protection,address - (1 << vm_page_shift));
- }
- }
- if (!(debug_flags & SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE)) {
- err = vm_protect(mach_task_self(), (vm_address_t)(uintptr_t)address + size, vm_page_size, 0, protection);
- if (err) {
- malloc_printf("*** can't protect(%p) region for postlude guard page at %p\n",
- protection, address + size);
- }
- }
-}
-
-static void *
-allocate_pages(szone_t *szone, size_t size, unsigned char align, unsigned debug_flags, int vm_page_label)
-{
- // align specifies a desired alignment (as a log) or 0 if no alignment requested
- void *vm_addr;
- uintptr_t addr, aligned_address;
- boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES;
- size_t allocation_size = round_page(size);
- size_t delta;
-
- if (align) add_guard_pages = 0; // too cumbersome to deal with that
- if (!allocation_size) allocation_size = 1 << vm_page_shift;
- if (add_guard_pages) allocation_size += 2 * (1 << vm_page_shift);
- if (align) allocation_size += (size_t)1 << align;
- vm_addr = mmap(0, allocation_size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, VM_MAKE_TAG(vm_page_label), 0);
- if ((uintptr_t)vm_addr == -1) {
- szone_error(szone, "can't allocate region", NULL, "*** mmap(size=%lld) failed (error code=%d)\n", (long long)allocation_size, errno);
- return NULL;
- }
- addr = (uintptr_t)vm_addr;
- if (align) {
- aligned_address = (addr + ((uintptr_t)1 << align) - 1) & ~ (((uintptr_t)1 << align) - 1);
- if (aligned_address != addr) {
- delta = aligned_address - addr;
- if (munmap((void *)addr, delta) == -1)
- malloc_printf("*** freeing unaligned header failed with %d\n", errno);
- addr = aligned_address;
- allocation_size -= delta;
- }
- if (allocation_size > size) {
- if (munmap((void *)(addr + size), allocation_size - size) == -1)
- malloc_printf("*** freeing unaligned footer failed with %d\n", errno);
- }
- }
- if (add_guard_pages) {
- addr += (uintptr_t)1 << vm_page_shift;
- protect((void *)addr, size, 0, debug_flags);
- }
- return (void *)addr;
-}
-
-static void
-deallocate_pages(szone_t *szone, void *addr, size_t size, unsigned debug_flags)
-{
- int err;
- boolean_t add_guard_pages = debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES;
-
- if (add_guard_pages) {
- addr -= 1 << vm_page_shift;
- size += 2 * (1 << vm_page_shift);
- }
- err = munmap(addr, size);
- if ((err == -1) && szone)
- szone_error(szone, "Can't deallocate_pages region", addr, NULL);
-}
-
-static kern_return_t
-_szone_default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr)
-{
- *ptr = (void *)address;
- return 0;
-}
-
-/********************* FREE LIST UTILITIES ************************/
-
-// A free list entry is comprised of a pair of pointers, previous and next.
-// Because the free list entries are previously freed objects, there is a
-// non-zero chance that a misbehaved program will write to an allocated object
-// after it has called free() on the pointer. This write would then potentially
-// corrupt the previous and next pointers, leading to a crash. In order to
-// detect this case, we take advantage of the fact that pointers are known to
-// be at least 16 byte aligned, and thus have at least 4 trailing zero bits.
-// When an entry is added to the free list, the previous and next pointers are
-// shifted right by 2 bits, and then have the high and low 2 bits set, to act
-// as guard bits. Before accessing a free list object, we verify that these
-// bits are still set, and log an error if they are not.
-
-static INLINE void
-free_list_checksum(szone_t *szone, free_list_t *ptr, const char *msg)
-{
- uintptr_t ptrs = ptr->previous.u & ptr->next.u;
-
-#ifdef __LP64__
- ptrs = (ptrs << 2) | (ptrs >> (64-2));
-#else
- ptrs = (ptrs << 2) | (ptrs >> (32-2));
-#endif
-
- if ((ptrs & 15) != 15)
- szone_error(szone, "incorrect checksum for freed object "
- "- object was probably modified after being freed.", ptr, NULL);
-}
-
-static INLINE uintptr_t
-free_list_checksum_ptr(void *p)
-{
- ptr_union ptr;
- ptr.p = p;
-
-#ifdef __LP64__
- return (ptr.u >> 2) | 0xC000000000000003ULL;
-#else
- return (ptr.u >> 2) | 0xC0000003U;
-#endif
-}
-
-static INLINE void *
-free_list_unchecksum_ptr(ptr_union ptr)
-{
- uintptr_t u = (ptr.u >> 2) << 4;
- return (void *)u;
-}
-
-static INLINE void
-free_list_set_checksum(szone_t *szone, free_list_t *ptr)
-{
- ptr->previous.u = free_list_checksum_ptr(ptr->previous.p);
- ptr->next.u = free_list_checksum_ptr(ptr->next.p);
-}
-
-static unsigned
-free_list_count(const free_list_t *ptr)
-{
- unsigned count = 0;
-
- while (ptr) {
- count++;
- ptr = free_list_unchecksum_ptr(ptr->next);
- }
- return count;
-}
-
-/* XXX inconsistent use of BITMAP32 and BITARRAY operations could be cleaned up */
-
-#define BITMAP32_SET(bitmap,bit) (bitmap |= 1 << (bit))
-#define BITMAP32_CLR(bitmap,bit) (bitmap &= ~ (1 << (bit)))
-#define BITMAP32_BIT(bitmap,bit) ((bitmap >> (bit)) & 1)
-
-/* returns bit # of least-significant one bit, starting at 0 (undefined if !bitmap) */
-#define BITMAP32_CTZ(bitmap) (__builtin_ctz(bitmap))
-
-/********************* TINY FREE LIST UTILITIES ************************/
-
-// We encode the meta-headers as follows:
-// Each quantum has an associated set of 2 bits:
-// block_header when 1 says this block is the beginning of a block
-// in_use when 1 says this block is in use
-// so a block in use of size 3 is 1-1 0-X 0-X
-// for a free block TINY_FREE_SIZE(ptr) carries the size and the bits are 1-0 X-X X-X
-// for a block middle the bits are 0-0
-
-// Attention double evaluation for these
-#define BITARRAY_SET(bits,index) (bits[index>>3] |= (1 << (index & 7)))
-#define BITARRAY_CLR(bits,index) (bits[index>>3] &= ~(1 << (index & 7)))
-#define BITARRAY_BIT(bits,index) (((bits[index>>3]) >> (index & 7)) & 1)
-
-// Following is for start<8 and end<=start+32
-static void ALWAYSINLINE
-bitarray_mclr(void *bits, unsigned start, unsigned end) {
- unsigned word = OSReadLittleInt32(bits, 0);
- unsigned mask = (0xFFFFFFFFU >> (31 - start)) >> 1;
-
- if (end > 31) {
- unsigned char *bytes = (unsigned char *)bits;
- bytes[4] &= ~((1 << (end - 32)) - 1);
- } else {
- mask |= (0xFFFFFFFF << end);
- }
- OSWriteLittleInt32(bits, 0, word & mask);
-}
-
-/*
- * Obtain the size of a free tiny block (in msize_t units).
- */
-static msize_t
-get_tiny_free_size(const void *ptr)
-{
- void *next_block = (void *)((uintptr_t)ptr + TINY_QUANTUM);
- void *region_end = TINY_REGION_END(TINY_REGION_FOR_PTR(ptr));
-
- // check whether the next block is outside the tiny region or a block header
- // if so, then the size of this block is one, and there is no stored size.
- if (next_block < region_end)
- {
- unsigned char *next_header = TINY_BLOCK_HEADER_FOR_PTR(next_block);
- msize_t next_index = TINY_INDEX_FOR_PTR(next_block);
-
- if (!BITARRAY_BIT(next_header, next_index))
- return TINY_FREE_SIZE(ptr);
- }
- return 1;
-}
-
-/*
- * Get the size of the previous free block, which is stored in the last two
- * bytes of the block. If the previous block is not free, then the result is
- * undefined.
- */
-static msize_t
-get_tiny_previous_free_msize(const void *ptr)
-{
- // check whether the previous block is in the tiny region and a block header
- // if so, then the size of the previous block is one, and there is no stored
- // size.
- if (ptr != TINY_REGION_FOR_PTR(ptr))
- {
- void *prev_block = (void *)((uintptr_t)ptr - TINY_QUANTUM);
- unsigned char *prev_header = TINY_BLOCK_HEADER_FOR_PTR(prev_block);
- msize_t prev_index = TINY_INDEX_FOR_PTR(prev_block);
- if (BITARRAY_BIT(prev_header, prev_index))
- return 1;
- return TINY_PREVIOUS_MSIZE(ptr);
- }
- // don't read possibly unmapped memory before the beginning of the region
- return 0;
-}
-
-static INLINE msize_t
-get_tiny_meta_header(const void *ptr, boolean_t *is_free)
-{
- // returns msize and is_free
- // may return 0 for the msize component (meaning 65536)
- unsigned char *block_header;
- unsigned char *in_use;
- msize_t index;
- unsigned byte_index;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- index = TINY_INDEX_FOR_PTR(ptr);
- byte_index = index >> 3;
-
- block_header += byte_index;
- index &= 7;
- *is_free = 0;
- if (!BITMAP32_BIT(*block_header, index))
- return 0;
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- if (!BITMAP32_BIT(*in_use, index)) {
- *is_free = 1;
- return get_tiny_free_size(ptr);
- }
- uint32_t *addr = (uint32_t *)((uintptr_t)block_header & ~3);
- uint32_t word0 = OSReadLittleInt32(addr, 0) >> index;
- uint32_t word1 = OSReadLittleInt32(addr, 4) << (8 - index);
- uint32_t bits = (((uintptr_t)block_header & 3) * 8); // precision loss on LP64 OK here
- uint32_t word = (word0 >> bits) | (word1 << (24 - bits));
- uint32_t result = ffs(word >> 1);
- return result;
-}
-
-static INLINE void
-set_tiny_meta_header_in_use(const void *ptr, msize_t msize)
-{
- unsigned char *block_header;
- unsigned char *in_use;
- msize_t index;
- unsigned byte_index;
- msize_t clr_msize;
- unsigned end_bit;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- index = TINY_INDEX_FOR_PTR(ptr);
- byte_index = index >> 3;
-
-#if DEBUG_MALLOC
- if (msize >= 32)
- malloc_printf("set_tiny_meta_header_in_use() invariant broken %p %d\n", ptr, msize);
- if ((unsigned)index + (unsigned)msize > 0x10000)
- malloc_printf("set_tiny_meta_header_in_use() invariant broken (2) %p %d\n", ptr, msize);
-#endif
- block_header += byte_index;
- index &= 7;
- BITMAP32_SET(*block_header, index);
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- BITMAP32_SET(*in_use, index);
- index++;
- clr_msize = msize-1;
- if (clr_msize) {
- byte_index = index >> 3;
- block_header += byte_index; in_use += byte_index;
- index &= 7;
- end_bit = index + clr_msize;
- bitarray_mclr(block_header, index, end_bit);
- bitarray_mclr(in_use, index, end_bit);
- }
- BITARRAY_SET(block_header, index+clr_msize); // we set the block_header bit for the following block to reaffirm next block is a block
-#if DEBUG_MALLOC
- {
- boolean_t ff;
- msize_t mf;
-
- mf = get_tiny_meta_header(ptr, &ff);
- if (msize != mf) {
- malloc_printf("setting header for tiny in_use %p : %d\n", ptr, msize);
- malloc_printf("reading header for tiny %p : %d %d\n", ptr, mf, ff);
- }
- }
-#endif
-}
-
-static INLINE void
-set_tiny_meta_header_middle(const void *ptr)
-{
- // indicates this block is in the middle of an in use block
- unsigned char *block_header;
- unsigned char *in_use;
- msize_t index;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- index = TINY_INDEX_FOR_PTR(ptr);
-
- BITARRAY_CLR(block_header, index);
- BITARRAY_CLR(in_use, index);
-}
-
-static INLINE void
-set_tiny_meta_header_free(const void *ptr, msize_t msize)
-{
- // !msize is acceptable and means 65536
- unsigned char *block_header;
- unsigned char *in_use;
- msize_t index;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- index = TINY_INDEX_FOR_PTR(ptr);
-
-#if DEBUG_MALLOC
- if ((unsigned)index + (unsigned)msize > 0x10000) {
- malloc_printf("setting header for tiny free %p msize too large: %d\n", ptr, msize);
- }
-#endif
- BITARRAY_SET(block_header, index);
- BITARRAY_CLR(in_use, index);
- // mark the end of this block if msize is > 1. For msize == 0, the whole
- // region is free, so there is no following block. For msize == 1, there is
- // no space to write the size on 64 bit systems. The size for 1 quantum
- // blocks is computed from the metadata bitmaps.
- if (msize > 1) {
- void *follower = FOLLOWING_TINY_PTR(ptr, msize);
- TINY_PREVIOUS_MSIZE(follower) = msize;
- TINY_FREE_SIZE(ptr) = msize;
- }
- if (msize == 0) {
- TINY_FREE_SIZE(ptr) = msize;
- }
-#if DEBUG_MALLOC
- boolean_t ff;
- msize_t mf = get_tiny_meta_header(ptr, &ff);
- if ((msize != mf) || !ff) {
- malloc_printf("setting header for tiny free %p : %u\n", ptr, msize);
- malloc_printf("reading header for tiny %p : %u %u\n", ptr, mf, ff);
- }
-#endif
-}
-
-static INLINE boolean_t
-tiny_meta_header_is_free(const void *ptr)
-{
- unsigned char *block_header;
- unsigned char *in_use;
- msize_t index;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- index = TINY_INDEX_FOR_PTR(ptr);
- if (!BITARRAY_BIT(block_header, index))
- return 0;
- return !BITARRAY_BIT(in_use, index);
-}
-
-static INLINE void *
-tiny_previous_preceding_free(void *ptr, msize_t *prev_msize)
-{
- // returns the previous block, assuming and verifying it's free
- unsigned char *block_header;
- unsigned char *in_use;
- msize_t index;
- msize_t previous_msize;
- msize_t previous_index;
- void *previous_ptr;
-
- block_header = TINY_BLOCK_HEADER_FOR_PTR(ptr);
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- index = TINY_INDEX_FOR_PTR(ptr);
-
- if (!index)
- return NULL;
- if ((previous_msize = get_tiny_previous_free_msize(ptr)) > index)
- return NULL;
-
- previous_index = index - previous_msize;
- previous_ptr = (void *)(TINY_REGION_FOR_PTR(ptr) + TINY_BYTES_FOR_MSIZE(previous_index));
- if (!BITARRAY_BIT(block_header, previous_index))
- return NULL;
- if (BITARRAY_BIT(in_use, previous_index))
- return NULL;
- if (get_tiny_free_size(previous_ptr) != previous_msize)
- return NULL;
-
- // conservative check did match true check
- *prev_msize = previous_msize;
- return previous_ptr;
-}
-
-/*
- * Adds an item to the proper free list, and also marks the meta-header of the
- * block properly.
- * Assumes szone has been locked
- */
-static void
-tiny_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize)
-{
- grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1;
- free_list_t *free_ptr = ptr;
- free_list_t *free_head = szone->tiny_free_list[slot];
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize);
- }
- if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) {
- szone_error(szone, "tiny_free_list_add_ptr: Unaligned ptr", ptr, NULL);
- }
-#endif
- set_tiny_meta_header_free(ptr, msize);
- if (free_head) {
- free_list_checksum(szone, free_head, __PRETTY_FUNCTION__);
-#if DEBUG_MALLOC
- if (free_list_unchecksum_ptr(free_head->previous)) {
- szone_error(szone, "tiny_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr,
- "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, free_head, free_head->previous.p);
- }
- if (! tiny_meta_header_is_free(free_head)) {
- szone_error(szone, "tiny_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr,
- "ptr=%p slot=%d free_head=%p\n", ptr, slot, free_head);
- }
-#endif
- free_head->previous.u = free_list_checksum_ptr(free_ptr);
- } else {
- BITMAP32_SET(szone->tiny_bitmap, slot);
- }
- free_ptr->previous.p = NULL;
- free_ptr->next.p = free_head;
- free_list_set_checksum(szone, free_ptr);
- szone->tiny_free_list[slot] = free_ptr;
-}
-
-/*
- * Removes the item pointed to by ptr in the proper free list.
- * Assumes szone has been locked
- */
-static INLINE void
-tiny_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize)
-{
- grain_t slot = (!msize || (msize >= NUM_TINY_SLOTS)) ? NUM_TINY_SLOTS - 1 : msize - 1;
- free_list_t *free_ptr = ptr, *next, *previous;
- free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__);
-
- next = free_list_unchecksum_ptr(free_ptr->next);
- previous = free_list_unchecksum_ptr(free_ptr->previous);
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize);
- }
-#endif
- if (!previous) {
- // The block to remove is the head of the free list
-#if DEBUG_MALLOC
- if (szone->tiny_free_list[slot] != ptr) {
- szone_error(szone, "tiny_free_list_remove_ptr: Internal invariant broken (szone->tiny_free_list[slot])", ptr,
- "ptr=%p slot=%d msize=%d szone->tiny_free_list[slot]=%p\n",
- ptr, slot, msize, szone->tiny_free_list[slot]);
- return;
- }
-#endif
- szone->tiny_free_list[slot] = next;
- if (!next) BITMAP32_CLR(szone->tiny_bitmap, slot);
- } else {
- // We know free_ptr is already checksummed, so we don't need to do it
- // again.
- previous->next = free_ptr->next;
- }
- if (next) {
- // We know free_ptr is already checksummed, so we don't need to do it
- // again.
- next->previous = free_ptr->previous;
- }
-}
-
-/*
- * tiny_region_for_ptr_no_lock - Returns the tiny region containing the pointer,
- * or NULL if not found.
- */
-static INLINE region_t *
-tiny_region_for_ptr_no_lock(szone_t *szone, const void *ptr)
-{
- return hash_lookup_region_no_lock(szone->tiny_regions,
- szone->num_tiny_regions_allocated,
- TINY_REGION_FOR_PTR(ptr));
-}
-
-static INLINE void
-tiny_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize)
-{
- size_t original_size = TINY_BYTES_FOR_MSIZE(msize);
- void *next_block = ((char *)ptr + original_size);
- msize_t previous_msize;
- void *previous;
- msize_t next_msize;
- free_list_t *big_free_block;
- free_list_t *after_next_block;
- free_list_t *before_next_block;
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
- if (! msize) {
- szone_error(szone, "trying to free tiny block that is too small", ptr,
- "in tiny_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
- // We try to coalesce this block with the preceeding one
- previous = tiny_previous_preceding_free(ptr, &previous_msize);
- if (previous) {
-#if DEBUG_MALLOC
- if (LOG(szone, ptr) || LOG(szone,previous)) {
- malloc_printf("in tiny_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous);
- }
-#endif
- // clear the meta_header since this is no longer the start of a block
- set_tiny_meta_header_middle(ptr);
- tiny_free_list_remove_ptr(szone, previous, previous_msize);
- ptr = previous;
- msize += previous_msize;
- }
- // We try to coalesce with the next block
- if ((next_block < TINY_REGION_END(*region)) && tiny_meta_header_is_free(next_block)) {
- next_msize = get_tiny_free_size(next_block);
-#if DEBUG_MALLOC
- if (LOG(szone, ptr) || LOG(szone, next_block)) {
- malloc_printf("in tiny_free_no_lock(), for ptr=%p, msize=%d coalesced forward=%p next_msize=%d\n",
- ptr, msize, next_block, next_msize);
- }
-#endif
- // If we are coalescing with the next block, and the next block is in
- // the last slot of the free list, then we optimize this case here to
- // avoid removing next_block from the slot 31 and then adding ptr back
- // to slot 31.
- if (next_msize >= NUM_TINY_SLOTS) {
- msize += next_msize;
- big_free_block = (free_list_t *)next_block;
- free_list_checksum(szone, big_free_block, __PRETTY_FUNCTION__);
- after_next_block = free_list_unchecksum_ptr(big_free_block->next);
- before_next_block = free_list_unchecksum_ptr(big_free_block->previous);
- if (!before_next_block) {
- szone->tiny_free_list[NUM_TINY_SLOTS-1] = ptr;
- } else {
- before_next_block->next.u = free_list_checksum_ptr(ptr);
- }
- if (after_next_block) {
- after_next_block->previous.u = free_list_checksum_ptr(ptr);
- }
- // we don't need to checksum these since they are already checksummed
- ((free_list_t *)ptr)->previous = big_free_block->previous;
- ((free_list_t *)ptr)->next = big_free_block->next;
-
- // clear the meta_header to enable coalescing backwards
- set_tiny_meta_header_middle(big_free_block);
- set_tiny_meta_header_free(ptr, msize);
- goto tiny_free_ending;
- }
- tiny_free_list_remove_ptr(szone, next_block, next_msize);
- set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards
- msize += next_msize;
- }
-#if !TINY_CACHE
- // The tiny cache already scribbles free blocks as they go through the
- // cache, so we do not need to do it here.
- if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize) {
- memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize));
- }
-#endif
- tiny_free_list_add_ptr(szone, ptr, msize);
- tiny_free_ending:
- // When in proper debug mode we write on the memory to help debug memory smashers
- szone->num_tiny_objects--;
- szone->num_bytes_in_tiny_objects -= original_size; // we use original_size and not msize to avoid double counting the coalesced blocks
-}
-
-// Allocates from the last region or a freshly allocated region
-static void *
-tiny_malloc_from_region_no_lock(szone_t *szone, msize_t msize)
-{
- void *last_block, *ptr, *aligned_address;
- unsigned char *last_header;
- msize_t last_msize, last_index;
-
- // Before anything we transform any remaining tiny_bytes_free_at_end into a
- // regular free block. We take special care here to update the bitfield
- // information, since we are bypassing the normal free codepath. If there
- // is more than one quanta worth of memory in tiny_bytes_free_at_end, then
- // there will be two block headers:
- // 1) header for the free space at end, msize = 1
- // 2) header inserted by set_tiny_meta_header_in_use after block
- // We must clear the second one so that when the free block's size is
- // queried, we do not think the block is only 1 quantum in size because
- // of the second set header bit.
- if (szone->tiny_bytes_free_at_end) {
- last_block = TINY_REGION_END(szone->last_tiny_region) - szone->tiny_bytes_free_at_end;
- last_msize = TINY_MSIZE_FOR_BYTES(szone->tiny_bytes_free_at_end);
- last_header = TINY_BLOCK_HEADER_FOR_PTR(last_block);
- last_index = TINY_INDEX_FOR_PTR(last_block);
-
- if (last_index != (NUM_TINY_BLOCKS - 1))
- BITARRAY_CLR(last_header, last_index + 1);
-
- tiny_free_list_add_ptr(szone, last_block, last_msize);
- szone->tiny_bytes_free_at_end = 0;
- }
- // time to create a new region
- aligned_address = allocate_pages(szone, TINY_REGION_SIZE, TINY_BLOCKS_ALIGN, 0, VM_MEMORY_MALLOC_TINY);
- if (!aligned_address) // out of memory!
- return NULL;
- // We set the padding after block_header to be all 1
- ((uint32_t *)(aligned_address + TINY_HEADER_START + (NUM_TINY_BLOCKS >> 3)))[0] = ~0;
-
- // Check to see if the hash ring of tiny regions needs to grow. Try to
- // avoid the hash ring becoming too dense.
- if (szone->num_tiny_regions_allocated < (2 * szone->num_tiny_regions)) {
- region_t *new_regions;
- size_t new_size;
- new_regions = hash_regions_grow_no_lock(szone, szone->tiny_regions,
- szone->num_tiny_regions_allocated,
- &new_size);
- // Do not deallocate the current tiny_regions allocation since someone may
- // be iterating it. Instead, just leak it.
- szone->tiny_regions = new_regions;
- szone->num_tiny_regions_allocated = new_size;
- }
- // Insert the new region into the hash ring, and update malloc statistics
- hash_region_insert_no_lock(szone->tiny_regions,
- szone->num_tiny_regions_allocated,
- aligned_address);
- szone->last_tiny_region = aligned_address;
-
- szone->num_tiny_regions++;
- ptr = aligned_address;
- set_tiny_meta_header_in_use(ptr, msize);
- szone->num_tiny_objects++;
- szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(msize);
-
- // We put a header on the last block so that it appears in use (for coalescing, etc...)
- set_tiny_meta_header_in_use(ptr + TINY_BYTES_FOR_MSIZE(msize), 1);
- szone->tiny_bytes_free_at_end = TINY_BYTES_FOR_MSIZE(NUM_TINY_BLOCKS - msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_from_region_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
- return ptr;
-}
-
-static INLINE boolean_t
-try_realloc_tiny_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size)
-{
- // returns 1 on success
- msize_t index;
- msize_t old_msize;
- unsigned next_index;
- void *next_block;
- boolean_t is_free;
- msize_t next_msize, coalesced_msize, leftover_msize;
- void *leftover;
-
- index = TINY_INDEX_FOR_PTR(ptr);
- old_msize = TINY_MSIZE_FOR_BYTES(old_size);
- next_index = index + old_msize;
-
- if (next_index >= NUM_TINY_BLOCKS) {
- return 0;
- }
- next_block = (char *)ptr + old_size;
- SZONE_LOCK(szone);
- is_free = tiny_meta_header_is_free(next_block);
- if (!is_free) {
- SZONE_UNLOCK(szone);
- return 0; // next_block is in use;
- }
- next_msize = get_tiny_free_size(next_block);
- if (old_size + TINY_MSIZE_FOR_BYTES(next_msize) < new_size) {
- SZONE_UNLOCK(szone);
- return 0; // even with next block, not enough
- }
- tiny_free_list_remove_ptr(szone, next_block, next_msize);
- set_tiny_meta_header_middle(next_block); // clear the meta_header to enable coalescing backwards
- coalesced_msize = TINY_MSIZE_FOR_BYTES(new_size - old_size + TINY_QUANTUM - 1);
- leftover_msize = next_msize - coalesced_msize;
- if (leftover_msize) {
- leftover = next_block + TINY_BYTES_FOR_MSIZE(coalesced_msize);
- tiny_free_list_add_ptr(szone, leftover, leftover_msize);
- }
- set_tiny_meta_header_in_use(ptr, old_msize + coalesced_msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in try_realloc_tiny_in_place(), ptr=%p, msize=%d\n", ptr, old_msize + coalesced_msize);
- }
-#endif
- szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(coalesced_msize);
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- return 1;
-}
-
-static boolean_t
-tiny_check_region(szone_t *szone, region_t region)
-{
- uintptr_t start, ptr, region_end;
- boolean_t prev_free = 0;
- boolean_t is_free;
- msize_t msize;
- free_list_t *free_head;
- void *follower, *previous, *next;
-
- /* establish region limits */
- start = (uintptr_t)TINY_REGION_ADDRESS(region);
- ptr = start;
- region_end = (uintptr_t)TINY_REGION_END(region);
-
- /*
- * The last region may have a trailing chunk which has not been converted into inuse/freelist
- * blocks yet.
- */
- if (region == szone->last_tiny_region)
- region_end -= szone->tiny_bytes_free_at_end;
-
-
- /*
- * Scan blocks within the region.
- */
- while (ptr < region_end) {
- /*
- * If the first block is free, and its size is 65536 (msize = 0) then the entire region is
- * free.
- */
- msize = get_tiny_meta_header((void *)ptr, &is_free);
- if (is_free && !msize && (ptr == start)) {
- return 1;
- }
-
- /*
- * If the block's size is 65536 (msize = 0) then since we're not the first entry the size is
- * corrupt.
- */
- if (!msize) {
- malloc_printf("*** invariant broken for tiny block %p this msize=%d - size is too small\n",
- ptr, msize);
- return 0;
- }
-
- if (!is_free) {
- /*
- * In use blocks cannot be more than 31 quanta large.
- */
- prev_free = 0;
- if (msize > 31 * TINY_QUANTUM) {
- malloc_printf("*** invariant broken for %p this tiny msize=%d[%p] - size is too large\n",
- ptr, msize, msize);
- return 0;
- }
- /* move to next block */
- ptr += TINY_BYTES_FOR_MSIZE(msize);
- } else {
- /*
- * Free blocks must have been coalesced, we cannot have a free block following another
- * free block.
- */
- if (prev_free) {
- malloc_printf("*** invariant broken for free block %p this tiny msize=%d: two free blocks in a row\n",
- ptr, msize);
- return 0;
- }
- prev_free = 1;
- /*
- * Check the integrity of this block's entry in its freelist.
- */
- free_head = (free_list_t *)ptr;
- free_list_checksum(szone, free_head, __PRETTY_FUNCTION__);
- previous = free_list_unchecksum_ptr(free_head->previous);
- next = free_list_unchecksum_ptr(free_head->next);
- if (previous && !tiny_meta_header_is_free(previous)) {
- malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n",
- ptr, previous);
- return 0;
- }
- if (next && !tiny_meta_header_is_free(next)) {
- malloc_printf("*** invariant broken for %p (next in free list %p is not a free pointer)\n",
- ptr, next);
- return 0;
- }
- /*
- * Check the free block's trailing size value.
- */
- follower = FOLLOWING_TINY_PTR(ptr, msize);
- if (((uintptr_t)follower != region_end) && (get_tiny_previous_free_msize(follower) != msize)) {
- malloc_printf("*** invariant broken for tiny free %p followed by %p in region [%p-%p] "
- "(end marker incorrect) should be %d; in fact %d\n",
- ptr, follower, TINY_REGION_ADDRESS(region), region_end, msize, get_tiny_previous_free_msize(follower));
- return 0;
- }
- /* move to next block */
- ptr = (uintptr_t)follower;
- }
- }
- /*
- * Ensure that we scanned the entire region
- */
- if (ptr != region_end) {
- malloc_printf("*** invariant broken for region end %p - %p\n", ptr, region_end);
- return 0;
- }
- /*
- * Check the trailing block's integrity.
- */
- if (region == szone->last_tiny_region) {
- if (szone->tiny_bytes_free_at_end) {
- msize = get_tiny_meta_header((void *)ptr, &is_free);
- if (is_free || (msize != 1)) {
- malloc_printf("*** invariant broken for blocker block %p - %d %d\n", ptr, msize, is_free);
- }
- }
- }
- return 1;
-}
-
-static kern_return_t
-tiny_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder)
-{
- size_t num_regions = szone->num_tiny_regions_allocated;
- void *last_tiny_free = szone->last_tiny_free;
- size_t index;
- region_t *regions;
- vm_range_t buffer[MAX_RECORDER_BUFFER];
- unsigned count = 0;
- kern_return_t err;
- region_t region;
- vm_range_t range;
- vm_range_t admin_range;
- vm_range_t ptr_range;
- unsigned char *mapped_region;
- unsigned char *block_header;
- unsigned char *in_use;
- unsigned block_index;
- unsigned block_limit;
- boolean_t is_free;
- msize_t msize;
- void *mapped_ptr;
- unsigned bit;
- vm_address_t last_tiny_free_ptr = 0;
- msize_t last_tiny_free_msize = 0;
-
- if (last_tiny_free) {
- last_tiny_free_ptr = (uintptr_t) last_tiny_free & ~(TINY_QUANTUM - 1);
- last_tiny_free_msize = (uintptr_t) last_tiny_free & (TINY_QUANTUM - 1);
- }
-
- err = reader(task, (vm_address_t)szone->tiny_regions, sizeof(region_t) * num_regions, (void **)®ions);
- if (err) return err;
- for (index = 0; index < num_regions; ++index) {
- region = regions[index];
- if (region) {
- range.address = (vm_address_t)TINY_REGION_ADDRESS(region);
- range.size = (vm_size_t)TINY_REGION_SIZE;
- if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) {
- admin_range.address = range.address + TINY_HEADER_START;
- admin_range.size = TINY_HEADER_SIZE;
- recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1);
- }
- if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) {
- ptr_range.address = range.address;
- ptr_range.size = NUM_TINY_BLOCKS * TINY_QUANTUM;
- recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1);
- }
- if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) {
- err = reader(task, range.address, range.size, (void **)&mapped_region);
- if (err)
- return err;
-
- block_header = (unsigned char *)(mapped_region + TINY_HEADER_START);
- in_use = TINY_INUSE_FOR_HEADER(block_header);
- block_index = 0;
- block_limit = NUM_TINY_BLOCKS;
- if (region == szone->last_tiny_region)
- block_limit -= TINY_MSIZE_FOR_BYTES(szone->tiny_bytes_free_at_end);
-
- while (block_index < block_limit) {
- vm_size_t block_offset = TINY_BYTES_FOR_MSIZE(block_index);
- is_free = !BITARRAY_BIT(in_use, block_index);
- if (is_free) {
- mapped_ptr = mapped_region + block_offset;
-
- // mapped_region, the address at which 'range' in 'task' has been
- // mapped into our process, is not necessarily aligned to
- // TINY_BLOCKS_ALIGN.
- //
- // Since the code in get_tiny_free_size() assumes the pointer came
- // from a properly aligned tiny region, and mapped_region is not
- // necessarily aligned, then do the size calculation directly.
- // If the next bit is set in the header bitmap, then the size is one
- // quantum. Otherwise, read the size field.
- if (!BITARRAY_BIT(block_header, block_index+1))
- msize = TINY_FREE_SIZE(mapped_ptr);
- else
- msize = 1;
-
- if (!msize)
- break;
- } else if (range.address + block_offset != last_tiny_free_ptr) {
- msize = 1;
- bit = block_index + 1;
- while (! BITARRAY_BIT(block_header, bit)) {
- bit++;
- msize ++;
- }
- buffer[count].address = range.address + block_offset;
- buffer[count].size = TINY_BYTES_FOR_MSIZE(msize);
- count++;
- if (count >= MAX_RECORDER_BUFFER) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
- count = 0;
- }
- } else {
- // Block is not free but it matches last_tiny_free_ptr so even
- // though it is not marked free in the bitmap, we treat it as if
- // it is and move on
- msize = last_tiny_free_msize;
- }
- block_index += msize;
- }
- }
- }
- }
- if (count) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
- }
- return 0;
-}
-
-static void *
-tiny_malloc_from_free_list(szone_t *szone, msize_t msize)
-{
- // Assumes we've locked the region
- free_list_t *ptr;
- msize_t this_msize;
- grain_t slot = msize - 1;
- free_list_t **free_list = szone->tiny_free_list;
- free_list_t **the_slot = free_list + slot;
- free_list_t *next;
- free_list_t **limit;
- unsigned bitmap;
- msize_t leftover_msize;
- free_list_t *leftover_ptr;
-
- // Assumes locked
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
-
- // Look for an exact match by checking the freelist for this msize.
- //
- ptr = *the_slot;
- if (ptr) {
- next = free_list_unchecksum_ptr(ptr->next);
- if (next) {
- next->previous = ptr->previous;
- } else {
- BITMAP32_CLR(szone->tiny_bitmap, slot);
- }
- *the_slot = next;
- this_msize = msize;
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), exact match ptr=%p, this_msize=%d\n", ptr, this_msize);
- }
-#endif
- goto return_tiny_alloc;
- }
-
- // Mask off the bits representing slots holding free blocks smaller than the
- // size we need. If there are no larger free blocks, try allocating from
- // the free space at the end of the tiny region.
- bitmap = szone->tiny_bitmap & ~ ((1 << slot) - 1);
- if (!bitmap)
- goto try_tiny_malloc_from_end;
-
- slot = BITMAP32_CTZ(bitmap);
- limit = free_list + NUM_TINY_SLOTS - 1;
- free_list += slot;
-
- // Iterate over freelists looking for free blocks, starting at first list
- // which is not empty, and contains blocks which are large enough to satisfy
- // our request.
- while (free_list < limit) {
- ptr = *free_list;
- if (ptr) {
- next = free_list_unchecksum_ptr(ptr->next);
- *free_list = next;
- this_msize = get_tiny_free_size(ptr);
- if (next) {
- next->previous = ptr->previous;
- } else {
- BITMAP32_CLR(szone->tiny_bitmap, this_msize - 1);
- }
- goto add_leftover_and_proceed;
- }
- free_list++;
- }
-
- // We are now looking at the last slot, which contains blocks equal to, or
- // due to coalescing of free blocks, larger than 31 * tiny quantum size.
- // If the last freelist is not empty, and the head contains a block that is
- // larger than our request, then the remainder is put back on the free list.
- ptr = *limit;
- if (ptr) {
- free_list_checksum(szone, ptr, __PRETTY_FUNCTION__);
- this_msize = get_tiny_free_size(ptr);
- next = free_list_unchecksum_ptr(ptr->next);
- if (this_msize - msize >= NUM_TINY_SLOTS) {
- // the leftover will go back to the free list, so we optimize by
- // modifying the free list rather than a pop and push of the head
- leftover_msize = this_msize - msize;
- leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize));
- *limit = leftover_ptr;
- if (next) {
- next->previous.u = free_list_checksum_ptr(leftover_ptr);
- }
- leftover_ptr->previous = ptr->previous;
- leftover_ptr->next = ptr->next;
- set_tiny_meta_header_free(leftover_ptr, leftover_msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), last slot ptr=%p, msize=%d this_msize=%d\n", ptr, msize, this_msize);
- }
-#endif
- this_msize = msize;
- goto return_tiny_alloc;
- }
- if (next) {
- next->previous = ptr->previous;
- }
- *limit = next;
- goto add_leftover_and_proceed;
- }
-
-try_tiny_malloc_from_end:
- // Let's see if we can use szone->tiny_bytes_free_at_end
- if (szone->tiny_bytes_free_at_end >= TINY_BYTES_FOR_MSIZE(msize)) {
- ptr = (free_list_t *)(TINY_REGION_END(szone->last_tiny_region) - szone->tiny_bytes_free_at_end);
- szone->tiny_bytes_free_at_end -= TINY_BYTES_FOR_MSIZE(msize);
- if (szone->tiny_bytes_free_at_end) {
- // let's add an in use block after ptr to serve as boundary
- set_tiny_meta_header_in_use((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize), 1);
- }
- this_msize = msize;
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), from end ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
- goto return_tiny_alloc;
- }
- return NULL;
-
-add_leftover_and_proceed:
- if (!this_msize || (this_msize > msize)) {
- leftover_msize = this_msize - msize;
- leftover_ptr = (free_list_t *)((unsigned char *)ptr + TINY_BYTES_FOR_MSIZE(msize));
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize);
- }
-#endif
- tiny_free_list_add_ptr(szone, leftover_ptr, leftover_msize);
- this_msize = msize;
- }
-
-return_tiny_alloc:
- szone->num_tiny_objects++;
- szone->num_bytes_in_tiny_objects += TINY_BYTES_FOR_MSIZE(this_msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize);
- }
-#endif
- set_tiny_meta_header_in_use(ptr, this_msize);
- return ptr;
-}
-
-static INLINE void *
-tiny_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested)
-{
- boolean_t locked = 0;
- void *ptr;
-
-#if DEBUG_MALLOC
- if (!msize) {
- szone_error(szone, "invariant broken (!msize) in allocation (region)", NULL, NULL);
- return(NULL);
- }
-#endif
-#if TINY_CACHE
- ptr = szone->last_tiny_free;
- if ((((uintptr_t)ptr) & (TINY_QUANTUM - 1)) == msize) {
- // we have a candidate - let's lock to make sure
- LOCK_AND_NOTE_LOCKED(szone, locked);
- if (ptr == szone->last_tiny_free) {
- szone->last_tiny_free = NULL;
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- ptr = (void *)((uintptr_t)ptr & ~ (TINY_QUANTUM - 1));
- if (cleared_requested) {
- memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize));
- }
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in tiny_malloc_should_clear(), tiny cache ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
- return ptr;
- }
- }
-#endif
- // Except in rare occasions where we need to add a new region, we are going to end up locking, so we might as well lock right away to avoid doing unnecessary optimistic probes
- if (!locked) LOCK_AND_NOTE_LOCKED(szone, locked);
- ptr = tiny_malloc_from_free_list(szone, msize);
- if (ptr) {
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- if (cleared_requested) {
- memset(ptr, 0, TINY_BYTES_FOR_MSIZE(msize));
- }
- return ptr;
- }
- ptr = tiny_malloc_from_region_no_lock(szone, msize);
- // we don't clear because this freshly allocated space is pristine
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- return ptr;
-}
-
-static INLINE void
-free_tiny(szone_t *szone, void *ptr, region_t *tiny_region)
-{
- msize_t msize;
- boolean_t is_free;
-#if TINY_CACHE
- void *ptr2;
-#endif
-
- // ptr is known to be in tiny_region
- SZONE_LOCK(szone);
-#if TINY_CACHE
- ptr2 = szone->last_tiny_free;
- /* check that we don't already have this pointer in the cache */
- if (ptr == (void *)((uintptr_t)ptr2 & ~ (TINY_QUANTUM - 1))) {
- szone_error(szone, "double free", ptr, NULL);
- return;
- }
-#endif /* TINY_CACHE */
- msize = get_tiny_meta_header(ptr, &is_free);
- if (is_free) {
- szone_error(szone, "double free", ptr, NULL);
- return;
- }
-#if DEBUG_MALLOC
- if (!msize) {
- malloc_printf("*** szone_free() block in use is too large: %p\n", ptr);
- return;
- }
-#endif
-#if TINY_CACHE
- if (msize < TINY_QUANTUM) { // to see if the bits fit in the last 4 bits
- if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && msize)
- memset(ptr, 0x55, TINY_BYTES_FOR_MSIZE(msize));
- szone->last_tiny_free = (void *)(((uintptr_t)ptr) | msize);
- if (!ptr2) {
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- return;
- }
- msize = (uintptr_t)ptr2 & (TINY_QUANTUM - 1);
- ptr = (void *)(((uintptr_t)ptr2) & ~(TINY_QUANTUM - 1));
- tiny_region = tiny_region_for_ptr_no_lock(szone, ptr);
- if (!tiny_region) {
- szone_error(szone, "double free (tiny cache)", ptr, NULL);
- }
- }
-#endif
- tiny_free_no_lock(szone, tiny_region, ptr, msize);
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
-}
-
-static void
-print_tiny_free_list(szone_t *szone)
-{
- grain_t slot = 0;
- free_list_t *ptr;
- _SIMPLE_STRING b = _simple_salloc();
-
- if (b) {
- _simple_sappend(b, "tiny free sizes: ");
- while (slot < NUM_TINY_SLOTS) {
- ptr = szone->tiny_free_list[slot];
- if (ptr) {
- _simple_sprintf(b, "%s%y[%d]; ", (slot == NUM_TINY_SLOTS-1) ? ">=" : "", (slot+1)*TINY_QUANTUM, free_list_count(ptr));
- }
- slot++;
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-
-static void
-print_tiny_region(boolean_t verbose, region_t region, size_t bytes_at_end)
-{
- unsigned counts[1024];
- unsigned in_use = 0;
- uintptr_t start = (uintptr_t)TINY_REGION_ADDRESS(region);
- uintptr_t current = start;
- uintptr_t limit = (uintptr_t)TINY_REGION_END(region) - bytes_at_end;
- boolean_t is_free;
- msize_t msize;
- unsigned ci;
- _SIMPLE_STRING b;
-
- memset(counts, 0, 1024 * sizeof(unsigned));
- while (current < limit) {
- msize = get_tiny_meta_header((void *)current, &is_free);
- if (is_free & !msize && (current == start)) {
- // first block is all free
- break;
- }
- if (!msize) {
- malloc_printf("*** error with %p: msize=%d\n", (void *)current, (unsigned)msize);
- break;
- }
- if (!is_free) {
- // block in use
- if (msize > 32)
- malloc_printf("*** error at %p msize for in_use is %d\n", (void *)current, msize);
- if (msize < 1024)
- counts[msize]++;
- in_use++;
- }
- current += TINY_BYTES_FOR_MSIZE(msize);
- }
- if ((b = _simple_salloc()) != NULL) {
- _simple_sprintf(b, "Tiny region [%p-%p, %y]\t", (void *)start, TINY_REGION_END(region), (int)TINY_REGION_SIZE);
- _simple_sprintf(b, "In_use=%d ", in_use);
- if (bytes_at_end) _simple_sprintf(b, "untouched=%ly", bytes_at_end);
- if (verbose && in_use) {
- _simple_sappend(b, "\n\tSizes in use: ");
- for (ci = 0; ci < 1024; ci++)
- if (counts[ci])
- _simple_sprintf(b, "%d[%d]", TINY_BYTES_FOR_MSIZE(ci), counts[ci]);
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-
-static boolean_t
-tiny_free_list_check(szone_t *szone, grain_t slot)
-{
- unsigned count = 0;
- free_list_t *ptr = szone->tiny_free_list[slot];
- free_list_t *previous = NULL;
- boolean_t is_free;
-
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
- while (ptr) {
- free_list_checksum(szone, ptr, __PRETTY_FUNCTION__);
- is_free = tiny_meta_header_is_free(ptr);
- if (! is_free) {
- malloc_printf("*** in-use ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr);
- return 0;
- }
- if (((uintptr_t)ptr) & (TINY_QUANTUM - 1)) {
- malloc_printf("*** unaligned ptr in free list slot=%d count=%d ptr=%p\n", slot, count, ptr);
- return 0;
- }
- if (!tiny_region_for_ptr_no_lock(szone, ptr)) {
- malloc_printf("*** ptr not in szone slot=%d count=%d ptr=%p\n", slot, count, ptr);
- return 0;
- }
- if (free_list_unchecksum_ptr(ptr->previous) != previous) {
- malloc_printf("*** previous incorrectly set slot=%d count=%d ptr=%p\n", slot, count, ptr);
- return 0;
- }
- previous = ptr;
- ptr = free_list_unchecksum_ptr(ptr->next);
- count++;
- }
- return 1;
-}
-
-/********************* SMALL FREE LIST UTILITIES ************************/
-
-/*
- * Mark a block as free. Only the first quantum of a block is marked thusly,
- * the remainder are marked "middle".
- */
-static INLINE void
-small_meta_header_set_is_free(msize_t *meta_headers, unsigned index, msize_t msize)
-{
- meta_headers[index] = msize | SMALL_IS_FREE;
-}
-
-/*
- * Mark a block as in use. Only the first quantum of a block is marked thusly,
- * the remainder are marked "middle".
- */
-static INLINE void
-small_meta_header_set_in_use(msize_t *meta_headers, msize_t index, msize_t msize)
-{
- meta_headers[index] = msize;
-}
-
-/*
- * Mark a quantum as being the second or later in a block.
- */
-static INLINE void
-small_meta_header_set_middle(msize_t *meta_headers, msize_t index)
-{
- meta_headers[index] = 0;
-}
-
-// Adds an item to the proper free list
-// Also marks the header of the block properly
-// Assumes szone has been locked
-static void
-small_free_list_add_ptr(szone_t *szone, void *ptr, msize_t msize)
-{
- grain_t slot = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1;
- free_list_t *free_ptr = ptr;
- free_list_t *free_head = szone->small_free_list[slot];
- void *follower;
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize);
- }
- if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) {
- szone_error(szone, "small_free_list_add_ptr: Unaligned ptr", ptr, NULL);
- }
-#endif
- if (free_head) {
- free_list_checksum(szone, free_head, __PRETTY_FUNCTION__);
-#if DEBUG_MALLOC
- if (free_list_unchecksum_ptr(free_head->previous)) {
- szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head->previous)", ptr,
- "ptr=%p slot=%d free_head=%p previous=%p\n", ptr, slot, free_head, free_head->previous.p);
- }
- if (!SMALL_PTR_IS_FREE(free_head)) {
- szone_error(szone, "small_free_list_add_ptr: Internal invariant broken (free_head is not a free pointer)", ptr,
- "ptr=%p slot=%d free_head=%p\n", ptr, slot, free_head);
- }
-#endif
- free_head->previous.u = free_list_checksum_ptr(free_ptr);
- } else {
- BITMAP32_SET(szone->small_bitmap, slot);
- }
- free_ptr->previous.p = NULL;
- free_ptr->next.p = free_head;
- free_list_set_checksum(szone, free_ptr);
- szone->small_free_list[slot] = free_ptr;
- follower = ptr + SMALL_BYTES_FOR_MSIZE(msize);
- SMALL_PREVIOUS_MSIZE(follower) = msize;
-}
-
-// Removes item in the proper free list
-// msize could be read, but all callers have it so we pass it in
-// Assumes szone has been locked
-static void
-small_free_list_remove_ptr(szone_t *szone, void *ptr, msize_t msize)
-{
- grain_t slot = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1;
- free_list_t *free_ptr = ptr, *next, *previous;
- free_list_checksum(szone, free_ptr, __PRETTY_FUNCTION__);
-
- next = free_list_unchecksum_ptr(free_ptr->next);
- previous = free_list_unchecksum_ptr(free_ptr->previous);
-
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("In %s, ptr=%p, msize=%d\n", __FUNCTION__, ptr, msize);
- }
-#endif
- if (!previous) {
- // The block to remove is the head of the free list
-#if DEBUG_MALLOC
- if (szone->small_free_list[slot] != ptr) {
- szone_error(szone, "small_free_list_remove_ptr: Internal invariant broken (szone->small_free_list[grain])", ptr,
- "ptr=%p slot=%d msize=%d szone->small_free_list[slot]=%p\n",
- ptr, slot, msize, szone->small_free_list[slot]);
- return;
- }
-#endif
- szone->small_free_list[slot] = next;
- if (!next) BITMAP32_CLR(szone->small_bitmap, slot);
- } else {
- // We know free_ptr is already checksummed, so we don't need to do it
- // again.
- previous->next = free_ptr->next;
- }
- if (next) {
- // We know free_ptr is already checksummed, so we don't need to do it
- // again.
- next->previous = free_ptr->previous;
- }
-}
-
-static INLINE region_t *
-small_region_for_ptr_no_lock(szone_t *szone, const void *ptr)
-{
- return hash_lookup_region_no_lock(szone->small_regions,
- szone->num_small_regions_allocated,
- SMALL_REGION_FOR_PTR(ptr));
-}
-
-static INLINE void
-small_free_no_lock(szone_t *szone, region_t *region, void *ptr, msize_t msize)
-{
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
- unsigned index = SMALL_META_INDEX_FOR_PTR(ptr);
- size_t original_size = SMALL_BYTES_FOR_MSIZE(msize);
- unsigned char *next_block = ((unsigned char *)ptr + original_size);
- msize_t next_index = index + msize;
- msize_t previous_msize, next_msize;
- void *previous;
-
- // Assumes locked
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
- if (! msize) {
- szone_error(szone, "trying to free small block that is too small", ptr,
- "in small_free_no_lock(), ptr=%p, msize=%d\n", ptr, msize);
- }
-#endif
- // We try to coalesce this block with the preceeding one
- if (index && (SMALL_PREVIOUS_MSIZE(ptr) <= index)) {
- previous_msize = SMALL_PREVIOUS_MSIZE(ptr);
- if (meta_headers[index - previous_msize] == (previous_msize | SMALL_IS_FREE)) {
- previous = ptr - SMALL_BYTES_FOR_MSIZE(previous_msize);
- // previous is really to be coalesced
-#if DEBUG_MALLOC
- if (LOG(szone, ptr) || LOG(szone,previous)) {
- malloc_printf("in small_free_no_lock(), coalesced backwards for %p previous=%p\n", ptr, previous);
- }
-#endif
- small_free_list_remove_ptr(szone, previous, previous_msize);
- small_meta_header_set_middle(meta_headers, index);
- ptr = previous;
- msize += previous_msize;
- index -= previous_msize;
- }
- }
- // We try to coalesce with the next block
- if ((next_block < SMALL_REGION_END(*region)) && (meta_headers[next_index] & SMALL_IS_FREE)) {
- // next block is free, we coalesce
- next_msize = meta_headers[next_index] & ~ SMALL_IS_FREE;
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) malloc_printf("In small_free_no_lock(), for ptr=%p, msize=%d coalesced next block=%p next_msize=%d\n", ptr, msize, next_block, next_msize);
-#endif
- small_free_list_remove_ptr(szone, next_block, next_msize);
- small_meta_header_set_middle(meta_headers, next_index);
- msize += next_msize;
- }
- if (szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) {
- if (!msize) {
- szone_error(szone, "incorrect size information - block header was damaged", ptr, NULL);
- } else {
- memset(ptr, 0x55, SMALL_BYTES_FOR_MSIZE(msize));
- }
- }
- small_free_list_add_ptr(szone, ptr, msize);
- small_meta_header_set_is_free(meta_headers, index, msize);
- szone->num_small_objects--;
- szone->num_bytes_in_small_objects -= original_size; // we use original_size and not msize to avoid double counting the coalesced blocks
-}
-
-static void *
-small_malloc_from_region_no_lock(szone_t *szone, msize_t msize)
-{
- void *last_block;
- void *ptr;
- void *new_address;
- msize_t *meta_headers;
- msize_t index ;
- msize_t msize_left;
-
- // Allocates from the last region or a freshly allocated region
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
- // Before anything we transform the small_bytes_free_at_end - if any - to a regular free block
- if (szone->small_bytes_free_at_end) {
- last_block = (void *)(SMALL_REGION_END(szone->last_small_region) - szone->small_bytes_free_at_end);
- small_free_list_add_ptr(szone, last_block, SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end));
- *SMALL_METADATA_FOR_PTR(last_block) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end) | SMALL_IS_FREE;
- szone->small_bytes_free_at_end = 0;
- }
- // time to create a new region
- new_address = allocate_pages(szone, SMALL_REGION_SIZE, SMALL_BLOCKS_ALIGN,
- 0, VM_MEMORY_MALLOC_SMALL);
- if (!new_address)
- return NULL;
-
- ptr = new_address;
- meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
- index = 0;
-
- // Check to see if the hash ring of small regions needs to grow. Try to
- // avoid the hash ring becoming too dense.
- if (szone->num_small_regions_allocated < (2 * szone->num_small_regions)) {
- region_t *new_regions;
- size_t new_size;
- new_regions = hash_regions_grow_no_lock(szone, szone->small_regions,
- szone->num_small_regions_allocated,
- &new_size);
- // Do not deallocate the current small_regions allocation since someone
- // may be iterating it. Instead, just leak it.
- szone->small_regions = new_regions;
- szone->num_small_regions_allocated = new_size;
- }
- // Insert the new region into the hash ring, and update malloc statistics
- hash_region_insert_no_lock(szone->small_regions,
- szone->num_small_regions_allocated,
- new_address);
- szone->last_small_region = new_address;
-
- // we bump the number of regions AFTER we have changes the regions pointer
- // to enable finding a small region without taking the lock
- //
- // FIXME: naive assumption assumes memory ordering coherence between this
- // and other CPUs. This also applies to the near-identical code in
- // tiny_malloc_from_region_no_lock.
- szone->num_small_regions++;
- small_meta_header_set_in_use(meta_headers, index, msize);
- msize_left = NUM_SMALL_BLOCKS - index;
- szone->num_small_objects++;
- szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(msize);
- // add a big free block
- index += msize; msize_left -= msize;
- meta_headers[index] = msize_left;
- szone->small_bytes_free_at_end = SMALL_BYTES_FOR_MSIZE(msize_left);
- return ptr;
-}
-
-static INLINE boolean_t
-try_realloc_small_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size)
-{
- // returns 1 on success
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
- unsigned index = SMALL_META_INDEX_FOR_PTR(ptr);
- msize_t old_msize = SMALL_MSIZE_FOR_BYTES(old_size);
- msize_t new_msize = SMALL_MSIZE_FOR_BYTES(new_size + SMALL_QUANTUM - 1);
- void *next_block = (char *)ptr + old_size;
- unsigned next_index = index + old_msize;
- msize_t next_msize_and_free;
- msize_t next_msize;
- msize_t leftover_msize;
- void *leftover;
- unsigned leftover_index;
-
- if (next_index >= NUM_SMALL_BLOCKS) {
- return 0;
- }
-#if DEBUG_MALLOC
- if ((uintptr_t)next_block & (SMALL_QUANTUM - 1)) {
- szone_error(szone, "internal invariant broken in realloc(next_block)", next_block, NULL);
- }
- if (meta_headers[index] != old_msize)
- malloc_printf("*** try_realloc_small_in_place incorrect old %d %d\n",
- meta_headers[index], old_msize);
-#endif
- SZONE_LOCK(szone);
- /*
- * Look for a free block immediately afterwards. If it's large enough, we can consume (part of)
- * it.
- */
- next_msize_and_free = meta_headers[next_index];
- next_msize = next_msize_and_free & ~ SMALL_IS_FREE;
- if (!(next_msize_and_free & SMALL_IS_FREE) || (old_msize + next_msize < new_msize)) {
- SZONE_UNLOCK(szone);
- return 0;
- }
- /*
- * The following block is big enough; pull it from its freelist and chop off enough to satisfy
- * our needs.
- */
- small_free_list_remove_ptr(szone, next_block, next_msize);
- small_meta_header_set_middle(meta_headers, next_index);
- leftover_msize = old_msize + next_msize - new_msize;
- if (leftover_msize) {
- /* there's some left, so put the remainder back */
- leftover = (unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(new_msize);
- small_free_list_add_ptr(szone, leftover, leftover_msize);
- leftover_index = index + new_msize;
- small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize);
- }
-#if DEBUG_MALLOC
- if (SMALL_BYTES_FOR_MSIZE(new_msize) >= LARGE_THRESHOLD) {
- malloc_printf("*** realloc in place for %p exceeded msize=%d\n", new_msize);
- }
-#endif
- small_meta_header_set_in_use(meta_headers, index, new_msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in szone_realloc(), ptr=%p, msize=%d\n", ptr, *SMALL_METADATA_FOR_PTR(ptr));
- }
-#endif
- szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(new_msize - old_msize);
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- return 1;
-}
-
-static boolean_t
-szone_check_small_region(szone_t *szone, region_t region)
-{
- unsigned char *ptr = SMALL_REGION_ADDRESS(region);
- msize_t *meta_headers = SMALL_META_HEADER_FOR_PTR(ptr);
- unsigned char *region_end = SMALL_REGION_END(region);
- msize_t prev_free = 0;
- unsigned index;
- msize_t msize_and_free;
- msize_t msize;
- free_list_t *free_head;
- void *previous, *next;
- msize_t *follower;
-
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
- if (region == szone->last_small_region) region_end -= szone->small_bytes_free_at_end;
- while (ptr < region_end) {
- index = SMALL_META_INDEX_FOR_PTR(ptr);
- msize_and_free = meta_headers[index];
- if (!(msize_and_free & SMALL_IS_FREE)) {
- // block is in use
- msize = msize_and_free;
- if (!msize) {
- malloc_printf("*** invariant broken: null msize ptr=%p num_small_regions=%d end=%p\n",
- ptr, szone->num_small_regions, region_end);
- return 0;
- }
- if (msize > (LARGE_THRESHOLD / SMALL_QUANTUM)) {
- malloc_printf("*** invariant broken for %p this small msize=%d - size is too large\n",
- ptr, msize_and_free);
- return 0;
- }
- ptr += SMALL_BYTES_FOR_MSIZE(msize);
- prev_free = 0;
- } else {
- // free pointer
- msize = msize_and_free & ~ SMALL_IS_FREE;
- free_head = (free_list_t *)ptr;
- follower = (msize_t *)FOLLOWING_SMALL_PTR(ptr, msize);
- if (!msize) {
- malloc_printf("*** invariant broken for free block %p this msize=%d\n", ptr, msize);
- return 0;
- }
- if (prev_free) {
- malloc_printf("*** invariant broken for %p (2 free in a row)\n", ptr);
- return 0;
- }
- free_list_checksum(szone, free_head, __PRETTY_FUNCTION__);
- previous = free_list_unchecksum_ptr(free_head->previous);
- next = free_list_unchecksum_ptr(free_head->next);
- if (previous && !SMALL_PTR_IS_FREE(previous)) {
- malloc_printf("*** invariant broken for %p (previous %p is not a free pointer)\n",
- ptr, free_head->previous);
- return 0;
- }
- if (next && !SMALL_PTR_IS_FREE(next)) {
- malloc_printf("*** invariant broken for %p (next is not a free pointer)\n", ptr);
- return 0;
- }
- if (SMALL_PREVIOUS_MSIZE(follower) != msize) {
- malloc_printf("*** invariant broken for small free %p followed by %p in region [%p-%p] "
- "(end marker incorrect) should be %d; in fact %d\n",
- ptr, follower, SMALL_REGION_ADDRESS(region), region_end, msize, SMALL_PREVIOUS_MSIZE(follower));
- return 0;
- }
- ptr = (unsigned char *)follower;
- prev_free = SMALL_IS_FREE;
- }
- }
- return 1;
-}
-
-static kern_return_t
-small_in_use_enumerator(task_t task, void *context, unsigned type_mask, szone_t *szone, memory_reader_t reader, vm_range_recorder_t recorder)
-{
- size_t num_regions = szone->num_small_regions_allocated;
- void *last_small_free = szone->last_small_free;
- size_t index;
- region_t *regions;
- vm_range_t buffer[MAX_RECORDER_BUFFER];
- unsigned count = 0;
- kern_return_t err;
- region_t region;
- vm_range_t range;
- vm_range_t admin_range;
- vm_range_t ptr_range;
- unsigned char *mapped_region;
- msize_t *block_header;
- unsigned block_index;
- unsigned block_limit;
- msize_t msize_and_free;
- msize_t msize;
- vm_address_t last_small_free_ptr = 0;
- msize_t last_small_free_msize = 0;
-
- if (last_small_free) {
- last_small_free_ptr = (uintptr_t)last_small_free & ~(SMALL_QUANTUM - 1);
- last_small_free_msize = (uintptr_t)last_small_free & (SMALL_QUANTUM - 1);
- }
-
- err = reader(task, (vm_address_t)szone->small_regions, sizeof(region_t) * num_regions, (void **)®ions);
- if (err) return err;
- for (index = 0; index < num_regions; ++index) {
- region = regions[index];
- if (region) {
- range.address = (vm_address_t)SMALL_REGION_ADDRESS(region);
- range.size = SMALL_REGION_SIZE;
- if (type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) {
- admin_range.address = range.address + SMALL_HEADER_START;
- admin_range.size = SMALL_ARRAY_SIZE;
- recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &admin_range, 1);
- }
- if (type_mask & (MALLOC_PTR_REGION_RANGE_TYPE | MALLOC_ADMIN_REGION_RANGE_TYPE)) {
- ptr_range.address = range.address;
- ptr_range.size = NUM_SMALL_BLOCKS * SMALL_QUANTUM;
- recorder(task, context, MALLOC_PTR_REGION_RANGE_TYPE, &ptr_range, 1);
- }
- if (type_mask & MALLOC_PTR_IN_USE_RANGE_TYPE) {
- err = reader(task, range.address, range.size, (void **)&mapped_region);
- if (err) return err;
- block_header = (msize_t *)(mapped_region + SMALL_HEADER_START);
- block_index = 0;
- block_limit = NUM_SMALL_BLOCKS;
- if (region == szone->last_small_region)
- block_limit -= SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end);
- while (block_index < block_limit) {
- msize_and_free = block_header[block_index];
- msize = msize_and_free & ~ SMALL_IS_FREE;
- if (! (msize_and_free & SMALL_IS_FREE) &&
- range.address + SMALL_BYTES_FOR_MSIZE(block_index) != last_small_free_ptr) {
- // Block in use
- buffer[count].address = range.address + SMALL_BYTES_FOR_MSIZE(block_index);
- buffer[count].size = SMALL_BYTES_FOR_MSIZE(msize);
- count++;
- if (count >= MAX_RECORDER_BUFFER) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
- count = 0;
- }
- }
- block_index += msize;
- }
- }
- }
- }
- if (count) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE, buffer, count);
- }
- return 0;
-}
-
-static void *
-small_malloc_from_free_list(szone_t *szone, msize_t msize)
-{
- free_list_t *ptr;
- msize_t this_msize;
- grain_t slot = (msize <= NUM_SMALL_SLOTS) ? msize - 1 : NUM_SMALL_SLOTS - 1;
- free_list_t **free_list = szone->small_free_list;
- free_list_t *next;
- free_list_t **limit;
- unsigned bitmap = szone->small_bitmap & ~ ((1 << slot) - 1);
- msize_t leftover_msize;
- free_list_t *leftover_ptr;
- msize_t *meta_headers;
- unsigned leftover_index;
-
- // Assumes locked
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
-
- // Mask off the bits representing slots holding free blocks smaller than the
- // size we need. If there are no larger free blocks, try allocating from
- // the free space at the end of the tiny region.
- if (!bitmap)
- goto try_small_from_end;
-
- slot = BITMAP32_CTZ(bitmap);
- limit = free_list + NUM_SMALL_SLOTS - 1;
- free_list += slot;
-
- // Iterate over freelists looking for free blocks, starting at first list
- // which is not empty, and contains blocks which are large enough to satisfy
- // our request.
- while (free_list < limit) {
- ptr = *free_list;
- if (ptr) {
- next = free_list_unchecksum_ptr(ptr->next);
- *free_list = next;
- this_msize = SMALL_PTR_SIZE(ptr);
- if (next) {
- next->previous = ptr->previous;
- } else {
- BITMAP32_CLR(szone->small_bitmap, this_msize - 1);
- }
- goto add_leftover_and_proceed;
- }
- free_list++;
- }
-
- // We are now looking at the last slot, which contains blocks equal to, or
- // due to coalescing of free blocks, larger than 31 * small quantum size.
- // If the last freelist is not empty, and the head contains a block that is
- // larger than our request, then the remainder is put back on the free list.
- //
- // FIXME: This code doesn't have the optimization from the 'tiny' codepath
- // that optimizes for the this_msize >= 2 * num slots
- // FIXME: this code also seems somewhat bogus. There's a check for
- // this_msize >= msize, but by definition we can't ask for a small
- // block larger than 31 small quanta, and every free block in this
- // slot has to be at least that large.
- ptr = *limit;
- while (ptr) {
- free_list_checksum(szone, ptr, __PRETTY_FUNCTION__);
- next = free_list_unchecksum_ptr(ptr->next);
- this_msize = SMALL_PTR_SIZE(ptr);
- if (this_msize >= msize) {
- small_free_list_remove_ptr(szone, ptr, this_msize);
- goto add_leftover_and_proceed;
- }
- ptr = next;
- }
-
-try_small_from_end:
- // Let's see if we can use szone->small_bytes_free_at_end
- if (szone->small_bytes_free_at_end >= SMALL_BYTES_FOR_MSIZE(msize)) {
- ptr = (free_list_t *)(SMALL_REGION_END(szone->last_small_region) - szone->small_bytes_free_at_end);
- szone->small_bytes_free_at_end -= SMALL_BYTES_FOR_MSIZE(msize);
- if (szone->small_bytes_free_at_end) {
- // let's mark this block as in use to serve as boundary
- *SMALL_METADATA_FOR_PTR((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize)) = SMALL_MSIZE_FOR_BYTES(szone->small_bytes_free_at_end);
- }
- this_msize = msize;
- goto return_small_alloc;
- }
- return NULL;
-
-add_leftover_and_proceed:
- if (this_msize > msize) {
- leftover_msize = this_msize - msize;
- leftover_ptr = (free_list_t *)((unsigned char *)ptr + SMALL_BYTES_FOR_MSIZE(msize));
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in small_malloc_from_free_list(), adding leftover ptr=%p, this_msize=%d\n", ptr, this_msize);
- }
-#endif
- small_free_list_add_ptr(szone, leftover_ptr, leftover_msize);
- meta_headers = SMALL_META_HEADER_FOR_PTR(leftover_ptr);
- leftover_index = SMALL_META_INDEX_FOR_PTR(leftover_ptr);
- small_meta_header_set_is_free(meta_headers, leftover_index, leftover_msize);
- this_msize = msize;
- }
-
-return_small_alloc:
- szone->num_small_objects++;
- szone->num_bytes_in_small_objects += SMALL_BYTES_FOR_MSIZE(this_msize);
-#if DEBUG_MALLOC
- if (LOG(szone,ptr)) {
- malloc_printf("in small_malloc_from_free_list(), ptr=%p, this_msize=%d, msize=%d\n", ptr, this_msize, msize);
- }
-#endif
- *SMALL_METADATA_FOR_PTR(ptr) = this_msize;
- return ptr;
-}
-
-static INLINE void *
-small_malloc_should_clear(szone_t *szone, msize_t msize, boolean_t cleared_requested)
-{
- boolean_t locked = 0;
-#if SMALL_CACHE
- void *ptr;
-#endif
-
-#if SMALL_CACHE
- ptr = (void *)szone->last_small_free;
- if ((((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) == msize) {
- // we have a candidate - let's lock to make sure
- LOCK_AND_NOTE_LOCKED(szone, locked);
- if (ptr == (void *)szone->last_small_free) {
- szone->last_small_free = NULL;
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- ptr = (void *)((uintptr_t)ptr & ~ (SMALL_QUANTUM - 1));
- if (cleared_requested) {
- memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize));
- }
- return ptr;
- }
- }
-#endif
- // Except in rare occasions where we need to add a new region, we are going to end up locking,
- // so we might as well lock right away to avoid doing unnecessary optimistic probes
- if (!locked) LOCK_AND_NOTE_LOCKED(szone, locked);
- ptr = small_malloc_from_free_list(szone, msize);
- if (ptr) {
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- if (cleared_requested) {
- memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize));
- }
- return ptr;
- }
- ptr = small_malloc_from_region_no_lock(szone, msize);
- // we don't clear because this freshly allocated space is pristine
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- return ptr;
-}
-
-// tries to allocate a small, cleared block
-static INLINE void *
-small_malloc_cleared_no_lock(szone_t *szone, msize_t msize)
-{
- void *ptr;
-
- // Assumes already locked
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
- ptr = small_malloc_from_free_list(szone, msize);
- if (ptr) {
- memset(ptr, 0, SMALL_BYTES_FOR_MSIZE(msize));
- return ptr;
- } else {
- ptr = small_malloc_from_region_no_lock(szone, msize);
- // we don't clear because this freshly allocated space is pristine
- }
- return ptr;
-}
-
-static INLINE void
-free_small(szone_t *szone, void *ptr, region_t *small_region)
-{
- msize_t msize = SMALL_PTR_SIZE(ptr);
-#if SMALL_CACHE
- void *ptr2;
-#endif
-
- // ptr is known to be in small_region
- SZONE_LOCK(szone);
-#if SMALL_CACHE
- ptr2 = szone->last_small_free;
- /* check that we don't already have this pointer in the cache */
- if (ptr == (void *)((uintptr_t)ptr2 & ~ (SMALL_QUANTUM - 1))) {
- szone_error(szone, "double free", ptr, NULL);
- return;
- }
-#endif
- if (SMALL_PTR_IS_FREE(ptr)) {
- szone_error(szone, "double free", ptr, NULL);
- return;
- }
-#if SMALL_CACHE
- szone->last_small_free = (void *)(((uintptr_t)ptr) | msize);
- if (!ptr2) {
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- return;
- }
- msize = (uintptr_t)ptr2 & (SMALL_QUANTUM - 1);
- ptr = (void *)(((uintptr_t)ptr2) & ~ (SMALL_QUANTUM - 1));
- small_region = small_region_for_ptr_no_lock(szone, ptr);
- if (!small_region) {
- szone_error(szone, "double free (small cache)", ptr, NULL);
- return;
- }
-#endif
- small_free_no_lock(szone, small_region, ptr, msize);
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
-}
-
-static void
-print_small_free_list(szone_t *szone)
-{
- grain_t grain = 0;
- free_list_t *ptr;
- _SIMPLE_STRING b = _simple_salloc();
-
- if (b) {
- _simple_sappend(b, "small free sizes: ");
- while (grain < NUM_SMALL_SLOTS) {
- ptr = szone->small_free_list[grain];
- if (ptr) {
- _simple_sprintf(b, "%s%y[%d]; ", (grain == NUM_SMALL_SLOTS-1) ? ">=" : "", (grain + 1) * SMALL_QUANTUM, free_list_count(ptr));
- }
- grain++;
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-
-static void
-print_small_region(szone_t *szone, boolean_t verbose, region_t region, size_t bytes_at_end)
-{
- unsigned counts[1024];
- unsigned in_use = 0;
- void *start = SMALL_REGION_ADDRESS(region);
- void *limit = SMALL_REGION_END(region) - bytes_at_end;
- msize_t msize_and_free;
- msize_t msize;
- unsigned ci;
- _SIMPLE_STRING b;
-
- memset(counts, 0, 1024 * sizeof(unsigned));
- while (start < limit) {
- msize_and_free = *SMALL_METADATA_FOR_PTR(start);
- msize = msize_and_free & ~ SMALL_IS_FREE;
- if (!(msize_and_free & SMALL_IS_FREE)) {
- // block in use
- if (msize < 1024)
- counts[msize]++;
- in_use++;
- }
- start += SMALL_BYTES_FOR_MSIZE(msize);
- }
- if ((b = _simple_salloc()) != NULL) {
- _simple_sprintf(b, "Small region [%p-%p, %y]\tIn_use=%d ",
- SMALL_REGION_ADDRESS(region), SMALL_REGION_END(region), (int)SMALL_REGION_SIZE, in_use);
- if (bytes_at_end)
- _simple_sprintf(b, "Untouched=%ly", bytes_at_end);
- if (verbose && in_use) {
- _simple_sappend(b, "\n\tSizes in use: ");
- for (ci = 0; ci < 1024; ci++)
- if (counts[ci])
- _simple_sprintf(b, "%d[%d] ", SMALL_BYTES_FOR_MSIZE(ci), counts[ci]);
- }
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-
-static boolean_t
-small_free_list_check(szone_t *szone, grain_t grain)
-{
- unsigned count = 0;
- free_list_t *ptr = szone->small_free_list[grain];
- free_list_t *previous = NULL;
- msize_t msize_and_free;
-
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
- while (ptr) {
- msize_and_free = *SMALL_METADATA_FOR_PTR(ptr);
- count++;
- if (!(msize_and_free & SMALL_IS_FREE)) {
- malloc_printf("*** in-use ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr);
- return 0;
- }
- if (((uintptr_t)ptr) & (SMALL_QUANTUM - 1)) {
- malloc_printf("*** unaligned ptr in free list grain=%d count=%d ptr=%p\n", grain, count, ptr);
- return 0;
- }
- if (!small_region_for_ptr_no_lock(szone, ptr)) {
- malloc_printf("*** ptr not in szone grain=%d count=%d ptr=%p\n", grain, count, ptr);
- return 0;
- }
- free_list_checksum(szone, ptr, __PRETTY_FUNCTION__);
- if (free_list_unchecksum_ptr(ptr->previous) != previous) {
- malloc_printf("*** previous incorrectly set grain=%d count=%d ptr=%p\n", grain, count, ptr);
- return 0;
- }
- previous = ptr;
- ptr = free_list_unchecksum_ptr(ptr->next);
- }
- return 1;
-}
-
-/*******************************************************************************
- * Region hash implementation
- *
- * This is essentially a duplicate of the existing Large allocator hash, minus
- * the ability to remove entries. The two should be combined eventually.
- ******************************************************************************/
-#pragma mark region hash
-
-/*
- * hash_lookup_region_no_lock - Scan a hash ring looking for an entry for a
- * given region.
- *
- * FIXME: If consecutive queries of the same region are likely, a one-entry
- * cache would likely be a significant performance win here.
- */
-static region_t *
-hash_lookup_region_no_lock(region_t *regions, size_t num_entries, region_t r) {
- size_t index, hash_index;
- region_t *entry;
-
- if (!num_entries)
- return 0;
-
- index = hash_index = ((uintptr_t)r >> 20) % num_entries;
- do {
- entry = regions + index;
- if (*entry == 0)
- return 0;
- if (*entry == r)
- return entry;
- if (++index == num_entries)
- index = 0;
- } while (index != hash_index);
- return 0;
-}
-
-/*
- * hash_region_insert_no_lock - Insert a region into the hash ring.
- */
-static void
-hash_region_insert_no_lock(region_t *regions, size_t num_entries, region_t r) {
- size_t index, hash_index;
- region_t *entry;
-
- index = hash_index = ((uintptr_t)r >> 20) % num_entries;
- do {
- entry = regions + index;
- if (*entry == 0) {
- *entry = r;
- return;
- }
- if (++index == num_entries)
- index = 0;
- } while (index != hash_index);
-}
-
-/*
- * hash_regions_alloc_no_lock - Allocate space for a number of entries. This
- * must be a VM allocation as to avoid recursing between allocating a new small
- * region, and asking the small region to allocate space for the new list of
- * regions.
- */
-static region_t *
-hash_regions_alloc_no_lock(szone_t *szone, size_t num_entries)
-{
- size_t size = num_entries * sizeof(region_t);
- return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC);
-}
-
-/*
- * hash_regions_grow_no_lock - Grow the hash ring, and rehash the entries.
- * Return the new region and new size to update the szone. Do not deallocate
- * the old entries since someone may still be allocating them.
- */
-static region_t *
-hash_regions_grow_no_lock(szone_t *szone, region_t *regions, size_t old_size,
- size_t *new_size)
-{
- // double in size and allocate memory for the regions
- *new_size = old_size * 2 + 1;
- region_t *new_regions = hash_regions_alloc_no_lock(szone, *new_size);
-
- // rehash the entries into the new list
- size_t index;
- for (index = 0; index < old_size; ++index) {
- region_t r = regions[index];
- if (r != 0)
- hash_region_insert_no_lock(new_regions, *new_size, r);
- }
- return new_regions;
-}
-
-/*******************************************************************************
- * Large allocator implementation
- ******************************************************************************/
-#pragma mark large allocator
-
-#if DEBUG_MALLOC
-
-static void
-large_debug_print(szone_t *szone)
-{
- unsigned num_large_entries = szone->num_large_entries;
- unsigned index = num_large_entries;
- large_entry_t *range;
- _SIMPLE_STRING b = _simple_salloc();
-
- if (b) {
- for (index = 0, range = szone->large_entries; index < szone->num_large_entries; index++, range++)
- if (!LARGE_ENTRY_IS_EMPTY(*range))
- _simple_sprintf(b, "%d: %p(%y); ", index, LARGE_ENTRY_ADDRESS(*range), LARGE_ENTRY_SIZE(*range));
-
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX, "%s\n", _simple_string(b));
- _simple_sfree(b);
- }
-}
-#endif
-
-/*
- * Scan the hash ring looking for an entry for the given pointer.
- */
-static large_entry_t *
-large_entry_for_pointer_no_lock(szone_t *szone, const void *ptr)
-{
- // result only valid with lock held
- unsigned num_large_entries = szone->num_large_entries;
- unsigned hash_index;
- unsigned index;
- large_entry_t *range;
-
- if (!num_large_entries)
- return NULL;
- hash_index = ((uintptr_t)ptr >> vm_page_shift) % num_large_entries;
- index = hash_index;
- do {
- range = szone->large_entries + index;
- if (LARGE_ENTRY_MATCHES(*range, ptr))
- return range;
- if (LARGE_ENTRY_IS_EMPTY(*range))
- return NULL; // end of chain
- index++;
- if (index == num_large_entries)
- index = 0;
- } while (index != hash_index);
- return NULL;
-}
-
-static void
-large_entry_insert_no_lock(szone_t *szone, large_entry_t range)
-{
- unsigned num_large_entries = szone->num_large_entries;
- unsigned hash_index = (range.address_and_num_pages >> vm_page_shift) % num_large_entries;
- unsigned index = hash_index;
- large_entry_t *entry;
-
- do {
- entry = szone->large_entries + index;
- if (LARGE_ENTRY_IS_EMPTY(*entry)) {
- *entry = range;
- return; // end of chain
- }
- index++;
- if (index == num_large_entries)
- index = 0;
- } while (index != hash_index);
-}
-
-static INLINE void
-large_entries_rehash_after_entry_no_lock(szone_t *szone, large_entry_t *entry)
-{
- unsigned num_large_entries = szone->num_large_entries;
- unsigned hash_index = entry - szone->large_entries;
- unsigned index = hash_index;
- large_entry_t range;
-
- do {
- index++;
- if (index == num_large_entries)
- index = 0;
- range = szone->large_entries[index];
- if (LARGE_ENTRY_IS_EMPTY(range))
- return;
- szone->large_entries[index].address_and_num_pages = 0;
- large_entry_insert_no_lock(szone, range); // this will reinsert in the
- // proper place
- } while (index != hash_index);
-}
-
-static INLINE large_entry_t *
-large_entries_alloc_no_lock(szone_t *szone, unsigned num)
-{
- size_t size = num * sizeof(large_entry_t);
- boolean_t is_vm_allocation = size >= LARGE_THRESHOLD;
-
- if (is_vm_allocation) {
- // Note that we allocate memory (via a system call) under a spin lock
- // That is certainly evil, however it's very rare in the lifetime of a process
- // The alternative would slow down the normal case
- return allocate_pages(szone, round_page(size), 0, 0, VM_MEMORY_MALLOC_LARGE);
- } else {
- return small_malloc_cleared_no_lock(szone, SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1));
- }
-}
-
-static void
-large_entries_free_no_lock(szone_t *szone, large_entry_t *entries, unsigned num, vm_range_t *range_to_deallocate)
-{
- // returns range to deallocate
- size_t size = num * sizeof(large_entry_t);
- boolean_t is_vm_allocation = size >= LARGE_THRESHOLD;
- region_t *region;
- msize_t msize_and_free;
-
- if (is_vm_allocation) {
- range_to_deallocate->address = (vm_address_t)entries;
- range_to_deallocate->size = round_page(size);
- } else {
- range_to_deallocate->size = 0;
- region = small_region_for_ptr_no_lock(szone, entries);
- msize_and_free = *SMALL_METADATA_FOR_PTR(entries);
- if (msize_and_free & SMALL_IS_FREE) {
- szone_error(szone, "object already freed being freed", entries, NULL);
- return;
- }
- small_free_no_lock(szone, region, entries, msize_and_free);
- }
-}
-
-static large_entry_t *
-large_entries_grow_no_lock(szone_t *szone, vm_range_t *range_to_deallocate)
-{
- // sets range_to_deallocate
- unsigned old_num_entries = szone->num_large_entries;
- large_entry_t *old_entries = szone->large_entries;
- unsigned new_num_entries = (old_num_entries) ? old_num_entries * 2 + 1 : 63; // always an odd number for good hashing
- large_entry_t *new_entries = large_entries_alloc_no_lock(szone, new_num_entries);
- unsigned index = old_num_entries;
- large_entry_t oldRange;
-
- // if the allocation of new entries failed, bail
- if (new_entries == NULL)
- return NULL;
-
- szone->num_large_entries = new_num_entries;
- szone->large_entries = new_entries;
-
- /* rehash entries into the new list */
- while (index--) {
- oldRange = old_entries[index];
- if (!LARGE_ENTRY_IS_EMPTY(oldRange)) {
- large_entry_insert_no_lock(szone, oldRange);
- }
- }
- if (old_entries) {
- large_entries_free_no_lock(szone, old_entries, old_num_entries, range_to_deallocate);
- } else {
- range_to_deallocate->size = 0;
- }
- return new_entries;
-}
-
-// frees the specific entry in the size table
-// returns a range to truly deallocate
-static vm_range_t
-large_free_no_lock(szone_t *szone, large_entry_t *entry)
-{
- vm_range_t range;
-
- range.address = (vm_address_t)LARGE_ENTRY_ADDRESS(*entry);
- range.size = (vm_size_t)LARGE_ENTRY_SIZE(*entry);
- szone->num_large_objects_in_use--;
- szone->num_bytes_in_large_objects -= range.size;
- if (szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) {
- protect((void *)range.address, range.size, VM_PROT_READ | VM_PROT_WRITE, szone->debug_flags);
- range.address -= vm_page_size;
- range.size += 2 * vm_page_size;
- }
- entry->address_and_num_pages = 0;
- large_entries_rehash_after_entry_no_lock(szone, entry);
-#if DEBUG_MALLOC
- if (large_entry_for_pointer_no_lock(szone, (void *)range.address)) {
- malloc_printf("*** freed entry %p still in use; num_large_entries=%d\n",
- range.address, szone->num_large_entries);
- large_debug_print(szone);
- szone_sleep();
- }
-#endif
- return range;
-}
-
-static kern_return_t
-large_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t large_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder)
-{
- unsigned index = 0;
- vm_range_t buffer[MAX_RECORDER_BUFFER];
- unsigned count = 0;
- large_entry_t *entries;
- kern_return_t err;
- vm_range_t range;
- large_entry_t entry;
-
- err = reader(task, large_entries_address, sizeof(large_entry_t) * num_entries, (void **)&entries);
- if (err)
- return err;
- index = num_entries;
- if ((type_mask & MALLOC_ADMIN_REGION_RANGE_TYPE) &&
- (num_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD)) {
- range.address = large_entries_address;
- range.size = round_page(num_entries * sizeof(large_entry_t));
- recorder(task, context, MALLOC_ADMIN_REGION_RANGE_TYPE, &range, 1);
- }
- if (type_mask & (MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE))
- while (index--) {
- entry = entries[index];
- if (!LARGE_ENTRY_IS_EMPTY(entry)) {
- range.address = (vm_address_t)LARGE_ENTRY_ADDRESS(entry);
- range.size = (vm_size_t)LARGE_ENTRY_SIZE(entry);
- buffer[count++] = range;
- if (count >= MAX_RECORDER_BUFFER) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count);
- count = 0;
- }
- }
- }
- if (count) {
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE
- | MALLOC_PTR_REGION_RANGE_TYPE, buffer, count);
- }
- return 0;
-}
-
-/********************* HUGE ENTRY UTILITIES ************************/
-
-static huge_entry_t *
-huge_entry_for_pointer_no_lock(szone_t *szone, const void *ptr)
-{
- unsigned index;
- huge_entry_t *huge;
-
- for (index = szone->num_huge_entries, huge = szone->huge_entries;
- index > 0;
- index--, huge++) {
-
- if ((void *)huge->address == ptr)
- return huge;
- }
- return NULL;
-}
-
-static boolean_t
-huge_entry_append(szone_t *szone, huge_entry_t huge)
-{
- huge_entry_t *new_huge_entries = NULL, *old_huge_entries;
- unsigned num_huge_entries;
-
- // We do a little dance with locking because doing allocation (even in the
- // default szone) may cause something to get freed in this szone, with a
- // deadlock
- // Returns 1 on success
- SZONE_LOCK(szone);
- for (;;) {
- num_huge_entries = szone->num_huge_entries;
- SZONE_UNLOCK(szone);
- /* check for counter wrap */
- if ((num_huge_entries + 1) < num_huge_entries)
- return 0;
- /* stale allocation from last time around the loop? */
- if (new_huge_entries)
- szone_free(szone, new_huge_entries);
- new_huge_entries = szone_malloc(szone, (num_huge_entries + 1) * sizeof(huge_entry_t));
- if (new_huge_entries == NULL)
- return 0;
- SZONE_LOCK(szone);
- if (num_huge_entries == szone->num_huge_entries) {
- // No change - our malloc still applies
- old_huge_entries = szone->huge_entries;
- if (num_huge_entries) {
- memcpy(new_huge_entries, old_huge_entries, num_huge_entries * sizeof(huge_entry_t));
- }
- new_huge_entries[szone->num_huge_entries++] = huge;
- szone->huge_entries = new_huge_entries;
- SZONE_UNLOCK(szone);
- szone_free(szone, old_huge_entries);
- return 1;
- }
- // try again!
- }
-}
-
-static kern_return_t
-huge_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t huge_entries_address, unsigned num_entries, memory_reader_t reader, vm_range_recorder_t recorder)
-{
- huge_entry_t *entries;
- kern_return_t err;
-
- err = reader(task, huge_entries_address, sizeof(huge_entry_t) * num_entries, (void **)&entries);
- if (err)
- return err;
- if (num_entries)
- recorder(task, context, MALLOC_PTR_IN_USE_RANGE_TYPE | MALLOC_PTR_REGION_RANGE_TYPE, entries, num_entries);
-
- return 0;
-}
-
-static void *
-large_and_huge_malloc(szone_t *szone, size_t num_pages)
-{
- void *addr;
- vm_range_t range_to_deallocate;
- huge_entry_t huge_entry;
- size_t size;
- large_entry_t large_entry;
-
- if (!num_pages)
- num_pages = 1; // minimal allocation size for this szone
- size = (size_t)num_pages << vm_page_shift;
- range_to_deallocate.size = 0;
- if (num_pages >= (1 << vm_page_shift)) {
- addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MEMORY_MALLOC_HUGE);
- if (addr == NULL)
- return NULL;
- huge_entry.size = size;
- huge_entry.address = (vm_address_t)addr;
- if (!huge_entry_append(szone, huge_entry))
- return NULL; // we are leaking the allocation here
- SZONE_LOCK(szone);
- szone->num_bytes_in_huge_objects += size;
- } else {
-
- addr = allocate_pages(szone, size, 0, szone->debug_flags, VM_MEMORY_MALLOC_LARGE);
-#if DEBUG_MALLOC
- if (LOG(szone, addr))
- malloc_printf("in szone_malloc true large allocation at %p for %ly\n", (void *)addr, size);
-#endif
- SZONE_LOCK(szone);
- if (addr == NULL) {
- SZONE_UNLOCK(szone);
- return NULL;
- }
-#if DEBUG_MALLOC
- if (large_entry_for_pointer_no_lock(szone, addr)) {
- malloc_printf("freshly allocated is already in use: %p\n", addr);
- large_debug_print(szone);
- szone_sleep();
- }
-#endif
- if ((szone->num_large_objects_in_use + 1) * 4 > szone->num_large_entries) {
- // density of hash table too high; grow table
- // we do that under lock to avoid a race
- large_entry_t *entries = large_entries_grow_no_lock(szone, &range_to_deallocate);
- if (entries == NULL) {
- SZONE_UNLOCK(szone);
- return NULL;
- }
- }
- large_entry.address_and_num_pages = (uintptr_t)addr | num_pages;
-#if DEBUG_MALLOC
- if (large_entry_for_pointer_no_lock(szone, addr)) {
- malloc_printf("entry about to be added already in use: %p\n", addr);
- large_debug_print(szone);
- szone_sleep();
- }
-#endif
- large_entry_insert_no_lock(szone, large_entry);
-#if DEBUG_MALLOC
- if (!large_entry_for_pointer_no_lock(szone, (void *)addr)) {
- malloc_printf("can't find entry just added\n");
- large_debug_print(szone);
- szone_sleep();
- }
-#endif
- szone->num_large_objects_in_use ++;
- szone->num_bytes_in_large_objects += size;
- }
- SZONE_UNLOCK(szone);
- if (range_to_deallocate.size) {
- deallocate_pages(szone, (void *)range_to_deallocate.address, range_to_deallocate.size, 0); // we deallocate outside the lock
- }
- return (void *)addr;
-}
-
-static INLINE void
-free_large_or_huge(szone_t *szone, void *ptr)
-{
- // We have established ptr is page-aligned and not tiny nor small
- large_entry_t *entry;
- vm_range_t vm_range_to_deallocate;
- huge_entry_t *huge;
-
- SZONE_LOCK(szone);
- entry = large_entry_for_pointer_no_lock(szone, ptr);
- if (entry) {
- vm_range_to_deallocate = large_free_no_lock(szone, entry);
-#if DEBUG_MALLOC
- if (large_entry_for_pointer_no_lock(szone, ptr)) {
- malloc_printf("*** just after freeing %p still in use num_large_entries=%d\n", ptr, szone->num_large_entries);
- large_debug_print(szone);
- szone_sleep();
- }
-#endif
- } else if ((huge = huge_entry_for_pointer_no_lock(szone, ptr))) {
- vm_range_to_deallocate = *huge;
- *huge = szone->huge_entries[--szone->num_huge_entries]; // last entry fills that spot
- szone->num_bytes_in_huge_objects -= (size_t)vm_range_to_deallocate.size;
- } else {
-#if DEBUG_MALLOC
- large_debug_print(szone);
-#endif
- szone_error(szone, "pointer being freed was not allocated", ptr, NULL);
- return;
- }
- SZONE_UNLOCK(szone); // we release the lock asap
- CHECK(szone, __PRETTY_FUNCTION__);
- // we deallocate_pages, including guard pages
- if (vm_range_to_deallocate.address) {
-#if DEBUG_MALLOC
- if (large_entry_for_pointer_no_lock(szone, (void *)vm_range_to_deallocate.address)) {
- malloc_printf("*** invariant broken: %p still in use num_large_entries=%d\n", vm_range_to_deallocate.address, szone->num_large_entries);
- large_debug_print(szone);
- szone_sleep();
- }
-#endif
- deallocate_pages(szone, (void *)vm_range_to_deallocate.address, (size_t)vm_range_to_deallocate.size, 0);
- }
-}
-
-static INLINE int
-try_realloc_large_or_huge_in_place(szone_t *szone, void *ptr, size_t old_size, size_t new_size)
-{
- vm_address_t addr = (vm_address_t)ptr + old_size;
- large_entry_t *large_entry, saved_entry;
- huge_entry_t *huge_entry, huge;
- kern_return_t err;
-
-#if DEBUG_MALLOC
- if (old_size != ((old_size >> vm_page_shift) << vm_page_shift)) {
- malloc_printf("*** old_size is %d\n", old_size);
- }
-#endif
- SZONE_LOCK(szone);
- large_entry = large_entry_for_pointer_no_lock(szone, (void *)addr);
- SZONE_UNLOCK(szone);
- if (large_entry) {
- return 0; // large pointer already exists in table - extension is not going to work
- }
- new_size = round_page(new_size);
- /*
- * Ask for allocation at a specific address, and mark as realloc
- * to request coalescing with previous realloc'ed extensions.
- */
- err = vm_allocate(mach_task_self(), &addr, new_size - old_size, VM_MAKE_TAG(VM_MEMORY_REALLOC));
- if (err != KERN_SUCCESS) {
- return 0;
- }
- SZONE_LOCK(szone);
- /*
- * If the new size is still under the large/huge threshold, we can just
- * extend the existing large block.
- *
- * Note: this logic is predicated on the understanding that an allocated
- * block can never really shrink, so that the new size will always be
- * larger than the old size.
- *
- * Note: the use of 1 << vm_page_shift here has to do with the subdivision
- * of the bits in the large_entry_t, and not the size of a page (directly).
- */
- if ((new_size >> vm_page_shift) < (1 << vm_page_shift)) {
- /* extend existing large entry */
- large_entry = large_entry_for_pointer_no_lock(szone, ptr);
- if (!large_entry) {
- szone_error(szone, "large entry reallocated is not properly in table", ptr, NULL);
- /* XXX will cause fault on next reference to entry */
- }
- large_entry->address_and_num_pages = (uintptr_t)ptr | (new_size >> vm_page_shift);
- szone->num_bytes_in_large_objects += new_size - old_size;
- } else if ((old_size >> vm_page_shift) >= (1 << vm_page_shift)) {
- /* extend existing huge entry */
- huge_entry = huge_entry_for_pointer_no_lock(szone, ptr);
- if (!huge_entry) {
- szone_error(szone, "huge entry reallocated is not properly in table", ptr, NULL);
- /* XXX will cause fault on next reference to huge_entry */
- }
- huge_entry->size = new_size;
- szone->num_bytes_in_huge_objects += new_size - old_size;
- } else {
- /* need to convert large entry to huge entry */
-
- /* release large entry, note we still have the VM allocation */
- large_entry = large_entry_for_pointer_no_lock(szone, ptr);
- saved_entry = *large_entry; // in case we need to put it back
- large_free_no_lock(szone, large_entry);
-
- /* and get a huge entry */
- huge.address = (vm_address_t)ptr;
- huge.size = new_size; /* fix up size */
- SZONE_UNLOCK(szone);
- if (huge_entry_append(szone, huge)) {
- szone->num_bytes_in_huge_objects += new_size;
- return 1; // success!
- }
- SZONE_LOCK(szone);
- // we leak memory (the extra space appended) but data structures are correct
- large_entry_insert_no_lock(szone, saved_entry); // this will reinsert the large entry
- }
- SZONE_UNLOCK(szone); // we release the lock asap
- return 1;
-}
-
-/********************* Zone call backs ************************/
-
-static void
-szone_free(szone_t *szone, void *ptr)
-{
- region_t *tiny_region;
- region_t *small_region;
-
-#if DEBUG_MALLOC
- if (LOG(szone, ptr))
- malloc_printf("in szone_free with %p\n", ptr);
-#endif
- if (!ptr)
- return;
- /*
- * Try to free to a tiny region.
- */
- if ((uintptr_t)ptr & (TINY_QUANTUM - 1)) {
- szone_error(szone, "Non-aligned pointer being freed", ptr, NULL);
- return;
- }
- if ((tiny_region = tiny_region_for_ptr_no_lock(szone, ptr)) != NULL) {
- if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS) {
- szone_error(szone, "Pointer to metadata being freed", ptr, NULL);
- return;
- }
- free_tiny(szone, ptr, tiny_region);
- return;
- }
-
- /*
- * Try to free to a small region.
- */
- if ((uintptr_t)ptr & (SMALL_QUANTUM - 1)) {
- szone_error(szone, "Non-aligned pointer being freed (2)", ptr, NULL);
- return;
- }
- if ((small_region = small_region_for_ptr_no_lock(szone, ptr)) != NULL) {
- if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS) {
- szone_error(szone, "Pointer to metadata being freed (2)", ptr, NULL);
- return;
- }
- free_small(szone, ptr, small_region);
- return;
- }
-
- /* check that it's a legal large/huge allocation */
- if ((uintptr_t)ptr & (vm_page_size - 1)) {
- szone_error(szone, "non-page-aligned, non-allocated pointer being freed", ptr, NULL);
- return;
- }
- free_large_or_huge(szone, ptr);
-}
-
-static INLINE void *
-szone_malloc_should_clear(szone_t *szone, size_t size, boolean_t cleared_requested)
-{
- void *ptr;
- msize_t msize;
-
- if (size <= 31*TINY_QUANTUM) {
- // think tiny
- msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
- if (!msize)
- msize = 1;
- ptr = tiny_malloc_should_clear(szone, msize, cleared_requested);
- } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (size < LARGE_THRESHOLD)) {
- // think small
- msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1);
- if (! msize) msize = 1;
- ptr = small_malloc_should_clear(szone, msize, cleared_requested);
- } else {
- // large or huge
- size_t num_pages = round_page(size) >> vm_page_shift;
- if (num_pages == 0) /* Overflowed */
- ptr = 0;
- else
- ptr = large_and_huge_malloc(szone, num_pages);
- }
-#if DEBUG_MALLOC
- if (LOG(szone, ptr))
- malloc_printf("szone_malloc returned %p\n", ptr);
-#endif
- /*
- * If requested, scribble on allocated memory.
- */
- if ((szone->debug_flags & SCALABLE_MALLOC_DO_SCRIBBLE) && ptr && !cleared_requested && size)
- memset(ptr, 0xaa, size);
-
- return ptr;
-}
-
-static void *
-szone_malloc(szone_t *szone, size_t size) {
- return szone_malloc_should_clear(szone, size, 0);
-}
-
-static void *
-szone_calloc(szone_t *szone, size_t num_items, size_t size)
-{
- size_t total_bytes = num_items * size;
- if ((num_items > 1) && (size != 0) && ((total_bytes / size) != num_items))
- return NULL;
- return szone_malloc_should_clear(szone, total_bytes, 1);
-}
-
-static void *
-szone_valloc(szone_t *szone, size_t size)
-{
- void *ptr;
- size_t num_pages;
-
- num_pages = round_page(size) >> vm_page_shift;
- ptr = large_and_huge_malloc(szone, num_pages);
-#if DEBUG_MALLOC
- if (LOG(szone, ptr))
- malloc_printf("szone_valloc returned %p\n", ptr);
-#endif
- return ptr;
-}
-
-static size_t
-szone_size(szone_t *szone, const void *ptr)
-{
- size_t size = 0;
- boolean_t is_free;
- msize_t msize, msize_and_free;
- large_entry_t *entry;
- huge_entry_t *huge;
-
- if (!ptr)
- return 0;
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("in szone_size for %p (szone=%p)\n", ptr, szone);
- }
-#endif
-
- /*
- * Look for it in a tiny region.
- */
- if ((uintptr_t)ptr & (TINY_QUANTUM - 1))
- return 0;
- if (tiny_region_for_ptr_no_lock(szone, ptr)) {
- if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS)
- return 0;
- msize = get_tiny_meta_header(ptr, &is_free);
- return (is_free) ? 0 : TINY_BYTES_FOR_MSIZE(msize);
- }
-
- /*
- * Look for it in a small region.
- */
- if ((uintptr_t)ptr & (SMALL_QUANTUM - 1))
- return 0;
- if (small_region_for_ptr_no_lock(szone, ptr)) {
- if (SMALL_META_INDEX_FOR_PTR(ptr) >= NUM_SMALL_BLOCKS)
- return 0;
- msize_and_free = *SMALL_METADATA_FOR_PTR(ptr);
- return (msize_and_free & SMALL_IS_FREE) ? 0 : SMALL_BYTES_FOR_MSIZE(msize_and_free);
- }
-
- /*
- * If not page-aligned, it cannot have come from a large or huge allocation.
- */
- if ((uintptr_t)ptr & (vm_page_size - 1))
- return(0);
-
- /*
- * Look for it in a large or huge entry.
- */
- SZONE_LOCK(szone);
- entry = large_entry_for_pointer_no_lock(szone, ptr);
- if (entry) {
- size = LARGE_ENTRY_SIZE(*entry);
- } else if ((huge = huge_entry_for_pointer_no_lock(szone, ptr))) {
- size = huge->size;
- }
- SZONE_UNLOCK(szone);
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("szone_size for %p returned %d\n", ptr, (unsigned)size);
- }
-#endif
- return size;
-}
-
-static void *
-szone_realloc(szone_t *szone, void *ptr, size_t new_size)
-{
- size_t old_size;
- void *new_ptr;
-
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("in szone_realloc for %p, %d\n", ptr, (unsigned)new_size);
- }
-#endif
- if (!ptr) {
- ptr = szone_malloc(szone, new_size);
- return ptr;
- }
- old_size = szone_size(szone, ptr);
- if (!old_size) {
- szone_error(szone, "pointer being reallocated was not allocated", ptr, NULL);
- return NULL;
- }
- /* we never shrink an allocation */
- if (old_size >= new_size)
- return ptr;
-
- /*
- * If the old and new sizes both suit the tiny allocator, try to reallocate in-place.
- */
- if ((new_size + TINY_QUANTUM - 1) <= 31 * TINY_QUANTUM) {
- if (try_realloc_tiny_in_place(szone, ptr, old_size, new_size)) {
- return ptr;
- }
-
- /*
- * If the old and new sizes both suit the small allocator, and we're not protecting the
- * small allocations, try to reallocate in-place.
- */
- } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) &&
- ((new_size + SMALL_QUANTUM - 1) < LARGE_THRESHOLD) &&
- (old_size > 31 * TINY_QUANTUM)) {
- if (try_realloc_small_in_place(szone, ptr, old_size, new_size)) {
- return ptr;
- }
-
- /*
- * If the allocation's a large or huge allocation, try to reallocate in-place there.
- */
- } else if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (old_size > LARGE_THRESHOLD)) {
- if (try_realloc_large_or_huge_in_place(szone, ptr, old_size, new_size)) {
- return ptr;
- }
- }
-
- /*
- * Can't reallocate in place for whatever reason; allocate a new buffer and copy.
- */
- new_ptr = szone_malloc(szone, new_size);
- if (new_ptr == NULL)
- return NULL;
-
- /*
- * If the allocation's large enough, try to copy using VM. If that fails, or
- * if it's too small, just copy by hand.
- */
- if ((old_size < VM_COPY_THRESHOLD) ||
- vm_copy(mach_task_self(), (vm_address_t)ptr, old_size, (vm_address_t)new_ptr))
- memcpy(new_ptr, ptr, old_size);
- szone_free(szone, ptr);
-
-#if DEBUG_MALLOC
- if (LOG(szone, ptr)) {
- malloc_printf("szone_realloc returned %p for %d\n", new_ptr, (unsigned)new_size);
- }
-#endif
- return new_ptr;
-}
-
-// given a size, returns the number of pointers allocated capable of holding
-// that size, up to the limit specified by the 'count' argument. These pointers
-// are stored in the 'results' array, which must be allocated by the caller.
-// may return zero, since this function is only a best attempt at allocating
-// the pointers. clients should be prepared to call malloc for any additional
-// blocks they need.
-static unsigned
-szone_batch_malloc(szone_t *szone, size_t size, void **results, unsigned count)
-{
- msize_t msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
- unsigned found = 0;
-
- // only bother implementing this for tiny
- if (size > 31*TINY_QUANTUM)
- return 0;
- // make sure to return objects at least one quantum in size
- if (!msize)
- msize = 1;
-
- CHECK(szone, __PRETTY_FUNCTION__);
-
- // We must lock the zone now, since tiny_malloc_from_free_list assumes that
- // the caller has done so.
- SZONE_LOCK(szone);
-
- // with the zone locked, allocate objects from the free list until all
- // sufficiently large objects have been exhausted, or we have met our quota
- // of objects to allocate.
- while (found < count) {
- void *ptr = tiny_malloc_from_free_list(szone, msize);
- if (!ptr)
- break;
-
- *results++ = ptr;
- found++;
- }
- SZONE_UNLOCK(szone);
- return found;
-}
-
-static void
-szone_batch_free(szone_t *szone, void **to_be_freed, unsigned count)
-{
- unsigned cc = 0;
- void *ptr;
- region_t *tiny_region;
- boolean_t is_free;
- msize_t msize;
-
- // frees all the pointers in to_be_freed
- // note that to_be_freed may be overwritten during the process
- if (!count)
- return;
- CHECK(szone, __PRETTY_FUNCTION__);
- SZONE_LOCK(szone);
- while (cc < count) {
- ptr = to_be_freed[cc];
- if (ptr) {
- /* XXX this really slows us down */
- tiny_region = tiny_region_for_ptr_no_lock(szone, ptr);
- if (tiny_region) {
- // this is a tiny pointer
- if (TINY_INDEX_FOR_PTR(ptr) >= NUM_TINY_BLOCKS)
- break; // pointer to metadata; let the standard free deal with it
- msize = get_tiny_meta_header(ptr, &is_free);
- if (is_free)
- break; // a double free; let the standard free deal with it
- tiny_free_no_lock(szone, tiny_region, ptr, msize);
- to_be_freed[cc] = NULL;
- }
- }
- cc++;
- }
- SZONE_UNLOCK(szone);
- CHECK(szone, __PRETTY_FUNCTION__);
- while (count--) {
- ptr = to_be_freed[count];
- if (ptr)
- szone_free(szone, ptr);
- }
-}
-
-static void
-szone_destroy(szone_t *szone)
-{
- size_t index;
- large_entry_t *large;
- vm_range_t range_to_deallocate;
- huge_entry_t *huge;
-
- /* destroy large entries */
- index = szone->num_large_entries;
- while (index--) {
- large = szone->large_entries + index;
- if (!LARGE_ENTRY_IS_EMPTY(*large)) {
- // we deallocate_pages, including guard pages
- deallocate_pages(szone, (void *)LARGE_ENTRY_ADDRESS(*large), LARGE_ENTRY_SIZE(*large), szone->debug_flags);
- }
- }
- if (szone->num_large_entries * sizeof(large_entry_t) >= LARGE_THRESHOLD) {
- // we do not free in the small chunk case
- large_entries_free_no_lock(szone, szone->large_entries, szone->num_large_entries, &range_to_deallocate);
- if (range_to_deallocate.size)
- deallocate_pages(szone, (void *)range_to_deallocate.address, (size_t)range_to_deallocate.size, 0);
- }
-
- /* destroy huge entries */
- index = szone->num_huge_entries;
- while (index--) {
- huge = szone->huge_entries + index;
- deallocate_pages(szone, (void *)huge->address, huge->size, szone->debug_flags);
- }
-
- /* destroy tiny regions */
- for (index = 0; index < szone->num_tiny_regions_allocated; ++index)
- if (szone->tiny_regions[index])
- deallocate_pages(szone, szone->tiny_regions[index], TINY_REGION_SIZE, 0);
-
- /* destroy small regions */
- for (index = 0; index < szone->num_small_regions_allocated; ++index)
- if (szone->small_regions[index])
- deallocate_pages(szone, szone->small_regions[index], SMALL_REGION_SIZE, 0);
-
- /* destroy region hash rings, if any */
- if (szone->tiny_regions != szone->initial_tiny_regions) {
- size_t size = round_page(szone->num_tiny_regions_allocated * sizeof(region_t));
- deallocate_pages(szone, szone->tiny_regions, size, 0);
- }
- if (szone->small_regions != szone->initial_small_regions) {
- size_t size = round_page(szone->num_small_regions_allocated * sizeof(region_t));
- deallocate_pages(szone, szone->small_regions, size, 0);
- }
- /* Now destroy the separate szone region */
- deallocate_pages(szone, (void *)szone, SZONE_PAGED_SIZE, SCALABLE_MALLOC_ADD_GUARD_PAGES);
-}
-
-static size_t
-szone_good_size(szone_t *szone, size_t size)
-{
- msize_t msize;
- unsigned num_pages;
-
- if (size <= 31 * TINY_QUANTUM) {
- // think tiny
- msize = TINY_MSIZE_FOR_BYTES(size + TINY_QUANTUM - 1);
- if (! msize) msize = 1;
- return TINY_BYTES_FOR_MSIZE(msize);
- }
- if (!((szone->debug_flags & SCALABLE_MALLOC_ADD_GUARD_PAGES) && PROTECT_SMALL) && (size < LARGE_THRESHOLD)) {
- // think small
- msize = SMALL_MSIZE_FOR_BYTES(size + SMALL_QUANTUM - 1);
- if (! msize) msize = 1;
- return SMALL_BYTES_FOR_MSIZE(msize);
- } else {
- num_pages = round_page(size) >> vm_page_shift;
- if (!num_pages)
- num_pages = 1; // minimal allocation size for this
- return num_pages << vm_page_shift;
- }
-}
-
-unsigned szone_check_counter = 0;
-unsigned szone_check_start = 0;
-unsigned szone_check_modulo = 1;
-
-static boolean_t
-szone_check_all(szone_t *szone, const char *function)
-{
- size_t index;
-
- SZONE_LOCK(szone);
- CHECK_LOCKED(szone, __PRETTY_FUNCTION__);
-
- /* check tiny regions - chould check region count */
- for (index = 0; index < szone->num_tiny_regions_allocated; ++index) {
- region_t tiny = szone->tiny_regions[index];
- if (tiny && !tiny_check_region(szone, tiny)) {
- SZONE_UNLOCK(szone);
- szone->debug_flags &= ~ CHECK_REGIONS;
- szone_error(szone, "check: tiny region incorrect", NULL,
- "*** tiny region %d incorrect szone_check_all(%s) counter=%d\n",
- index, function, szone_check_counter);
- return 0;
- }
- }
- /* check tiny free lists */
- for (index = 0; index < NUM_TINY_SLOTS; ++index) {
- if (!tiny_free_list_check(szone, index)) {
- SZONE_UNLOCK(szone);
- szone->debug_flags &= ~ CHECK_REGIONS;
- szone_error(szone, "check: tiny free list incorrect", NULL,
- "*** tiny free list incorrect (slot=%d) szone_check_all(%s) counter=%d\n",
- index, function, szone_check_counter);
- return 0;
- }
- }
- /* check small regions - could check region count */
- for (index = 0; index < szone->num_small_regions_allocated; ++index) {
- region_t small = szone->small_regions[index];
- if (small && !szone_check_small_region(szone, small)) {
- SZONE_UNLOCK(szone);
- szone->debug_flags &= ~ CHECK_REGIONS;
- szone_error(szone, "check: small region incorrect", NULL,
- "*** small region %d incorrect szone_check_all(%s) counter=%d\n",
- index, function, szone_check_counter);
- return 0;
- }
- }
- /* check small free lists */
- for (index = 0; index < NUM_SMALL_SLOTS; ++index) {
- if (!small_free_list_check(szone, index)) {
- SZONE_UNLOCK(szone);
- szone->debug_flags &= ~ CHECK_REGIONS;
- szone_error(szone, "check: small free list incorrect", NULL,
- "*** small free list incorrect (grain=%d) szone_check_all(%s) counter=%d\n",
- index, function, szone_check_counter);
- return 0;
- }
- }
- SZONE_UNLOCK(szone);
- return 1;
-}
-
-static boolean_t
-szone_check(szone_t *szone)
-{
- if ((++szone_check_counter % 10000) == 0)
- _malloc_printf(ASL_LEVEL_NOTICE, "at szone_check counter=%d\n", szone_check_counter);
- if (szone_check_counter < szone_check_start)
- return 1;
- if (szone_check_counter % szone_check_modulo)
- return 1;
- return szone_check_all(szone, "");
-}
-
-static kern_return_t
-szone_ptr_in_use_enumerator(task_t task, void *context, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder)
-{
- szone_t *szone;
- kern_return_t err;
-
- if (!reader) reader = _szone_default_reader;
- err = reader(task, zone_address, sizeof(szone_t), (void **)&szone);
- if (err) return err;
- err = tiny_in_use_enumerator(task, context, type_mask, szone, reader, recorder);
- if (err) return err;
- err = small_in_use_enumerator(task, context, type_mask, szone, reader, recorder);
- if (err) return err;
- err = large_in_use_enumerator(task, context, type_mask,
- (vm_address_t)szone->large_entries, szone->num_large_entries, reader,
- recorder);
- if (err) return err;
- err = huge_in_use_enumerator(task, context, type_mask,
- (vm_address_t)szone->huge_entries, szone->num_huge_entries, reader,
- recorder);
- return err;
-}
-
-// Following method is deprecated: use scalable_zone_statistics instead
-void
-scalable_zone_info(malloc_zone_t *zone, unsigned *info_to_fill, unsigned count)
-{
- szone_t *szone = (void *)zone;
- unsigned info[13];
-
- // We do not lock to facilitate debug
- info[4] = szone->num_tiny_objects;
- info[5] = szone->num_bytes_in_tiny_objects;
- info[6] = szone->num_small_objects;
- info[7] = szone->num_bytes_in_small_objects;
- info[8] = szone->num_large_objects_in_use;
- info[9] = szone->num_bytes_in_large_objects;
- info[10] = szone->num_huge_entries;
- info[11] = szone->num_bytes_in_huge_objects;
- info[12] = szone->debug_flags;
- info[0] = info[4] + info[6] + info[8] + info[10];
- info[1] = info[5] + info[7] + info[9] + info[11];
- info[3] = szone->num_tiny_regions * TINY_REGION_SIZE + szone->num_small_regions * SMALL_REGION_SIZE + info[9] + info[11];
- info[2] = info[3] - szone->tiny_bytes_free_at_end - szone->small_bytes_free_at_end;
- memcpy(info_to_fill, info, sizeof(unsigned)*count);
-}
-
-static void
-szone_print(szone_t *szone, boolean_t verbose)
-{
- unsigned info[13];
- size_t index;
- region_t region;
-
- SZONE_LOCK(szone);
- scalable_zone_info((void *)szone, info, 13);
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "Scalable zone %p: inUse=%d(%y) touched=%y allocated=%y flags=%d\n",
- szone, info[0], info[1], info[2], info[3], info[12]);
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "\ttiny=%d(%y) small=%d(%y) large=%d(%y) huge=%d(%y)\n",
- info[4], info[5], info[6], info[7], info[8], info[9], info[10], info[11]);
- // tiny
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "%d tiny regions:\n", szone->num_tiny_regions);
- for (index = 0; index < szone->num_tiny_regions_allocated; ++index) {
- region = szone->tiny_regions[index];
- if (region)
- print_tiny_region(verbose, region, (region == szone->last_tiny_region) ?
- szone->tiny_bytes_free_at_end : 0);
- }
- if (verbose)
- print_tiny_free_list(szone);
- // small
- _malloc_printf(MALLOC_PRINTF_NOLOG | MALLOC_PRINTF_NOPREFIX,
- "%d small regions:\n", szone->num_small_regions);
- for (index = 0; index < szone->num_small_regions_allocated; ++index) {
- region = szone->small_regions[index];
- if (region)
- print_small_region(szone, verbose, region,
- (region == szone->last_small_region) ?
- szone->small_bytes_free_at_end : 0);
- }
- if (verbose)
- print_small_free_list(szone);
- SZONE_UNLOCK(szone);
-}
-
-static void
-szone_log(malloc_zone_t *zone, void *log_address)
-{
- szone_t *szone = (szone_t *)zone;
-
- szone->log_address = log_address;
-}
-
-static void
-szone_force_lock(szone_t *szone)
-{
- SZONE_LOCK(szone);
-}
-
-static void
-szone_force_unlock(szone_t *szone)
-{
- SZONE_UNLOCK(szone);
-}
-
-boolean_t
-scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone)
-{
- szone_t *szone = (szone_t *)zone;
-
- switch (subzone) {
- case 0:
- stats->blocks_in_use = szone->num_tiny_objects;
- stats->size_in_use = szone->num_bytes_in_tiny_objects;
- stats->size_allocated = szone->num_tiny_regions * TINY_REGION_SIZE;
- stats->max_size_in_use = stats->size_allocated - szone->tiny_bytes_free_at_end;
- return 1;
- case 1:
- stats->blocks_in_use = szone->num_small_objects;
- stats->size_in_use = szone->num_bytes_in_small_objects;
- stats->size_allocated = szone->num_small_regions * SMALL_REGION_SIZE;
- stats->max_size_in_use = stats->size_allocated - szone->small_bytes_free_at_end;
- return 1;
- case 2:
- stats->blocks_in_use = szone->num_large_objects_in_use;
- stats->size_in_use = szone->num_bytes_in_large_objects;
- stats->max_size_in_use = stats->size_allocated = stats->size_in_use;
- return 1;
- case 3:
- stats->blocks_in_use = szone->num_huge_entries;
- stats->size_in_use = szone->num_bytes_in_huge_objects;
- stats->max_size_in_use = stats->size_allocated = stats->size_in_use;
- return 1;
- }
- return 0;
-}
-
-static void
-szone_statistics(szone_t *szone, malloc_statistics_t *stats)
-{
- size_t big_and_huge;
-
- stats->blocks_in_use =
- szone->num_tiny_objects +
- szone->num_small_objects +
- szone->num_large_objects_in_use +
- szone->num_huge_entries;
- big_and_huge = szone->num_bytes_in_large_objects + szone->num_bytes_in_huge_objects;
- stats->size_in_use = szone->num_bytes_in_tiny_objects + szone->num_bytes_in_small_objects + big_and_huge;
- stats->max_size_in_use = stats->size_allocated =
- szone->num_tiny_regions * TINY_REGION_SIZE +
- szone->num_small_regions * SMALL_REGION_SIZE +
- big_and_huge ;
-
- // Now we account for the untouched areas
- stats->max_size_in_use -= szone->tiny_bytes_free_at_end;
- stats->max_size_in_use -= szone->small_bytes_free_at_end;
-}
-
-static const struct malloc_introspection_t szone_introspect = {
- (void *)szone_ptr_in_use_enumerator,
- (void *)szone_good_size,
- (void *)szone_check,
- (void *)szone_print,
- szone_log,
- (void *)szone_force_lock,
- (void *)szone_force_unlock,
- (void *)szone_statistics
-}; // marked as const to spare the DATA section
-
-malloc_zone_t *
-create_scalable_zone(size_t initial_size, unsigned debug_flags)
-{
- szone_t *szone;
-
- /*
- * Sanity-check our build-time assumptions about the size of a page.
- * Since we have sized various things assuming the default page size,
- * attempting to determine it dynamically is not useful.
- */
- if ((vm_page_size != _vm_page_size) || (vm_page_shift != _vm_page_shift)) {
- malloc_printf("*** FATAL ERROR - machine page size does not match our assumptions.\n");
- exit(-1);
- }
-
- /* get memory for the zone, which is now separate from any region.
- add guard pages to prevent walking from any other vm allocations
- to here and overwriting the function pointers in basic_zone. */
- szone = allocate_pages(NULL, SZONE_PAGED_SIZE, 0,
- SCALABLE_MALLOC_ADD_GUARD_PAGES,
- VM_MEMORY_MALLOC);
- if (!szone)
- return NULL;
- /* set up the szone structure */
- szone->tiny_regions = szone->initial_tiny_regions;
- szone->small_regions = szone->initial_small_regions;
- szone->num_tiny_regions_allocated = INITIAL_NUM_REGIONS;
- szone->num_small_regions_allocated = INITIAL_NUM_REGIONS;
- szone->basic_zone.version = 3;
- szone->basic_zone.size = (void *)szone_size;
- szone->basic_zone.malloc = (void *)szone_malloc;
- szone->basic_zone.calloc = (void *)szone_calloc;
- szone->basic_zone.valloc = (void *)szone_valloc;
- szone->basic_zone.free = (void *)szone_free;
- szone->basic_zone.realloc = (void *)szone_realloc;
- szone->basic_zone.destroy = (void *)szone_destroy;
- szone->basic_zone.batch_malloc = (void *)szone_batch_malloc;
- szone->basic_zone.batch_free = (void *)szone_batch_free;
- szone->basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect;
- szone->debug_flags = debug_flags;
- LOCK_INIT(szone->lock);
-
-#if 0
-#warning CHECK_REGIONS enabled
- debug_flags |= CHECK_REGIONS;
-#endif
-#if 0
-#warning LOG enabled
- szone->log_address = ~0;
-#endif
- CHECK(szone, __PRETTY_FUNCTION__);
- return (malloc_zone_t *)szone;
-}
-
-/********* Support code for emacs unexec ************/
-
-/* History of freezedry version numbers:
- *
- * 1) Old malloc (before the scalable malloc implementation in this file
- * existed).
- * 2) Original freezedrying code for scalable malloc. This code was apparently
- * based on the old freezedrying code and was fundamentally flawed in its
- * assumption that tracking allocated memory regions was adequate to fake
- * operations on freezedried memory. This doesn't work, since scalable
- * malloc does not store flags in front of large page-aligned allocations.
- * 3) Original szone-based freezedrying code.
- * 4) Fresher malloc with tiny zone
- * 5) 32/64bit compatible malloc
- * 6) Metadata within 1MB and 8MB region for tiny and small
- *
- * No version backward compatibility is provided, but the version number does
- * make it possible for malloc_jumpstart() to return an error if the application
- * was freezedried with an older version of malloc.
- */
-#define MALLOC_FREEZEDRY_VERSION 6
-
-typedef struct {
- unsigned version;
- unsigned nszones;
- szone_t *szones;
-} malloc_frozen;
-
-static void *
-frozen_malloc(szone_t *zone, size_t new_size)
-{
- return malloc(new_size);
-}
-
-static void *
-frozen_calloc(szone_t *zone, size_t num_items, size_t size)
-{
- return calloc(num_items, size);
-}
-
-static void *
-frozen_valloc(szone_t *zone, size_t new_size)
-{
- return valloc(new_size);
-}
-
-static void *
-frozen_realloc(szone_t *zone, void *ptr, size_t new_size)
-{
- size_t old_size = szone_size(zone, ptr);
- void *new_ptr;
-
- if (new_size <= old_size) {
- return ptr;
- }
- new_ptr = malloc(new_size);
- if (old_size > 0) {
- memcpy(new_ptr, ptr, old_size);
- }
- return new_ptr;
-}
-
-static void
-frozen_free(szone_t *zone, void *ptr)
-{
-}
-
-static void
-frozen_destroy(szone_t *zone)
-{
-}
-
-/********* Pseudo-private API for emacs unexec ************/
-
-/*
- * malloc_freezedry() records all of the szones in use, so that they can be
- * partially reconstituted by malloc_jumpstart(). Due to the differences
- * between reconstituted memory regions and those created by the szone code,
- * care is taken not to reallocate from the freezedried memory, except in the
- * case of a non-growing realloc().
- *
- * Due to the flexibility provided by the zone registration mechanism, it is
- * impossible to implement generic freezedrying for any zone type. This code
- * only handles applications that use the szone allocator, so malloc_freezedry()
- * returns 0 (error) if any non-szone zones are encountered.
- */
-
-uintptr_t
-malloc_freezedry(void)
-{
- extern unsigned malloc_num_zones;
- extern malloc_zone_t **malloc_zones;
- malloc_frozen *data;
- unsigned i;
-
- /* Allocate space in which to store the freezedry state. */
- data = (malloc_frozen *) malloc(sizeof(malloc_frozen));
-
- /* Set freezedry version number so that malloc_jumpstart() can check for compatibility. */
- data->version = MALLOC_FREEZEDRY_VERSION;
-
- /* Allocate the array of szone pointers. */
- data->nszones = malloc_num_zones;
- data->szones = (szone_t *) calloc(malloc_num_zones, sizeof(szone_t));
-
- /*
- * Fill in the array of szone structures. They are copied rather than
- * referenced, since the originals are likely to be clobbered during malloc
- * initialization.
- */
- for (i = 0; i < malloc_num_zones; i++) {
- if (strcmp(malloc_zones[i]->zone_name, "DefaultMallocZone")) {
- /* Unknown zone type. */
- free(data->szones);
- free(data);
- return 0;
- }
- memcpy(&data->szones[i], malloc_zones[i], sizeof(szone_t));
- }
-
- return((uintptr_t)data);
-}
-
-int
-malloc_jumpstart(uintptr_t cookie)
-{
- malloc_frozen *data = (malloc_frozen *)cookie;
- unsigned i;
-
- if (data->version != MALLOC_FREEZEDRY_VERSION) {
- /* Unsupported freezedry version. */
- return 1;
- }
-
- for (i = 0; i < data->nszones; i++) {
- /* Set function pointers. Even the functions that stay the same must be
- * set, since there are no guarantees that they will be mapped to the
- * same addresses. */
- data->szones[i].basic_zone.size = (void *) szone_size;
- data->szones[i].basic_zone.malloc = (void *) frozen_malloc;
- data->szones[i].basic_zone.calloc = (void *) frozen_calloc;
- data->szones[i].basic_zone.valloc = (void *) frozen_valloc;
- data->szones[i].basic_zone.free = (void *) frozen_free;
- data->szones[i].basic_zone.realloc = (void *) frozen_realloc;
- data->szones[i].basic_zone.destroy = (void *) frozen_destroy;
- data->szones[i].basic_zone.introspect = (struct malloc_introspection_t *)&szone_introspect;
-
- /* Register the freezedried zone. */
- malloc_zone_register(&data->szones[i].basic_zone);
- }
-
- return 0;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#import <malloc/malloc.h>
-
-#define SCALABLE_MALLOC_ADD_GUARD_PAGES (1 << 0)
- // add a guard page before and after each VM region to help debug
-#define SCALABLE_MALLOC_DONT_PROTECT_PRELUDE (1 << 1)
- // do not protect prelude page
-#define SCALABLE_MALLOC_DONT_PROTECT_POSTLUDE (1 << 2)
- // do not protect postlude page
-#define SCALABLE_MALLOC_DO_SCRIBBLE (1 << 3)
- // write 0x55 onto free blocks
-#define SCALABLE_MALLOC_ABORT_ON_ERROR (1 << 4)
- // call abort() on any malloc error, such as double free or out of memory.
-#define SCALABLE_MALLOC_PURGEABLE (1 << 5)
- // allocate objects such that they may be used with VM purgability APIs
-#define SCALABLE_MALLOC_ABORT_ON_CORRUPTION (1 << 6)
- // call abort() on malloc errors, but not on out of memory.
-
-extern malloc_zone_t *create_scalable_zone(size_t initial_size, unsigned debug_flags);
- /* Create a new zone that scales for small objects or large objects */
-
-extern malloc_zone_t *create_purgeable_zone(size_t initial_size, malloc_zone_t *malloc_default_zone, unsigned debug_flags);
- /* Create a new zone that supports malloc_make{un}purgeable() discipline. */
-
-extern malloc_zone_t *create_legacy_scalable_zone(size_t initial_size, unsigned debug_flags);
- /*
- * For use by CheckFix: create a new zone whose behavior is, apart from
- * the use of death-row and per-CPU magazines, that of Leopard.
- */
-
-/***** Private API for debug and performance tools ********/
-
-extern boolean_t scalable_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats, unsigned subzone);
- /* Fills stats with some statistics;
- 1 is returned on success; else 0 is returned
- Currently: subzone=0 => tiny; subzone=1 => small; subzone=2 => large; subzone=3 => huge; any other subzone => returns 0
- */
-
+++ /dev/null
-.\" Copyright (c) 1990, 1991, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" This code is derived from software contributed to Berkeley by
-.\" the American National Standards Committee X3, on Information
-.\" Processing Systems.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)setjmp.3 8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/gen/setjmp.3,v 1.9 2001/10/01 16:08:51 ru Exp $
-.\"
-.Dd June 4, 1993
-.Dt SETJMP 3
-.Os
-.Sh NAME
-.Nm _longjmp ,
-.Nm _setjmp ,
-.Nm longjmp ,
-.Nm longjmperror ,
-.Nm setjmp ,
-.Nm siglongjmp ,
-.Nm sigsetjmp
-.Nd non-local jumps
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In setjmp.h
-.Ft void
-.Fo _longjmp
-.Fa "jmp_buf env"
-.Fa "int val"
-.Fc
-.Ft int
-.Fo _setjmp
-.Fa "jmp_buf env"
-.Fc
-.Ft void
-.Fo longjmp
-.Fa "jmp_buf env"
-.Fa "int val"
-.Fc
-.Ft void
-.Fo longjmperror
-.Fa void
-.Fc
-.Ft int
-.Fo setjmp
-.Fa "jmp_buf env"
-.Fc
-.Ft void
-.Fo siglongjmp
-.Fa "sigjmp_buf env"
-.Fa "int val"
-.Fc
-.Ft int
-.Fo sigsetjmp
-.Fa "sigjmp_buf env"
-.Fa "int savemask"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn sigsetjmp ,
-.Fn setjmp ,
-and
-.Fn _setjmp
-functions save their calling environment in
-.Fa env .
-Each of these functions returns 0.
-.Pp
-The corresponding
-.Fn longjmp
-functions restore the environment saved by their most recent respective
-invocations
-of the
-.Fn setjmp
-function.
-They then return, so that program execution continues
-as if the corresponding invocation of the
-.Fn setjmp
-call had just returned the value specified by
-.Fa val ,
-instead of 0.
-.Pp
-Pairs of calls may be intermixed
-(i.e., both
-.Fn sigsetjmp
-and
-.Fn siglongjmp
-and
-.Fn setjmp
-and
-.Fn longjmp
-combinations may be used in the same program); however, individual
-calls may not (e.g. the
-.Fa env
-argument to
-.Fn setjmp
-may not be passed to
-.Fn siglongjmp ) .
-.Pp
-The
-.Fn longjmp
-routines may not be called after the routine which called the
-.Fn setjmp
-routines returns.
-.Pp
-All accessible objects have values as of the time
-.Fn longjmp
-routine was called, except that the values of objects of automatic storage
-invocation duration that do not have the
-.Em volatile
-type and have been changed between the
-.Fn setjmp
-invocation and
-.Fn longjmp
-call are indeterminate.
-.Pp
-The
-.Fn setjmp Ns / Ns Fn longjmp
-pairs save and restore the signal mask while
-.Fn _setjmp Ns / Ns Fn _longjmp
-pairs save and restore only the register set and the stack.
-(See
-.Fn sigprocmask 2 . )
-.Pp
-The
-.Fn sigsetjmp Ns / Ns Fn siglongjmp
-function
-pairs save and restore the signal mask if the argument
-.Fa savemask
-is non-zero; otherwise, only the register set and the stack are saved.
-.Sh ERRORS
-If the contents of the
-.Fa env
-are corrupted, or correspond to an environment that has already returned,
-the
-.Fn longjmp
-routine calls the routine
-.Fn longjmperror 3 .
-If
-.Fn longjmperror
-returns, the program is aborted (see
-.Xr abort 3 ) .
-The default version of
-.Fn longjmperror
-prints the message
-.Dq Li longjmp botch
-to standard error and returns.
-User programs wishing to exit more gracefully should write their own
-versions of
-.Fn longjmperror .
-.Sh SEE ALSO
-.Xr sigaction 2 ,
-.Xr sigaltstack 2 ,
-.Xr signal 3
-.Sh STANDARDS
-The
-.Fn setjmp
-and
-.Fn longjmp
-functions conform to
-.St -isoC .
-The
-.Fn sigsetjmp
-and
-.Fn siglongjmp
-functions conform to
-.St -p1003.1-88 .
#include <unistd.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
extern int __setlogin(const char* name);
-extern int _logname_valid; /* shared with getlogin() */
+extern pthread_mutex_t __logname_mutex;
+extern char *__logname;
int setlogin(const char* name)
{
- return (_logname_valid = __setlogin(name));
+ pthread_mutex_lock(&__logname_mutex);
+
+ int res = __setlogin(name);
+ if (res == 0 && __logname != NULL) {
+ __logname[0] = 0;
+ }
+
+ pthread_mutex_unlock(&__logname_mutex);
+
+ return res;
}
+++ /dev/null
-/*
- * Copyright (c) 1999, 2000, 2002-2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/* Bertrand from vmutils -> CF -> System */
-
-#import "stack_logging.h"
-#import "malloc_printf.h"
-
-#import <libc.h>
-#import <pthread.h>
-#import <mach/mach.h>
-#include <mach/vm_statistics.h>
-#import <malloc/malloc.h>
-#import <stdlib.h>
-#import <CrashReporterClient.h>
-
-extern void spin_lock(int *);
-extern void spin_unlock(int *);
-extern void thread_stack_pcs(vm_address_t *, unsigned, unsigned *);
-
-static inline void *allocate_pages(unsigned) __attribute__((always_inline));
-static inline void *allocate_pages(unsigned bytes) {
- void *address;
- if (vm_allocate(mach_task_self(), (vm_address_t *)&address, bytes,
- VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)| TRUE)) {
- malloc_printf("*** out of memory while stack logging\n");
- CRSetCrashLogMessage("*** out of memory while stack logging\n");
- abort();
- }
- return (void *)address;
-}
-
-static inline void deallocate_pages(void *, unsigned) __attribute__((always_inline));
-static inline void deallocate_pages(void *ptr, unsigned bytes) {
- vm_deallocate(mach_task_self(), (vm_address_t)ptr, bytes);
-}
-
-static inline void copy_pages(const void *, void *, unsigned) __attribute__((always_inline));
-static inline void copy_pages(const void *source, void *dest, unsigned bytes) {
- if (vm_copy(mach_task_self(), (vm_address_t)source, bytes, (vm_address_t)dest)) memmove(dest, source, bytes);
-}
-
-/*************** Uniquing stack ***********/
-
-#define MAX_COLLIDE 8
-
-#define MAX_NUM_PC 512
-
-static int enter_pair_in_table(unsigned *table, unsigned numPages, unsigned *uniquedParent, unsigned thisPC) {
- // uniquedParent is in-out; return 1 is collisions max not exceeded
- unsigned base = numPages * vm_page_size / (sizeof(int)*2*2);
- unsigned hash = base + (((*uniquedParent) << 4) ^ (thisPC >> 2)) % (base - 1); // modulo odd number for hashing
- unsigned collisions = MAX_COLLIDE;
- while (collisions--) {
- unsigned *head = table + hash*2;
- if (! head[0] && !head[1]) {
- /* end of chain; store this entry! */
- /* Note that we need to test for both head[0] and head[1] as (0, -1) is a valid entry */
- head[0] = thisPC;
- head[1] = *uniquedParent;
- *uniquedParent = hash;
- return 1;
- }
- if ((head[0] == thisPC) && (head[1] == *uniquedParent)) {
- /* we found the proper entry, the value for the pair is the entry offset */
- *uniquedParent = hash;
- return 1;
- }
- hash++;
- if (hash == base*2) hash = base;
- }
- return 0;
-}
-
-unsigned stack_logging_get_unique_stack(unsigned **table, unsigned *table_num_pages, unsigned *stack_entries, unsigned count, unsigned num_hot_to_skip) {
- unsigned uniquedParent = (unsigned)-1;
- // we skip the warmest entries that are an artefact of the code
- while (num_hot_to_skip--) {
- if (count > 0) { stack_entries++; count--; }
- }
- while (count--) {
- unsigned thisPC = stack_entries[count];
- while (!enter_pair_in_table(*table, *table_num_pages, &uniquedParent, thisPC)) {
- unsigned *newTable;
- unsigned oldBytes = (*table_num_pages) * vm_page_size;
- newTable = allocate_pages(oldBytes*2);
- copy_pages(*table, newTable, oldBytes);
- deallocate_pages(*table, oldBytes);
- *table_num_pages *= 2;
- *table = newTable;
- }
- }
- return uniquedParent;
-}
-
-/*************** Logging stack and arguments ***********/
-
-stack_logging_record_list_t *stack_logging_the_record_list = NULL;
-
-int stack_logging_enable_logging = 0;
-int stack_logging_dontcompact = 0;
-int stack_logging_finished_init = 0;
-int stack_logging_postponed = 0;
-
-static int stack_logging_spin_lock = 0;
-
-static stack_logging_record_list_t *GrowLogRecords(stack_logging_record_list_t *records, unsigned desiredNumRecords) {
- stack_logging_record_list_t *new_records;
- unsigned old_size = records->overall_num_bytes;
- if (desiredNumRecords*sizeof(stack_logging_record_t)+sizeof(stack_logging_record_list_t) < records->overall_num_bytes) return records;
- records->overall_num_bytes += records->overall_num_bytes + vm_page_size; // in order to always get an even number of pages
- new_records = allocate_pages(records->overall_num_bytes);
- copy_pages(records, new_records, old_size);
- deallocate_pages(records, old_size);
- return new_records;
-}
-
-static void prepare_to_log_stack(void) {
- if (!stack_logging_the_record_list) {
- unsigned totalSize = 4 * vm_page_size;
- stack_logging_the_record_list = allocate_pages(totalSize);
- memset(stack_logging_the_record_list, 0, sizeof(stack_logging_record_list_t));
- stack_logging_the_record_list->overall_num_bytes = totalSize;
- stack_logging_the_record_list->uniquing_table_num_pages = 128;
- stack_logging_the_record_list->uniquing_table = allocate_pages(stack_logging_the_record_list->uniquing_table_num_pages * vm_page_size);
- }
-}
-
-void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_to_skip) {
- stack_logging_record_t *rec;
- if (!stack_logging_enable_logging) return;
- // printf("stack_logging_log_stack 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result);
- if (type & stack_logging_flag_zone) {
- // just process it now and be done with it!
- arg1 = arg2; arg2 = arg3; arg3 = 0; type &= ~stack_logging_flag_zone;
- }
- if (type & stack_logging_flag_calloc) {
- // just process it now and be done with it!
- arg1 *= arg2; arg2 = arg3; arg3 = 0; type &= ~stack_logging_flag_calloc;
- }
- if (type & stack_logging_flag_object) {
- unsigned *class = (unsigned *)(uintptr_t)arg1;
- arg1 = arg2 + class[5]; // corresponds to the instance_size field
- arg2 = 0; arg3 = 0; type = stack_logging_type_alloc;
- }
- if (type & stack_logging_flag_cleared) {
- type &= ~stack_logging_flag_cleared;
- }
- if (type & stack_logging_flag_handle) {
- if (stack_logging_type_alloc) {
- if (!result) return;
- stack_logging_log_stack(stack_logging_type_alloc, 0, 0, 0, result, num_hot_to_skip+1);
- stack_logging_log_stack(stack_logging_type_alloc, arg1, 0, 0, *((int *)(uintptr_t)result), num_hot_to_skip+1);
- return;
- }
- if (stack_logging_type_dealloc) {
- if (!arg1) return;
- stack_logging_log_stack(stack_logging_type_dealloc, *((int *)(uintptr_t)arg1), 0, 0, 0, num_hot_to_skip+1);
- stack_logging_log_stack(stack_logging_type_dealloc, arg1, 0, 0, 0, num_hot_to_skip+1);
- return;
- }
- fprintf(stderr, "*** Unknown logging type: 0x%x\n", type);
- }
- if (type == stack_logging_flag_set_handle_size) {
- if (!arg1) return;
- // Thanks to a horrible hack, arg3 contains the prvious handle value
- if (arg3 == *((int *)(uintptr_t)arg1)) return;
- stack_logging_log_stack(stack_logging_type_dealloc, arg3, 0, 0, 0, num_hot_to_skip+1);
- stack_logging_log_stack(stack_logging_type_alloc, arg2, 0, 0, *((int *)(uintptr_t)arg1), num_hot_to_skip+1);
- return;
- }
- if (type == (stack_logging_type_dealloc|stack_logging_type_alloc)) {
- if (arg1 == result) return; // realloc had no effect, skipping
- if (!arg1) {
- // realloc(NULL, size) same as malloc(size)
- type = stack_logging_type_alloc; arg1 = arg2; arg2 = arg3; arg3 = 0;
- } else {
- // realloc(arg1, arg2) -> result is same as free(arg1); malloc(arg2) -> result
- stack_logging_log_stack(stack_logging_type_dealloc, arg1, 0, 0, 0, num_hot_to_skip+1);
- stack_logging_log_stack(stack_logging_type_alloc, arg2, 0, 0, result, num_hot_to_skip+1);
- return;
- }
- }
- if (type == stack_logging_type_dealloc) {
- // simple free
- if (!arg1) return; // free(nil)
- }
- prepare_to_log_stack();
- spin_lock(&stack_logging_spin_lock);
- stack_logging_the_record_list = GrowLogRecords(stack_logging_the_record_list, stack_logging_the_record_list->num_records + 1);
- rec = stack_logging_the_record_list->records + stack_logging_the_record_list->num_records;
- // We take care of the common case of alloc-dealloc
- if (!stack_logging_dontcompact && stack_logging_the_record_list->num_records && (type == stack_logging_type_dealloc) && arg1 && ((rec-1)->type == stack_logging_type_alloc) && (arg1 == STACK_LOGGING_DISGUISE((rec-1)->address))) {
- stack_logging_the_record_list->num_records--;
- // printf("Erased previous record in alloc-dealloc sequence\n");
- } else {
- unsigned stack_entries[MAX_NUM_PC];
- unsigned count = 0;
- rec->type = type;
- if (type == stack_logging_type_dealloc) {
- rec->argument = 0;
- rec->address = STACK_LOGGING_DISGUISE(arg1); // we disguise the address
- } else if (type == stack_logging_type_alloc) {
- rec->argument = arg1;
- rec->address = STACK_LOGGING_DISGUISE(result); // we disguise the address
- } else {
- rec->argument = arg2;
- rec->address = STACK_LOGGING_DISGUISE(arg1); // we disguise the address
- }
- // printf("Before getting samples 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result);
- thread_stack_pcs((vm_address_t *)stack_entries, MAX_NUM_PC - 1, &count);
- // We put at the bottom of the stack a marker that denotes the thread (+1 for good measure...)
- stack_entries[count++] = (int)(uintptr_t)pthread_self() + 1;
- /* now let's unique the sample */
- // printf("Uniquing 0x%x 0x%x 0x%x 0x%x -> 0x%x\n", type, arg1, arg2, arg3, result);
- rec->uniqued_stack = stack_logging_get_unique_stack(&stack_logging_the_record_list->uniquing_table, &stack_logging_the_record_list->uniquing_table_num_pages, stack_entries, count, num_hot_to_skip+2); // we additionally skip the warmest 2 entries that are an artefact of the code
- stack_logging_the_record_list->num_records++;
- }
- spin_unlock(&stack_logging_spin_lock);
-}
-
-static kern_return_t default_reader(task_t task, vm_address_t address, vm_size_t size, void **ptr) {
- *ptr = (void *)address;
- return 0;
-}
-
-static kern_return_t get_remote_records(task_t task, memory_reader_t reader, stack_logging_record_list_t **records) {
- // sets records
- vm_address_t *remote_records_address_ref;
- kern_return_t err;
- *records = NULL;
- err = reader(task, (vm_address_t)&stack_logging_the_record_list, sizeof(vm_address_t), (void **)&remote_records_address_ref);
- if (err) return err;
- if (!*remote_records_address_ref) {
- // printf("stack_logging: no stack record\n");
- return 0;
- }
- // printf("stack_logging: stack records at %p\n", (void *)(*remote_records_address_ref));
- // printf("stack_logging: reading %d bytes\n", sizeof(stack_logging_record_list_t));
- err = reader(task, *remote_records_address_ref, sizeof(stack_logging_record_list_t), (void **)records); // get the list head
- if (err) return err;
- // printf("stack_logging: overall num bytes = %d\n", records->overall_num_bytes);
- return reader(task, *remote_records_address_ref, (*records)->overall_num_bytes, (void **)records);
-}
-
-kern_return_t stack_logging_get_frames(task_t task, memory_reader_t reader, vm_address_t address, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames) {
- stack_logging_record_list_t *records;
- kern_return_t err;
- unsigned index;
- unsigned disguised = STACK_LOGGING_DISGUISE(address);
- if (!reader) reader = default_reader;
- *num_frames = 0;
- err = get_remote_records(task, reader, &records);
- if (err || !records) return err;
- // printf("stack_logging: %d records\n", records->num_records);
- index = 0;
- while (index < records->num_records) {
- stack_logging_record_t *record = records->records + index;
- if (record->address == disguised) {
- return stack_logging_frames_for_uniqued_stack(task, reader, record->uniqued_stack, stack_frames_buffer, max_stack_frames, num_frames);
- }
- index++;
- }
- fprintf(stderr, "*** stack_logging: no record found for %p\n", address);
- return 0;
-}
-
-kern_return_t stack_logging_enumerate_records(task_t task, memory_reader_t reader, vm_address_t address, void enumerator(stack_logging_record_t, void *), void *context) {
- stack_logging_record_list_t *records;
- kern_return_t err;
- unsigned index;
- unsigned disguised = STACK_LOGGING_DISGUISE(address);
- if (!reader) reader = default_reader;
- err = get_remote_records(task, reader, &records);
- if (err || !records) return err;
- // printf("stack_logging: %d records\n", records->num_records);
- index = 0;
- while (index < records->num_records) {
- stack_logging_record_t *record = records->records + index;
- if (!address || (record->address == disguised)) enumerator(*record, context);
- index++;
- }
- return 0;
-}
-
-kern_return_t stack_logging_frames_for_uniqued_stack(task_t task, memory_reader_t reader, unsigned uniqued_stack, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames) {
- stack_logging_record_list_t *records;
- unsigned *uniquing_table;
- kern_return_t err;
- if (!reader) reader = default_reader;
- *num_frames = 0;
- err = get_remote_records(task, reader, &records);
- if (err || !records) return err;
- err = reader(task, (vm_address_t)records->uniquing_table, records->uniquing_table_num_pages * vm_page_size, (void **)&uniquing_table);
- if (err) return err;
- while (max_stack_frames && (uniqued_stack != -1)) {
- unsigned thisPC;
- if ((uniqued_stack * 2 + 1) * sizeof(unsigned) >= records->uniquing_table_num_pages * vm_page_size) {
- fprintf(stderr, "*** stack_logging: Invalid uniqued stack 0x%x", uniqued_stack);
- break;
- }
- thisPC = uniquing_table[uniqued_stack * 2];
- uniqued_stack = uniquing_table[uniqued_stack * 2 + 1];
- if (!thisPC && !uniqued_stack) {
- // Invalid entry
- fprintf(stderr, "*** stack_logging: Invalid entry 0x%x", thisPC);
- break;
- }
- stack_frames_buffer[0] = thisPC;
- stack_frames_buffer++;
- (*num_frames)++;
- max_stack_frames--;
- }
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#import <malloc/malloc.h>
-
-#define stack_logging_type_free 0
-#define stack_logging_type_generic 1 /* anything that is not allocation/deallocation */
-#define stack_logging_type_alloc 2 /* malloc, realloc, etc... */
-#define stack_logging_type_dealloc 4 /* free, realloc, etc... */
-
-// Following flags are absorbed by stack_logging_log_stack()
-#define stack_logging_flag_zone 8 /* NSZoneMalloc, etc... */
-#define stack_logging_flag_calloc 16 /* multiply arguments to get the size */
-#define stack_logging_flag_object 32 /* NSAllocateObject(Class, extraBytes, zone) */
-#define stack_logging_flag_cleared 64 /* for NewEmptyHandle */
-#define stack_logging_flag_handle 128 /* for Handle (de-)allocation routines */
-#define stack_logging_flag_set_handle_size 256 /* (Handle, newSize) treated specially */
-
-/* Macro used to disguise addresses so that leak finding can work */
-#define STACK_LOGGING_DISGUISE(address) ((address) ^ 0x00005555) /* nicely idempotent */
-
-extern int stack_logging_enable_logging; /* when clear, no logging takes place */
-extern int stack_logging_dontcompact; /* default is to compact; when set does not compact alloc/free logs; useful for tracing history */
-extern int stack_logging_finished_init; /* set after we've returned from the Libsystem initialiser */
-extern int stack_logging_postponed; /* set if we needed to postpone logging till after initialisation */
-
-
-extern void stack_logging_log_stack(unsigned type, unsigned arg1, unsigned arg2, unsigned arg3, unsigned result, unsigned num_hot_to_skip);
- /* This is the old log-to-memory logger, which is now deprecated. It remains for compatibility with performance tools that haven't been updated to disk_stack_logging_log_stack() yet. */
-
-extern void __disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip);
- /* Fits as the malloc_logger; logs malloc/free/realloc events and can log custom events if called directly */
-
-
-/* 64-bit-aware stack log access. As new SPI, these routines are prefixed with double-underscore to avoid conflict with Libsystem clients. */
-
-typedef struct {
- uint32_t type_flags;
- uint64_t stack_identifier;
- uint64_t argument;
- mach_vm_address_t address;
-} mach_stack_logging_record_t;
-
-extern kern_return_t __mach_stack_logging_set_file_path(task_t task, char* file_path);
-
-extern kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count);
- /* Gets the last allocation record (malloc, realloc, or free) about address */
-
-extern kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context);
- /* Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records */
-
-extern kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count);
- /* Given a uniqued_stack fills stack_frames_buffer */
-
-
-#pragma mark -
-#pragma mark Legacy
-
-/* The following is the old 32-bit-only, in-process-memory stack logging. This is deprecated and clients should move to the above 64-bit-aware disk stack logging SPI. */
-
-typedef struct {
- unsigned type;
- unsigned uniqued_stack;
- unsigned argument;
- unsigned address; /* disguised, to avoid confusing leaks */
-} stack_logging_record_t;
-
-typedef struct {
- unsigned overall_num_bytes;
- unsigned num_records;
- unsigned lock; /* 0 means OK to lock; used for inter-process locking */
- unsigned *uniquing_table; /* allocated using vm_allocate() */
- /* hashtable organized as (PC, uniqued parent)
- Only the second half of the table is active
- To enable us to grow dynamically */
- unsigned uniquing_table_num_pages; /* number of pages of the table */
- unsigned extra_retain_count; /* not used by stack_logging_log_stack */
- unsigned filler[2]; /* align to cache lines for better performance */
- stack_logging_record_t records[0]; /* records follow here */
-} stack_logging_record_list_t;
-
-extern stack_logging_record_list_t *stack_logging_the_record_list;
- /* This is the global variable containing all logs */
-
-extern kern_return_t stack_logging_get_frames(task_t task, memory_reader_t reader, vm_address_t address, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames);
- /* Gets the last record in stack_logging_the_record_list about address */
-
-#define STACK_LOGGING_ENUMERATION_PROVIDED 1 // temporary to avoid dependencies between projects
-
-extern kern_return_t stack_logging_enumerate_records(task_t task, memory_reader_t reader, vm_address_t address, void enumerator(stack_logging_record_t, void *), void *context);
- /* Gets all the records about address;
- If !address, gets all records */
-
-extern kern_return_t stack_logging_frames_for_uniqued_stack(task_t task, memory_reader_t reader, unsigned uniqued_stack, vm_address_t *stack_frames_buffer, unsigned max_stack_frames, unsigned *num_frames);
- /* Given a uniqued_stack fills stack_frames_buffer */
-
-
-
-extern void thread_stack_pcs(vm_address_t *buffer, unsigned max, unsigned *num);
- /* Convenience to fill buffer with the PCs of the frames, starting with the hot frames;
- num: returned number of frames
- */
-
+++ /dev/null
-/*
- * Copyright (c) 2007-2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <dirent.h>
-#include <libkern/OSAtomic.h>
-#include <mach/mach.h>
-#include <mach/mach_vm.h>
-#include <sys/sysctl.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <pthread.h>
-#include <paths.h>
-#include <errno.h>
-#include "stack_logging.h"
-#include "malloc_printf.h"
-#include "_simple.h" // as included by malloc.c, this defines ASL_LEVEL_INFO
-
-#pragma mark -
-#pragma mark Defines
-
-#ifdef TEST_DISK_STACK_LOGGING
-#define _malloc_printf fprintf
-#undef ASL_LEVEL_INFO
-#define ASL_LEVEL_INFO stderr
-#endif
-
-#define STACK_LOGGING_MAX_STACK_SIZE 512
-#define STACK_LOGGING_BLOCK_WRITING_SIZE 8192
-#define STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED 3
-
-#define BACKTRACE_UNIQUING_DEBUG 0
-
-// The expansion factor controls the shifting up of table size. A factor of 1 will double the size upon expanding,
-// 2 will quadruple the size, etc. Maintaining a 66% fill in an ideal table requires the collision allowance to
-// increase by 3 for every quadrupling of the table size (although this the constant applied to insertion
-// performance O(c*n))
-#define EXPAND_FACTOR 2
-#define COLLISION_GROWTH_RATE 3
-
-// For a uniquing table, the useful node size is slots := floor(table_byte_size / (2 * sizeof(mach_vm_address_t)))
-// Some useful numbers for the initial max collision value (desiring 66% fill):
-// 16K-23K slots -> 16 collisions
-// 24K-31K slots -> 17 collisions
-// 32K-47K slots -> 18 collisions
-// 48K-79K slots -> 19 collisions
-// 80K-96K slots -> 20 collisions
-#define INITIAL_MAX_COLLIDE 19
-#define DEFAULT_UNIQUING_PAGE_SIZE 256
-
-#pragma mark -
-#pragma mark Macros
-
-#define STACK_LOGGING_FLAGS(longlongvar) (uint8_t)((uint64_t)(longlongvar) >> 56)
-#define STACK_LOGGING_OFFSET(longlongvar) ((longlongvar) & 0x00FFFFFFFFFFFFFFull)
-#define STACK_LOGGING_OFFSET_AND_FLAGS(longlongvar, realshortvar) (((uint64_t)(longlongvar) & 0x00FFFFFFFFFFFFFFull) | ((uint64_t)(realshortvar) << 56))
-
-#pragma mark -
-#pragma mark Types
-
-typedef struct {
- uintptr_t argument;
- uintptr_t address;
- uint64_t offset_and_flags; // top 8 bits are actually the flags!
-} stack_logging_index_event;
-
-typedef struct {
- uint32_t argument;
- uint32_t address;
- uint64_t offset_and_flags; // top 8 bits are actually the flags!
-} stack_logging_index_event32;
-
-typedef struct {
- uint64_t argument;
- uint64_t address;
- uint64_t offset_and_flags; // top 8 bits are actually the flags!
-} stack_logging_index_event64;
-
-#pragma pack(push,4)
-typedef struct {
- uint64_t numPages; // number of pages of the table
- uint64_t numNodes;
- uint64_t tableSize;
- uint64_t untouchableNodes;
- mach_vm_address_t table_address;
- int32_t max_collide;
- // 'table_address' is just an always 64-bit version of the pointer-sized 'table' field to remotely read;
- // it's important that the offset of 'table_address' in the struct does not change between 32 and 64-bit.
-#if BACKTRACE_UNIQUING_DEBUG
- uint64_t nodesFull;
- uint64_t backtracesContained;
-#endif
- mach_vm_address_t *table; // allocated using vm_allocate()
-} backtrace_uniquing_table;
-#pragma pack(pop)
-
-// for storing/looking up allocations that haven't yet be written to disk; consistent size across 32/64-bit processes.
-// It's important that these fields don't change alignment due to the architecture because they may be accessed from an
-// analyzing process with a different arch - hence the pragmas.
-#pragma pack(push,4)
-typedef struct {
- uint64_t start_index_offset;
- uint32_t next_free_index_buffer_offset;
- mach_vm_address_t uniquing_table_address;
- char index_buffer[STACK_LOGGING_BLOCK_WRITING_SIZE];
- backtrace_uniquing_table *uniquing_table;
-} stack_buffer_shared_memory;
-#pragma pack(pop)
-
-// target process address -> record table (for __mach_stack_logging_get_frames)
-typedef struct {
- uint64_t address;
- uint64_t index_file_offset;
-} remote_index_node;
-
-// for caching index information client-side:
-typedef struct {
- size_t cache_size;
- size_t cache_node_capacity;
- uint32_t collision_allowance;
- remote_index_node *table_memory; // this can be malloced; it's on the client side.
- stack_buffer_shared_memory *shmem; // shared memory
- stack_buffer_shared_memory snapshot; // memory snapshot of the remote process' shared memory
- uint32_t last_pre_written_index_size;
- uint64_t last_index_file_offset;
- backtrace_uniquing_table uniquing_table; // snapshot of the remote process' uniquing table
-} remote_index_cache;
-
-// for reading stack history information from remote processes:
-typedef struct {
- task_t remote_task;
- pid_t remote_pid;
- int32_t task_is_64_bit;
- int32_t in_use_count;
- FILE *index_file_stream;
- remote_index_cache *cache;
-} remote_task_file_streams;
-
-#pragma mark -
-#pragma mark Constants/Globals
-
-static OSSpinLock stack_logging_lock = OS_SPINLOCK_INIT;
-
-// support for multi-threaded forks
-extern void __stack_logging_fork_prepare();
-extern void __stack_logging_fork_parent();
-extern void __stack_logging_fork_child();
-extern void __stack_logging_early_finished();
-
-// support for gdb and others checking for stack_logging locks
-__private_extern__ boolean_t __stack_logging_locked();
-
-// single-thread access variables
-static stack_buffer_shared_memory *pre_write_buffers;
-static vm_address_t *stack_buffer;
-static uintptr_t last_logged_malloc_address = 0;
-
-// Constants to define stack logging file path names.
-// Files will get written as /tmp/stack-logs.<pid>.<progname>.XXXXXX.index
-// unless the base directory is specified otherwise with MallocStackLoggingDirectory.
-// In this case, a file /tmp/stack-logs.<pid>.<progname>.XXXXXX.link will also be created.
-static const char *stack_log_file_base_name = "stack-logs.";
-static const char *stack_log_file_suffix = ".index";
-static const char *stack_log_link_suffix = ".link";
-
-static void *stack_log_path_buffers = NULL;
-static char *stack_log_location = NULL;
-static char *stack_log_reference_file = NULL;
-char *__stack_log_file_path__ = NULL;
-static int index_file_descriptor = -1;
-
-// for accessing remote log files
-static remote_task_file_streams remote_fds[STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED];
-static uint32_t next_remote_task_fd = 0;
-static uint32_t remote_task_fd_count = 0;
-static OSSpinLock remote_fd_list_lock = OS_SPINLOCK_INIT;
-
-// activation variables
-static int logging_use_compaction = 1; // set this to zero to always disable compaction.
-
-// We set malloc_logger to NULL to disable logging, if we encounter errors
-// during file writing
-typedef void (malloc_logger_t)(uint32_t type, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3, uintptr_t result, uint32_t num_hot_frames_to_skip);
-extern malloc_logger_t *malloc_logger;
-
-#pragma mark -
-#pragma mark In-Memory Backtrace Uniquing
-
-static __attribute__((always_inline))
-inline void*
-allocate_pages(uint64_t memSize)
-{
- mach_vm_address_t allocatedMem = 0ull;
- if (mach_vm_allocate(mach_task_self(), &allocatedMem, memSize, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_ANALYSIS_TOOL)) != KERN_SUCCESS) {
- malloc_printf("allocate_pages(): virtual memory exhaused!\n");
- }
- return (void*)(uintptr_t)allocatedMem;
-}
-
-static __attribute__((always_inline))
-inline int
-deallocate_pages(void* memPointer, uint64_t memSize)
-{
- return mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)memPointer, memSize);
-}
-
-static backtrace_uniquing_table*
-__create_uniquing_table(void)
-{
- backtrace_uniquing_table *uniquing_table = (backtrace_uniquing_table*)allocate_pages((uint64_t)round_page(sizeof(backtrace_uniquing_table)));
- if (!uniquing_table) return NULL;
- bzero(uniquing_table, sizeof(backtrace_uniquing_table));
- uniquing_table->numPages = DEFAULT_UNIQUING_PAGE_SIZE;
- uniquing_table->tableSize = uniquing_table->numPages * vm_page_size;
- uniquing_table->numNodes = ((uniquing_table->tableSize / (sizeof(mach_vm_address_t) * 2)) >> 1) << 1; // make sure it's even.
- uniquing_table->table = (mach_vm_address_t*)(uintptr_t)allocate_pages(uniquing_table->tableSize);
- uniquing_table->table_address = (uintptr_t)uniquing_table->table;
- uniquing_table->max_collide = INITIAL_MAX_COLLIDE;
- uniquing_table->untouchableNodes = 0;
-
-#if BACKTRACE_UNIQUING_DEBUG
- malloc_printf("create_uniquing_table(): creating. size: %lldKB == %lldMB, numnodes: %lld (%lld untouchable)\n", uniquing_table->tableSize >> 10, uniquing_table->tableSize >> 20, uniquing_table->numNodes, uniquing_table->untouchableNodes);
- malloc_printf("create_uniquing_table(): table: %p; end: %p\n", uniquing_table->table, (void*)((uintptr_t)uniquing_table->table + (uintptr_t)uniquing_table->tableSize));
-#endif
- return uniquing_table;
-}
-
-static void
-__destroy_uniquing_table(backtrace_uniquing_table* table)
-{
- deallocate_pages(table->table, table->tableSize);
- deallocate_pages(table, sizeof(backtrace_uniquing_table));
-}
-
-static void
-__expand_uniquing_table(backtrace_uniquing_table *uniquing_table)
-{
- mach_vm_address_t *oldTable = uniquing_table->table;
- uint64_t oldsize = uniquing_table->tableSize;
- uint64_t oldnumnodes = uniquing_table->numNodes;
-
- uniquing_table->numPages = uniquing_table->numPages << EXPAND_FACTOR;
- uniquing_table->tableSize = uniquing_table->numPages * vm_page_size;
- uniquing_table->numNodes = ((uniquing_table->tableSize / (sizeof(mach_vm_address_t) * 2)) >> 1) << 1; // make sure it's even.
- mach_vm_address_t *newTable = (mach_vm_address_t*)(uintptr_t)allocate_pages(uniquing_table->tableSize);
-
- uniquing_table->table = newTable;
- uniquing_table->table_address = (uintptr_t)uniquing_table->table;
- uniquing_table->max_collide = uniquing_table->max_collide + COLLISION_GROWTH_RATE;
-
- if (mach_vm_copy(mach_task_self(), (mach_vm_address_t)(uintptr_t)oldTable, oldsize, (mach_vm_address_t)(uintptr_t)newTable) != KERN_SUCCESS) {
- malloc_printf("expandUniquingTable(): VMCopyFailed\n");
- }
- uniquing_table->untouchableNodes = oldnumnodes;
-
-#if BACKTRACE_UNIQUING_DEBUG
- malloc_printf("expandUniquingTable(): expanded from nodes full: %lld of: %lld (~%2d%%); to nodes: %lld (inactive = %lld); unique bts: %lld\n",
- uniquing_table->nodesFull, oldnumnodes, (int)(((uniquing_table->nodesFull * 100.0) / (double)oldnumnodes) + 0.5),
- uniquing_table->numNodes, uniquing_table->untouchableNodes, uniquing_table->backtracesContained);
- malloc_printf("expandUniquingTable(): allocate: %p; end: %p\n", newTable, (void*)((uintptr_t)newTable + (uintptr_t)(uniquing_table->tableSize)));
- malloc_printf("expandUniquingTable(): deallocate: %p; end: %p\n", oldTable, (void*)((uintptr_t)oldTable + (uintptr_t)oldsize));
-#endif
-
- if (deallocate_pages(oldTable, oldsize) != KERN_SUCCESS) {
- malloc_printf("expandUniquingTable(): mach_vm_deallocate failed. [%p]\n", uniquing_table->table);
- }
-}
-
-static int
-__enter_frames_in_table(backtrace_uniquing_table *uniquing_table, uint64_t *foundIndex, mach_vm_address_t *frames, int32_t count)
-{
- // The hash values need to be the same size as the addresses (because we use the value -1), for clarity, define a new type
- typedef mach_vm_address_t hash_index_t;
-
- mach_vm_address_t thisPC;
- hash_index_t hash, uParent = (hash_index_t)(-1ll), modulus = (uniquing_table->numNodes-uniquing_table->untouchableNodes-1);
- int32_t collisions, lcopy = count, returnVal = 1;
- hash_index_t hash_multiplier = ((uniquing_table->numNodes - uniquing_table->untouchableNodes)/(uniquing_table->max_collide*2+1));
- mach_vm_address_t *node;
- while (--lcopy >= 0) {
- thisPC = frames[lcopy];
-
- // hash = initialHash(uniquing_table, uParent, thisPC);
- hash = uniquing_table->untouchableNodes + (((uParent << 4) ^ (thisPC >> 2)) % modulus);
- collisions = uniquing_table->max_collide;
-
- while (collisions--) {
- node = uniquing_table->table + (hash * 2);
-
- if (*node == 0 && node[1] == 0) {
- // blank; store this entry!
- // Note that we need to test for both head[0] and head[1] as (0, -1) is a valid entry
- node[0] = thisPC;
- node[1] = uParent;
- uParent = hash;
-#if BACKTRACE_UNIQUING_DEBUG
- uniquing_table->nodesFull++;
- if (lcopy == 0) {
- uniquing_table->backtracesContained++;
- }
-#endif
- break;
- }
- if (*node == thisPC && node[1] == uParent) {
- // hit! retrieve index and go.
- uParent = hash;
- break;
- }
-
- hash += collisions * hash_multiplier + 1;
-
- if (hash >= uniquing_table->numNodes) {
- hash -= (uniquing_table->numNodes - uniquing_table->untouchableNodes); // wrap around.
- }
- }
-
- if (collisions < 0) {
- returnVal = 0;
- break;
- }
- }
-
- if (returnVal) *foundIndex = uParent;
-
- return returnVal;
-}
-
-static void
-__unwind_stack_from_table_index(backtrace_uniquing_table *uniquing_table, uint64_t index_pos, mach_vm_address_t *out_frames_buffer, uint32_t *out_frames_count, uint32_t max_frames)
-{
- mach_vm_address_t *node = uniquing_table->table + (index_pos * 2);
- uint32_t foundFrames = 0;
- if (index_pos < uniquing_table->numNodes) {
- while (foundFrames < max_frames) {
- out_frames_buffer[foundFrames++] = node[0];
- if (node[1] == (mach_vm_address_t)(-1ll)) break;
- node = uniquing_table->table + (node[1] * 2);
- }
- }
-
- *out_frames_count = foundFrames;
-}
-
-#pragma mark -
-#pragma mark Disk Stack Logging
-
-static void delete_log_files(void); // pre-declare
-static int delete_logging_file(char *log_location);
-
-static void
-append_int(char * filename, pid_t pid, size_t maxLength)
-{
- size_t len = strlen(filename);
-
- uint32_t count = 0;
- pid_t value = pid;
- while (value > 0) {
- value /= 10;
- count++;
- }
-
- if (len + count >= maxLength) return; // don't modify the string if it would violate maxLength
-
- filename[len + count] = '\0';
-
- value = pid;
- uint32_t i;
- for (i = 0 ; i < count ; i ++) {
- filename[len + count - 1 - i] = '0' + value % 10;
- value /= 10;
- }
-}
-
-/*
- * <rdar://problem/11128080> if we needed to call confstr during init then setting this
- * flag will postpone stack logging until after Libsystem's initialiser has run.
- */
-static void
-postpone_stack_logging(void)
-{
- _malloc_printf(ASL_LEVEL_INFO, "stack logging postponed until after initialization.\n");
- stack_logging_postponed = 1;
-}
-
-/*
- * Check various temporary directory options starting with _PATH_TMP and use confstr.
- * Allocating and releasing target buffer is the caller's responsibility.
- */
-static bool
-get_writeable_temp_dir(char* target)
-{
- if (!target) return false;
- if (-1 != access(_PATH_TMP, W_OK)) {
- strlcpy(target, _PATH_TMP, (size_t)PATH_MAX);
- return true;
- }
- if (getenv("TMPDIR") && (-1 != access(getenv("TMPDIR"), W_OK))) {
- strlcpy(target, getenv("TMPDIR"), (size_t)PATH_MAX);
- return true;
- }
- if (stack_logging_finished_init) {
- size_t n = confstr(_CS_DARWIN_USER_TEMP_DIR, target, (size_t) PATH_MAX);
- if ((n > 0) && (n < PATH_MAX)) return true;
- n = confstr(_CS_DARWIN_USER_CACHE_DIR, target, (size_t) PATH_MAX);
- if ((n > 0) && (n < PATH_MAX)) return true;
- } else {
- /* <rdar://problem/11128080> Can't call confstr during init, so postpone
- logging till after */
- postpone_stack_logging();
- }
- /* No writeable tmp directory found. Maybe shd try /private/var/tmp for device here ... */
- *target = '\0';
- return false;
-}
-
-/*
- * If successful, returns path to log file that was created, otherwise NULL.
- *
- * The log could be in one of 3 places (in decreasing order of preference)
- *
- * 1) value of environment variable MallocStackLoggingDirectory
- * 2) the temp directory /tmp for desktop apps and internal apps on devices, or
- * 3) the sandbox location + tmp/ in case of 3rd party apps on the device.
- *
- * For 1 and 3, we create a .link file with the path of the file. We prefer to
- * create this file in /tmp, but if we are unable to (device 3rd party case),
- * we create it in the same location as the .index file and issue a message
- * in syslog asking for it to be copied to /tmp to enable tools.
- *
- */
-static char *
-create_log_file(void)
-{
- pid_t pid = getpid();
- const char *progname = getprogname();
- char *created_log_location = NULL;
-
- if (stack_log_path_buffers == NULL) {
- /*
- * on first use, allocate buffers directly from the OS without
- * using malloc
- */
-
- stack_log_path_buffers = allocate_pages((uint64_t)round_page(3*PATH_MAX));
- if (stack_log_path_buffers == NULL) {
- _malloc_printf(ASL_LEVEL_INFO, "unable to allocate memory for path buffers\n");
- return NULL;
- }
-
- stack_log_location = &((char *)stack_log_path_buffers)[0*PATH_MAX];
- stack_log_reference_file = &((char *)stack_log_path_buffers)[1*PATH_MAX];
- __stack_log_file_path__ = &((char *)stack_log_path_buffers)[2*PATH_MAX];
- }
-
- // WARNING! use of snprintf can induce malloc() calls
- bool use_alternate_location = false;
- char *evn_log_directory = getenv("MallocStackLoggingDirectory");
- size_t stack_log_len;
- if (evn_log_directory && *evn_log_directory) {
- use_alternate_location = true;
- strlcpy(stack_log_location, evn_log_directory, (size_t)PATH_MAX);
- }
- if (!use_alternate_location || (access(stack_log_location, W_OK) == -1)) {
- if (!get_writeable_temp_dir(stack_log_location)) {
- if (!stack_logging_postponed) {
- _malloc_printf(ASL_LEVEL_INFO, "No writeable tmp dir\n");
- }
- return NULL;
- }
- if (0 != strcmp(stack_log_location, _PATH_TMP))
- use_alternate_location = true;
- }
- stack_log_len = strlen(stack_log_location);
- // add the '/' only if it's not already there.
- if (stack_log_location[stack_log_len-1] != '/') {
- strlcat(stack_log_location, "/", (size_t)PATH_MAX);
- ++stack_log_len;
- }
-
- strlcpy(__stack_log_file_path__, stack_log_location, (size_t)PATH_MAX);
-
- strlcat(__stack_log_file_path__, stack_log_file_base_name, (size_t)PATH_MAX);
- append_int(__stack_log_file_path__, pid, (size_t)PATH_MAX);
- if (progname && progname[0] != '\0') {
- strlcat(__stack_log_file_path__, ".", (size_t)PATH_MAX);
- strlcat(__stack_log_file_path__, progname, (size_t)PATH_MAX);
- }
- if (!use_alternate_location) strlcat(__stack_log_file_path__, ".XXXXXX", (size_t)PATH_MAX);
- strlcat(__stack_log_file_path__, stack_log_file_suffix, (size_t)PATH_MAX);
-
- // Securely create the log file.
- if ((index_file_descriptor = mkstemps(__stack_log_file_path__, (int)strlen(stack_log_file_suffix))) != -1) {
- _malloc_printf(ASL_LEVEL_INFO, "stack logs being written into %s\n", __stack_log_file_path__);
- created_log_location = __stack_log_file_path__;
- } else {
- _malloc_printf(ASL_LEVEL_INFO, "unable to create stack logs at %s\n", stack_log_location);
- if (use_alternate_location) delete_logging_file(stack_log_reference_file);
- stack_log_reference_file[0] = '\0';
- stack_log_location[0] = '\0';
- __stack_log_file_path__[0] = '\0';
- created_log_location = NULL;
- return created_log_location;
- }
-
- // in the case where the user has specified an alternate location, drop a reference file
- // in /tmp with the suffix 'stack_log_link_suffix' (".link") and save the path of the
- // stack logging file there.
- bool use_alternate_link_location = false;
- if (use_alternate_location) {
- strlcpy(stack_log_reference_file, _PATH_TMP, (size_t)PATH_MAX);
- if (access(stack_log_reference_file, W_OK) == -1) {
- strlcpy(stack_log_reference_file, stack_log_location, (size_t)PATH_MAX);
- use_alternate_link_location = true;
- }
- strlcat(stack_log_reference_file, stack_log_file_base_name, (size_t)PATH_MAX);
- append_int(stack_log_reference_file, pid, (size_t)PATH_MAX);
- if (progname && progname[0] != '\0') {
- strlcat(stack_log_reference_file, ".", (size_t)PATH_MAX);
- strlcat(stack_log_reference_file, progname, (size_t)PATH_MAX);
- }
- if (!use_alternate_link_location)
- strlcat(stack_log_reference_file, ".XXXXXX", (size_t)PATH_MAX);
- strlcat(stack_log_reference_file, ".XXXXXX", (size_t)PATH_MAX);
- strlcat(stack_log_reference_file, stack_log_link_suffix, (size_t)PATH_MAX);
-
- int link_file_descriptor = mkstemps(stack_log_reference_file, (int)strlen(stack_log_link_suffix));
- if (link_file_descriptor == -1) {
- _malloc_printf(ASL_LEVEL_INFO, "unable to create stack reference file %s at %s\n",
- stack_log_reference_file, stack_log_location);
- } else {
- ssize_t written = write(link_file_descriptor, __stack_log_file_path__, strlen(__stack_log_file_path__));
- if (written < (ssize_t)strlen(__stack_log_file_path__)) {
- _malloc_printf(ASL_LEVEL_INFO, "unable to write to stack reference file %s at %s\n",
- stack_log_reference_file, stack_log_location);
- } else {
- const char *description_string = "\n(This is a reference file to the stack logs at the path above.)\n";
- write(link_file_descriptor, description_string, strlen(description_string));
- }
- }
- close(link_file_descriptor);
- }
- if (use_alternate_link_location) {
- _malloc_printf(ASL_LEVEL_INFO, "Please issue: cp %s %s\n", stack_log_reference_file, _PATH_TMP);
- }
- return created_log_location;
-}
-
-// Check to see if the log file is actually a reference to another location
-static int
-log_file_is_reference(char *log_location, char *out_reference_loc_buffer, size_t max_reference_path_size)
-{
- if (log_location == NULL || log_location[0] == '\0') return 0;
-
- size_t log_len = strlen(log_location);
- size_t link_suffix_len = strlen(stack_log_link_suffix);
- if (log_len < link_suffix_len || strncmp(log_location+log_len-link_suffix_len, stack_log_link_suffix, link_suffix_len) != 0) {
- // not a reference file.
- return 0;
- }
-
- if (!out_reference_loc_buffer || max_reference_path_size == 0) return 1;
-
- FILE *reference_file = fopen(log_location, "r");
- if (reference_file == NULL) {
- // if unable to open the file, it may be because another user created it; no need to warn.
- out_reference_loc_buffer[0] = '\0';
- return 1;
- }
-
- char *ret = fgets(out_reference_loc_buffer, (int)max_reference_path_size, reference_file);
- if (!ret) {
- out_reference_loc_buffer[0] = '\0';
- _malloc_printf(ASL_LEVEL_INFO, "unable to read from stack logging reference file at %s\n", log_location);
- return 1;
- } else {
- size_t read_line_len = strlen(out_reference_loc_buffer);
- if (read_line_len >= 1 && out_reference_loc_buffer[read_line_len-1] == '\n') {
- out_reference_loc_buffer[read_line_len-1] = '\0';
- }
- }
-
- fclose(reference_file);
-
- return 1;
-}
-
-// This function may be called from either the target process when exiting, or from either the the target process or
-// a stack log analysis process, when reaping orphaned stack log files.
-// Returns -1 if the files exist and they couldn't be removed, returns 0 otherwise.
-static int
-delete_logging_file(char *log_location)
-{
- if (log_location == NULL || log_location[0] == '\0') return 0;
-
- struct stat statbuf;
- if (unlink(log_location) != 0 && stat(log_location, &statbuf) == 0) {
- return -1;
- }
- return 0;
-}
-
-// This function will be called from atexit() in the target process.
-static void
-delete_log_files(void)
-{
- if (__stack_log_file_path__ && __stack_log_file_path__[0]) {
- if (delete_logging_file(__stack_log_file_path__) == 0) {
- _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", __stack_log_file_path__);
- __stack_log_file_path__[0] = '\0';
- } else {
- _malloc_printf(ASL_LEVEL_INFO, "unable to delete stack logs from %s\n", __stack_log_file_path__);
- }
- }
- if (stack_log_reference_file && stack_log_reference_file[0]) {
- delete_logging_file(stack_log_reference_file);
- }
-}
-
-static bool
-is_process_running(pid_t pid)
-{
- struct kinfo_proc kpt[1];
- size_t size = sizeof(struct kinfo_proc);
- int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
-
- sysctl(mib, 4, kpt, &size, NULL, (size_t)0); // size is either 1 or 0 entries when we ask for a single pid
-
- return (size==sizeof(struct kinfo_proc));
-}
-
-// The log files can be quite large and aren't too useful after the process that created them no longer exists.
-// Normally they should get removed when the process exits, but if the process crashed the log files might remain.
-// So, reap any stack log files for processes that no longer exist.
-//
-// lf the remove_for_this_pid flag is set, then any log files that already exist for the current process will also be deleted.
-// Those log files are probably the result of this process having been exec'ed from another one (without a fork()).
-// The remove_for_this_pid flag is only set for a target process (one just starting logging); a stack logging "client"
-// process reaps log files too, but if we're using stack logging on the client process itself, then we don't want to remove
-// its own log files.
-static void
-reap_orphaned_log_files(bool remove_for_this_pid)
-{
- DIR *dp;
- struct dirent *entry;
- char prefix_name[PATH_MAX];
- char pathname[PATH_MAX];
- pid_t current_pid = getpid();
-
- if ((dp = opendir(_PATH_TMP)) == NULL) {
- return;
- }
-
- strlcpy(prefix_name, stack_log_file_base_name, (size_t)PATH_MAX);
- size_t prefix_length = strlen(prefix_name);
-
- while ( (entry = readdir(dp)) != NULL ) {
- if ( entry->d_type != DT_DIR && entry->d_type != DT_LNK && ( strncmp( entry->d_name, prefix_name, prefix_length) == 0 ) ) {
- long pid = strtol(&entry->d_name[prefix_length], (char **)NULL, 10);
- if ( (! is_process_running((pid_t)pid)) || (remove_for_this_pid && (pid_t)pid == current_pid) ) {
- strlcpy(pathname, _PATH_TMP, (size_t)PATH_MAX);
- strlcat(pathname, entry->d_name, (size_t)PATH_MAX);
- char reference_file_buffer[PATH_MAX];
- bool pathname_is_ref_file = false;
- if (log_file_is_reference(pathname, reference_file_buffer, (size_t)PATH_MAX) && *reference_file_buffer) {
- pathname_is_ref_file = true;
- if (delete_logging_file(reference_file_buffer) == 0) {
- if (remove_for_this_pid && pid == current_pid) {
- _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", reference_file_buffer);
- } else {
- _malloc_printf(ASL_LEVEL_INFO, "process %ld no longer exists, stack logs deleted from %s\n", pid, reference_file_buffer);
- }
- }
- }
- if (delete_logging_file(pathname) == 0) {
- if (remove_for_this_pid && pid == current_pid) {
- if (!pathname_is_ref_file) _malloc_printf(ASL_LEVEL_INFO, "stack logs deleted from %s\n", pathname);
- } else {
- if (!pathname_is_ref_file) _malloc_printf(ASL_LEVEL_INFO, "process %ld no longer exists, stack logs deleted from %s\n", pid, pathname);
- }
- char shmem_name_string[PATH_MAX];
- strlcpy(shmem_name_string, stack_log_file_base_name, (size_t)PATH_MAX);
- append_int(shmem_name_string, (pid_t)pid, (size_t)PATH_MAX);
- if (pid != current_pid) shm_unlink(shmem_name_string);
- }
- }
- }
- }
- closedir(dp);
-}
-
-/*
- * Since there a many errors that could cause stack logging to get disabled, this is a convenience method
- * for disabling any future logging in this process and for informing the user.
- */
-static void
-disable_stack_logging(void)
-{
- _malloc_printf(ASL_LEVEL_INFO, "stack logging disabled due to previous errors.\n");
- stack_logging_enable_logging = 0;
- malloc_logger = NULL;
-}
-
-/* A wrapper around write() that will try to reopen the index/stack file and
- * write to it if someone closed it underneath us (e.g. the process we just
- * started decide to close all file descriptors except stin/err/out). Some
- * programs like to do that and calling abort() on them is rude.
- */
-static ssize_t
-robust_write(int fd, const void *buf, size_t nbyte) {
- extern int errno;
- ssize_t written = write(fd, buf, nbyte);
- if (written == -1 && errno == EBADF) {
- char *file_to_reopen = NULL;
- int *fd_to_reset = NULL;
-
- // descriptor was closed on us. We need to reopen it
- if (fd == index_file_descriptor) {
- file_to_reopen = __stack_log_file_path__;
- fd_to_reset = &index_file_descriptor;
- } else {
- // We don't know about this file. Return (and abort()).
- _malloc_printf(ASL_LEVEL_INFO, "Unknown file descriptor; expecting stack logging index file\n");
- return -1;
- }
-
- // The file *should* already exist. If not, fail.
- fd = open(file_to_reopen, O_WRONLY | O_APPEND);
- if (fd < 3) {
- // If we somehow got stdin/out/err, we need to relinquish them and
- // get another fd.
- int fds_to_close[3] = { 0 };
- while (fd < 3) {
- if (fd == -1) {
- _malloc_printf(ASL_LEVEL_INFO, "unable to re-open stack logging file %s\n", file_to_reopen);
- delete_log_files();
- return -1;
- }
- fds_to_close[fd] = 1;
- fd = dup(fd);
- }
-
- // We have an fd we like. Close the ones we opened.
- if (fds_to_close[0]) close(0);
- if (fds_to_close[1]) close(1);
- if (fds_to_close[2]) close(2);
- }
-
- *fd_to_reset = fd;
- written = write(fd, buf, nbyte);
- }
- return written;
-}
-
-static void
-flush_data(void)
-{
- ssize_t written; // signed size_t
- size_t remaining;
- char * p;
-
- if (index_file_descriptor == -1) {
- if (create_log_file() == NULL) {
- return;
- }
- }
-
- // Write the events before the index so that hopefully the events will be on disk if the index refers to them.
- p = pre_write_buffers->index_buffer;
- remaining = (size_t)pre_write_buffers->next_free_index_buffer_offset;
- while (remaining > 0) {
- written = robust_write(index_file_descriptor, p, remaining);
- if (written == -1) {
- _malloc_printf(ASL_LEVEL_INFO, "Unable to write to stack logging file %s (%s)\n",
- __stack_log_file_path__, strerror(errno));
- disable_stack_logging();
- return;
- }
- p += written;
- remaining -= written;
- }
-
- pre_write_buffers->start_index_offset += pre_write_buffers->next_free_index_buffer_offset;
- pre_write_buffers->next_free_index_buffer_offset = 0;
-}
-
-static void
-prepare_to_log_stacks(void)
-{
- if (!pre_write_buffers) {
- last_logged_malloc_address = 0ul;
- logging_use_compaction = (stack_logging_dontcompact ? 0 : logging_use_compaction);
-
- // Create a shared memory region to hold the pre-write index and stack buffers. This will allow remote analysis processes to access
- // these buffers to get logs for even the most recent allocations. The remote process will need to pause this process to assure that
- // the contents of these buffers don't change while being inspected.
- char shmem_name_string[PATH_MAX];
- strlcpy(shmem_name_string, stack_log_file_base_name, (size_t)PATH_MAX);
- append_int(shmem_name_string, getpid(), (size_t)PATH_MAX);
-
- int shmid = shm_open(shmem_name_string, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
- if (shmid < 0) {
- // Failed to create shared memory region; turn off stack logging.
- _malloc_printf(ASL_LEVEL_INFO, "error while allocating shared memory for disk-based stack logging output buffers\n");
- disable_stack_logging();
- return;
- }
-
- size_t full_shared_mem_size = sizeof(stack_buffer_shared_memory);
- ftruncate(shmid, (off_t)full_shared_mem_size);
- pre_write_buffers = (stack_buffer_shared_memory*)mmap(0, full_shared_mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, shmid, (off_t)0);
- close(shmid);
-
- if (MAP_FAILED == pre_write_buffers) {
- _malloc_printf(ASL_LEVEL_INFO, "error mapping in shared memory for disk-based stack logging output buffers\n");
- disable_stack_logging();
- return;
- }
-
- // Store and use the buffer offsets in shared memory so that they can be accessed remotely
- pre_write_buffers->start_index_offset = 0ull;
- pre_write_buffers->next_free_index_buffer_offset = 0;
-
- // create the backtrace uniquing table
- pre_write_buffers->uniquing_table = __create_uniquing_table();
- pre_write_buffers->uniquing_table_address = (mach_vm_address_t)(uintptr_t)pre_write_buffers->uniquing_table;
- if (!pre_write_buffers->uniquing_table) {
- _malloc_printf(ASL_LEVEL_INFO, "error while allocating stack uniquing table\n");
- disable_stack_logging();
- return;
- }
-
- uint64_t stack_buffer_sz = (uint64_t)round_page(sizeof(vm_address_t) * STACK_LOGGING_MAX_STACK_SIZE);
- stack_buffer = (vm_address_t*)allocate_pages(stack_buffer_sz);
- if (!stack_buffer) {
- _malloc_printf(ASL_LEVEL_INFO, "error while allocating stack trace buffer\n");
- disable_stack_logging();
- return;
- }
-
- // malloc() can be called by the following, so these need to be done outside the stack_logging_lock but after the buffers have been set up.
- atexit(delete_log_files); // atexit() can call malloc()
- reap_orphaned_log_files(true); // this calls opendir() which calls malloc()
-
- // this call ensures that the log files exist; analyzing processes will rely on this assumption.
- if (create_log_file() == NULL) {
- /* postponement support requires cleaning up these structures now */
- __destroy_uniquing_table(pre_write_buffers->uniquing_table);
- deallocate_pages(stack_buffer, stack_buffer_sz);
- stack_buffer = NULL;
-
- munmap(pre_write_buffers, full_shared_mem_size);
- pre_write_buffers = NULL;
-
- if (!stack_logging_postponed) {
- disable_stack_logging();
- }
- return;
- }
- }
-}
-
-void
-__disk_stack_logging_log_stack(uint32_t type_flags, uintptr_t zone_ptr, uintptr_t size, uintptr_t ptr_arg, uintptr_t return_val, uint32_t num_hot_to_skip)
-{
- if (!stack_logging_enable_logging || stack_logging_postponed) return;
-
- // check incoming data
- if (type_flags & stack_logging_type_alloc && type_flags & stack_logging_type_dealloc) {
- uintptr_t swapper = size;
- size = ptr_arg;
- ptr_arg = swapper;
- if (ptr_arg == return_val) return; // realloc had no effect, skipping
-
- if (ptr_arg == 0) { // realloc(NULL, size) same as malloc(size)
- type_flags ^= stack_logging_type_dealloc;
- } else {
- // realloc(arg1, arg2) -> result is same as free(arg1); malloc(arg2) -> result
- __disk_stack_logging_log_stack(stack_logging_type_dealloc, zone_ptr, ptr_arg, (uintptr_t)0, (uintptr_t)0, num_hot_to_skip + 1);
- __disk_stack_logging_log_stack(stack_logging_type_alloc, zone_ptr, size, (uintptr_t)0, return_val, num_hot_to_skip + 1);
- return;
- }
- }
- if (type_flags & stack_logging_type_dealloc) {
- if (size) {
- ptr_arg = size;
- size = 0;
- } else return; // free(nil)
- }
- if (type_flags & stack_logging_type_alloc && return_val == 0) return; // alloc that failed
-
- type_flags &= 0x7;
-
- // now actually begin
- prepare_to_log_stacks();
-
- // since there could have been a fatal (to stack logging) error such as the log files not being created, check this variable before continuing
- if (!stack_logging_enable_logging || stack_logging_postponed) return;
-
- vm_address_t self_thread = (vm_address_t)pthread_self(); // use pthread_self() rather than mach_thread_self() to avoid system call
-
- // lock and enter
- OSSpinLockLock(&stack_logging_lock);
-
- if (!stack_logging_enable_logging) {
- OSSpinLockUnlock(&stack_logging_lock);
- return;
- }
-
- // compaction
- if (last_logged_malloc_address && (type_flags & stack_logging_type_dealloc) && STACK_LOGGING_DISGUISE(ptr_arg) == last_logged_malloc_address) {
- // *waves hand* the last allocation never occurred
- pre_write_buffers->next_free_index_buffer_offset -= (uint32_t)sizeof(stack_logging_index_event);
- last_logged_malloc_address = 0ul;
-
- OSSpinLockUnlock(&stack_logging_lock);
- return;
- }
-
- // gather stack
- uint32_t count;
- thread_stack_pcs(stack_buffer, STACK_LOGGING_MAX_STACK_SIZE-1, &count); // only gather up to STACK_LOGGING_MAX_STACK_SIZE-1 since we append thread id
- stack_buffer[count++] = self_thread + 1; // stuffing thread # in the coldest slot. Add 1 to match what the old stack logging did.
- num_hot_to_skip += 2;
- if (count <= num_hot_to_skip) {
- // Oops! Didn't get a valid backtrace from thread_stack_pcs().
- OSSpinLockUnlock(&stack_logging_lock);
- return;
- }
-
- // unique stack in memory
- count -= num_hot_to_skip;
-#if __LP64__
- mach_vm_address_t *frames = (mach_vm_address_t*)stack_buffer + num_hot_to_skip;
-#else
- mach_vm_address_t frames[STACK_LOGGING_MAX_STACK_SIZE];
- uint32_t i;
- for (i = 0; i < count; i++) {
- frames[i] = stack_buffer[i+num_hot_to_skip];
- }
-#endif
-
- uint64_t uniqueStackIdentifier = (uint64_t)(-1ll);
- while (!__enter_frames_in_table(pre_write_buffers->uniquing_table, &uniqueStackIdentifier, frames, (int32_t)count)) {
- __expand_uniquing_table(pre_write_buffers->uniquing_table);
- }
-
- stack_logging_index_event current_index;
- if (type_flags & stack_logging_type_alloc) {
- current_index.address = STACK_LOGGING_DISGUISE(return_val);
- current_index.argument = size;
- if (logging_use_compaction) {
- last_logged_malloc_address = current_index.address; // disguised
- }
- } else {
- current_index.address = STACK_LOGGING_DISGUISE(ptr_arg);
- current_index.argument = 0ul;
- last_logged_malloc_address = 0ul;
- }
- current_index.offset_and_flags = STACK_LOGGING_OFFSET_AND_FLAGS(uniqueStackIdentifier, type_flags);
-
-// the following line is a good debugging tool for logging each allocation event as it happens.
-// malloc_printf("{0x%lx, %lld}\n", STACK_LOGGING_DISGUISE(current_index.address), uniqueStackIdentifier);
-
- // flush the data buffer to disk if necessary
- if (pre_write_buffers->next_free_index_buffer_offset + sizeof(stack_logging_index_event) >= STACK_LOGGING_BLOCK_WRITING_SIZE) {
- flush_data();
- }
-
- // store bytes in buffers
- memcpy(pre_write_buffers->index_buffer+pre_write_buffers->next_free_index_buffer_offset, ¤t_index, sizeof(stack_logging_index_event));
- pre_write_buffers->next_free_index_buffer_offset += (uint32_t)sizeof(stack_logging_index_event);
-
- OSSpinLockUnlock(&stack_logging_lock);
-}
-
-void
-__stack_logging_fork_prepare() {
- OSSpinLockLock(&stack_logging_lock);
-}
-
-void
-__stack_logging_fork_parent() {
- OSSpinLockUnlock(&stack_logging_lock);
-}
-
-void
-__stack_logging_fork_child() {
- malloc_logger = NULL;
- stack_logging_enable_logging = 0;
- OSSpinLockUnlock(&stack_logging_lock);
-}
-
-void
-__stack_logging_early_finished() {
- stack_logging_finished_init = 1;
- stack_logging_postponed = 0;
-}
-
-boolean_t
-__stack_logging_locked()
-{
- bool acquired_lock = OSSpinLockTry(&stack_logging_lock);
- if (acquired_lock) OSSpinLockUnlock(&stack_logging_lock);
- return (acquired_lock ? false : true);
-}
-
-#pragma mark -
-#pragma mark Remote Stack Log Access
-
-#pragma mark - Design notes:
-
-/*
-
-this first one will look through the index, find the "stack_identifier" (i.e. the offset in the log file), and call the third function listed here.
-extern kern_return_t __mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *num_frames);
- // Gets the last allocation record about address
-
-if !address, will load index and iterate through (expensive)
-else will load just index, search for stack, and then use third function here to retrieve. (also expensive)
-extern kern_return_t __mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context);
- // Applies enumerator to all records involving address sending context as enumerator's second parameter; if !address, applies enumerator to all records
-
-this function will load the stack file, look for the stack, and follow up to STACK_LOGGING_FORCE_FULL_BACKTRACE_EVERY references to reconstruct.
-extern kern_return_t __mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count);
- // Given a uniqued_stack fills stack_frames_buffer
-
-*/
-
-#pragma mark - caching
-
-__attribute__((always_inline)) static inline size_t
-hash_index(uint64_t address, size_t max_pos) {
- return (size_t)((address >> 2) % (max_pos-1)); // simplicity rules.
-}
-
-__attribute__((always_inline)) static inline size_t
-hash_multiplier(size_t capacity, uint32_t allowed_collisions) {
- return (capacity/(allowed_collisions*2+1));
-}
-
-__attribute__((always_inline)) static inline size_t
-next_hash(size_t hash, size_t multiplier, size_t capacity, uint32_t collisions) {
- hash += multiplier * collisions;
- if (hash >= capacity) hash -= capacity;
- return hash;
-}
-
-static void
-transfer_node(remote_index_cache *cache, remote_index_node *old_node)
-{
- uint32_t collisions = 0;
- size_t pos = hash_index(old_node->address, cache->cache_node_capacity);
- size_t multiplier = hash_multiplier(cache->cache_node_capacity, cache->collision_allowance);
- do {
- if (cache->table_memory[pos].address == old_node->address) { // hit like this shouldn't happen.
- fprintf(stderr, "impossible collision! two address==address lists! (transfer_node)\n");
- break;
- } else if (cache->table_memory[pos].address == 0) { // empty
- cache->table_memory[pos] = *old_node;
- break;
- } else {
- collisions++;
- pos = next_hash(pos, multiplier, cache->cache_node_capacity, collisions);
- }
- } while (collisions <= cache->collision_allowance);
-
- if (collisions > cache->collision_allowance) {
- fprintf(stderr, "reporting bad hash function! disk stack logging reader %lu bit. (transfer_node)\n", sizeof(void*)*8);
- }
-}
-
-static void
-expand_cache(remote_index_cache *cache)
-{
- // keep old stats
- size_t old_node_capacity = cache->cache_node_capacity;
- remote_index_node *old_table = cache->table_memory;
-
- // double size
- cache->cache_size <<= 2;
- cache->cache_node_capacity <<= 2;
- cache->collision_allowance += 3;
- cache->table_memory = (void*)calloc(cache->cache_node_capacity, sizeof(remote_index_node));
-
- // repopulate (expensive!)
- size_t i;
- for (i = 0; i < old_node_capacity; i++) {
- if (old_table[i].address) {
- transfer_node(cache, &old_table[i]);
- }
- }
- free(old_table);
-// printf("cache expanded to %0.2f mb (eff: %3.0f%%, capacity: %lu, nodes: %llu, llnodes: %llu)\n", ((float)(cache->cache_size))/(1 << 20), ((float)(cache->cache_node_count)*100.0)/((float)(cache->cache_node_capacity)), cache->cache_node_capacity, cache->cache_node_count, cache->cache_llnode_count);
-}
-
-static void
-insert_node(remote_index_cache *cache, uint64_t address, uint64_t index_file_offset)
-{
- uint32_t collisions = 0;
- size_t pos = hash_index(address, cache->cache_node_capacity);
- size_t multiplier = hash_multiplier(cache->cache_node_capacity, cache->collision_allowance);
-
- bool inserted = false;
- while (!inserted) {
- if (cache->table_memory[pos].address == 0ull || cache->table_memory[pos].address == address) { // hit or empty
- cache->table_memory[pos].address = address;
- cache->table_memory[pos].index_file_offset = index_file_offset;
- inserted = true;
- break;
- }
-
- collisions++;
- pos = next_hash(pos, multiplier, cache->cache_node_capacity, collisions);
-
- if (collisions > cache->collision_allowance) {
- expand_cache(cache);
- pos = hash_index(address, cache->cache_node_capacity);
- multiplier = hash_multiplier(cache->cache_node_capacity, cache->collision_allowance);
- collisions = 0;
- }
- }
-
-}
-
-static void
-update_cache_for_file_streams(remote_task_file_streams *descriptors)
-{
- remote_index_cache *cache = descriptors->cache;
-
- // create from scratch if necessary.
- if (!cache) {
- descriptors->cache = cache = (remote_index_cache*)calloc((size_t)1, sizeof(remote_index_cache));
- cache->cache_node_capacity = 1 << 14;
- cache->collision_allowance = 17;
- cache->last_index_file_offset = 0;
- cache->cache_size = cache->cache_node_capacity*sizeof(remote_index_node);
- cache->table_memory = (void*)calloc(cache->cache_node_capacity, sizeof(remote_index_node));
-
- // now map in the shared memory, if possible
- char shmem_name_string[PATH_MAX];
- strlcpy(shmem_name_string, stack_log_file_base_name, (size_t)PATH_MAX);
- append_int(shmem_name_string, descriptors->remote_pid, (size_t)PATH_MAX);
-
- int shmid = shm_open(shmem_name_string, O_RDWR, S_IRUSR | S_IWUSR);
- if (shmid >= 0) {
- cache->shmem = mmap(0, sizeof(stack_buffer_shared_memory), PROT_READ | PROT_WRITE, MAP_SHARED, shmid, (off_t)0);
- close(shmid);
- }
-
- if (shmid < 0 || cache->shmem == MAP_FAILED) {
- // failed to connect to the shared memory region; warn and continue.
- _malloc_printf(ASL_LEVEL_INFO, "warning: unable to connect to remote process' shared memory; allocation histories may not be up-to-date.\n");
- }
- }
-
- // suspend and see how much updating there is to do. there are three scenarios, listed below
- bool update_snapshot = false;
- if (descriptors->remote_task != mach_task_self()) {
- task_suspend(descriptors->remote_task);
- }
-
- struct stat file_statistics;
- fstat(fileno(descriptors->index_file_stream), &file_statistics);
- size_t read_size = (descriptors->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32));
- uint64_t read_this_update = 0;
-
- // the delta indecies is a complex number; there are three cases:
- // 1. there is no shared memory (or we can't connect); diff the last_index_file_offset from the filesize.
- // 2. the only updates have been in shared memory; disk file didn't change at all. delta_indecies should be zero, scan snapshot only.
- // 3. the updates have flushed to disk, meaning that most likely there is new data on disk that wasn't read from shared memory.
- // correct delta_indecies for the pre-scanned amount and read the new data from disk and shmem.
- uint64_t delta_indecies = (file_statistics.st_size - cache->last_index_file_offset) / read_size;
- uint32_t last_snapshot_scan_index = 0;
- if (delta_indecies && cache->shmem) {
- // case 3: add cache scanned to known from disk and recalc
- cache->last_index_file_offset += cache->snapshot.next_free_index_buffer_offset;
- delta_indecies = (file_statistics.st_size - cache->last_index_file_offset) / read_size;
- update_snapshot = true;
- } else if (cache->shmem) {
- // case 2: set the last snapshot scan count so we don't rescan something we've seen.
- last_snapshot_scan_index = cache->snapshot.next_free_index_buffer_offset / (uint32_t)read_size;
- }
-
- // no update necessary for the file; check if need a snapshot.
- if (delta_indecies == 0) {
- if (cache->shmem && !update_snapshot) {
- update_snapshot = (cache->shmem->next_free_index_buffer_offset != cache->snapshot.next_free_index_buffer_offset);
- }
- }
-
- // if a snapshot is necessary, memcpy from remote frozen process' memory
- // note: there were two ways to do this - spin lock or suspend. suspend allows us to
- // analyze processes even if they were artificially suspended. with a lock, there'd be
- // worry that the target was suspended with the lock taken.
- if (update_snapshot) {
- memcpy(&cache->snapshot, cache->shmem, sizeof(stack_buffer_shared_memory));
- // also need to update our version of the remote uniquing table
- vm_address_t local_uniquing_address = 0ul;
- mach_msg_type_number_t local_uniquing_size = 0;
- mach_vm_size_t desired_size = round_page(sizeof(backtrace_uniquing_table));
- kern_return_t err;
- if ((err = mach_vm_read(descriptors->remote_task, cache->shmem->uniquing_table_address, desired_size, &local_uniquing_address, &local_uniquing_size)) != KERN_SUCCESS
- || local_uniquing_size != desired_size) {
- fprintf(stderr, "error while attempting to mach_vm_read remote stack uniquing table (%d): %s\n", err, mach_error_string(err));
- } else {
- // the mach_vm_read was successful, so acquire the uniquing table
-
- // need to re-read the table, so deallocate the current memory
- if (cache->uniquing_table.table) mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)(cache->uniquing_table.table), cache->uniquing_table.tableSize);
-
- // the following line gathers the uniquing table structure data, but the actual table memory is invalid since it's a pointer from the
- // remote process. this pointer will be mapped shared in a few lines.
- cache->uniquing_table = *((backtrace_uniquing_table*)local_uniquing_address);
-
- vm_address_t local_table_address = 0ul;
- mach_msg_type_number_t local_table_size = 0;
-
- err = mach_vm_read(descriptors->remote_task, cache->uniquing_table.table_address, cache->uniquing_table.tableSize, &local_table_address, &local_table_size);
- if (err == KERN_SUCCESS) cache->uniquing_table.table = (mach_vm_address_t*)local_table_address;
- else cache->uniquing_table.table = NULL;
-
- mach_vm_deallocate(mach_task_self(), (mach_vm_address_t)local_uniquing_address, (mach_vm_size_t)local_uniquing_size);
- }
- }
-
- // resume
- if (descriptors->remote_task != mach_task_self()) {
- task_resume(descriptors->remote_task);
- }
-
- if (!update_snapshot && delta_indecies == 0) return; // absolutely no updating needed.
-
- FILE *the_index = (descriptors->index_file_stream);
-
- // prepare for the read; target process could be 32 or 64 bit.
-
- stack_logging_index_event32 *target_32_index = NULL;
- stack_logging_index_event64 *target_64_index = NULL;
-
- // perform the update from the file
- uint32_t i;
- if (delta_indecies) {
- char bufferSpace[4096]; // 4 kb
- target_32_index = (stack_logging_index_event32*)bufferSpace;
- target_64_index = (stack_logging_index_event64*)bufferSpace;
- size_t number_slots = (size_t)(4096/read_size);
-
- size_t read_count = 0;
- if (fseeko(the_index, (off_t)(cache->last_index_file_offset), SEEK_SET)) {
- fprintf(stderr, "error while attempting to cache information from remote stack index file. (update_cache_for_file_streams)\n");
- }
- off_t current_index_position = cache->last_index_file_offset;
- do {
- number_slots = (size_t)MIN(delta_indecies - read_this_update, number_slots);
- read_count = fread(bufferSpace, read_size, number_slots, the_index);
- if (descriptors->task_is_64_bit) {
- for (i = 0; i < read_count; i++) {
- insert_node(cache, STACK_LOGGING_DISGUISE(target_64_index[i].address), (uint64_t)current_index_position);
- read_this_update++;
- current_index_position += read_size;
- }
- } else {
- for (i = 0; i < read_count; i++) {
- insert_node(cache, (mach_vm_address_t)STACK_LOGGING_DISGUISE(target_32_index[i].address), (uint64_t)current_index_position);
- read_this_update++;
- current_index_position += read_size;
- }
- }
- } while (read_count);
-
- if (read_this_update < delta_indecies) {
- fprintf(stderr, "insufficient data in remote stack index file; expected more records.\n");
- }
- cache->last_index_file_offset += read_this_update * read_size;
- }
-
- if (update_snapshot) {
- target_32_index = (stack_logging_index_event32*)(cache->snapshot.index_buffer);
- target_64_index = (stack_logging_index_event64*)(cache->snapshot.index_buffer);
-
- uint32_t free_snapshot_scan_index = cache->snapshot.next_free_index_buffer_offset / (uint32_t)read_size;
- off_t current_index_position = cache->snapshot.start_index_offset;
- if (descriptors->task_is_64_bit) {
- for (i = last_snapshot_scan_index; i < free_snapshot_scan_index; i++) {
- insert_node(cache, STACK_LOGGING_DISGUISE(target_64_index[i].address), (uint64_t)(current_index_position + (i * read_size)));
- }
- } else {
- for (i = last_snapshot_scan_index; i < free_snapshot_scan_index; i++) {
- insert_node(cache, (mach_vm_address_t)STACK_LOGGING_DISGUISE(target_32_index[i].address), (uint64_t)(current_index_position + (i * read_size)));
- }
- }
- }
-}
-
-static void
-destroy_cache_for_file_streams(remote_task_file_streams *descriptors)
-{
- if (descriptors->cache->shmem) {
- munmap(descriptors->cache->shmem, sizeof(stack_buffer_shared_memory));
- }
- free(descriptors->cache->table_memory);
- free(descriptors->cache);
- descriptors->cache = NULL;
-}
-
-#pragma mark - internal
-
-// In the stack log analysis process, find the stack logging files for target process <pid>
-// by scanning the temporary directory for directory entries with names of the form "stack-logs.<pid>."
-// If we find such a directory then open the stack logging files in there.
-// We might also have been passed the file path if the client first read it from __stack_log_file_path__
-// global variable in the target task, as will be needed if the .link cannot be put in /tmp.
-static void
-open_log_files(pid_t pid, char* file_path, remote_task_file_streams *this_task_streams)
-{
- DIR *dp;
- struct dirent *entry;
- char prefix_name[PATH_MAX];
- char pathname[PATH_MAX];
-
- reap_orphaned_log_files(false); // reap any left-over log files (for non-existant processes, but not for this analysis process)
-
- if (file_path != NULL) {
- this_task_streams->index_file_stream = fopen(file_path, "r");
- return;
- }
-
- if ((dp = opendir(_PATH_TMP)) == NULL) {
- return;
- }
-
- // It's OK to use snprintf in this routine since it should only be called by the clients
- // of stack logging, and thus calls to malloc are OK.
- snprintf(prefix_name, (size_t)PATH_MAX, "%s%d.", stack_log_file_base_name, pid); // make sure to use "%s%d." rather than just "%s%d" to match the whole pid
- size_t prefix_length = strlen(prefix_name);
-
- while ( (entry = readdir(dp)) != NULL ) {
- if ( strncmp( entry->d_name, prefix_name, prefix_length) == 0 ) {
- snprintf(pathname, (size_t)PATH_MAX, "%s%s", _PATH_TMP, entry->d_name);
- char reference_file[PATH_MAX];
- if (log_file_is_reference(pathname, reference_file, (size_t)PATH_MAX)) {
- this_task_streams->index_file_stream = fopen(reference_file, "r");
- } else {
- this_task_streams->index_file_stream = fopen(pathname, "r");
- }
-
- break;
- }
- }
- closedir(dp);
-}
-
-static remote_task_file_streams*
-retain_file_streams_for_task(task_t task, char* file_path)
-{
- if (task == MACH_PORT_NULL) return NULL;
-
- OSSpinLockLock(&remote_fd_list_lock);
-
- // see if they're already in use
- uint32_t i = 0;
- for (i = 0; i < remote_task_fd_count; i++) {
- if (remote_fds[i].remote_task == task) {
- remote_fds[i].in_use_count++;
- OSSpinLockUnlock(&remote_fd_list_lock);
- return &remote_fds[i];
- }
- }
-
- // open them
- uint32_t failures = 0;
- if (remote_task_fd_count == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) {
- while (remote_fds[next_remote_task_fd].in_use_count > 0) {
- next_remote_task_fd++;
- if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) next_remote_task_fd = 0;
- failures++;
- if (failures >= STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) {
- OSSpinLockUnlock(&remote_fd_list_lock);
- return NULL;
- }
- }
- fclose(remote_fds[next_remote_task_fd].index_file_stream);
- destroy_cache_for_file_streams(&remote_fds[next_remote_task_fd]);
- }
-
- pid_t pid;
- kern_return_t err = pid_for_task(task, &pid);
- if (err != KERN_SUCCESS) {
- OSSpinLockUnlock(&remote_fd_list_lock);
- return NULL;
- }
-
- remote_task_file_streams *this_task_streams = &remote_fds[next_remote_task_fd];
-
- open_log_files(pid, file_path, this_task_streams);
-
- // check if opens failed
- if (this_task_streams->index_file_stream == NULL) {
- if (this_task_streams->index_file_stream) fclose(this_task_streams->index_file_stream);
- OSSpinLockUnlock(&remote_fd_list_lock);
- return NULL;
- }
-
- // check if target pid is running 64-bit
- int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
- struct kinfo_proc processInfo;
- size_t bufsize = sizeof(processInfo);
- if (sysctl(mib, (unsigned)(sizeof(mib)/sizeof(int)), &processInfo, &bufsize, NULL, (size_t)0) == 0 && bufsize > 0) {
- this_task_streams->task_is_64_bit = processInfo.kp_proc.p_flag & P_LP64;
- } else {
- this_task_streams->task_is_64_bit = 0;
- }
-
- // otherwise set vars and go
- this_task_streams->in_use_count = 1;
- this_task_streams->remote_task = task;
- this_task_streams->remote_pid = pid;
- next_remote_task_fd++;
- if (next_remote_task_fd == STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED) next_remote_task_fd = 0;
- remote_task_fd_count = MIN(remote_task_fd_count + 1, STACK_LOGGING_MAX_SIMUL_REMOTE_TASKS_INSPECTED);
-
- OSSpinLockUnlock(&remote_fd_list_lock);
- return this_task_streams;
-}
-
-static void
-release_file_streams_for_task(task_t task)
-{
- OSSpinLockLock(&remote_fd_list_lock);
-
- // decrement in-use count
- uint32_t i = 0;
- for (i = 0; i < remote_task_fd_count; i++) {
- if (remote_fds[i].remote_task == task) {
- remote_fds[i].in_use_count--;
- break;
- }
- }
-
- OSSpinLockUnlock(&remote_fd_list_lock);
-}
-
-#pragma mark - extern
-
-//
-// The following is used by client tools like malloc_history and Instruments to pass along the path
-// of the index file as read from the target task's __stack_log_file_path__ variable (set in this file)
-// Eventually, at a suitable point, this additional argument should just be added to the other APIs below.
-//
-kern_return_t
-__mach_stack_logging_set_file_path(task_t task, char* file_path)
-{
- remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, file_path);
- if (remote_fd == NULL) {
- return KERN_FAILURE;
- }
- return KERN_SUCCESS;
-}
-
-kern_return_t
-__mach_stack_logging_get_frames(task_t task, mach_vm_address_t address, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count)
-{
- remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL);
- if (remote_fd == NULL) {
- return KERN_FAILURE;
- }
-
- update_cache_for_file_streams(remote_fd);
-
- uint32_t collisions = 0;
- size_t hash = hash_index(address, remote_fd->cache->cache_node_capacity);
- size_t multiplier = hash_multiplier(remote_fd->cache->cache_node_capacity, remote_fd->cache->collision_allowance);
- uint64_t located_file_position = 0;
-
- bool found = false;
- do {
- if (remote_fd->cache->table_memory[hash].address == address) { // hit!
- located_file_position = remote_fd->cache->table_memory[hash].index_file_offset;
- found = true;
- break;
- } else if (remote_fd->cache->table_memory[hash].address == 0ull) { // failure!
- break;
- }
-
- collisions++;
- hash = next_hash(hash, multiplier, remote_fd->cache->cache_node_capacity, collisions);
-
- } while (collisions <= remote_fd->cache->collision_allowance);
-
- if (found) {
- // prepare for the read; target process could be 32 or 64 bit.
- stack_logging_index_event32 *target_32_index = NULL;
- stack_logging_index_event64 *target_64_index = NULL;
-
- if (located_file_position >= remote_fd->cache->last_index_file_offset) {
- // must be in shared memory
- if (remote_fd->cache->shmem) {
- if (remote_fd->task_is_64_bit) {
- target_64_index = (stack_logging_index_event64*)(remote_fd->cache->snapshot.index_buffer + (located_file_position - remote_fd->cache->snapshot.start_index_offset));
- located_file_position = STACK_LOGGING_OFFSET(target_64_index->offset_and_flags);
- } else {
- target_32_index = (stack_logging_index_event32*)(remote_fd->cache->snapshot.index_buffer + (located_file_position - remote_fd->cache->snapshot.start_index_offset));
- located_file_position = STACK_LOGGING_OFFSET(target_32_index->offset_and_flags);
- }
- } else {
- found = false;
- }
-
- } else {
- // it's written to disk
- char bufferSpace[128];
-
- size_t read_size = (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32));
- fseeko(remote_fd->index_file_stream, (off_t)located_file_position, SEEK_SET);
- size_t read_count = fread(bufferSpace, read_size, (size_t)1, remote_fd->index_file_stream);
- if (read_count) {
- if (remote_fd->task_is_64_bit) {
- target_64_index = (stack_logging_index_event64*)bufferSpace;
- located_file_position = STACK_LOGGING_OFFSET(target_64_index->offset_and_flags);
- } else {
- target_32_index = (stack_logging_index_event32*)bufferSpace;
- located_file_position = STACK_LOGGING_OFFSET(target_32_index->offset_and_flags);
- }
- } else {
- found = false;
- }
- }
- }
-
- release_file_streams_for_task(task);
-
- if (!found) {
- return KERN_FAILURE;
- }
-
- return __mach_stack_logging_frames_for_uniqued_stack(task, located_file_position, stack_frames_buffer, max_stack_frames, count);
-}
-
-
-kern_return_t
-__mach_stack_logging_enumerate_records(task_t task, mach_vm_address_t address, void enumerator(mach_stack_logging_record_t, void *), void *context)
-{
- remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL);
- if (remote_fd == NULL) {
- return KERN_FAILURE;
- }
-
- bool reading_all_addresses = (address == 0 ? true : false);
- mach_stack_logging_record_t pass_record;
- kern_return_t err = KERN_SUCCESS;
-
- // update (read index file once and only once)
- update_cache_for_file_streams(remote_fd);
-
- FILE *the_index = (remote_fd->index_file_stream);
-
- // prepare for the read; target process could be 32 or 64 bit.
- char bufferSpace[2048]; // 2 kb
- stack_logging_index_event32 *target_32_index = (stack_logging_index_event32*)bufferSpace;
- stack_logging_index_event64 *target_64_index = (stack_logging_index_event64*)bufferSpace;
- uint32_t target_addr_32 = (uint32_t)STACK_LOGGING_DISGUISE((uint32_t)address);
- uint64_t target_addr_64 = STACK_LOGGING_DISGUISE((uint64_t)address);
- size_t read_size = (remote_fd->task_is_64_bit ? sizeof(stack_logging_index_event64) : sizeof(stack_logging_index_event32));
- size_t number_slots = (size_t)(2048/read_size);
- uint64_t total_slots = remote_fd->cache->last_index_file_offset / read_size;
-
- // perform the search
- size_t read_count = 0;
- int64_t current_file_offset = 0;
- uint32_t i;
- do {
- // at this point, we need to read index events; read them from the file until it's necessary to grab them from the shared memory snapshot
- // and crop file reading to the point where we last scanned
- number_slots = (size_t)MIN(number_slots, total_slots);
-
- // if out of file to read (as of the time we entered this function), try to use shared memory snapshot
- if (number_slots == 0) {
- if (remote_fd->cache->shmem && remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset > (uint64_t)current_file_offset) {
- // use shared memory
- target_32_index = (stack_logging_index_event32*)remote_fd->cache->snapshot.index_buffer;
- target_64_index = (stack_logging_index_event64*)remote_fd->cache->snapshot.index_buffer;
- read_count = (uint32_t)(remote_fd->cache->snapshot.start_index_offset + remote_fd->cache->snapshot.next_free_index_buffer_offset - current_file_offset) / read_size;
- current_file_offset += read_count * read_size;
- } else {
- break;
- }
- } else {
- // get and save index (enumerator could modify)
- fseeko(the_index, current_file_offset, SEEK_SET);
- read_count = fread(bufferSpace, read_size, number_slots, the_index);
- current_file_offset = ftello(the_index);
- total_slots -= read_count;
- }
-
- if (remote_fd->task_is_64_bit) {
- for (i = 0; i < read_count; i++) {
- if (reading_all_addresses || target_64_index[i].address == target_addr_64) {
- pass_record.address = STACK_LOGGING_DISGUISE(target_64_index[i].address);
- pass_record.argument = target_64_index[i].argument;
- pass_record.stack_identifier = STACK_LOGGING_OFFSET(target_64_index[i].offset_and_flags);
- pass_record.type_flags = STACK_LOGGING_FLAGS(target_64_index[i].offset_and_flags);
- enumerator(pass_record, context);
- }
- }
- } else {
- for (i = 0; i < read_count; i++) {
- if (reading_all_addresses || target_32_index[i].address == target_addr_32) {
- pass_record.address = STACK_LOGGING_DISGUISE(target_32_index[i].address);
- pass_record.argument = target_32_index[i].argument;
- pass_record.stack_identifier = STACK_LOGGING_OFFSET(target_32_index[i].offset_and_flags);
- pass_record.type_flags = STACK_LOGGING_FLAGS(target_32_index[i].offset_and_flags);
- enumerator(pass_record, context);
- }
- }
- }
- } while (read_count);
-
- release_file_streams_for_task(task);
- return err;
-}
-
-
-kern_return_t
-__mach_stack_logging_frames_for_uniqued_stack(task_t task, uint64_t stack_identifier, mach_vm_address_t *stack_frames_buffer, uint32_t max_stack_frames, uint32_t *count)
-{
- remote_task_file_streams *remote_fd = retain_file_streams_for_task(task, NULL);
- if (remote_fd == NULL) return KERN_FAILURE;
-
- __unwind_stack_from_table_index(&remote_fd->cache->uniquing_table, stack_identifier, stack_frames_buffer, count, max_stack_frames);
-
- release_file_streams_for_task(task);
-
- if (*count) return KERN_SUCCESS;
- else return KERN_FAILURE;
-}
-
-
-#ifdef TEST_DISK_STACK_LOGGING
-
-// cc -o stack_logging_disk stack_logging_disk.c -DTEST_DISK_STACK_LOGGING
-
-#include <sys/wait.h>
-
-int
-main()
-{
- int status;
- int i;
- size_t total_globals = 0ul;
-
- fprintf(stderr, "master test process is %d\n", getpid());
- fprintf(stderr, "sizeof pre_write_buffers: %lu\n", sizeof(pre_write_buffers)); total_globals += sizeof(pre_write_buffers);
- fprintf(stderr, "sizeof stack_buffer: %lu\n", sizeof(stack_buffer)); total_globals += sizeof(stack_buffer);
- fprintf(stderr, "sizeof last_logged_malloc_address: %lu\n", sizeof(last_logged_malloc_address)); total_globals += sizeof(last_logged_malloc_address);
- fprintf(stderr, "sizeof stack_log_file_base_name: %lu\n", sizeof(stack_log_file_base_name)); total_globals += sizeof(stack_log_file_base_name);
- fprintf(stderr, "sizeof stack_log_file_suffix: %lu\n", sizeof(stack_log_file_suffix)); total_globals += sizeof(stack_log_file_suffix);
- fprintf(stderr, "sizeof stack_log_link_suffix: %lu\n", sizeof(stack_log_link_suffix)); total_globals += sizeof(stack_log_link_suffix);
- fprintf(stderr, "sizeof stack_log_location: %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX;
- fprintf(stderr, "sizeof stack_log_reference_file: %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX;
- fprintf(stderr, "sizeof __stack_log_file_path__ (index_file_path): %lu\n", (size_t)PATH_MAX); total_globals += (size_t)PATH_MAX;
- fprintf(stderr, "sizeof index_file_descriptor: %lu\n", sizeof(index_file_descriptor)); total_globals += sizeof(index_file_descriptor);
- fprintf(stderr, "sizeof remote_fds: %lu\n", sizeof(remote_fds)); total_globals += sizeof(remote_fds);
- fprintf(stderr, "sizeof next_remote_task_fd: %lu\n", sizeof(next_remote_task_fd)); total_globals += sizeof(next_remote_task_fd);
- fprintf(stderr, "sizeof remote_task_fd_count: %lu\n", sizeof(remote_task_fd_count)); total_globals += sizeof(remote_task_fd_count);
- fprintf(stderr, "sizeof remote_fd_list_lock: %lu\n", sizeof(remote_fd_list_lock)); total_globals += sizeof(remote_fd_list_lock);
- fprintf(stderr, "sizeof logging_use_compaction: %lu\n", sizeof(logging_use_compaction)); total_globals += sizeof(logging_use_compaction);
-
- fprintf(stderr, "size of all global data: %lu\n", total_globals);
-
- create_log_file();
-
- // create a few child processes and exit them cleanly so their logs should get cleaned up
- fprintf(stderr, "\ncreating child processes and exiting cleanly\n");
- for (i = 0; i < 3; i++) {
- if (fork() == 0) {
- fprintf(stderr, "\nin child processes %d\n", getpid());
- create_log_file();
- fprintf(stderr, "exiting child processes %d\n", getpid());
- exit(1);
- }
- wait(&status);
- }
-
- // create a few child processes and abruptly _exit them, leaving their logs around
- fprintf(stderr, "\ncreating child processes and exiting abruptly, leaving logs around\n");
- for (i = 0; i < 3; i++) {
- if (fork() == 0) {
- fprintf(stderr, "\nin child processes %d\n", getpid());
- create_log_file();
- fprintf(stderr, "exiting child processes %d\n", getpid());
- _exit(1);
- }
- wait(&status);
- }
-
- // this should reap any remaining logs
- fprintf(stderr, "\nexiting master test process %d\n", getpid());
- delete_log_files();
- return 0;
-}
-
-#endif
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
static struct {
char *name;
+++ /dev/null
-.\" Copyright (c) 1985, 1991, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by the University of
-.\" California, Berkeley and its contributors.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)syslog.3 8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/gen/syslog.3,v 1.22 2001/10/01 16:08:51 ru Exp $
-.\"
-.Dd June 4, 1993
-.Dt SYSLOG 3
-.Os
-.Sh NAME
-.Nm closelog ,
-.Nm openlog ,
-.Nm setlogmask ,
-.Nm syslog ,
-.Nm vsyslog
-.Nd control system log
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In syslog.h
-.Ft void
-.Fo closelog
-.Fa void
-.Fc
-.Ft void
-.Fo openlog
-.Fa "const char *ident"
-.Fa "int logopt"
-.Fa "int facility"
-.Fc
-.Ft int
-.Fo setlogmask
-.Fa "int maskpri"
-.Fc
-.Ft void
-.Fo syslog
-.Fa "int priority"
-.Fa "const char *message"
-.Fa "..."
-.Fc
-.In syslog.h
-.In stdarg.h
-.Ft void
-.Fo vsyslog
-.Fa "int priority"
-.Fa "const char *message"
-.Fa "va_list args"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn syslog
-function
-writes
-.Fa message
-to the system message logger.
-The message is then written to the system console, log files,
-logged-in users, or forwarded to other machines as appropriate.
-(See
-.Xr syslogd 8 . )
-.Pp
-The message is identical to a
-.Xr printf 3
-format string, except that
-.Ql %m
-is replaced by the current error
-message.
-(As denoted by the global variable
-.Va errno ;
-see
-.Xr strerror 3 . )
-A trailing newline is added if none is present.
-.Pp
-Newlines and other non-printable characters embedded in the message string are printed in an alternate format.
-This prevents someone from using non-printable characters to construct misleading log messages in an output file.
-Newlines are printed as "\\n",
-tabs are printed as "\\t".
-Other control characters are printed using a caret ("^") representation, for example "^M" for carriage return.
-.Pp
-The
-.Fn vsyslog
-function
-is an alternate form in which the arguments have already been captured
-using the variable-length argument facilities of
-.Xr stdarg 3 .
-.Pp
-The message is tagged with
-.Fa priority .
-Priorities are encoded as a
-.Fa facility
-and a
-.Em level .
-The facility describes the part of the system
-generating the message.
-The level is selected from the following
-.Em ordered
-(high to low) list:
-.Bl -tag -width LOG_AUTHPRIV
-.It Dv LOG_EMERG
-A panic condition.
-This is normally broadcast to all users.
-.It Dv LOG_ALERT
-A condition that should be corrected immediately, such as a corrupted
-system database.
-.It Dv LOG_CRIT
-Critical conditions, e.g., hard device errors.
-.It Dv LOG_ERR
-Errors.
-.It Dv LOG_WARNING
-Warning messages.
-.It Dv LOG_NOTICE
-Conditions that are not error conditions,
-but should possibly be handled specially.
-.It Dv LOG_INFO
-Informational messages.
-.It Dv LOG_DEBUG
-Messages that contain information
-normally of use only when debugging a program.
-.El
-.Pp
-The
-.Fn openlog
-function
-provides for more specialized processing of the messages sent
-by
-.Fn syslog
-and
-.Fn vsyslog .
-The parameter
-.Fa ident
-is a string that will be prepended to every message.
-The
-.Fa logopt
-argument
-is a bit field specifying logging options, which is formed by
-.Tn OR Ns 'ing
-one or more of the following values:
-.Bl -tag -width LOG_AUTHPRIV
-.It Dv LOG_CONS
-If
-.Fn syslog
-cannot pass the message to
-.Xr syslogd 8
-it will attempt to write the message to the console
-.Pq Dq Pa /dev/console .
-.It Dv LOG_NDELAY
-Open the connection to
-.Xr syslogd 8
-immediately.
-Normally the open is delayed until the first message is logged.
-Useful for programs that need to manage the order in which file
-descriptors are allocated.
-.It Dv LOG_PERROR
-Write the message to standard error output as well to the system log.
-.It Dv LOG_PID
-Log the process id with each message: useful for identifying
-instantiations of daemons.
-.El
-.Pp
-The
-.Fa facility
-parameter encodes a default facility to be assigned to all messages
-that do not have an explicit facility encoded:
-.Bl -tag -width LOG_AUTHPRIV
-.It Dv LOG_AUTH
-The authorization system:
-.Xr login 1 ,
-.Xr su 1 ,
-.Xr getty 8 ,
-etc.
-.It Dv LOG_AUTHPRIV
-The same as
-.Dv LOG_AUTH ,
-but logged to a file readable only by
-selected individuals.
-.It Dv LOG_CRON
-The cron daemon:
-.Xr cron 8 .
-.It Dv LOG_DAEMON
-System daemons, such as
-.Xr routed 8 ,
-that are not provided for explicitly by other facilities.
-.It Dv LOG_FTP
-The file transfer protocol daemons:
-.Xr ftpd 8 ,
-.Xr tftpd 8 .
-.It Dv LOG_KERN
-Messages generated by the kernel.
-These cannot be generated by any user processes.
-.It Dv LOG_LPR
-The line printer spooling system:
-.Xr cups-lpd 8 ,
-.Xr cupsd 8 ,
-etc.
-.It Dv LOG_MAIL
-The mail system.
-.It Dv LOG_NEWS
-The network news system.
-.It Dv LOG_SECURITY
-Security subsystems, such as
-.Xr ipfw 4 .
-.It Dv LOG_SYSLOG
-Messages generated internally by
-.Xr syslogd 8 .
-.It Dv LOG_USER
-Messages generated by random user processes.
-This is the default facility identifier if none is specified.
-.It Dv LOG_UUCP
-The uucp system.
-.It Dv LOG_LOCAL0
-Reserved for local use.
-Similarly for
-.Dv LOG_LOCAL1
-through
-.Dv LOG_LOCAL7 .
-.El
-.Pp
-The
-.Fn closelog
-function
-can be used to close the log file.
-.Pp
-The
-.Fn setlogmask
-function
-sets the log priority mask to
-.Fa maskpri
-and returns the previous mask.
-Calls to
-.Fn syslog
-with a priority not set in
-.Fa maskpri
-are rejected.
-The mask for an individual priority
-.Fa pri
-is calculated by the macro
-.Fn LOG_MASK pri ;
-the mask for all priorities up to and including
-.Fa toppri
-is given by the macro
-.Fn LOG_UPTO toppri ; .
-The default allows all priorities to be logged.
-.Sh RETURN VALUES
-The routines
-.Fn closelog ,
-.Fn openlog ,
-.Fn syslog ,
-and
-.Fn vsyslog
-return no value.
-.Pp
-The routine
-.Fn setlogmask
-always returns the previous log mask level.
-.Sh EXAMPLES
-.Bd -literal -offset indent -compact
-syslog(LOG_ALERT, "who: internal error 23");
-
-openlog("ftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
-
-setlogmask(LOG_UPTO(LOG_ERR));
-
-syslog(LOG_INFO, "Connection from host %d", CallingHost);
-
-syslog(LOG_INFO|LOG_LOCAL2, "foobar error: %m");
-.Ed
-.Sh LEGACY SYNOPSIS
-.Fd #include <syslog.h>
-.Fd #include <stdarg.h>
-.Pp
-These include files are necessary for all functions.
-.Sh SEE ALSO
-.Xr asl 3 ,
-.Xr logger 1 ,
-.Xr compat 5 ,
-.Xr syslogd 8
-.Sh HISTORY
-These
-functions appeared in
-.Bx 4.2 .
-.Sh BUGS
-Never pass a string with user-supplied data as a format without using
-.Ql %s .
-An attacker can put format specifiers in the string to mangle your stack,
-leading to a possible security hole.
-This holds true even if the string was built using a function like
-.Fn snprintf ,
-as the resulting string may still contain user-supplied conversion specifiers
-for later interpolation by
-.Fn syslog .
-.Pp
-Always use the proper secure idiom:
-.Pp
-.Bd -literal -offset indent -compact
-syslog(LOG_ERR, "%s", string);
-.Ed
+++ /dev/null
-/*
- * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Copyright (c) 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/syslog.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <pthread.h>
-#include <asl.h>
-#include "asl_private.h"
-
-#ifdef __STDC__
-#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
-
-#define LOG_NO_NOTIFY 0x1000
-extern const char *asl_syslog_faciliy_num_to_name(int n);
-
-#ifdef BUILDING_VARIANT
-__private_extern__ pthread_mutex_t _sl_lock;
-__private_extern__ aslclient _sl_asl;
-__private_extern__ char *_sl_ident;
-__private_extern__ int _sl_fac;
-__private_extern__ int _sl_opts;
-__private_extern__ int _sl_mask;
-#else /* !BUILDING_VARIANT */
-__private_extern__ pthread_mutex_t _sl_lock = PTHREAD_MUTEX_INITIALIZER;
-__private_extern__ aslclient _sl_asl = NULL;
-__private_extern__ char *_sl_ident = NULL;
-__private_extern__ int _sl_fac = 0;
-__private_extern__ int _sl_opts = 0;
-__private_extern__ int _sl_mask = 0;
-#endif /* BUILDING_VARIANT */
-
-/*
- * syslog, vsyslog --
- * print message on log file; output is intended for syslogd(8).
- */
-void
-#ifdef __STDC__
-syslog(int pri, const char *fmt, ...)
-#else
-syslog(pri, fmt, va_alist)
- int pri;
- char *fmt;
- va_dcl
-#endif
-{
- va_list ap;
-
-#ifdef __STDC__
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- vsyslog(pri, fmt, ap);
- va_end(ap);
-}
-
-void
-vsyslog(int pri, const char *fmt, va_list ap)
-{
- int fac;
- aslmsg facmsg;
- const char *facility;
-
- facmsg = NULL;
- fac = pri & LOG_FACMASK;
- if (fac != 0)
- {
- facility = asl_syslog_faciliy_num_to_name(fac);
- if (facility != NULL)
- {
- facmsg = asl_new(ASL_TYPE_MSG);
- asl_set(facmsg, ASL_KEY_FACILITY, facility);
- }
- }
-
- asl_vlog(_sl_asl, facmsg, LOG_PRI(pri), fmt, ap);
- if (facmsg != NULL) asl_free(facmsg);
-}
-
-#ifndef BUILDING_VARIANT
-
-void
-openlog(const char *ident, int opts, int logfac)
-{
- const char *facility;
- uint32_t asl_opts;
-
- pthread_mutex_lock(&_sl_lock);
-
- /* close existing aslclient */
- if (_sl_asl != NULL) asl_close(_sl_asl);
- _sl_asl = NULL;
-
- if (_sl_ident != NULL) free(_sl_ident);
- _sl_ident = NULL;
-
- /* open with specified parameters */
-
- if (ident != NULL) _sl_ident = strdup(ident);
- /* NB we allow the strdup to fail silently */
-
- _sl_fac = logfac;
- facility = asl_syslog_faciliy_num_to_name(_sl_fac);
-
- _sl_opts = opts;
- asl_opts = ASL_OPT_SYSLOG_LEGACY;
-
- if (_sl_opts & LOG_NO_NOTIFY) asl_opts |= ASL_OPT_NO_REMOTE;
- if (_sl_opts & LOG_PERROR) asl_opts |= ASL_OPT_STDERR;
-
- _sl_mask = ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG);
-
- _sl_asl = asl_open(_sl_ident, facility, asl_opts);
- asl_set_filter(_sl_asl, _sl_mask);
-
- pthread_mutex_unlock(&_sl_lock);
-}
-
-void
-closelog()
-{
- pthread_mutex_lock(&_sl_lock);
-
- if (_sl_asl != NULL) asl_close(_sl_asl);
- _sl_asl = NULL;
-
- if (_sl_ident != NULL) free(_sl_ident);
- _sl_ident = NULL;
-
- pthread_mutex_unlock(&_sl_lock);
-}
-
-/* setlogmask -- set the log mask level */
-int
-setlogmask(int mask)
-{
- int oldmask;
-
- pthread_mutex_lock(&_sl_lock);
-
- _sl_mask = mask;
- oldmask = asl_set_filter(_sl_asl, mask);
-
- pthread_mutex_unlock(&_sl_lock);
-
- return oldmask;
-}
-
-#endif /* !BUILDING_VARIANT */
#include <mach/mach.h>
#include <mach/vm_statistics.h>
#include <stdlib.h>
+#include "stack_logging.h"
#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
#define FP_LINK_OFFSET 1
.Em rule
from the rest of the specification.
.Sh FILES
-.Bl -tag -width /usr/share/zoneinfo/posixrules -compact
+#ifdef UNIFDEF_TZDIR_SYMLINK
+.ds zi /var/db/timezone/zoneinfo
+#else /* !UNIFDEF_TZDIR_SYMLINK */
+.ds zi /usr/share/zoneinfo
+#endif /* UNIFDEF_TZDIR_SYMLINK */
+.Bl -tag -width \*(zi/posixrules -compact
.It Pa /etc/localtime
local time zone file
-.It Pa /usr/share/zoneinfo
+.It Pa \*(zi
time zone directory
-.It Pa /usr/share/zoneinfo/posixrules
+.It Pa \*(zi/posixrules
rules for
.Tn POSIX Ns -style
.Tn TZ Ns 's
-.It Pa /usr/share/zoneinfo/GMT
+.It Pa \*(zi/GMT
for
.Tn UTC
leap seconds
.El
.Pp
If the file
-.Pa /usr/share/zoneinfo/GMT
+.Pa \*(zi/GMT
does not exist,
.Tn UTC
leap seconds are loaded from
-.Pa /usr/share/zoneinfo/posixrules .
+.Pa \*(zi/posixrules .
.Sh SEE ALSO
.Xr date 1 ,
.Xr gettimeofday 2 ,
rval = -1;
else
for (p = name->version; len--; ++p)
- if (*p == '\n' || *p == '\t')
- if (len > 1)
+ if (*p == '\n' || *p == '\t') {
+ if (len > 1) {
*p = ' ';
- else
+ } else {
*p = '\0';
-
+ }
+ }
mib[0] = CTL_HW;
mib[1] = HW_MACHINE;
len = sizeof(name->machine);
#include <mach/mach_types.h>
#include <servers/bootstrap.h>
#include <pthread.h>
-#include <asl_ipc.h>
#ifdef UTMP_COMPAT
#include <ttyent.h>
static void msg2utmpx(const aslmsg, struct utmpx *);
static void utmpx2msg(const struct utmpx *, aslmsg);
-static int pw_size = 0;
+static size_t pw_size = 0;
#define FACILITY "Facility"
#define WTMP_COUNT 32
#define LASTLOG_FACILITY "com.apple.system.lastlog"
#define UTMPX_FACILITY "com.apple.system.utmpx"
-#define UTMPX_LOCK(x) if (__is_threaded) pthread_mutex_lock(&(x)->utmpx_mutex)
-#define UTMPX_UNLOCK(x) if (__is_threaded) pthread_mutex_unlock(&(x)->utmpx_mutex)
+#define UTMPX_LOCK(x) pthread_mutex_lock(&(x)->utmpx_mutex)
+#define UTMPX_UNLOCK(x) pthread_mutex_unlock(&(x)->utmpx_mutex)
#define UTMPX_MAGIC 8
#define __UTX_MAGIC__ { 'u', 't', 'x', 0, 'v', 1, 0, 0 }
LIBC_ABORT("%s: magic mismatch", (x)); \
}
-extern int __is_threaded;
-
struct _utmpx {
char magic[UTMPX_MAGIC];
struct utmpx ut;
unsigned int utfile_system :1; /* are we using _PATH_UTMPX? */
unsigned int readonly :1;
};
-extern struct _utmpx __utx__; /* the default struct _utmpx */
extern const char __utx_magic__[]; /* size of UTMPX_MAGIC */
#ifdef __LP64__
};
#endif /* __LP64__ */
+struct _utmpx *__default_utx(void);
+
void __endutxent(struct _utmpx *);
struct utmpx *__getutxent(struct _utmpx *);
void __setutxent(struct _utmpx *);
* @APPLE_LICENSE_HEADER_END@
*/
+#include <TargetConditionals.h>
+
+#if TARGET_OS_IPHONE
+/* <rdar://problem/13875458> */
+
+#include <wordexp.h>
+int wordexp(const char *restrict words __unused, wordexp_t *restrict pwordexp __unused, int flags __unused) {
+ return WRDE_NOSPACE;
+}
+
+void wordfree(wordexp_t *pwordexp __unused) {
+}
+
+#else
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <crt_externs.h>
extern size_t malloc_good_size(size_t size);
-extern int errno;
-pthread_once_t re_init_c = PTHREAD_ONCE_INIT;
+static pthread_once_t re_init_c = PTHREAD_ONCE_INIT;
static regex_t re_cmd, re_goodchars, re_subcmd_syntax_err_kludge, re_quoted_string;
/* Similar to popen, but captures stderr for you. Doesn't interoperate
}
char *word = NULL;
- int word_l = 0;
- int word_i = 0;
+ size_t word_l = 0;
+ size_t word_i = 0;
int ch;
while(EOF != (ch = fgetc(out))) {
char err_buf[1024];
size_t err_sz = fread(err_buf, 1, sizeof(err_buf) -1, err);
- err_buf[(err_sz >= 0) ? err_sz : 0] = '\0';
+ err_buf[err_sz] = '\0';
if (flags & WRDE_SHOWERR) {
fputs(err_buf, stderr);
}
pid_t got_pid = 0;
int status;
do {
- pid = wait4(pid, &status, 0, NULL);
+ got_pid = wait4(pid, &status, 0, NULL);
} while(got_pid == -1 && errno == EINTR);
fclose(out);
free(pwe->we_wordv);
pwe->we_wordv = NULL;
}
+
+#endif /* TARGET_OS_IPHONE */
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(__i386__)
-
-#include <architecture/i386/asm_help.h>
-
-/*
- * _ctx_start((void *func)(int arg1, ..., argn),
- * int arg1, ..., argn, ucontext_t *ucp)
- *
- * 0(%esp) - func
- * 4(%esp) - arg1
- * 8(%esp) - arg2
- * ...
- * (4*n)(%esp) - argn
- * (4*(n + 1))(%esp) - ucp, %ebp setup to point here (base of stack)
- */
-TEXT
-LABEL(__ctx_start)
- popl %eax /* get start function */
- call *%eax /* call start function */
- movl %esi, %esp /*
- * setup stack for completion routine;
- * ucp is now at top of stack
- */
- CALL_EXTERN(__ctx_done) /* should never return */
- int $5 /* trap */
-
-#endif /* __i386__ */
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#if defined(__i386__)
-
-#include <architecture/i386/asm_help.h>
-
-TEXT
-LABEL(__setcontext)
- subl $28, %esp
- movl 32(%esp), %eax
- movl 4(%eax), %eax
- movl %eax, (%esp) /* load up signal mask */
- CALL_EXTERN(_sigsetmask) /* set signal mask */
- addl $28, %esp
- movl 4(%esp), %ecx
- movl 28(%ecx), %ecx
- movl 16(%ecx), %ebx
- movl 28(%ecx), %edi
- movl 32(%ecx), %esi
- movl 36(%ecx), %ebp
- movl 40(%ecx), %esp
- pushl 48(%ecx)
- popfl
- movl 12(%ecx), %eax
- jmp *52(%ecx)
-
-#endif /* __i386__ */
+++ /dev/null
-/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <sys/appleapiopts.h>
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-/*
- * These platfunc routines provide fast access to the logical cpu number
- * of the calling processor assuming no pre-emption occurs. This number
- * is encoded in the bottom 12-bits of the limit field of the IDTR (the
- * Interrupt Descriptor Table Register). The SIDT instruction is used in
- * userspace to read this register and thus to gain access to the cpu number.
- * The IDTR is loaded by the kernel for each processor at startup - see
- * osfmk/i386/mp_desc.c.
- */
-
-/* return logical cpu number in %eax */
-
- .align 4
- .private_extern _cpu_number
-_cpu_number:
- push %ebp
- mov %esp,%ebp
- sub $8, %esp // space to read IDTR
-
- sidt (%esp) // store limit:base on stack
- movw (%esp), %ax // get limit
- and $0xfff, %eax // mask off lower 12 bits to return
-
- mov %ebp,%esp
- pop %ebp
- ret
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#if defined(__i386__)
-
-#include <architecture/i386/asm_help.h>
-
-TEXT
-LABEL(_getcontext)
- subl $28, %esp
- movl 32(%esp), %eax
- movl %eax, (%esp)
- movl %esp, 4(%esp)
- CALL_EXTERN(_getmcontext)
- movl %eax, %ecx
- addl $28, %esp
- movl %ebx, 16(%ecx)
- movl %edi, 28(%ecx)
- movl %esi, 32(%ecx)
- movl %ebp, 36(%ecx)
- movl (%esp), %eax
- movl %eax, 52(%ecx)
- movl %esp, %eax
- addl $4, %eax
- movl %eax, 40(%ecx)
- pushf
- popl %eax
- movl %eax, 48(%ecx)
- xorl %eax, %eax
- movl %eax, 12(%ecx)
- ret
-
-#endif /* __i386__ */
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#if defined(__i386__)
-
-#define _XOPEN_SOURCE 600L
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <signal.h>
-#include <ucontext.h>
-
-extern size_t pthread_get_stacksize_np(pthread_t);
-extern void *pthread_get_stackaddr_np(pthread_t);
-#ifdef __DYNAMIC__
-extern int __in_sigtramp;
-#endif /* __DYNAMIC_ */
-
-__private_extern__ mcontext_t
-getmcontext(ucontext_t *uctx, void *sp)
-{
- pthread_t self = pthread_self();
- mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data;
- size_t stacksize = pthread_get_stacksize_np(self);
- stack_t stack;
-
- uctx->uc_stack.ss_sp = sp;
- uctx->uc_stack.ss_flags = 0;
-
- if (0 == sigaltstack(NULL, &stack)) {
- if (stack.ss_flags & SS_ONSTACK) {
- uctx->uc_stack = stack;
- stacksize = stack.ss_size;
- }
- }
-
- if (stacksize == 0) { /* main thread doesn't have pthread stack size */
- struct rlimit rlim;
- if (0 == getrlimit(RLIMIT_STACK, &rlim))
- stacksize = rlim.rlim_cur;
- }
-
- uctx->uc_stack.ss_size = stacksize;
-
- if (uctx->uc_mcontext != mctx) {
- uctx->uc_mcontext = mctx;
-
-#ifdef __DYNAMIC__
- uctx->uc_link = (ucontext_t*)__in_sigtramp; /* non-zero if in signal handler */
-#else /* !__DYNAMIC__ */
- uctx->uc_link = 0;
-#endif /* __DYNAMIC__ */
-
- }
-
- sigprocmask(0, NULL, &uctx->uc_sigmask);
- return mctx;
-}
-
-#endif /* __i386__ */
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
- #include <machine/cpu_capabilities.h>
-
-
- .text
- .align 4, 0x00
-
-/* void sys_icache_invalidate(addr_t start, int length) */
-
- .globl _sys_icache_invalidate
-_sys_icache_invalidate:
- // This is a NOP on intel processors, since the intent of the API
- // is to make data executable, and Intel L1Is are coherent with L1D.
- ret
-
-
-/* void sys_dcache_flush(addr_t start, int length) */
-
- .globl _sys_dcache_flush
-_sys_dcache_flush:
- movl 8(%esp),%ecx // get length
- movl 4(%esp),%edx // get ptr
- testl %ecx,%ecx // length 0?
- jz 2f // yes
- mfence // ensure previous stores make it to memory
- clflush -1(%edx,%ecx) // make sure last line is flushed
-1:
- clflush (%edx) // flush a line
- addl $64,%edx
- subl $64,%ecx
- ja 1b
- mfence // make sure memory is updated before we return
-2:
- ret
+++ /dev/null
-/*
- * Copyright (c) 2007, 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Copyright (c) 2001 Daniel M. Eischen <deischen@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(__i386__)
-
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/signal.h>
-#include <sys/ucontext.h>
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ucontext.h>
-#include <unistd.h>
-
-/* Prototypes */
-extern void _ctx_start(ucontext_t *, int argc, ...);
-
-void
-_ctx_done (ucontext_t *ucp)
-{
- if (ucp->uc_link == NULL)
- exit(0);
- else {
- /*
- * Since this context has finished, don't allow it
- * to be restarted without being reinitialized (via
- * setcontext or swapcontext).
- */
- ucp->uc_mcsize = 0;
-
- /* Set context to next one in link */
- /* XXX - what to do for error, abort? */
- setcontext((const ucontext_t *)ucp->uc_link);
- LIBC_ABORT("setcontext failed"); /* should never get here */
- }
-}
-
-void
-makecontext(ucontext_t *ucp, void (*start)(), int argc, ...)
-{
- va_list ap;
- char *stack_top;
- intptr_t *argp;
- int i;
-
- if (ucp == NULL)
- return;
- else if ((ucp->uc_stack.ss_sp == NULL) ||
- (ucp->uc_stack.ss_size < MINSIGSTKSZ)) {
- /*
- * This should really return -1 with errno set to ENOMEM
- * or something, but the spec says that makecontext is
- * a void function. At least make sure that the context
- * isn't valid so it can't be used without an error.
- */
- ucp->uc_mcsize = 0;
- }
- /* XXX - Do we want to sanity check argc? */
- else if ((argc < 0) || (argc > NCARGS)) {
- ucp->uc_mcsize = 0;
- }
- /* Make sure the context is valid. */
- else {
- /*
- * Arrange the stack as follows:
- *
- * _ctx_start() - context start wrapper
- * start() - user start routine
- * arg1 - first argument, aligned(16)
- * ...
- * argn
- * ucp - this context, %ebp points here
- *
- * When the context is started, control will return to
- * the context start wrapper which will pop the user
- * start routine from the top of the stack. After that,
- * the top of the stack will be setup with all arguments
- * necessary for calling the start routine. When the
- * start routine returns, the context wrapper then sets
- * the stack pointer to %ebp which was setup to point to
- * the base of the stack (and where ucp is stored). It
- * will then call _ctx_done() to swap in the next context
- * (uc_link != 0) or exit the program (uc_link == 0).
- */
- mcontext_t mc;
-
- stack_top = (char *)(ucp->uc_stack.ss_sp +
- ucp->uc_stack.ss_size - sizeof(intptr_t));
-
- /*
- * Adjust top of stack to allow for 3 pointers (return
- * address, _ctx_start, and ucp) and argc arguments.
- * We allow the arguments to be pointers also. The first
- * argument to the user function must be properly aligned.
- */
- stack_top = stack_top - (sizeof(intptr_t) * (1 + argc));
- stack_top = (char *)((unsigned)stack_top & ~15);
- stack_top = stack_top - (2 * sizeof(intptr_t));
- argp = (intptr_t *)stack_top;
-
- /*
- * Setup the top of the stack with the user start routine
- * followed by all of its aguments and the pointer to the
- * ucontext. We need to leave a spare spot at the top of
- * the stack because setcontext will move eip to the top
- * of the stack before returning.
- */
- *argp = (intptr_t)_ctx_start; /* overwritten with same value */
- argp++;
- *argp = (intptr_t)start;
- argp++;
-
- /* Add all the arguments: */
- va_start(ap, argc);
- for (i = 0; i < argc; i++) {
- *argp = va_arg(ap, intptr_t);
- argp++;
- }
- va_end(ap);
-
- /* The ucontext is placed at the bottom of the stack. */
- *argp = (intptr_t)ucp;
-
- /*
- * Set the machine context to point to the top of the
- * stack and the program counter to the context start
- * wrapper. Note that setcontext() pushes the return
- * address onto the top of the stack, so allow for this
- * by adjusting the stack downward 1 slot. Also set
- * %esi to point to the base of the stack where ucp
- * is stored.
- */
- mc = ucp->uc_mcontext;
-
- mc->__ss.__esi = (int)argp;
- mc->__ss.__ebp = 0;
- mc->__ss.__esp = (int)stack_top + sizeof(caddr_t);
- mc->__ss.__eip = (int)_ctx_start;
- }
-}
-
-#endif /* __i386__ */
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#if defined(__i386__)
-
-#define _XOPEN_SOURCE 600L
-
-#include <ucontext.h>
-
-extern int _setcontext(const ucontext_t *);
-
-int
-setcontext(const ucontext_t *uctx)
-{
- mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data;
- ucontext_t *_uctx = (ucontext_t *)uctx;
- if (mctx != _uctx->uc_mcontext)
- _uctx->uc_mcontext = mctx;
- return _setcontext(uctx);
-}
-
-#endif /* __i386__ */
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)setjmperr.c 5.4 (Berkeley) 6/27/88";
-#endif /* LIBC_SCCS and not lint */
-
-#include <unistd.h>
-
-/*
- * This routine is called from longjmp() when an error occurs.
- * Programs that wish to exit gracefully from this error may
- * write their own versions.
- * If this routine returns, the program is aborted.
- */
-
-void
-longjmperror()
-{
-#define ERRMSG "longjmp botch\n"
- write(2, ERRMSG, sizeof(ERRMSG) - 1);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Copyright (c) 2001 Daniel M. Eischen <deischen@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(__i386__)
-
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#include <sys/signal.h>
-#include <ucontext.h>
-
-#include <errno.h>
-#include <stddef.h>
-
-#define uc_flags uc_onstack
-#define UCF_SWAPPED 0x80000000
-
-int
-swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
-{
- int ret;
-
- if ((oucp == NULL) || (ucp == NULL)) {
- errno = EINVAL;
- return (-1);
- }
- oucp->uc_flags &= ~UCF_SWAPPED;
- ret = getcontext(oucp);
- if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) {
- oucp->uc_flags |= UCF_SWAPPED;
- ret = setcontext(ucp);
- }
- return (ret);
-}
-
-#endif /* __i386__ */
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/* Initialize the "_cpu_capabilities" vector on x86 processors. */
-
-#define _APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#undef _APPLE_API_PRIVATE
-
-int _cpu_has_altivec = 0; // DEPRECATED
-int _cpu_capabilities = 0;
-
-__private_extern__ void
-_init_cpu_capabilities( void )
-{
- _cpu_capabilities = _get_cpu_capabilities();
-}
+++ /dev/null
-/*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <mach/i386/syscall_sw.h>
-
-/* Subroutine to make a preempt syscall. Called when we notice %ebx is
- * nonzero after returning from a PFZ subroutine.
- * When we enter kernel:
- * %edx = return address
- * %ecx = stack ptr
- * Destroys %eax, %ecx, and %edx.
- */
- .align 4
- .private_extern _preempt
-_preempt:
- popl %edx // get return address
- movl %esp,%ecx // save stack ptr here
- movl $(-58),%eax /* 58 = pfz_exit */
- xorl %ebx,%ebx // clear "preemption pending" flag
- sysenter
-
-
-/* Subroutine to back off if we cannot get the spinlock. Called
- * after a few attempts inline in the PFZ subroutines. This code is
- * not in the PFZ.
- * %edi = ptr to queue head structure
- * %ebx = preemption flag (nonzero if preemption pending)
- * Destroys %eax.
- */
-
- .align 4
- .private_extern _backoff
-_backoff:
- testl %ebx,%ebx // does kernel want to preempt us?
- jz 1f // no
- xorl %ebx,%ebx // yes, clear flag
- pushl %edx // preserve regs used by preempt syscall
- pushl %ecx
- call _preempt
- popl %ecx
- popl %edx
-1:
- pause // SMT-friendly backoff
- cmpl $0,8(%edi) // sniff the lockword
- jnz 1b // loop if still taken
- ret // lockword is free, so reenter PFZ
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "pthread_machdep.h"
-
-.text
-.align 2, 0x90
-.globl _pthread_getspecific
-_pthread_getspecific:
- movl 4(%esp),%eax
- movl %gs:(,%eax,4),%eax
- ret
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <architecture/i386/asm_help.h>
-
- .text
- .align 2
- .globl __commpage_pthread_mutex_lock
-__commpage_pthread_mutex_lock:
- pushl %ebp // set up frame for backtrace
- movl %esp,%ebp
- pushl %esi
- pushl %edi
- pushl %ebx
- xorl %ebx,%ebx // clear "preemption pending" flag
- movl 20(%esp),%edi // %edi == ptr to LVAL/UVAL structure
- lea 20(%esp),%esi // %esi == ptr to argument list
- movl _COMM_PAGE_SPIN_COUNT, %edx
- movl 16(%esi),%ecx // get mask (ie, PTHRW_EBIT etc)
-1:
- testl 0(%edi),%ecx // is mutex available?
- jz 2f // yes, it is available
- pause
- decl %edx // decrement max spin count
- jnz 1b // keep spinning
-2:
- EXTERN_TO_REG(_commpage_pfz_base, %ecx)
- movl (%ecx), %ecx
- addl $(_COMM_TEXT_PFZ_MUTEX_LOCK_OFFSET), %ecx
- call *%ecx
- testl %ebx,%ebx // pending preemption?
- jz 3f
- pushl %eax // save return value across sysenter
- call _preempt
- popl %eax
-3:
- popl %ebx
- popl %edi
- popl %esi
- popl %ebp
- ret
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "pthread_machdep.h"
-
-.text
-.align 2, 0x90
-.globl _pthread_self
-_pthread_self:
- movl %gs:0,%eax
- ret
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <mach/i386/syscall_sw.h>
-
-.text
-.align 2, 0x90
-.globl ___pthread_set_self
-___pthread_set_self:
- pushl 4(%esp)
- pushl $0
- movl $3,%eax
- MACHDEP_SYSCALL_TRAP
- addl $8,%esp
- ret
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "pthread_machdep.h"
-
-.text
-.align 2, 0x90
-.globl _start_wqthread
-_start_wqthread:
-// This routine is never called directly by user code, jumped from kernel
- push %ebp
- mov %esp,%ebp
- sub $28,%esp // align the stack
- mov %edi,16(%esp) //arg5
- mov %edx,12(%esp) //arg4
- mov %ecx,8(%esp) //arg3
- mov %ebx,4(%esp) //arg2
- mov %eax,(%esp) //arg1
- call __pthread_wqthread
- leave
- ret
-
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "pthread_machdep.h"
-
-.text
-.align 2, 0x90
-.globl _thread_start
-_thread_start:
-// This routine is never called directly by user code, jumped from kernel
- push %ebp
- mov %esp,%ebp
- sub $28,%esp // align the stack
- mov %esi,20(%esp) //arg6
- mov %edi,16(%esp) //arg5
- mov %edx,12(%esp) //arg4
- mov %ecx,8(%esp) //arg3
- mov %ebx,4(%esp) //arg2
- mov %eax,(%esp) //arg1
- call __pthread_start
- leave
- ret
-
+++ /dev/null
- .globl ___bzero
-___bzero:
- jmp _bzero
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse42);
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse3x);
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse2);
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, scalar);
-
-static const platfunc_descriptor *bcopy_platfunc_descriptors[] = {
- PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse42),
- PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse3x),
- PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse2),
- PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, scalar),
- 0
-};
-
-void *bcopy_chooser() __asm__("_bcopy");
-void *bcopy_chooser() {
- __asm__(".desc _bcopy, 0x100");
- return find_platform_function((const platfunc_descriptor **) bcopy_platfunc_descriptors);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from locore.s.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/appleapiopts.h>
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-#include <machine/asm.h>
-
- /*
- * (ov)bcopy (src,dst,cnt)
- * ws@tools.de (Wolfgang Solfrank, TooLs GmbH) +49-228-985800
- */
-
-PLATFUNC_FUNCTION_START_GENERIC(bcopy, scalar, 32, 5)
- pushl %ebp /* set up a frame for backtraces */
- movl %esp,%ebp
- pushl %esi
- pushl %edi
- movl 8(%ebp),%esi
- movl 12(%ebp),%edi
- jmp 1f
-
-PLATFUNC_FUNCTION_START_GENERIC(memcpy, scalar, 32, 0)
-PLATFUNC_FUNCTION_START_GENERIC(memmove, scalar, 32, 0)
- pushl %ebp /* set up a frame for backtraces */
- movl %esp,%ebp
- pushl %esi
- pushl %edi
- movl 8(%ebp),%edi
- movl 12(%ebp),%esi
- movl %edi,%eax
-1:
- movl 16(%ebp),%ecx
- movl %edi,%edx
- subl %esi,%edx
- cmpl %ecx,%edx /* overlapping? */
- jb 2f
- cld /* nope, copy forwards. */
- movl %ecx,%edx
- shrl $2,%ecx /* copy by words */
- rep
- movsl
- movl %edx,%ecx
- andl $3,%ecx /* any bytes left? */
- rep
- movsb
- popl %edi
- popl %esi
- popl %ebp
- ret
-2:
- addl %ecx,%edi /* copy backwards. */
- addl %ecx,%esi
- std
- movl %ecx,%edx
- andl $3,%ecx /* any fractional bytes? */
- decl %edi
- decl %esi
- rep
- movsb
- movl %edx,%ecx /* copy remainder by words */
- shrl $2,%ecx
- subl $3,%esi
- subl $3,%edi
- rep
- movsl
- popl %edi
- popl %esi
- popl %ebp
- cld
- ret
-
-PLATFUNC_DESCRIPTOR(bcopy,scalar,0,0)
-PLATFUNC_DESCRIPTOR(memcpy,scalar,0,0)
-PLATFUNC_DESCRIPTOR(memmove,scalar,0,0)
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-/*
- * The bcopy/memcpy loops, tuned for Pentium-M class processors with
- * Supplemental SSE3 and 64-byte cache lines.
- *
- * The following #defines are tightly coupled to the u-architecture:
- */
-
-#define kShort 80 // too short to bother with SSE (must be >=80)
-#define kVeryLong (500*1024) // large enough for non-temporal stores (must be >= 8192)
-#define kFastUCode ((16*1024)-15) // cutoff for microcode fastpath for "rep/movsl"
-
-// void bcopy(const void *src, void *dst, size_t len);
-
-PLATFUNC_FUNCTION_START(bcopy, sse3x, 32, 5)
- pushl %ebp // set up a frame for backtraces
- movl %esp,%ebp
- pushl %esi
- pushl %edi
- pushl %ebx
- movl 8(%ebp),%esi // get source ptr
- movl 12(%ebp),%edi // get dest ptr
- movl 16(%ebp),%ecx // get length
- movl %edi,%edx
- subl %esi,%edx // (dest - source)
- cmpl %ecx,%edx // must move in reverse if (dest - source) < length
- jb LReverseIsland
- cmpl $(kShort),%ecx // long enough to bother with SSE?
- jbe Lshort // no
- jmp LNotShort
-
-//
-// void *memcpy(void *dst, const void *src, size_t len);
-// void *memmove(void *dst, const void *src, size_t len);
-//
-
-PLATFUNC_FUNCTION_START(memcpy, sse3x, 32, 0) // void *memcpy(void *dst, const void *src, size_t len)
-PLATFUNC_FUNCTION_START(memmove, sse3x, 32, 0) // void *memmove(void *dst, const void *src, size_t len)
- pushl %ebp // set up a frame for backtraces
- movl %esp,%ebp
- pushl %esi
- pushl %edi
- pushl %ebx
- movl 8(%ebp),%edi // get dest ptr
- movl 12(%ebp),%esi // get source ptr
- movl 16(%ebp),%ecx // get length
- movl %edi,%edx
- subl %esi,%edx // (dest - source)
- cmpl %ecx,%edx // must move in reverse if (dest - source) < length
- jb LReverseIsland
- cmpl $(kShort),%ecx // long enough to bother with SSE?
- ja LNotShort // yes
-
-// Handle short forward copies. As the most common case, this is the fall-through path.
-// ecx = length (<= kShort)
-// esi = source ptr
-// edi = dest ptr
-
-Lshort:
- movl %ecx,%edx // copy length
- shrl $2,%ecx // get #doublewords
- jz LLeftovers
-2: // loop copying doublewords
- movl (%esi),%eax
- addl $4,%esi
- movl %eax,(%edi)
- addl $4,%edi
- dec %ecx
- jnz 2b
-LLeftovers: // handle leftover bytes (0..3) in last word
- andl $3,%edx // any leftover bytes?
- jz Lexit
-4: // loop copying bytes
- movb (%esi),%al
- inc %esi
- movb %al,(%edi)
- inc %edi
- dec %edx
- jnz 4b
-Lexit:
- movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove
- popl %ebx
- popl %edi
- popl %esi
- popl %ebp
- ret
-
-
-LReverseIsland: // keep the "jb" above a short branch...
- jmp LReverse // ...because reverse moves are uncommon
-
-
-// Handle forward moves that are long enough to justify use of SSE3.
-// First, 16-byte align the destination.
-// ecx = length (> kShort)
-// esi = source ptr
-// edi = dest ptr
-
-LNotShort:
- cmpl $(kVeryLong),%ecx // long enough to justify heavyweight loops?
- movl %edi,%edx // copy destination
- jae LVeryLong // use very-long-operand path
- negl %edx
- andl $15,%edx // get #bytes to align destination
- jz LDestAligned // already aligned
- subl %edx,%ecx // decrement length
-1: // loop copying 1..15 bytes
- movb (%esi),%al
- inc %esi
- movb %al,(%edi)
- inc %edi
- dec %edx
- jnz 1b
-
-// Destination is now aligned. Dispatch to one of sixteen loops over 64-byte chunks,
-// based on the alignment of the source. All vector loads and stores are aligned.
-// Even though this means we have to shift and repack vectors, doing so is much faster
-// than unaligned loads. Since kShort>=80 and we've moved at most 15 bytes already,
-// there is at least one chunk. When we enter the copy loops, the following registers
-// are set up:
-// ecx = residual length (0..63)
-// edx = -(length to move), a multiple of 64
-// esi = ptr to 1st source byte not to move (unaligned)
-// edi = ptr to 1st dest byte not to move (aligned)
-
-LDestAligned:
- movl %ecx,%edx // copy length
- movl %esi,%eax // copy source address
- andl $63,%ecx // get remaining bytes for Lshort
- andl $-64,%edx // get number of bytes we will copy in inner loop
- andl $15,%eax // mask to low 4 bits of source address
- addl %edx,%esi // point to 1st byte not copied
- addl %edx,%edi
- negl %edx // now generate offset to 1st byte to be copied
- call 1f
-1:
- popl %ebx
- movl (LTable-1b)(%ebx,%eax,4), %eax // load jump table entry address, relative to LZero
- leal (LTable-1b)(%ebx,%eax,1), %eax
- jmp *%eax
-
- .align 2
-LTable: // table of copy loop addresses
- .long LMod0 -LTable
- .long LMod1 -LTable
- .long LMod2 -LTable
- .long LMod3 -LTable
- .long LMod4 -LTable
- .long LMod5 -LTable
- .long LMod6 -LTable
- .long LMod7 -LTable
- .long LMod8 -LTable
- .long LMod9 -LTable
- .long LMod10 -LTable
- .long LMod11 -LTable
- .long LMod12 -LTable
- .long LMod13 -LTable
- .long LMod14 -LTable
- .long LMod15 -LTable
-
-
-// Very long forward moves. These are at least several pages. They are special cased
-// and aggressively optimized, not so much because they are common or useful, but
-// because they are subject to benchmark. There isn't enough room for them in the
-// area reserved on the platfunc for bcopy, so we put them elsewhere. We call
-// the longcopy routine using the normal ABI.
-
-LVeryLong:
- pushl %ecx // length (>= kVeryLong)
- pushl %esi // source ptr
- pushl %edi // dest ptr
- call _longcopy
- addl $12,%esp // pop off our parameters
- jmp Lexit
-
-
-// On Pentium-M, the microcode for "rep/movsl" is faster than SSE for 8-byte
-// aligned operands from about 32KB up to kVeryLong for the hot cache case, and from
-// about 256 bytes up to kVeryLong for cold caches. This is because the microcode
-// avoids having to read destination cache lines that will be completely overwritten.
-// The cutoff we use (ie, kFastUCode) must somehow balance the two cases, since
-// we do not know if the destination is in cache or not.
-
-Lfastpath:
- addl %edx,%esi // restore ptrs to 1st byte of source and dest
- addl %edx,%edi
- negl %edx // make length positive
- orl %edx,%ecx // restore total #bytes remaining to move
- cld // we'll move forward
- movl %ecx,%edx // copy total length to move
- shrl $2,%ecx // compute #words to move
- rep // the u-code will optimize this
- movsl
- jmp LLeftovers // handle 0..3 leftover bytes
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 0000
-
-LMod0:
- cmpl $(-kFastUCode),%edx // %edx == -length, where (length < kVeryLong)
- jle Lfastpath // long enough for fastpath in microcode
- jmp 1f
- .align 4,0x90 // 16-byte align inner loops
-1: // loop over 64-byte chunks
- movdqa (%esi,%edx),%xmm0
- movdqa 16(%esi,%edx),%xmm1
- movdqa 32(%esi,%edx),%xmm2
- movdqa 48(%esi,%edx),%xmm3
-
- movdqa %xmm0,(%edi,%edx)
- movdqa %xmm1,16(%edi,%edx)
- movdqa %xmm2,32(%edi,%edx)
- movdqa %xmm3,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 0001
-
-LMod1:
- movdqa -1(%esi,%edx),%xmm0 // prime the loop by loading 1st quadword
-1: // loop over 64-byte chunks
- movdqa 15(%esi,%edx),%xmm1
- movdqa 31(%esi,%edx),%xmm2
- movdqa 47(%esi,%edx),%xmm3
- movdqa 63(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $1,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $1,%xmm2,%xmm3
- palignr $1,%xmm1,%xmm2
- palignr $1,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 0010
-
-LMod2:
- movdqa -2(%esi,%edx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 14(%esi,%edx),%xmm1
- movdqa 30(%esi,%edx),%xmm2
- movdqa 46(%esi,%edx),%xmm3
- movdqa 62(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $2,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $2,%xmm2,%xmm3
- palignr $2,%xmm1,%xmm2
- palignr $2,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 0011
-
-LMod3:
- movdqa -3(%esi,%edx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 13(%esi,%edx),%xmm1
- movdqa 29(%esi,%edx),%xmm2
- movdqa 45(%esi,%edx),%xmm3
- movdqa 61(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $3,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $3,%xmm2,%xmm3
- palignr $3,%xmm1,%xmm2
- palignr $3,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 0100
-// We use the float single data type in order to use "movss" to merge vectors.
-
-LMod4:
- movaps -4(%esi,%edx),%xmm0 // 4-byte aligned: prime the loop
- jmp 1f
- .align 4,0x90
-1: // loop over 64-byte chunks
- movaps 12(%esi,%edx),%xmm1
- movaps 28(%esi,%edx),%xmm2
- movss %xmm1,%xmm0 // copy low 4 bytes of source into destination
- pshufd $(0x39),%xmm0,%xmm0 // rotate right 4 bytes (mask -- 00 11 10 01)
- movaps 44(%esi,%edx),%xmm3
- movss %xmm2,%xmm1
- pshufd $(0x39),%xmm1,%xmm1
- movaps 60(%esi,%edx),%xmm4
- movss %xmm3,%xmm2
- pshufd $(0x39),%xmm2,%xmm2
-
- movaps %xmm0,(%edi,%edx)
- movss %xmm4,%xmm3
- pshufd $(0x39),%xmm3,%xmm3
- movaps %xmm1,16(%edi,%edx)
- movaps %xmm2,32(%edi,%edx)
- movaps %xmm4,%xmm0
- movaps %xmm3,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 0101
-
-LMod5:
- movdqa -5(%esi,%edx),%xmm0// prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 11(%esi,%edx),%xmm1
- movdqa 27(%esi,%edx),%xmm2
- movdqa 43(%esi,%edx),%xmm3
- movdqa 59(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $5,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $5,%xmm2,%xmm3
- palignr $5,%xmm1,%xmm2
- palignr $5,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 0110
-
-LMod6:
- movdqa -6(%esi,%edx),%xmm0// prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 10(%esi,%edx),%xmm1
- movdqa 26(%esi,%edx),%xmm2
- movdqa 42(%esi,%edx),%xmm3
- movdqa 58(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $6,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $6,%xmm2,%xmm3
- palignr $6,%xmm1,%xmm2
- palignr $6,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 0111
-
-LMod7:
- movdqa -7(%esi,%edx),%xmm0// prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 9(%esi,%edx),%xmm1
- movdqa 25(%esi,%edx),%xmm2
- movdqa 41(%esi,%edx),%xmm3
- movdqa 57(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $7,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $7,%xmm2,%xmm3
- palignr $7,%xmm1,%xmm2
- palignr $7,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 1000
-// We use the float double data type in order to use "shufpd" to shift by 8 bytes.
-
-LMod8:
- cmpl $(-kFastUCode),%edx// %edx == -length, where (length < kVeryLong)
- jle Lfastpath // long enough for fastpath in microcode
- movapd -8(%esi,%edx),%xmm0// 8-byte aligned: prime the loop
- jmp 1f
- .align 4,0x90
-1: // loop over 64-byte chunks
- movapd 8(%esi,%edx),%xmm1
- movapd 24(%esi,%edx),%xmm2
- shufpd $01,%xmm1,%xmm0 // %xmm0 <- shr( %xmm0 || %xmm1, 8 bytes)
- movapd 40(%esi,%edx),%xmm3
- shufpd $01,%xmm2,%xmm1
- movapd 56(%esi,%edx),%xmm4
- shufpd $01,%xmm3,%xmm2
-
- movapd %xmm0,(%edi,%edx)
- shufpd $01,%xmm4,%xmm3
- movapd %xmm1,16(%edi,%edx)
- movapd %xmm2,32(%edi,%edx)
- movapd %xmm4,%xmm0
- movapd %xmm3,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 1001
-
-LMod9:
- movdqa -9(%esi,%edx),%xmm0// prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 7(%esi,%edx),%xmm1
- movdqa 23(%esi,%edx),%xmm2
- movdqa 39(%esi,%edx),%xmm3
- movdqa 55(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $9,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $9,%xmm2,%xmm3
- palignr $9,%xmm1,%xmm2
- palignr $9,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 1010
-
-LMod10:
- movdqa -10(%esi,%edx),%xmm0// prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 6(%esi,%edx),%xmm1
- movdqa 22(%esi,%edx),%xmm2
- movdqa 38(%esi,%edx),%xmm3
- movdqa 54(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $10,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $10,%xmm2,%xmm3
- palignr $10,%xmm1,%xmm2
- palignr $10,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 1011
-
-LMod11:
- movdqa -11(%esi,%edx),%xmm0// prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 5(%esi,%edx),%xmm1
- movdqa 21(%esi,%edx),%xmm2
- movdqa 37(%esi,%edx),%xmm3
- movdqa 53(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $11,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $11,%xmm2,%xmm3
- palignr $11,%xmm1,%xmm2
- palignr $11,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 1100
-// We use the float single data type in order to use "movss" to merge vectors.
-
-LMod12:
- movss (%esi,%edx),%xmm0// prefetch 1st four bytes of source, right justified
- jmp 1f
- .align 4,0x90
-1: // loop over 64-byte chunks
- pshufd $(0x93),4(%esi,%edx),%xmm1 // load and rotate right 12 bytes (mask -- 10 01 00 11)
- pshufd $(0x93),20(%esi,%edx),%xmm2
- pshufd $(0x93),36(%esi,%edx),%xmm3
- pshufd $(0x93),52(%esi,%edx),%xmm4
-
- movaps %xmm4,%xmm5
- movss %xmm3,%xmm4 // copy low 4 bytes of source into destination
- movss %xmm2,%xmm3
- movss %xmm1,%xmm2
- movss %xmm0,%xmm1
-
- movaps %xmm1,(%edi,%edx)
- movaps %xmm2,16(%edi,%edx)
- movaps %xmm5,%xmm0
- movaps %xmm3,32(%edi,%edx)
- movaps %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 1101
-
-LMod13:
- movdqa -13(%esi,%edx),%xmm0// prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 3(%esi,%edx),%xmm1
- movdqa 19(%esi,%edx),%xmm2
- movdqa 35(%esi,%edx),%xmm3
- movdqa 51(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $13,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $13,%xmm2,%xmm3
- palignr $13,%xmm1,%xmm2
- palignr $13,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 1110
-
-LMod14:
- movdqa -14(%esi,%edx),%xmm0// prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 2(%esi,%edx),%xmm1
- movdqa 18(%esi,%edx),%xmm2
- movdqa 34(%esi,%edx),%xmm3
- movdqa 50(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $14,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $14,%xmm2,%xmm3
- palignr $14,%xmm1,%xmm2
- palignr $14,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %esi == 1111
-
-LMod15:
- movdqa -15(%esi,%edx),%xmm0// prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 1(%esi,%edx),%xmm1
- movdqa 17(%esi,%edx),%xmm2
- movdqa 33(%esi,%edx),%xmm3
- movdqa 49(%esi,%edx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $15,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $15,%xmm2,%xmm3
- palignr $15,%xmm1,%xmm2
- palignr $15,%xmm5,%xmm1
-
- movdqa %xmm1,(%edi,%edx)
- movdqa %xmm2,16(%edi,%edx)
- movdqa %xmm3,32(%edi,%edx)
- movdqa %xmm4,48(%edi,%edx)
-
- addl $64,%edx
- jnz 1b
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Reverse moves. These are not optimized as aggressively as their forward
-// counterparts, as they are only used with destructive overlap.
-// ecx = length
-// esi = source ptr
-// edi = dest ptr
-
-LReverse:
- addl %ecx,%esi // point to end of strings
- addl %ecx,%edi
- cmpl $(kShort),%ecx // long enough to bother with SSE?
- ja LReverseNotShort // yes
-
-// Handle reverse short copies.
-// ecx = length
-// esi = one byte past end of source
-// edi = one byte past end of dest
-
-LReverseShort:
- movl %ecx,%edx // copy length
- shrl $2,%ecx // #words
- jz 3f
-1:
- subl $4,%esi
- movl (%esi),%eax
- subl $4,%edi
- movl %eax,(%edi)
- dec %ecx
- jnz 1b
-3:
- andl $3,%edx // bytes?
- jz 5f
-4:
- dec %esi
- movb (%esi),%al
- dec %edi
- movb %al,(%edi)
- dec %edx
- jnz 4b
-5:
- movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove
- popl %ebx
- popl %edi
- popl %esi
- popl %ebp
- ret
-
-// Handle a reverse move long enough to justify using SSE.
-// ecx = length
-// esi = one byte past end of source
-// edi = one byte past end of dest
-
-LReverseNotShort:
- movl %edi,%edx // copy destination
- andl $15,%edx // get #bytes to align destination
- je LReverseDestAligned // already aligned
- subl %edx,%ecx // adjust length
-1: // loop copying 1..15 bytes
- dec %esi
- movb (%esi),%al
- dec %edi
- movb %al,(%edi)
- dec %edx
- jnz 1b
-
-// Destination is now aligned. Prepare for reverse loops.
-
-LReverseDestAligned:
- movl %ecx,%edx // copy length
- andl $63,%ecx // get remaining bytes for Lshort
- andl $-64,%edx // get number of bytes we will copy in inner loop
- subl %edx,%esi // point to endpoint of copy
- subl %edx,%edi
- testl $15,%esi // is source aligned too?
- jnz LReverseUnalignedLoop // no
-
-LReverseAlignedLoop: // loop over 64-byte chunks
- movdqa -16(%esi,%edx),%xmm0
- movdqa -32(%esi,%edx),%xmm1
- movdqa -48(%esi,%edx),%xmm2
- movdqa -64(%esi,%edx),%xmm3
-
- movdqa %xmm0,-16(%edi,%edx)
- movdqa %xmm1,-32(%edi,%edx)
- movdqa %xmm2,-48(%edi,%edx)
- movdqa %xmm3,-64(%edi,%edx)
-
- subl $64,%edx
- jne LReverseAlignedLoop
-
- jmp LReverseShort // copy remaining 0..63 bytes and done
-
-
-// Reverse, unaligned loop. LDDQU==MOVDQU on these machines.
-
-LReverseUnalignedLoop: // loop over 64-byte chunks
- movdqu -16(%esi,%edx),%xmm0
- movdqu -32(%esi,%edx),%xmm1
- movdqu -48(%esi,%edx),%xmm2
- movdqu -64(%esi,%edx),%xmm3
-
- movdqa %xmm0,-16(%edi,%edx)
- movdqa %xmm1,-32(%edi,%edx)
- movdqa %xmm2,-48(%edi,%edx)
- movdqa %xmm3,-64(%edi,%edx)
-
- subl $64,%edx
- jne LReverseUnalignedLoop
-
- jmp LReverseShort // copy remaining 0..63 bytes and done
-
-PLATFUNC_DESCRIPTOR(bcopy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2)
-PLATFUNC_DESCRIPTOR(memcpy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2)
-PLATFUNC_DESCRIPTOR(memmove,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2)
+++ /dev/null
-/*
- * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-/*
- * The bcopy/memcpy loops, tuned for Nehalem.
- *
- * The following #defines are tightly coupled to the u-architecture:
- */
-
-#define kShort 80 // too short to bother with SSE (must be >=80)
-
-
-// void bcopy(const void *src, void *dst, size_t len);
-
-PLATFUNC_FUNCTION_START(bcopy, sse42, 32, 5)
- pushl %ebp // set up a frame for backtraces
- movl %esp,%ebp
- pushl %esi
- pushl %edi
- movl 8(%ebp),%esi // get source ptr
- movl 12(%ebp),%edi // get dest ptr
- movl 16(%ebp),%ecx // get length
- movl %edi,%edx
- subl %esi,%edx // (dest - source)
- cmpl %ecx,%edx // must move in reverse if (dest - source) < length
- jb LReverseIsland
- cmpl $(kShort),%ecx // long enough to bother with SSE?
- jbe Lshort // no
- jmp LNotShort
-
-//
-// void *memcpy(void *dst, const void *src, size_t len);
-// void *memmove(void *dst, const void *src, size_t len);
-//
-
-PLATFUNC_FUNCTION_START(memcpy, sse42, 32, 0) // void *memcpy(void *dst, const void *src, size_t len)
-PLATFUNC_FUNCTION_START(memmove, sse42, 32, 0) // void *memmove(void *dst, const void *src, size_t len)
- pushl %ebp // set up a frame for backtraces
- movl %esp,%ebp
- pushl %esi
- pushl %edi
- movl 8(%ebp),%edi // get dest ptr
- movl 12(%ebp),%esi // get source ptr
- movl 16(%ebp),%ecx // get length
- movl %edi,%edx
- subl %esi,%edx // (dest - source)
- cmpl %ecx,%edx // must move in reverse if (dest - source) < length
- jb LReverseIsland
- cmpl $(kShort),%ecx // long enough to bother with SSE?
- ja LNotShort // yes
-
-// Handle short forward copies. As the most common case, this is the fall-through path.
-// ecx = length (<= kShort)
-// esi = source ptr
-// edi = dest ptr
-
-Lshort:
- movl %ecx,%edx // copy length
- shrl $2,%ecx // get #doublewords
- jz 3f
-2: // loop copying doublewords
- movl (%esi),%eax
- addl $4,%esi
- movl %eax,(%edi)
- addl $4,%edi
- dec %ecx
- jnz 2b
-3: // handle leftover bytes (0..3) in last word
- andl $3,%edx // any leftover bytes?
- jz Lexit
-4: // loop copying bytes
- movb (%esi),%al
- inc %esi
- movb %al,(%edi)
- inc %edi
- dec %edx
- jnz 4b
-Lexit:
- movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove
- popl %edi
- popl %esi
- popl %ebp
- ret
-
-
-LReverseIsland: // keep the "jb" above a short branch...
- jmp LReverse // ...because reverse moves are uncommon
-
-
-// Handle forward moves that are long enough to justify use of SSE.
-// First, 16-byte align the destination.
-// ecx = length (> kShort)
-// esi = source ptr
-// edi = dest ptr
-
-LNotShort:
- movl %edi,%edx // copy destination
- negl %edx
- andl $15,%edx // get #bytes to align destination
- jz LDestAligned // already aligned
- subl %edx,%ecx // decrement length
-1: // loop copying 1..15 bytes
- movb (%esi),%al
- inc %esi
- movb %al,(%edi)
- inc %edi
- dec %edx
- jnz 1b
-
-// Destination is now aligned. Nehalem does a great job with unaligned SSE loads,
-// so we use MOVDQU rather than aligned loads and shifts. Since kShort>=80, we
-// know there is at least one 64-byte chunk to move.
-// When we enter the copy loops, the following registers are set up:
-// ecx = residual length (0..63)
-// edx = -(length to move), a multiple of 64
-// esi = ptr to 1st source byte not to move (unaligned)
-// edi = ptr to 1st dest byte not to move (aligned)
-
-LDestAligned:
- movl %ecx,%edx // copy length
- andl $63,%ecx // get remaining bytes for Lshort
- andl $-64,%edx // get number of bytes we will copy in inner loop
- addl %edx,%esi // point to 1st byte not copied
- addl %edx,%edi
- negl %edx // now generate offset to 1st byte to be copied
- testl $15,%esi // source also aligned?
- jnz LUnalignedLoop
- jmp LAlignedLoop
-
-
-// Forward loop for aligned operands.
-
- .align 4,0x90 // 16-byte align inner loops
-LAlignedLoop: // loop over 64-byte chunks
- movdqa (%esi,%edx),%xmm0
- movdqa 16(%esi,%edx),%xmm1
- movdqa 32(%esi,%edx),%xmm2
- movdqa 48(%esi,%edx),%xmm3
-
- movdqa %xmm0,(%edi,%edx)
- movdqa %xmm1,16(%edi,%edx)
- movdqa %xmm2,32(%edi,%edx)
- movdqa %xmm3,48(%edi,%edx)
-
- addl $64,%edx
- jnz LAlignedLoop
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for unaligned operands.
-
- .align 4,0x90 // 16-byte align inner loops
-LUnalignedLoop: // loop over 64-byte chunks
- movdqu (%esi,%edx),%xmm0
- movdqu 16(%esi,%edx),%xmm1
- movdqu 32(%esi,%edx),%xmm2
- movdqu 48(%esi,%edx),%xmm3
-
- movdqa %xmm0,(%edi,%edx)
- movdqa %xmm1,16(%edi,%edx)
- movdqa %xmm2,32(%edi,%edx)
- movdqa %xmm3,48(%edi,%edx)
-
- addl $64,%edx
- jnz LUnalignedLoop
-
- jmp Lshort // copy remaining 0..63 bytes and done
-
-
-// Reverse moves. They are only used with destructive overlap.
-// ecx = length
-// esi = source ptr
-// edi = dest ptr
-
-LReverse:
- addl %ecx,%esi // point to end of strings
- addl %ecx,%edi
- cmpl $(kShort),%ecx // long enough to bother with SSE?
- ja LReverseNotShort // yes
-
-// Handle reverse short copies.
-// ecx = length
-// esi = one byte past end of source
-// edi = one byte past end of dest
-
-LReverseShort:
- movl %ecx,%edx // copy length
- shrl $2,%ecx // #words
- jz 3f
-1:
- subl $4,%esi
- movl (%esi),%eax
- subl $4,%edi
- movl %eax,(%edi)
- dec %ecx
- jnz 1b
-3:
- andl $3,%edx // bytes?
- jz 5f
-4:
- dec %esi
- movb (%esi),%al
- dec %edi
- movb %al,(%edi)
- dec %edx
- jnz 4b
-5:
- movl 8(%ebp),%eax // get return value (dst ptr) for memcpy/memmove
- popl %edi
- popl %esi
- popl %ebp
- ret
-
-// Handle a reverse move long enough to justify using SSE.
-// ecx = length
-// esi = one byte past end of source
-// edi = one byte past end of dest
-
-LReverseNotShort:
- movl %edi,%edx // copy destination
- andl $15,%edx // get #bytes to align destination
- je LReverseDestAligned // already aligned
- subl %edx,%ecx // adjust length
-1: // loop copying 1..15 bytes
- dec %esi
- movb (%esi),%al
- dec %edi
- movb %al,(%edi)
- dec %edx
- jnz 1b
-
-// Destination is now aligned. Prepare for reverse loops.
-
-LReverseDestAligned:
- movl %ecx,%edx // copy length
- andl $63,%ecx // get remaining bytes for Lshort
- andl $-64,%edx // get number of bytes we will copy in inner loop
- subl %edx,%esi // point to endpoint of copy
- subl %edx,%edi
- testl $15,%esi // is source aligned too?
- jnz LReverseUnalignedLoop // no
-
-LReverseAlignedLoop: // loop over 64-byte chunks
- movdqa -16(%esi,%edx),%xmm0
- movdqa -32(%esi,%edx),%xmm1
- movdqa -48(%esi,%edx),%xmm2
- movdqa -64(%esi,%edx),%xmm3
-
- movdqa %xmm0,-16(%edi,%edx)
- movdqa %xmm1,-32(%edi,%edx)
- movdqa %xmm2,-48(%edi,%edx)
- movdqa %xmm3,-64(%edi,%edx)
-
- subl $64,%edx
- jne LReverseAlignedLoop
-
- jmp LReverseShort // copy remaining 0..63 bytes and done
-
-
-// Reverse, unaligned loop. LDDQU==MOVDQU on these machines.
-
-LReverseUnalignedLoop: // loop over 64-byte chunks
- movdqu -16(%esi,%edx),%xmm0
- movdqu -32(%esi,%edx),%xmm1
- movdqu -48(%esi,%edx),%xmm2
- movdqu -64(%esi,%edx),%xmm3
-
- movdqa %xmm0,-16(%edi,%edx)
- movdqa %xmm1,-32(%edi,%edx)
- movdqa %xmm2,-48(%edi,%edx)
- movdqa %xmm3,-64(%edi,%edx)
-
- subl $64,%edx
- jne LReverseUnalignedLoop
-
- jmp LReverseShort // copy remaining 0..63 bytes and done
-
-
-PLATFUNC_DESCRIPTOR(bcopy,sse42,kHasSSE4_2,0)
-PLATFUNC_DESCRIPTOR(memcpy,sse42,kHasSSE4_2,0)
-PLATFUNC_DESCRIPTOR(memmove,sse42,kHasSSE4_2,0)
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse42)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse2)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, scalar)
-
-static const platfunc_descriptor *bzero_platfunc_descriptors[] = {
- PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse42),
- PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse2),
- PLATFUNC_DESCRIPTOR_REFERENCE(bzero, scalar),
- 0
-};
-
-void *bzero_chooser() __asm__("_bzero");
-void *bzero_chooser() {
- __asm__(".desc _bzero, 0x100");
- return find_platform_function((const platfunc_descriptor **) bzero_platfunc_descriptors);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1993 Winning Strategies, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Winning Strategies, Inc.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software withough specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <sys/appleapiopts.h>
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-/*
- * bzero (void *b, size_t len)
- * write len zero bytes to the string b.
- *
- * Written by:
- * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc.
- */
-
-PLATFUNC_FUNCTION_START_GENERIC(bzero, scalar, 32, 4)
- pushl %ebp /* set up a frame for backtraces */
- movl %esp,%ebp
- pushl %edi
- pushl %ebx
- movl 8(%ebp),%edi
- movl 12(%ebp),%ecx
-
- cld /* set fill direction forward */
- xorl %eax,%eax /* set fill data to 0 */
-
- /*
- * if the string is too short, it's really not worth the overhead
- * of aligning to word boundries, etc. So we jump to a plain
- * unaligned set.
- */
- cmpl $0x0f,%ecx
- jbe L1
-
- movl %edi,%edx /* compute misalignment */
- negl %edx
- andl $3,%edx
- movl %ecx,%ebx
- subl %edx,%ebx
-
- movl %edx,%ecx /* zero until word aligned */
- rep
- stosb
-
- movl %ebx,%ecx /* zero by words */
- shrl $2,%ecx
- rep
- stosl
-
- movl %ebx,%ecx
- andl $3,%ecx /* zero remainder by bytes */
-L1: rep
- stosb
-
- popl %ebx
- popl %edi
- popl %ebp
- ret
-
-PLATFUNC_DESCRIPTOR(bzero,scalar,0,0)
+++ /dev/null
-/*
- * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-/*
- * Bzero, tuned for processors with SSE4.2 and 64-byte cache lines, ie Nehalem.
- * We don't actually use SSE4.2, but rather use it to identify Nehalem.
- *
- * We do not use nontemporal operations, but use MOVDQA in preference to REP/STOS.
- *
- * This routine is also used for memset(p,0,n), which is a common case
- * since gcc sometimes silently maps bzero() into memset(). As a result,
- * we always load the original ptr into %eax before returning.
- */
-
-#define kShort 80 // too short to bother with SSE (must be >=80)
-
-
-PLATFUNC_FUNCTION_START(bzero, sse42, 32, 5)
- pushl %ebp // set up a frame for backtraces
- movl %esp,%ebp
- pushl %edi
- movl 8(%ebp),%edi // get ptr
- movl 12(%ebp),%edx // get length
-
- xorl %eax,%eax // set fill data to 0
- cmpl $(kShort),%edx // long enough for SSE?
- jg LNotShort // yes
-
-// Here for short operands or the end of long ones.
-// %edx = length
-// %edi = ptr
-// %eax = zero
-
-Lshort:
- cmpl $12,%edx // long enough to word align?
- jge 3f // yes
- test %edx,%edx // length==0?
- jz 6f
-1:
- movb %al,(%edi) // zero a byte
- inc %edi
- dec %edx
- jnz 1b
- jmp 6f
-2:
- movb %al,(%edi) // zero a byte
- inc %edi
- dec %edx
-3:
- test $3,%edi // is ptr doubleword aligned?
- jnz 2b // no
- movl %edx,%ecx // copy length
- shrl $2,%edx // #doublewords to store
-4:
- movl %eax,(%edi) // zero an aligned doubleword
- addl $4,%edi
- dec %edx
- jnz 4b
- andl $3,%ecx // mask down to #bytes at end (0..3)
- jz 6f // none
-5:
- movb %al,(%edi) // zero a byte
- inc %edi
- dec %ecx
- jnz 5b
-6:
- movl 8(%ebp),%eax // get return value in case this was a call of memset()
- popl %edi
- popl %ebp
- ret
-
-
-// We will be using SSE, so align ptr.
-// %edx = length
-// %edi = ptr
-// %eax = zero
-
-LNotShort:
- testl $3,%edi // 4-byte aligned?
- jz 2f // yes
- movb %al,(%edi) // zero another byte
- incl %edi
- decl %edx
- jmp LNotShort
-1: // zero doublewords until 16-byte aligned
- movl %eax,(%edi)
- addl $4,%edi
- subl $4,%edx
-2:
- testl $15,%edi // 16-byte aligned?
- jnz 1b // no
-
-
-// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks.
-// %edx = length
-// %edi = ptr
-// %eax = zero
-
-LDestAligned:
- movl %edx,%ecx
- andl $63,%edx // mask down to residual length (0..63)
- andl $-64,%ecx // get #bytes we will zero in this loop
- pxor %xmm0,%xmm0 // zero an SSE register
- addl %ecx,%edi // increment ptr by length to move
- negl %ecx // negate length to move
- jmp 1f
-
-// Loop over 64-byte chunks, storing into cache.
-
- .align 4,0x90 // keep inner loops 16-byte aligned
-1:
- movdqa %xmm0,(%edi,%ecx)
- movdqa %xmm0,16(%edi,%ecx)
- movdqa %xmm0,32(%edi,%ecx)
- movdqa %xmm0,48(%edi,%ecx)
- addl $64,%ecx
- jne 1b
-
- jmp Lshort
-
-
-
-PLATFUNC_DESCRIPTOR(bzero,sse42,kHasSSE4_2,0)
+++ /dev/null
-/*
- * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
- .text
-
- .align 2
- .globl _ffs
-_ffs:
- .globl _ffsl
-_ffsl:
- movl $(-1), %edx
- bsfl 4(%esp), %eax
- cmovel %edx, %eax
- incl %eax
- ret
-
-
- .align 2
- .globl _fls
-_fls:
- .globl _flsl
-_flsl:
- movl $(-1), %edx
- bsrl 4(%esp), %eax
- cmovel %edx, %eax
- incl %eax
- ret
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-
-/*
- * The bcopy/memcpy loops for very long operands, tuned for Pentium-M
- * class processors with Supplemental SSE3 and 64-byte cache lines.
- *
- * The following #defines are tightly coupled to the u-architecture:
- */
-
-#define kBigChunk (256*1024) // outer loop chunk size for kVeryLong sized operands
-
-
-// Very long forward moves. These are at least several pages, so we loop over big
-// chunks of memory (kBigChunk in size.) We first prefetch the chunk, and then copy
-// it using non-temporal stores. Hopefully all the reads occur in the prefetch loop,
-// so the copy loop reads from L2 and writes directly to memory (with write combining.)
-// This minimizes bus turnaround and maintains good DRAM page locality.
-// Note that for this scheme to work, kVeryLong must be a large fraction of L2 cache
-// size. Otherwise, it is counter-productive to bypass L2 on the stores.
-//
-// We are called from the platfunc bcopy loops when they encounter very long
-// operands, with the standard ABI.
-//
-// void longcopy(const void *dest, void *sou, size_t len)
-
-// void longcopy(const void *dest, void *sou, size_t len)
-
- .text
- .private_extern _longcopy
-
- .align 5
-_longcopy:
- pushl %ebp // set up a frame for backtraces
- movl %esp,%ebp
- pushl %esi
- pushl %edi
- pushl %ebx // we'll need to use this too
- movl 8(%ebp),%edi // get dest ptr
- movl 12(%ebp),%esi // get source ptr
- movl 16(%ebp),%ecx // get length
- movl %edi,%ebx // copy dest ptr
- negl %ebx
- andl $63,%ebx // get #bytes to cache line align destination
- jz LBigChunkLoop // already aligned
-
-// Cache line align destination, so temporal stores in copy loops work right.
-
- pushl %ebx // arg3 - #bytes to align destination (1..63)
- pushl %esi // arg2 - source
- pushl %edi // arg1 - dest
- call _memcpy // align the destination
- addl $12,%esp
- movl 8(%ebp),%edi // recover dest ptr
- movl 12(%ebp),%esi // recover source ptr
- movl 16(%ebp),%ecx // recover length
- addl %ebx,%esi // adjust ptrs and lengths past copy
- addl %ebx,%edi
- subl %ebx,%ecx
-
-// Loop over big chunks.
-// ecx = length remaining (>= 4096)
-// edi = dest (64-byte aligned)
-// esi = source (may be unaligned)
-
-LBigChunkLoop:
- movl $(kBigChunk),%edx // assume we can do a full chunk
- cmpl %edx,%ecx // do we have a full chunk left to do?
- cmovbl %ecx,%edx // if not, only move what we have left
- andl $-4096,%edx // we work in page multiples
- xor %eax,%eax // initialize chunk offset
- jmp LTouchLoop
-
-// Touch in the next chunk. We try to keep the prefetch unit in "kick-start" mode,
-// by touching two adjacent cache lines every 8 lines of each page, in four slices.
-// Because the source may be unaligned, we use byte loads to touch.
-// ecx = length remaining (including this chunk)
-// edi = ptr to start of dest chunk
-// esi = ptr to start of source chunk
-// edx = chunk length (multiples of pages)
-// ebx = scratch reg used to read a byte of each cache line
-// eax = chunk offset
-
- .align 4,0x90 // 16-byte align inner loops
-LTouchLoop:
- movzb (%esi,%eax),%ebx // touch line 0, 2, 4, or 6 of page
- movzb 1*64(%esi,%eax),%ebx // touch line 1, 3, 5, or 7
- movzb 8*64(%esi,%eax),%ebx // touch line 8, 10, 12, or 14
- movzb 9*64(%esi,%eax),%ebx // etc
-
- movzb 16*64(%esi,%eax),%ebx
- movzb 17*64(%esi,%eax),%ebx
- movzb 24*64(%esi,%eax),%ebx
- movzb 25*64(%esi,%eax),%ebx
-
- movzb 32*64(%esi,%eax),%ebx
- movzb 33*64(%esi,%eax),%ebx
- movzb 40*64(%esi,%eax),%ebx
- movzb 41*64(%esi,%eax),%ebx
-
- movzb 48*64(%esi,%eax),%ebx
- movzb 49*64(%esi,%eax),%ebx
- movzb 56*64(%esi,%eax),%ebx
- movzb 57*64(%esi,%eax),%ebx
-
- subl $-128,%eax // next slice of page (adding 128 w 8-bit immediate)
- testl $512,%eax // done with this page?
- jz LTouchLoop // no, next of four slices
- addl $(4096-512),%eax // move on to next page
- cmpl %eax,%edx // done with this chunk?
- jnz LTouchLoop // no, do next page
-
-// The chunk has been pre-fetched, now copy it using non-temporal stores.
-// There are two copy loops, depending on whether the source is 16-byte aligned
-// or not.
-
- addl %edx,%esi // increment ptrs by chunk length
- addl %edx,%edi
- subl %edx,%ecx // adjust remaining length
- negl %edx // prepare loop index (counts up to 0)
- testl $15,%esi // is source 16-byte aligned?
- jnz LVeryLongUnaligned // source is not aligned
- jmp LVeryLongAligned
-
- .align 4,0x90 // 16-byte align inner loops
-LVeryLongAligned: // aligned loop over 128-bytes
- movdqa (%esi,%edx),%xmm0
- movdqa 16(%esi,%edx),%xmm1
- movdqa 32(%esi,%edx),%xmm2
- movdqa 48(%esi,%edx),%xmm3
- movdqa 64(%esi,%edx),%xmm4
- movdqa 80(%esi,%edx),%xmm5
- movdqa 96(%esi,%edx),%xmm6
- movdqa 112(%esi,%edx),%xmm7
-
- movntdq %xmm0,(%edi,%edx)
- movntdq %xmm1,16(%edi,%edx)
- movntdq %xmm2,32(%edi,%edx)
- movntdq %xmm3,48(%edi,%edx)
- movntdq %xmm4,64(%edi,%edx)
- movntdq %xmm5,80(%edi,%edx)
- movntdq %xmm6,96(%edi,%edx)
- movntdq %xmm7,112(%edi,%edx)
-
- subl $-128,%edx // add 128 with an 8-bit immediate
- jnz LVeryLongAligned
- jmp LVeryLongChunkEnd
-
- .align 4,0x90 // 16-byte align inner loops
-LVeryLongUnaligned: // unaligned loop over 128-bytes
- movdqu (%esi,%edx),%xmm0
- movdqu 16(%esi,%edx),%xmm1
- movdqu 32(%esi,%edx),%xmm2
- movdqu 48(%esi,%edx),%xmm3
- movdqu 64(%esi,%edx),%xmm4
- movdqu 80(%esi,%edx),%xmm5
- movdqu 96(%esi,%edx),%xmm6
- movdqu 112(%esi,%edx),%xmm7
-
- movntdq %xmm0,(%edi,%edx)
- movntdq %xmm1,16(%edi,%edx)
- movntdq %xmm2,32(%edi,%edx)
- movntdq %xmm3,48(%edi,%edx)
- movntdq %xmm4,64(%edi,%edx)
- movntdq %xmm5,80(%edi,%edx)
- movntdq %xmm6,96(%edi,%edx)
- movntdq %xmm7,112(%edi,%edx)
-
- subl $-128,%edx // add 128 with an 8-bit immediate
- jnz LVeryLongUnaligned
-
-LVeryLongChunkEnd:
- cmpl $4096,%ecx // at least another page to go?
- jae LBigChunkLoop // yes
-
-// Done. Call memcpy() again to handle the 0-4095 bytes at the end.
-
- sfence // required by non-temporal stores
- testl %ecx,%ecx // anything left to copy?
- jz 1f
- pushl %ecx // arg3 - #bytes to align destination (1..63)
- pushl %esi // arg2 - source
- pushl %edi // arg1 - dest
- call _memcpy // align the destination
- addl $12,%esp // pop off arguments
-1:
- popl %ebx
- popl %edi
- popl %esi
- popl %ebp
- ret
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// *************** ***********
-// * M E M C M P * and * B C M P *
-// *************** ***********
-//
-// int memcmp(const char *s1, const char *s2, size_t len);
-// int bcmp(const char *s1, const char *s2, size_t len);
-//
-// Bcmp returns (+,0,-), whereas memcmp returns the true difference
-// between the first differing bytes, but we treat them identically.
-//
-// We optimize the compare by doing it with SSE. This introduces
-// a complication: if we blindly did vector loads from both sides until
-// finding a difference, we might get a spurious page fault by
-// reading bytes past the difference. To avoid this, we never do a load
-// that crosses a page boundary.
-
-#define kShort 18 // too short for vectors (must be >16)
-
- .text
- .align 4
-
- .globl _memcmp
- .globl _bcmp
-
-_memcmp: // int memcmp(const char *s1,const char *s2,size_t len);
-_bcmp: // int bcmp(const char *s1,const char *s2,size_t len);
- pushl %esi
- pushl %edi
- movl 20(%esp),%ecx // get length
- movl 12(%esp),%esi // get LHS ptr
- movl 16(%esp),%edi // get RHS ptr
- cmpl $(kShort),%ecx // worth accelerating?
- ja LNotShort // yes
-
-
-// Too short to bother with parallel compares. Loop over bytes.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length (<= kShort)
-
-LShort:
- testl %ecx,%ecx // 0-length?
- jnz LShortLoop // no
- xorl %eax,%eax // return 0
- jmp LExit
- .align 4,0x90 // align inner loops to optimize I-fetch
-LShortLoop: // loop over bytes
- movzb (%esi),%eax // get LHS byte
- movzb (%edi),%edx // get RHS byte
- incl %esi
- incl %edi
- subl %edx,%eax // compare them
- jnz LExit // done if not equal
- decl %ecx // decrement length
- jnz LShortLoop
-LExit: // return value is in %eax
- popl %edi
- popl %esi
- ret
-
-LNotEqual: // here from LLoopOverBytes with LHS in eax
- movzb (%edi),%edx // get RHS byte
- subl %edx,%eax // generate return value (nonzero)
- popl %edi
- popl %esi
- ret
-
-
-// Loop over bytes until we reach end of a page.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length remaining after end of loop (ie, already adjusted)
-// %edx = #bytes until next page (1..15)
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%esi),%eax // get LHS byte
- inc %esi
- cmpb (%edi),%al // compare to RHS byte
- jnz LNotEqual // done if not equal
- inc %edi
- dec %edx // more to go?
- jnz LLoopOverBytes
-
-
-// Long enough to justify overhead of setting up vector compares. In order to
-// avoid spurious page faults, we loop over:
-//
-// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4
-//
-// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte
-// comparison until reaching the next page, then resume the vector comparison.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length (> kShort)
-
-LNotShort:
- movl %esi,%eax // copy ptrs
- movl %edi,%edx
- andl $4095,%eax // mask down to page offsets
- andl $4095,%edx
- cmpl %eax,%edx // which is bigger?
- cmova %edx,%eax // %eax = max(LHS offset, RHS offset);
- movl $4096,%edx
- subl %eax,%edx // get #bytes to next page crossing
- cmpl %ecx,%edx // will operand run out first?
- cmova %ecx,%edx // get min(length remaining, bytes to page end)
- movl %edx,%eax
- shrl $4,%edx // get #chunks till end of operand or page
- jnz LLoopOverChunks // enter vector loop
-
-// Too near page end for vectors.
-
- subl %eax,%ecx // adjust length remaining
- movl %eax,%edx // %edx <- #bytes to page end
- cmpl $(kShort),%ecx // will there be enough after we cross page for vectors?
- ja LLoopOverBytes // yes
- addl %eax,%ecx // no, restore total length remaining
- jmp LShortLoop // compare rest byte-by-byte (%ecx != 0)
-
-
-// Loop over 16-byte chunks.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length remaining
-// %edx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%esi),%xmm0 // get LHS
- movdqu (%edi),%xmm1 // get RHS
- addl $16,%esi
- pcmpeqb %xmm1,%xmm0 // compare LHS to RHS
- addl $16,%edi
- pmovmskb %xmm0,%eax // collect comparison result bits (1 if equal)
- subl $16,%ecx // adjust length remaining
- xorl $0xFFFF,%eax // all equal?
- jne LDifferent // no, we found differing bytes
- dec %edx // more to go?
- jnz LLoopOverChunks
-
- cmpl $(kShort),%ecx // a lot more to compare?
- jbe LShort // no
- jmp LNotShort // compute distance to next page crossing etc
-
-
-// Found a difference.
-// %esi = LHS ptr, already advanced by 16
-// %edi = RHS ptr, already advanced by 16
-// %eax = complemented compare vector (ie, 0 == equal)
-
-LDifferent:
- bsf %eax,%edx // which byte differed?
- subl $16,%esi // point to byte 0 while we wait for bit scan
- subl $16,%edi
- movzb (%esi,%edx),%eax // get LHS byte
- movzb (%edi,%edx),%ecx // get RHS byte
- subl %ecx,%eax // compute difference (ie, return value)
- popl %edi
- popl %esi
- ret
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse42)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse3x)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse2)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, scalar)
-
-static const platfunc_descriptor *memcpy_platfunc_descriptors[] = {
- PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse42),
- PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse3x),
- PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse2),
- PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, scalar),
- 0
-};
-
-void *memcpy_chooser() __asm__("_memcpy");
-void *memcpy_chooser() {
- __asm__(".desc _memcpy, 0x100");
- return find_platform_function((const platfunc_descriptor **) memcpy_platfunc_descriptors);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse42)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse3x)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse2)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, scalar)
-
-static const platfunc_descriptor *memmove_platfunc_descriptors[] = {
- PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse42),
- PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse3x),
- PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse2),
- PLATFUNC_DESCRIPTOR_REFERENCE(memmove, scalar),
- 0
-};
-
-void *memmove_chooser() __asm__("_memmove");
-void *memmove_chooser() {
- __asm__(".desc _memmove, 0x100");
- return find_platform_function((const platfunc_descriptor **) memmove_platfunc_descriptors);
-}
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-
-
-/* This file contains the following functions:
- *
- * void *memset(void *b, int c, size_t len);
- * void memset_pattern4(void *b, const void *c4, size_t len);
- * void memset_pattern8(void *b, const void *c8, size_t len);
- * void memset_pattern16(void *b, const void *c16, size_t len);
- *
- * Calls of memset() with c==0 are routed to the bzero() routine. Most of the
- * others go to _memset_pattern, which is entered as follows:
- * %edi = ptr to memory to set (aligned)
- * %edx = length (which can be short, though we bias in favor of long operands)
- * %xmm0 = the pattern to store
- * Return conditions:
- * %eax, %edi, %esi, %ecx, and %edx all trashed
- *
- * NB: we avoid "stos" family of instructions (stosl, stosb), as they are very slow
- * on P4s and probably other processors.
- */
-
- #define kShort 255 // for nonzero memset(), too short for commpage
-
-
- .text
- .globl _memset
- .align 2
-_memset: // void *memset(void *b, int c, size_t len);
- movl 8(%esp),%eax // get 1-byte pattern
- movl 12(%esp),%edx // get length
- andl $0xFF,%eax // (c==0) ?
- jnz LNonzero // not a bzero
-
- movl %edx,8(%esp) // put count where bzero() expects it
- jmp _bzero // enter _bzero
-
-
- // Handle memset of a nonzero value.
-
-LNonzero:
- pushl %edi // save a few nonvolatiles
- pushl %esi
- movl %eax,%esi // replicate byte in %al into all four bytes
- movl 12(%esp),%edi // point to operand
- shll $8,%esi
- orl %esi,%eax
- movl %eax,%esi
- shll $16,%esi
- orl %esi,%eax // now %eax has "c" in all 4 bytes
- cmpl $(kShort),%edx // is operand too short for SSE?
- ja LCallCommpage // no
-
-// Nonzero memset() too short to call commpage.
-// %eax = replicated 4-byte pattern
-// %edi = ptr
-// %edx = length (<= kShort)
-
- cmpl $16,%edx // long enough to word align?
- jge 3f // yes
- test %edx,%edx // length==0?
- jz 6f
-1:
- movb %al,(%edi) // pack in a byte
- inc %edi
- dec %edx
- jnz 1b
- jmp 6f
-2:
- movb %al,(%edi) // pack in a byte
- inc %edi
- dec %edx
-3:
- test $3,%edi // is ptr doubleword aligned?
- jnz 2b // no
- movl %edx,%ecx // copy length
- shrl $2,%edx // #doublewords to store
-4:
- movl %eax,(%edi) // store aligned doubleword
- addl $4,%edi
- dec %edx
- jnz 4b
- andl $3,%ecx // any leftover bytes?
- jz 6f // no
-5:
- movb %al,(%edi) // pack in a byte
- inc %edi
- dec %ecx
- jnz 5b
-6:
- movl 12(%esp),%eax // get return value (ie, original ptr)
- popl %esi
- popl %edi
- ret
-
-// Nonzero memset() is long enough to call commpage.
-// %eax = replicated 4-byte pattern
-// %edi = ptr
-// %edx = length (> kShort)
-
-LCallCommpage:
- movd %eax,%xmm0 // move %eax to low 4 bytes of %xmm0
- pshufd $(0x00),%xmm0,%xmm0 // replicate across the vector
- movl %edi,%ecx // copy dest ptr
- negl %ecx
- andl $15,%ecx // get #bytes to align ptr
- jz 2f // skip if already aligned
- subl %ecx,%edx // decrement length
-1:
- movb %al,(%edi) // pack in a byte
- inc %edi
- dec %ecx
- jnz 1b
-2: // ptr aligned, length long enough to justify
- call _memset_pattern // call commpage to do the heavy lifting
- movl 12(%esp),%eax // get return value (ie, original ptr)
- popl %esi
- popl %edi
- ret
-
-
-// Handle memset of a 16-byte pattern.
-
- .globl _memset_pattern16
- .align 2, 0x90
-_memset_pattern16: // void memset_pattern16(void *b, const void *c16, size_t len);
- pushl %edi
- pushl %esi
- movl 20(%esp),%edx // get length
- movl 16(%esp),%esi // get ptr to 16-byte pattern
- movl 12(%esp),%edi // point to operand
- movdqu (%esi),%xmm0 // load the pattern
- jmp LAlignPtr
-
-
-// Handle memset of an 8-byte pattern.
-
- .globl _memset_pattern8
- .align 2, 0x90
-_memset_pattern8: // void memset_pattern8(void *b, const void *c8, size_t len);
- pushl %edi
- pushl %esi
- movl 20(%esp),%edx // get length
- movl 16(%esp),%esi // get ptr to 8-byte pattern
- movl 12(%esp),%edi // point to operand
- movq (%esi),%xmm0 // load pattern into low 8 bytes
- punpcklqdq %xmm0,%xmm0 // replicate into all 16
- jmp LAlignPtr
-
-// Handle memset of a 4-byte pattern.
-
- .globl _memset_pattern4
- .align 2, 0x90
-_memset_pattern4: // void memset_pattern4(void *b, const void *c4, size_t len);
- pushl %edi
- pushl %esi
- movl 20(%esp),%edx // get length
- movl 16(%esp),%esi // get ptr to 4-byte pattern
- movl 12(%esp),%edi // point to operand
- movd (%esi),%xmm0 // load pattern into low 4 bytes
- pshufd $(0x00),%xmm0,%xmm0 // replicate the 4 bytes across the vector
-
-
-// Align ptr if necessary. We must rotate the pattern right for each byte we
-// store while aligning the ptr. Since there is no rotate instruction in SSE3,
-// we have to synthesize the rotates.
-// %edi = ptr
-// %edx = length
-// %xmm0 = pattern
-
-LAlignPtr: // NB: can drop down to here!
- cmpl $100,%edx // long enough to bother aligning ptr?
- movl %edi,%ecx // copy ptr
- jb LReady // not long enough
- negl %ecx
- andl $15,%ecx // get #bytes to align ptr
- jz LReady // already aligned
- subl %ecx,%edx // adjust length
-
- test $1,%cl // 1-byte store required?
- movd %xmm0,%eax // get 4 low bytes in %eax
- jz 2f // no
- movdqa %xmm0,%xmm1 // copy pattern so we can shift in both directions
- movb %al,(%edi) // pack in the low-order byte
- psrldq $1,%xmm0 // shift pattern right 1 byte
- inc %edi
- pslldq $15,%xmm1 // shift pattern left 15 bytes
- shrl $8,%eax // in case 2-byte store is required
- por %xmm1,%xmm0 // complete right rotate of pattern by 1 byte
-2:
- test $2,%cl // 2-byte store required?
- jz 4f // no
- psrldq $2,%xmm0 // shift pattern down 2 bytes
- movw %ax,(%edi) // pack in next two bytes
- pinsrw $7,%eax,%xmm0 // insert low word of %eax into high word of %xmm0
- addl $2,%edi // adjust ptr
-4:
- test $4,%cl // 4-byte store required?
- jz 8f // no
- movd %xmm0,(%edi) // store low 4 bytes of %xmm0
- pshufd $(0x39),%xmm0,%xmm0 // rotate %xmm0 right 4 bytes (mask == 00 11 10 01)
- addl $4,%edi // adjust ptr
-8:
- test $8,%cl // 8-byte store required?
- jz LReady // no
- movq %xmm0,(%edi) // store low 8 bytes of %xmm0
- pshufd $(0x4e),%xmm0,%xmm0 // rotate %xmm0 right 8 bytes (mask == 01 00 11 10)
- addl $8,%edi // adjust ptr
-
-// Ptr is aligned if practical, we're ready to call commpage to do the heavy lifting.
-
-LReady:
- call _memset_pattern // call commpage to do the heavy lifting
- popl %esi
- popl %edi
- ret
+++ /dev/null
-/*
- * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-/* The common path for nonzero memset and the memset_pattern routines,
- * tuned for Pentium-M class processors with SSE2 and 64-byte cache lines.
- * This is used by the following functions:
- *
- * void *memset(void *b, int c, size_t len); // when c!=0
- * void memset_pattern4(void *b, const void *c4, size_t len);
- * void memset_pattern8(void *b, const void *c8, size_t len);
- * void memset_pattern16(void *b, const void *c16, size_t len);
- *
- * Note bzero() and memset() of 0 are handled separately.
- */
-
-#define kShort 63
-#define kVeryLong (1024*1024)
-
-// Initial entry from Libc with parameters passed in registers. Although we
-// correctly handle misaligned ptrs and short operands, they are inefficient.
-// Therefore our caller should filter out short operands and exploit local
-// knowledge (ie, original pattern length) to align the ptr if possible.
-// When called, we expect:
-// %edi = ptr to memory to set (not necessarily aligned)
-// %edx = length (may be short or even 0)
-// %xmm0 = the pattern to store
-// Return conditions:
-// %eax, %edi, %esi, %ecx, and %edx all trashed
-
- .align 5
- .private_extern _memset_pattern
-_memset_pattern:
- cmpl $(kShort),%edx // long enough to bother aligning?
- ja LNotShort // yes
- jmp LShort // no
-
-// Here for short operands or the end of long ones.
-// %edx = length
-// %edi = ptr (may not be not aligned)
-// %xmm0 = pattern
-
-LUnalignedStore16:
- movdqu %xmm0,(%edi) // stuff in another 16 bytes
- subl $16,%edx
- addl $16,%edi
-LShort:
- cmpl $16,%edx // room for another vector?
- jge LUnalignedStore16 // yes
-LLessThan16: // here at end of copy with < 16 bytes remaining
- test $8,%dl // 8-byte store required?
- jz 2f // no
- movq %xmm0,(%edi) // pack in 8 low bytes
- psrldq $8,%xmm0 // then shift vector down 8 bytes
- addl $8,%edi
-2:
- test $4,%dl // 4-byte store required?
- jz 3f // no
- movd %xmm0,(%edi) // pack in 4 low bytes
- psrldq $4,%xmm0 // then shift vector down 4 bytes
- addl $4,%edi
-3:
- andl $3,%edx // more to go?
- jz 5f // no
- movd %xmm0,%eax // move remainders out into %eax
-4: // loop on up to three bytes
- movb %al,(%edi) // pack in next byte
- shrl $8,%eax // shift next byte into position
- inc %edi
- dec %edx
- jnz 4b
-5: ret
-
-// Long enough to justify aligning ptr. Note that we have to rotate the
-// pattern to account for any alignment. We do this by doing two unaligned
-// stores, and then an aligned load from the middle of the two stores.
-// This will stall on store forwarding alignment mismatch, and the unaligned
-// stores can be pretty slow too, but the alternatives aren't any better.
-// Fortunately, in most cases our caller has already aligned the ptr.
-// %edx = length (> kShort)
-// %edi = ptr (may not be aligned)
-// %xmm0 = pattern
-
-LNotShort:
- movl %edi,%ecx // copy dest ptr
- negl %ecx
- andl $15,%ecx // mask down to #bytes to 16-byte align
- jz LAligned // skip if already aligned
- movdqu %xmm0,(%edi) // store 16 unaligned bytes
- movdqu %xmm0,16(%edi) // and 16 more, to be sure we have an aligned chunk
- addl %ecx,%edi // now point to the aligned chunk
- subl %ecx,%edx // adjust remaining count
- movdqa (%edi),%xmm0 // get the rotated pattern (probably stalling)
- addl $16,%edi // skip past the aligned chunk
- subl $16,%edx
-
-// Set up for 64-byte loops.
-// %edx = length remaining
-// %edi = ptr (aligned)
-// %xmm0 = rotated pattern
-
-LAligned:
- movl %edx,%ecx // copy length remaining
- andl $63,%edx // mask down to residual length (0..63)
- andl $-64,%ecx // %ecx <- #bytes we will zero in by-64 loop
- jz LNoMoreChunks // no 64-byte chunks
- addl %ecx,%edi // increment ptr by length to move
- cmpl $(kVeryLong),%ecx // long enough to justify non-temporal stores?
- jge LVeryLong // yes
- negl %ecx // negate length to move
- jmp 1f
-
-// Loop over 64-byte chunks, storing into cache.
-
- .align 4,0x90 // keep inner loops 16-byte aligned
-1:
- movdqa %xmm0,(%edi,%ecx)
- movdqa %xmm0,16(%edi,%ecx)
- movdqa %xmm0,32(%edi,%ecx)
- movdqa %xmm0,48(%edi,%ecx)
- addl $64,%ecx
- jne 1b
-
- jmp LNoMoreChunks
-
-// Very long operands: use non-temporal stores to bypass cache.
-
-LVeryLong:
- negl %ecx // negate length to move
- jmp 1f
-
- .align 4,0x90 // keep inner loops 16-byte aligned
-1:
- movntdq %xmm0,(%edi,%ecx)
- movntdq %xmm0,16(%edi,%ecx)
- movntdq %xmm0,32(%edi,%ecx)
- movntdq %xmm0,48(%edi,%ecx)
- addl $64,%ecx
- jne 1b
-
- sfence // required by non-temporal stores
- jmp LNoMoreChunks
-
-// Handle leftovers: loop by 16.
-// %edx = length remaining (<64)
-// %edi = ptr (aligned)
-// %xmm0 = rotated pattern
-
-LLoopBy16:
- movdqa %xmm0,(%edi) // pack in 16 more bytes
- subl $16,%edx // decrement count
- addl $16,%edi // increment ptr
-LNoMoreChunks:
- cmpl $16,%edx // more to go?
- jge LLoopBy16 // yes
- jmp LLessThan16 // handle up to 15 remaining bytes
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// ***************
-// * S T R C M P *
-// ***************
-//
-// int strcmp(const char *s1, const char *s2);
-//
-// We optimize the compare by doing it in parallel, using SSE. This introduces
-// a complication: if we blindly did vector loads from both sides until
-// finding a difference (or 0), we might get a spurious page fault by
-// reading bytes past the difference. To avoid this, we never do a load
-// that crosses a page boundary.
-
- .text
- .globl _strcmp
-
- .align 4
-_strcmp: // int strcmp(const char *s1,const char *s2);
- pushl %esi
- pushl %edi
- movl 12(%esp),%esi // get LHS ptr
- movl 16(%esp),%edi // get RHS ptr
-
-
-// In order to avoid spurious page faults, we loop over:
-//
-// min( bytes_in_LHS_page, bytes_in_RHS_page) >> 4
-//
-// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte
-// comparison until reaching the next page, then resume the vector comparison.
-// %esi = LHS ptr
-// %edi = RHS ptr
-
-LNextChunk:
- movl %esi,%eax // copy ptrs
- movl %edi,%edx
- andl $4095,%eax // mask down to page offsets
- andl $4095,%edx
- cmpl %eax,%edx // which is bigger?
- cmova %edx,%eax // %eax = max(LHS offset, RHS offset);
- movl $4096,%edx
- subl %eax,%edx // get #bytes to next page crossing
- movl %edx,%eax
- shrl $4,%edx // get #chunks till end of operand or page
- jnz LLoopOverChunks // enter vector loop
- movl %eax,%edx // no chunks...
- jmp LLoopOverBytes // ...so loop over bytes until page end
-
-
-// Loop over bytes.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %edx = byte count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%esi),%eax // get LHS byte
- movzb (%edi),%ecx // get RHS byte
- inc %esi
- inc %edi
- testl %eax,%eax // 0?
- jz LExit0 // yes, we're done
- subl %ecx,%eax // compare them
- jnz LExit // done if not equal
- dec %edx // more to go?
- jnz LLoopOverBytes
-
- jmp LNextChunk // we've come to end of page
-
-
-// Loop over 16-byte chunks.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %edx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%esi),%xmm1 // get LHS
- movdqu (%edi),%xmm2 // get RHS
- pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads
- addl $16,%esi
- pcmpeqb %xmm1,%xmm2 // compare LHS to RHS
- pcmpeqb %xmm1,%xmm0 // compare LHS to 0s
- addl $16,%edi
- pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS
- pmovmskb %xmm0,%ecx // get result mask for 0 check
- xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal"
- orl %ecx,%eax // combine the masks and check for 1-bits
- jnz LFoundDiffOr0 // we found differing bytes or a 0-byte
- dec %edx // more to go?
- jnz LLoopOverChunks
-
- jmp LNextChunk // compare up to next page boundary
-
-
-// Found a zero and/or a difference in vector compare.
-// %esi = LHS ptr, already advanced by 16
-// %edi = RHS ptr, already advanced by 16
-// %eax = bit n set if bytes n differed or were 0
-
-LFoundDiffOr0:
- bsf %eax,%edx // which byte differed or was 0?
- subl $16,%esi // point to start of vectors while we wait for bit scan
- subl $16,%edi
- movzb (%esi,%edx),%eax // get LHS byte
- movzb (%edi,%edx),%ecx // get RHS byte
- subl %ecx,%eax // compute difference (ie, return value)
- popl %edi
- popl %esi
- ret
-
-
-// Found a zero and/or difference in byte loop.
-// %eax = LHS byte
-// %ecx = RHS byte
-
-LExit0:
- subl %ecx,%eax // compute difference (ie, return value)
-LExit: // here with difference already in %eax
- popl %edi
- popl %esi
- ret
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// *****************
-// * S T R N C M P *
-// *****************
-//
-// int strncmp(const char *s1, const char *s2, size_t len);
-//
-// We optimize the compare by doing it vector parallel. This introduces
-// a complication: if we blindly did vector loads from both sides until
-// finding a difference (or 0), we might get a spurious page fault by
-// reading bytes past the difference. To avoid this, we never do a load
-// that crosses a page boundary.
-
-#define kShort 20 // too short for vectors (must be >16)
-
- .text
- .globl _strncmp
-
- .align 4
-_strncmp: // int strncmp(const char *s1, const char *s2, size_t len);
- pushl %esi
- pushl %edi
- movl 20(%esp),%ecx // get length
- movl 12(%esp),%esi // get LHS ptr
- movl 16(%esp),%edi // get RHS ptr
- push %ebx
- cmpl $(kShort),%ecx // worth accelerating?
- ja LNotShort // yes
-
-
-// Too short to bother with parallel compares. Loop over bytes.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length (<= kShort)
-
-LShort:
- testl %ecx,%ecx // 0-length?
- jnz LShortLoop // no
- jmp LReturn0 // yes, return 0
- .align 4,0x90 // align inner loops to optimize I-fetch
-LShortLoop: // loop over bytes
- movzb (%esi),%eax // get LHS byte
- movzb (%edi),%ebx // get RHS byte
- incl %esi
- incl %edi
- testl %eax,%eax // LHS==0 ?
- jz LNotEqual // yes, this terminates comparison
- subl %ebx,%eax // compare them
- jnz LExit // done if not equal
- decl %ecx // decrement length
- jnz LShortLoop
-LReturn0:
- xorl %eax,%eax // all bytes equal, so return 0
-LExit: // return value is in %eax
- popl %ebx
- popl %edi
- popl %esi
- ret
-
-LNotEqual: // LHS in eax, RHS in ebx
- subl %ebx,%eax // generate return value (nonzero)
- popl %ebx
- popl %edi
- popl %esi
- ret
-
-
-// Loop over bytes until we reach end of a page.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length remaining after end of loop (ie, already adjusted)
-// %edx = #bytes until next page (1..15)
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%esi),%eax // get LHS byte
- movzb (%edi),%ebx // get RHS byte
- inc %esi
- inc %edi
- testl %eax,%eax // LHS==0 ?
- jz LNotEqual // yes, this terminates comparison
- subl %ebx,%eax // compare them
- jnz LExit // done if not equal
- dec %edx // more to go?
- jnz LLoopOverBytes
-
-
-// Long enough to justify overhead of setting up vector compares. In order to
-// avoid spurious page faults, we loop over:
-//
-// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4
-//
-// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte
-// comparison until reaching the next page, then resume the vector comparison.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length (> kShort)
-
-LNotShort:
- movl %esi,%eax // copy ptrs
- movl %edi,%edx
- andl $4095,%eax // mask down to page offsets
- andl $4095,%edx
- cmpl %eax,%edx // which is bigger?
- cmova %edx,%eax // %eax = max(LHS offset, RHS offset);
- movl $4096,%edx
- subl %eax,%edx // get #bytes to next page crossing
- cmpl %ecx,%edx // will operand run out first?
- cmova %ecx,%edx // get min(length remaining, bytes to page end)
- movl %edx,%eax
- shrl $4,%edx // get #chunks till end of operand or page
- jnz LLoopOverChunks // enter vector loop
-
-// Too near page end for vectors.
-
- subl %eax,%ecx // adjust length remaining
- movl %eax,%edx // %edx <- #bytes to page end
- cmpl $(kShort),%ecx // will there be enough after we cross page for vectors?
- ja LLoopOverBytes // yes
- addl %eax,%ecx // no, restore total length remaining
- jmp LShortLoop // compare rest byte-by-byte (%ecx != 0)
-
-
-// Loop over 16-byte chunks.
-// %esi = LHS ptr
-// %edi = RHS ptr
-// %ecx = length remaining
-// %edx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%esi),%xmm1 // get LHS
- movdqu (%edi),%xmm2 // get RHS
- pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads
- addl $16,%esi
- pcmpeqb %xmm1,%xmm2 // compare LHS to RHS
- pcmpeqb %xmm1,%xmm0 // compare LHS to 0s
- addl $16,%edi
- pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS
- pmovmskb %xmm0,%ebx // get result mask for 0 check
- subl $16,%ecx // decrement length remaining
- xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal"
- orl %ebx,%eax // combine the masks and check for 1-bits
- jnz LFoundDiffOr0 // we found differing bytes or a 0-byte
- dec %edx // more to go?
- jnz LLoopOverChunks // yes
-
- cmpl $(kShort),%ecx // a lot more to compare?
- jbe LShort // no
- jmp LNotShort // compute distance to next page crossing etc
-
-
-// Found a zero and/or a difference in vector compare.
-// %esi = LHS ptr, already advanced by 16
-// %edi = RHS ptr, already advanced by 16
-// %eax = bit n set if bytes n differed or were 0
-
-LFoundDiffOr0:
- bsf %eax,%edx // which byte differed or was 0?
- subl $16,%esi // point to start of vectors while we wait for bit scan
- subl $16,%edi
- movzb (%esi,%edx),%eax // get LHS byte
- movzb (%edi,%edx),%ecx // get RHS byte
- popl %ebx
- popl %edi
- subl %ecx,%eax // compute difference (ie, return value)
- popl %esi
- ret
// %ecx = buffer length remaining
LZeroBuffer:
- pushl %ecx // remaining buffer size
- pushl %edi // ptr to 1st unstored byte
+// The stack currently is aligned to 4 mod 16 (it was 0 mod 16 at the time of
+// the call, and the return address, edi, and esi have been pushed). It needs
+// to aligned 0 mod 16 when we call bzero, so we subtract 20 from esp (not 4
+// because we need to have 8 bytes for the arguments to bzero).
+ subl $20,%esp
+ movl %ecx,4(%esp) // remaining buffer size
+ movl %edi, (%esp) // pointer to first unstored byte
call _bzero
- addl $8,%esp // pop off the arguments
+ addl $20,%esp
LDone:
movl 12(%esp),%eax // original dest ptr is return value
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-#include <architecture/i386/asm_help.h>
-
-#define ATOMIC_UP 0
-#define ATOMIC_MP 1
-#define ATOMIC_RET_ORIG 0
-#define ATOMIC_RET_NEW 1
-
-// compare and exchange 32-bit
-// xchg32 <new> <dst> <mp>
-.macro xchg32
- .if $2 == ATOMIC_MP
- lock
- .endif
- cmpxchgl $0, ($1)
-.endm
-
-// compare and exchange 64-bit
-// xchg64 <dst> <mp>
-.macro xchg64
- .if $1 == ATOMIC_MP
- lock
- .endif
- cmpxchg8b ($0)
-.endm
-
-
-// int32_t OSAtomicAdd32(int32_t theAmount, volatile int32_t *theValue);
-#define ATOMIC_ARITHMETIC(instr, orig, mp) \
- movl 8(%esp), %ecx /* load 2nd arg ptr into ecx */ ;\
- movl (%ecx), %eax /* load contents of ecx into eax */ ;\
-1: movl 4(%esp), %edx /* load 1st arg into edx */ ;\
- instr %eax, %edx /* do the operation */ ;\
- xchg32 %edx, %ecx, mp /* old in %eax, new in %edx, exchange into %ecx */ ;\
- jnz 1b /* go back if we failed to exchange */ ;\
- .if orig == ATOMIC_RET_NEW ;\
- movl %edx, %eax /* return new value */ ;\
- .endif
-
-// bool OSAtomicTestAndSet(uint32_t n, volatile void *theAddress);
-#define ATOMIC_BIT_OP(instr, mp) \
- movl 4(%esp), %eax ;\
- movl 8(%esp), %edx ;\
- shldl $3,%edx,%ecx /* save top 3 bits of address in %ecx */ ;\
- shll $3,%edx ;\
- xorl $7,%eax /* bit position is numbered big endian so convert to little endian */ ;\
- addl %eax,%edx /* generate bit address */ ;\
- adcl $0,%ecx /* handle carry out of lower half of address */ ;\
- movl %edx,%eax /* copy lower half of bit address */ ;\
- andl $31,%eax /* keep bit offset in range 0..31 */ ;\
- xorl %eax,%edx /* 4-byte align address */ ;\
- shrdl $3,%ecx,%edx /* restore 32-bit byte address in %edx */ ;\
- .if mp == ATOMIC_MP ;\
- lock ;\
- .endif ;\
- instr %eax, (%edx) ;\
- setc %al ;\
- movzbl %al,%eax // widen in case caller assumes we return an int
-
-// int64_t OSAtomicAdd64(int64_t theAmount, volatile int64_t *theValue);
-#define ATOMIC_ADD64(mp) \
- pushl %ebx ;\
- pushl %esi ;\
- movl 20(%esp), %esi ;\
- movl 0(%esi), %eax ;\
- movl 4(%esi), %edx ;\
-1: movl 12(%esp), %ebx ;\
- movl 16(%esp), %ecx ;\
- addl %eax, %ebx ;\
- adcl %edx, %ecx ;\
- xchg64 %esi, mp ;\
- jnz 1b ;\
- movl %ebx, %eax ;\
- movl %ecx, %edx ;\
- popl %esi ;\
- popl %ebx
-
- .text
-
-PLATFUNC_FUNCTION_START(OSAtomicAnd32, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicAnd32Barrier, up, 32, 2)
- ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Barrier, mp, 32, 2)
- ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_MP)
- ret
-
-PLATFUNC_FUNCTION_START(OSAtomicOr32, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicOr32Barrier, up, 32, 2)
- ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Barrier, mp, 32, 2)
- ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_MP)
- ret
-
-PLATFUNC_FUNCTION_START(OSAtomicXor32, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicXor32Barrier, up, 32, 2)
- ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Barrier, mp, 32, 2)
- ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_MP)
- ret
-
-PLATFUNC_FUNCTION_START(OSAtomicAnd32Orig, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicAnd32OrigBarrier, up, 32, 2)
- ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Orig, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32OrigBarrier, mp, 32, 2)
- ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_MP)
- ret
-
-PLATFUNC_FUNCTION_START(OSAtomicOr32Orig, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicOr32OrigBarrier, up, 32, 2)
- ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Orig, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32OrigBarrier, mp, 32, 2)
- ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_MP)
- ret
-
-PLATFUNC_FUNCTION_START(OSAtomicXor32Orig, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicXor32OrigBarrier, up, 32, 2)
- ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Orig, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32OrigBarrier, mp, 32, 2)
- ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_MP)
- ret
-
-// bool OSAtomicCompareAndSwapInt(int oldValue, int newValue, volatile int *theValue);
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtr, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtrBarrier, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapInt, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapIntBarrier, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLong, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLongBarrier, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32Barrier, up, 32, 2)
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl 12(%esp), %ecx
- xchg32 %edx, %ecx, ATOMIC_UP
- sete %al
- movzbl %al,%eax // widen in case caller assumes we return an int
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtr, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtrBarrier, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapInt, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapIntBarrier, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLong, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLongBarrier, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32Barrier, mp, 32, 2)
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl 12(%esp), %ecx
- xchg32 %edx, %ecx, ATOMIC_MP
- sete %al
- movzbl %al,%eax // widen in case caller assumes we return an int
- ret
-
-// bool OSAtomicCompareAndSwap64(int64_t oldValue, int64_t newValue, volatile int64_t *theValue);
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64Barrier, up, 32, 2)
- pushl %ebx // push out spare stuff for space
- pushl %esi
- movl 12(%esp), %eax // load in 1st 64-bit parameter
- movl 16(%esp), %edx
- movl 20(%esp), %ebx // load in 2nd 64-bit parameter
- movl 24(%esp), %ecx
- movl 28(%esp), %esi // laod in destination address
- xchg64 %esi, ATOMIC_UP // compare and swap 64-bit
- sete %al
- movzbl %al,%eax // widen in case caller assumes we return an int
- popl %esi
- popl %ebx
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64Barrier, mp, 32, 2)
- pushl %ebx // push out spare stuff for space
- pushl %esi
- movl 12(%esp), %eax // load in 1st 64-bit parameter
- movl 16(%esp), %edx
- movl 20(%esp), %ebx // load in 2nd 64-bit parameter
- movl 24(%esp), %ecx
- movl 28(%esp), %esi // laod in destination address
- xchg64 %esi, ATOMIC_MP // compare and swap 64-bit
- sete %al
- movzbl %al,%eax // widen in case caller assumes we return an int
- popl %esi
- popl %ebx
- ret
-
-PLATFUNC_FUNCTION_START(OSAtomicAdd32, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicAdd32Barrier, up, 32, 2)
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl %eax, %ecx
- xaddl %eax, (%edx)
- addl %ecx, %eax
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32Barrier, mp, 32, 2)
- movl 4(%esp), %eax
- movl 8(%esp), %edx
- movl %eax, %ecx
- lock
- xaddl %eax, (%edx)
- addl %ecx, %eax
- ret
-
-PLATFUNC_FUNCTION_START(OSAtomicAdd64, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicAdd64Barrier, up, 32, 2)
- ATOMIC_ADD64(ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64Barrier, mp, 32, 2)
- ATOMIC_ADD64(ATOMIC_MP)
- ret
-
-PLATFUNC_FUNCTION_START(OSAtomicTestAndSet, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicTestAndSetBarrier, up, 32, 2)
- ATOMIC_BIT_OP(btsl, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSet, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSetBarrier, mp, 32, 2)
- ATOMIC_BIT_OP(btsl, ATOMIC_MP)
- ret
-
-PLATFUNC_FUNCTION_START(OSAtomicTestAndClear, up, 32, 2)
-PLATFUNC_FUNCTION_START(OSAtomicTestAndClearBarrier, up, 32, 2)
- ATOMIC_BIT_OP(btrl, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClear, mp, 32, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClearBarrier, mp, 32, 2)
- ATOMIC_BIT_OP(btrl, ATOMIC_MP)
- ret
-
-// OSMemoryBarrier()
-// These are used both in 32 and 64-bit mode. We use a fence even on UP
-// machines, so this function can be used with nontemporal stores.
-
-PLATFUNC_FUNCTION_START_GENERIC(OSMemoryBarrier, all, 32, 4)
- lock
- addl $0,(%esp)
- ret
-PLATFUNC_DESCRIPTOR(OSMemoryBarrier,all,0,kHasSSE2);
-
-PLATFUNC_FUNCTION_START(OSMemoryBarrier, sse2, 32, 4)
- mfence
- ret
-PLATFUNC_DESCRIPTOR(OSMemoryBarrier,sse2,kHasSSE2,0);
-
- /*
- * typedef volatile struct {
- * void *opaque1; <-- ptr to 1st queue element or null
- * long opaque2; <-- generation count
- * } OSQueueHead;
- *
- * void OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset);
- */
-PLATFUNC_FUNCTION_START(OSAtomicEnqueue, up, 32, 2)
- pushl %edi
- pushl %esi
- pushl %ebx
- movl 16(%esp),%edi // %edi == ptr to list head
- movl 20(%esp),%ebx // %ebx == new
- movl 24(%esp),%esi // %esi == offset
- movl (%edi),%eax // %eax == ptr to 1st element in Q
- movl 4(%edi),%edx // %edx == current generation count
-1: movl %eax,(%ebx,%esi)// link to old list head from new element
- movl %edx,%ecx
- incl %ecx // increment generation count
- xchg64 %edi, ATOMIC_UP // ...push on new element
- jnz 1b
- popl %ebx
- popl %esi
- popl %edi
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicEnqueue, mp, 32, 2)
- pushl %edi
- pushl %esi
- pushl %ebx
- movl 16(%esp),%edi // %edi == ptr to list head
- movl 20(%esp),%ebx // %ebx == new
- movl 24(%esp),%esi // %esi == offset
- movl (%edi),%eax // %eax == ptr to 1st element in Q
- movl 4(%edi),%edx // %edx == current generation count
-1: movl %eax,(%ebx,%esi)// link to old list head from new element
- movl %edx,%ecx
- incl %ecx // increment generation count
- xchg64 %edi, ATOMIC_MP // ...push on new element
- jnz 1b
- popl %ebx
- popl %esi
- popl %edi
- ret
-
-/* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */
-PLATFUNC_FUNCTION_START(OSAtomicDequeue, up, 32, 2)
- pushl %edi
- pushl %esi
- pushl %ebx
- movl 16(%esp),%edi // %edi == ptr to list head
- movl 20(%esp),%esi // %esi == offset
- movl (%edi),%eax // %eax == ptr to 1st element in Q
- movl 4(%edi),%edx // %edx == current generation count
-1: testl %eax,%eax // list empty?
- jz 2f // yes
- movl (%eax,%esi),%ebx // point to 2nd in Q
- movl %edx,%ecx
- incl %ecx // increment generation count
- xchg64 %edi, ATOMIC_UP // ...pop off 1st element
- jnz 1b
-2: popl %ebx
- popl %esi
- popl %edi
- ret // ptr to 1st element in Q still in %eax
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicDequeue, mp, 32, 2)
- pushl %edi
- pushl %esi
- pushl %ebx
- movl 16(%esp),%edi // %edi == ptr to list head
- movl 20(%esp),%esi // %esi == offset
- movl (%edi),%eax // %eax == ptr to 1st element in Q
- movl 4(%edi),%edx // %edx == current generation count
-1: testl %eax,%eax // list empty?
- jz 2f // yes
- movl (%eax,%esi),%ebx // point to 2nd in Q
- movl %edx,%ecx
- incl %ecx // increment generation count
- xchg64 %edi, ATOMIC_MP // ...pop off 1st element
- jnz 1b
-2: popl %ebx
- popl %esi
- popl %edi
- ret // ptr to 1st element in Q still in %eax
-
-/*
- * typedef volatile struct {
- * void *opaque1; <-- ptr to first queue element or null
- * void *opaque2; <-- ptr to last queue element or null
- * int opaque3; <-- spinlock
- * } OSFifoQueueHead;
- *
- * void OSAtomicFifoEnqueue( OSFifoQueueHead *list, void *new, size_t offset);
- */
- .align 2
- .globl _OSAtomicFifoEnqueue
-_OSAtomicFifoEnqueue:
- pushl %edi
- pushl %esi
- pushl %ebx
- xorl %ebx,%ebx // clear "preemption pending" flag
- movl 16(%esp),%edi // %edi == ptr to list head
- movl 20(%esp),%esi // %esi == new
- EXTERN_TO_REG(_commpage_pfz_base,%ecx)
- movl (%ecx), %ecx
- addl $(_COMM_TEXT_PFZ_ENQUEUE_OFFSET), %ecx
- movl 24(%esp),%edx // %edx == offset
- call *%ecx
- testl %ebx,%ebx // pending preemption?
- jz 1f
- call _preempt
-1: popl %ebx
- popl %esi
- popl %edi
- ret
-
-/* void* OSAtomicFifoDequeue( OSFifoQueueHead *list, size_t offset); */
- .align 2
- .globl _OSAtomicFifoDequeue
-_OSAtomicFifoDequeue:
- pushl %edi
- pushl %esi
- pushl %ebx
- xorl %ebx,%ebx // clear "preemption pending" flag
- movl 16(%esp),%edi // %edi == ptr to list head
- PICIFY(_commpage_pfz_base)
- movl (%edx),%ecx
- movl 20(%esp),%edx // %edx == offset
- addl $(_COMM_TEXT_PFZ_DEQUEUE_OFFSET), %ecx
- call *%ecx
- testl %ebx,%ebx // pending preemption?
- jz 1f
- pushl %eax // save return value across sysenter
- call _preempt
- popl %eax
-1: popl %ebx
- popl %esi
- popl %edi
- ret // ptr to 1st element in Q still in %eax
-
-// Local Variables:
-// tab-width: 8
-// End:
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
- *
- * HISTORY
- * 20-Apr-92 Bruce Martin (bmartin@next.com)
- * Created from M68K sources.
- */
-
-/*
- * C library -- _setjmp, _longjmp
- *
- * _longjmp(a,v)
- * will generate a "return(v)" from
- * the last call to
- * _setjmp(a)
- * by restoring registers from the stack,
- * The previous signal state is NOT restored.
- *
- */
-
-#include <architecture/i386/asm_help.h>
-
-// The FP control word is actually two bytes, but there's no harm in
-// using four bytes for it and keeping the struct aligned.
-#define JB_FPCW 0
-#define JB_MASK 4
-#define JB_MXCSR 8
-#define JB_EBX 12
-#define JB_ONSTACK 16
-#define JB_EDX 20
-#define JB_EDI 24
-#define JB_ESI 28
-#define JB_EBP 32
-#define JB_ESP 36
-#define JB_SS 40
-#define JB_EFLAGS 44
-#define JB_EIP 48
-#define JB_CS 52
-#define JB_DS 56
-#define JB_ES 60
-#define JB_FS 64
-#define JB_GS 68
-
-LEAF(__setjmp, 0)
- movl 4(%esp), %ecx // jmp_buf (struct sigcontext *)
-
- // Build the jmp_buf
- fnstcw JB_FPCW(%ecx) // Save the FP control word
- stmxcsr JB_MXCSR(%ecx) // Save the MXCSR
- movl %ebx, JB_EBX(%ecx)
- movl %edi, JB_EDI(%ecx)
- movl %esi, JB_ESI(%ecx)
- movl %ebp, JB_EBP(%ecx)
-
- // EIP is set to the frame return address value
- movl (%esp), %eax
- movl %eax, JB_EIP(%ecx)
- // ESP is set to the frame return address plus 4
- leal 4(%esp), %eax
- movl %eax, JB_ESP(%ecx)
-
- // return 0
- xorl %eax, %eax
- ret
-
-
-LEAF(__longjmp, 0)
- fninit // Clear all FP exceptions
- movl 4(%esp), %ecx // jmp_buf (struct sigcontext *)
- movl 8(%esp), %eax // return value
- testl %eax, %eax
- jnz 1f
- incl %eax
-
- // general registers
-1: movl JB_EBX(%ecx), %ebx
- movl JB_ESI(%ecx), %esi
- movl JB_EDI(%ecx), %edi
- movl JB_EBP(%ecx), %ebp
- movl JB_ESP(%ecx), %esp
-
- fldcw JB_FPCW(%ecx) // Restore FP control word
- ldmxcsr JB_MXCSR(%ecx) // Restore the MXCSR
-
- cld // Make sure DF is reset
- jmp *JB_EIP(%ecx)
+++ /dev/null
-/*
- * Copyright (c) 2007, 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <sys/syscall.h>
-
-#if defined(__DYNAMIC__)
- .globl ___in_sigtramp
- .data
- .align 2
-___in_sigtramp:
- .space 4
-#endif
-
-#define UC_TRAD 1
-#define UC_FLAVOR 30
-
-/* Structure fields for ucontext and mcontext. */
-#define UCONTEXT_UC_MCONTEXT 28
-
-#define MCONTEXT_ES_EXCEPTION 0
-#define MCONTEXT_SS_EAX 12
-#define MCONTEXT_SS_EBX 16
-#define MCONTEXT_SS_ECX 20
-#define MCONTEXT_SS_EDX 24
-#define MCONTEXT_SS_EDI 28
-#define MCONTEXT_SS_ESI 32
-#define MCONTEXT_SS_EBP 36
-#define MCONTEXT_SS_ESP 40
-#define MCONTEXT_SS_EFLAGS 48
-#define MCONTEXT_SS_EIP 52
-
-/* register use:
- %ebp frame pointer
- %ebx Address of "L00000000001$pb"
- %esi uctx
-
-void
-_sigtramp(
- union __sigaction_u __sigaction_u,
- int sigstyle,
- int sig,
- siginfo_t *sinfo,
- ucontext_t *uctx
-)
-*/
-
- .globl __sigtramp
- .text
- .align 4,0x90
-__sigtramp:
-Lstart:
- /* Although this routine does not need any stack frame, various parts
- of the OS can't analyse the stack without them. */
- pushl %ebp
- movl %esp, %ebp
- subl $24, %esp
- movl 8(%ebp), %ecx # get '__sigaction_u'
-#if defined(__DYNAMIC__)
- call 0f
-"L00000000001$pb":
-0:
- popl %ebx
- incl ___in_sigtramp-"L00000000001$pb"(%ebx)
-#endif
- movl 16(%ebp), %edx # get 'sig'
- movl 20(%ebp), %eax # get 'sinfo'
- movl 24(%ebp), %esi # get 'uctx'
- /* Call the signal handler.
- Some variants are not supposed to get the last two parameters,
- but the test to prevent this is more expensive than just passing
- them. */
- movl %esi, 8(%esp)
- movl %eax, 4(%esp)
- movl %edx, (%esp)
- call *%ecx
-#if defined(__DYNAMIC__)
- decl ___in_sigtramp-"L00000000001$pb"(%ebx)
-#endif
- movl %esi, 4(%esp)
- movl $ UC_FLAVOR, 8(%esp)
- movl $ SYS_sigreturn, %eax
- int $0x80
-Lend:
-
-/* DWARF unwind table #defines. */
-#define DW_CFA_advance_loc_4 0x44
-#define DW_CFA_def_cfa 0x0c
-#define DW_CFA_def_cfa_expression 0x0F
-#define DW_CFA_expression 0x10
-#define DW_CFA_val_expression 0x16
-#define DW_CFA_offset(column) 0x80+(column)
-
-/* DWARF expression #defines. */
-#define DW_OP_deref 0x06
-#define DW_OP_const1u 0x08
-#define DW_OP_dup 0x12
-#define DW_OP_drop 0x13
-#define DW_OP_over 0x14
-#define DW_OP_pick 0x15
-#define DW_OP_swap 0x16
-#define DW_OP_rot 0x17
-#define DW_OP_abs 0x19
-#define DW_OP_and 0x1a
-#define DW_OP_div 0x1b
-#define DW_OP_minus 0x1c
-#define DW_OP_mod 0x1d
-#define DW_OP_mul 0x1e
-#define DW_OP_neg 0x1f
-#define DW_OP_not 0x20
-#define DW_OP_or 0x21
-#define DW_OP_plus 0x22
-#define DW_OP_plus_uconst 0x23
-#define DW_OP_shl 0x24
-#define DW_OP_shr 0x25
-#define DW_OP_shra 0x26
-#define DW_OP_xor 0x27
-#define DW_OP_skip 0x2f
-#define DW_OP_bra 0x28
-#define DW_OP_eq 0x29
-#define DW_OP_ge 0x2A
-#define DW_OP_gt 0x2B
-#define DW_OP_le 0x2C
-#define DW_OP_lt 0x2D
-#define DW_OP_ne 0x2E
-#define DW_OP_lit(n) 0x30+(n)
-#define DW_OP_breg(n) 0x70+(n)
-#define DW_OP_deref_size 0x94
-
-/* The location expression we'll use. */
-
-#define loc_expr_for_reg(regno, offs) \
- .byte DW_CFA_expression, regno, 5 /* block length */, \
- DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \
- DW_OP_plus_uconst, offs
-
- /* Unwind tables. */
- .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
-EH_frame1:
- .set L$set$0,LECIE1-LSCIE1
- .long L$set$0 # Length of Common Information Entry
-LSCIE1:
- .long 0 # CIE Identifier Tag
- .byte 0x1 # CIE Version
- .ascii "zRS\0" # CIE Augmentation
- .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
- .byte 0x7c # sleb128 -4; CIE Data Alignment Factor
- .byte 0x8 # CIE RA Column
- .byte 0x1 # uleb128 0x1; Augmentation size
- .byte 0x10 # FDE Encoding (pcrel)
- .byte DW_CFA_def_cfa
- .byte 0x5 # uleb128 0x5
- .byte 0x4 # uleb128 0x4
- .byte DW_CFA_offset(8)
- .byte 0x1 # uleb128 0x1
- .byte DW_CFA_offset(8) // double DW_CFA_offset (eip, -4) tells linker to not make compact unwind
- .byte 0x1 # uleb128 0x1
- .align 2
-LECIE1:
- .globl _sigtramp.eh
-_sigtramp.eh:
-LSFDE1:
- .set L$set$1,LEFDE1-LASFDE1
- .long L$set$1 # FDE Length
-LASFDE1:
- .long LASFDE1-EH_frame1 # FDE CIE offset
- .long Lstart-. # FDE initial location
- .set L$set$2,Lend-Lstart
- .long L$set$2 # FDE address range
- .byte 0x0 # uleb128 0x0; Augmentation size
-
- /* Now for the expressions, which all compute
- uctx->uc_mcontext->register
- for each register.
-
- Describe even the registers that are not call-saved because they
- might be being used in the prologue to save other registers.
- Only integer registers are described at present. */
-
- loc_expr_for_reg (0, MCONTEXT_SS_EAX)
- loc_expr_for_reg (1, MCONTEXT_SS_ECX)
- loc_expr_for_reg (2, MCONTEXT_SS_EDX)
- loc_expr_for_reg (3, MCONTEXT_SS_EBX)
- loc_expr_for_reg (4, MCONTEXT_SS_EBP) # note that GCC switches
- loc_expr_for_reg (5, MCONTEXT_SS_ESP) # DWARF registers 4 & 5
- loc_expr_for_reg (6, MCONTEXT_SS_ESI)
- loc_expr_for_reg (7, MCONTEXT_SS_EDI)
- loc_expr_for_reg (9, MCONTEXT_SS_EFLAGS)
-
- /* The Intel architecture classifies exceptions into three categories,
- 'faults' which put the address of the faulting instruction
- in EIP, 'traps' which put the following instruction in EIP,
- and 'aborts' which don't typically report the instruction
- causing the exception.
-
- The traps are #BP and #OF. */
-
- .byte DW_CFA_val_expression, 8
- .set L$set$3,Lpc_end-Lpc_start
- .byte L$set$3
-Lpc_start:
- /* Push the mcontext address twice. */
- .byte DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref, DW_OP_dup
- /* Find the value of EIP. */
- .byte DW_OP_plus_uconst, MCONTEXT_SS_EIP, DW_OP_deref, DW_OP_swap
- /* Determine the exception type. */
- .byte DW_OP_plus_uconst, MCONTEXT_ES_EXCEPTION, DW_OP_deref
- /* Check whether it is #BP (3) or #OF (4). */
- .byte DW_OP_dup, DW_OP_lit(3), DW_OP_ne
- .byte DW_OP_swap, DW_OP_lit(4), DW_OP_ne, DW_OP_and
- /* If it is, then add 1 to the instruction address, so as to point
- within or past the faulting instruction. */
- .byte DW_OP_plus
-Lpc_end:
-
- /* The CFA will have been saved as the value of ESP (it is not
- ESP+4). */
- .byte DW_CFA_def_cfa_expression
- .set L$set$4,Lcfa_end-Lcfa_start
- .byte L$set$4
-Lcfa_start:
- .byte DW_OP_breg(6), UCONTEXT_UC_MCONTEXT, DW_OP_deref
- .byte DW_OP_plus_uconst, MCONTEXT_SS_ESP, DW_OP_deref
-Lcfa_end:
-
- .align 2
-LEFDE1:
-
- .subsections_via_symbols
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-#define RESOLVER_UP_MP(symbol) \
- PLATFUNC_DESCRIPTOR(symbol, up, kUP, 0); \
- PLATFUNC_DESCRIPTOR(symbol, mp, 0, kUP); \
- static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \
- PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \
- PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \
- 0 \
- }; \
- void* symbol ## _chooser() __asm__("_" #symbol); \
- void* symbol ## _chooser() { \
- __asm__(".symbol_resolver _" #symbol); \
- return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \
- }
-
-RESOLVER_UP_MP(OSAtomicAnd32)
-RESOLVER_UP_MP(OSAtomicAnd32Barrier)
-RESOLVER_UP_MP(OSAtomicOr32)
-RESOLVER_UP_MP(OSAtomicOr32Barrier)
-RESOLVER_UP_MP(OSAtomicXor32)
-RESOLVER_UP_MP(OSAtomicXor32Barrier)
-RESOLVER_UP_MP(OSAtomicAnd32Orig)
-RESOLVER_UP_MP(OSAtomicAnd32OrigBarrier)
-RESOLVER_UP_MP(OSAtomicOr32Orig)
-RESOLVER_UP_MP(OSAtomicOr32OrigBarrier)
-RESOLVER_UP_MP(OSAtomicXor32Orig)
-RESOLVER_UP_MP(OSAtomicXor32OrigBarrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapPtr)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapPtrBarrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapInt)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapIntBarrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapLong)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapLongBarrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwap32)
-RESOLVER_UP_MP(OSAtomicCompareAndSwap32Barrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwap64)
-RESOLVER_UP_MP(OSAtomicCompareAndSwap64Barrier)
-RESOLVER_UP_MP(OSAtomicAdd32)
-RESOLVER_UP_MP(OSAtomicAdd32Barrier)
-RESOLVER_UP_MP(OSAtomicAdd64)
-RESOLVER_UP_MP(OSAtomicAdd64Barrier)
-RESOLVER_UP_MP(OSAtomicTestAndSet)
-RESOLVER_UP_MP(OSAtomicTestAndSetBarrier)
-RESOLVER_UP_MP(OSAtomicTestAndClear)
-RESOLVER_UP_MP(OSAtomicTestAndClearBarrier)
-RESOLVER_UP_MP(OSAtomicEnqueue)
-RESOLVER_UP_MP(OSAtomicDequeue)
-
-PLATFUNC_DESCRIPTOR_PROTOTYPE(OSMemoryBarrier, all)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(OSMemoryBarrier, sse2)
-
-static const platfunc_descriptor *OSMemoryBarrier_platfunc_descriptors[] = {
- PLATFUNC_DESCRIPTOR_REFERENCE(OSMemoryBarrier, sse2),
- PLATFUNC_DESCRIPTOR_REFERENCE(OSMemoryBarrier, all),
- 0
-};
-
-void *OSMemoryBarrier_chooser() __asm__("_OSMemoryBarrier");
-void *OSMemoryBarrier_chooser() {
- __asm__(".symbol_resolver _OSMemoryBarrier");
- return find_platform_function((const platfunc_descriptor **) OSMemoryBarrier_platfunc_descriptors);
-}
+++ /dev/null
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <sys/appleapiopts.h>
-#include <machine/cpu_capabilities.h>
-
-#define NSEC_PER_SEC 1000*1000*1000
-#define NSEC_PER_USEC 1000
-
- .align 4
- .private_extern ___commpage_gettimeofday
-___commpage_gettimeofday:
- push %ebp
- mov %esp,%ebp
- push %esi
- push %ebx
-
-0:
- movl _COMM_PAGE_GTOD_GENERATION,%esi /* get generation (0 if disabled) */
- testl %esi,%esi /* disabled? */
- jz 4f
-
- call _mach_absolute_time /* get nanotime in %edx:%eax */
-
- sub _COMM_PAGE_GTOD_NS_BASE,%eax
- sbb _COMM_PAGE_GTOD_NS_BASE+4,%edx
- mov _COMM_PAGE_GTOD_SEC_BASE,%ebx /* load all the data before checking generation */
- mov $ NSEC_PER_SEC,%ecx
-
- cmpl _COMM_PAGE_GTOD_GENERATION,%esi /* has time data changed out from under us? */
- jne 0b
-
- div %ecx
- add %eax,%ebx
-
- mov $ NSEC_PER_USEC,%ecx
- mov %edx,%eax
- xor %edx,%edx
- div %ecx
-
- mov 8(%ebp),%ecx
- mov %ebx,(%ecx)
- mov %eax,4(%ecx)
- xor %eax,%eax
-
-3:
- pop %ebx
- pop %esi
- pop %ebp
- ret
-4: /* fail */
- movl $1,%eax
- jmp 3b
+++ /dev/null
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <sys/appleapiopts.h>
-#include <machine/cpu_capabilities.h>
-
-
-/* return mach_absolute_time in %edx:%eax
- *
- * The algorithm we use is:
- *
- * ns = ((((rdtsc - rnt_tsc_base)<<rnt_shift)*rnt_tsc_scale) / 2**32) + rnt_ns_base;
- *
- * rnt_shift, a constant computed during initialization, is the smallest value for which:
- *
- * (tscFreq << rnt_shift) > SLOW_TSC_THRESHOLD
- *
- * Where SLOW_TSC_THRESHOLD is about 10e9. Since most processor's tscFreq is greater
- * than 1GHz, rnt_shift is usually 0. rnt_tsc_scale is also a 32-bit constant:
- *
- * rnt_tsc_scale = (10e9 * 2**32) / (tscFreq << rnt_shift);
- */
-
- .globl _mach_absolute_time
-_mach_absolute_time:
- pushl %ebp
- movl %esp,%ebp
- pushl %esi
- pushl %ebx
-
-0:
- movl _COMM_PAGE_NT_GENERATION,%esi /* get generation (0 if being changed) */
- testl %esi,%esi /* if being updated, loop until stable */
- jz 0b
-
- lfence
- rdtsc /* get TSC in %edx:%eax */
- lfence
-
- subl _COMM_PAGE_NT_TSC_BASE,%eax
- sbbl _COMM_PAGE_NT_TSC_BASE+4,%edx
-
- /*
- * Prior to supporting "slow" processors, xnu always set _NT_SHIFT to 32.
- * Now it defaults to 0, unless the processor is slow. The shifts
- * below implicitly mask the count down to 5 bits, handling either default.
- */
- movl _COMM_PAGE_NT_SHIFT,%ecx
- shldl %cl,%eax,%edx /* shift %edx left, filling in from %eax */
- shll %cl,%eax /* finish shifting %edx:%eax left by _COMM_PAGE_NT_SHIFT bits */
-
- movl _COMM_PAGE_NT_SCALE,%ecx
-
- movl %edx,%ebx
- mull %ecx
- movl %ebx,%eax
- movl %edx,%ebx
- mull %ecx
- addl %ebx,%eax
- adcl $0,%edx
-
- addl _COMM_PAGE_NT_NS_BASE,%eax
- adcl _COMM_PAGE_NT_NS_BASE+4,%edx
-
- cmpl _COMM_PAGE_NT_GENERATION,%esi /* have the parameters changed? */
- jne 0b /* yes, loop until stable */
-
- popl %ebx
- popl %esi
- popl %ebp
- ret
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
- */
-/*
- * NeXT 386 setjmp/longjmp
- *
- * Written by Bruce Martin, NeXT Inc. 4/9/92
- */
-
-/*
- * C library -- setjmp, longjmp
- *
- * longjmp(a,v)
- * will generate a "return(v)" from
- * the last call to
- * setjmp(a)
- * by restoring registers from the stack,
- * The previous value of the signal mask is
- * restored.
- *
- */
-
-#include <architecture/i386/asm_help.h>
-
-// The FP control word is actually two bytes, but there's no harm in
-// using four bytes for it and keeping the struct aligned.
-#define JB_FPCW 0
-#define JB_MASK 4
-#define JB_MXCSR 8
-#define JB_EBX 12
-#define JB_ONSTACK 16
-#define JB_EDX 20
-#define JB_EDI 24
-#define JB_ESI 28
-#define JB_EBP 32
-#define JB_ESP 36
-#define JB_SS 40
-#define JB_EFLAGS 44
-#define JB_EIP 48
-#define JB_CS 52
-#define JB_DS 56
-#define JB_ES 60
-#define JB_FS 64
-#define JB_GS 68
-#define JB_SAVEMASK 72 // sigsetjmp/siglongjmp only
-
-LEAF(_sigsetjmp, 0)
- movl 4(%esp), %eax // sigjmp_buf * jmpbuf;
- movl 8(%esp), %ecx // int savemask;
- movl %ecx, JB_SAVEMASK(%eax) // jmpbuf[_JBLEN] = savemask;
- cmpl $0, %ecx // if savemask != 0
- jne _setjmp // setjmp(jmpbuf);
- jmp L_do__setjmp // else _setjmp(jmpbuf);
-
-LEAF(_setjmp, 0)
- subl $16, %esp // make space for return from sigprocmask
- // + 12 to align stack
- pushl %esp // oset
- pushl $0 // set = NULL
- pushl $1 // how = SIG_BLOCK
- CALL_EXTERN(_sigprocmask)
- movl 12(%esp),%eax // save the mask
- addl $28, %esp // restore original esp
- movl 4(%esp), %ecx // jmp_buf (struct sigcontext *)
- movl %eax, JB_MASK(%ecx)
-
- subl $20, %esp // temporary struct sigaltstack + 8 to
- // align stack
- pushl %esp // oss
- pushl $0 // ss == NULL
- CALL_EXTERN(_sigaltstack) // get alternate signal stack info
- movl 16(%esp), %eax // oss->ss_flags
- addl $28, %esp // Restore %esp
- movl %eax, JB_ONSTACK(%ecx)
-
-L_do__setjmp:
- BRANCH_EXTERN(__setjmp)
-
-LEAF(_siglongjmp, 0)
- movl 4(%esp), %eax // sigjmp_buf * jmpbuf;
- cmpl $0, JB_SAVEMASK(%eax) // if jmpbuf[_JBLEN] != 0
- jne _longjmp // longjmp(jmpbuf, var);
- jmp L_do__longjmp // else _longjmp(jmpbuf, var);
-
-LEAF(_longjmp, 0)
- movl 4(%esp), %ecx // address of jmp_buf (saved context)
- movl JB_MASK(%ecx),%eax // get the mask
- subl $12, %esp // Make sure the stack is 16-byte
- // aligned when we call sigprocmask
- pushl %eax // store the mask
- movl %esp, %edx // save the address where we stored the mask
- pushl $0 // oset = NULL
- pushl %edx // set
- pushl $3 // how = SIG_SETMASK
- CALL_EXTERN_AGAIN(_sigprocmask)
- addl $28, %esp // restore original esp
-
- movl 4(%esp), %ecx // address of jmp_buf
- movl JB_ONSTACK(%ecx), %eax // ss_flags
- subl $8, %esp
- pushl %eax
- CALL_EXTERN(__sigunaltstack)
- addl $12, %esp
-
-L_do__longjmp:
- BRANCH_EXTERN(__longjmp) // else
-END(_longjmp)
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-
-#define RESOLVER_UP_MP(symbol) \
- PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, up); \
- PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, mp); \
- static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \
- PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \
- PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \
- 0 \
- }; \
- void* symbol ## _chooser() __asm__("_" #symbol); \
- void* symbol ## _chooser() { \
- __asm__(".symbol_resolver _" #symbol); \
- return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \
- }
-
-RESOLVER_UP_MP(OSSpinLockTry)
-RESOLVER_UP_MP(_spin_lock_try)
-RESOLVER_UP_MP(OSSpinLockLock)
-RESOLVER_UP_MP(_spin_lock)
-RESOLVER_UP_MP(spin_lock)
+++ /dev/null
-/*
- * Copyright (c) 2003-2009 Apple, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <sys/appleapiopts.h>
-#include <machine/cpu_capabilities.h>
-#include <platfunc.h>
-#include <mach/i386/syscall_sw.h>
-
-
-PLATFUNC_FUNCTION_START(OSSpinLockTry, up, 32, 4)
-PLATFUNC_FUNCTION_START(_spin_lock_try, up, 32, 4)
- movl 4(%esp), %ecx
- xorl %eax, %eax
- orl $-1, %edx
- cmpxchgl %edx, (%ecx)
- setz %dl
- movzbl %dl, %eax
- ret
-PLATFUNC_DESCRIPTOR(OSSpinLockTry,up,kUP,0)
-PLATFUNC_DESCRIPTOR(_spin_lock_try,up,kUP,0)
-
-PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockTry, mp, 32, 4)
-PLATFUNC_FUNCTION_START_GENERIC(_spin_lock_try, mp, 32, 4)
- movl 4(%esp), %ecx
- xorl %eax, %eax
- orl $-1, %edx
- lock
- cmpxchgl %edx, (%ecx)
- setz %dl
- movzbl %dl, %eax
- ret
-PLATFUNC_DESCRIPTOR(OSSpinLockTry,mp,0,kUP)
-PLATFUNC_DESCRIPTOR(_spin_lock_try,mp,0,kUP)
-
-
-PLATFUNC_FUNCTION_START(spin_lock, up, 32, 4)
-PLATFUNC_FUNCTION_START(OSSpinLockLock, up, 32, 4)
-PLATFUNC_FUNCTION_START(_spin_lock, up, 32, 4)
-Lspin_lock_up:
- movl 4(%esp), %ecx
- xorl %eax, %eax
- orl $-1, %edx
- cmpxchgl %edx, (%ecx)
- jnz 1f
- ret
-1:
- /* failed to get lock so relinquish the processor immediately on UP */
- pushl $1 /* 1 ms */
- pushl $1 /* SWITCH_OPTION_DEPRESS */
- pushl $0 /* THREAD_NULL */
- pushl $0 /* push dummy stack ret addr */
- movl $-61,%eax /* SYSCALL_THREAD_SWITCH */
- int $(MACH_INT)
- addl $16, %esp /* adjust stack*/
- jmp Lspin_lock_up
-PLATFUNC_DESCRIPTOR(spin_lock,up,kUP,0)
-PLATFUNC_DESCRIPTOR(OSSpinLockLock,up,kUP,0)
-PLATFUNC_DESCRIPTOR(_spin_lock,up,kUP,0)
-
-PLATFUNC_FUNCTION_START_GENERIC(spin_lock, mp, 32, 4)
-PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockLock, mp, 32, 4)
-PLATFUNC_FUNCTION_START_GENERIC(_spin_lock, mp, 32, 4)
-Lspin_lock_mp:
- movl 4(%esp), %ecx
- xorl %eax, %eax
-0:
- orl $-1, %edx
- lock
- cmpxchgl %edx, (%ecx)
- jnz 1f
- ret
-1:
- xorl %eax, %eax
- movl $(MP_SPIN_TRIES), %edx
-2:
- pause
- cmpl %eax, (%ecx)
- jz 0b /* favor success and slow down spin loop */
- decl %edx
- jnz 2b
- /* failed to get lock after spinning so relinquish */
- pushl $1 /* 1 ms */
- pushl $1 /* SWITCH_OPTION_DEPRESS */
- pushl $0 /* THREAD_NULL */
- pushl $0 /* push dummy stack ret addr */
- movl $-61,%eax /* SYSCALL_THREAD_SWITCH */
- int $(MACH_INT)
- addl $16, %esp /* adjust stack*/
- jmp Lspin_lock_mp
-PLATFUNC_DESCRIPTOR(spin_lock,mp,0,kUP)
-PLATFUNC_DESCRIPTOR(OSSpinLockLock,mp,0,kUP)
-PLATFUNC_DESCRIPTOR(_spin_lock,mp,0,kUP)
-
- .align 2, 0x90
- .globl _OSSpinLockUnlock
- .globl _spin_unlock
- .globl __spin_unlock
-_OSSpinLockUnlock:
-_spin_unlock:
-__spin_unlock:
- movl 4(%esp), %eax
- movl $0, (%eax)
- ret
-
int __size;
} *nl_catd;
-#ifndef _NL_ITEM
-typedef __darwin_nl_item nl_item;
-#define _NL_ITEM
-#endif
+#include <_types/_nl_item.h>
__BEGIN_DECLS
nl_catd catopen(const char *, int);
#include <sys/time.h>
#include <sys/cdefs.h>
#include <Availability.h>
-
-#ifndef _PID_T
-#define _PID_T
-typedef __darwin_pid_t pid_t;
-#endif
+#include <sys/_types/_pid_t.h>
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
-#ifndef _UID_T
-#define _UID_T
-typedef __darwin_uid_t uid_t;
-#endif
+#include <sys/_types/_uid_t.h>
#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */
#define _PATH_UTMPX "/var/run/utmpx"
getlastlogxbyname(const char*, struct lastlogx *)__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
#ifdef UNIFDEF_LEGACY_UTMP_APIS
struct utmp; /* forward reference */
-void getutmp(const struct utmpx *, struct utmp *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-void getutmpx(const struct utmp *, struct utmpx *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
+void getutmp(const struct utmpx *, struct utmp *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_9, __IPHONE_2_0, __IPHONE_7_0);
+void getutmpx(const struct utmp *, struct utmpx *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_9, __IPHONE_2_0, __IPHONE_7_0);
#endif /* UNIFDEF_LEGACY_UTMP_APIS */
#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */
char int_n_sign_posn;
};
-#ifndef NULL
-#define NULL __DARWIN_NULL
-#endif /* ! NULL */
+#include <sys/_types/_null.h>
__BEGIN_DECLS
struct lconv *localeconv(void);
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _INTMAX_T
+#define _INTMAX_T
+#ifdef __INTMAX_TYPE__
+typedef __INTMAX_TYPE__ intmax_t;
+#else
+#ifdef __LP64__
+typedef long int intmax_t;
+#else
+typedef long long int intmax_t;
+#endif /* __LP64__ */
+#endif /* __INTMAX_TYPE__ */
+#endif /* _INTMAX_T */
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _NL_ITEM
+#define _NL_ITEM
+typedef __darwin_nl_item nl_item;
+#endif /* _NL_ITEM */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _UINT16_T
+#define _UINT16_T
+typedef unsigned short uint16_t;
+#endif /* _UINT16_T */
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _UINT32_T
+#define _UINT32_T
+typedef unsigned int uint32_t;
+#endif /* _UINT32_T */
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _UINT64_T
+#define _UINT64_T
+typedef unsigned long long uint64_t;
+#endif /* _UINT64_T */
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _UINT8_T
+#define _UINT8_T
+typedef unsigned char uint8_t;
+#endif /* _UINT8_T */
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _UINTMAX_T
+#define _UINTMAX_T
+#ifdef __UINTMAX_TYPE__
+typedef __UINTMAX_TYPE__ uintmax_t;
+#else
+#ifdef __LP64__
+typedef long unsigned int uintmax_t;
+#else
+typedef long long unsigned int uintmax_t;
+#endif /* __LP64__ */
+#endif /* __UINTMAX_TYPE__ */
+#endif /* _UINTMAX_T */
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _WCTRANS_T
+#define _WCTRANS_T
+typedef __darwin_wctrans_t wctrans_t;
+#endif /* _WCTRANS_T */
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#ifndef _WCTYPE_T
+#define _WCTYPE_T
+typedef __darwin_wctype_t wctype_t;
+#endif /* _WCTYPE_T */
\ No newline at end of file
*
* Contains everything required by wctype.h except:
*
- * typedef __darwin_wctrans_t wctrans_t;
+ * #include <_types/_wctrans_t.h>
* int iswblank(wint_t);
* wint_t towctrans(wint_t, wctrans_t);
* wctrans_t wctrans(const char *);
#include <sys/cdefs.h>
#include <_types.h>
-#ifndef _WINT_T
-#define _WINT_T
-typedef __darwin_wint_t wint_t;
-#endif
-
-#ifndef _WCTYPE_T
-#define _WCTYPE_T
-typedef __darwin_wctype_t wctype_t;
-#endif
+#include <sys/_types/_wint_t.h>
+#include <sys/_types/_wint_t.h>
+#include <_types/_wctype_t.h>
#ifndef WEOF
#define WEOF __DARWIN_WEOF
#endif
-#ifndef __DARWIN_WCTYPE_TOP_static_inline
-#define __DARWIN_WCTYPE_TOP_static_inline static __inline
+#ifndef __DARWIN_WCTYPE_TOP_inline
+#define __DARWIN_WCTYPE_TOP_inline __header_inline
#endif
#include <ctype.h>
#if !defined(_DONT_USE_CTYPE_INLINE_) && \
(defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus))
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswalnum(wint_t _wc)
{
return (__istype(_wc, _CTYPE_A|_CTYPE_D));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswalpha(wint_t _wc)
{
return (__istype(_wc, _CTYPE_A));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswcntrl(wint_t _wc)
{
return (__istype(_wc, _CTYPE_C));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswctype(wint_t _wc, wctype_t _charclass)
{
return (__istype(_wc, _charclass));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswdigit(wint_t _wc)
{
return (__isctype(_wc, _CTYPE_D));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswgraph(wint_t _wc)
{
return (__istype(_wc, _CTYPE_G));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswlower(wint_t _wc)
{
return (__istype(_wc, _CTYPE_L));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswprint(wint_t _wc)
{
return (__istype(_wc, _CTYPE_R));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswpunct(wint_t _wc)
{
return (__istype(_wc, _CTYPE_P));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswspace(wint_t _wc)
{
return (__istype(_wc, _CTYPE_S));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswupper(wint_t _wc)
{
return (__istype(_wc, _CTYPE_U));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswxdigit(wint_t _wc)
{
return (__isctype(_wc, _CTYPE_X));
}
-__DARWIN_WCTYPE_TOP_static_inline wint_t
+__DARWIN_WCTYPE_TOP_inline wint_t
towlower(wint_t _wc)
{
return (__tolower(_wc));
}
-__DARWIN_WCTYPE_TOP_static_inline wint_t
+__DARWIN_WCTYPE_TOP_inline wint_t
towupper(wint_t _wc)
{
return (__toupper(_wc));
#include <sys/cdefs.h>
#include <_types.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
+#include <sys/_types/_size_t.h>
__BEGIN_DECLS
void *alloca(size_t); /* built-in for gcc */
--- /dev/null
+/*
+ * ++Copyright++ 1983, 1993
+ * -
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ * @(#)inet.h 8.1 (Berkeley) 6/2/93
+ * $Id: inet.h,v 1.10 2006/02/01 18:09:47 majka Exp $
+ */
+
+#ifndef _ARPA_INET_H_
+#define _ARPA_INET_H_
+
+/* External definitions for functions in inet(3), addr2ascii(3) */
+
+#include <sys/cdefs.h>
+#include <sys/_types.h>
+#include <stdint.h> /* uint32_t uint16_t */
+#include <machine/endian.h> /* htonl() and family if (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
+#include <sys/_endian.h> /* htonl() and family if (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */
+#include <netinet/in.h> /* in_addr */
+
+__BEGIN_DECLS
+
+in_addr_t inet_addr(const char *);
+char *inet_ntoa(struct in_addr);
+const char *inet_ntop(int, const void *, char *, socklen_t);
+int inet_pton(int, const char *, void *);
+
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
+int ascii2addr(int, const char *, void *);
+char *addr2ascii(int, const void *, int, char *);
+int inet_aton(const char *, struct in_addr *);
+in_addr_t inet_lnaof(struct in_addr);
+struct in_addr inet_makeaddr(in_addr_t, in_addr_t);
+in_addr_t inet_netof(struct in_addr);
+in_addr_t inet_network(const char *);
+char *inet_net_ntop(int, const void *, int, char *, __darwin_size_t);
+int inet_net_pton(int, const char *, void *, __darwin_size_t);
+char *inet_neta(in_addr_t, char *, __darwin_size_t);
+unsigned int inet_nsap_addr(const char *, unsigned char *, int);
+char *inet_nsap_ntoa(int, const unsigned char *, char *);
+#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */
+
+__END_DECLS
+
+#endif /* !_ARPA_INET_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __ASL_H__
-#define __ASL_H__
-
-#include <stdint.h>
-#include <stdarg.h>
-#include <sys/cdefs.h>
-#include <Availability.h>
-
-typedef struct __aslclient *aslclient;
-typedef struct __aslmsg *aslmsg;
-typedef struct __aslresponse *aslresponse;
-
-/*! @header
- * These routines provide an interface to the Apple System Log facility.
- * The API allows client applications to create flexible, structured messages
- * and send them to the syslogd server. Messages received by the server are
- * saved in a data store, subject to input filtering constraints.
- * This API also permits clients to create queries and search the message
- * data store for matching messages.
- */
-
-/*
- * NOTE FOR HeaderDoc
- *
- * These are added to allow headerdoc2html to process
- * the prototypes of asl_log and asl_vlog correctly.
- * The "-p" option to headerdoc2html is required.
- */
-#ifndef __printflike
-/*! @parseOnly */
-#define __printflike(a,b)
-#endif
-
-/*! @defineblock Log Message Priority Levels
- * Log levels of the message.
- */
-#define ASL_LEVEL_EMERG 0
-#define ASL_LEVEL_ALERT 1
-#define ASL_LEVEL_CRIT 2
-#define ASL_LEVEL_ERR 3
-#define ASL_LEVEL_WARNING 4
-#define ASL_LEVEL_NOTICE 5
-#define ASL_LEVEL_INFO 6
-#define ASL_LEVEL_DEBUG 7
-/*! @/defineblock */
-
-/*! @defineblock Log Message Priority Level Strings
- * Strings corresponding to log levels.
- */
-#define ASL_STRING_EMERG "Emergency"
-#define ASL_STRING_ALERT "Alert"
-#define ASL_STRING_CRIT "Critical"
-#define ASL_STRING_ERR "Error"
-#define ASL_STRING_WARNING "Warning"
-#define ASL_STRING_NOTICE "Notice"
-#define ASL_STRING_INFO "Info"
-#define ASL_STRING_DEBUG "Debug"
-/*! @/defineblock */
-
-/*! @defineblock Attribute Matching
- * Attribute value comparison operations.
- */
-#define ASL_QUERY_OP_CASEFOLD 0x0010
-#define ASL_QUERY_OP_PREFIX 0x0020
-#define ASL_QUERY_OP_SUFFIX 0x0040
-#define ASL_QUERY_OP_SUBSTRING 0x0060
-#define ASL_QUERY_OP_NUMERIC 0x0080
-#define ASL_QUERY_OP_REGEX 0x0100
-
-#define ASL_QUERY_OP_EQUAL 0x0001
-#define ASL_QUERY_OP_GREATER 0x0002
-#define ASL_QUERY_OP_GREATER_EQUAL 0x0003
-#define ASL_QUERY_OP_LESS 0x0004
-#define ASL_QUERY_OP_LESS_EQUAL 0x0005
-#define ASL_QUERY_OP_NOT_EQUAL 0x0006
-#define ASL_QUERY_OP_TRUE 0x0007
-/*! @/defineblock */
-
-/*! @defineblock Message Attributes
- *
- * These attributes are known by ASL, and are generally
- * associated with all log messages.
- * Additional attributes may be added as desired.
- */
-#define ASL_KEY_TIME "Time" /* Timestamp. Set automatically */
-#define ASL_KEY_TIME_NSEC "TimeNanoSec" /* Nanosecond time. */
-#define ASL_KEY_HOST "Host" /* Sender's address (set by the server). */
-#define ASL_KEY_SENDER "Sender" /* Sender's identification string. Default is process name. */
-#define ASL_KEY_FACILITY "Facility" /* Sender's facility. Default is "user". */
-#define ASL_KEY_PID "PID" /* Sending process ID encoded as a string. Set automatically. */
-#define ASL_KEY_UID "UID" /* UID that sent the log message (set by the server). */
-#define ASL_KEY_GID "GID" /* GID that sent the log message (set by the server). */
-#define ASL_KEY_LEVEL "Level" /* Log level number encoded as a string. See levels above. */
-#define ASL_KEY_MSG "Message" /* Message text. */
-#define ASL_KEY_READ_UID "ReadUID" /* User read access (-1 is any user). */
-#define ASL_KEY_READ_GID "ReadGID" /* Group read access (-1 is any group). */
-#define ASL_KEY_EXPIRE_TIME "ASLExpireTime" /* Expiration time for messages with long TTL. */
-#define ASL_KEY_MSG_ID "ASLMessageID" /* 64-bit message ID number (set by the server). */
-#define ASL_KEY_SESSION "Session" /* Session (set by the launchd). */
-#define ASL_KEY_REF_PID "RefPID" /* Reference PID for messages proxied by launchd */
-#define ASL_KEY_REF_PROC "RefProc" /* Reference process for messages proxied by launchd */
-#define ASL_KEY_AUX_TITLE "ASLAuxTitle" /* Auxiliary title string */
-#define ASL_KEY_AUX_UTI "ASLAuxUTI" /* Auxiliary Uniform Type ID */
-#define ASL_KEY_AUX_URL "ASLAuxURL" /* Auxiliary Uniform Resource Locator */
-#define ASL_KEY_AUX_DATA "ASLAuxData" /* Auxiliary in-line data */
-#define ASL_KEY_OPTION "ASLOption" /* Internal */
-#define ASL_KEY_SENDER_INSTANCE "SenderInstance" /* Sender instance UUID. */
-/*! @/defineblock */
-
-/*! @defineblock aslmsg Types
- * Message type argument passed to asl_new().
- */
-#define ASL_TYPE_MSG 0
-#define ASL_TYPE_QUERY 1
-/*! @/defineblock */
-
-/*! @defineblock Filter Masks
- * Used in client-side filtering, which determines which
- * messages are sent by the client to the syslogd server.
- */
-#define ASL_FILTER_MASK_EMERG 0x01
-#define ASL_FILTER_MASK_ALERT 0x02
-#define ASL_FILTER_MASK_CRIT 0x04
-#define ASL_FILTER_MASK_ERR 0x08
-#define ASL_FILTER_MASK_WARNING 0x10
-#define ASL_FILTER_MASK_NOTICE 0x20
-#define ASL_FILTER_MASK_INFO 0x40
-#define ASL_FILTER_MASK_DEBUG 0x80
-/*! @/defineblock */
-
-/*! @defineblock Filter Mask Macros
- * Macros to create bitmasks for filter settings - see asl_set_filter().
- */
-#define ASL_FILTER_MASK(level) (1 << (level))
-#define ASL_FILTER_MASK_UPTO(level) ((1 << ((level) + 1)) - 1)
-/*! @/defineblock */
-
-/*! @defineblock Client Creation Options
- * Options for asl_open().
- */
-#define ASL_OPT_STDERR 0x00000001
-#define ASL_OPT_NO_DELAY 0x00000002
-#define ASL_OPT_NO_REMOTE 0x00000004
-/*! @/defineblock */
-
-/*! @defineblock File Descriptor Types
- * Instructions on how to treat the file descriptor in asl_log_descriptor().
- */
-#define ASL_LOG_DESCRIPTOR_READ 1
-#define ASL_LOG_DESCRIPTOR_WRITE 2
-
-/*!
- * ASL_PREFILTER_LOG is a macro similar to asl_log(), but it first checks
- * if the message will simply be ignored due to local filter settings.
- * This prevents the variable argument list from being evaluated.
- * Note that the message may still be processed if it will be written
- * to a file or stderr.
- *
- * @param asl
- * (input) An ASL client handle
- * @param msg
- * (input) An aslmsg (default attributes will be supplied if msg is NULL)
- * @param level
- * (input) Log level (ASL_LEVEL_DEBUG to ASL_LEVEL_EMERG)
- * @param format
- * (input) A printf() - style format string followed by a list of arguments
- */
-#define ASL_PREFILTER_LOG(asl, msg, level, format, ...) \
- do { \
- aslclient _asl = (asl); \
- aslmsg _msg = (msg); \
- uint32_t _asl_eval = _asl_evaluate_send(_asl, _msg, (level)); \
- if (_asl_eval != 0) _asl_lib_log(_asl, _asl_eval, _msg, (format), ## __VA_ARGS__); \
- } while (0)
-
-__BEGIN_DECLS
-
-/* ASL Library SPI - do not call directly */
-int _asl_lib_log(aslclient asl, uint32_t eval, aslmsg msg, const char *format, ...) __printflike(4, 5);
-
-uint32_t _asl_evaluate_send(aslclient asl, aslmsg msg, int level);
-
-/*!
- * Initialize a connection to the ASL server.
- *
- * This call is optional in most cases. The library will perform any
- * necessary initializations on the fly. A call to asl_open() is required
- * if optional settings must be made before messages are sent to the server.
- * These include setting the client filter and managing additional output
- * file descriptors. Note that the default setting of the client filter is
- * ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE), so ASL_LEVEL_DEBUG and ASL_LEVEL_INFO
- * messages are not sent to the server by default.
- *
- * Options (defined above) may be set using the opts parameter. They are:
- *
- * ASL_OPT_STDERR - adds stderr as an output file descriptor
- *
- * ASL_OPT_NO_DELAY - connects to the server immediately
- *
- * ASL_OPT_NO_REMOTE - disables the remote-control mechanism for adjusting
- * filter levers for processes using e.g. syslog -c ...
- *
- * @param ident
- * (input) Sender name
- * @param facility
- * (input) Facility name
- * @param opts
- * (input) Options (see asl_open Options)
- * @result Returns an ASL client handle
- */
-aslclient asl_open(const char *ident, const char *facility, uint32_t opts);
-
-/*!
- * Shuts down a connection to the server.
- *
- * @param asl
- * (input) An ASL client handle
- */
-void asl_close(aslclient asl);
-
-/*!
- * Write log messages to the given file descriptor.
- *
- * Log messages will be written to this file as well as to the server.
- *
- * @param asl
- * (input) An ASL client handle
- * @param descriptor
- * (input) A file descriptor
- * @result Returns 0 on success, non-zero on failure
-*/
-int asl_add_log_file(aslclient asl, int descriptor);
-
-/*!
- * Stop writing log messages to the given file descriptor.
- * The file descripter is not closed by this routine.
- *
- * @param asl
- * (input) An ASL client handle
- * @param descriptor
- * (input) A file descriptor
- * @result Returns 0 on success, non-zero on failure
- */
-int asl_remove_log_file(aslclient asl, int descriptor);
-
-/*!
- * Set a filter for messages being sent to the server.
- * The filter is a bitmask representing priorities. The ASL_FILTER_MASK
- * macro may be used to convert a priority level into a bitmask for that
- * level. The ASL_FILTER_MASK_UPTO macro creates a bitmask for all
- * priorities up to and including a given priority.
- * Messages with priority levels that do not have a corresponding bit
- * set in the filter are not sent to the server, although they will be
- * sent to any file descripters added with asl_add_log_file().
- * The default setting is ASL_FILTER_MASK_UPTO(ASL_LEVEL_NOTICE).
- * Returns the previous filter value.
- *
- * @param asl
- * (input) An ASL client handle
- * @param f
- * (input) A filter value
- * @result Returns the previous filter value
- */
-int asl_set_filter(aslclient asl, int f);
-
-/*
- * Examine attribute keys.
- *
- * @param msg
- * (input) An ASL message
- * @param n
- * (input) An index value
- * @result Returns the key of the nth attribute in a message (beginning at zero),
- * or NULL if n is greater than the largest message index.
- */
-const char *asl_key(aslmsg msg, uint32_t n);
-
-/*!
- * Create a new log message or query message.
- *
- * @param type
- * (input) Message type (see aslmsg Types)
- * @result Returns a newly allocated asmsg of the specified type
- */
-aslmsg asl_new(uint32_t type);
-
-/*!
- * Set or re-set a message attribute.
- *
- * @param msg
- * (input) An aslmsg
- * @param key
- * (input) Attribute key
- * @param value
- * (input) Attribute value
- * @result returns 0 for success, non-zero for failure
- */
-int asl_set(aslmsg msg, const char *key, const char *value);
-
-/*!
- * Remove a message attribute.
- *
- * @param msg
- * (input) An aslmsg
- * @param key
- * (input) Attribute key
- * returns 0 for success, non-zero for failure
- */
-int asl_unset(aslmsg msg, const char *key);
-
-/*!
- * Get the value of a message attribute.
- *
- * @param msg
- * (input) An aslmsg
- * @param key
- * (input) Attribute key
- * @result Returns the attribute value, or NULL if the message does not contain the key
- */
-const char *asl_get(aslmsg msg, const char *key);
-
-/*!
- * Log a message with a particular log level.
- *
- * @param asl
- * (input) An ASL client handle
- * @param msg
- * (input) An aslmsg (default attributes will be supplied if msg is NULL)
- * @param level
- * (input) Log level (ASL_LEVEL_DEBUG to ASL_LEVEL_EMERG)
- * @param format
- * (input) A printf() - style format string followed by a list of arguments
- * @result Returns 0 for success, non-zero for failure
- */
-int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __printflike(4, 5);
-
-/*!
- * Log a message with a particular log level.
- * Similar to asl_log, but takes a va_list argument.
- *
- * @param asl
- * (input) An ASL client handle
- * @param msg
- * (input) An aslmsg (default attributes will be supplied if msg is NULL)
- * @param level
- * (input) Log level (ASL_LEVEL_DEBUG to ASL_LEVEL_EMERG)
- * @param format
- * (input) A printf() - style format string followed by a list of arguments
- * @param ap
- * (input) A va_list containing the values for the format string
- * @result Returns 0 for success, non-zero for failure
- */
-int asl_vlog(aslclient asl, aslmsg msg, int level, const char *format, va_list ap) __printflike(4, 0);
-
-/*!
- * Log a message.
- *
- * This routine may be used instead of asl_log() or asl_vlog() if asl_set()
- * has been used to set all of a message's attributes.
- *
- * @param asl
- * (input) An ASL client handle
- * @param msg
- * (input) An aslmsg
- * @result Returns 0 for success, non-zero for failure
- */
-int asl_send(aslclient asl, aslmsg msg);
-
-/*!
- * Free a message. Frees all the attribute keys and values.
- *
- * @param msg
- * (input) An aslmsg to free
- */
-void asl_free(aslmsg msg);
-
-/*!
- * Set arbitrary parameters of a query.
- * This is similar to asl_set, but allows richer query operations.
- * See ASL_QUERY_OP_* above.
- *
- * @param msg
- * (input) An aslmsg
- * @param key
- * (input) Attribute key
- * @param value
- * (input) Attribute value
- * @param op
- * (input) An operation (ASL_QUERY_OP_*)
- * @result Returns 0 for success, non-zero for failure
- */
-int asl_set_query(aslmsg msg, const char *key, const char *value, uint32_t op);
-
-/*!
- * Search for messages matching the criteria described by the aslmsg.
- * The caller should set the attributes to match using asl_set_query() or asl_set().
- * The operatoin ASL_QUERY_OP_EQUAL is used for attributes set with asl_set().
- *
- * @param msg
- * (input) An aslmsg to match
- * @result Returns a set of messages accessable using aslresponse_next(),
- */
-aslresponse asl_search(aslclient asl, aslmsg msg);
-
-/*!
- * Iterate over responses returned from asl_search().
- *
- * @param r
- * (input) An aslresponse returned by asl_search()
- * @result Returns the next message (an aslmsg) in the response, or NULL when there are no more messages
- */
-aslmsg aslresponse_next(aslresponse r);
-
-/*!
- * Free a response returned from asl_search().
- * @param r
- * (input) An aslresponse returned by asl_search()
- */
-void aslresponse_free(aslresponse r);
-
-/*!
- * Creates an auxiliary file that may be used to save arbitrary data. The ASL message msg
- * will be saved at the time that the auxiliary file is closed with asl_close_auxiliary_file().
- * The log entry will include any keys and values found in msg, and it will include the title
- * and Uniform Type Identifier specified. If NULL is supplied as a value for the uti parameter,
- * the type "public.data" is used. Console.app will display a hyperlink to the file.
- * Output parameter out_descriptor will contain a readable and writable file descriptor for the new
- * auxiliary file.
- *
- * By default, the file will be world-readable. If the message contains a ReadUID and/or a
- * ReadGID key, then the values for those keys will determine read access to the file.
- *
- * The file will be deleted at the same time that the message expires from the ASL data store.
- * The aslmanager utility manages message expiry. If msg contains a value for ASLExpireTime,
- * then the message and the file will not be deleted before that time. The value may be in
- * seconds after the Epoch, or it may be ctime() format, e.g "Thu Jun 24 18:22:48 2010".
- *
- * @param msg
- * (input) An aslmsg
- * @param tite
- * (input) A title string for the file
- * @param uti
- * (input) Uniform Type Identifier for the file
- * @param out_descriptor
- * (output) A writable file descriptor
- * @result Returns 0 for success, non-zero for failure
- */
-int asl_create_auxiliary_file(aslmsg msg, const char *title, const char *uti, int *out_descriptor)
-__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0);
-
-/*!
- * Close an auxiliary file opened by asl_create_auxiliary_file() when writing is complete.
- * syslogd will log the message provided to asl_create_auxiliary_file() when this routine
- * is called.
- *
- * @param descriptor
- * (input) The file descriptor
- * @result Returns 0 for success, non-zero for failure
- */
-int asl_close_auxiliary_file(int descriptor)
-__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0);
-
-/*!
- * Sends an ASL message to syslogd along with a title string, Uniform Resource Locator,
- * and Uniform Type Identifier specified. Console.app will hyperlink the title string to
- * the specified URL. If NULL is supplied as a value for the uti parameter, the default
- * type "public.data" is used.
- *
- * @param msg
- * (input) An aslmsg
- * @param title
- * (input) A title string for the file
- * @param uti
- * (input) Uniform Type Identifier for the file
- * @param url
- * (input) Uniform Type Locator
- * @result Returns 0 for success, non-zero for failure
- */
-int asl_log_auxiliary_location(aslmsg msg, const char *title, const char *uti, const char *url)
-__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0);
-
-/*!
- * Creates an aslclient for logging to a file descriptor. The file must be opened for read and
- * write access. This routine may be used in conjunction with asl_create_auxiliary_file() to
- * save ASL format log messages to an auxiliary file.
- *
- * The file will be truncated if it is not empty. When logging to the auxiliary file is complete,
- * aslclient should be closed using asl_close(). The file should be closed using
- * asl_close_auxiliary_file() if it was returned by asl_create_auxiliary_file(), or close()
- * otherwise.
- *
- * The returned aslclient is thread-safe.
- *
- * Note that per-message read access controls (ReadUID and ReadGID) and message expire
- * times (ASLExpireTime) keys have no effect for messages written to this file.
- *
- * @param descriptor
- * (input) A file descriptor
- * @param ident
- * (input) Sender name
- * @param facility
- * (input) Facility name
- * @result An aslclient
- */
-aslclient asl_open_from_file(int descriptor, const char *ident, const char *facility)
-__OSX_AVAILABLE_STARTING(__MAC_10_7,__IPHONE_5_0);
-
-/*!
- * This API provides functionality to use file descriptors to send logging
- * data to ASL.
- *
- * asl is retained by ASL and must still be closed by the caller by calling
- * asl_close() if the caller loses reference to it. msg is copied by ASL and
- * similarly must still be freed by the caller by calling asl_free() if the
- * caller loses reference to it. Any changes made to it after calling
- * asl_log_descriptor() are not applicable to the message used. descriptor
- * is treated differentlty based on the value of fd_type.
- *
- * If fd_type is ASL_LOG_DESCRIPTOR_READ, the descriptor must be open for read
- * access. ASL uses GCD to read from the descriptor as data becomes available.
- * These data are line buffered and passed to asl_log. When EOF is read, the
- * descriptor is closed.
- *
- * Example:
- * asl_log_descriptor(c, m, ASL_LEVEL_NOTICE, STDIN_FILENO, ASL_LOG_DESCRIPTOR_READ);
- *
- * If fd_type is ASL_LOG_DESCRIPTOR_WRITE, the descriptor is closed and a new
- * writable descriptor is created with the same fileno. Any data written to
- * this new descriptor are line buffered and passed to asl_log. When EOF is
- * sent, no further data are read. The caller is responsible for closing the
- * new descriptor. One common use for this API is to redirect writes to stdout
- * or stderr to ASL by passing STDOUT_FILENO or STDERR_FILENO as descriptor.
- *
- * Example:
- * asl_log_descriptor(c, m, ASL_LEVEL_NOTICE, STDOUT_FILENO, ASL_LOG_DESCRIPTOR_WRITE);
- * asl_log_descriptor(c, m, ASL_LEVEL_ERR, STDERR_FILENO, ASL_LOG_DESCRIPTOR_WRITE);
- *
- * @param asl
- * (input) An ASL client handle
- * @param msg
- * (input) An aslmsg (default attributes will be supplied if msg is NULL)
- * @param level
- * (input) Log level (ASL_LEVEL_DEBUG to ASL_LEVEL_EMERG)
- * @param descriptor
- * (input) An open file descriptor to read from
- * @param fd_type
- * (input) Either ASL_LOG_DESCRIPTOR_READ or ASL_LOG_DESCRIPTOR_WRITE
- * @result Returns 0 for success, non-zero for failure
- */
-int asl_log_descriptor(aslclient asl, aslmsg msg, int level, int descriptor, uint32_t fd_type)
-__OSX_AVAILABLE_STARTING(__MAC_10_8,__IPHONE_5_1);
-
-__END_DECLS
-
-#endif /* __ASL_H__ */
#ifndef _CTYPE_H_
#define _CTYPE_H_
+#include <sys/cdefs.h>
#include <runetype.h>
#define _CTYPE_A 0x00000100L /* Alpha */
#define _SW3 _CTYPE_SW3 /* 3 width character */
#endif /* _NONSTD_SOURCE */
+//Begin-Libc
/*
* _EXTERNALIZE_CTYPE_INLINES_ is defined in locale/nomacros.c to tell us
* to generate code for extern versions of all intermediate inline functions.
*/
#ifdef _EXTERNALIZE_CTYPE_INLINES_
#define _USE_CTYPE_INLINE_
-#define __DARWIN_CTYPE_static_inline
+#define __DARWIN_CTYPE_inline
#else /* !_EXTERNALIZE_CTYPE_INLINES_ */
-#define __DARWIN_CTYPE_static_inline static __inline
+//End-Libc
+#define __DARWIN_CTYPE_inline __header_inline
+//Begin-Libc
#endif /* !_EXTERNALIZE_CTYPE_INLINES_ */
+//End-Libc
+//Begin-Libc
/*
* _EXTERNALIZE_CTYPE_INLINES_TOP_ is defined in locale/isctype.c to tell us
* to generate code for extern versions of all top-level inline functions.
*/
#ifdef _EXTERNALIZE_CTYPE_INLINES_TOP_
#define _USE_CTYPE_INLINE_
-#define __DARWIN_CTYPE_TOP_static_inline
+#define __DARWIN_CTYPE_TOP_inline
#else /* !_EXTERNALIZE_CTYPE_INLINES_TOP_ */
-#define __DARWIN_CTYPE_TOP_static_inline static __inline
+//End-Libc
+#define __DARWIN_CTYPE_TOP_inline __header_inline
+//Begin-Libc
#endif /* _EXTERNALIZE_CTYPE_INLINES_TOP_ */
+//End-Libc
/*
* Use inline functions if we are allowed to and the compiler supports them.
__darwin_ct_rune_t ___toupper(__darwin_ct_rune_t);
__END_DECLS
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isascii(int _c)
{
return ((_c & ~0x7F) == 0);
}
#ifdef USE_ASCII
-__DARWIN_CTYPE_static_inline int
+__DARWIN_CTYPE_inline int
__maskrune(__darwin_ct_rune_t _c, unsigned long _f)
{
return _DefaultRuneLocale.__runetype[_c & 0xff] & _f;
}
//Begin-Libc
#elif defined(__LIBC__)
-__DARWIN_CTYPE_static_inline int
+__DARWIN_CTYPE_inline int
__maskrune(__darwin_ct_rune_t _c, unsigned long _f)
{
return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype(_c) :
__END_DECLS
#endif /* USE_ASCII */
-__DARWIN_CTYPE_static_inline int
+__DARWIN_CTYPE_inline int
__istype(__darwin_ct_rune_t _c, unsigned long _f)
{
#ifdef USE_ASCII
#endif /* USE_ASCII */
}
-__DARWIN_CTYPE_static_inline __darwin_ct_rune_t
+__DARWIN_CTYPE_inline __darwin_ct_rune_t
__isctype(__darwin_ct_rune_t _c, unsigned long _f)
{
#ifdef USE_ASCII
}
#ifdef USE_ASCII
-__DARWIN_CTYPE_static_inline __darwin_ct_rune_t
+__DARWIN_CTYPE_inline __darwin_ct_rune_t
__toupper(__darwin_ct_rune_t _c)
{
return _DefaultRuneLocale.__mapupper[_c & 0xff];
}
-__DARWIN_CTYPE_static_inline __darwin_ct_rune_t
+__DARWIN_CTYPE_inline __darwin_ct_rune_t
__tolower(__darwin_ct_rune_t _c)
{
return _DefaultRuneLocale.__maplower[_c & 0xff];
* assume c >= _CACHED_RUNES. So we are stuck making __toupper() a routine
* to hide the extended locale details, outside of Libc.
*/
-__DARWIN_CTYPE_static_inline __darwin_ct_rune_t
+__DARWIN_CTYPE_inline __darwin_ct_rune_t
__toupper(__darwin_ct_rune_t _c)
{
return (_c < 0 || _c >= _CACHED_RUNES) ? ___toupper(_c) :
__current_locale()->__lc_ctype->_CurrentRuneLocale.__mapupper[_c];
}
-__DARWIN_CTYPE_static_inline __darwin_ct_rune_t
+__DARWIN_CTYPE_inline __darwin_ct_rune_t
__tolower(__darwin_ct_rune_t _c)
{
return (_c < 0 || _c >= _CACHED_RUNES) ? ___tolower(_c) :
__END_DECLS
#endif /* USE_ASCII */
-__DARWIN_CTYPE_static_inline int
+__DARWIN_CTYPE_inline int
__wcwidth(__darwin_ct_rune_t _c)
{
unsigned int _x;
#define _tolower(c) __tolower(c)
#define _toupper(c) __toupper(c)
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isalnum(int _c)
{
return (__istype(_c, _CTYPE_A|_CTYPE_D));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isalpha(int _c)
{
return (__istype(_c, _CTYPE_A));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isblank(int _c)
{
return (__istype(_c, _CTYPE_B));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
iscntrl(int _c)
{
return (__istype(_c, _CTYPE_C));
}
/* ANSI -- locale independent */
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isdigit(int _c)
{
return (__isctype(_c, _CTYPE_D));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isgraph(int _c)
{
return (__istype(_c, _CTYPE_G));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
islower(int _c)
{
return (__istype(_c, _CTYPE_L));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isprint(int _c)
{
return (__istype(_c, _CTYPE_R));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
ispunct(int _c)
{
return (__istype(_c, _CTYPE_P));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isspace(int _c)
{
return (__istype(_c, _CTYPE_S));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isupper(int _c)
{
return (__istype(_c, _CTYPE_U));
}
/* ANSI -- locale independent */
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isxdigit(int _c)
{
return (__isctype(_c, _CTYPE_X));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
toascii(int _c)
{
return (_c & 0x7F);
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
tolower(int _c)
{
return (__tolower(_c));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
toupper(int _c)
{
return (__toupper(_c));
}
#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
digittoint(int _c)
{
return (__maskrune(_c, 0x0F));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
ishexnumber(int _c)
{
return (__istype(_c, _CTYPE_X));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isideogram(int _c)
{
return (__istype(_c, _CTYPE_I));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isnumber(int _c)
{
return (__istype(_c, _CTYPE_D));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isphonogram(int _c)
{
return (__istype(_c, _CTYPE_Q));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isrune(int _c)
{
return (__istype(_c, 0xFFFFFFF0L));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isspecial(int _c)
{
return (__istype(_c, _CTYPE_T));
/*
- * Copyright (c) 2000, 2003-2006, 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2000, 2003-2006, 2008, 2012 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#define _FTS_H_
#include <sys/_types.h>
-
-#ifndef _DEV_T
-typedef __darwin_dev_t dev_t; /* device number */
-#define _DEV_T
-#endif
-
-#ifndef _INO_T
-typedef __darwin_ino_t ino_t; /* inode number */
-#define _INO_T
-#endif
-
-#ifndef _NLINK_T
-typedef __uint16_t nlink_t; /* link count */
-#define _NLINK_T
-#endif
+#include <sys/_types/_dev_t.h>
+#include <sys/_types/_ino_t.h>
+#include <sys/_types/_nlink_t.h>
typedef struct {
struct _ftsent *fts_cur; /* current node */
#define FTS_XDEV 0x040 /* don't cross devices */
#define FTS_WHITEOUT 0x080 /* return whiteout information */
#define FTS_COMFOLLOWDIR 0x400 /* (non-std) follow command line symlinks for directories only */
+#if (defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1090) || (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 70000)
+#define FTS_NOSTAT_TYPE 0x800 /* (non-std) no stat, but use d_type in struct dirent when available */
+#define FTS_OPTIONMASK 0xcff /* valid user option mask */
+#else
#define FTS_OPTIONMASK 0x4ff /* valid user option mask */
+#endif
#define FTS_NAMEONLY 0x100 /* (private) child names only */
#define FTS_STOP 0x200 /* (private) unrecoverable error */
#include <_types.h>
#include <sys/cdefs.h>
#include <Availability.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
+#include <sys/_types/_size_t.h>
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
struct dirent;
extern intmax_t strtoimax(const char * restrict nptr, char ** restrict endptr, int base);
extern uintmax_t strtoumax(const char * restrict nptr, char ** restrict endptr, int base);
-#ifndef __cplusplus /* wchar_t is a built-in type in C++ */
-# ifndef _WCHAR_T
-# define _WCHAR_T
- typedef __darwin_wchar_t wchar_t;
-# endif /* _WCHAR_T */
-#endif /* __cplusplus */
+#include <sys/_types/_wchar_t.h>
/* 7.8.2.4 */
extern intmax_t wcstoimax(const wchar_t * restrict nptr, wchar_t ** restrict endptr, int base);
#define _LANGINFO_H_
#include <_types.h>
-
-#ifndef _NL_ITEM
-typedef __darwin_nl_item nl_item;
-#define _NL_ITEM
-#endif
+#include <_types/_nl_item.h>
#define CODESET 0 /* codeset name */
#define D_T_FMT 1 /* string for formatting date and time */
+++ /dev/null
-/*
- * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _OSATOMIC_H_
-#define _OSATOMIC_H_
-
-#include <stddef.h>
-#include <sys/cdefs.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#include <Availability.h>
-
-/*! @header
- * These are the preferred versions of the atomic and synchronization operations.
- * Their implementation is customized at boot time for the platform, including
- * late-breaking errata fixes as necessary. They are thread safe.
- *
- * WARNING: all addresses passed to these functions must be "naturally aligned",
- * i.e. * <code>int32_t</code> pointers must be 32-bit aligned (low 2 bits of
- * address are zeroes), and <code>int64_t</code> pointers must be 64-bit aligned
- * (low 3 bits of address are zeroes.)
- *
- * Note that some versions of the atomic functions incorporate memory barriers
- * and some do not. Barriers strictly order memory access on weakly-ordered
- * architectures such as PPC. All loads and stores that appear (in sequential
- * program order) before the barrier are guaranteed to complete before any
- * load or store that appears after the barrier.
- *
- * On a uniprocessor system, the barrier operation is typically a no-op. On a
- * multiprocessor system, the barrier can be quite expensive on some platforms,
- * such as PPC.
- *
- * Most code should use the barrier functions to ensure that memory shared between
- * threads is properly synchronized. For example, if you want to initialize
- * a shared data structure and then atomically increment a variable to indicate
- * that the initialization is complete, you must use {@link OSAtomicIncrement32Barrier}
- * to ensure that the stores to your data structure complete before the atomic
- * increment.
- *
- * Likewise, the consumer of that data structure must use {@link OSAtomicDecrement32Barrier},
- * in order to ensure that their loads of the structure are not executed before
- * the atomic decrement. On the other hand, if you are simply incrementing a global
- * counter, then it is safe and potentially faster to use {@link OSAtomicIncrement32}.
- *
- * If you are unsure which version to use, prefer the barrier variants as they are
- * safer.
- *
- * The spinlock and queue operations always incorporate a barrier.
- *
- * For the kernel-space version of this header, see
- * {@link //apple_ref/doc/header/OSAtomic.h OSAtomic.h (Kernel Framework)}
- *
- * @apiuid //apple_ref/doc/header/user_space_OSAtomic.h
- */
-__BEGIN_DECLS
-
-
-/*! @group Arithmetic functions
- All functions in this group return the new value.
- */
-
-/*! @abstract Atomically adds two 32-bit values.
- @discussion
- This function adds the value given by <code>__theAmount</code> to the
- value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
- @result Returns the new value.
- */
-int32_t OSAtomicAdd32( int32_t __theAmount, volatile int32_t *__theValue );
-
-
-/*! @abstract Atomically adds two 32-bit values.
- @discussion
- This function adds the value given by <code>__theAmount</code> to the
- value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
-
- This function is equivalent to {@link OSAtomicAdd32}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-int32_t OSAtomicAdd32Barrier( int32_t __theAmount, volatile int32_t *__theValue );
-
-
-/*! @abstract Atomically increments a 32-bit value.
- */
-__inline static
-int32_t OSAtomicIncrement32( volatile int32_t *__theValue )
- { return OSAtomicAdd32( 1, __theValue); }
-
-
-/*! @abstract Atomically increments a 32-bit value with a barrier.
- @discussion
- This function is equivalent to {@link OSAtomicIncrement32}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-__inline static
-int32_t OSAtomicIncrement32Barrier( volatile int32_t *__theValue )
- { return OSAtomicAdd32Barrier( 1, __theValue); }
-
-/*! @abstract Atomically decrements a 32-bit value. */
-__inline static
-int32_t OSAtomicDecrement32( volatile int32_t *__theValue )
- { return OSAtomicAdd32( -1, __theValue); }
-
-/*! @abstract Atomically increments a 32-bit value with a barrier.
- @discussion
- This function is equivalent to {@link OSAtomicDecrement32}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-__inline static
-int32_t OSAtomicDecrement32Barrier( volatile int32_t *__theValue )
- { return OSAtomicAdd32Barrier( -1, __theValue); }
-
-
-/*! @abstract Atomically adds two 64-bit values.
- @discussion
- This function adds the value given by <code>__theAmount</code> to the
- value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
- */
-int64_t OSAtomicAdd64( int64_t __theAmount, volatile int64_t *__theValue );
-
-
-/*! @abstract Atomically adds two 64-bit values with a barrier.
- @discussion
- This function adds the value given by <code>__theAmount</code> to the
- value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
-
- This function is equivalent to {@link OSAtomicAdd64}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2);
-
-
-/*! @abstract Atomically increments a 64-bit value. */
-__inline static
-int64_t OSAtomicIncrement64( volatile int64_t *__theValue )
- { return OSAtomicAdd64( 1, __theValue); }
-
-/*! @abstract Atomically increments a 64-bit value with a barrier.
- @discussion
- This function is equivalent to {@link OSAtomicIncrement64}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-__inline static
-int64_t OSAtomicIncrement64Barrier( volatile int64_t *__theValue )
- { return OSAtomicAdd64Barrier( 1, __theValue); }
-
-
-/*! @abstract Atomically decrements a 64-bit value.
- @discussion
- This function is equivalent to {@link OSAtomicIncrement64}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-__inline static
-int64_t OSAtomicDecrement64( volatile int64_t *__theValue )
- { return OSAtomicAdd64( -1, __theValue); }
-
-
-/*! @abstract Atomically decrements a 64-bit value with a barrier.
- @discussion
- This function is equivalent to {@link OSAtomicDecrement64}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-__inline static
-int64_t OSAtomicDecrement64Barrier( volatile int64_t *__theValue )
- { return OSAtomicAdd64Barrier( -1, __theValue); }
-
-
-/*! @group Boolean functions (AND, OR, XOR)
- *
- * @discussion Functions in this group come in four variants for each operation:
- * with and without barriers, and functions that return the original value or
- * the result value of the operation.
- *
- * The "Orig" versions return the original value, (before the operation); the non-Orig
- * versions return the value after the operation. All are layered on top of
- * {@link OSAtomicCompareAndSwap32} and similar.
- */
-
-/*! @abstract Atomic bitwise OR of two 32-bit values.
- @discussion
- This function performs the bitwise OR of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
- @result Returns the new value.
- */
-int32_t OSAtomicOr32( uint32_t __theMask, volatile uint32_t *__theValue );
-
-
-/*! @abstract Atomic bitwise OR of two 32-bit values with barrier.
- @discussion
- This function performs the bitwise OR of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
-
- This function is equivalent to {@link OSAtomicOr32}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-int32_t OSAtomicOr32Barrier( uint32_t __theMask, volatile uint32_t *__theValue );
-
-
-/*! @abstract Atomic bitwise OR of two 32-bit values returning original.
- @discussion
- This function performs the bitwise OR of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
- @result Returns the original value referenced by <code>__theValue</code>.
- */
-int32_t OSAtomicOr32Orig( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2);
-
-
-/*! @abstract Atomic bitwise OR of two 32-bit values returning original with barrier.
- @discussion
- This function performs the bitwise OR of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
-
- This function is equivalent to {@link OSAtomicOr32Orig}
- except that it also introduces a barrier.
- @result Returns the original value referenced by <code>__theValue</code>.
- */
-int32_t OSAtomicOr32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2);
-
-
-
-
-/*! @abstract Atomic bitwise AND of two 32-bit values.
- @discussion
- This function performs the bitwise AND of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
- @result Returns the new value.
- */
-int32_t OSAtomicAnd32( uint32_t __theMask, volatile uint32_t *__theValue );
-
-
-/*! @abstract Atomic bitwise AND of two 32-bit values with barrier.
- @discussion
- This function performs the bitwise AND of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
-
- This function is equivalent to {@link OSAtomicAnd32}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-int32_t OSAtomicAnd32Barrier( uint32_t __theMask, volatile uint32_t *__theValue );
-
-
-/*! @abstract Atomic bitwise AND of two 32-bit values returning original.
- @discussion
- This function performs the bitwise AND of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
- @result Returns the original value referenced by <code>__theValue</code>.
- */
-int32_t OSAtomicAnd32Orig( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2);
-
-
-/*! @abstract Atomic bitwise AND of two 32-bit values returning original with barrier.
- @discussion
- This function performs the bitwise AND of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
-
- This function is equivalent to {@link OSAtomicAnd32Orig}
- except that it also introduces a barrier.
- @result Returns the original value referenced by <code>__theValue</code>.
- */
-int32_t OSAtomicAnd32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2);
-
-
-
-
-/*! @abstract Atomic bitwise XOR of two 32-bit values.
- @discussion
- This function performs the bitwise XOR of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
- @result Returns the new value.
- */
-int32_t OSAtomicXor32( uint32_t __theMask, volatile uint32_t *__theValue );
-
-
-/*! @abstract Atomic bitwise XOR of two 32-bit values with barrier.
- @discussion
- This function performs the bitwise XOR of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
-
- This function is equivalent to {@link OSAtomicXor32}
- except that it also introduces a barrier.
- @result Returns the new value.
- */
-int32_t OSAtomicXor32Barrier( uint32_t __theMask, volatile uint32_t *__theValue );
-
-
-/*! @abstract Atomic bitwise XOR of two 32-bit values returning original.
- @discussion
- This function performs the bitwise XOR of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
- @result Returns the original value referenced by <code>__theValue</code>.
- */
-int32_t OSAtomicXor32Orig( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2);
-
-
-/*! @abstract Atomic bitwise XOR of two 32-bit values returning original with barrier.
- @discussion
- This function performs the bitwise XOR of the value given by <code>__theMask</code>
- with the value in the memory location referenced by <code>__theValue</code>,
- storing the result back to that memory location atomically.
-
- This function is equivalent to {@link OSAtomicXor32Orig}
- except that it also introduces a barrier.
- @result Returns the original value referenced by <code>__theValue</code>.
- */
-int32_t OSAtomicXor32OrigBarrier( uint32_t __theMask, volatile uint32_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_3_2);
-
-
-/*! @group Compare and swap
- * Functions in this group return true if the swap occured. There are several versions,
- * depending on data type and on whether or not a barrier is used.
- */
-
-
-/*! @abstract Compare and swap for 32-bit values.
- @discussion
- This function compares the value in <code>__oldValue</code> to the value
- in the memory location referenced by <code>__theValue</code>. If the values
- match, this function stores the value from <code>__newValue</code> into
- that memory location atomically.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwap32( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue );
-
-
-/*! @abstract Compare and swap for 32-bit values with barrier.
- @discussion
- This function compares the value in <code>__oldValue</code> to the value
- in the memory location referenced by <code>__theValue</code>. If the values
- match, this function stores the value from <code>__newValue</code> into
- that memory location atomically.
-
- This function is equivalent to {@link OSAtomicCompareAndSwap32}
- except that it also introduces a barrier.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwap32Barrier( int32_t __oldValue, int32_t __newValue, volatile int32_t *__theValue );
-
-
-/*! @abstract Compare and swap pointers.
- @discussion
- This function compares the pointer stored in <code>__oldValue</code> to the pointer
- in the memory location referenced by <code>__theValue</code>. If the pointers
- match, this function stores the pointer from <code>__newValue</code> into
- that memory location atomically.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwapPtr( void *__oldValue, void *__newValue, void * volatile *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-
-/*! @abstract Compare and swap pointers with barrier.
- @discussion
- This function compares the pointer stored in <code>__oldValue</code> to the pointer
- in the memory location referenced by <code>__theValue</code>. If the pointers
- match, this function stores the pointer from <code>__newValue</code> into
- that memory location atomically.
-
- This function is equivalent to {@link OSAtomicCompareAndSwapPtr}
- except that it also introduces a barrier.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwapPtrBarrier( void *__oldValue, void *__newValue, void * volatile *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-
-/*! @abstract Compare and swap for <code>int</code> values.
- @discussion
- This function compares the value in <code>__oldValue</code> to the value
- in the memory location referenced by <code>__theValue</code>. If the values
- match, this function stores the value from <code>__newValue</code> into
- that memory location atomically.
-
- This function is equivalent to {@link OSAtomicCompareAndSwap32}.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwapInt( int __oldValue, int __newValue, volatile int *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-
-/*! @abstract Compare and swap for <code>int</code> values.
- @discussion
- This function compares the value in <code>__oldValue</code> to the value
- in the memory location referenced by <code>__theValue</code>. If the values
- match, this function stores the value from <code>__newValue</code> into
- that memory location atomically.
-
- This function is equivalent to {@link OSAtomicCompareAndSwapInt}
- except that it also introduces a barrier.
-
- This function is equivalent to {@link OSAtomicCompareAndSwap32Barrier}.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwapIntBarrier( int __oldValue, int __newValue, volatile int *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-
-/*! @abstract Compare and swap for <code>long</code> values.
- @discussion
- This function compares the value in <code>__oldValue</code> to the value
- in the memory location referenced by <code>__theValue</code>. If the values
- match, this function stores the value from <code>__newValue</code> into
- that memory location atomically.
-
- This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures,
- or {@link OSAtomicCompareAndSwap64} on 64-bit architectures.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwapLong( long __oldValue, long __newValue, volatile long *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-
-/*! @abstract Compare and swap for <code>long</code> values.
- @discussion
- This function compares the value in <code>__oldValue</code> to the value
- in the memory location referenced by <code>__theValue</code>. If the values
- match, this function stores the value from <code>__newValue</code> into
- that memory location atomically.
-
- This function is equivalent to {@link OSAtomicCompareAndSwapLong}
- except that it also introduces a barrier.
-
- This function is equivalent to {@link OSAtomicCompareAndSwap32} on 32-bit architectures,
- or {@link OSAtomicCompareAndSwap64} on 64-bit architectures.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwapLongBarrier( long __oldValue, long __newValue, volatile long *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-
-/*! @abstract Compare and swap for <code>uint64_t</code> values.
- @discussion
- This function compares the value in <code>__oldValue</code> to the value
- in the memory location referenced by <code>__theValue</code>. If the values
- match, this function stores the value from <code>__newValue</code> into
- that memory location atomically.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwap64( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
-
-
-/*! @abstract Compare and swap for <code>uint64_t</code> values.
- @discussion
- This function compares the value in <code>__oldValue</code> to the value
- in the memory location referenced by <code>__theValue</code>. If the values
- match, this function stores the value from <code>__newValue</code> into
- that memory location atomically.
-
- This function is equivalent to {@link OSAtomicCompareAndSwap64}
- except that it also introduces a barrier.
- @result Returns TRUE on a match, FALSE otherwise.
- */
-bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue ) __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_3_2);
-
-
-/* Test and set. They return the original value of the bit, and operate on bit (0x80>>(n&7))
- * in byte ((char*)theAddress + (n>>3)).
- */
-/*! @abstract Atomic test and set
- @discussion
- This function tests a bit in the value referenced by <code>__theAddress</code>
- and if it is not set, sets it. The bit is chosen by the value of <code>__n</code>.
- The bits are numbered in order beginning with bit 1 as the lowest order bit.
-
- For example, if <code>__theAddress</code> points to a 64-bit value,
- to compare the value of the highest bit, you would specify <code>64</code> for
- <code>__n</code>.
- @result
- Returns the original value of the bit being tested.
- */
-bool OSAtomicTestAndSet( uint32_t __n, volatile void *__theAddress );
-
-
-/*! @abstract Atomic test and set with barrier
- @discussion
- This function tests a bit in the value referenced by <code>__theAddress</code>
- and if it is not set, sets it. The bit is chosen by the value of <code>__n</code>.
- The bits are numbered in order beginning with bit 1 as the lowest order bit.
-
- For example, if <code>__theAddress</code> points to a 64-bit value,
- to compare the value of the highest bit, you would specify <code>64</code> for
- <code>__n</code>.
-
- This function is equivalent to {@link OSAtomicTestAndSet}
- except that it also introduces a barrier.
- @result
- Returns the original value of the bit being tested.
- */
-
-bool OSAtomicTestAndSetBarrier( uint32_t __n, volatile void *__theAddress );
-
-
-
-/*! @abstract Atomic test and clear
- @discussion
- This function tests a bit in the value referenced by <code>__theAddress</code>
- and if it is not cleared, clears it. The bit is chosen by the value of <code>__n</code>.
- The bits are numbered in order beginning with bit 1 as the lowest order bit.
-
- For example, if <code>__theAddress</code> points to a 64-bit value,
- to compare the value of the highest bit, you would specify <code>64</code> for
- <code>__n</code>.
- @result
- Returns the original value of the bit being tested.
- */
-bool OSAtomicTestAndClear( uint32_t __n, volatile void *__theAddress );
-
-
-/*! @abstract Atomic test and clear
- @discussion
- This function tests a bit in the value referenced by <code>__theAddress</code>
- and if it is not cleared, clears it. The bit is chosen by the value of <code>__n</code>.
- The bits are numbered in order beginning with bit 1 as the lowest order bit.
-
- For example, if <code>__theAddress</code> points to a 64-bit value,
- to compare the value of the highest bit, you would specify <code>64</code> for
- <code>__n</code>.
-
- This function is equivalent to {@link OSAtomicTestAndSet}
- except that it also introduces a barrier.
- @result
- Returns the original value of the bit being tested.
- */
-bool OSAtomicTestAndClearBarrier( uint32_t __n, volatile void *__theAddress );
-
-
-/*! @group Spinlocks
- * These spinlocks use memory barriers as required to synchronize access to shared
- * memory protected by the lock.
- */
-
-/*! @abstract The default value for an <code>OSSpinLock</code>.
- @discussion
- The convention is that unlocked is zero, locked is nonzero.
- */
-#define OS_SPINLOCK_INIT 0
-
-
-/*! @abstract Data type for a spinlock.
- @discussion
- You should always initialize a spinlock to {@link OS_SPINLOCK_INIT} before
- using it.
- */
-typedef int32_t OSSpinLock;
-
-
-/*! @abstract Locks a spinlock if it would not block
- @result
- Returns <code>false</code> if the lock was already held by another thread,
- <code>true</code> if it took the lock successfully.
- */
-bool OSSpinLockTry( volatile OSSpinLock *__lock );
-
-
-/*! @abstract Locks a spinlock
- @discussion
- Although the lock operation spins, it employs various strategies
- to back off if the lock is held, making it immune to most priority-inversion
- livelocks.
- */
-void OSSpinLockLock( volatile OSSpinLock *__lock );
-
-
-/*! @abstract Unlocks a spinlock */
-void OSSpinLockUnlock( volatile OSSpinLock *__lock );
-
-
-/*! @group Lockless atomic enqueue and dequeue
- * These routines manipulate singly-linked LIFO lists.
- */
-
-/*! @abstract The data structure for a queue head.
- @discussion
- You should always initialize a queue head structure with the
- initialization vector {@link OS_ATOMIC_QUEUE_INIT} before use.
- */
-#if defined(__x86_64__)
-
-typedef volatile struct {
- void *opaque1;
- long opaque2;
-} __attribute__ ((aligned (16))) OSQueueHead;
-
-#else
-
-typedef volatile struct {
- void *opaque1;
- long opaque2;
-} OSQueueHead;
-
-#endif
-
-/*! @abstract The initialization vector for a queue head. */
-#define OS_ATOMIC_QUEUE_INIT { NULL, 0 }
-
-/*! @abstract Enqueue an item onto a list.
- @discussion
- Memory barriers are incorporated as needed to permit thread-safe access
- to the queue element.
- @param __list
- The list on which you want to enqueue the item.
- @param __new
- The item to add.
- @param __offset
- The "offset" parameter is the offset (in bytes) of the link field
- from the beginning of the data structure being queued (<code>__new</code>).
- The link field should be a pointer type.
- The <code>__offset</code> value needs to be same for all enqueuing and
- dequeuing operations on the same queue, even if different structure types
- are enqueued on that queue. The use of <code>offsetset()</code>, defined in
- <code>stddef.h</code> is the common way to specify the <code>__offset</code>
- value.
- */
-void OSAtomicEnqueue( OSQueueHead *__list, void *__new, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0);
-
-
-/*! @abstract Dequeue an item from a list.
- @discussion
- Memory barriers are incorporated as needed to permit thread-safe access
- to the queue element.
- @param __list
- The list on which you want to enqueue the item.
- @param __offset
- The "offset" parameter is the offset (in bytes) of the link field
- from the beginning of the data structure being queued (<code>__new</code>).
- The link field should be a pointer type.
- The <code>__offset</code> value needs to be same for all enqueuing and
- dequeuing operations on the same queue, even if different structure types
- are enqueued on that queue. The use of <code>offsetset()</code>, defined in
- <code>stddef.h</code> is the common way to specify the <code>__offset</code>
- value.
- @result
- Returns the most recently enqueued element, or <code>NULL</code> if the
- list is empty.
- */
-void* OSAtomicDequeue( OSQueueHead *__list, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_4_0);
-
-#if defined(__x86_64__) || defined(__i386__)
-
-/*! @group Lockless atomic fifo enqueue and dequeue
- * These routines manipulate singly-linked FIFO lists.
- */
-
-/*! @abstract The data structure for a fifo queue head.
- @discussion
- You should always initialize a fifo queue head structure with the
- initialization vector {@link OS_ATOMIC_FIFO_QUEUE_INIT} before use.
- */
-#if defined(__x86_64__)
-
-typedef volatile struct {
- void *opaque1;
- void *opaque2;
- int opaque3;
-} __attribute__ ((aligned (16))) OSFifoQueueHead;
-
-#else
-
-typedef volatile struct {
- void *opaque1;
- void *opaque2;
- int opaque3;
-} OSFifoQueueHead;
-
-#endif
-
-/*! @abstract The initialization vector for a fifo queue head. */
-#define OS_ATOMIC_FIFO_QUEUE_INIT { NULL, NULL, 0 }
-
-/*! @abstract Enqueue an item onto a list.
- @discussion
- Memory barriers are incorporated as needed to permit thread-safe access
- to the queue element.
- @param __list
- The list on which you want to enqueue the item.
- @param __new
- The item to add.
- @param __offset
- The "offset" parameter is the offset (in bytes) of the link field
- from the beginning of the data structure being queued (<code>__new</code>).
- The link field should be a pointer type.
- The <code>__offset</code> value needs to be same for all enqueuing and
- dequeuing operations on the same queue, even if different structure types
- are enqueued on that queue. The use of <code>offsetset()</code>, defined in
- <code>stddef.h</code> is the common way to specify the <code>__offset</code>
- value.
- */
-void OSAtomicFifoEnqueue( OSFifoQueueHead *__list, void *__new, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-
-/*! @abstract Dequeue an item from a list.
- @discussion
- Memory barriers are incorporated as needed to permit thread-safe access
- to the queue element.
- @param __list
- The list on which you want to enqueue the item.
- @param __offset
- The "offset" parameter is the offset (in bytes) of the link field
- from the beginning of the data structure being queued (<code>__new</code>).
- The link field should be a pointer type.
- The <code>__offset</code> value needs to be same for all enqueuing and
- dequeuing operations on the same queue, even if different structure types
- are enqueued on that queue. The use of <code>offsetset()</code>, defined in
- <code>stddef.h</code> is the common way to specify the <code>__offset</code>
- value.
- @result
- Returns the oldest enqueued element, or <code>NULL</code> if the
- list is empty.
- */
-void* OSAtomicFifoDequeue( OSFifoQueueHead *__list, size_t __offset) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-
-#endif /* __i386__ || __x86_64__ */
-
-/*! @group Memory barriers */
-
-/*! @abstract Memory barrier.
- @discussion
- This function serves as both a read and write barrier.
- */
-void OSMemoryBarrier( void );
-
-__END_DECLS
-
-#endif /* _OSATOMIC_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _OS_CACHE_CONTROL_H_
-#define _OS_CACHE_CONTROL_H_
-
-#include <stddef.h>
-#include <sys/cdefs.h>
-#include <stdint.h>
-#include <Availability.h>
-
-__BEGIN_DECLS
-
-
-/* Functions performed by sys_cache_control(): */
-
-/* Prepare memory for execution. This should be called
- * after writing machine instructions to memory, before
- * executing them. It syncs the dcache and icache.
- * On IA32 processors this function is a NOP, because
- * no synchronization is required.
- */
-#define kCacheFunctionPrepareForExecution 1
-
-/* Flush data cache(s). This ensures that cached data
- * makes it all the way out to DRAM, and then removes
- * copies of the data from all processor caches.
- * It can be useful when dealing with cache incoherent
- * devices or DMA.
- */
-#define kCacheFunctionFlushDcache 2
-
-
-/* perform one of the above cache functions: */
-int sys_cache_control( int function, void *start, size_t len);
-
-/* equivalent to sys_cache_control(kCacheFunctionPrepareForExecution): */
-void sys_icache_invalidate( void *start, size_t len);
-
-/* equivalent to sys_cache_control(kCacheFunctionFlushDcache): */
-void sys_dcache_flush( void *start, size_t len) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-
-__END_DECLS
-
-#endif /* _OS_CACHE_CONTROL_H_ */
#define OSThermalNotificationLevelUrgent OSThermalNotificationLevelAppTerminate
#define OSThermalNotificationLevelCritical OSThermalNotificationLevelDeviceRestart
+/* Define pressure levels usable by OSThermalPressureLevel */
+typedef enum {
+ kOSThermalPressureLevelNominal = 0,
+ kOSThermalPressureLevelModerate,
+ kOSThermalPressureLevelHeavy,
+ kOSThermalPressureLevelTrapping,
+ kOSThermalPressureLevelSleeping
+} OSThermalPressureLevel;
+
/*
** Simple polling interface to detect current thermal level
*/
extern const char * const kOSThermalNotificationName __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_2_0);
+/*
+** External notify(3) string for alerting user of a thermal condition
+*/
+
+extern const char * const kOSThermalNotificationAlert __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_6_0);
+
+/*
+** External notify(3) string for notifying system the options taken to resolve thermal condition
+*/
+
+extern const char * const kOSThermalNotificationDecision __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_6_0);
+
+/*
+** External notify(3) string for thermal pressure level notification
+*/
+
+extern const char * const kOSThermalNotificationPressureLevelName __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_7_0);
+
+
__END_DECLS
#endif /* _OSTHERMALNOTIFICATION_H_ */
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _MALLOC_MALLOC_H_
-#define _MALLOC_MALLOC_H_
-
-#include <stddef.h>
-#include <mach/mach_types.h>
-#include <sys/cdefs.h>
-#include <Availability.h>
-
-__BEGIN_DECLS
-/********* Type definitions ************/
-
-typedef struct _malloc_zone_t {
- /* Only zone implementors should depend on the layout of this structure;
- Regular callers should use the access functions below */
- void *reserved1; /* RESERVED FOR CFAllocator DO NOT USE */
- void *reserved2; /* RESERVED FOR CFAllocator DO NOT USE */
- size_t (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */
- void *(*malloc)(struct _malloc_zone_t *zone, size_t size);
- void *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */
- void *(*valloc)(struct _malloc_zone_t *zone, size_t size); /* same as malloc, but block returned is set to zero and is guaranteed to be page aligned */
- void (*free)(struct _malloc_zone_t *zone, void *ptr);
- void *(*realloc)(struct _malloc_zone_t *zone, void *ptr, size_t size);
- void (*destroy)(struct _malloc_zone_t *zone); /* zone is destroyed and all memory reclaimed */
- const char *zone_name;
-
- /* Optional batch callbacks; these may be NULL */
- unsigned (*batch_malloc)(struct _malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); /* given a size, returns pointers capable of holding that size; returns the number of pointers allocated (maybe 0 or less than num_requested) */
- void (*batch_free)(struct _malloc_zone_t *zone, void **to_be_freed, unsigned num_to_be_freed); /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process */
-
- struct malloc_introspection_t *introspect;
- unsigned version;
-
- /* aligned memory allocation. The callback may be NULL. Present in version >= 5. */
- void *(*memalign)(struct _malloc_zone_t *zone, size_t alignment, size_t size);
-
- /* free a pointer known to be in zone and known to have the given size. The callback may be NULL. Present in version >= 6.*/
- void (*free_definite_size)(struct _malloc_zone_t *zone, void *ptr, size_t size);
-
- /* Empty out caches in the face of memory pressure. The callback may be NULL. Present in version >= 8. */
- size_t (*pressure_relief)(struct _malloc_zone_t *zone, size_t goal);
-} malloc_zone_t;
-
-/********* Creation and destruction ************/
-
-extern malloc_zone_t *malloc_default_zone(void);
- /* The initial zone */
-
-extern malloc_zone_t *malloc_create_zone(vm_size_t start_size, unsigned flags);
- /* Creates a new zone with default behavior and registers it */
-
-extern void malloc_destroy_zone(malloc_zone_t *zone);
- /* Destroys zone and everything it allocated */
-
-/********* Block creation and manipulation ************/
-
-extern void *malloc_zone_malloc(malloc_zone_t *zone, size_t size);
- /* Allocates a new pointer of size size; zone must be non-NULL */
-
-extern void *malloc_zone_calloc(malloc_zone_t *zone, size_t num_items, size_t size);
- /* Allocates a new pointer of size num_items * size; block is cleared; zone must be non-NULL */
-
-extern void *malloc_zone_valloc(malloc_zone_t *zone, size_t size);
- /* Allocates a new pointer of size size; zone must be non-NULL; Pointer is guaranteed to be page-aligned and block is cleared */
-
-extern void malloc_zone_free(malloc_zone_t *zone, void *ptr);
- /* Frees pointer in zone; zone must be non-NULL */
-
-extern void *malloc_zone_realloc(malloc_zone_t *zone, void *ptr, size_t size);
- /* Enlarges block if necessary; zone must be non-NULL */
-
-extern malloc_zone_t *malloc_zone_from_ptr(const void *ptr);
- /* Returns the zone for a pointer, or NULL if not in any zone.
- The ptr must have been returned from a malloc or realloc call. */
-
-extern size_t malloc_size(const void *ptr);
- /* Returns size of given ptr */
-
-extern size_t malloc_good_size(size_t size);
- /* Returns number of bytes greater than or equal to size that can be allocated without padding */
-
-extern void *malloc_zone_memalign(malloc_zone_t *zone, size_t alignment, size_t size) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
- /*
- * Allocates a new pointer of size size whose address is an exact multiple of alignment.
- * alignment must be a power of two and at least as large as sizeof(void *).
- * zone must be non-NULL.
- */
-
-/********* Batch methods ************/
-
-extern unsigned malloc_zone_batch_malloc(malloc_zone_t *zone, size_t size, void **results, unsigned num_requested);
- /* Allocates num blocks of the same size; Returns the number truly allocated (may be 0) */
-
-extern void malloc_zone_batch_free(malloc_zone_t *zone, void **to_be_freed, unsigned num);
- /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process; This function will always free even if the zone has no batch callback */
-
-/********* Functions for libcache ************/
-
-extern malloc_zone_t *malloc_default_purgeable_zone(void) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
- /* Returns a pointer to the default purgeable_zone. */
-
-extern void malloc_make_purgeable(void *ptr) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
- /* Make an allocation from the purgeable zone purgeable if possible. */
-
-extern int malloc_make_nonpurgeable(void *ptr) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_0);
- /* Makes an allocation from the purgeable zone nonpurgeable.
- * Returns zero if the contents were not purged since the last
- * call to malloc_make_purgeable, else returns non-zero. */
-
-/********* Functions for zone implementors ************/
-
-extern void malloc_zone_register(malloc_zone_t *zone);
- /* Registers a custom malloc zone; Should typically be called after a
- * malloc_zone_t has been filled in with custom methods by a client. See
- * malloc_create_zone for creating additional malloc zones with the
- * default allocation and free behavior. */
-
-extern void malloc_zone_unregister(malloc_zone_t *zone);
- /* De-registers a zone
- Should typically be called before calling the zone destruction routine */
-
-extern void malloc_set_zone_name(malloc_zone_t *zone, const char *name);
- /* Sets the name of a zone */
-
-extern const char *malloc_get_zone_name(malloc_zone_t *zone);
- /* Returns the name of a zone */
-
-size_t malloc_zone_pressure_relief(malloc_zone_t *zone, size_t goal) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
- /* malloc_zone_pressure_relief() advises the malloc subsystem that the process is under memory pressure and
- * that the subsystem should make its best effort towards releasing (i.e. munmap()-ing) "goal" bytes from "zone".
- * If "goal" is passed as zero, the malloc subsystem will attempt to achieve maximal pressure relief in "zone".
- * If "zone" is passed as NULL, all zones are examined for pressure relief opportunities.
- * malloc_zone_pressure_relief() returns the number of bytes released.
- */
-
-typedef struct {
- vm_address_t address;
- vm_size_t size;
-} vm_range_t;
-
-typedef struct malloc_statistics_t {
- unsigned blocks_in_use;
- size_t size_in_use;
- size_t max_size_in_use; /* high water mark of touched memory */
- size_t size_allocated; /* reserved in memory */
-} malloc_statistics_t;
-
-typedef kern_return_t memory_reader_t(task_t remote_task, vm_address_t remote_address, vm_size_t size, void **local_memory);
- /* given a task, "reads" the memory at the given address and size
-local_memory: set to a contiguous chunk of memory; validity of local_memory is assumed to be limited (until next call) */
-
-#define MALLOC_PTR_IN_USE_RANGE_TYPE 1 /* for allocated pointers */
-#define MALLOC_PTR_REGION_RANGE_TYPE 2 /* for region containing pointers */
-#define MALLOC_ADMIN_REGION_RANGE_TYPE 4 /* for region used internally */
-#define MALLOC_ZONE_SPECIFIC_FLAGS 0xff00 /* bits reserved for zone-specific purposes */
-
-typedef void vm_range_recorder_t(task_t, void *, unsigned type, vm_range_t *, unsigned);
- /* given a task and context, "records" the specified addresses */
-
-typedef struct malloc_introspection_t {
- kern_return_t (*enumerator)(task_t task, void *, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder); /* enumerates all the malloc pointers in use */
- size_t (*good_size)(malloc_zone_t *zone, size_t size);
- boolean_t (*check)(malloc_zone_t *zone); /* Consistency checker */
- void (*print)(malloc_zone_t *zone, boolean_t verbose); /* Prints zone */
- void (*log)(malloc_zone_t *zone, void *address); /* Enables logging of activity */
- void (*force_lock)(malloc_zone_t *zone); /* Forces locking zone */
- void (*force_unlock)(malloc_zone_t *zone); /* Forces unlocking zone */
- void (*statistics)(malloc_zone_t *zone, malloc_statistics_t *stats); /* Fills statistics */
- boolean_t (*zone_locked)(malloc_zone_t *zone); /* Are any zone locks held */
-
- /* Discharge checking. Present in version >= 7. */
- boolean_t (*enable_discharge_checking)(malloc_zone_t *zone);
- void (*disable_discharge_checking)(malloc_zone_t *zone);
- void (*discharge)(malloc_zone_t *zone, void *memory);
-#ifdef __BLOCKS__
- void (*enumerate_discharged_pointers)(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info));
-#else
- void *enumerate_unavailable_without_blocks;
-#endif /* __BLOCKS__ */
-} malloc_introspection_t;
-
-extern void malloc_printf(const char *format, ...);
- /* Convenience for logging errors and warnings;
- No allocation is performed during execution of this function;
- Only understands usual %p %d %s formats, and %y that expresses a number of bytes (5b,10KB,1MB...)
- */
-
-/********* Functions for performance tools ************/
-
-extern kern_return_t malloc_get_all_zones(task_t task, memory_reader_t reader, vm_address_t **addresses, unsigned *count);
- /* Fills addresses and count with the addresses of the zones in task;
- Note that the validity of the addresses returned correspond to the validity of the memory returned by reader */
-
-/********* Debug helpers ************/
-
-extern void malloc_zone_print_ptr_info(void *ptr);
- /* print to stdout if this pointer is in the malloc heap, free status, and size */
-
-extern boolean_t malloc_zone_check(malloc_zone_t *zone);
- /* Checks zone is well formed; if !zone, checks all zones */
-
-extern void malloc_zone_print(malloc_zone_t *zone, boolean_t verbose);
- /* Prints summary on zone; if !zone, prints all zones */
-
-extern void malloc_zone_statistics(malloc_zone_t *zone, malloc_statistics_t *stats);
- /* Fills statistics for zone; if !zone, sums up all zones */
-
-extern void malloc_zone_log(malloc_zone_t *zone, void *address);
- /* Controls logging of all activity; if !zone, for all zones;
- If address==0 nothing is logged;
- If address==-1 all activity is logged;
- Else only the activity regarding address is logged */
-
-struct mstats {
- size_t bytes_total;
- size_t chunks_used;
- size_t bytes_used;
- size_t chunks_free;
- size_t bytes_free;
-};
-
-extern struct mstats mstats(void);
-
-extern boolean_t malloc_zone_enable_discharge_checking(malloc_zone_t *zone) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-/* Increment the discharge checking enabled counter for a zone. Returns true if the zone supports checking, false if it does not. */
-
-extern void malloc_zone_disable_discharge_checking(malloc_zone_t *zone) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-/* Decrement the discharge checking enabled counter for a zone. */
-
-extern void malloc_zone_discharge(malloc_zone_t *zone, void *memory) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-/* Register memory that the programmer expects to be freed soon.
- zone may be NULL in which case the zone is determined using malloc_zone_from_ptr().
- If discharge checking is off for the zone this function is a no-op. */
-
-#ifdef __BLOCKS__
-extern void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void (^report_discharged)(void *memory, void *info)) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-/* Calls report_discharged for each block that was registered using malloc_zone_discharge() but has not yet been freed.
- info is used to provide zone defined information about the memory block.
- If zone is NULL then the enumeration covers all zones. */
-#else
-extern void malloc_zone_enumerate_discharged_pointers(malloc_zone_t *zone, void *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-#endif /* __BLOCKS__ */
-
-__END_DECLS
-
-#endif /* _MALLOC_MALLOC_H_ */
#include <sys/cdefs.h>
#include <_types.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef __darwin_ssize_t ssize_t;
-#endif
+#include <sys/_types/_size_t.h>
+#include <sys/_types/_ssize_t.h>
__BEGIN_DECLS
ssize_t strfmon(char *, size_t, const char *, ...);
#define _NDBM_H_
#include <_types.h>
-
-#ifndef _MODE_T
-typedef __darwin_mode_t mode_t;
-#define _MODE_T
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
+#include <sys/_types/_mode_t.h>
+#include <sys/_types/_size_t.h>
#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
/* Map dbm interface onto db(3). */
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/include/printf.h,v 1.5 2011/03/06 17:45:37 pjd Exp $
+ */
+
+#ifndef _PRINTF_H_
+#define _PRINTF_H_
+
+/****************************************************************************
+ * This is the header file for extensible printf, a set of APIs that allow
+ * adding/modifying conversion specifier(s) for stdio formatted printing.
+ * It is based on the GLIBC API documented in:
+ *
+ * http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html
+ *
+ * Because that API affects printf behavior process-wide and so is unsafe,
+ * we adapt a modified form, based on the concept of printf domains in which
+ * changes to conversion specifiers can be made independent of one another
+ * and which don't affect the normal printf behavior. In addition, there
+ * is now a set of printf variants that take a printf domain as an argument.
+ *
+ * See xprintf(5) for more details.
+ ****************************************************************************/
+
+#include <stdio.h>
+#include <wchar.h>
+#include <xlocale.h>
+#include <Availability.h>
+
+#ifdef __GNUC__
+#define __XPRINTF_ATTR(x) __attribute__(x)
+#else /* !__GNUC__ */
+#define __XPRINTF_ATTR(x) /* nothing */
+#endif /* !__GNUC__ */
+
+/*
+ * The API defined by GLIBC allows a renderer to take multiple arguments
+ * This is obviously usable for things like (ptr+len) pairs etc.
+ * The current limit is to deal with up to __PRINTFMAXARG arguments (any
+ * above this limit are ignored).
+ */
+#define __PRINTFMAXARG 2
+
+struct printf_info {
+ /* Mac OS X extensions */
+ void *context; /* User context pointer */
+ locale_t loc; /* Extended locale */
+ wchar_t vsep; /* Vector separator char */
+ /* one of ,:;_ flag or X by default */
+
+ /* GLIBC compatible */
+ int prec; /* precision */
+ int width; /* Width */
+ wchar_t spec; /* Format letter */
+ wchar_t pad; /* Padding char */
+ /* 0 if 0 flag set, otherwise space */
+
+ /* FreeBSD extensions */
+ wchar_t signchar; /* Sign char */
+
+ /* GLIBC compatible flags */
+ unsigned is_long_double :1; /* L or ll flag */
+ unsigned is_char :1; /* hh flag */
+ unsigned is_short :1; /* h flag */
+ unsigned is_long :1; /* l flag */
+ unsigned alt :1; /* # flag */
+ unsigned space :1; /* Space flag */
+ unsigned left :1; /* - flag */
+ unsigned showsign :1; /* + flag */
+ unsigned group :1; /* ' flag */
+ unsigned extra :1; /* For special use (currently unused) */
+ unsigned wide :1; /* Nonzero for wide character streams (currently unused) */
+
+ /* FreeBSD flags */
+ unsigned is_quad :1; /* q flag */
+ unsigned is_intmax :1; /* j flag */
+ unsigned is_ptrdiff :1; /* t flag */
+ unsigned is_size :1; /* z flag */
+
+ /* Mac OS X flags */
+ unsigned is_vec :1; /* v flag */
+
+ /* private */
+ int sofar;
+ unsigned get_width;
+ unsigned get_prec;
+ const char *begin;
+ const char *end;
+ void *arg[__PRINTFMAXARG];
+};
+
+enum {
+ PA_INT = (1 << 0), /* int */
+ PA_CHAR = (1 << 1), /* int, cast to char */
+ PA_WCHAR = (1 << 2), /* wide char */
+ PA_STRING = (1 << 3), /* const char * (with '\0') */
+ PA_WSTRING = (1 << 4), /* const wchar_t * */
+ PA_POINTER = (1 << 5), /* void * */
+ PA_FLOAT = (1 << 6), /* float (Defined but unused; best to avoid.) */
+ PA_DOUBLE = (1 << 7), /* double */
+ PA_VECTOR = (1 << 8), /* vector */
+};
+
+#define PA_FLAG_MASK 0xff0000
+#define PA_FLAG_LONG_LONG (1 << 16)
+#define PA_FLAG_LONG (1 << 17)
+#define PA_FLAG_SHORT (1 << 18)
+#define PA_FLAG_PTR (1 << 19)
+#define PA_FLAG_QUAD (1 << 20)
+#define PA_FLAG_INTMAX (1 << 21)
+#define PA_FLAG_SIZE (1 << 22)
+#define PA_FLAG_PTRDIFF (1 << 23)
+#define PA_FLAG_LONG_DOUBLE PA_FLAG_LONG_LONG
+
+/************************ Basic Extensible Printf APIs ************************/
+
+typedef int printf_arginfo_function(const struct printf_info *__info,
+ size_t __n, int *__argtypes);
+typedef int printf_function(FILE *__stream,
+ const struct printf_info *__info, const void *const *__args);
+
+/*
+ * We don't support the GLIBC register_printf_function() or FreeBSD
+ * register_printf_render_std(), because they affect printf globally
+ * and are unsafe.
+ */
+
+/*************** Extensible Printf Domains APIs ****************/
+
+struct _printf_domain; /* forward reference */
+typedef struct _printf_domain *printf_domain_t;
+
+__BEGIN_DECLS
+
+printf_domain_t copy_printf_domain(printf_domain_t __domain)
+ __XPRINTF_ATTR((__nonnull__(1)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+void free_printf_domain(printf_domain_t __domain)
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+printf_domain_t new_printf_domain(void)
+ __XPRINTF_ATTR((__malloc__))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int register_printf_domain_function(printf_domain_t __domain,
+ int __spec, printf_function *__render,
+ printf_arginfo_function *__arginfo, void *__context)
+ __XPRINTF_ATTR((__nonnull__(1)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int register_printf_domain_render_std(printf_domain_t __domain,
+ const char *__specs)
+ __XPRINTF_ATTR((__nonnull__(1)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/**** All-in-one extensible printf variants ****/
+int asxprintf(char ** __restrict __ret,
+ printf_domain_t __restrict __domain, locale_t __restrict __loc,
+ const char * __restrict __format, ...)
+ __XPRINTF_ATTR((__nonnull__(1, 2, 4)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int dxprintf(int __fd, printf_domain_t __restrict __domain,
+ locale_t __restrict __loc, const char * __restrict __format, ...)
+ __XPRINTF_ATTR((__nonnull__(2, 4)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int fxprintf(FILE * __restrict __stream,
+ printf_domain_t __restrict __domain, locale_t __restrict __loc,
+ const char * __restrict __format, ...)
+ __XPRINTF_ATTR((__nonnull__(1, 2, 4)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int sxprintf(char * __restrict __str, size_t __size,
+ printf_domain_t __restrict __domain, locale_t __restrict __loc,
+ const char * __restrict __format, ...)
+ __XPRINTF_ATTR((__nonnull__(1, 3, 5)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int xprintf(printf_domain_t __restrict __domain,
+ locale_t __restrict __loc, const char * __restrict __format, ...)
+ __XPRINTF_ATTR((__nonnull__(1, 3)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+int vasxprintf(char ** __restrict __ret,
+ printf_domain_t __restrict __domain, locale_t __restrict __loc,
+ const char * __restrict __format, va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(1, 2, 4)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int vdxprintf(int __fd, printf_domain_t __restrict __domain,
+ locale_t __restrict __loc, const char * __restrict __format,
+ va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(2, 4)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int vfxprintf(FILE * __restrict __stream,
+ printf_domain_t __restrict __domain, locale_t __restrict __loc,
+ const char * __restrict __format, va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(1, 2, 4)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int vsxprintf(char * __restrict __str, size_t __size,
+ printf_domain_t __restrict __domain, locale_t __restrict __loc,
+ const char * __restrict __format, va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(1, 3, 5)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int vxprintf(printf_domain_t __restrict __domain,
+ locale_t __restrict __loc, const char * __restrict __format,
+ va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(1, 3)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+__END_DECLS
+
+/******** Extensible Printf Compilation/Execution APIs *********/
+struct _printf_compiled; /* forward reference */
+typedef struct _printf_compiled *printf_comp_t;
+
+__BEGIN_DECLS
+
+void free_printf_comp(printf_comp_t __pc)
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+printf_comp_t new_printf_comp(printf_domain_t __restrict __domain,
+ locale_t __restrict __loc, const char * __restrict __fmt)
+ __XPRINTF_ATTR((__nonnull__(1, 3)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+/**** Extensible printf execution ****/
+int asxprintf_exec(char ** __restrict __ret,
+ printf_comp_t __restrict __pc, ...)
+ __XPRINTF_ATTR((__nonnull__(1, 2)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int dxprintf_exec(int __fd, printf_comp_t __restrict __pc, ...)
+ __XPRINTF_ATTR((__nonnull__(2)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int fxprintf_exec(FILE * __restrict __stream,
+ printf_comp_t __restrict __pc, ...)
+ __XPRINTF_ATTR((__nonnull__(1, 2)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int sxprintf_exec(char * __restrict __str, size_t __size,
+ printf_comp_t __restrict __pc, ...)
+ __XPRINTF_ATTR((__nonnull__(1, 3)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int xprintf_exec(printf_comp_t __restrict __pc, ...)
+ __XPRINTF_ATTR((__nonnull__(1)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+int vasxprintf_exec(char ** __restrict __ret,
+ printf_comp_t __restrict __pc, va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(1, 2)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int vdxprintf_exec(int __fd, printf_comp_t __restrict __pc,
+ va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(2)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int vfxprintf_exec(FILE * __restrict __stream,
+ printf_comp_t __restrict __pc, va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(1, 2)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int vsxprintf_exec(char * __restrict __str, size_t __size,
+ printf_comp_t __restrict __pc, va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(1, 3)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+int vxprintf_exec(printf_comp_t __restrict __pc, va_list __ap)
+ __XPRINTF_ATTR((__nonnull__(1)))
+ __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+
+__END_DECLS
+
+#endif /* !_PRINTF_H */
#define RPP_SEVENBIT 0x10 /* Strip the high bit from input. */
#include <_types.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
+#include <sys/_types/_size_t.h>
__BEGIN_DECLS
char * readpassphrase(const char *, char *, size_t, int);
#include <_types.h>
#include <Availability.h>
+#include <sys/_types/_size_t.h>
/*********/
/* types */
/*********/
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
-#ifndef __cplusplus
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef __darwin_wchar_t wchar_t;
-#endif /* _WCHAR_T */
-#endif /* __cplusplus */
+#include <sys/_types/_wchar_t.h>
#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
typedef __darwin_off_t regoff_t;
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
-
typedef struct {
int re_magic;
size_t re_nsub; /* number of parenthesized subexpressions */
#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
-
-#ifndef _CT_RUNE_T
-#define _CT_RUNE_T
-typedef __darwin_ct_rune_t ct_rune_t;
-#endif
-
-#ifndef _RUNE_T
-#define _RUNE_T
-typedef __darwin_rune_t rune_t;
-#endif
-
-#ifndef __cplusplus
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef __darwin_wchar_t wchar_t;
-#endif /* _WCHAR_T */
-#endif /* __cplusplus */
-
-#ifndef _WINT_T
-#define _WINT_T
-typedef __darwin_wint_t wint_t;
-#endif
+#include <sys/_types/_size_t.h>
+#include <sys/_types/_ct_rune_t.h>
+#include <sys/_types/_rune_t.h>
+#include <sys/_types/_wchar_t.h>
+#include <sys/_types/_wint_t.h>
#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
#include <sys/cdefs.h>
#include <_types.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
+#include <sys/_types/_size_t.h>
typedef struct entry {
char *key;
#endif
#define __darwin_obsz0(object) __builtin_object_size (object, 0)
-#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1)
+#define __darwin_obsz(object) __builtin_object_size (object, _USE_FORTIFY_LEVEL > 1 ? 1 : 0)
#endif
#if _USE_FORTIFY_LEVEL > 0
-#undef sprintf
-#undef vsprintf
-
-#if __DARWIN_C_LEVEL >= 200112L
-#undef snprintf
-#undef vsnprintf
+#ifndef __has_builtin
+#define _undef__has_builtin
+#define __has_builtin(x) 0
#endif
/* sprintf, vsprintf, snprintf, vsnprintf */
-
+#if __has_builtin(__builtin___sprintf_chk) || defined(__GNUC__)
extern int __sprintf_chk (char * __restrict, int, size_t,
const char * __restrict, ...);
+#undef sprintf
#define sprintf(str, ...) \
__builtin___sprintf_chk (str, 0, __darwin_obsz(str), __VA_ARGS__)
+#endif
+#if __DARWIN_C_LEVEL >= 200112L
+#if __has_builtin(__builtin___snprintf_chk) || defined(__GNUC__)
extern int __snprintf_chk (char * __restrict, size_t, int, size_t,
const char * __restrict, ...);
-#if __DARWIN_C_LEVEL >= 200112L
+#undef snprintf
#define snprintf(str, len, ...) \
__builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
+#endif
+#if __has_builtin(__builtin___vsprintf_chk) || defined(__GNUC__)
extern int __vsprintf_chk (char * __restrict, int, size_t,
const char * __restrict, va_list);
+#undef vsprintf
#define vsprintf(str, format, ap) \
__builtin___vsprintf_chk (str, 0, __darwin_obsz(str), format, ap)
+#endif
+#if __has_builtin(__builtin___vsnprintf_chk) || defined(__GNUC__)
extern int __vsnprintf_chk (char * __restrict, size_t, int, size_t,
const char * __restrict, va_list);
+#undef vsnprintf
#define vsnprintf(str, len, format, ap) \
__builtin___vsnprintf_chk (str, len, 0, __darwin_obsz(str), format, ap)
#endif
-#endif
+#endif /* __DARWIN_C_LEVEL >= 200112L */
+#ifdef _undef__has_builtin
+#undef _undef__has_builtin
+#undef __has_builtin
#endif
+
+#endif /* _USE_FORTIFY_LEVEL > 0 */
+#endif /* _SECURE__STDIO_H_ */
#ifndef _SECURE__STRING_H_
#define _SECURE__STRING_H_
+#include <Availability.h>
#include <sys/cdefs.h>
#include <secure/_common.h>
#if _USE_FORTIFY_LEVEL > 0
-/* memcpy, mempcpy, memmove, memset, strcpy, stpcpy, strncpy, stpncpy,
- strcat, and strncat */
+#ifndef __has_builtin
+#define _undef__has_builtin
+#define __has_builtin(x) 0
+#endif
-#undef memcpy
-#undef memmove
-#undef memset
-#undef strcpy
-#if __DARWIN_C_LEVEL >= 200809L
-#undef stpcpy
-#undef stpncpy
+/* <rdar://problem/12622659> */
+#if defined(__clang__) && \
+ ((defined(__apple_build_version__) && __apple_build_version__ >= 4260006) || \
+ (!defined(__apple_build_version__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 3))))
+#define __HAS_FIXED_CHK_PROTOTYPES 1
+#else
+#define __HAS_FIXED_CHK_PROTOTYPES 0
+#endif
+
+/* memccpy, memcpy, mempcpy, memmove, memset, strcpy, strlcpy, stpcpy,
+ strncpy, stpncpy, strcat, strlcat, and strncat */
+
+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+#if __has_builtin(__builtin___memccpy_chk) && __HAS_FIXED_CHK_PROTOTYPES
+#undef memccpy
+#define memccpy(dest, src, c, len) \
+ __builtin___memccpy_chk (dest, src, c, len, __darwin_obsz0 (dest))
#endif
-#undef strncpy
-#undef strcat
-#if ! (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 32000)
-#undef strncat
#endif
+#if __has_builtin(__builtin___memcpy_chk) || defined(__GNUC__)
+#undef memcpy
#define memcpy(dest, src, len) \
- ((__darwin_obsz0 (dest) != (size_t) -1) \
- ? __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest)) \
- : __inline_memcpy_chk (dest, src, len))
-
-static __inline void *
-__inline_memcpy_chk (void *__dest, const void *__src, size_t __len)
-{
- return __builtin___memcpy_chk (__dest, __src, __len, __darwin_obsz0(__dest));
-}
+ __builtin___memcpy_chk (dest, src, len, __darwin_obsz0 (dest))
+#endif
+#if __has_builtin(__builtin___memmove_chk) || defined(__GNUC__)
+#undef memmove
#define memmove(dest, src, len) \
- ((__darwin_obsz0 (dest) != (size_t) -1) \
- ? __builtin___memmove_chk (dest, src, len, __darwin_obsz0 (dest)) \
- : __inline_memmove_chk (dest, src, len))
-
-static __inline void *
-__inline_memmove_chk (void *__dest, const void *__src, size_t __len)
-{
- return __builtin___memmove_chk (__dest, __src, __len, __darwin_obsz0(__dest));
-}
+ __builtin___memmove_chk (dest, src, len, __darwin_obsz0 (dest))
+#endif
+#if __has_builtin(__builtin___memset_chk) || defined(__GNUC__)
+#undef memset
#define memset(dest, val, len) \
- ((__darwin_obsz0 (dest) != (size_t) -1) \
- ? __builtin___memset_chk (dest, val, len, __darwin_obsz0 (dest)) \
- : __inline_memset_chk (dest, val, len))
-
-static __inline void *
-__inline_memset_chk (void *__dest, int __val, size_t __len)
-{
- return __builtin___memset_chk (__dest, __val, __len, __darwin_obsz0(__dest));
-}
+ __builtin___memset_chk (dest, val, len, __darwin_obsz0 (dest))
+#endif
+#if __has_builtin(__builtin___strcpy_chk) || defined(__GNUC__)
+#undef strcpy
#define strcpy(dest, src) \
- ((__darwin_obsz0 (dest) != (size_t) -1) \
- ? __builtin___strcpy_chk (dest, src, __darwin_obsz (dest)) \
- : __inline_strcpy_chk (dest, src))
-
-static __inline char *
-__inline_strcpy_chk (char *__restrict __dest, const char *__restrict __src)
-{
- return __builtin___strcpy_chk (__dest, __src, __darwin_obsz(__dest));
-}
+ __builtin___strcpy_chk (dest, src, __darwin_obsz (dest))
+#endif
#if __DARWIN_C_LEVEL >= 200809L
+#if __has_builtin(__builtin___stpcpy_chk) || defined(__GNUC__)
+#undef stpcpy
#define stpcpy(dest, src) \
- ((__darwin_obsz0 (dest) != (size_t) -1) \
- ? __builtin___stpcpy_chk (dest, src, __darwin_obsz (dest)) \
- : __inline_stpcpy_chk (dest, src))
-
-static __inline char *
-__inline_stpcpy_chk (char *__dest, const char *__src)
-{
- return __builtin___stpcpy_chk (__dest, __src, __darwin_obsz(__dest));
-}
+ __builtin___stpcpy_chk (dest, src, __darwin_obsz (dest))
+#endif
+#if __has_builtin(__builtin___stpncpy_chk) || __APPLE_CC__ >= 5666 || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)
+#undef stpncpy
#define stpncpy(dest, src, len) \
- ((__darwin_obsz0 (dest) != (size_t) -1) \
- ? __builtin___stpncpy_chk (dest, src, len, __darwin_obsz (dest)) \
- : __inline_stpncpy_chk (dest, src, len))
+ __builtin___stpncpy_chk (dest, src, len, __darwin_obsz (dest))
+#endif
+#endif /* _DARWIN_C_LEVEL >= 200809L */
+
+#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
+#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+#if __has_builtin(__builtin___strlcpy_chk) && __HAS_FIXED_CHK_PROTOTYPES
+#undef strlcpy
+#define strlcpy(dest, src, len) \
+ __builtin___strlcpy_chk (dest, src, len, __darwin_obsz (dest))
+#endif
-static __inline char *
-__inline_stpncpy_chk (char *__restrict __dest, const char *__restrict __src,
- size_t __len)
-{
- return __builtin___stpncpy_chk (__dest, __src, __len, __darwin_obsz(__dest));
-}
+#if __has_builtin(__builtin___strlcat_chk) && __HAS_FIXED_CHK_PROTOTYPES
+#undef strlcat
+#define strlcat(dest, src, len) \
+ __builtin___strlcat_chk (dest, src, len, __darwin_obsz (dest))
#endif
+#endif /* __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 || __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 */
+#endif /* __DARWIN_C_LEVEL >= __DARWIN_C_FULL */
+#if __has_builtin(__builtin___strncpy_chk) || defined(__GNUC__)
+#undef strncpy
#define strncpy(dest, src, len) \
- ((__darwin_obsz0 (dest) != (size_t) -1) \
- ? __builtin___strncpy_chk (dest, src, len, __darwin_obsz (dest)) \
- : __inline_strncpy_chk (dest, src, len))
-
-static __inline char *
-__inline_strncpy_chk (char *__restrict __dest, const char *__restrict __src,
- size_t __len)
-{
- return __builtin___strncpy_chk (__dest, __src, __len, __darwin_obsz(__dest));
-}
+ __builtin___strncpy_chk (dest, src, len, __darwin_obsz (dest))
+#endif
+#if __has_builtin(__builtin___strcat_chk) || defined(__GNUC__)
+#undef strcat
#define strcat(dest, src) \
- ((__darwin_obsz0 (dest) != (size_t) -1) \
- ? __builtin___strcat_chk (dest, src, __darwin_obsz (dest)) \
- : __inline_strcat_chk (dest, src))
-
-static __inline char *
-__inline_strcat_chk (char *__restrict __dest, const char *__restrict __src)
-{
- return __builtin___strcat_chk (__dest, __src, __darwin_obsz(__dest));
-}
+ __builtin___strcat_chk (dest, src, __darwin_obsz (dest))
+#endif
#if ! (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 32000)
+#if __has_builtin(__builtin___strncat_chk) || defined(__GNUC__)
+#undef strncat
#define strncat(dest, src, len) \
- ((__darwin_obsz0 (dest) != (size_t) -1) \
- ? __builtin___strncat_chk (dest, src, len, __darwin_obsz (dest)) \
- : __inline_strncat_chk (dest, src, len))
-
-static __inline char *
-__inline_strncat_chk (char *__restrict __dest, const char *__restrict __src,
- size_t __len)
-{
- return __builtin___strncat_chk (__dest, __src, __len, __darwin_obsz(__dest));
-}
+ __builtin___strncat_chk (dest, src, len, __darwin_obsz (dest))
#endif
-
#endif
+
+#ifdef _undef__has_builtin
+#undef _undef__has_builtin
+#undef __has_builtin
#endif
+
+#undef __HAS_FIXED_CHK_PROTOTYPES
+
+#endif /* _USE_FORTIFY_LEVEL > 0 */
+#endif /* _SECURE__STRING_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#ifndef _BSD_SETJMP_H
-#define _BSD_SETJMP_H
-
-#include <sys/cdefs.h>
-
-#if defined(__x86_64__)
-/*
- * _JBLEN is number of ints required to save the following:
- * rflags, rip, rbp, rsp, rbx, r12, r13, r14, r15... these are 8 bytes each
- * mxcsr, fp control word, sigmask... these are 4 bytes each
- * add 16 ints for future expansion needs...
- */
-#define _JBLEN ((9 * 2) + 3 + 16)
-typedef int jmp_buf[_JBLEN];
-typedef int sigjmp_buf[_JBLEN + 1];
-
-#elif defined(__i386__)
-
-/*
- * _JBLEN is number of ints required to save the following:
- * eax, ebx, ecx, edx, edi, esi, ebp, esp, ss, eflags, eip,
- * cs, de, es, fs, gs == 16 ints
- * onstack, mask = 2 ints
- */
-
-#define _JBLEN (18)
-typedef int jmp_buf[_JBLEN];
-typedef int sigjmp_buf[_JBLEN + 1];
-
-#elif defined(__arm__)
-
-#include <machine/signal.h>
-
-/*
- * _JBLEN is number of ints required to save the following:
- * r4-r8, r10, fp, sp, lr, sig == 10 register_t sized
- * s16-s31 == 16 register_t sized + 1 int for FSTMX
- * 1 extra int for future use
- */
-#define _JBLEN (10 + 16 + 2)
-#define _JBLEN_MAX _JBLEN
-
-typedef int jmp_buf[_JBLEN];
-typedef int sigjmp_buf[_JBLEN + 1];
-
-#else
-# error Undefined platform for setjmp
-#endif
-
-__BEGIN_DECLS
-extern int setjmp(jmp_buf);
-extern void longjmp(jmp_buf, int) __dead2;
-
-#ifndef _ANSI_SOURCE
-int _setjmp(jmp_buf);
-void _longjmp(jmp_buf, int) __dead2;
-int sigsetjmp(sigjmp_buf, int);
-void siglongjmp(sigjmp_buf, int) __dead2;
-#endif /* _ANSI_SOURCE */
-
-#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
-void longjmperror(void);
-#endif /* neither ANSI nor POSIX */
-__END_DECLS
-
-#endif /* _BSD_SETJMP_H */
#include <sys/cdefs.h>
#include <_types.h>
#include <sys/signal.h>
-
-#ifndef _PTHREAD_T
-typedef __darwin_pthread_t pthread_t;
-#define _PTHREAD_T
-#endif
+#include <sys/_types/_pthread_t.h>
#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
extern __const char *__const sys_signame[NSIG];
/* List definitions after function declarations, or Reiser cpp gets upset. */
#if defined(__i386__) || defined(__x86_64__)
/* The left shift operator on intel is modulo 32 */
-static __inline int
+__header_always_inline int
__sigbits(int __signo)
{
return __signo > __DARWIN_NSIG ? 0 : (1 << (__signo - 1));
+++ /dev/null
-/*
- * Copyright (c) 2006, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-#ifndef _SPAWN_H_
-#define _SPAWN_H_
-
-/*
- * [SPN] Support for _POSIX_SPAWN
- */
-
-#include <sys/cdefs.h>
-#include <_types.h>
-#include <sys/spawn.h> /* shared types */
-
-#include <Availability.h>
-
-/*
- * [SPN] Inclusion of the <spawn.h> header may make visible symbols defined
- * in the <sched.h>, <signal.h>, and <sys/types.h> headers.
- */
-#ifndef _PID_T
-typedef __darwin_pid_t pid_t;
-#define _PID_T
-#endif
-
-#ifndef _SIGSET_T
-#define _SIGSET_T
-typedef __darwin_sigset_t sigset_t;
-#endif
-
-#ifndef _MODE_T
-typedef __darwin_mode_t mode_t;
-#define _MODE_T
-#endif
-
-/*
- * Opaque types for use with posix_spawn() family functions. Internals are
- * not defined, and should not be accessed directly. Types are defined as
- * mandated by POSIX.
- */
-typedef void *posix_spawnattr_t;
-typedef void *posix_spawn_file_actions_t;
-
-__BEGIN_DECLS
-/*
- * gcc under c99 mode won't compile "[ __restrict]" by itself. As a workaround,
- * a dummy argument name is added.
- */
-int posix_spawn(pid_t * __restrict, const char * __restrict,
- const posix_spawn_file_actions_t *,
- const posix_spawnattr_t * __restrict,
- char *const __argv[ __restrict],
- char *const __envp[ __restrict]) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnp(pid_t * __restrict, const char * __restrict,
- const posix_spawn_file_actions_t *,
- const posix_spawnattr_t * __restrict,
- char *const __argv[ __restrict],
- char *const __envp[ __restrict]) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *, int,
- int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawn_file_actions_addopen(
- posix_spawn_file_actions_t * __restrict, int,
- const char * __restrict, int, mode_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawn_file_actions_init(posix_spawn_file_actions_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_destroy(posix_spawnattr_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict,
- sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_getflags(const posix_spawnattr_t * __restrict,
- short * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict,
- pid_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict,
- sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_init(posix_spawnattr_t *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict,
- const sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_setflags(posix_spawnattr_t *, short) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_setpgroup(posix_spawnattr_t *, pid_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict,
- const sigset_t * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-#if 0 /* _POSIX_PRIORITY_SCHEDULING [PS] : not supported */
-int posix_spawnattr_setschedparam(posix_spawnattr_t * __restrict,
- const struct sched_param * __restrict);
-int posix_spawnattr_setschedpolicy(posix_spawnattr_t *, int);
-int posix_spawnattr_getschedparam(const posix_spawnattr_t * __restrict,
- struct sched_param * __restrict);
-int posix_spawnattr_getschedpolicy(const posix_spawnattr_t * __restrict,
- int * __restrict);
-#endif /* 0 */
-
-__END_DECLS
-
-#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
-/*
- * Darwin-specific extensions below
- */
-#include <mach/exception_types.h>
-#include <mach/machine.h>
-#include <mach/port.h>
-
-#ifndef _SIZE_T
-typedef __darwin_size_t size_t;
-#define _SIZE_T
-#endif
-
-__BEGIN_DECLS
-
-int posix_spawnattr_getbinpref_np(const posix_spawnattr_t * __restrict,
- size_t, cpu_type_t *__restrict, size_t *__restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_setauditsessionport_np(posix_spawnattr_t *__restrict,
- mach_port_t) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-int posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict,
- size_t, cpu_type_t *__restrict, size_t *__restrict) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_setexceptionports_np(posix_spawnattr_t *__restrict,
- exception_mask_t, mach_port_t,
- exception_behavior_t, thread_state_flavor_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawnattr_setspecialport_np(posix_spawnattr_t *__restrict,
- mach_port_t, int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int posix_spawn_file_actions_addinherit_np(posix_spawn_file_actions_t *,
- int) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-
-__END_DECLS
-
-#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
-#endif /* _SPAWN_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2006, 2008 Apple,Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _SPAWN_PRIVATE_H_
-#define _SPAWN_PRIVATE_H_
-
-#include <spawn.h>
-#include <sys/cdefs.h>
-#include <Availability.h>
-#include <TargetConditionals.h>
-
-int posix_spawnattr_getpcontrol_np(const posix_spawnattr_t * __restrict, int * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-int posix_spawnattr_setpcontrol_np(posix_spawnattr_t *, const int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-
-int posix_spawnattr_getapptype_np(const posix_spawnattr_t * __restrict, int * __restrict) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0);
-int posix_spawnattr_setapptype_np(posix_spawnattr_t *, const int) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0);
-
-int posix_spawnattr_setcpumonitor(posix_spawnattr_t * __restrict, uint64_t, uint64_t) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0);
-int posix_spawnattr_getcpumonitor(posix_spawnattr_t * __restrict, uint64_t *, uint64_t *) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0);
-
-#if TARGET_OS_EMBEDDED
-int posix_spawnattr_setjetsam(posix_spawnattr_t * __restrict attr,
- short flags, int priority, int high_water_mark) __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_5_0);
-#endif
-
-#endif /* !defined _SPAWN_PRIVATE_H_*/
#if !defined(__need_wchar_t) && !defined(__need_size_t) \
&& !defined(__need_ptrdiff_t) && !defined(__need_NULL) \
- && !defined(__need_wint_t)
+ && !defined(__need_wint_t) && !defined(__need_rsize_t)
#define __STDDEF_H__
#endif /* none of __need_* defined */
#include <_types.h>
#if defined(__STDDEF_H__) || defined(__need_ptrdiff_t)
-#ifndef _PTRDIFF_T
-#define _PTRDIFF_T
-typedef __darwin_ptrdiff_t ptrdiff_t;
-#endif /* _PTRDIFF_T */
+#include <sys/_types/_ptrdiff_t.h>
#endif /* __STDDEF_H__ || __need_ptrdiff_t */
#if defined(__STDDEF_H__) || defined(__need_size_t)
-#ifndef _SIZE_T
-#define _SIZE_T
/* DO NOT REMOVE THIS COMMENT: fixincludes needs to see:
* _GCC_SIZE_T */
-typedef __darwin_size_t size_t;
-#endif /* _SIZE_T */
+#include <sys/_types/_size_t.h>
#endif /* __STDDEF_H__ || __need_size_t */
+#if (defined(__STDDEF_H__) && defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1) || defined(__need_rsize_t)
+#include <sys/_types/_rsize_t.h>
+#endif /* (__STDDEF_H__ && __STDC_WANT_LIB_EXT1__ >= 1) || __need_rsize_t */
+
#if defined(__STDDEF_H__) || defined(__need_wchar_t)
-#ifndef __cplusplus
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef __darwin_wchar_t wchar_t;
-#endif /* _WCHAR_T */
-#endif /* __cplusplus */
+#include <sys/_types/_wchar_t.h>
#endif /* __STDDEF_H__ || __need_wchar_t */
#if (defined(__STDDEF_H__) && !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))) \
|| defined(__need_wint_t)
-#ifndef _WINT_T
-#define _WINT_T
-typedef __darwin_wint_t wint_t;
-#endif /* _WINT_T */
+#include <sys/_types/_wint_t.h>
#endif /* __STDDEF_H__ && !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) || __need_wchar_t */
#if defined(__STDDEF_H__) || defined(__need_NULL)
-#ifndef NULL
-#define NULL __DARWIN_NULL
-#endif /* ! NULL */
+#include <sys/_types/_null.h>
#endif /* __STDDEF_H__ || __need_NULL */
#ifdef __STDDEF_H__
/* from ISO/IEC 988:1999 spec */
/* 7.18.1.1 Exact-width integer types */
-#ifndef _INT8_T
-#define _INT8_T
-typedef signed char int8_t;
-#endif /*_INT8_T */
-
-#ifndef _INT16_T
-#define _INT16_T
-typedef short int16_t;
-#endif /* _INT16_T */
-
-#ifndef _INT32_T
-#define _INT32_T
-typedef int int32_t;
-#endif /* _INT32_T */
-
-#ifndef _INT64_T
-#define _INT64_T
-typedef long long int64_t;
-#endif /* _INT64_T */
-
-#ifndef _UINT8_T
-#define _UINT8_T
-typedef unsigned char uint8_t;
-#endif /*_UINT8_T */
-
-#ifndef _UINT16_T
-#define _UINT16_T
-typedef unsigned short uint16_t;
-#endif /* _UINT16_T */
-
-#ifndef _UINT32_T
-#define _UINT32_T
-typedef unsigned int uint32_t;
-#endif /* _UINT32_T */
-
-#ifndef _UINT64_T
-#define _UINT64_T
-typedef unsigned long long uint64_t;
-#endif /* _UINT64_T */
+#include <sys/_types/_int8_t.h>
+#include <sys/_types/_int16_t.h>
+#include <sys/_types/_int32_t.h>
+#include <sys/_types/_int64_t.h>
+
+#include <_types/_uint8_t.h>
+#include <_types/_uint16_t.h>
+#include <_types/_uint32_t.h>
+#include <_types/_uint64_t.h>
/* 7.18.1.2 Minimum-width integer types */
typedef int8_t int_least8_t;
/* 7.18.1.4 Integer types capable of holding object pointers */
-#ifndef _INTPTR_T
-#define _INTPTR_T
-typedef long intptr_t;
-#endif /* _INTPTR_T */
-
-#ifndef _UINTPTR_T
-#define _UINTPTR_T
-typedef unsigned long uintptr_t;
-#endif /* _UINTPTR_T */
+#include <sys/_types.h>
+#include <sys/_types/_intptr_t.h>
+#include <sys/_types/_uintptr_t.h>
/* 7.18.1.5 Greatest-width integer types */
-#ifndef _INTMAX_T
-#define _INTMAX_T
-#ifdef __INTMAX_TYPE__
-typedef __INTMAX_TYPE__ intmax_t;
-#else /* __INTMAX_TYPE__ */
-typedef long long intmax_t;
-#endif /* __INTMAX_TYPE__ */
-#endif /* _INTMAX_T */
-
-#ifndef _UINTMAX_T
-#define _UINTMAX_T
-#ifdef __UINTMAX_TYPE__
-typedef __UINTMAX_TYPE__ uintmax_t;
-#else /* __UINTMAX_TYPE__ */
-typedef unsigned long long uintmax_t;
-#endif /* __UINTMAX_TYPE__ */
-#endif /* _UINTMAX_T */
+#include <_types/_intmax_t.h>
+#include <_types/_uintmax_t.h>
/* 7.18.2 Limits of specified-width integer types:
* These #defines specify the minimum and maximum limits
#define SIZE_MAX UINT32_MAX
#endif
+#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1
+#define RSIZE_MAX (SIZE_MAX >> 1)
+#endif
+
#ifndef WCHAR_MAX
# ifdef __WCHAR_MAX__
# define WCHAR_MAX __WCHAR_MAX__
#define UINT32_C(v) (v ## U)
#define UINT64_C(v) (v ## ULL)
+#ifdef __LP64__
+#define INTMAX_C(v) (v ## L)
+#define UINTMAX_C(v) (v ## UL)
+#else
#define INTMAX_C(v) (v ## LL)
#define UINTMAX_C(v) (v ## ULL)
+#endif
#endif /* _STDINT_H_ */
#include <_types.h>
-#ifndef _VA_LIST
-#define _VA_LIST
/* DO NOT REMOVE THIS COMMENT: fixincludes needs to see:
* __gnuc_va_list and include <stdarg.h> */
-typedef __darwin_va_list va_list;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
-
-#ifndef NULL
-#define NULL __DARWIN_NULL
-#endif /* ! NULL */
+#include <sys/_types/_va_list.h>
+#include <sys/_types/_size_t.h>
+#include <sys/_types/_null.h>
typedef __darwin_off_t fpos_t;
int sprintf(char * __restrict, const char * __restrict, ...) __printflike(2, 3);
int sscanf(const char * __restrict, const char * __restrict, ...) __scanflike(2, 3);
FILE *tmpfile(void);
+
+#if !defined(_POSIX_C_SOURCE)
+__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tmpnam(3), it is highly recommended that you use mkstemp(3) instead.")
+#endif
char *tmpnam(char *);
int ungetc(int, FILE *);
int vfprintf(FILE * __restrict, const char * __restrict, va_list) __printflike(2, 0);
*/
#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++))
#if defined(__GNUC__) && defined(__STDC__)
-static __inline int __sputc(int _c, FILE *_p) {
+__header_always_inline int __sputc(int _c, FILE *_p) {
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
return (*_p->_p++ = _c);
else
int putw(int, FILE *);
#endif
+#if !defined(_POSIX_C_SOURCE)
+__deprecated_msg("This function is provided for compatibility reasons only. Due to security concerns inherent in the design of tempnam(3), it is highly recommended that you use mkstemp(3) instead.")
+#endif
//Begin-Libc
#ifndef LIBC_ALIAS_TEMPNAM
//End-Libc
*/
#if __DARWIN_C_LEVEL >= 200112L
-#ifndef _OFF_T
-#define _OFF_T
-typedef __darwin_off_t off_t;
-#endif
+#include <sys/_types/_off_t.h>
__BEGIN_DECLS
int fseeko(FILE *, off_t, int);
*/
#if __DARWIN_C_LEVEL >= 200809L
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef __darwin_ssize_t ssize_t;
-#endif
+#include <sys/_types/_ssize_t.h>
__BEGIN_DECLS
int dprintf(int, const char * __restrict, ...) __printflike(2, 3) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
extern __const int sys_nerr; /* perror(3) external variables */
extern __const char *__const sys_errlist[];
-int asprintf(char **, const char *, ...) __printflike(2, 3);
+int asprintf(char ** __restrict, const char * __restrict, ...) __printflike(2, 3);
char *ctermid_r(char *);
char *fgetln(FILE *, size_t *);
__const char *fmtcheck(const char *, const char *);
int fpurge(FILE *);
void setbuffer(FILE *, char *, int);
int setlinebuf(FILE *);
-int vasprintf(char **, const char *, va_list) __printflike(2, 0);
+int vasprintf(char ** __restrict, const char * __restrict, va_list) __printflike(2, 0);
FILE *zopen(const char *, const char *, int);
#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
#endif /* !_ANSI_SOURCE */
-#ifndef _SIZE_T
-#define _SIZE_T
/* DO NOT REMOVE THIS COMMENT: fixincludes needs to see:
* _GCC_SIZE_T */
-typedef __darwin_size_t size_t;
-#endif
+#include <sys/_types/_size_t.h>
#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
-#ifndef _CT_RUNE_T
-#define _CT_RUNE_T
-typedef __darwin_ct_rune_t ct_rune_t;
-#endif
-
-#ifndef _RUNE_T
-#define _RUNE_T
-typedef __darwin_rune_t rune_t;
-#endif
+#include <sys/_types/_ct_rune_t.h>
+#include <sys/_types/_rune_t.h>
#endif /* !_ANSI_SOURCE && (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
-#ifndef __cplusplus
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef __darwin_wchar_t wchar_t;
-#endif /* _WCHAR_T */
-#endif /* __cplusplus */
+#include <sys/_types/_wchar_t.h>
typedef struct {
int quot; /* quotient */
} lldiv_t;
#endif /* !__DARWIN_NO_LONG_LONG */
-#ifndef NULL
-#define NULL __DARWIN_NULL
-#endif /* ! NULL */
+#include <sys/_types/_null.h>
#define EXIT_FAILURE 1
#define EXIT_SUCCESS 0
#if !defined(_ANSI_SOURCE) && (!defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE))
#include <machine/types.h>
-#ifndef _DEV_T
-typedef __darwin_dev_t dev_t;
-#define _DEV_T
-#endif
-
-#ifndef _MODE_T
-typedef __darwin_mode_t mode_t;
-#define _MODE_T
-#endif
+#include <sys/_types/_dev_t.h>
+#include <sys/_types/_mode_t.h>
-u_int32_t
- arc4random(void);
+u_int32_t arc4random(void);
void arc4random_addrandom(unsigned char * /*dat*/, int /*datlen*/);
void arc4random_buf(void * /*buf*/, size_t /*nbytes*/) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
void arc4random_stir(void);
#define _STRING_H_
#include <_types.h>
-
#include <sys/cdefs.h>
#include <Availability.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
-
-#ifndef NULL
-#define NULL __DARWIN_NULL
-#endif /* ! NULL */
-
-
+#include <sys/_types/_size_t.h>
+#include <sys/_types/_null.h>
/* ANSI-C */
__END_DECLS
#endif /* __DARWIN_C_LEVEL >= 200809L */
+/* C11 Annex K */
+#if defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1
+#include <sys/_types/_rsize_t.h>
+#include <sys/_types/_errno_t.h>
+
+__BEGIN_DECLS
+errno_t memset_s(void *, rsize_t, int, rsize_t) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
+__END_DECLS
+#endif
/* Darwin extensions */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef __darwin_ssize_t ssize_t;
-#endif
+#include <sys/_types/_ssize_t.h>
__BEGIN_DECLS
void *memmem(const void *, size_t, const void *, size_t) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
#include <sys/cdefs.h>
#include <Availability.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
+#include <sys/_types/_size_t.h>
__BEGIN_DECLS
/* Removed in Issue 7 */
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
__BEGIN_DECLS
int ffsl(long) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
+int ffsll(long long) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
int fls(int) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
int flsl(long) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
+int flsll(long long) __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0);
__END_DECLS
#include <string.h>
#define LIBC_EXTSN(sym) __asm("_" __STRING(sym) LIBC_SUF_EXTSN)
#define LIBC_EXTSN_C(sym) __asm("_" __STRING(sym) LIBC_SUF_EXTSN LIBC_SUF_NON_CANCELABLE)
-extern int __pthread_tsd_first;
extern int pthread_key_init_np(int, void (*)(void *));
-#define __LIBC_PTHREAD_KEY(x) (__pthread_tsd_first + (x))
+#include <TargetConditionals.h>
+#if TARGET_IPHONE_SIMULATOR
+/* Simulator keys are offset by 200 */
+#define __LIBC_PTHREAD_KEY(x) (210 + (x))
+#else
+#define __LIBC_PTHREAD_KEY(x) (10 + (x))
+#endif
/*
* Libc pthread key assignments
--- /dev/null
+/* $NetBSD: rbtree.h,v 1.2 2012/02/17 08:20:55 yamt Exp $ */
+
+/*-
+ * Copyright (c) 2001 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Portions Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas <matt@3am-software.com>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _SYS_RBTREE_H_
+#define _SYS_RBTREE_H_
+
+#include <Availability.h>
+
+#include <sys/types.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <sys/queue.h>
+
+__BEGIN_DECLS
+
+
+#define RB_DIR_LEFT 0
+#define RB_DIR_RIGHT 1
+
+#define RB_TREE_MIN(T) rb_tree_iterate((T), NULL, RB_DIR_RIGHT)
+#define RB_TREE_MAX(T) rb_tree_iterate((T), NULL, RB_DIR_LEFT)
+#define RB_TREE_FOREACH(N, T) \
+ for ((N) = RB_TREE_MIN(T); (N); \
+ (N) = rb_tree_iterate((T), (N), RB_DIR_RIGHT))
+#define RB_TREE_FOREACH_REVERSE(N, T) \
+ for ((N) = RB_TREE_MAX(T); (N); \
+ (N) = rb_tree_iterate((T), (N), RB_DIR_LEFT))
+
+/*
+ * rbto_compare_nodes_fn:
+ * return a positive value if the first node > the second node.
+ * return a negative value if the first node < the second node.
+ * return 0 if they are considered same.
+ *
+ * rbto_compare_key_fn:
+ * return a positive value if the node > the key.
+ * return a negative value if the node < the key.
+ * return 0 if they are considered same.
+ */
+
+typedef signed int (*rbto_compare_nodes_fn)(void *, const void *, const void *);
+typedef signed int (*rbto_compare_key_fn)(void *, const void *, const void *);
+
+typedef struct {
+ rbto_compare_nodes_fn rbto_compare_nodes;
+ rbto_compare_key_fn rbto_compare_key;
+ size_t rbto_node_offset;
+ void *rbto_context;
+} rb_tree_ops_t;
+
+//Begin-Libc
+#ifdef _RBTREE_NO_OPAQUE_STRUCTS_
+typedef struct rb_node rb_node_t;
+typedef struct rb_tree rb_tree_t;
+#else
+//End-Libc
+typedef struct rb_node { void * opaque[3]; } rb_node_t;
+typedef struct rb_tree { void *opaque[8]; } rb_tree_t;
+//Begin-Libc
+#endif
+//End-Libc
+
+#define _rb_availability __OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0);
+void rb_tree_init(rb_tree_t *, const rb_tree_ops_t *) _rb_availability;
+void * rb_tree_insert_node(rb_tree_t *, void *) _rb_availability;
+void * rb_tree_find_node(rb_tree_t *, const void *) _rb_availability;
+void * rb_tree_find_node_geq(rb_tree_t *, const void *) _rb_availability;
+void * rb_tree_find_node_leq(rb_tree_t *, const void *) _rb_availability;
+void rb_tree_remove_node(rb_tree_t *, void *) _rb_availability;
+void * rb_tree_iterate(rb_tree_t *, void *, const unsigned int) _rb_availability;
+size_t rb_tree_count(rb_tree_t *) _rb_availability;
+#undef _rb_availability
+
+__END_DECLS
+
+#endif /* _SYS_RBTREE_H_*/
#include <sys/_types.h>
#include <sys/cdefs.h>
-#ifndef _FSBLKCNT_T
-#define _FSBLKCNT_T
-typedef __darwin_fsblkcnt_t fsblkcnt_t;
-#endif
-
-#ifndef _FSFILCNT_T
-#define _FSFILCNT_T
-typedef __darwin_fsfilcnt_t fsfilcnt_t;
-#endif
+#include <sys/_types/_fsblkcnt_t.h>
+#include <sys/_types/_fsfilcnt_t.h>
/* Following structure is used as a statvfs/fstatvfs function parameter */
struct statvfs {
#include <sys/cdefs.h>
#include <sys/termios.h>
#include <_types.h>
-
-#ifndef _PID_T
-typedef __darwin_pid_t pid_t;
-#define _PID_T
-#endif
+#include <sys/_types/_pid_t.h>
__BEGIN_DECLS
pid_t tcgetsid(int);
#define __need_struct_timespec
#include <_structs.h>
-
-#ifndef NULL
-#define NULL __DARWIN_NULL
-#endif /* ! NULL */
-
-#ifndef _CLOCK_T
-#define _CLOCK_T
-typedef __darwin_clock_t clock_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef __darwin_time_t time_t;
-#endif
+#include <sys/_types/_null.h>
+#include <sys/_types/_clock_t.h>
+#include <sys/_types/_size_t.h>
+#include <sys/_types/_time_t.h>
struct tm {
int tm_sec; /* seconds after the minute [0-60] */
+++ /dev/null
-/*
- * Copyright (c) 2002, 2008, 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * These routines are DEPRECATED and should not be used.
- */
-#ifndef _UCONTEXT_H_
-#define _UCONTEXT_H_
-
-#include <sys/cdefs.h>
-
-//Begin-Libc
-#ifdef __LIBC__
-#include <sys/ucontext.h>
-__BEGIN_DECLS
-int getcontext(ucontext_t *);
-void makecontext(ucontext_t *, void (*)(), int, ...);
-int setcontext(const ucontext_t *);
-int swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict);
-__END_DECLS
-#else /* !__LIBC__ */
-//End-Libc
-#ifdef _XOPEN_SOURCE
-#include <sys/ucontext.h>
-#include <Availability.h>
-
-__BEGIN_DECLS
-int getcontext(ucontext_t *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0);
-void makecontext(ucontext_t *, void (*)(), int, ...) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0);
-int setcontext(const ucontext_t *) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0);
-int swapcontext(ucontext_t * __restrict, const ucontext_t * __restrict) __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_5, __MAC_10_6, __IPHONE_2_0, __IPHONE_2_0);
-__END_DECLS
-#else /* !_XOPEN_SOURCE */
-#error The deprecated ucontext routines require _XOPEN_SOURCE to be defined
-#endif /* _XOPEN_SOURCE */
-//Begin-Libc
-#endif /* __LIBC__ */
-//End-Libc
-
-#endif /* _UCONTEXT_H_ */
#include <_types.h>
#include <sys/unistd.h>
#include <Availability.h>
-
-#ifndef _GID_T
-#define _GID_T
-typedef __darwin_gid_t gid_t;
-#endif
-
-#ifndef _INTPTR_T
-#define _INTPTR_T
-typedef __darwin_intptr_t intptr_t;
-#endif
-
-#ifndef _OFF_T
-#define _OFF_T
-typedef __darwin_off_t off_t;
-#endif
-
-#ifndef _PID_T
-#define _PID_T
-typedef __darwin_pid_t pid_t;
-#endif
-
-#ifndef _SIZE_T
-#define _SIZE_T
+#include <sys/_types/_gid_t.h>
+#include <sys/_types/_intptr_t.h>
+#include <sys/_types/_off_t.h>
+#include <sys/_types/_pid_t.h>
/* DO NOT REMOVE THIS COMMENT: fixincludes needs to see:
* _GCC_SIZE_T */
-typedef __darwin_size_t size_t;
-#endif
-
-#ifndef _SSIZE_T
-#define _SSIZE_T
-typedef __darwin_ssize_t ssize_t;
-#endif
-
-#ifndef _UID_T
-#define _UID_T
-typedef __darwin_uid_t uid_t; /* user id */
-#endif
-
-#ifndef _USECONDS_T
-#define _USECONDS_T
-typedef __darwin_useconds_t useconds_t;
-#endif
-
-#ifndef NULL
-#define NULL __DARWIN_NULL
-#endif /* ! NULL */
+#include <sys/_types/_size_t.h>
+#include <sys/_types/_ssize_t.h>
+#include <sys/_types/_uid_t.h>
+#include <sys/_types/_useconds_t.h>
+#include <sys/_types/_null.h>
#define STDIN_FILENO 0 /* standard input file descriptor */
#define STDOUT_FILENO 1 /* standard output file descriptor */
/* Begin XSI */
/* Removed in Issue 6 */
#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L
+#if !defined(_POSIX_C_SOURCE)
+__deprecated
+#endif
void *brk(const void *);
int chroot(const char *) __POSIX_C_DEPRECATED(199506L);
#endif
#if !defined(_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 200112L
/* Note that Issue 5 changed the argument as intprt_t,
* but we keep it as int for binary compatability. */
+#if !defined(_POSIX_C_SOURCE)
+__deprecated
+#endif
void *sbrk(int);
#endif
#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
#include <sys/select.h>
-#ifndef _DEV_T
-#define _DEV_T
-typedef __darwin_dev_t dev_t;
-#endif
-
-#ifndef _MODE_T
-#define _MODE_T
-typedef __darwin_mode_t mode_t;
-#endif
-
-#ifndef _UUID_T
-#define _UUID_T
-typedef __darwin_uuid_t uuid_t;
-#endif /* _UUID_T */
+#include <sys/_types/_dev_t.h>
+#include <sys/_types/_mode_t.h>
+#include <sys/_types/_uuid_t.h>
__BEGIN_DECLS
void _Exit(int) __dead2;
char *fflagstostr(unsigned long);
int getdomainname(char *, int);
int getgrouplist(const char *, int, int *, int *);
-int gethostuuid(uuid_t, const struct timespec *) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
+#if defined(__has_include)
+#if __has_include(<gethostuuid_private.h>)
+#include <gethostuuid_private.h>
+#else
+#include <gethostuuid.h>
+#endif
+#else
+#include <gethostuuid.h>
+#endif
mode_t getmode(const void *, mode_t);
int getpeereid(int, uid_t *, gid_t *);
int getsgroups_np(int *, uuid_t);
#define _UTIME_H_
#include <_types.h>
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef __darwin_time_t time_t;
-#endif /* _TIME_T */
+#include <sys/_types/_time_t.h>
struct utimbuf {
time_t actime; /* Access time */
*/
#include <_types.h>
-
-#ifndef _TIME_T
-#define _TIME_T
-typedef __darwin_time_t time_t;
-#endif
+#include <sys/_types/_time_t.h>
/* These files no longer exist in 10.5 and later */
#define _PATH_UTMP "/var/run/utmp"
#define _VIS_H_
#include <_types.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
+#include <sys/_types/_size_t.h>
/*
* to select alternate encoding format
#include <sys/cdefs.h>
#include <Availability.h>
-#ifndef NULL
-#define NULL __DARWIN_NULL
-#endif /* ! NULL */
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
-
-#ifndef _MBSTATE_T
-#define _MBSTATE_T
-typedef __darwin_mbstate_t mbstate_t;
-#endif
-
-#ifndef _CT_RUNE_T
-#define _CT_RUNE_T
-typedef __darwin_ct_rune_t ct_rune_t;
-#endif
-
-#ifndef _RUNE_T
-#define _RUNE_T
-typedef __darwin_rune_t rune_t;
-#endif
-
-#ifndef __cplusplus
-#ifndef _WCHAR_T
-#define _WCHAR_T
-typedef __darwin_wchar_t wchar_t;
-#endif /* _WCHAR_T */
-#endif /* __cplusplus */
+#include <sys/_types/_null.h>
+#include <sys/_types/_size_t.h>
+#include <sys/_types/_mbstate_t.h>
+#include <sys/_types/_ct_rune_t.h>
+#include <sys/_types/_rune_t.h>
+#include <sys/_types/_wchar_t.h>
#ifndef WCHAR_MIN
#define WCHAR_MIN __DARWIN_WCHAR_MIN
#include <sys/cdefs.h>
#include <_types.h>
+#include <_types/_wctrans_t.h>
-#ifndef _WCTRANS_T
-#define _WCTRANS_T
-typedef __darwin_wctrans_t wctrans_t;
-#endif
-
+//Begin-Libc
/*
* _EXTERNALIZE_WCTYPE_INLINES_TOP_ is defined in locale/iswctype.c to tell us
* to generate code for extern versions of all top-level inline functions.
*/
#ifdef _EXTERNALIZE_WCTYPE_INLINES_TOP_
#define _USE_CTYPE_INLINE_
-#define __DARWIN_WCTYPE_TOP_static_inline
+#define __DARWIN_WCTYPE_TOP_inline
#else /* !_EXTERNALIZE_WCTYPE_INLINES_TOP_ */
-#define __DARWIN_WCTYPE_TOP_static_inline static __inline
+//End-Libc
+#define __DARWIN_WCTYPE_TOP_inline __header_inline
+//Begin-Libc
#endif /* _EXTERNALIZE_WCTYPE_INLINES_TOP_ */
+//End-Libc
#include <_wctype.h>
#include <ctype.h>
#if !defined(_DONT_USE_CTYPE_INLINE_) && \
(defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus))
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswblank(wint_t _wc)
{
return (__istype(_wc, _CTYPE_B));
}
#if !defined(_ANSI_SOURCE)
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswascii(wint_t _wc)
{
return ((_wc & ~0x7F) == 0);
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswhexnumber(wint_t _wc)
{
return (__istype(_wc, _CTYPE_X));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswideogram(wint_t _wc)
{
return (__istype(_wc, _CTYPE_I));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswnumber(wint_t _wc)
{
return (__istype(_wc, _CTYPE_D));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswphonogram(wint_t _wc)
{
return (__istype(_wc, _CTYPE_Q));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswrune(wint_t _wc)
{
return (__istype(_wc, 0xFFFFFFF0L));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswspecial(wint_t _wc)
{
return (__istype(_wc, _CTYPE_T));
#include <sys/cdefs.h>
#include <_types.h>
-
-#ifndef _SIZE_T
-#define _SIZE_T
-typedef __darwin_size_t size_t;
-#endif
+#include <sys/_types/_size_t.h>
+#include <Availability.h>
typedef struct {
size_t we_wordc;
#define WRDE_BADCHAR 1
#define WRDE_BADVAL 2
#define WRDE_CMDSUB 3
-#define WRDE_NOSPACE 4
-#define WRDE_NOSYS 5
+#define WRDE_NOSPACE 4
+#define WRDE_NOSYS 5
#define WRDE_SYNTAX 6
__BEGIN_DECLS
-int wordexp(const char * __restrict, wordexp_t * __restrict, int);
-void wordfree(wordexp_t *);
+int wordexp(const char * __restrict, wordexp_t * __restrict, int) __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_NA);
+void wordfree(wordexp_t *) __OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_NA);
__END_DECLS
#endif /* _WORDEXP_H */
#if !defined(_DONT_USE_CTYPE_INLINE_) && \
(defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus))
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswalnum_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_A|_CTYPE_D, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswalpha_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_A, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswcntrl_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_C, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswctype_l(wint_t _wc, wctype_t _charclass, locale_t _l)
{
return (__istype_l(_wc, _charclass, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswdigit_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_D, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswgraph_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_G, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswlower_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_L, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswprint_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_R, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswpunct_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_P, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswspace_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_S, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswupper_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_U, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswxdigit_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_X, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline wint_t
+__DARWIN_WCTYPE_TOP_inline wint_t
towlower_l(wint_t _wc, locale_t _l)
{
return (__tolower_l(_wc, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline wint_t
+__DARWIN_WCTYPE_TOP_inline wint_t
towupper_l(wint_t _wc, locale_t _l)
{
return (__toupper_l(_wc, _l));
//Begin-Libc
#ifdef __LIBC__
-__DARWIN_CTYPE_static_inline int
+__DARWIN_CTYPE_inline int
__maskrune_l(__darwin_ct_rune_t _c, unsigned long _f, locale_t _l)
{
return ((_c < 0 || _c >= _CACHED_RUNES) ? ___runetype_l(_c, _l) :
#endif /* __LIBC__ */
//End-Libc
-__DARWIN_CTYPE_static_inline int
+__DARWIN_CTYPE_inline int
__istype_l(__darwin_ct_rune_t _c, unsigned long _f, locale_t _l)
{
return !!(isascii(_c) ? (_DefaultRuneLocale.__runetype[_c] & _f)
: __maskrune_l(_c, _f, _l));
}
-__DARWIN_CTYPE_static_inline __darwin_ct_rune_t
+__DARWIN_CTYPE_inline __darwin_ct_rune_t
__toupper_l(__darwin_ct_rune_t _c, locale_t _l)
{
return isascii(_c) ? _DefaultRuneLocale.__mapupper[_c]
: ___toupper_l(_c, _l);
}
-__DARWIN_CTYPE_static_inline __darwin_ct_rune_t
+__DARWIN_CTYPE_inline __darwin_ct_rune_t
__tolower_l(__darwin_ct_rune_t _c, locale_t _l)
{
return isascii(_c) ? _DefaultRuneLocale.__maplower[_c]
: ___tolower_l(_c, _l);
}
-__DARWIN_CTYPE_static_inline int
+__DARWIN_CTYPE_inline int
__wcwidth_l(__darwin_ct_rune_t _c, locale_t _l)
{
unsigned int _x;
#ifndef _EXTERNALIZE_CTYPE_INLINES_
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
digittoint_l(int c, locale_t l)
{
return (__maskrune_l(c, 0x0F, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isalnum_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_A|_CTYPE_D, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isalpha_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_A, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isblank_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_B, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
iscntrl_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_C, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isdigit_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_D, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isgraph_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_G, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
ishexnumber_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_X, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isideogram_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_I, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
islower_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_L, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isnumber_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_D, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isphonogram_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_Q, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isprint_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_R, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
ispunct_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_P, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isrune_l(int c, locale_t l)
{
return (__istype_l(c, 0xFFFFFFF0L, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isspace_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_S, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isspecial_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_T, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isupper_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_U, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
isxdigit_l(int c, locale_t l)
{
return (__istype_l(c, _CTYPE_X, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
tolower_l(int c, locale_t l)
{
return (__tolower_l(c, l));
}
-__DARWIN_CTYPE_TOP_static_inline int
+__DARWIN_CTYPE_TOP_inline int
toupper_l(int c, locale_t l)
{
return (__toupper_l(c, l));
__BEGIN_DECLS
-int fprintf_l(FILE * __restrict, locale_t, const char * __restrict, ...)
+int fprintf_l(FILE * __restrict, locale_t __restrict, const char * __restrict, ...)
__printflike(3, 4);
-int fscanf_l(FILE * __restrict, locale_t, const char * __restrict, ...)
+int fscanf_l(FILE * __restrict, locale_t __restrict, const char * __restrict, ...)
__scanflike(3, 4);
-int printf_l(locale_t, const char * __restrict, ...)
+int printf_l(locale_t __restrict, const char * __restrict, ...)
__printflike(2, 3);
-int scanf_l(locale_t, const char * __restrict, ...)
+int scanf_l(locale_t __restrict, const char * __restrict, ...)
__scanflike(2, 3);
-int sprintf_l(char * __restrict, locale_t, const char * __restrict, ...)
+int sprintf_l(char * __restrict, locale_t __restrict, const char * __restrict, ...)
__printflike(3, 4);
-int sscanf_l(const char * __restrict, locale_t, const char * __restrict, ...)
+int sscanf_l(const char * __restrict, locale_t __restrict, const char * __restrict, ...)
__scanflike(3, 4);
-int vfprintf_l(FILE * __restrict, locale_t, const char * __restrict, va_list)
+int vfprintf_l(FILE * __restrict, locale_t __restrict, const char * __restrict, va_list)
__printflike(3, 0);
-int vprintf_l(locale_t, const char * __restrict, va_list)
+int vprintf_l(locale_t __restrict, const char * __restrict, va_list)
__printflike(2, 0);
-int vsprintf_l(char * __restrict, locale_t, const char * __restrict, va_list)
+int vsprintf_l(char * __restrict, locale_t __restrict, const char * __restrict, va_list)
__printflike(3, 0);
-#if __DARWIN_C_LEVEL >= 200112L
-int snprintf_l(char * __restrict, size_t, locale_t, const char * __restrict, ...)
+#if __DARWIN_C_LEVEL >= 200112L || defined(__cplusplus)
+int snprintf_l(char * __restrict, size_t, locale_t __restrict, const char * __restrict, ...)
__printflike(4, 5);
-int vfscanf_l(FILE * __restrict, locale_t, const char * __restrict, va_list)
+int vfscanf_l(FILE * __restrict, locale_t __restrict, const char * __restrict, va_list)
__scanflike(3, 0);
-int vscanf_l(locale_t, const char * __restrict, va_list)
+int vscanf_l(locale_t __restrict, const char * __restrict, va_list)
__scanflike(2, 0);
-int vsnprintf_l(char * __restrict, size_t, locale_t, const char * __restrict, va_list)
+int vsnprintf_l(char * __restrict, size_t, locale_t __restrict, const char * __restrict, va_list)
__printflike(4, 0);
-int vsscanf_l(const char * __restrict, locale_t, const char * __restrict, va_list)
+int vsscanf_l(const char * __restrict, locale_t __restrict, const char * __restrict, va_list)
__scanflike(3, 0);
#endif
-#if __DARWIN_C_LEVEL >= 200809L
-int dprintf_l(int, locale_t, const char * __restrict, ...)
+#if __DARWIN_C_LEVEL >= 200809L || defined(__cplusplus)
+int dprintf_l(int, locale_t __restrict, const char * __restrict, ...)
__printflike(3, 4) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
-int vdprintf_l(int, locale_t, const char * __restrict, va_list)
+int vdprintf_l(int, locale_t __restrict, const char * __restrict, va_list)
__printflike(3, 0) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
#endif
-#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL
-int asprintf_l(char **, locale_t, const char *, ...)
+#if __DARWIN_C_LEVEL >= __DARWIN_C_FULL || defined(__cplusplus)
+int asprintf_l(char ** __restrict, locale_t __restrict, const char * __restrict, ...)
__printflike(3, 4);
-int vasprintf_l(char **, locale_t, const char *, va_list)
+int vasprintf_l(char ** __restrict, locale_t __restrict, const char * __restrict, va_list)
__printflike(3, 0);
#endif
#if !defined(_DONT_USE_CTYPE_INLINE_) && \
(defined(_USE_CTYPE_INLINE_) || defined(__GNUC__) || defined(__cplusplus))
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswblank_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_B, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswhexnumber_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_X, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswideogram_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_I, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswnumber_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_D, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswphonogram_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_Q, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswrune_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, 0xFFFFFFF0L, _l));
}
-__DARWIN_WCTYPE_TOP_static_inline int
+__DARWIN_WCTYPE_TOP_inline int
iswspecial_l(wint_t _wc, locale_t _l)
{
return (__istype_l(_wc, _CTYPE_T, _l));
struct lconv *
localeconv_l(locale_t loc)
{
- struct lconv *lc;
-
NORMALIZE_LOCALE(loc);
if (loc->__mlocale_changed) {
/*
* Category names for getenv()
*/
-static char *categories[_LC_LAST] = {
+static const char * const categories[_LC_LAST] = {
"LC_ALL",
"LC_COLLATE",
"LC_CTYPE",
static char new_categories[_LC_LAST][ENCODING_LEN + 1];
static char saved_categories[_LC_LAST][ENCODING_LEN + 1];
-static char current_locale_string[_LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1)];
-
static char *currentlocale(void);
static char *loadlocale(int);
__private_extern__ const char *__get_locale_env(int);
{
int i;
- (void)strcpy(current_locale_string, current_categories[1]);
+ size_t bufsiz = _LC_LAST * (ENCODING_LEN + 1/*"/"*/ + 1);
+ static char *current_locale_string = NULL;
+
+ if (current_locale_string == NULL) {
+ current_locale_string = malloc(bufsiz);
+ if (current_locale_string == NULL) {
+ return NULL;
+ }
+ }
+
+ (void)strlcpy(current_locale_string, current_categories[1], bufsiz);
for (i = 2; i < _LC_LAST; ++i)
if (strcmp(current_categories[1], current_categories[i])) {
#include <wchar.h>
#include "mblocal.h"
-#define UTF8_MB_CUR_MAX 6
+/*
+ * 10952550: detect ill-formed UTF-8
+ * Unicode 6.0, section D92, mandates specific byte sequences for well-
+ * formed UTF-8. UTF-8 sequences are now limited to 4 bytes, while the
+ * FreeBSD code originally handled up to 6. Illegal surrogate code point
+ * sequences are now detected. And while "non-shortest forms" were detected,
+ * this only happened after completing the sequence. Now, all ill-formed
+ * sequences are detected at the earliest point.
+ *
+ * Table 3-7. Well-Formed UTF-8 Byte Sequences
+ *
+ * Code Points 1st 2nd 3rd 4th Byte
+ * U+0000..U+007F 00..7F
+ * U+0080..U+07FF C2..DF 80..BF
+ * U+0800..U+0FFF E0 A0..BF 80..BF
+ * U+1000..U+CFFF E1..EC 80..BF 80..BF
+ * U+D000..U+D7FF ED 80..9F 80..BF
+ * U+E000..U+FFFF EE..EF 80..BF 80..BF
+ * U+10000..U+3FFFF F0 90..BF 80..BF 80..BF
+ * U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF
+ * U+100000..U+10FFFF F4 80..8F 80..BF 80..BF
+ *
+ * Note that while any 3rd and 4th byte can be in the range 80..BF, the
+ * second byte is often limited to a smaller range.
+ */
+
+typedef struct {
+ unsigned char lowerbound;
+ unsigned char upperbound;
+} SecondByte;
+static SecondByte sb_00_00 = {0x00, 0x00};
+static SecondByte sb_80_8F = {0x80, 0x8F};
+static SecondByte sb_80_9F = {0x80, 0x9F};
+static SecondByte sb_80_BF = {0x80, 0xBF};
+static SecondByte sb_90_BF = {0x90, 0xBF};
+static SecondByte sb_A0_BF = {0xA0, 0xBF};
+
+#define UTF8_MB_CUR_MAX 4
static size_t _UTF8_mbrtowc(wchar_t * __restrict, const char * __restrict,
size_t, mbstate_t * __restrict, locale_t);
typedef struct {
wchar_t ch;
int want;
- wchar_t lbound;
+ SecondByte sb;
} _UTF8State;
__private_extern__ int
{
_UTF8State *us;
int ch, i, mask, want;
- wchar_t lbound, wch;
+ wchar_t wch;
+ SecondByte sb;
us = (_UTF8State *)ps;
- if (us->want < 0 || us->want > 6) {
+ if (us->want < 0 || us->want > UTF8_MB_CUR_MAX) {
errno = EINVAL;
return ((size_t)-1);
}
* interesting bits of the first octet. We already know
* the character is at least two bytes long.
*
- * We also specify a lower bound for the character code to
- * detect redundant, non-"shortest form" encodings. For
- * example, the sequence C0 80 is _not_ a legal representation
- * of the null character. This enforces a 1-to-1 mapping
- * between character codes and their multibyte representations.
+ * We detect if the first byte is illegal, and set sb to
+ * the legal range of the second byte.
*/
ch = (unsigned char)*s;
if ((ch & 0x80) == 0) {
mask = 0x7f;
want = 1;
- lbound = 0;
+ sb = sb_00_00;
} else if ((ch & 0xe0) == 0xc0) {
+ if (ch < 0xc2) goto malformed;
mask = 0x1f;
want = 2;
- lbound = 0x80;
+ sb = sb_80_BF;
} else if ((ch & 0xf0) == 0xe0) {
mask = 0x0f;
want = 3;
- lbound = 0x800;
+ switch (ch) {
+ case 0xe0:
+ sb = sb_A0_BF;
+ break;
+ case 0xed:
+ sb = sb_80_9F;
+ break;
+ default:
+ sb = sb_80_BF;
+ break;
+ }
} else if ((ch & 0xf8) == 0xf0) {
+ if (ch > 0xf4) goto malformed;
mask = 0x07;
want = 4;
- lbound = 0x10000;
- } else if ((ch & 0xfc) == 0xf8) {
- mask = 0x03;
- want = 5;
- lbound = 0x200000;
- } else if ((ch & 0xfe) == 0xfc) {
- mask = 0x01;
- want = 6;
- lbound = 0x4000000;
+ switch (ch) {
+ case 0xf0:
+ sb = sb_90_BF;
+ break;
+ case 0xf4:
+ sb = sb_80_8F;
+ break;
+ default:
+ sb = sb_80_BF;
+ break;
+ }
} else {
+malformed:
/*
* Malformed input; input is not UTF-8.
*/
}
} else {
want = us->want;
- lbound = us->lbound;
+ sb = us->sb;
}
/*
else
wch = us->ch;
for (i = (us->want == 0) ? 1 : 0; i < MIN(want, n); i++) {
- if ((*s & 0xc0) != 0x80) {
- /*
- * Malformed input; bad characters in the middle
- * of a character.
- */
- errno = EILSEQ;
- return ((size_t)-1);
- }
+ if (sb.lowerbound) {
+ if ((unsigned char)*s < sb.lowerbound ||
+ (unsigned char)*s > sb.upperbound) goto malformed;
+ sb = sb_00_00;
+ } else if ((*s & 0xc0) != 0x80) goto malformed;
wch <<= 6;
wch |= *s++ & 0x3f;
}
if (i < want) {
/* Incomplete multibyte sequence. */
us->want = want - i;
- us->lbound = lbound;
+ us->sb = sb;
us->ch = wch;
return ((size_t)-2);
}
- if (wch < lbound) {
- /*
- * Malformed input; redundant encoding.
- */
- errno = EILSEQ;
- return ((size_t)-1);
- }
if (pwc != NULL)
*pwc = wch;
us->want = 0;
lead = 0xc0;
len = 2;
} else if ((wc & ~0xffff) == 0) {
+ if (wc >= 0xd800 && wc <= 0xdfff) goto illegal;
lead = 0xe0;
len = 3;
} else if ((wc & ~0x1fffff) == 0) {
+ if (wc > 0x10ffff) goto illegal;
lead = 0xf0;
len = 4;
- } else if ((wc & ~0x3ffffff) == 0) {
- lead = 0xf8;
- len = 5;
- } else if ((wc & ~0x7fffffff) == 0) {
- lead = 0xfc;
- len = 6;
} else {
+illegal:
errno = EILSEQ;
return ((size_t)-1);
}
char buf[MB_CUR_MAX];
size_t converted = wcrtomb(buf, rune, NULL);
- if (converted < 0) {
+ if (converted == (size_t)-1) {
if (result)
*result = string;
} else if (n >= converted) {
*result = string + converted;
} else if (result)
*result = NULL;
- return (converted < 0 ? 0 : converted);
+ return (converted == (size_t)-1 ? 0 : converted);
}
__private_extern__ rune_t
errno = EINVAL;
return NULL;
}
- if (loc == NULL)
- loc = __current_locale();
- else if (loc == LC_GLOBAL_LOCALE)
- loc = &__global_locale;
+ DEFAULT_CURRENT_LOCALE(loc);
m = ffs(mask);
if (m == 0 || m > _LC_NUM_MASK) {
errno = EINVAL;
/*
* Called from the Libc initializer to setup the thread-specific key.
*/
-/*
- * Partition _pthread_keys in a lower part that dyld can use, and an upper
- * part for libSystem. The libSystem part starts at __pthread_tsd_first = 10.
- * dyld will set this value to 1.
- */
-
__private_extern__ void
__xlocale_init(void)
{
#undef MB_CUR_MAX_L
#define MB_CUR_MAX_L(x) ((x)->__lc_ctype->__mb_cur_max)
-extern int __is_threaded;
-
typedef void (*__free_extra_t)(void *);
#define XPERMANENT ((__free_extra_t)-1)
struct lconv __lc_localeconv;
};
+#define DEFAULT_CURRENT_LOCALE(x) \
+ if ((x) == NULL) { \
+ (x) = __current_locale(); \
+ } else if ((x) == LC_GLOBAL_LOCALE) { \
+ (x) = &__global_locale; \
+ }
+
#define NORMALIZE_LOCALE(x) if ((x) == NULL) { \
(x) = _c_locale; \
} else if ((x) == LC_GLOBAL_LOCALE) { \
Sizes less than 512 bytes or greater than a gigabyte are ignored.
.It Ev EXINIT
A startup list of commands read by
-.Xr ex 1 ,
-.Xr edit 1 ,
+.Xr ex 1
and
.Xr vi 1 .
.It Ev HOME
The kind of terminal for which output is to be prepared.
This information is used by commands, such as
.Xr nroff 1
-or
-.Xr plot 1
which may exploit special terminal capabilities. See
-.Pa /usr/share/misc/termcap
-.Pq Xr termcap 5
-for a list of terminal types.
-.It Ev TERMCAP
-The string describing the terminal in TERM, or, if
-it begins with a '/', the name of the termcap file.
-See
-.Ev TERMPATH
-below,
-.Xr termcap 5 ,
+.Xr termcap 3
and
-.Xr termcap .
-.It Ev TERMPATH
-A sequence of pathnames of termcap files, separated by colons or spaces,
-which are searched for terminal descriptions in the order listed. Having
-no
-.Ev TERMPATH
-is equivalent to a
-.Ev TERMPATH
-of
-.Dq Pa $HOME/.termcap:/etc/termcap .
-.Ev TERMPATH
-is ignored if
-.Ev TERMCAP
-contains a full pathname.
+.Xr terminfo 5 .
.It Ev TMPDIR
The directory in which to store temporary files.
Most applications use either
.Xr execle 3 ,
.Xr system 3 ,
.Xr termcap 3 ,
-.Xr termcap 5
+.Xr terminfo 5
.Sh HISTORY
The
.Nm environ
gethostuuid.2 gethostuuid.2
killpg.2 killpg.2
nanosleep.2 nanosleep.2
-pthread_kill.2 pthread_kill.2
-pthread_sigmask.2 pthread_sigmask.2
sigblock.2 sigblock.2
sigpause.2 sigpause.2
sigsetmask.2 sigsetmask.2 sigmask.2
alarm.3 alarm.3
alloca.3 alloca.3
arc4random.3 arc4random.3 arc4random_addrandom.3 arc4random_buf.3 arc4random_stir.3 arc4random_uniform.3
-asl.3 asl.3 asl_add_log_file.3 asl_close.3 asl_free.3 asl_get.3 asl_key.3 asl_log.3 asl_new.3 asl_open.3 asl_remove_log_file.3 asl_search.3 asl_send.3 asl_set.3 asl_set_filter.3 asl_set_query.3 asl_unset.3 asl_vlog.3 aslresponse_free.3 aslresponse_next.3
assert.3 assert.3
atexit.3 atexit.3 atexit_b.3
atof.3 atof.3 atof_l.3
atoi.3 atoi.3 atoi_l.3
atol.3 atol.3 atol_l.3 atoll.3 atoll_l.3
-atomic.3 atomic.3 OSAtomicAdd32.3 OSAtomicAdd32Barrier.3 OSAtomicAdd64.3 OSAtomicAdd64Barrier.3 OSAtomicAnd32.3 OSAtomicAnd32Barrier.3 OSAtomicAnd32Orig.3 OSAtomicAnd32OrigBarrier.3 OSAtomicCompareAndSwap32.3 OSAtomicCompareAndSwap32Barrier.3 OSAtomicCompareAndSwap64.3 OSAtomicCompareAndSwap64Barrier.3 OSAtomicCompareAndSwapInt.3 OSAtomicCompareAndSwapIntBarrier.3 OSAtomicCompareAndSwapLong.3 OSAtomicCompareAndSwapLongBarrier.3 OSAtomicCompareAndSwapPtr.3 OSAtomicCompareAndSwapPtrBarrier.3 OSAtomicDecrement32.3 OSAtomicDecrement32Barrier.3 OSAtomicDecrement64.3 OSAtomicDecrement64Barrier.3 OSAtomicDequeue.3 OSAtomicEnqueue.3 OSAtomicIncrement32.3 OSAtomicIncrement32Barrier.3 OSAtomicIncrement64.3 OSAtomicIncrement64Barrier.3 OSAtomicOr32.3 OSAtomicOr32Barrier.3 OSAtomicOr32Orig.3 OSAtomicOr32OrigBarrier.3 OSAtomicTestAndClear.3 OSAtomicTestAndClearBarrier.3 OSAtomicTestAndSet.3 OSAtomicTestAndSetBarrier.3 OSAtomicXor32.3 OSAtomicXor32Barrier.3 OSAtomicXor32Orig.3 OSAtomicXor32OrigBarrier.3
backtrace.3 backtrace.3 backtrace_symbols.3 backtrace_symbols_fd.3
-barrier.3 barrier.3 OSMemoryBarrier.3
basename.3 basename.3
bcmp.3 bcmp.3
bcopy.3 bcopy.3
btree.3 btree.3
byteorder.3 byteorder.3 htonl.3 htons.3 ntohl.3 ntohs.3
bzero.3 bzero.3
-cache.3 cache.3 sys_cache_control.3 sys_icache_invalidate.3 sys_dcache_flush.3
catclose.3 catclose.3
catgets.3 catgets.3
catopen.3 catopen.3
fclose.3 fclose.3
ferror.3 ferror.3 clearerr.3 clearerr_unlocked.3 feof.3 feof_unlocked.3 ferror_unlocked.3 fileno.3 fileno_unlocked.3
fflush.3 fflush.3 fpurge.3
-ffs.3 ffs.3 ffsl.3 fls.3 flsl.3
fgetln.3 fgetln.3
fgets.3 fgets.3 gets.3
fgetwln.3 fgetwln.3 fgetwln_l.3
getbsize.3 getbsize.3
getc.3 getc.3 fgetc.3 getc_unlocked.3 getchar.3 getchar_unlocked.3 getw.3
getcap.3 getcap.3 cgetcap.3 cgetclose.3 cgetent.3 cgetfirst.3 cgetmatch.3 cgetnext.3 cgetnum.3 cgetset.3 cgetstr.3 cgetustr.3
-getcontext.3 getcontext.3 setcontext.3
getcwd.3 getcwd.3 getwd.3
getdate.3 getdate.3
getdomainname.3 getdomainname.3 setdomainname.3
getenv.3 getenv.3 putenv.3 setenv.3 unsetenv.3
gethostid.3 gethostid.3 sethostid.3
gethostname.3 gethostname.3 sethostname.3
-getiopolicy_np.3 getiopolicy_np.3 setiopolicy_np.3
getlastlogx.3 getlastlogx.3 getlastlogxbyname.3 getutmp.3 getutmpx.3 utmpxname.3
getline.3 getline.3 getdelim.3
getloadavg.3 getloadavg.3
login.3 login.3 logwtmp.3 logout.3
lsearch.3 lsearch.3 lfind.3
lutimes.3 lutimes.3
-makecontext.3 makecontext.3 swapcontext.3
-malloc.3 malloc.3 calloc.3 free.3 realloc.3 reallocf.3 valloc.3
-malloc_size.3 malloc_size.3 malloc_good_size.3
-malloc_zone_malloc.3 malloc_zone_malloc.3 malloc_create_zone.3 malloc_destroy_zone.3 malloc_default_zone.3 malloc_zone_from_ptr.3 malloc_zone_calloc.3 malloc_zone_valloc.3 malloc_zone_realloc.3 malloc_zone_memalign.3 malloc_zone_free.3
mblen.3 mblen.3 mblen_l.3
mbrlen.3 mbrlen.3 mbrlen_l.3
mbrtowc.3 mbrtowc.3 mbrtowc_l.3
memmove.3 memmove.3
memory.3 memory.3
memset.3 memset.3
+memset_s.3 memset_s.3
memset_pattern.3 memset_pattern.3 memset_pattern4.3 memset_pattern8.3 memset_pattern16.3
mkpath_np.3 mkpath_np.3
mktemp.3 mktemp.3 mkdtemp.3 mkstemp.3 mkstemps.3
pselect.3 pselect.3
psignal.3 psignal.3 sys_siglist.3 sys_signame.3 strsignal.3 sys_siglist.3 sys_signame.3
psort.3 psort.3 psort_b.3 psort_r.3
-pthread.3 pthread.3
-pthread_atfork.3 pthread_atfork.3
-pthread_attr.3 pthread_attr.3 pthread_attr_destroy.3 pthread_attr_getdetachstate.3 pthread_attr_getinheritsched.3 pthread_attr_getschedparam.3 pthread_attr_getschedpolicy.3 pthread_attr_getscope.3 pthread_attr_getstackaddr.3 pthread_attr_getstacksize.3 pthread_attr_init.3 pthread_attr_setdetachstate.3 pthread_attr_setinheritsched.3 pthread_attr_setschedparam.3 pthread_attr_setschedpolicy.3 pthread_attr_setscope.3 pthread_attr_setstackaddr.3 pthread_attr_setstacksize.3
-pthread_cancel.3 pthread_cancel.3
-pthread_cleanup_pop.3 pthread_cleanup_pop.3
-pthread_cleanup_push.3 pthread_cleanup_push.3
-pthread_cond_broadcast.3 pthread_cond_broadcast.3
-pthread_cond_destroy.3 pthread_cond_destroy.3
-pthread_cond_init.3 pthread_cond_init.3
-pthread_cond_signal.3 pthread_cond_signal.3
-pthread_cond_timedwait.3 pthread_cond_timedwait.3
-pthread_cond_wait.3 pthread_cond_wait.3
-pthread_condattr.3 pthread_condattr.3 pthread_condattr_destroy.3 pthread_condattr_init.3
-pthread_create.3 pthread_create.3
-pthread_detach.3 pthread_detach.3
-pthread_equal.3 pthread_equal.3
-pthread_exit.3 pthread_exit.3
-pthread_getschedparam.3 pthread_getschedparam.3 pthread_setschedparam.3
-pthread_getspecific.3 pthread_getspecific.3
-pthread_join.3 pthread_join.3
-pthread_key_create.3 pthread_key_create.3
-pthread_key_delete.3 pthread_key_delete.3
-pthread_mutex_destroy.3 pthread_mutex_destroy.3
-pthread_mutex_init.3 pthread_mutex_init.3
-pthread_mutex_lock.3 pthread_mutex_lock.3
-pthread_mutex_trylock.3 pthread_mutex_trylock.3
-pthread_mutex_unlock.3 pthread_mutex_unlock.3
-pthread_mutexattr.3 pthread_mutexattr.3 pthread_mutexattr_destroy.3 pthread_mutexattr_getprioceiling.3 pthread_mutexattr_getprotocol.3 pthread_mutexattr_gettype.3 pthread_mutexattr_init.3 pthread_mutexattr_setprioceiling.3 pthread_mutexattr_setprotocol.3 pthread_mutexattr_settype.3
-pthread_once.3 pthread_once.3
-pthread_rwlock_destroy.3 pthread_rwlock_destroy.3
-pthread_rwlock_init.3 pthread_rwlock_init.3
-pthread_rwlock_rdlock.3 pthread_rwlock_rdlock.3 pthread_rwlock_tryrdlock.3
-pthread_rwlock_unlock.3 pthread_rwlock_unlock.3
-pthread_rwlock_wrlock.3 pthread_rwlock_wrlock.3 pthread_rwlock_trywrlock.3
-pthread_rwlockattr_destroy.3 pthread_rwlockattr_destroy.3
-pthread_rwlockattr_getpshared.3 pthread_rwlockattr_getpshared.3
-pthread_rwlockattr_init.3 pthread_rwlockattr_init.3
-pthread_rwlockattr_setpshared.3 pthread_rwlockattr_setpshared.3
-pthread_self.3 pthread_self.3
-pthread_setcancelstate.3 pthread_setcancelstate.3 pthread_setcanceltype.3 pthread_testcancel.3
-pthread_setspecific.3 pthread_setspecific.3
putc.3 putc.3 fputc.3 putc_unlocked.3 putchar.3 putchar_unlocked.3 putw.3
putwc.3 putwc.3 fputwc.3 putwchar.3
putwc_l.3 putwc_l.3 fputwc_l.3 putwchar_l.3
rand.3 rand.3 rand_r.3 srand.3 sranddev.3
rand48.3 rand48.3 _rand48.3 drand48.3 erand48.3 jrand48.3 lcong48.3 lrand48.3 mrand48.3 nrand48.3 seed48.3 srand48.3
random.3 random.3 initstate.3 setstate.3 srandom.3 srandomdev.3
+rbtree.3 rbtree.3
rcmdsh.3 rcmdsh.3
readpassphrase.3 readpassphrase.3
realpath.3 realpath.3
scanf.3 scanf.3 fscanf.3 sscanf.3 vfscanf.3 vscanf.3 vsscanf.3
scanf_l.3 scanf_l.3 fscanf_l.3 sscanf_l.3 vfscanf_l.3 vscanf_l.3 vsscanf_l.3
setbuf.3 setbuf.3 setbuffer.3 setlinebuf.3 setvbuf.3
-setjmp.3 setjmp.3 _longjmp.3 _setjmp.3 longjmp.3 longjmperr.3 longjmperror.3 siglongjmp.3 sigsetjmp.3
setlocale.3 setlocale.3
setmode.3 setmode.3 getmode.3
setruid.3 setruid.3 setrgid.3
sleep.3 sleep.3
sockatmark.3 sockatmark.3
sourcefilter.3 sourcefilter.3 getsourcefilter.3 getipv4sourcefilter.3 setsourcefilter.3 setipv4sourcefilter.3
-spinlock.3 spinlock.3 OSSpinLockLock.3 OSSpinLockTry.3 OSSpinLockUnlock.3
statvfs.3 statvfs.3 fstatvfs.3
stdarg.3 stdarg.3 va_arg.3 va_copy.3 va_end.3 va_start.3
stdio.3 stdio.3
sysconf.3 sysconf.3
sysctl.3 sysctl.3 sysctlbyname.3 sysctlnametomib.3
sysexits.3 sysexits.3
-syslog.3 syslog.3 closelog.3 openlog.3 setlogmask.3 vsyslog.3
system.3 system.3
tcgetpgrp.3 tcgetpgrp.3
tcgetsid.3 tcgetsid.3
ttyname.3 ttyname.3 isatty.3 ttyslot.3
tzset.3 tzset.3 tzsetwall.3
ualarm.3 ualarm.3
-ucontext.3 ucontext.3
ulimit.3 ulimit.3
uname.3 uname.3
ungetc.3 ungetc.3
wscanf.3 wscanf.3 fwscanf.3 swscanf.3 vfwscanf.3 vswscanf.3 vwscanf.3
wscanf_l.3 wscanf_l.3 fwscanf_l.3 swscanf_l.3 vfwscanf_l.3 vswscanf_l.3 vwscanf_l.3
xlocale.3 xlocale.3
+xprintf.3 xprintf.3 asxprintf.3 dxprintf.3 fxprintf.3 sxprintf.3 vasxprintf.3 vdxprintf.3 vfxprintf.3 vsxprintf.3 vxprintf.3
+xprintf_comp.3 xprintf_comp.3 free_printf_comp.3 new_printf_comp.3
+xprintf_domain.3 xprintf_domain.3 copy_printf_domain.3 free_printf_domain.3 new_printf_domain.3 register_printf_domain_function.3 register_printf_domain_render_std.3
+xprintf_exec.3 xprintf_exec.3 asxprintf_exec.3 dxprintf_exec.3 fxprintf_exec.3 sxprintf_exec.3 vasxprintf_exec.3 vdxprintf_exec.3 vfxprintf_exec.3 vsxprintf_exec.3 vxprintf_exec.3
# man5
big5.5 big5.5
utf8.5 utf8.5
utmp.5 utmp.5 lastlog.5 wtmp.5
utmpx.5 utmpx.5
+xprintf.5 xprintf.5
# man7
environ.7 environ.7
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <stdlib.h>
+
/*-
* Convert a network address from binary to printable numeric format.
* This API is copied from INRIA's IPv6 implementation, but it is a
* naming and the poor choice of arguments.
*/
char *
-addr2ascii(af, addrp, len, buf)
- int af;
- const void *addrp;
- int len; /* should be size_t XXX */
- char *buf; /* XXX should pass length of buffer */
+addr2ascii(int af, const void *addrp, int len, char *buf)
{
- static char staticbuf[64]; /* 64 for AF_LINK > 16 for AF_INET */
-
- if (!buf)
+ if (buf == NULL) {
+ static char *staticbuf = NULL;
+
+ if (staticbuf == NULL) {
+ staticbuf = malloc(64); // 64 for AF_LINK > 16 for AF_INET
+ if (staticbuf == NULL) {
+ return NULL;
+ }
+ }
+
buf = staticbuf;
+ }
switch(af) {
case AF_INET:
return;
}
-static char hexlist[] = "0123456789abcdef";
+static const char hexlist[] = "0123456789abcdef";
char *
link_ntoa(sdl)
{
struct __msfilterreq msfr;
sockunion_t *psu;
- int err, level, nsrcs, optlen, optname;
+ int err, level, nsrcs, optname;
+ unsigned int optlen;
if (interface == 0 || group == NULL || numsrc == NULL ||
fmode == NULL) {
--- /dev/null
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/socket.h>
+
+#define MAX_V4_ADDR_LEN 16
+#define MAX_V6_ADDR_LEN 64
+
+static const char *hexchars = "0123456789abcdef";
+
+const char *
+inet_ntop6(const struct in6_addr *addr, char *dst, socklen_t size)
+{
+ char hexa[8][5], tmp[MAX_V6_ADDR_LEN];
+ int zr[8];
+ socklen_t len;
+ int32_t i, j, k, skip;
+ uint8_t x8, hx8;
+ uint16_t x16;
+ struct in_addr a4;
+
+ if (addr == NULL)
+ {
+ errno = EAFNOSUPPORT;
+ return NULL;
+ }
+
+ if (dst == NULL)
+ {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ memset(tmp, 0, MAX_V6_ADDR_LEN);
+
+ /* check for mapped or compat addresses */
+ i = IN6_IS_ADDR_V4MAPPED(addr);
+ j = IN6_IS_ADDR_V4COMPAT(addr);
+ if ((i != 0) || (j != 0))
+ {
+ a4.s_addr = addr->__u6_addr.__u6_addr32[3];
+ sprintf(tmp, "::%s%s", (i != 0) ? "ffff:" : "", inet_ntoa(a4));
+ len = strlen(tmp) + 1;
+ if (len > size)
+ {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ memcpy(dst, tmp, len);
+ return dst;
+ }
+
+ k = 0;
+ for (i = 0; i < 16; i += 2)
+ {
+ j = 0;
+ skip = 1;
+
+ memset(hexa[k], 0, 5);
+
+ x8 = addr->__u6_addr.__u6_addr8[i];
+
+ hx8 = x8 >> 4;
+ if (hx8 != 0)
+ {
+ skip = 0;
+ hexa[k][j++] = hexchars[hx8];
+ }
+
+ hx8 = x8 & 0x0f;
+ if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
+ {
+ skip = 0;
+ hexa[k][j++] = hexchars[hx8];
+ }
+
+ x8 = addr->__u6_addr.__u6_addr8[i + 1];
+
+ hx8 = x8 >> 4;
+ if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
+ {
+ hexa[k][j++] = hexchars[hx8];
+ }
+
+ hx8 = x8 & 0x0f;
+ hexa[k][j++] = hexchars[hx8];
+
+ k++;
+ }
+
+ /* find runs of zeros for :: convention */
+ j = 0;
+ for (i = 7; i >= 0; i--)
+ {
+ zr[i] = j;
+ x16 = addr->__u6_addr.__u6_addr16[i];
+ if (x16 == 0) j++;
+ else j = 0;
+ zr[i] = j;
+ }
+
+ /* find longest run of zeros */
+ k = -1;
+ j = 0;
+ for(i = 0; i < 8; i++)
+ {
+ if (zr[i] > j)
+ {
+ k = i;
+ j = zr[i];
+ }
+ }
+
+ for(i = 0; i < 8; i++)
+ {
+ if (i != k) zr[i] = 0;
+ }
+
+ len = 0;
+ for (i = 0; i < 8; i++)
+ {
+ if (zr[i] != 0)
+ {
+ /* check for leading zero */
+ if (i == 0) tmp[len++] = ':';
+ tmp[len++] = ':';
+ i += (zr[i] - 1);
+ continue;
+ }
+ for (j = 0; hexa[i][j] != '\0'; j++) tmp[len++] = hexa[i][j];
+ if (i != 7) tmp[len++] = ':';
+ }
+
+ /* trailing NULL */
+ len++;
+
+ if (len > size)
+ {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ memcpy(dst, tmp, len);
+ return dst;
+}
+
+const char *
+inet_ntop4(const struct in_addr *addr, char *dst, socklen_t size)
+{
+ char tmp[MAX_V4_ADDR_LEN], *p;
+ const u_int8_t *ap = (u_int8_t *)&addr->s_addr;
+ int i, ql, len;
+
+ if (addr == NULL)
+ {
+ errno = EAFNOSUPPORT;
+ return NULL;
+ }
+
+ if (dst == NULL)
+ {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ memset(tmp, 0, MAX_V4_ADDR_LEN);
+
+ /* 3 dots, trailing nul */
+ len = 4;
+
+ p = tmp;
+
+ for (i = 0; i < 4; i++, ap++)
+ {
+ snprintf(p, 4, "%d", *ap);
+ ql = strlen(p);
+ len += ql;
+ p += ql;
+ if (i < 3) *p++ = '.';
+ }
+
+ if (len > size)
+ {
+ errno = ENOSPC;
+ return NULL;
+ }
+
+ memcpy(dst, tmp, len);
+ return dst;
+}
+
+const char *
+inet_ntop(int af, const void *addr, char *buf, socklen_t len)
+{
+ if (af == AF_INET6) return inet_ntop6(addr, buf, len);
+ if (af == AF_INET) return inet_ntop4(addr, buf, len);
+
+ errno = EAFNOSUPPORT;
+ return NULL;
+}
--- /dev/null
+/*
+ * Copyright (c) 1996,1999 by Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
+ * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
+ * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: inet_pton.c,v 1.3 2003/04/10 18:53:29 majka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#define INET6 1
+
+#define IN6ADDRSZ 16
+
+#if 0
+#ifndef HAVE_PORTABLE_PROTOTYPE
+#include "cdecl_ext.h"
+#endif
+
+#ifndef HAVE_U_INT16_T
+#include "bittypes.h"
+#endif
+#if !(defined(HAVE_INADDRSZ) && defined(HAVE_IN6ADDRSZ))
+#include "addrsize.h"
+#endif
+#endif
+#ifndef NS_INADDRSZ
+#define NS_INADDRSZ INADDRSZ
+#endif
+#ifndef NS_IN6ADDRSZ
+#define NS_IN6ADDRSZ IN6ADDRSZ
+#endif
+#ifndef NS_INT16SZ
+#define NS_INT16SZ sizeof(u_int16_t)
+#endif
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4 __P((const char *src, u_char *dst));
+#ifdef INET6
+static int inet_pton6 __P((const char *src, u_char *dst));
+#endif
+
+/* int
+ * inet_pton(af, src, dst)
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * return:
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * author:
+ * Paul Vixie, 1996.
+ */
+int
+inet_pton(int af, const char *src, void *dst)
+{
+ int status;
+ unsigned short ifnum;
+ char *p, *s;
+
+ switch (af)
+ {
+ case AF_INET:
+ {
+ return (inet_pton4(src, dst));
+ }
+
+#ifdef INET6
+ case AF_INET6:
+ {
+ ifnum = 0;
+ p = NULL;
+ s = (char *)src;
+
+ if (src != NULL) p = strrchr(src, '%');
+ if (p != NULL)
+ {
+ s = strdup(src);
+ if (s == NULL)
+ {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ s[p - src] = '\0';
+ }
+
+ status = inet_pton6(s, dst);
+ if (p != NULL) free(s);
+ if (status != 1) return status;
+
+ if ((p != NULL) && IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)dst))
+ {
+ ifnum = if_nametoindex(++p);
+ ifnum = htons(ifnum);
+ ((struct in6_addr *)dst)->__u6_addr.__u6_addr16[1] = ifnum;
+ }
+
+ return 1;
+ }
+#endif
+
+ default:
+ {
+ errno = EAFNOSUPPORT;
+ return -1;
+ }
+ }
+
+ /* NOTREACHED */
+ return -1;
+}
+
+/* int
+ * inet_pton4(src, dst)
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ * 1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ * does not touch `dst' unless it's returning 1.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, u_char *dst)
+{
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ u_char tmp[NS_INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ u_int new = *tp * 10 + (pch - digits);
+
+ if (new > 255)
+ return (0);
+ *tp = new;
+ if (! saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+ memcpy(dst, tmp, NS_INADDRSZ);
+ return (1);
+}
+
+#ifdef INET6
+/* int
+ * inet_pton6(src, dst)
+ * convert presentation level address to network order binary form.
+ * return:
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ * (1) does not touch `dst' unless it's returning 1.
+ * (2) :: in a full address is silently ignored.
+ * credit:
+ * inspired by Mark Andrews.
+ * author:
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, u_char *dst)
+{
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, saw_xdigit;
+ u_int val;
+
+ memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+ endp = tp + NS_IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ saw_xdigit = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (val > 0xffff)
+ return (0);
+ saw_xdigit = 1;
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!saw_xdigit) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ } else if (*src == '\0') {
+ return (0);
+ }
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ saw_xdigit = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += NS_INADDRSZ;
+ saw_xdigit = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (saw_xdigit) {
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (u_char) (val >> 8) & 0xff;
+ *tp++ = (u_char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const int n = tp - colonp;
+ int i;
+
+ if (tp == endp)
+ return (0);
+ for (i = 1; i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
+ return (1);
+}
+#endif /*INET6*/
--- /dev/null
+/*
+ * Copyright (c) 2011, 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <dispatch/dispatch.h>
+#include <uuid/uuid.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <mach-o/loader.h>
+#include <mach-o/fat.h>
+#include <mach-o/arch.h>
+#include <mach-o/getsect.h>
+#include <pthread.h>
+#include <sys/types.h>
+#include <execinfo.h>
+#include <stdio.h>
+#include <dlfcn.h>
+#include <_simple.h>
+#include <errno.h>
+#include <pthread.h>
+#include <string.h>
+#include "os/assumes.h"
+#include "gen/assumes.h"
+#include <os/trace.h>
+
+#define OSX_ASSUMES_LOG_REDIRECT_SECT_NAME "__osx_log_func"
+#define os_atomic_cmpxchg(p, o, n) __sync_bool_compare_and_swap((p), (o), (n))
+
+static bool _os_should_abort_on_assumes = false;
+
+static const char *
+_os_basename(const char *p)
+{
+ return ((strrchr(p, '/') ? : p - 1) + 1);
+}
+
+static void
+_os_get_build(char *build, size_t sz)
+{
+ /* Get the build every time. We used to cache it, but if PID 1 experiences
+ * an assumes() failure before the build has been set, that would mean that
+ * all future failures would get bad build info. So we fetch it every time.
+ * Since assumes() failures are on the slow path anyway, not a huge deal.
+ */
+ int mib[] = { CTL_KERN, KERN_OSVERSION };
+
+ size_t oldsz = sz;
+ int r = sysctl(mib, 2, build, &sz, NULL, 0);
+ if (r == 0 && sz == 1) {
+ (void)strlcpy(build, "99Z999", oldsz);
+ }
+}
+
+static void
+_os_get_image_uuid(void *hdr, uuid_t uuid)
+{
+#if __LP64__
+ struct mach_header_64 *hdr32or64 = (struct mach_header_64 *)hdr;
+#else
+ struct mach_header *hdr32or64 = (struct mach_header *)hdr;
+#endif /* __LP64__ */
+
+ size_t i = 0;
+ size_t next = sizeof(*hdr32or64);
+ struct load_command *cur = NULL;
+ for (i = 0; i < hdr32or64->ncmds; i++) {
+ cur = (struct load_command *)((uintptr_t)hdr32or64 + next);
+ if (cur->cmd == LC_UUID) {
+ struct uuid_command *cmd = (struct uuid_command *)cur;
+ uuid_copy(uuid, cmd->uuid);
+ break;
+ }
+
+ next += cur->cmdsize;
+ }
+
+ if (i == hdr32or64->ncmds) {
+ uuid_clear(uuid);
+ }
+}
+
+static void
+_os_abort_on_assumes_once(void)
+{
+ /* Embedded boot-args can get pretty long. Let's just hope this is big
+ * enough.
+ */
+ char bootargs[2048];
+ size_t len = sizeof(bootargs) - 1;
+
+ if (sysctlbyname("kern.bootargs", bootargs, &len, NULL, 0) == 0) {
+ if (strnstr(bootargs, "-os_assumes_fatal", len)) {
+ _os_should_abort_on_assumes = true;
+ }
+ }
+}
+
+static bool
+_os_abort_on_assumes(void)
+{
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ bool result = false;
+
+ if (getpid() != 1) {
+ if (getenv("OS_ASSUMES_FATAL")) {
+ result = true;
+ } else {
+ pthread_once(&once, _os_abort_on_assumes_once);
+ result = _os_should_abort_on_assumes;
+ }
+ } else {
+ if (getenv("OS_ASSUMES_FATAL_PID1")) {
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+#if __LP64__
+typedef struct mach_header_64 os_mach_header;
+#else
+typedef struct mach_header os_mach_header;
+#endif
+
+static os_redirect_t
+_os_find_log_redirect_func(os_mach_header *hdr)
+{
+ os_redirect_t result = NULL;
+
+ char name[128];
+ unsigned long size = 0;
+ uint8_t *data = getsectiondata(hdr, OS_ASSUMES_REDIRECT_SEG, OS_ASSUMES_REDIRECT_SECT, &size);
+ if (!data) {
+ data = getsectiondata(hdr, "__TEXT", OSX_ASSUMES_LOG_REDIRECT_SECT_NAME, &size);
+
+ if (data && size < sizeof(name) - 2) {
+ (void)strlcpy(name, (const char *)data, size + 1);
+ result = dlsym(RTLD_DEFAULT, name);
+ }
+ } else if (size == sizeof(struct _os_redirect_assumes_s)) {
+ struct _os_redirect_assumes_s *redirect = (struct _os_redirect_assumes_s *)data;
+ result = redirect->redirect;
+ }
+
+ return result;
+}
+
+static bool
+_os_log_redirect(void *hdr, const char *msg)
+{
+ bool result = false;
+
+ os_redirect_t redirect_func = _os_find_log_redirect_func(hdr);
+ if (redirect_func) {
+ result = redirect_func(msg);
+ }
+
+ return result;
+}
+
+__attribute__((always_inline))
+static void
+_os_construct_message(uint64_t code, _SIMPLE_STRING asl_message, Dl_info *info, char *buff, size_t sz)
+{
+ const char *image_name = NULL;
+ uintptr_t offset = 0;
+ uuid_string_t uuid_str;
+
+ void *ret = __builtin_return_address(0);
+ if (dladdr(ret, info)) {
+ uuid_t uuid;
+ _os_get_image_uuid(info->dli_fbase, uuid);
+
+ uuid_unparse(uuid, uuid_str);
+ image_name = _os_basename(info->dli_fname);
+
+ offset = ret - info->dli_fbase;
+ }
+
+ char sig[64];
+ (void)snprintf(sig, sizeof(sig), "%s:%lu", uuid_str, offset);
+
+ char result[24];
+ (void)snprintf(result, sizeof(result), "0x%llx", code);
+
+ char build[16];
+ size_t bsz = sizeof(build);
+ _os_get_build(build, bsz);
+
+ (void)snprintf(buff, sz, "assertion failed: %s: %s + %lu [%s]: %s", build, image_name, offset, uuid_str, result);
+
+ _simple_asl_msg_set(asl_message, "com.apple.message.domain", "com.apple.assumes.failure");
+ _simple_asl_msg_set(asl_message, "com.apple.message.signature", sig);
+ _simple_asl_msg_set(asl_message, "com.apple.message.signature2", result);
+ _simple_asl_msg_set(asl_message, "com.apple.message.signature3", image_name);
+ _simple_asl_msg_set(asl_message, "com.apple.message.summarize", "YES");
+}
+
+#pragma mark Internal Implementations
+__attribute__((always_inline))
+static inline void
+_os_assumes_log_impl(uint64_t code)
+{
+ _SIMPLE_STRING asl_message = _simple_asl_msg_new();
+ if (asl_message) {
+ Dl_info info;
+ char message[256];
+ _os_construct_message(code, asl_message, &info, message, sizeof(message));
+ if (!_os_log_redirect(info.dli_fbase, message)) {
+ _os_trace_error_str(message);
+ _simple_asl_msg_set(asl_message, "Level", "Error");
+ _simple_asl_msg_set(asl_message, "Message", "");
+ _simple_asl_send(asl_message);
+ }
+
+ _simple_sfree(asl_message);
+ }
+
+ if (_os_abort_on_assumes()) {
+ __builtin_trap();
+ }
+}
+
+__attribute__((always_inline))
+static inline char *
+_os_assert_log_impl(uint64_t code)
+{
+ char *result = NULL;
+
+ _SIMPLE_STRING asl_message = _simple_asl_msg_new();
+ if (asl_message) {
+ Dl_info info;
+ char message[256];
+ _os_construct_message(code, asl_message, &info, message, sizeof(message));
+ if (!_os_log_redirect(info.dli_fbase, message)) {
+ _os_trace_error_str(message);
+ _simple_asl_msg_set(asl_message, "Level", "Error");
+ _simple_asl_msg_set(asl_message, "Message", "");
+ _simple_asl_send(asl_message);
+ }
+
+ _simple_sfree(asl_message);
+ result = strdup(message);
+ }
+
+#if LIBC_NO_LIBCRASHREPORTERCLIENT
+ /* There is no crash report information facility on embedded, which is
+ * really regrettable. Fortunately, all we need to capture is the value
+ * which tripped up the assertion. We can just stuff that into the thread's
+ * name.
+ */
+ char name[64];
+ (void)pthread_getname_np(pthread_self(), name, sizeof(name));
+
+ char newname[64];
+ if (strlen(name) == 0) {
+ (void)snprintf(newname, sizeof(newname), "[Fatal bug: 0x%llx]", code);
+ } else {
+ (void)snprintf(newname, sizeof(newname), "%s [Fatal bug: 0x%llx]", name, code);
+ }
+
+ (void)pthread_setname_np(newname);
+#endif
+
+ return result;
+}
+
+__attribute__((always_inline))
+static inline void
+_os_assumes_log_ctx_impl(os_log_callout_t callout, void *ctx, uint64_t code)
+{
+ _SIMPLE_STRING asl_message = _simple_asl_msg_new();
+ if (asl_message) {
+ Dl_info info;
+ char message[256];
+ _os_construct_message(code, asl_message, &info, message, sizeof(message));
+
+ (void)callout(asl_message, ctx, message);
+ _simple_sfree(asl_message);
+ }
+
+ if (_os_abort_on_assumes()) {
+ __builtin_trap();
+ }
+}
+
+__attribute__((always_inline))
+static inline char *
+_os_assert_log_ctx_impl(os_log_callout_t callout, void *ctx, uint64_t code)
+{
+ char *result = NULL;
+
+ _SIMPLE_STRING asl_message = _simple_asl_msg_new();
+ if (asl_message) {
+ Dl_info info;
+ char message[256];
+ _os_construct_message(code, asl_message, &info, message, sizeof(message));
+
+ (void)callout(asl_message, ctx, message);
+ _simple_sfree(asl_message);
+ result = strdup(message);
+ }
+ return result;
+}
+
+#pragma mark Public Interfaces
+void
+_os_assumes_log(uint64_t code)
+{
+ _os_assumes_log_impl(code);
+}
+
+char *
+_os_assert_log(uint64_t code)
+{
+ return _os_assert_log_impl(code);
+}
+
+void
+_os_assumes_log_ctx(os_log_callout_t callout, void *ctx, uint64_t code)
+{
+ _os_assumes_log_ctx_impl(callout, ctx, code);
+}
+
+char *
+_os_assert_log_ctx(os_log_callout_t callout, void *ctx, uint64_t code)
+{
+ return _os_assert_log_ctx_impl(callout, ctx, code);
+}
+
+void
+_os_avoid_tail_call(void)
+{
+ // no-op
+}
+
+#pragma mark Legacy
+void
+_osx_assumes_log(uint64_t code)
+{
+ _os_assumes_log(code);
+}
+
+char *
+_osx_assert_log(uint64_t code)
+{
+ return _os_assert_log_impl(code);
+}
+
+void
+_osx_assumes_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code)
+{
+ _os_assumes_log_ctx_impl(callout, ctx, code);
+}
+
+char *
+_osx_assert_log_ctx(osx_log_callout_t callout, void *ctx, uint64_t code)
+{
+ return _os_assert_log_ctx_impl(callout, ctx, code);
+}
+
+void
+_osx_avoid_tail_call(void)
+{
+ _os_avoid_tail_call();
+}
--- /dev/null
+/* Copyright (c) 2012, 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef __OS_ASSUMES_H__
+#define __OS_ASSUMES_H__
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+
+#include <Availability.h>
+#include <TargetConditionals.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <_simple.h>
+#include <os/base.h>
+#include <errno.h>
+
+/* This is useful for clients who wish for the messages generated by assumes()
+ * failures to go somewhere other than (or in addition to) the system log. If
+ * you don't wish for the message to be logged to the system log, then return
+ * true (to indicate that the message has been handled). If you want the default
+ * behavior, return false.
+ */
+typedef bool (*os_redirect_t)(const char *);
+struct _os_redirect_assumes_s {
+ os_redirect_t redirect;
+};
+
+#define OS_ASSUMES_REDIRECT_SEG "__DATA"
+#define OS_ASSUMES_REDIRECT_SECT "__os_assumes_log"
+
+#define os_redirect_assumes(func) \
+ __attribute__((__used__)) \
+ __attribute__((__section__(OS_ASSUMES_REDIRECT_SEG "," OS_ASSUMES_REDIRECT_SECT))) \
+ static struct _os_redirect_assumes_s _os_redirect_##func = { \
+ .redirect = &func, \
+ };
+
+/* The asl_message argument is a _SIMPLE_STRING that, when given to _simple_asl_send(), will
+ * direct the message to the MessageTracer diagnostic messages store rather than
+ * the default system log store.
+ */
+typedef bool (*os_log_callout_t)(_SIMPLE_STRING asl_message, void *ctx, const char *);
+
+#if TARGET_OS_IPHONE
+#define os_set_crash_message(arg) /* no-op */
+#else
+#include <CrashReporterClient.h>
+#define os_set_crash_message(arg) _crc_make_setter(message, (arg))
+#endif
+
+#define os_assumes(e) __extension__({ \
+ __typeof__(e) _e = os_fastpath(e); \
+ if (!_e) { \
+ if (os_constant(e)) { \
+ __OS_COMPILETIME_ASSERT__(e); \
+ } \
+ _os_assumes_log((uint64_t)(uintptr_t)_e); \
+ _os_avoid_tail_call(); \
+ } \
+ _e; \
+})
+
+#define os_assumes_zero(e) __extension__({ \
+ __typeof__(e) _e = os_slowpath(e); \
+ if (_e) { \
+ if (os_constant(e)) { \
+ __OS_COMPILETIME_ASSERT__(!e); \
+ } \
+ _os_assumes_log((uint64_t)(uintptr_t)_e); \
+ _os_avoid_tail_call(); \
+ } \
+ _e; \
+})
+
+/* This variant is for use with old-style POSIX APIs that return -1 on failure
+ * and set errno. If the return code is -1, the value logged will be as though
+ * os_assumes_zero(errno) was used. It encapsulates the following pattern:
+ *
+ * int tubes[2];
+ * if (pipe(tubes) == -1) {
+ * (void)os_assumes_zero(errno);
+ * }
+ */
+#define posix_assumes_zero(e) __extension__({ \
+ __typeof__(e) _e = os_slowpath(e); \
+ if (_e == (typeof(e))-1) { \
+ _os_assumes_log((uint64_t)(uintptr_t)errno); \
+ _os_avoid_tail_call(); \
+ } \
+ _e; \
+})
+
+#define os_assert(e) __extension__({ \
+ __typeof__(e) _e = os_fastpath(e); \
+ if (!_e) { \
+ if (os_constant(e)) { \
+ __OS_COMPILETIME_ASSERT__(e); \
+ } \
+\
+ char *_fail_message = _os_assert_log((uint64_t)(uintptr_t)_e); \
+ os_set_crash_message(_fail_message); \
+ os_hardware_trap(); \
+ free(_fail_message); \
+ } \
+})
+
+#define os_assert_zero(e) __extension__({ \
+ __typeof__(e) _e = os_slowpath(e); \
+ if (_e) { \
+ if (os_constant(e)) { \
+ __OS_COMPILETIME_ASSERT__(!e); \
+ } \
+\
+ char *_fail_message = _os_assert_log((uint64_t)(uintptr_t)_e); \
+ os_set_crash_message(_fail_message); \
+ os_hardware_trap(); \
+ free(_fail_message); \
+ } \
+})
+
+#define posix_assert_zero(e) __extension__({ \
+ __typeof__(e) _e = os_slowpath(e); \
+ if (_e == (__typeof__(e))-1) { \
+ char *_fail_message = _os_assert_log((uint64_t)(uintptr_t)errno); \
+ os_set_crash_message(_fail_message); \
+ os_hardware_trap(); \
+ free(_fail_message); \
+ } \
+})
+
+/* These are for defining your own assumes()-like wrapper calls so that you can
+ * log additional information, such as the about-PID, sender, etc. They're
+ * generally not useful for direct inclusion in your code.
+ */
+#define os_assumes_ctx(f, ctx, e) __extension__({ \
+ __typeof__(e) _e = os_fastpath(e); \
+ if (!_e) { \
+ if (os_constant(e)) { \
+ __OS_COMPILETIME_ASSERT__(e); \
+ } \
+ _os_assumes_log_ctx(f, ctx, (uintptr_t)_e); \
+ _os_avoid_tail_call(); \
+ } \
+ _e; \
+})
+
+#define os_assumes_zero_ctx(f, ctx, e) __extension__({ \
+ __typeof__(e) _e = os_slowpath(e); \
+ if (_e) { \
+ if (os_constant(e)) { \
+ __OS_COMPILETIME_ASSERT__(!e); \
+ } \
+ _os_assumes_log_ctx((f), (ctx), (uintptr_t)_e); \
+ _os_avoid_tail_call(); \
+ } \
+ _e; \
+})
+
+#define posix_assumes_zero_ctx(f, ctx, e) __extension__({ \
+ __typeof__(e) _e = os_slowpath(e); \
+ if (_e == (__typeof__(e))-1) { \
+ _os_assumes_log_ctx((f), (ctx), (uintptr_t)errno); \
+ _os_avoid_tail_call(); \
+ } \
+ _e; \
+})
+
+#define os_assert_ctx(f, ctx, e) __extension__({ \
+ __typeof__(e) _e = os_fastpath(e); \
+ if (!_e) { \
+ if (os_constant(e)) { \
+ __OS_COMPILETIME_ASSERT__(e); \
+ } \
+\
+ char *_fail_message = _os_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)_e); \
+ os_set_crash_message(_fail_message); \
+ os_hardware_trap(); \
+ free(_fail_message); \
+ } \
+})
+
+#define os_assert_zero_ctx(f, ctx, e) __extension__({ \
+ __typeof__(e) _e = os_slowpath(e); \
+ if (_e) { \
+ if (os_constant(e)) { \
+ __OS_COMPILETIME_ASSERT__(!e); \
+ } \
+\
+ char *_fail_message = _os_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)_e); \
+ os_set_crash_message(_fail_message); \
+ os_hardware_trap(); \
+ free(_fail_message); \
+ } \
+})
+
+#define posix_assert_zero_ctx(f, ctx, e) __extension__({ \
+ __typeof__(e) _e = os_slowpath(e); \
+ if (_e == (__typeof__(e))-1) { \
+ char *_fail_message = _os_assert_log_ctx((f), (ctx), (uint64_t)(uintptr_t)errno); \
+ os_set_crash_message(_fail_message); \
+ os_hardware_trap(); \
+ free(_fail_message); \
+ } \
+})
+
+__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+extern void
+_os_assumes_log(uint64_t code);
+
+__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+extern char *
+_os_assert_log(uint64_t code);
+
+__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+extern void
+_os_assumes_log_ctx(os_log_callout_t callout, void *ctx, uint64_t code);
+
+__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+extern char *
+_os_assert_log_ctx(os_log_callout_t callout, void *ctx, uint64_t code);
+
+__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+extern void
+_os_avoid_tail_call(void);
+
+__END_DECLS
+
+#endif /* __OS_ASSUMES_H__ */
--- /dev/null
+/* Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef __OS_BASE_H__
+#define __OS_BASE_H__
+
+#if __GNUC__
+#define os_fastpath(x) ((__typeof__(x))(uintptr_t)__builtin_expect((uintptr_t)(x), ~0l))
+#define os_slowpath(x) ((__typeof__(x))(uintptr_t)__builtin_expect((uintptr_t)(x), 0l))
+#define os_constant(x) __builtin_constant_p((x))
+#define os_hardware_trap() __asm__ __volatile__ (""); __builtin_trap()
+
+#define __OS_COMPILETIME_ASSERT__(e) __extension__({ \
+ char __compile_time_assert__[(e) ? 1 : -1]; \
+ (void)__compile_time_assert__; \
+})
+
+#define __OS_CONST __attribute__((__const__))
+#define __OS_PRINTFLIKE(x,y) __attribute__((__format__(printf,x,y)))
+#else /* __GNUC__ */
+#define os_fastpath(x) (x)
+#define os_slowpath(x) (x)
+#define os_constant(x) ((long)0)
+#define os_hardware_trap() abort()
+
+#define __OS_COMPILETIME_ASSERT__(e) (e)
+
+#define __OS_CONST
+#define __OS_PRINTFLIKE(x,y)
+#endif /* __GNUC__ */
+
+#endif /* __OS_BASE_H__ */
--- /dev/null
+/* Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <dlfcn.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <mach/mach_time.h>
+#include <os/alloc_once_private.h>
+#include <os/trace.h>
+#include <_simple.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+// Move this to trace.h when it's removed from assumes.h
+typedef bool (*os_redirect_t)(const char *);
+
+struct os_trace_globals_s {
+ uint64_t start;
+ os_redirect_t redirect;
+ int logfd;
+ bool prepend_timestamp : 1;
+ bool errors_only : 1;
+};
+
+// If user picked a filename, use it and only it.
+// Otherwise, first try /var/tmp, then $TMPDIR, then give up.
+static inline
+int
+_os_trace_open_file(const char *suggestion)
+{
+ if (suggestion) {
+ return open(suggestion, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW |
+ O_EXCL | O_CLOEXEC, 0644);
+ }
+
+ int fd;
+ char filename[PATH_MAX];
+ char path[PATH_MAX];
+
+ snprintf(filename, sizeof(filename), "os_trace.%s.%d.log", getprogname(),
+ getpid());
+
+ strlcpy(path, "/var/tmp/", sizeof(path));
+ if (access(path, W_OK) == 0) {
+ strlcat(path, filename, sizeof(path));
+ fd = open(path, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW | O_EXCL |
+ O_CLOEXEC, 0644);
+ if (fd >= 0) {
+ return fd;
+ }
+ }
+
+ const char *tmpdir = getenv("TMPDIR");
+ if (tmpdir) {
+ strlcpy(path, tmpdir, sizeof(path));
+ if (access(path, W_OK) == 0) {
+ strlcat(path, filename, sizeof(path));
+ fd = open(path, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW |
+ O_EXCL | O_CLOEXEC, 0644);
+ if (fd >= 0) {
+ return fd;
+ }
+ }
+ }
+
+ return -1;
+}
+
+static
+void
+_os_trace_init(void *globals)
+{
+ struct os_trace_globals_s *g = globals;
+
+ g->errors_only = false;
+
+ g->redirect = dlsym(RTLD_MAIN_ONLY, "_os_trace_redirect_func");
+
+ // This is a bit of a hack. LIBDISPATCH_LOG is part of dispatch's API.
+ // But now all dispatch logging goes through os_trace. So we have to
+ // recognize this env var here in Libc.
+ // rdar://problem/11685359 tracks deprecating LIBDISPATCH_LOG from dispatch.
+ char *e = getenv("LIBDISPATCH_LOG");
+ if (!e) {
+ e = getenv("OS_TRACE");
+ }
+
+ // Default log destination
+ if (!e || strcmp(e, "YES") == 0) {
+#if DEBUG
+ e = "file";
+#else
+ e = "syslog";
+#endif
+ }
+
+ if (strcmp(e, "NO") == 0) {
+ g->logfd = -1;
+ g->errors_only = true;
+ } else if (strcmp(e, "syslog") == 0) {
+ g->logfd = -1;
+ } else if (strcmp(e, "stderr") == 0) {
+ g->logfd = STDERR_FILENO;
+ } else if (strcmp(e, "stdout") == 0) {
+ g->logfd = STDOUT_FILENO;
+ } else if (strcmp(e, "file") == 0) {
+ g->logfd = _os_trace_open_file(NULL);
+ if (g->logfd == -1) {
+ g->errors_only = true;
+ }
+ } else {
+ g->logfd = _os_trace_open_file(e);
+ if (g->logfd == -1) {
+ g->errors_only = true;
+ }
+ }
+
+ // From now on, g->logfd == -1 means syslog; anything >= 0 is the
+ // fd to use. Remember that file descriptor 0 is a perfectly valid
+ // value for open() to return if you closed (or never had) stdin.
+
+ // Timestamp every log message if logging directly to file and no
+ // redirector is set up.
+ if (g->logfd >= 0 && !g->redirect) {
+ g->prepend_timestamp = true;
+
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+
+ g->start = mach_absolute_time();
+
+ dprintf(g->logfd,
+ "=== os_trace log file opened for %s[%u] at %ld.%06u",
+ getprogname(), getpid(),
+ tv.tv_sec, tv.tv_usec);
+ if (g->prepend_timestamp) {
+ mach_timebase_info_data_t tbi;
+ if (mach_timebase_info(&tbi) == 0) {
+ dprintf(g->logfd, " [ns=ticks*%u/%u]",
+ tbi.numer, tbi.denom);
+ }
+ }
+ dprintf(g->logfd, " ===\n");
+ }
+}
+
+static inline __OS_CONST
+struct os_trace_globals_s *
+os_trace_globals(void)
+{
+ return (struct os_trace_globals_s *)
+ os_alloc_once(OS_ALLOC_ONCE_KEY_OS_TRACE,
+ sizeof(struct os_trace_globals_s),
+ _os_trace_init);
+}
+
+static __attribute__((always_inline))
+uint64_t
+_os_trace_ticks_since_start(void)
+{
+ return mach_absolute_time() - os_trace_globals()->start;
+}
+
+// False on error writing to file
+static inline
+bool
+_os_trace_write_fd(int level __attribute__((__unused__)),
+ char *str, int fd)
+{
+ size_t len = strlen(str);
+
+ str[len++] = '\n'; // overwrite null - don't use str*() anymore
+
+ ssize_t rc, wlen = 0;
+ do {
+ rc = write(fd, &str[wlen], len - wlen);
+ if (os_slowpath(rc == -1)) {
+ if(errno == EINTR) {
+ rc = 0;
+ } else {
+ return false;
+ }
+ }
+ wlen += rc;
+ } while (wlen < len);
+
+ return true;
+}
+
+static __attribute__((__noinline__))
+void
+_os_trace_write_error(void)
+{
+ char err_str[256];
+ const char *pfx = "os_trace() :";
+ size_t pfxlen = strlen(pfx);
+
+ strlcpy(err_str, pfx, sizeof(err_str));
+ strerror_r(errno, err_str+pfxlen, sizeof(err_str)-pfxlen);
+ _simple_asl_log(LOG_ERR, "com.apple.os_trace", err_str);
+}
+
+static inline
+void
+_os_trace_write(int level, char *str)
+{
+ int fd = os_trace_globals()->logfd;
+ os_redirect_t rdr = os_trace_globals()->redirect;
+ // true = redirect has fully handled, don't log
+ if (os_slowpath(rdr) && os_fastpath(rdr(str))) {
+ return;
+ }
+ if (os_slowpath(fd >= 0)) {
+ if (os_fastpath(_os_trace_write_fd(level, str, fd))) {
+ return;
+ } else {
+ _os_trace_write_error();
+ os_trace_globals()->logfd = -1;
+ // Don't return, fall out to syslog().
+ }
+ }
+ _simple_asl_log(level, "com.apple.os_trace", str);
+}
+
+static __attribute__((always_inline))
+void
+_os_tracev(int level, const char *msg, va_list ap)
+{
+ if (os_slowpath(os_trace_globals()->errors_only) && level > LOG_ERR) {
+ // more important = lower integer
+ return;
+ }
+ char *buf, *freebuf;
+ size_t len;
+
+ len = vasprintf(&buf, msg, ap);
+ if (!buf) {
+ return;
+ }
+ freebuf = buf;
+
+ // The os_trace macros prepend many spaces to the format string.
+ // Overwrite them with a timestamp, *or* skip them.
+ const size_t pfxlen = strlen(_OS_TRACE_PREFIX);
+ const size_t timelen = 16;
+ __OS_COMPILETIME_ASSERT__(pfxlen >= timelen);
+
+ if (os_fastpath(len > pfxlen)) {
+ if (os_slowpath(os_trace_globals()->prepend_timestamp)) {
+ char tmp = buf[timelen];
+ snprintf(buf, timelen + 1, "%16llu", _os_trace_ticks_since_start());
+ buf[timelen] = tmp; // snprintf's null
+ } else {
+ buf += pfxlen;
+ }
+ }
+
+ _os_trace_write(level, buf);
+ free(freebuf);
+}
+
+void
+_os_trace_error_str(char *msg)
+{
+ _os_trace_write(LOG_ERR, msg);
+}
+
+__OS_PRINTFLIKE(1, 2)
+void
+_os_trace(const char *msg, ...)
+{
+ va_list ap;
+ va_start(ap, msg);
+ _os_tracev(LOG_DEBUG, msg, ap);
+ va_end(ap);
+}
--- /dev/null
+/* Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef __OS_TRACE_H__
+#define __OS_TRACE_H__
+
+#include <Availability.h>
+#include <TargetConditionals.h>
+
+#include <os/base.h>
+#include <stdarg.h>
+
+__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+__OS_PRINTFLIKE(1, 2)
+extern void
+_os_trace(const char *msg, ...);
+
+/* The os_trace macros insert spaces before the message. If logging to a file,
+ * the spaces will be replaced by a timestamp. If logging to syslog, they will
+ * be skipped (syslog knows what time it is). There are 20 spaces because the
+ * timestamp is printed as %16llu + 4 spaces before the next column.
+ * 10^16 ns = 3.8 months. Don't run your process in _debug for that long. This
+ * isn't syslog.
+ */
+#define _OS_TRACE_PREFIX " "
+
+#define os_trace(tag, fmt, ...) __extension__({\
+ _os_trace(_OS_TRACE_PREFIX "%s: " fmt, tag, ## __VA_ARGS__); \
+})
+
+#define os_trace_ctx(tag, ctx, fmt, ...) __extension__({\
+ _os_trace(_OS_TRACE_PREFIX "[%p] %s: " fmt, ctx, tag, ## __VA_ARGS__); \
+})
+
+/* This is useful for clients who wish for the messages generated by os_trace()
+ * or os_assumes() failures to go somewhere other than (or in addition to) the
+ * system log, for example launchd or syslogd itself. If you don't wish for the
+ * message to be logged to the system log, then return true (to indicate that
+ * the message has been handled). If you want the default behavior, return
+ * false. Please use this macro, rather than directly declaring a function,
+ * since the declaration magic may change in the future.
+ */
+#define os_trace_redirect(func) \
+ __attribute__((__used__)) \
+ __attribute__((__visibility__("default"))) \
+ bool _os_trace_redirect_func(const char *msg) { \
+ return func(msg); \
+ }
+
+# pragma mark -
+# pragma mark Private To Libc
+
+// str must be modifiable (non-const)!
+__OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_6_0)
+extern void
+_os_trace_error_str(char *str);
+
+#endif /* __OS_TRACE_H__ */
static acl_t acl_get_file1(const char *path, acl_type_t acl_type, int follow);
+int acl_delete_fd_np(int filedes, acl_type_t type);
int
acl_delete_fd_np(int filedes, acl_type_t type)
{
return(-1);
}
+int acl_delete_file_np(const char *path, acl_type_t type);
int
acl_delete_file_np(const char *path, acl_type_t type)
{
return(-1);
}
+int acl_delete_link_np(const char *path, acl_type_t type);
int
acl_delete_link_np(const char *path, acl_type_t type)
{
+++ /dev/null
-/*
- * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * This program will generate the stuff necessary to "publish" the POSIX
- * header <pthread.h> in a machine dependent fashion.
- */
-
-#include <pthread_internals.h>
-#include <stdio.h>
-
-int
-main(void)
-{
- printf("#ifndef _PTHREAD_IMPL_H_\n");
- printf("#define _PTHREAD_IMPL_H_\n");
- printf("/*\n");
- printf(" * Internal implementation details\n");
- printf(" */\n");
- printf("\n");
- printf("#define __PTHREAD_SIZE__ %zd\n", sizeof(struct _pthread)-sizeof(long));
- printf("#define __PTHREAD_ATTR_SIZE__ %zd\n", sizeof(pthread_attr_t)-sizeof(long));
- printf("#define __PTHREAD_MUTEXATTR_SIZE__ %zd\n", sizeof(pthread_mutexattr_t)-sizeof(long));
- printf("#define __PTHREAD_MUTEX_SIZE__ %zd\n", sizeof(pthread_mutex_t)-sizeof(long));
- printf("#define __PTHREAD_CONDATTR_SIZE__ %zd\n", sizeof(pthread_condattr_t)-sizeof(long));
- printf("#define __PTHREAD_COND_SIZE__ %zd\n", sizeof(pthread_cond_t)-sizeof(long));
- printf("#define __PTHREAD_ONCE_SIZE__ %zd\n", sizeof(pthread_once_t)-sizeof(long));
- printf("#define __PTHREAD_sig_OFFSET__ %zd\n", offsetof(struct _pthread, sig));
- printf("#define __PTHREAD_cleanup_stack_OFFSET__ %zd\n", offsetof(struct _pthread, __cleanup_stack));
- printf("#define __PTHREAD_guardsize_OFFSET__ %zd\n", offsetof(struct _pthread, guardsize));
- printf("#define __PTHREAD_param_OFFSET__ %zd\n", offsetof(struct _pthread, param));
- printf("#define __PTHREAD_mutexes_OFFSET__ %zd\n", offsetof(struct _pthread, mutexes));
- printf("#define __PTHREAD_joiner_OFFSET__ %zd\n", offsetof(struct _pthread, joiner));
- printf("#define __PTHREAD_exit_value_OFFSET__ %zd\n", offsetof(struct _pthread, exit_value));
- printf("#define __PTHREAD_death_OFFSET__ %zd\n", offsetof(struct _pthread, death));
- printf("#define __PTHREAD_kernel_thread_OFFSET__ %zd\n", offsetof(struct _pthread, kernel_thread));
- printf("#define __PTHREAD_fun_OFFSET__ %zd\n", offsetof(struct _pthread, fun));
- printf("#define __PTHREAD_arg_OFFSET__ %zd\n", offsetof(struct _pthread, arg));
- printf("#define __PTHREAD_cancel_state_OFFSET__ %zd\n", offsetof(struct _pthread, cancel_state));
- printf("#define __PTHREAD_err_no_OFFSET__ %zd\n", offsetof(struct _pthread, err_no));
- printf("#define __PTHREAD_tsd_OFFSET__ %zd\n", offsetof(struct _pthread, tsd));
- printf("#define __PTHREAD_stackaddr_OFFSET__ %zd\n", offsetof(struct _pthread, stackaddr));
- printf("#define __PTHREAD_stacksize_OFFSET__ %zd\n", offsetof(struct _pthread, stacksize));
- printf("#define __PTHREAD_reply_port_OFFSET__ %zd\n", offsetof(struct _pthread, reply_port));
- printf("#define __PTHREAD_cthread_self_OFFSET__ %zd\n", offsetof(struct _pthread, cthread_self));
- printf("#define __PTHREAD_freeStackOnExit_OFFSET__ %zd\n", offsetof(struct _pthread, freeStackOnExit));
- printf("#define __PTHREAD_plist_OFFSET__ %zd\n", offsetof(struct _pthread, plist));
- printf("/*\n");
- printf(" * [Internal] data structure signatures\n");
- printf(" */\n");
- printf("#define _PTHREAD_MUTEX_SIG_init 0x%08X\n", _PTHREAD_MUTEX_SIG_init);
- printf("#define _PTHREAD_COND_SIG_init 0x%08X\n", _PTHREAD_COND_SIG_init);
- printf("#define _PTHREAD_ONCE_SIG_init 0x%08X\n", _PTHREAD_ONCE_SIG_init);
- printf("/*\n");
- printf(" * POSIX scheduling policies \n");
- printf(" */\n");
- printf("#define SCHED_OTHER %d\n", SCHED_OTHER);
- printf("#define SCHED_FIFO %d\n", SCHED_FIFO);
- printf("#define SCHED_RR %d\n", SCHED_RR);
- printf("\n");
- printf("#define __SCHED_PARAM_SIZE__ %ld\n", (long) sizeof(struct sched_param)-sizeof(int));
- printf("\n");
- printf("#endif _PTHREAD_IMPL_H_\n");
-
- exit(0);
-}
+++ /dev/null
-typedef struct _opaque_pthread_mutex_t pthread_mutex_t;
-typedef struct _opaque_pthread_rwlock_t pthread_rwlock_t;
-
-provider plockstat {
- probe mutex__acquire(pthread_mutex_t *mutex, int recursive, int spin_count);
- probe mutex__release(pthread_mutex_t *mutex, int recursive);
- probe mutex__error(pthread_mutex_t *mutex, int errno);
- probe mutex__block(pthread_mutex_t *mutex);
- probe mutex__blocked(pthread_mutex_t *mutex, int successful);
- probe mutex__spin(pthread_mutex_t *mutex);
- probe mutex__spun(pthread_mutex_t *mutex, int successful, int spin_count);
-
- probe rw__acquire(pthread_rwlock_t *rwlock, int write_lock);
- probe rw__block(pthread_rwlock_t *rwlock, int write_lock);
- probe rw__blocked(pthread_rwlock_t *rwlock, int write_lock, int successful);
- probe rw__release(pthread_rwlock_t *rwlock, int write_lock);
- probe rw__error(pthread_rwlock_t *rwlock, int write_lock, int error);
-};
-
-#pragma D attributes Evolving/Evolving/ISA provider plockstat provider
-#pragma D attributes Private/Private/Unknown provider plockstat module
-#pragma D attributes Private/Private/Unknown provider plockstat function
-#pragma D attributes Evolving/Evolving/ISA provider plockstat name
-#pragma D attributes Evolving/Evolving/ISA provider plockstat args
+++ /dev/null
-/*
- * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * POSIX Realtime Scheduling Framework - IEEE 1003.1b
- */
-
-#ifndef _POSIX_SCHED_H
-#define _POSIX_SCHED_H
-
-struct sched_param
-{
- int sched_priority;
- int quantum;
-};
-
-/*
- * POSIX scheduling policies
- */
-
-#define SCHED_OTHER POLICY_TIMESHARE
-#define SCHED_FIFO POLICY_FIFO
-#define SCHED_RR POLICY_RR
-
-#endif /* _POSIX_SCHED_H */
+++ /dev/null
-.\" Portions Copyright (c) 2001 Apple Computer, Inc. All Rights Reserved.
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/share/man/man3/pthread.3,v 1.12.2.4 2001/08/17 13:08:36 ru Exp $
-.\"
-.Dd November 5, 2001
-.Dt PTHREAD 3
-.Os Darwin
-.Sh NAME
-.Nm pthread
-.Nd POSIX thread functions
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Sh DESCRIPTION
-POSIX threads are a set of functions that support applications with
-requirements for multiple flows of control, called
-.Fa threads ,
-within a process.
-Multithreading is used to improve the performance of a
-program.
-.Pp
-The POSIX thread functions are summarized in this section in the following
-groups:
-.Bl -bullet -offset indent
-.It
-Thread Routines
-.It
-Attribute Object Routines
-.It
-Mutex Routines
-.It
-Condition Variable Routines
-.It
-Read/Write Lock Routines
-.It
-Per-Thread Context Routines
-.It
-Cleanup Routines
-.El
-.Sh THREAD ROUTINES
-.Bl -tag -width Er
-.It Xo
-.Ft int
-.Fn pthread_create "pthread_t *thread" "const pthread_attr_t *attr" "void *(*start_routine)(void *)" "void *arg"
-.Xc
-Creates a new thread of execution.
-.It Xo
-.Ft int
-.Fn pthread_detach "pthread_t thread"
-.Xc
-Marks a thread for deletion.
-.It Xo
-.Ft int
-.Fn pthread_equal "pthread_t t1" "pthread_t t2"
-.Xc
-Compares two thread IDs.
-.It Xo
-.Ft void
-.Fn pthread_exit "void *value_ptr"
-.Xc
-Terminates the calling thread.
-.It Xo
-.Ft int
-.Fn pthread_join "pthread_t thread" "void **value_ptr"
-.Xc
-Causes the calling thread to wait for the termination of the specified thread.
-.It Xo
-.Ft int
-.Fn pthread_cancel "pthread_t thread"
-.Xc
-Cancels execution of a thread.
-.It Xo
-.Ft int
-.Fn pthread_once "pthread_once_t *once_control" "void (*init_routine)(void)"
-.Xc
-Calls an initialization routine once.
-.It Xo
-.Ft pthread_t
-.Fn pthread_self void
-.Xc
-Returns the thread ID of the calling thread.
-.It Xo
-.Ft int
-.Fn pthread_atfork "void (*prepare)(void)" "void (*parent)(void)" "void (*child)(void)"
-.Xc
-Registers handlers to be called before and after
-.Fn fork
-.El
-.Sh ATTRIBUTE OBJECT ROUTINES
-.Bl -tag -width Er
-.It Xo
-.Ft int
-.Fn pthread_attr_destroy "pthread_attr_t *attr"
-.Xc
-Destroy a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_getinheritsched "const pthread_attr_t *attr" "int *inheritsched"
-.Xc
-Get the inherit scheduling attribute from a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_getschedparam "const pthread_attr_t *attr" "struct sched_param *param"
-.Xc
-Get the scheduling parameter attribute from a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_getschedpolicy "const pthread_attr_t *attr" "int *policy"
-.Xc
-Get the scheduling policy attribute from a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_getscope "const pthread_attr_t *attr" "int *contentionscope"
-.Xc
-Get the contention scope attribute from a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_getstacksize "const pthread_attr_t *attr" "size_t *stacksize"
-.Xc
-Get the stack size attribute from a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_getstackaddr "const pthread_attr_t *attr" "void **stackaddr"
-.Xc
-Get the stack address attribute from a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_getdetachstate "const pthread_attr_t *attr" "int *detachstate"
-.Xc
-Get the detach state attribute from a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_init "pthread_attr_t *attr"
-.Xc
-Initialize a thread attributes object with default values.
-.It Xo
-.Ft int
-.Fn pthread_attr_setinheritsched "pthread_attr_t *attr" "int inheritsched"
-.Xc
-Set the inherit scheduling attribute in a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_setschedparam "pthread_attr_t *attr" "const struct sched_param *param"
-.Xc
-Set the scheduling parameter attribute in a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_setschedpolicy "pthread_attr_t *attr" "int policy"
-.Xc
-Set the scheduling policy attribute in a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_setscope "pthread_attr_t *attr" "int contentionscope"
-.Xc
-Set the contention scope attribute in a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_setstacksize "pthread_attr_t *attr" "size_t stacksize"
-.Xc
-Set the stack size attribute in a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_setstackaddr "pthread_attr_t *attr" "void *stackaddr"
-.Xc
-Set the stack address attribute in a thread attributes object.
-.It Xo
-.Ft int
-.Fn pthread_attr_setdetachstate "pthread_attr_t *attr" "int detachstate"
-.Xc
-Set the detach state in a thread attributes object.
-.El
-.Sh MUTEX ROUTINES
-.Bl -tag -width Er
-.It Xo
-.Ft int
-.Fn pthread_mutexattr_destroy "pthread_mutexattr_t *attr"
-.Xc
-Destroy a mutex attributes object.
-.It Xo
-.Ft int
-.Fn pthread_mutexattr_init "pthread_mutexattr_t *attr"
-.Xc
-Initialize a mutex attributes object with default values.
-.It Xo
-.Ft int
-.Fn pthread_mutex_destroy "pthread_mutex_t *mutex"
-.Xc
-Destroy a mutex.
-.It Xo
-.Ft int
-.Fn pthread_mutex_init "pthread_mutex_t *mutex" "const pthread_mutexattr_t *attr"
-.Xc
-Initialize a mutex with specified attributes.
-.It Xo
-.Ft int
-.Fn pthread_mutex_lock "pthread_mutex_t *mutex"
-.Xc
-Lock a mutex and block until it becomes available.
-.It Xo
-.Ft int
-.Fn pthread_mutex_trylock "pthread_mutex_t *mutex"
-.Xc
-Try to lock a mutex, but don't block if the mutex is locked by another thread,
-including the current thread.
-.It Xo
-.Ft int
-.Fn pthread_mutex_unlock "pthread_mutex_t *mutex"
-.Xc
-Unlock a mutex.
-.El
-.Sh CONDITION VARIABLE ROUTINES
-.Bl -tag -width Er
-.It Xo
-.Ft int
-.Fn pthread_condattr_init "pthread_condattr_t *attr"
-.Xc
-Initialize a condition variable attributes object with default values.
-.It Xo
-.Ft int
-.Fn pthread_condattr_destroy "pthread_condattr_t *attr"
-.Xc
-Destroy a condition variable attributes object.
-.It Xo
-.Ft int
-.Fn pthread_cond_broadcast "pthread_cond_t *cond"
-.Xc
-Unblock all threads currently blocked on the specified condition variable.
-.It Xo
-.Ft int
-.Fn pthread_cond_destroy "pthread_cond_t *cond"
-.Xc
-Destroy a condition variable.
-.It Xo
-.Ft int
-.Fn pthread_cond_init "pthread_cond_t *cond" "const pthread_condattr_t *attr"
-.Xc
-Initialize a condition variable with specified attributes.
-.It Xo
-.Ft int
-.Fn pthread_cond_signal "pthread_cond_t *cond"
-.Xc
-Unblock at least one of the threads blocked on the specified condition variable.
-.It Xo
-.Ft int
-.Fn pthread_cond_timedwait "pthread_cond_t *cond" "pthread_mutex_t *mutex" "const struct timespec *abstime"
-.Xc
-Wait no longer than the specified time for a condition and lock the specified mutex.
-.It Xo
-.Ft int
-.Fn pthread_cond_wait "pthread_cond_t *" "pthread_mutex_t *mutex"
-.Xc
-Wait for a condition and lock the specified mutex.
-.El
-.Sh READ/WRITE LOCK ROUTINES
-.Bl -tag -width Er
-.It Xo
-.Ft int
-.Fn pthread_rwlock_destroy "pthread_rwlock_t *lock"
-.Xc
-Destroy a read/write lock object.
-.It Xo
-.Ft int
-.Fn pthread_rwlock_init "pthread_rwlock_t *lock" "const pthread_rwlockattr_t *attr"
-.Xc
-Initialize a read/write lock object.
-.It Xo
-.Ft int
-.Fn pthread_rwlock_rdlock "pthread_rwlock_t *lock"
-.Xc
-Lock a read/write lock for reading, blocking until the lock can be
-acquired.
-.It Xo
-.Ft int
-.Fn pthread_rwlock_tryrdlock "pthread_rwlock_t *lock"
-.Xc
-Attempt to lock a read/write lock for reading, without blocking if the
-lock is unavailable.
-.It Xo
-.Ft int
-.Fn pthread_rwlock_trywrlock "pthread_rwlock_t *lock"
-.Xc
-Attempt to lock a read/write lock for writing, without blocking if the
-lock is unavailable.
-.It Xo
-.Ft int
-.Fn pthread_rwlock_unlock "pthread_rwlock_t *lock"
-.Xc
-Unlock a read/write lock.
-.It Xo
-.Ft int
-.Fn pthread_rwlock_wrlock "pthread_rwlock_t *lock"
-.Xc
-Lock a read/write lock for writing, blocking until the lock can be
-acquired.
-.It Xo
-.Ft int
-.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr"
-.Xc
-Destroy a read/write lock attribute object.
-.It Xo
-.Ft int
-.Fn pthread_rwlockattr_getpshared "const pthread_rwlockattr_t *attr" "int *pshared"
-.Xc
-Retrieve the process shared setting for the read/write lock attribute
-object.
-.It Xo
-.Ft int
-.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr"
-.Xc
-Initialize a read/write lock attribute object.
-.It Xo
-.Ft int
-.Fn pthread_rwlockattr_setpshared "pthread_rwlockattr_t *attr" "int pshared"
-.Xc
-Set the process shared setting for the read/write lock attribute object.
-.El
-.Sh PER-THREAD CONTEXT ROUTINES
-.Bl -tag -width Er
-.It Xo
-.Ft int
-.Fn pthread_key_create "pthread_key_t *key" "void (*routine)(void *)"
-.Xc
-Create a thread-specific data key.
-.It Xo
-.Ft int
-.Fn pthread_key_delete "pthread_key_t key"
-.Xc
-Delete a thread-specific data key.
-.It Xo
-.Ft "void *"
-.Fn pthread_getspecific "pthread_key_t key"
-.Xc
-Get the thread-specific value for the specified key.
-.It Xo
-.Ft int
-.Fn pthread_setspecific "pthread_key_t key" "const void *value_ptr"
-.Xc
-Set the thread-specific value for the specified key.
-.El
-.Sh CLEANUP ROUTINES
-.Bl -tag -width Er
-.It Xo
-.Ft void
-.Fn pthread_cleanup_pop "int execute"
-.Xc
-Remove the routine at the top of the calling thread's cancellation cleanup
-stack and optionally invoke it.
-.It Xo
-.Ft void
-.Fn pthread_cleanup_push "void (*routine)(void *)" "void *routine_arg"
-.Xc
-Push the specified cancellation cleanup handler onto the calling thread's
-cancellation stack.
-.El
-.Sh INSTALLATION
-The default system libraries include
-.Nm pthread
-functions.
-No additional libraries or CFLAGS are necessary to use this API.
-.Sh SEE ALSO
-.Xr pthread_cleanup_pop 3 ,
-.Xr pthread_cleanup_push 3 ,
-.Xr pthread_cond_broadcast 3 ,
-.Xr pthread_cond_destroy 3 ,
-.Xr pthread_cond_init 3 ,
-.Xr pthread_cond_signal 3 ,
-.Xr pthread_cond_timedwait 3 ,
-.Xr pthread_cond_wait 3 ,
-.Xr pthread_create 3 ,
-.Xr pthread_detach 3 ,
-.Xr pthread_equal 3 ,
-.Xr pthread_exit 3 ,
-.Xr pthread_getspecific 3 ,
-.Xr pthread_join 3 ,
-.Xr pthread_key_delete 3 ,
-.Xr pthread_mutex_destroy 3 ,
-.Xr pthread_mutex_init 3 ,
-.Xr pthread_mutex_lock 3 ,
-.Xr pthread_mutex_trylock 3 ,
-.Xr pthread_mutex_unlock 3 ,
-.Xr pthread_once 3 ,
-.Xr pthread_rwlock_destroy 3 ,
-.Xr pthread_rwlock_init 3 ,
-.Xr pthread_rwlock_rdlock 3 ,
-.Xr pthread_rwlock_unlock 3 ,
-.Xr pthread_rwlock_wrlock 3 ,
-.Xr pthread_rwlockattr_destroy 3 ,
-.Xr pthread_rwlockattr_getpshared 3 ,
-.Xr pthread_rwlockattr_init 3 ,
-.Xr pthread_rwlockattr_setpshared 3 ,
-.Xr pthread_self 3 ,
-.Xr pthread_setspecific 3
-.Sh STANDARDS
-The functions in
-.Fa libc
-with the
-.Fa pthread_
-prefix and not
-.Fa _np
-suffix or
-.Fa pthread_rwlock
-prefix conform to
-.St -p1003.1-96 .
-.Pp
-The functions in libc with the
-.Fa pthread_
-prefix and
-.Fa _np
-suffix are non-portable extensions to POSIX threads.
-.Pp
-The functions in libc with the
-.Fa pthread_rwlock
-prefix are extensions created by The Open Group as part of the
-.St -susv2 .
+++ /dev/null
-/*
- * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * POSIX Pthread Library
- */
-
-#include "pthread_internals.h"
-#include "pthread_workqueue.h"
-
-#include <assert.h>
-#include <stdio.h> /* For printf(). */
-#include <stdlib.h>
-#include <errno.h> /* For __mach_errno_addr() prototype. */
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/sysctl.h>
-#include <sys/queue.h>
-#include <sys/mman.h>
-#include <machine/vmparam.h>
-#include <mach/vm_statistics.h>
-#include <mach/mach_init.h>
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-#include <libkern/OSAtomic.h>
-#if defined(__ppc__)
-#include <libkern/OSCrossEndian.h>
-#endif
-#include <dispatch/private.h> /* for at_fork handlers */
-
-
-extern int _pthread_setcancelstate_internal(int state, int *oldstate, int conforming);
-extern int __pthread_sigmask(int, const sigset_t *, sigset_t *);
-
-#ifndef BUILDING_VARIANT /* [ */
-
-__private_extern__ struct __pthread_list __pthread_head = TAILQ_HEAD_INITIALIZER(__pthread_head);
-
-
-
-int32_t workq_targetconc[WORKQ_NUM_PRIOQUEUE];
-
-/* Per-thread kernel support */
-extern void _pthread_set_self(pthread_t);
-extern void mig_init(int);
-static int _pthread_create_pthread_onstack(pthread_attr_t *attrs, void **stack, pthread_t *thread);
-static kern_return_t _pthread_free_pthread_onstack(pthread_t t, int freestruct, int termthread);
-static void _pthread_struct_init(pthread_t t, const pthread_attr_t *attrs, void * stack, size_t stacksize, int kernalloc, int nozero);
-static int _new_pthread_create_suspended(pthread_t *thread,
- const pthread_attr_t *attr,
- void *(*start_routine)(void *),
- void *arg,
- int create_susp);
-
-/* the registered libdispatch worker function */
-static void (*__libdispatch_workerfunction)(int, int, void *) = NULL;
-
-/* Get CPU capabilities from the kernel */
-__private_extern__ void _init_cpu_capabilities(void);
-
-/* Needed to tell the malloc subsystem we're going multithreaded */
-extern void set_malloc_singlethreaded(int);
-
-/* Used when we need to call into the kernel with no reply port */
-extern pthread_lock_t reply_port_lock;
-int _pthread_find_thread(pthread_t thread);
-
-/* Mach message used to notify that a thread needs to be reaped */
-
-typedef struct _pthread_reap_msg_t {
- mach_msg_header_t header;
- pthread_t thread;
- mach_msg_trailer_t trailer;
-} pthread_reap_msg_t;
-
-/* Utilitie */
-
-__private_extern__ uintptr_t commpage_pfz_base=0;
-
-void __pthread_pfz_setup(const char *apple[]) __attribute__ ((visibility ("hidden")));
-
-static uintptr_t __pfz_from_kernel(const char *str)
-{
- unsigned long tmpval;
- /* Skip over key to the first value */
- str = strchr(str, '=');
- if (str == NULL)
- return 0;
- str++;
- tmpval = strtoul(str, NULL, 0); /* may err by 0 or ULONG_MAX */
- if (tmpval == ULONG_MAX)
- tmpval = 0;
-
- return (uintptr_t) tmpval;
-}
-
-void
-__pthread_pfz_setup(const char *apple[])
-{
- const char **p;
- for (p = apple; p && *p; p++) {
- /* checking if matching apple variable is at begining */
- if (strstr(*p, "pfz=") == *p) {
- commpage_pfz_base = __pfz_from_kernel(*p);
- bzero(*p,strlen(*p));
- break;
- }
- }
-
- if (commpage_pfz_base == 0)
- commpage_pfz_base = _COMM_PAGE_TEXT_START;
-
- return;
-}
-
-
-/* We'll implement this when the main thread is a pthread */
-/* Use the local _pthread struct to avoid malloc before our MiG reply port is set */
-static struct _pthread _thread = {0};
-
-/* This global should be used (carefully) by anyone needing to know if a
-** pthread has been created.
-*/
-int __is_threaded = 0;
-/* _pthread_count is protected by _pthread_list_lock */
-static int _pthread_count = 1;
-int __unix_conforming = 0;
-static int __workqueue_newspis = 0;
-static int __workqueue_oldspis = 0;
-__private_extern__ size_t pthreadsize = 0;
-
-/* under rosetta we will use old style creation of threads */
-static int __oldstyle = 0;
-
-__private_extern__ pthread_lock_t _pthread_list_lock = LOCK_INITIALIZER;
-
-/* Same implementation as LOCK, but without the __is_threaded check */
-int _spin_tries = 0;
-extern kern_return_t syscall_thread_switch(mach_port_name_t, int, mach_msg_timeout_t);
-__private_extern__ void _spin_lock_retry(pthread_lock_t *lock)
-{
- int tries = _spin_tries;
- do {
- if (tries-- > 0)
- continue;
- syscall_thread_switch(THREAD_NULL, SWITCH_OPTION_DEPRESS, 1);
- tries = _spin_tries;
- } while(!_spin_lock_try(lock));
-}
-
-static mach_port_t thread_recycle_port = MACH_PORT_NULL;
-
-/* These are used to keep track of a semaphore pool shared by mutexes and condition
-** variables.
-*/
-
-static semaphore_t *sem_pool = NULL;
-static int sem_pool_count = 0;
-static int sem_pool_current = 0;
-static pthread_lock_t sem_pool_lock = LOCK_INITIALIZER;
-
-static int default_priority;
-static int max_priority;
-static int min_priority;
-static int pthread_concurrency;
-
-static OSSpinLock __workqueue_list_lock = OS_SPINLOCK_INIT;
-
-static void _pthread_exit(pthread_t self, void *value_ptr) __dead2;
-static void _pthread_setcancelstate_exit(pthread_t self, void *value_ptr, int conforming);
-static pthread_attr_t _pthread_attr_default = {0};
-static void _pthread_workq_init(pthread_workqueue_t wq, const pthread_workqueue_attr_t * attr);
-static int kernel_workq_setup = 0;
-static volatile int32_t kernel_workq_count = 0;
-static volatile unsigned int user_workq_count = 0; /* number of outstanding workqueues */
-static volatile unsigned int user_workitem_count = 0; /* number of outstanding workitems */
-#define KERNEL_WORKQ_ELEM_MAX 64 /* Max number of elements in the kerrel */
-static int wqreadyprio = 0; /* current highest prio queue ready with items */
-
-__private_extern__ struct __pthread_workitem_pool __pthread_workitem_pool_head = TAILQ_HEAD_INITIALIZER(__pthread_workitem_pool_head);
-__private_extern__ struct __pthread_workqueue_pool __pthread_workqueue_pool_head = TAILQ_HEAD_INITIALIZER(__pthread_workqueue_pool_head);
-
-static struct _pthread_workitem * __workqueue_pool_ptr;
-static size_t __workqueue_pool_size = 0;
-static int __workqueue_nitems = 0;
-
-struct _pthread_workqueue_head __pthread_workq0_head;
-struct _pthread_workqueue_head __pthread_workq1_head;
-struct _pthread_workqueue_head __pthread_workq2_head;
-struct _pthread_workqueue_head __pthread_workq3_head;
-pthread_workqueue_head_t __pthread_wq_head_tbl[WORKQ_NUM_PRIOQUEUE] = {&__pthread_workq0_head, &__pthread_workq1_head, &__pthread_workq2_head, &__pthread_workq3_head};
-
-static void workqueue_list_lock(void);
-static void workqueue_list_unlock(void);
-static int valid_workq(pthread_workqueue_t);
-static void pick_nextworkqueue_droplock(void);
-static int post_nextworkitem(pthread_workqueue_t workq);
-static void _pthread_workq_return(pthread_t self);
-static pthread_workqueue_attr_t _pthread_wq_attr_default = {0};
-extern void start_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_workitem_t item, int reuse);
-extern void thread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int flags);
-static pthread_workitem_t alloc_workitem(void);
-static void free_workitem(pthread_workitem_t);
-static void grow_workitem(void);
-static pthread_workqueue_t alloc_workqueue(void);
-static void free_workqueue(pthread_workqueue_t);
-static int _pthread_work_internal_init(void);
-static void workqueue_exit(pthread_t self, pthread_workqueue_t workq, pthread_workitem_t item);
-void _pthread_fork_child_postinit();
-
-void pthread_workqueue_atfork_prepare(void);
-void pthread_workqueue_atfork_parent(void);
-void pthread_workqueue_atfork_child(void);
-
-extern void dispatch_atfork_prepare(void);
-extern void dispatch_atfork_parent(void);
-extern void dispatch_atfork_child(void);
-
-/* workq_kernreturn commands */
-#define WQOPS_QUEUE_ADD 1
-#define WQOPS_QUEUE_REMOVE 2
-#define WQOPS_THREAD_RETURN 4
-#define WQOPS_THREAD_SETCONC 8
-#define WQOPS_QUEUE_NEWSPISUPP 0x10 /* this is to check for newer SPI support */
-#define WQOPS_QUEUE_REQTHREADS 0x20 /* request number of threads of a prio */
-
-/* flag values for reuse field in the libc side _pthread_wqthread */
-#define WQ_FLAG_THREAD_PRIOMASK 0x0000ffff
-#define WQ_FLAG_THREAD_OVERCOMMIT 0x00010000 /* thread is with overcommit prio */
-#define WQ_FLAG_THREAD_REUSE 0x00020000 /* thread is being reused */
-#define WQ_FLAG_THREAD_NEWSPI 0x00040000 /* the call is with new SPIs */
-
-
-#define WORKQUEUE_OVERCOMMIT 0x10000 /* the work_kernreturn() for overcommit in prio field */
-
-/*
- * Flags filed passed to bsdthread_create and back in pthread_start
-31 <---------------------------------> 0
-_________________________________________
-| flags(8) | policy(8) | importance(16) |
------------------------------------------
-*/
-__private_extern__
-void _pthread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int flags);
-
-__private_extern__
-void _pthread_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_workitem_t item, int reuse);
-
-#define PTHREAD_START_CUSTOM 0x01000000
-#define PTHREAD_START_SETSCHED 0x02000000
-#define PTHREAD_START_DETACHED 0x04000000
-#define PTHREAD_START_POLICY_BITSHIFT 16
-#define PTHREAD_START_POLICY_MASK 0xff
-#define PTHREAD_START_IMPORTANCE_MASK 0xffff
-
-static int pthread_setschedparam_internal(pthread_t, mach_port_t, int, const struct sched_param *);
-extern pthread_t __bsdthread_create(void *(*func)(void *), void * func_arg, void * stack, pthread_t thread, unsigned int flags);
-extern int __bsdthread_register(void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), void (*)(pthread_t, mach_port_t, void *, pthread_workitem_t, int), int,void (*)(pthread_t, mach_port_t, void *(*)(void *), void *, size_t, unsigned int), int32_t *,__uint64_t);
-extern int __bsdthread_terminate(void * freeaddr, size_t freesize, mach_port_t kport, mach_port_t joinsem);
-extern __uint64_t __thread_selfid( void );
-extern int __pthread_canceled(int);
-extern void _pthread_keys_init(void);
-extern int __pthread_kill(mach_port_t, int);
-extern int __pthread_markcancel(int);
-extern int __workq_open(void);
-
-
-extern int __workq_kernreturn(int, pthread_workitem_t, int, int);
-
-#if defined(__ppc__) || defined(__ppc64__)
-static const vm_address_t PTHREAD_STACK_HINT = 0xF0000000;
-#elif defined(__i386__) || defined(__x86_64__)
-static const vm_address_t PTHREAD_STACK_HINT = 0xB0000000;
-#elif defined(__arm__)
-static const vm_address_t PTHREAD_STACK_HINT = 0x30000000;
-#else
-#error Need to define a stack address hint for this architecture
-#endif
-
-/* Set the base address to use as the stack pointer, before adjusting due to the ABI
- * The guardpages for stackoverflow protection is also allocated here
- * If the stack was already allocated(stackaddr in attr) then there are no guardpages
- * set up for the thread
- */
-
-static int
-_pthread_allocate_stack(pthread_attr_t *attrs, void **stack)
-{
- kern_return_t kr;
- vm_address_t stackaddr;
- size_t guardsize;
-
- assert(attrs->stacksize >= PTHREAD_STACK_MIN);
- if (attrs->stackaddr != NULL) {
- /* No guard pages setup in this case */
- assert(((uintptr_t)attrs->stackaddr % vm_page_size) == 0);
- *stack = attrs->stackaddr;
- return 0;
- }
-
- guardsize = attrs->guardsize;
- stackaddr = PTHREAD_STACK_HINT;
- kr = vm_map(mach_task_self(), &stackaddr,
- attrs->stacksize + guardsize,
- vm_page_size-1,
- VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE , MEMORY_OBJECT_NULL,
- 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL,
- VM_INHERIT_DEFAULT);
- if (kr != KERN_SUCCESS)
- kr = vm_allocate(mach_task_self(),
- &stackaddr, attrs->stacksize + guardsize,
- VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE);
- if (kr != KERN_SUCCESS) {
- return EAGAIN;
- }
- /* The guard page is at the lowest address */
- /* The stack base is the highest address */
- if (guardsize)
- kr = vm_protect(mach_task_self(), stackaddr, guardsize, FALSE, VM_PROT_NONE);
- *stack = (void *)(stackaddr + attrs->stacksize + guardsize);
- return 0;
-}
-
-static int
-_pthread_create_pthread_onstack(pthread_attr_t *attrs, void **stack, pthread_t *thread)
-{
- kern_return_t kr;
- pthread_t t;
- vm_address_t stackaddr;
- size_t guardsize, allocsize;
-
- assert(attrs->stacksize >= PTHREAD_STACK_MIN);
-
- if (attrs->stackaddr != NULL) {
- /* No guard pages setup in this case */
- assert(((uintptr_t)attrs->stackaddr % vm_page_size) == 0);
- *stack = attrs->stackaddr;
- t = (pthread_t)malloc(pthreadsize);
- _pthread_struct_init(t, attrs, attrs->stackaddr, 0, 0, 0);
- t->freeStackOnExit = 0;
- t->freeaddr = 0;
- t->freesize = 0;
- *thread = t;
- return 0;
- }
-
- guardsize = attrs->guardsize;
- allocsize = attrs->stacksize + guardsize + pthreadsize;
- stackaddr = PTHREAD_STACK_HINT;
- kr = vm_map(mach_task_self(), &stackaddr,
- allocsize,
- vm_page_size-1,
- VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE , MEMORY_OBJECT_NULL,
- 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL,
- VM_INHERIT_DEFAULT);
- if (kr != KERN_SUCCESS)
- kr = vm_allocate(mach_task_self(),
- &stackaddr, allocsize,
- VM_MAKE_TAG(VM_MEMORY_STACK)| VM_FLAGS_ANYWHERE);
- if (kr != KERN_SUCCESS) {
- return EAGAIN;
- }
- /* The guard page is at the lowest address */
- /* The stack base is the highest address */
- if (guardsize)
- kr = vm_protect(mach_task_self(), stackaddr, guardsize, FALSE, VM_PROT_NONE);
-
-
- *stack = (void *)(stackaddr + attrs->stacksize + guardsize);
-
- t = (pthread_t)(stackaddr + attrs->stacksize + guardsize);
- _pthread_struct_init(t, attrs, *stack, 0, 0, 1);
- t->kernalloc = 0;
- t->freesize = allocsize;
- t->freeaddr = (void *)stackaddr;
- t->freeStackOnExit = 1;
- *thread = t;
-
- return 0;
-}
-
-static kern_return_t
-_pthread_free_pthread_onstack(pthread_t t, int freestruct, int termthread)
-{
- kern_return_t res = 0;
- vm_address_t freeaddr;
- size_t freesize;
- int thread_count;
- mach_port_t kport;
- semaphore_t joinsem = SEMAPHORE_NULL;
-
-#if PTH_TRACE
- __kdebug_trace(0x900001c, freestruct, termthread, 0, 0, 0);
-#endif
- kport = t->kernel_thread;
- joinsem = t->joiner_notify;
-
- if (t->freeStackOnExit) {
- freeaddr = (vm_address_t)t->freeaddr;
- if (freestruct)
- freesize = t->stacksize + t->guardsize + pthreadsize;
- else
- freesize = t->stacksize + t->guardsize;
- if (termthread) {
- mig_dealloc_reply_port(MACH_PORT_NULL);
- LOCK(_pthread_list_lock);
- if (freestruct != 0) {
- TAILQ_REMOVE(&__pthread_head, t, plist);
- /* if parent has not returned from create yet keep pthread_t */
-#if PTH_LISTTRACE
- __kdebug_trace(0x9000010, t, 0, 0, 1, 0);
-#endif
- if (t->parentcheck == 0)
- freesize -= pthreadsize;
- }
- t->childexit = 1;
- thread_count = --_pthread_count;
- UNLOCK(_pthread_list_lock);
-
-#if PTH_TRACE
- __kdebug_trace(0x9000020, freeaddr, freesize, kport, 1, 0);
-#endif
- if (thread_count <=0)
- exit(0);
- else
- __bsdthread_terminate((void *)freeaddr, freesize, kport, joinsem);
- LIBC_ABORT("thread %p didn't terminate", t);
- } else {
-#if PTH_TRACE
- __kdebug_trace(0x9000024, freeaddr, freesize, 0, 1, 0);
-#endif
- res = vm_deallocate(mach_task_self(), freeaddr, freesize);
- }
- } else {
- if (termthread) {
- mig_dealloc_reply_port(MACH_PORT_NULL);
- LOCK(_pthread_list_lock);
- if (freestruct != 0) {
- TAILQ_REMOVE(&__pthread_head, t, plist);
-#if PTH_LISTTRACE
- __kdebug_trace(0x9000010, t, 0, 0, 2, 0);
-#endif
- }
- thread_count = --_pthread_count;
- t->childexit = 1;
- UNLOCK(_pthread_list_lock);
-
- if (freestruct) {
-#if PTH_TRACE
- __kdebug_trace(0x9000008, t, 0, 0, 2, 0);
-#endif
- free(t);
- }
-
- freeaddr = 0;
- freesize = 0;
-#if PTH_TRACE
- __kdebug_trace(0x9000020, 0, 0, kport, 2, 0);
-#endif
-
- if (thread_count <=0)
- exit(0);
- else
- __bsdthread_terminate(NULL, 0, kport, joinsem);
- LIBC_ABORT("thread %p didn't terminate", t);
- } else if (freestruct) {
- t->sig = _PTHREAD_NO_SIG;
-#if PTH_TRACE
- __kdebug_trace(0x9000024, t, 0, 0, 2, 0);
-#endif
- free(t);
- }
- }
- return(res);
-}
-
-
-
-/*
- * Destroy a thread attribute structure
- */
-int
-pthread_attr_destroy(pthread_attr_t *attr)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG)
- {
- attr->sig = 0;
- return (0);
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/*
- * Get the 'detach' state from a thread attribute structure.
- * Note: written as a helper function for info hiding
- */
-int
-pthread_attr_getdetachstate(const pthread_attr_t *attr,
- int *detachstate)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG)
- {
- *detachstate = attr->detached;
- return (0);
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/*
- * Get the 'inherit scheduling' info from a thread attribute structure.
- * Note: written as a helper function for info hiding
- */
-int
-pthread_attr_getinheritsched(const pthread_attr_t *attr,
- int *inheritsched)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG)
- {
- *inheritsched = attr->inherit;
- return (0);
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/*
- * Get the scheduling parameters from a thread attribute structure.
- * Note: written as a helper function for info hiding
- */
-int
-pthread_attr_getschedparam(const pthread_attr_t *attr,
- struct sched_param *param)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG)
- {
- *param = attr->param;
- return (0);
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/*
- * Get the scheduling policy from a thread attribute structure.
- * Note: written as a helper function for info hiding
- */
-int
-pthread_attr_getschedpolicy(const pthread_attr_t *attr,
- int *policy)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG)
- {
- *policy = attr->policy;
- return (0);
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/* Retain the existing stack size of 512K and not depend on Main thread default stack size */
-static const size_t DEFAULT_STACK_SIZE = (512*1024);
-/*
- * Initialize a thread attribute structure to default values.
- */
-int
-pthread_attr_init(pthread_attr_t *attr)
-{
- attr->stacksize = DEFAULT_STACK_SIZE;
- attr->stackaddr = NULL;
- attr->sig = _PTHREAD_ATTR_SIG;
- attr->param.sched_priority = default_priority;
- attr->param.quantum = 10; /* quantum isn't public yet */
- attr->detached = PTHREAD_CREATE_JOINABLE;
- attr->inherit = _PTHREAD_DEFAULT_INHERITSCHED;
- attr->policy = _PTHREAD_DEFAULT_POLICY;
- attr->freeStackOnExit = 1;
- attr->fastpath = 1;
- attr->schedset = 0;
- attr->guardsize = vm_page_size;
- return (0);
-}
-
-/*
- * Set the 'detach' state in a thread attribute structure.
- * Note: written as a helper function for info hiding
- */
-int
-pthread_attr_setdetachstate(pthread_attr_t *attr,
- int detachstate)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG)
- {
- if ((detachstate == PTHREAD_CREATE_JOINABLE) ||
- (detachstate == PTHREAD_CREATE_DETACHED))
- {
- attr->detached = detachstate;
- return (0);
- } else
- {
- return (EINVAL);
- }
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/*
- * Set the 'inherit scheduling' state in a thread attribute structure.
- * Note: written as a helper function for info hiding
- */
-int
-pthread_attr_setinheritsched(pthread_attr_t *attr,
- int inheritsched)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG)
- {
- if ((inheritsched == PTHREAD_INHERIT_SCHED) ||
- (inheritsched == PTHREAD_EXPLICIT_SCHED))
- {
- attr->inherit = inheritsched;
- return (0);
- } else
- {
- return (EINVAL);
- }
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/*
- * Set the scheduling paramters in a thread attribute structure.
- * Note: written as a helper function for info hiding
- */
-int
-pthread_attr_setschedparam(pthread_attr_t *attr,
- const struct sched_param *param)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG)
- {
- /* TODO: Validate sched_param fields */
- attr->param = *param;
- attr->schedset = 1;
- return (0);
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/*
- * Set the scheduling policy in a thread attribute structure.
- * Note: written as a helper function for info hiding
- */
-int
-pthread_attr_setschedpolicy(pthread_attr_t *attr,
- int policy)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG)
- {
- if ((policy == SCHED_OTHER) ||
- (policy == SCHED_RR) ||
- (policy == SCHED_FIFO))
- {
- attr->policy = policy;
- attr->schedset = 1;
- return (0);
- } else
- {
- return (EINVAL);
- }
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/*
- * Set the scope for the thread.
- * We currently only provide PTHREAD_SCOPE_SYSTEM
- */
-int
-pthread_attr_setscope(pthread_attr_t *attr,
- int scope)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG) {
- if (scope == PTHREAD_SCOPE_SYSTEM) {
- /* No attribute yet for the scope */
- return (0);
- } else if (scope == PTHREAD_SCOPE_PROCESS) {
- return (ENOTSUP);
- }
- }
- return (EINVAL); /* Not an attribute structure! */
-}
-
-/*
- * Get the scope for the thread.
- * We currently only provide PTHREAD_SCOPE_SYSTEM
- */
-int
-pthread_attr_getscope(const pthread_attr_t *attr,
- int *scope)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG) {
- *scope = PTHREAD_SCOPE_SYSTEM;
- return (0);
- }
- return (EINVAL); /* Not an attribute structure! */
-}
-
-/* Get the base stack address of the given thread */
-int
-pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG) {
- *stackaddr = attr->stackaddr;
- return (0);
- } else {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-int
-pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
-{
- if ((attr->sig == _PTHREAD_ATTR_SIG) && (((uintptr_t)stackaddr % vm_page_size) == 0)) {
- attr->stackaddr = stackaddr;
- attr->freeStackOnExit = 0;
- attr->fastpath = 0;
- return (0);
- } else {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-int
-pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG) {
- *stacksize = attr->stacksize;
- return (0);
- } else {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-int
-pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
-{
- if ((attr->sig == _PTHREAD_ATTR_SIG) && ((stacksize % vm_page_size) == 0) && (stacksize >= PTHREAD_STACK_MIN)) {
- attr->stacksize = stacksize;
- return (0);
- } else {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-int
-pthread_attr_getstack(const pthread_attr_t *attr, void **stackaddr, size_t * stacksize)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG) {
- *stackaddr = (void *)((uintptr_t)attr->stackaddr - attr->stacksize);
- *stacksize = attr->stacksize;
- return (0);
- } else {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-/* By SUSV spec, the stackaddr is the base address, the lowest addressable
- * byte address. This is not the same as in pthread_attr_setstackaddr.
- */
-int
-pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize)
-{
- if ((attr->sig == _PTHREAD_ATTR_SIG) &&
- (((uintptr_t)stackaddr % vm_page_size) == 0) &&
- ((stacksize % vm_page_size) == 0) && (stacksize >= PTHREAD_STACK_MIN)) {
- attr->stackaddr = (void *)((uintptr_t)stackaddr + stacksize);
- attr->stacksize = stacksize;
- attr->freeStackOnExit = 0;
- attr->fastpath = 0;
- return (0);
- } else {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-
-/*
- * Set the guardsize attribute in the attr.
- */
-int
-pthread_attr_setguardsize(pthread_attr_t *attr,
- size_t guardsize)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG) {
- /* Guardsize of 0 is valid, ot means no guard */
- if ((guardsize % vm_page_size) == 0) {
- attr->guardsize = guardsize;
- attr->fastpath = 0;
- return (0);
- } else
- return(EINVAL);
- }
- return (EINVAL); /* Not an attribute structure! */
-}
-
-/*
- * Get the guardsize attribute in the attr.
- */
-int
-pthread_attr_getguardsize(const pthread_attr_t *attr,
- size_t *guardsize)
-{
- if (attr->sig == _PTHREAD_ATTR_SIG) {
- *guardsize = attr->guardsize;
- return (0);
- }
- return (EINVAL); /* Not an attribute structure! */
-}
-
-
-/*
- * Create and start execution of a new thread.
- */
-
-static void
-_pthread_body(pthread_t self)
-{
- _pthread_set_self(self);
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- if( (self->thread_id = __thread_selfid()) == (__uint64_t)-1)
- printf("Failed to set thread_id in _pthread_body\n");
-#endif
- _pthread_exit(self, (self->fun)(self->arg));
-}
-
-void
-_pthread_start(pthread_t self, mach_port_t kport, void *(*fun)(void *), void * funarg, size_t stacksize, unsigned int pflags)
-{
-#if WQ_DEBUG
- pthread_t pself;
-#endif
- pthread_attr_t *attrs = &_pthread_attr_default;
- char * stackaddr;
-
- if ((pflags & PTHREAD_START_CUSTOM) == 0) {
- stackaddr = (char *)self;
- _pthread_struct_init(self, attrs, stackaddr, stacksize, 1, 1);
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- _pthread_set_self(self);
-#endif
- LOCK(_pthread_list_lock);
- if (pflags & PTHREAD_START_SETSCHED) {
- self->policy = ((pflags >> PTHREAD_START_POLICY_BITSHIFT) & PTHREAD_START_POLICY_MASK);
- self->param.sched_priority = (pflags & PTHREAD_START_IMPORTANCE_MASK);
- }
- /* These are not joinable threads */
- if ((pflags & PTHREAD_START_DETACHED) == PTHREAD_START_DETACHED) {
- self->detached &= ~PTHREAD_CREATE_JOINABLE;
- self->detached |= PTHREAD_CREATE_DETACHED;
- }
- } else {
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- _pthread_set_self(self);
-#endif
- LOCK(_pthread_list_lock);
- }
- self->kernel_thread = kport;
- self->fun = fun;
- self->arg = funarg;
-
- /* Add to the pthread list */
- if (self->parentcheck == 0) {
- TAILQ_INSERT_TAIL(&__pthread_head, self, plist);
-#if PTH_LISTTRACE
- __kdebug_trace(0x900000c, self, 0, 0, 3, 0);
-#endif
- _pthread_count++;
- }
- self->childrun = 1;
- UNLOCK(_pthread_list_lock);
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- if( (self->thread_id = __thread_selfid()) == (__uint64_t)-1)
- printf("Failed to set thread_id in pthread_start\n");
-#endif
-
-#if WQ_DEBUG
- pself = pthread_self();
- if (self != pself)
- LIBC_ABORT("self %p != pself %p", self, pself);
-#endif
-#if PTH_TRACE
- __kdebug_trace(0x9000030, self, pflags, 0, 0, 0);
-#endif
-
- _pthread_exit(self, (self->fun)(self->arg));
-}
-
-int
-_pthread_create(pthread_t t,
- const pthread_attr_t *attrs,
- void *stack,
- const mach_port_t kernel_thread)
-{
- int res;
- res = 0;
-
- do
- {
- memset(t, 0, sizeof(*t));
- t->newstyle = 0;
- t->schedset = 0;
- t->kernalloc = 0;
- t->tsd[0] = t;
- t->max_tsd_key = 0;
- t->wqthread = 0;
- t->cur_workq = 0;
- t->cur_workitem = 0;
- t->stacksize = attrs->stacksize;
- t->stackaddr = (void *)stack;
- t->guardsize = attrs->guardsize;
- t->kernel_thread = kernel_thread;
- t->detached = attrs->detached;
- t->inherit = attrs->inherit;
- t->policy = attrs->policy;
- t->param = attrs->param;
- t->freeStackOnExit = attrs->freeStackOnExit;
- t->cancel_error = 0;
- t->sig = _PTHREAD_SIG;
- t->reply_port = MACH_PORT_NULL;
- t->cthread_self = NULL;
- LOCK_INIT(t->lock);
- t->plist.tqe_next = (struct _pthread *)0;
- t->plist.tqe_prev = (struct _pthread **)0;
- t->cancel_state = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED;
- t->__cleanup_stack = (struct __darwin_pthread_handler_rec *)NULL;
- t->death = SEMAPHORE_NULL;
-
- if (kernel_thread != MACH_PORT_NULL)
- (void)pthread_setschedparam_internal(t, kernel_thread, t->policy, &t->param);
- } while (0);
- return (res);
-}
-
-void
-_pthread_struct_init(pthread_t t, const pthread_attr_t *attrs, void * stack, size_t stacksize, int kernalloc, int nozero)
-{
- mach_vm_offset_t stackaddr = (mach_vm_offset_t)(uintptr_t)stack;
-
- if (nozero == 0) {
- memset(t, 0, sizeof(*t));
- t->plist.tqe_next = (struct _pthread *)0;
- t->plist.tqe_prev = (struct _pthread **)0;
- }
- t->schedset = attrs->schedset;
- t->tsd[0] = t;
- if (kernalloc != 0) {
- stackaddr = (mach_vm_offset_t)(uintptr_t)t;
-
- /* if allocated from kernel set values appropriately */
- t->stacksize = stacksize;
- t->stackaddr = (void *)(uintptr_t)stackaddr;
- t->freeStackOnExit = 1;
- t->freeaddr = (void *)(uintptr_t)(stackaddr - stacksize - vm_page_size);
- t->freesize = pthreadsize + stacksize + vm_page_size;
- } else {
- t->stacksize = attrs->stacksize;
- t->stackaddr = (void *)stack;
- }
- t->guardsize = attrs->guardsize;
- t->detached = attrs->detached;
- t->inherit = attrs->inherit;
- t->policy = attrs->policy;
- t->param = attrs->param;
- t->cancel_error = 0;
- t->sig = _PTHREAD_SIG;
- t->reply_port = MACH_PORT_NULL;
- t->cthread_self = NULL;
- LOCK_INIT(t->lock);
- t->cancel_state = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED;
- t->__cleanup_stack = (struct __darwin_pthread_handler_rec *)NULL;
- t->death = SEMAPHORE_NULL;
- t->newstyle = 1;
- t->kernalloc = kernalloc;
- t->wqthread = 0;
- t->cur_workq = 0;
- t->cur_workitem = 0;
- t->max_tsd_key = 0;
-}
-
-/* Need to deprecate this in future */
-int
-_pthread_is_threaded(void)
-{
- return __is_threaded;
-}
-
-/* Non portable public api to know whether this process has(had) atleast one thread
- * apart from main thread. There could be race if there is a thread in the process of
- * creation at the time of call . It does not tell whether there are more than one thread
- * at this point of time.
- */
-int
-pthread_is_threaded_np(void)
-{
- return (__is_threaded);
-}
-
-mach_port_t
-pthread_mach_thread_np(pthread_t t)
-{
- mach_port_t kport = MACH_PORT_NULL;
-
- if (t == NULL)
- goto out;
-
- /*
- * If the call is on self, return the kernel port. We cannot
- * add this bypass for main thread as it might have exited,
- * and we should not return stale port info.
- */
- if (t == pthread_self())
- {
- kport = t->kernel_thread;
- goto out;
- }
-
- if (_pthread_lookup_thread(t, &kport, 0) != 0)
- return((mach_port_t)0);
-
-out:
- return(kport);
-}
-
-pthread_t pthread_from_mach_thread_np(mach_port_t kernel_thread)
-{
- struct _pthread * p = NULL;
-
- /* No need to wait as mach port is already known */
- LOCK(_pthread_list_lock);
- TAILQ_FOREACH(p, &__pthread_head, plist) {
- if (p->kernel_thread == kernel_thread)
- break;
- }
- UNLOCK(_pthread_list_lock);
- return p;
-}
-
-size_t
-pthread_get_stacksize_np(pthread_t t)
-{
- int ret;
- size_t size = 0;
-
- if (t == NULL)
- return(ESRCH);
-
- if ( t == pthread_self() || t == &_thread ) //since the main thread will not get de-allocated from underneath us
- {
- size=t->stacksize;
- return size;
- }
-
-
- LOCK(_pthread_list_lock);
-
- if ((ret = _pthread_find_thread(t)) != 0) {
- UNLOCK(_pthread_list_lock);
- return(ret);
- }
-
- size=t->stacksize;
- UNLOCK(_pthread_list_lock);
-
- return(size);
-}
-
-void *
-pthread_get_stackaddr_np(pthread_t t)
-{
- int ret;
- void * addr = NULL;
-
- if (t == NULL)
- return((void *)(uintptr_t)ESRCH);
-
- if(t == pthread_self() || t == &_thread) //since the main thread will not get deallocated from underneath us
- return t->stackaddr;
-
- LOCK(_pthread_list_lock);
-
- if ((ret = _pthread_find_thread(t)) != 0) {
- UNLOCK(_pthread_list_lock);
- return((void *)(uintptr_t)ret);
- }
- addr = t->stackaddr;
- UNLOCK(_pthread_list_lock);
-
- return(addr);
-}
-
-mach_port_t
-_pthread_reply_port(pthread_t t)
-{
- return t->reply_port;
-}
-
-
-/* returns non-zero if the current thread is the main thread */
-int
-pthread_main_np(void)
-{
- pthread_t self = pthread_self();
-
- return ((self->detached & _PTHREAD_CREATE_PARENT) == _PTHREAD_CREATE_PARENT);
-}
-
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
-/* if we are passed in a pthread_t that is NULL, then we return
- the current thread's thread_id. So folks don't have to call
- pthread_self, in addition to us doing it, if they just want
- their thread_id.
-*/
-int
-pthread_threadid_np(pthread_t thread, __uint64_t *thread_id)
-{
- int rval=0;
- pthread_t self = pthread_self();
-
- if (thread_id == NULL) {
- return(EINVAL);
- } else if (thread == NULL || thread == self) {
- *thread_id = self->thread_id;
- return rval;
- }
-
- LOCK(_pthread_list_lock);
- if ((rval = _pthread_find_thread(thread)) != 0) {
- UNLOCK(_pthread_list_lock);
- return(rval);
- }
- *thread_id = thread->thread_id;
- UNLOCK(_pthread_list_lock);
- return rval;
-}
-#endif
-
-int
-pthread_getname_np(pthread_t thread, char *threadname, size_t len)
-{
- int rval;
- rval = 0;
-
- if (thread == NULL)
- return(ESRCH);
-
- LOCK(_pthread_list_lock);
- if ((rval = _pthread_find_thread(thread)) != 0) {
- UNLOCK(_pthread_list_lock);
- return(rval);
- }
- strlcpy(threadname, thread->pthread_name, len);
- UNLOCK(_pthread_list_lock);
- return rval;
-}
-
-int
-pthread_setname_np(const char *threadname)
-{
- int rval = 0;
- int len = 0;
- pthread_t current_thread = pthread_self();
-
- if (threadname != NULL)
- len = strlen(threadname);
-
- /* protytype is in pthread_internals.h */
- rval = proc_setthreadname((void *)threadname, len);
- if (rval == 0) {
- if (threadname != NULL) {
- strlcpy(current_thread->pthread_name, threadname, MAXTHREADNAMESIZE);
- } else {
- memset(current_thread->pthread_name, 0 , MAXTHREADNAMESIZE);
- }
-
- }
- return rval;
-
-}
-
-static int
-_new_pthread_create_suspended(pthread_t *thread,
- const pthread_attr_t *attr,
- void *(*start_routine)(void *),
- void *arg,
- int create_susp)
-{
- pthread_attr_t *attrs;
- void *stack;
- int error;
- unsigned int flags;
- pthread_t t,t2;
- kern_return_t kern_res;
- mach_port_t kernel_thread = MACH_PORT_NULL;
- int needresume;
- task_t self = mach_task_self();
- int kernalloc = 0;
- int susp = create_susp;
-
- if ((attrs = (pthread_attr_t *)attr) == (pthread_attr_t *)NULL)
- { /* Set up default paramters */
- attrs = &_pthread_attr_default;
- } else if (attrs->sig != _PTHREAD_ATTR_SIG) {
- return EINVAL;
- }
- error = 0;
-
- if (((attrs->policy != _PTHREAD_DEFAULT_POLICY) ||
- (attrs->param.sched_priority != default_priority)) && (create_susp == 0)) {
- needresume = 1;
- susp = 1;
- } else
- needresume = 0;
-
- /* In default policy (ie SCHED_OTHER) only sched_priority is used. Check for
- * any change in priority or policy is needed here.
- */
- if ((__oldstyle == 1) || (create_susp != 0)) {
- /* Rosetta or pthread_create_suspended() */
- /* running under rosetta */
- /* Allocate a stack for the thread */
-#if PTH_TRACE
- __kdebug_trace(0x9000000, create_susp, 0, 0, 0, 0);
-#endif
- if ((error = _pthread_allocate_stack(attrs, &stack)) != 0) {
- return(error);
- }
- t = (pthread_t)malloc(sizeof(struct _pthread));
- *thread = t;
- if (susp) {
- /* Create the Mach thread for this thread */
- PTHREAD_MACH_CALL(thread_create(self, &kernel_thread), kern_res);
- if (kern_res != KERN_SUCCESS)
- {
- printf("Can't create thread: %d\n", kern_res);
- return(EINVAL);
- }
- }
- if ((error = _pthread_create(t, attrs, stack, kernel_thread)) != 0)
- {
- return(error);
- }
- set_malloc_singlethreaded(0);
- __is_threaded = 1;
-
- /* Send it on it's way */
- t->arg = arg;
- t->fun = start_routine;
- t->newstyle = 0;
- /* Now set it up to execute */
- LOCK(_pthread_list_lock);
- TAILQ_INSERT_TAIL(&__pthread_head, t, plist);
-#if PTH_LISTTRACE
- __kdebug_trace(0x900000c, t, 0, 0, 4, 0);
-#endif
- _pthread_count++;
- UNLOCK(_pthread_list_lock);
- _pthread_setup(t, _pthread_body, stack, susp, needresume);
- return(0);
- } else {
-
- flags = 0;
- if (attrs->fastpath == 1)
- kernalloc = 1;
-
- if (attrs->detached == PTHREAD_CREATE_DETACHED)
- flags |= PTHREAD_START_DETACHED;
- if (attrs->schedset != 0) {
- flags |= PTHREAD_START_SETSCHED;
- flags |= ((attrs->policy & PTHREAD_START_POLICY_MASK) << PTHREAD_START_POLICY_BITSHIFT);
- flags |= (attrs->param.sched_priority & PTHREAD_START_IMPORTANCE_MASK);
- }
-
- set_malloc_singlethreaded(0);
- __is_threaded = 1;
-
- if (kernalloc == 0) {
- /* Allocate a stack for the thread */
- flags |= PTHREAD_START_CUSTOM;
- if ((error = _pthread_create_pthread_onstack(attrs, &stack, &t)) != 0) {
- return(error);
- }
- /* Send it on it's way */
- t->arg = arg;
- t->fun = start_routine;
- t->newstyle = 1;
-
-#if PTH_TRACE
- __kdebug_trace(0x9000004, t, flags, 0, 0, 0);
-#endif
-
- if ((t2 = __bsdthread_create(start_routine, arg, stack, t, flags)) == (pthread_t)-1) {
- _pthread_free_pthread_onstack(t, 1, 0);
- return (EAGAIN);
- }
- else t=t2;
- LOCK(_pthread_list_lock);
- t->parentcheck = 1;
- if ((t->childexit != 0) && ((t->detached & PTHREAD_CREATE_DETACHED) == PTHREAD_CREATE_DETACHED)) {
- /* detached child exited, mop up */
- UNLOCK(_pthread_list_lock);
-#if PTH_TRACE
- __kdebug_trace(0x9000008, t, 0, 0, 1, 0);
-#endif
- if(t->freeStackOnExit)
- vm_deallocate(self, (mach_vm_address_t)(uintptr_t)t, pthreadsize);
- else
- free(t);
- } else if (t->childrun == 0) {
- TAILQ_INSERT_TAIL(&__pthread_head, t, plist);
- _pthread_count++;
-#if PTH_LISTTRACE
- __kdebug_trace(0x900000c, t, 0, 0, 1, 0);
-#endif
- UNLOCK(_pthread_list_lock);
- } else
- UNLOCK(_pthread_list_lock);
-
- *thread = t;
-
-#if PTH_TRACE
- __kdebug_trace(0x9000014, t, 0, 0, 1, 0);
-#endif
- return (0);
-
- } else {
- /* kernel allocation */
-#if PTH_TRACE
- __kdebug_trace(0x9000018, flags, 0, 0, 0, 0);
-#endif
- if ((t = __bsdthread_create(start_routine, arg, (void *)attrs->stacksize, NULL, flags)) == (pthread_t)-1)
- return (EAGAIN);
- /* Now set it up to execute */
- LOCK(_pthread_list_lock);
- t->parentcheck = 1;
- if ((t->childexit != 0) && ((t->detached & PTHREAD_CREATE_DETACHED) == PTHREAD_CREATE_DETACHED)) {
- /* detached child exited, mop up */
- UNLOCK(_pthread_list_lock);
-#if PTH_TRACE
- __kdebug_trace(0x9000008, t, pthreadsize, 0, 2, 0);
-#endif
- vm_deallocate(self, (mach_vm_address_t)(uintptr_t)t, pthreadsize);
- } else if (t->childrun == 0) {
- TAILQ_INSERT_TAIL(&__pthread_head, t, plist);
- _pthread_count++;
-#if PTH_LISTTRACE
- __kdebug_trace(0x900000c, t, 0, 0, 2, 0);
-#endif
- UNLOCK(_pthread_list_lock);
- } else
- UNLOCK(_pthread_list_lock);
-
- *thread = t;
-
-#if PTH_TRACE
- __kdebug_trace(0x9000014, t, 0, 0, 2, 0);
-#endif
- return(0);
- }
- }
-}
-
-static int
-_pthread_create_suspended(pthread_t *thread,
- const pthread_attr_t *attr,
- void *(*start_routine)(void *),
- void *arg,
- int suspended)
-{
- pthread_attr_t *attrs;
- void *stack;
- int res;
- pthread_t t;
- kern_return_t kern_res;
- mach_port_t kernel_thread = MACH_PORT_NULL;
- int needresume;
-
- if ((attrs = (pthread_attr_t *)attr) == (pthread_attr_t *)NULL)
- { /* Set up default paramters */
- attrs = &_pthread_attr_default;
- } else if (attrs->sig != _PTHREAD_ATTR_SIG) {
- return EINVAL;
- }
- res = 0;
-
- /* In default policy (ie SCHED_OTHER) only sched_priority is used. Check for
- * any change in priority or policy is needed here.
- */
- if (((attrs->policy != _PTHREAD_DEFAULT_POLICY) ||
- (attrs->param.sched_priority != default_priority)) && (suspended == 0)) {
- needresume = 1;
- suspended = 1;
- } else
- needresume = 0;
-
- do
- {
- /* Allocate a stack for the thread */
- if ((res = _pthread_allocate_stack(attrs, &stack)) != 0) {
- break;
- }
- t = (pthread_t)malloc(sizeof(struct _pthread));
- *thread = t;
- if (suspended) {
- /* Create the Mach thread for this thread */
- PTHREAD_MACH_CALL(thread_create(mach_task_self(), &kernel_thread), kern_res);
- if (kern_res != KERN_SUCCESS)
- {
- printf("Can't create thread: %d\n", kern_res);
- res = EINVAL; /* Need better error here? */
- break;
- }
- }
- if ((res = _pthread_create(t, attrs, stack, kernel_thread)) != 0)
- {
- break;
- }
- set_malloc_singlethreaded(0);
- __is_threaded = 1;
-
- /* Send it on it's way */
- t->arg = arg;
- t->fun = start_routine;
- /* Now set it up to execute */
- LOCK(_pthread_list_lock);
- TAILQ_INSERT_TAIL(&__pthread_head, t, plist);
-#if PTH_LISTTRACE
- __kdebug_trace(0x900000c, t, 0, 0, 5, 0);
-#endif
- _pthread_count++;
- UNLOCK(_pthread_list_lock);
- _pthread_setup(t, _pthread_body, stack, suspended, needresume);
- } while (0);
- return (res);
-}
-
-int
-pthread_create(pthread_t *thread,
- const pthread_attr_t *attr,
- void *(*start_routine)(void *),
- void *arg)
-{
- return _new_pthread_create_suspended(thread, attr, start_routine, arg, 0);
-}
-
-int
-pthread_create_suspended_np(pthread_t *thread,
- const pthread_attr_t *attr,
- void *(*start_routine)(void *),
- void *arg)
-{
- return _pthread_create_suspended(thread, attr, start_routine, arg, 1);
-}
-
-/*
- * Make a thread 'undetached' - no longer 'joinable' with other threads.
- */
-int
-pthread_detach(pthread_t thread)
-{
- int newstyle = 0;
- int ret;
-
- if ((ret = _pthread_lookup_thread(thread, NULL, 1)) != 0) {
- return (ret); /* Not a valid thread */
- }
-
- LOCK(thread->lock);
- newstyle = thread->newstyle;
- if (thread->detached & PTHREAD_CREATE_JOINABLE)
- {
- if (thread->detached & _PTHREAD_EXITED) {
- UNLOCK(thread->lock);
- pthread_join(thread, NULL);
- return 0;
- } else {
- if (newstyle == 0) {
- semaphore_t death = thread->death;
-
- thread->detached &= ~PTHREAD_CREATE_JOINABLE;
- thread->detached |= PTHREAD_CREATE_DETACHED;
- UNLOCK(thread->lock);
- if (death)
- (void) semaphore_signal(death);
- } else {
- mach_port_t joinport = thread->joiner_notify;
-
- thread->detached &= ~PTHREAD_CREATE_JOINABLE;
- thread->detached |= PTHREAD_CREATE_DETACHED;
-
- UNLOCK(thread->lock);
- if (joinport) {
- semaphore_signal(joinport);
- }
- }
- return(0);
- }
- } else {
- UNLOCK(thread->lock);
- return (EINVAL);
- }
-}
-
-
-/*
- * pthread_kill call to system call
- */
-int
-pthread_kill (
- pthread_t th,
- int sig)
-{
- int error = 0;
- mach_port_t kport = MACH_PORT_NULL;
-
- if ((sig < 0) || (sig > NSIG))
- return(EINVAL);
-
- if (_pthread_lookup_thread(th, &kport, 0) != 0)
- return (ESRCH); /* Not a valid thread */
-
- /* if the thread is a workqueue thread, just return error */
- if ((th->wqthread != 0) && (th->wqkillset ==0)) {
- return(ENOTSUP);
- }
-
- error = __pthread_kill(kport, sig);
-
- if (error == -1)
- error = errno;
- return(error);
-}
-
-int
-__pthread_workqueue_setkill(int enable)
-{
- pthread_t self = pthread_self();
-
- LOCK(self->lock);
- if (enable == 0)
- self->wqkillset = 0;
- else
- self->wqkillset = 1;
- UNLOCK(self->lock);
-
- return(0);
-
-}
-
-/* Announce that there are pthread resources ready to be reclaimed in a */
-/* subsequent pthread_exit or reaped by pthread_join. In either case, the Mach */
-/* thread underneath is terminated right away. */
-static
-void _pthread_become_available(pthread_t thread, mach_port_t kernel_thread) {
- pthread_reap_msg_t msg;
- kern_return_t ret;
-
- msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND,
- MACH_MSG_TYPE_MOVE_SEND);
- msg.header.msgh_size = sizeof msg - sizeof msg.trailer;
- msg.header.msgh_remote_port = thread_recycle_port;
- msg.header.msgh_local_port = kernel_thread;
- msg.header.msgh_id = 0x44454144; /* 'DEAD' */
- msg.thread = thread;
- ret = mach_msg_send(&msg.header);
- assert(ret == MACH_MSG_SUCCESS);
-}
-
-/* Reap the resources for available threads */
-__private_extern__
-int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr, int conforming) {
- mach_port_type_t ptype;
- kern_return_t ret;
- task_t self;
-
- self = mach_task_self();
- if (kernel_thread != MACH_PORT_DEAD) {
- ret = mach_port_type(self, kernel_thread, &ptype);
- if (ret == KERN_SUCCESS && ptype != MACH_PORT_TYPE_DEAD_NAME) {
- /* not quite dead yet... */
- return EAGAIN;
- }
- ret = mach_port_deallocate(self, kernel_thread);
- if (ret != KERN_SUCCESS) {
- fprintf(stderr,
- "mach_port_deallocate(kernel_thread) failed: %s\n",
- mach_error_string(ret));
- }
- }
-
- if (th->reply_port != MACH_PORT_NULL) {
- ret = mach_port_mod_refs(self, th->reply_port,
- MACH_PORT_RIGHT_RECEIVE, -1);
- if (ret != KERN_SUCCESS) {
- fprintf(stderr,
- "mach_port_mod_refs(reply_port) failed: %s\n",
- mach_error_string(ret));
- }
- }
-
- if (th->freeStackOnExit) {
- vm_address_t addr = (vm_address_t)th->stackaddr;
- vm_size_t size;
-
- size = (vm_size_t)th->stacksize + th->guardsize;
-
- addr -= size;
- ret = vm_deallocate(self, addr, size);
- if (ret != KERN_SUCCESS) {
- fprintf(stderr,
- "vm_deallocate(stack) failed: %s\n",
- mach_error_string(ret));
- }
- }
-
-
- if (value_ptr)
- *value_ptr = th->exit_value;
- if (conforming) {
- if ((th->cancel_state & (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) ==
- (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING) && (value_ptr != NULL))
- *value_ptr = PTHREAD_CANCELED;
- th->sig = _PTHREAD_NO_SIG;
- }
-
-
- if (th != &_thread)
- free(th);
-
- return 0;
-}
-
-static
-void _pthread_reap_threads(void)
-{
- pthread_reap_msg_t msg;
- kern_return_t ret;
-
- ret = mach_msg(&msg.header, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0,
- sizeof msg, thread_recycle_port,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- while (ret == MACH_MSG_SUCCESS) {
- mach_port_t kernel_thread = msg.header.msgh_remote_port;
- pthread_t thread = msg.thread;
-
- /* deal with race with thread_create_running() */
- if (kernel_thread == MACH_PORT_NULL &&
- kernel_thread != thread->kernel_thread) {
- kernel_thread = thread->kernel_thread;
- }
-
- if ( kernel_thread == MACH_PORT_NULL ||
- _pthread_reap_thread(thread, kernel_thread, (void **)0, 0) == EAGAIN)
- {
- /* not dead yet, put it back for someone else to reap, stop here */
- _pthread_become_available(thread, kernel_thread);
- return;
- }
-
- ret = mach_msg(&msg.header, MACH_RCV_MSG|MACH_RCV_TIMEOUT, 0,
- sizeof msg, thread_recycle_port,
- MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
- }
-}
-
-/* For compatibility... */
-
-pthread_t
-_pthread_self() {
- return pthread_self();
-}
-
-/*
- * Terminate a thread.
- */
-int __disable_threadsignal(int);
-
-static void
-_pthread_exit(pthread_t self, void *value_ptr)
-{
- struct __darwin_pthread_handler_rec *handler;
- kern_return_t kern_res;
- int thread_count;
- int newstyle = self->newstyle;
-
- /* Make this thread not to receive any signals */
- __disable_threadsignal(1);
-
-#if PTH_TRACE
- __kdebug_trace(0x900001c, self, newstyle, 0, 0, 0);
-#endif
-
- /* set cancel state to disable and type to deferred */
- _pthread_setcancelstate_exit(self, value_ptr, __unix_conforming);
-
- while ((handler = self->__cleanup_stack) != 0)
- {
- (handler->__routine)(handler->__arg);
- self->__cleanup_stack = handler->__next;
- }
- _pthread_tsd_cleanup(self);
-
- if (newstyle == 0) {
- _pthread_reap_threads();
-
- LOCK(self->lock);
- self->detached |= _PTHREAD_EXITED;
-
- if (self->detached & PTHREAD_CREATE_JOINABLE) {
- mach_port_t death = self->death;
- self->exit_value = value_ptr;
- UNLOCK(self->lock);
- /* the joiner will need a kernel thread reference, leave ours for it */
- if (death) {
- PTHREAD_MACH_CALL(semaphore_signal(death), kern_res);
- if (kern_res != KERN_SUCCESS)
- fprintf(stderr,
- "semaphore_signal(death) failed: %s\n",
- mach_error_string(kern_res));
- }
- LOCK(_pthread_list_lock);
- thread_count = --_pthread_count;
- UNLOCK(_pthread_list_lock);
- } else {
- UNLOCK(self->lock);
- LOCK(_pthread_list_lock);
- TAILQ_REMOVE(&__pthread_head, self, plist);
-#if PTH_LISTTRACE
- __kdebug_trace(0x9000010, self, 0, 0, 5, 0);
-#endif
- thread_count = --_pthread_count;
- UNLOCK(_pthread_list_lock);
- /* with no joiner, we let become available consume our cached ref */
- _pthread_become_available(self, self->kernel_thread);
- }
-
- if (thread_count <= 0)
- exit(0);
-
- /* Use a new reference to terminate ourselves. Should never return. */
- PTHREAD_MACH_CALL(thread_terminate(mach_thread_self()), kern_res);
- fprintf(stderr, "thread_terminate(mach_thread_self()) failed: %s\n",
- mach_error_string(kern_res));
- } else {
- semaphore_t joinsem = SEMAPHORE_NULL;
-
- if ((self->joiner_notify == (mach_port_t)0) && (self->detached & PTHREAD_CREATE_JOINABLE))
- joinsem = new_sem_from_pool();
- LOCK(self->lock);
- self->detached |= _PTHREAD_EXITED;
-
- self->exit_value = value_ptr;
- if (self->detached & PTHREAD_CREATE_JOINABLE) {
- if (self->joiner_notify == (mach_port_t)0) {
- self->joiner_notify = joinsem;
- joinsem = SEMAPHORE_NULL;
- }
- UNLOCK(self->lock);
- if (joinsem != SEMAPHORE_NULL)
- restore_sem_to_pool(joinsem);
- _pthread_free_pthread_onstack(self, 0, 1);
- } else {
- UNLOCK(self->lock);
- /* with no joiner, we let become available consume our cached ref */
- if (joinsem != SEMAPHORE_NULL)
- restore_sem_to_pool(joinsem);
- _pthread_free_pthread_onstack(self, 1, 1);
- }
- }
- LIBC_ABORT("thread %p didn't exit", self);
-}
-
-void
-pthread_exit(void *value_ptr)
-{
- pthread_t self = pthread_self();
- /* if the current thread is a workqueue thread, just crash the app, as per libdispatch folks */
- if (self->wqthread == 0) {
- _pthread_exit(self, value_ptr);
- } else {
- LIBC_ABORT("pthread_exit() may only be called against threads created via pthread_create()");
- }
-}
-
-/*
- * Get the scheduling policy and scheduling paramters for a thread.
- */
-int
-pthread_getschedparam(pthread_t thread,
- int *policy,
- struct sched_param *param)
-{
- int ret;
-
- if (thread == NULL)
- return(ESRCH);
-
- LOCK(_pthread_list_lock);
-
- if ((ret = _pthread_find_thread(thread)) != 0) {
- UNLOCK(_pthread_list_lock);
- return(ret);
- }
- if (policy != 0)
- *policy = thread->policy;
- if (param != 0)
- *param = thread->param;
- UNLOCK(_pthread_list_lock);
-
- return(0);
-}
-
-/*
- * Set the scheduling policy and scheduling paramters for a thread.
- */
-static int
-pthread_setschedparam_internal(pthread_t thread,
- mach_port_t kport,
- int policy,
- const struct sched_param *param)
-{
- policy_base_data_t bases;
- policy_base_t base;
- mach_msg_type_number_t count;
- kern_return_t ret;
-
- switch (policy)
- {
- case SCHED_OTHER:
- bases.ts.base_priority = param->sched_priority;
- base = (policy_base_t)&bases.ts;
- count = POLICY_TIMESHARE_BASE_COUNT;
- break;
- case SCHED_FIFO:
- bases.fifo.base_priority = param->sched_priority;
- base = (policy_base_t)&bases.fifo;
- count = POLICY_FIFO_BASE_COUNT;
- break;
- case SCHED_RR:
- bases.rr.base_priority = param->sched_priority;
- /* quantum isn't public yet */
- bases.rr.quantum = param->quantum;
- base = (policy_base_t)&bases.rr;
- count = POLICY_RR_BASE_COUNT;
- break;
- default:
- return (EINVAL);
- }
- ret = thread_policy(kport, policy, base, count, TRUE);
- if (ret != KERN_SUCCESS)
- return (EINVAL);
- return (0);
-}
-
-int
-pthread_setschedparam(pthread_t t,
- int policy,
- const struct sched_param *param)
-{
- mach_port_t kport = MACH_PORT_NULL;
- int error;
- int bypass = 1;
-
- if (t != pthread_self() && t != &_thread ) { //since the main thread will not get de-allocated from underneath us
- bypass = 0;
- if (_pthread_lookup_thread(t, &kport, 0) != 0)
- return(ESRCH);
- } else
- kport = t->kernel_thread;
-
- error = pthread_setschedparam_internal(t, kport, policy, param);
- if (error == 0) {
- if (bypass == 0) {
- /* ensure the thread is still valid */
- LOCK(_pthread_list_lock);
- if ((error = _pthread_find_thread(t)) != 0) {
- UNLOCK(_pthread_list_lock);
- return(error);
- }
- t->policy = policy;
- t->param = *param;
- UNLOCK(_pthread_list_lock);
- } else {
- t->policy = policy;
- t->param = *param;
- }
- }
- return(error);
-}
-
-/*
- * Get the minimum priority for the given policy
- */
-int
-sched_get_priority_min(int policy)
-{
- return default_priority - 16;
-}
-
-/*
- * Get the maximum priority for the given policy
- */
-int
-sched_get_priority_max(int policy)
-{
- return default_priority + 16;
-}
-
-/*
- * Determine if two thread identifiers represent the same thread.
- */
-int
-pthread_equal(pthread_t t1,
- pthread_t t2)
-{
- return (t1 == t2);
-}
-
-// Force LLVM not to optimise this to a call to __pthread_set_self, if it does
-// then _pthread_set_self won't be bound when secondary threads try and start up.
-void __attribute__((noinline))
-_pthread_set_self(pthread_t p)
-{
- extern void __pthread_set_self(void *);
-
- if (p == 0) {
- if (_thread.tsd[0] != 0) {
- bzero(&_thread, sizeof(struct _pthread));
- }
- p = &_thread;
- }
- p->tsd[0] = p;
- __pthread_set_self(&p->tsd[0]);
-}
-
-void
-cthread_set_self(void *cself)
-{
- pthread_t self = pthread_self();
- if ((self == (pthread_t)NULL) || (self->sig != _PTHREAD_SIG)) {
- _pthread_set_self(cself);
- return;
- }
- self->cthread_self = cself;
-}
-
-void *
-ur_cthread_self(void) {
- pthread_t self = pthread_self();
- if ((self == (pthread_t)NULL) || (self->sig != _PTHREAD_SIG)) {
- return (void *)self;
- }
- return self->cthread_self;
-}
-
-/*
- * cancellation handler for pthread once as the init routine can have a
- * cancellation point. In that case we need to restore the spin unlock
- */
-void
-__pthread_once_cancel_handler(pthread_once_t *once_control)
-{
- _spin_unlock(&once_control->lock);
-}
-
-
-/*
- * Execute a function exactly one time in a thread-safe fashion.
- */
-int
-pthread_once(pthread_once_t *once_control,
- void (*init_routine)(void))
-{
- _spin_lock(&once_control->lock);
- if (once_control->sig == _PTHREAD_ONCE_SIG_init)
- {
- pthread_cleanup_push((void (*)(void *))__pthread_once_cancel_handler, once_control);
- (*init_routine)();
- pthread_cleanup_pop(0);
- once_control->sig = _PTHREAD_ONCE_SIG;
- }
- _spin_unlock(&once_control->lock);
- return (0); /* Spec defines no possible errors! */
-}
-
-/*
- * Insert a cancellation point in a thread.
- */
-__private_extern__ void
-_pthread_testcancel(pthread_t thread, int isconforming)
-{
- LOCK(thread->lock);
- if ((thread->cancel_state & (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) ==
- (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING))
- {
- UNLOCK(thread->lock);
- if (isconforming)
- pthread_exit(PTHREAD_CANCELED);
- else
- pthread_exit(0);
- }
- UNLOCK(thread->lock);
-}
-
-
-
-int
-pthread_getconcurrency(void)
-{
- return(pthread_concurrency);
-}
-
-int
-pthread_setconcurrency(int new_level)
-{
- if (new_level < 0)
- return EINVAL;
- pthread_concurrency = new_level;
- return(0);
-}
-
-/*
- * Perform package initialization - called automatically when application starts
- */
-int
-pthread_init(void)
-{
- pthread_attr_t *attrs;
- pthread_t thread;
- kern_return_t kr;
- host_priority_info_data_t priority_info;
- host_info_t info;
- host_flavor_t flavor;
- host_t host;
- mach_msg_type_number_t count;
- int mib[2];
- int ncpus = 0;
- size_t len;
- void *stackaddr;
-
- pthreadsize = round_page(sizeof (struct _pthread));
- count = HOST_PRIORITY_INFO_COUNT;
- info = (host_info_t)&priority_info;
- flavor = HOST_PRIORITY_INFO;
- host = mach_host_self();
- kr = host_info(host, flavor, info, &count);
- if (kr != KERN_SUCCESS)
- printf("host_info failed (%d); probably need privilege.\n", kr);
- else {
- default_priority = priority_info.user_priority;
- min_priority = priority_info.minimum_priority;
- max_priority = priority_info.maximum_priority;
- }
- attrs = &_pthread_attr_default;
- pthread_attr_init(attrs);
-
- TAILQ_INIT(&__pthread_head);
- LOCK_INIT(_pthread_list_lock);
- thread = &_thread;
- TAILQ_INSERT_HEAD(&__pthread_head, thread, plist);
- _pthread_set_self(thread);
-#if PTH_LISTTRACE
- __kdebug_trace(0x900000c, thread, 0, 0, 10, 0);
-#endif
-
- /* In case of dyld reset the tsd keys from 1 - 10 */
- _pthread_keys_init();
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_USRSTACK;
- len = sizeof (stackaddr);
- if (sysctl (mib, 2, &stackaddr, &len, NULL, 0) != 0)
- stackaddr = (void *)USRSTACK;
- _pthread_create(thread, attrs, stackaddr, mach_thread_self());
- thread->stacksize = DFLSSIZ; //initialize main thread's stacksize based on vmparam.h
- thread->detached = PTHREAD_CREATE_JOINABLE|_PTHREAD_CREATE_PARENT;
-
- _init_cpu_capabilities();
- if ((ncpus = _NumCPUs()) > 1)
- _spin_tries = MP_SPIN_TRIES;
-
- workq_targetconc[WORKQ_HIGH_PRIOQUEUE] = ncpus;
- workq_targetconc[WORKQ_DEFAULT_PRIOQUEUE] = ncpus;
- workq_targetconc[WORKQ_LOW_PRIOQUEUE] = ncpus;
- workq_targetconc[WORKQ_BG_PRIOQUEUE] = ncpus;
-
- mach_port_deallocate(mach_task_self(), host);
-
-#if defined(__ppc__)
- IF_ROSETTA() {
- __oldstyle = 1;
- }
-#endif
-
-#if defined(_OBJC_PAGE_BASE_ADDRESS)
-{
- vm_address_t objcRTPage = (vm_address_t)_OBJC_PAGE_BASE_ADDRESS;
- kr = vm_map(mach_task_self(),
- &objcRTPage, vm_page_size * 4, vm_page_size - 1,
- VM_FLAGS_FIXED | VM_MAKE_TAG(0), // Which tag to use?
- MACH_PORT_NULL,
- (vm_address_t)0, FALSE,
- (vm_prot_t)0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE,
- VM_INHERIT_DEFAULT);
- /* We ignore the return result here. The ObjC runtime will just have to deal. */
-}
-#endif
- //added so that thread_recycle_port is initialized on new launch.
- _pthread_fork_child_postinit();
- mig_init(1); /* enable multi-threaded mig interfaces */
- if (__oldstyle == 0) {
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)), _pthread_start, &workq_targetconc[0], (uintptr_t)(&thread->tsd[__PTK_LIBDISPATCH_KEY0]) - (uintptr_t)(&thread->tsd[0]));
-#else
- __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)), NULL, &workq_targetconc[0], (uintptr_t)&thread->tsd[__PTK_LIBDISPATCH_KEY0] - (uintptr_t)thread);
-#endif
- }
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- if( (thread->thread_id = __thread_selfid()) == (__uint64_t)-1)
- printf("Failed to set thread_id in pthread_init\n");
-#endif
- return 0;
-}
-
-int sched_yield(void)
-{
- swtch_pri(0);
- return 0;
-}
-
-/* This used to be the "magic" that gets the initialization routine called when the application starts */
-/*
- * (These has been moved to setenv.c, so we can use it to fix a less than 10.5
- * crt1.o issue)
- * static int _do_nothing(void) { return 0; }
- * int (*_cthread_init_routine)(void) = _do_nothing;
- */
-
-/* Get a semaphore from the pool, growing it if necessary */
-
-__private_extern__ semaphore_t new_sem_from_pool(void) {
- kern_return_t res;
- semaphore_t sem;
- int i;
-
- LOCK(sem_pool_lock);
- if (sem_pool_current == sem_pool_count) {
- sem_pool_count += 16;
- sem_pool = realloc(sem_pool, sem_pool_count * sizeof(semaphore_t));
- for (i = sem_pool_current; i < sem_pool_count; i++) {
- PTHREAD_MACH_CALL(semaphore_create(mach_task_self(), &sem_pool[i], SYNC_POLICY_FIFO, 0), res);
- }
- }
- sem = sem_pool[sem_pool_current++];
- UNLOCK(sem_pool_lock);
- return sem;
-}
-
-/* Put a semaphore back into the pool */
-__private_extern__ void restore_sem_to_pool(semaphore_t sem) {
- LOCK(sem_pool_lock);
- sem_pool[--sem_pool_current] = sem;
- UNLOCK(sem_pool_lock);
-}
-
-static void sem_pool_reset(void) {
- LOCK(sem_pool_lock);
- sem_pool_count = 0;
- sem_pool_current = 0;
- sem_pool = NULL;
- UNLOCK(sem_pool_lock);
-}
-
-__private_extern__ void _pthread_fork_child(pthread_t p) {
- /* Just in case somebody had it locked... */
- UNLOCK(sem_pool_lock);
- sem_pool_reset();
- /* No need to hold the pthread_list_lock as no one other than this
- * thread is present at this time
- */
- TAILQ_INIT(&__pthread_head);
- LOCK_INIT(_pthread_list_lock);
- TAILQ_INSERT_HEAD(&__pthread_head, p, plist);
-#if PTH_LISTTRACE
- __kdebug_trace(0x900000c, p, 0, 0, 10, 0);
-#endif
- _pthread_count = 1;
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- if( (p->thread_id = __thread_selfid()) == (__uint64_t)-1)
- printf("Failed to set thread_id in pthread_fork_child\n");
-#endif
-}
-
-void _pthread_fork_child_postinit() {
- kern_return_t kr;
-
- kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &thread_recycle_port);
- if (kr != KERN_SUCCESS) {
- abort();
- }
-}
-
-/*
- * Query/update the cancelability 'state' of a thread
- */
-int
-_pthread_setcancelstate_internal(int state, int *oldstate, int conforming)
-{
- pthread_t self = pthread_self();
-
-
- switch (state) {
- case PTHREAD_CANCEL_ENABLE:
- if (conforming)
- __pthread_canceled(1);
- break;
- case PTHREAD_CANCEL_DISABLE:
- if (conforming)
- __pthread_canceled(2);
- break;
- default:
- return EINVAL;
- }
-
- self = pthread_self();
- LOCK(self->lock);
- if (oldstate)
- *oldstate = self->cancel_state & _PTHREAD_CANCEL_STATE_MASK;
- self->cancel_state &= ~_PTHREAD_CANCEL_STATE_MASK;
- self->cancel_state |= state;
- UNLOCK(self->lock);
- if (!conforming)
- _pthread_testcancel(self, 0); /* See if we need to 'die' now... */
- return (0);
-}
-
-/* When a thread exits set the cancellation state to DISABLE and DEFERRED */
-static void
-_pthread_setcancelstate_exit(pthread_t self, void * value_ptr, int conforming)
-{
- LOCK(self->lock);
- self->cancel_state &= ~(_PTHREAD_CANCEL_STATE_MASK | _PTHREAD_CANCEL_TYPE_MASK);
- self->cancel_state |= (PTHREAD_CANCEL_DISABLE | PTHREAD_CANCEL_DEFERRED);
- if ((value_ptr == PTHREAD_CANCELED)) {
-// 4597450: begin
- self->detached |= _PTHREAD_WASCANCEL;
-// 4597450: end
- }
- UNLOCK(self->lock);
-}
-
-int
-_pthread_join_cleanup(pthread_t thread, void ** value_ptr, int conforming)
-{
- kern_return_t res;
- int ret;
-
-#if PTH_TRACE
- __kdebug_trace(0x9000028, thread, 0, 0, 1, 0);
-#endif
- /* The scenario where the joiner was waiting for the thread and
- * the pthread detach happened on that thread. Then the semaphore
- * will trigger but by the time joiner runs, the target thread could be
- * freed. So we need to make sure that the thread is still in the list
- * and is joinable before we continue with the join.
- */
- LOCK(_pthread_list_lock);
- if ((ret = _pthread_find_thread(thread)) != 0) {
- UNLOCK(_pthread_list_lock);
- /* returns ESRCH */
- return(ret);
- }
- if ((thread->detached & PTHREAD_CREATE_JOINABLE) == 0) {
- /* the thread might be a detached thread */
- UNLOCK(_pthread_list_lock);
- return(ESRCH);
-
- }
- /* It is still a joinable thread and needs to be reaped */
- TAILQ_REMOVE(&__pthread_head, thread, plist);
-#if PTH_LISTTRACE
- __kdebug_trace(0x9000010, thread, 0, 0, 3, 0);
-#endif
- UNLOCK(_pthread_list_lock);
-
- if (value_ptr)
- *value_ptr = thread->exit_value;
- if (conforming) {
- if ((thread->cancel_state & (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING)) ==
- (PTHREAD_CANCEL_ENABLE|_PTHREAD_CANCEL_PENDING) && (value_ptr != NULL)) {
- *value_ptr = PTHREAD_CANCELED;
- }
- }
- if (thread->reply_port != MACH_PORT_NULL) {
- res = mach_port_mod_refs(mach_task_self(), thread->reply_port, MACH_PORT_RIGHT_RECEIVE, -1);
- if (res != KERN_SUCCESS)
- fprintf(stderr,"mach_port_mod_refs(reply_port) failed: %s\n",mach_error_string(res));
- thread->reply_port = MACH_PORT_NULL;
- }
- if (thread->freeStackOnExit) {
- thread->sig = _PTHREAD_NO_SIG;
-#if PTH_TRACE
- __kdebug_trace(0x9000028, thread, 0, 0, 2, 0);
-#endif
- vm_deallocate(mach_task_self(), (mach_vm_address_t)(uintptr_t)thread, pthreadsize);
- } else {
- thread->sig = _PTHREAD_NO_SIG;
-#if PTH_TRACE
- __kdebug_trace(0x9000028, thread, 0, 0, 3, 0);
-#endif
- free(thread);
- }
- return(0);
-}
-
-/* ALWAYS called with list lock and return with list lock */
-int
-_pthread_find_thread(pthread_t thread)
-{
- pthread_t p;
-
-loop:
- TAILQ_FOREACH(p, &__pthread_head, plist) {
- if (p == thread) {
- if (thread->kernel_thread == MACH_PORT_NULL) {
- UNLOCK(_pthread_list_lock);
- sched_yield();
- LOCK(_pthread_list_lock);
- goto loop;
- }
- return(0);
- }
- }
- return(ESRCH);
-}
-
-int
-_pthread_lookup_thread(pthread_t thread, mach_port_t * portp, int only_joinable)
-{
- mach_port_t kport;
- int ret = 0;
-
- if (thread == NULL)
- return(ESRCH);
-
- LOCK(_pthread_list_lock);
-
- if ((ret = _pthread_find_thread(thread)) != 0) {
- UNLOCK(_pthread_list_lock);
- return(ret);
- }
- if ((only_joinable != 0) && ((thread->detached & PTHREAD_CREATE_DETACHED) != 0)) {
- UNLOCK(_pthread_list_lock);
- return(EINVAL);
- }
- kport = thread->kernel_thread;
- UNLOCK(_pthread_list_lock);
- if (portp != NULL)
- *portp = kport;
- return(0);
-}
-
-/* XXXXXXXXXXXXX Pthread Workqueue Attributes XXXXXXXXXXXXXXXXXX */
-int
-pthread_workqueue_attr_init_np(pthread_workqueue_attr_t * attrp)
-{
- attrp->queueprio = WORKQ_DEFAULT_PRIOQUEUE;
- attrp->sig = PTHREAD_WORKQUEUE_ATTR_SIG;
- attrp->overcommit = 0;
- return(0);
-}
-
-int
-pthread_workqueue_attr_destroy_np(pthread_workqueue_attr_t * attr)
-{
- if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG)
- {
- return (0);
- } else
- {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-int
-pthread_workqueue_attr_getqueuepriority_np(const pthread_workqueue_attr_t * attr, int * qpriop)
-{
- if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) {
- *qpriop = attr->queueprio;
- return (0);
- } else {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-
-int
-pthread_workqueue_attr_setqueuepriority_np(pthread_workqueue_attr_t * attr, int qprio)
-{
-int error = 0;
-
- if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) {
- switch(qprio) {
- case WORKQ_HIGH_PRIOQUEUE:
- case WORKQ_DEFAULT_PRIOQUEUE:
- case WORKQ_LOW_PRIOQUEUE:
- case WORKQ_BG_PRIOQUEUE:
- attr->queueprio = qprio;
- break;
- default:
- error = EINVAL;
- }
- } else {
- error = EINVAL;
- }
- return (error);
-}
-
-
-int
-pthread_workqueue_attr_getovercommit_np(const pthread_workqueue_attr_t * attr, int * ocommp)
-{
- if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) {
- *ocommp = attr->overcommit;
- return (0);
- } else {
- return (EINVAL); /* Not an attribute structure! */
- }
-}
-
-
-int
-pthread_workqueue_attr_setovercommit_np(pthread_workqueue_attr_t * attr, int ocomm)
-{
-int error = 0;
-
- if (attr->sig == PTHREAD_WORKQUEUE_ATTR_SIG) {
- attr->overcommit = ocomm;
- } else {
- error = EINVAL;
- }
- return (error);
-}
-/* XXXXXXXXXXXXX Pthread Workqueue support routines XXXXXXXXXXXXXXXXXX */
-
-static void
-workqueue_list_lock()
-{
- OSSpinLockLock(&__workqueue_list_lock);
-}
-
-static void
-workqueue_list_unlock()
-{
- OSSpinLockUnlock(&__workqueue_list_lock);
-}
-
-int
-pthread_workqueue_init_np()
-{
- int ret;
-
- if (__workqueue_newspis != 0)
- return(EPERM);
- __workqueue_oldspis = 1;
-
- workqueue_list_lock();
- ret =_pthread_work_internal_init();
- workqueue_list_unlock();
-
- return(ret);
-}
-
-int
-pthread_workqueue_requestconcurrency_np(int queue, int request_concurrency)
-{
- int error = 0;
-
- if (__workqueue_newspis != 0)
- return(EPERM);
-
- if (queue < 0 || queue > WORKQ_NUM_PRIOQUEUE)
- return(EINVAL);
-
- error =__workq_kernreturn(WQOPS_THREAD_SETCONC, NULL, request_concurrency, queue);
-
- if (error == -1)
- return(errno);
- return(0);
-}
-
-void
-pthread_workqueue_atfork_prepare(void)
-{
- /*
- * NOTE: Any workq additions here
- * should be for i386,x86_64 only
- */
- dispatch_atfork_prepare();
-}
-
-void
-pthread_workqueue_atfork_parent(void)
-{
- /*
- * NOTE: Any workq additions here
- * should be for i386,x86_64 only
- */
- dispatch_atfork_parent();
-}
-
-void
-pthread_workqueue_atfork_child(void)
-{
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- pthread_t self = pthread_self();
-
- __workqueue_list_lock = OS_SPINLOCK_INIT;
-
- /* already using new spis? */
- if (__workqueue_newspis != 0) {
- /* prepare the kernel for workq action */
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)), _pthread_start, &workq_targetconc[0], (uintptr_t)(&self->tsd[__PTK_LIBDISPATCH_KEY0]) - (uintptr_t)(&self->tsd[0]));
-#else
- __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)),NULL,NULL,0);
-#endif
- (void)__workq_open();
- kernel_workq_setup = 1;
- return;
- }
-
- /* not using old spis either? */
- if (__workqueue_oldspis == 0)
- return;
-
- /*
- * NOTE: workq additions here
- * are for i386,x86_64 only as
- * ppc and arm do not support it
- */
- if (kernel_workq_setup != 0){
- kernel_workq_setup = 0;
- _pthread_work_internal_init();
- }
-#endif
- dispatch_atfork_child();
-}
-
-static int
-_pthread_work_internal_init(void)
-{
- int i, error;
- pthread_workqueue_head_t headp;
- pthread_workqueue_t wq;
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- pthread_t self = pthread_self();
-#endif
-
- if (kernel_workq_setup == 0) {
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- __bsdthread_register(thread_start, start_wqthread, round_page(sizeof(struct _pthread)), _pthread_start, &workq_targetconc[0], (uintptr_t)(&self->tsd[__PTK_LIBDISPATCH_KEY0]) - (uintptr_t)(&self->tsd[0]));
-#else
- __bsdthread_register(_pthread_start, _pthread_wqthread, round_page(sizeof(struct _pthread)),NULL,NULL,0);
-#endif
-
- _pthread_wq_attr_default.queueprio = WORKQ_DEFAULT_PRIOQUEUE;
- _pthread_wq_attr_default.sig = PTHREAD_WORKQUEUE_ATTR_SIG;
-
- for( i = 0; i< WORKQ_NUM_PRIOQUEUE; i++) {
- headp = __pthread_wq_head_tbl[i];
- TAILQ_INIT(&headp->wqhead);
- headp->next_workq = 0;
- }
-
- __workqueue_pool_ptr = NULL;
- __workqueue_pool_size = round_page(sizeof(struct _pthread_workitem) * WORKITEM_POOL_SIZE);
-
- __workqueue_pool_ptr = (struct _pthread_workitem *)mmap(NULL, __workqueue_pool_size,
- PROT_READ|PROT_WRITE,
- MAP_ANON | MAP_PRIVATE,
- 0,
- 0);
-
- if (__workqueue_pool_ptr == MAP_FAILED) {
- /* Not expected to fail, if it does, always malloc for work items */
- __workqueue_nitems = WORKITEM_POOL_SIZE;
- __workqueue_pool_ptr = NULL;
- } else
- __workqueue_nitems = 0;
-
- /* sets up the workitem pool */
- grow_workitem();
-
- /* since the size is less than a page, leaving this in malloc pool */
- wq = (struct _pthread_workqueue *)malloc(sizeof(struct _pthread_workqueue) * WORKQUEUE_POOL_SIZE);
- bzero(wq, (sizeof(struct _pthread_workqueue) * WORKQUEUE_POOL_SIZE));
- for (i = 0; i < WORKQUEUE_POOL_SIZE; i++) {
- TAILQ_INSERT_TAIL(&__pthread_workqueue_pool_head, &wq[i], wq_list);
- }
-
- if (error = __workq_open()) {
- TAILQ_INIT(&__pthread_workitem_pool_head);
- TAILQ_INIT(&__pthread_workqueue_pool_head);
- if (__workqueue_pool_ptr != NULL) {
- munmap((void *)__workqueue_pool_ptr, __workqueue_pool_size);
- }
- free(wq);
- return(ENOMEM);
- }
- kernel_workq_setup = 1;
- }
- return(0);
-}
-
-
-/* This routine is called with list lock held */
-static pthread_workitem_t
-alloc_workitem(void)
-{
- pthread_workitem_t witem;
-
- if (TAILQ_EMPTY(&__pthread_workitem_pool_head)) {
- /* the chunk size is set so some multiple of it is pool size */
- if (__workqueue_nitems < WORKITEM_POOL_SIZE) {
- grow_workitem();
- } else {
- workqueue_list_unlock();
- witem = malloc(sizeof(struct _pthread_workitem));
- workqueue_list_lock();
- witem->fromcache = 0;
- goto out;
- }
- }
- witem = TAILQ_FIRST(&__pthread_workitem_pool_head);
- TAILQ_REMOVE(&__pthread_workitem_pool_head, witem, item_entry);
- witem->fromcache = 1;
-out:
- witem->flags = 0;
- witem->item_entry.tqe_next = 0;
- witem->item_entry.tqe_prev = 0;
- user_workitem_count++;
- return(witem);
-}
-
-/* This routine is called with list lock held */
-static void
-free_workitem(pthread_workitem_t witem)
-{
- user_workitem_count--;
- witem->flags = 0;
- if (witem->fromcache != 0)
- TAILQ_INSERT_TAIL(&__pthread_workitem_pool_head, witem, item_entry);
- else
- free(witem);
-}
-
-static void
-grow_workitem(void)
-{
- pthread_workitem_t witemp;
- int i;
-
- witemp = &__workqueue_pool_ptr[__workqueue_nitems];
- bzero(witemp, (sizeof(struct _pthread_workitem) * WORKITEM_CHUNK_SIZE));
- for (i = 0; i < WORKITEM_CHUNK_SIZE; i++) {
- witemp[i].fromcache = 1;
- TAILQ_INSERT_TAIL(&__pthread_workitem_pool_head, &witemp[i], item_entry);
- }
- __workqueue_nitems += WORKITEM_CHUNK_SIZE;
-}
-
-/* This routine is called with list lock held */
-static pthread_workqueue_t
-alloc_workqueue(void)
-{
- pthread_workqueue_t wq;
-
- if (TAILQ_EMPTY(&__pthread_workqueue_pool_head)) {
- workqueue_list_unlock();
- wq = malloc(sizeof(struct _pthread_workqueue));
- workqueue_list_lock();
- } else {
- wq = TAILQ_FIRST(&__pthread_workqueue_pool_head);
- TAILQ_REMOVE(&__pthread_workqueue_pool_head, wq, wq_list);
- }
- user_workq_count++;
- return(wq);
-}
-
-/* This routine is called with list lock held */
-static void
-free_workqueue(pthread_workqueue_t wq)
-{
- user_workq_count--;
- TAILQ_INSERT_TAIL(&__pthread_workqueue_pool_head, wq, wq_list);
-}
-
-static void
-_pthread_workq_init(pthread_workqueue_t wq, const pthread_workqueue_attr_t * attr)
-{
- bzero(wq, sizeof(struct _pthread_workqueue));
- if (attr != NULL) {
- wq->queueprio = attr->queueprio;
- wq->overcommit = attr->overcommit;
- } else {
- wq->queueprio = WORKQ_DEFAULT_PRIOQUEUE;
- wq->overcommit = 0;
- }
- LOCK_INIT(wq->lock);
- wq->flags = 0;
- TAILQ_INIT(&wq->item_listhead);
- TAILQ_INIT(&wq->item_kernhead);
-#if WQ_LISTTRACE
- __kdebug_trace(0x90080ac, wq, &wq->item_listhead, wq->item_listhead.tqh_first, wq->item_listhead.tqh_last, 0);
-#endif
- wq->wq_list.tqe_next = 0;
- wq->wq_list.tqe_prev = 0;
- wq->sig = PTHREAD_WORKQUEUE_SIG;
- wq->headp = __pthread_wq_head_tbl[wq->queueprio];
-}
-
-int
-valid_workq(pthread_workqueue_t workq)
-{
- if (workq->sig == PTHREAD_WORKQUEUE_SIG)
- return(1);
- else
- return(0);
-}
-
-
-/* called with list lock */
-static void
-pick_nextworkqueue_droplock()
-{
- int i, curwqprio, val, found;
- pthread_workqueue_head_t headp;
- pthread_workqueue_t workq;
- pthread_workqueue_t nworkq = NULL;
-
-#if WQ_TRACE
- __kdebug_trace(0x9008098, kernel_workq_count, 0, 0, 0, 0);
-#endif
-loop:
- while (kernel_workq_count < KERNEL_WORKQ_ELEM_MAX) {
- found = 0;
- for (i = 0; i < WORKQ_NUM_PRIOQUEUE; i++) {
- wqreadyprio = i; /* because there is nothing else higher to run */
- headp = __pthread_wq_head_tbl[i];
-
- if (TAILQ_EMPTY(&headp->wqhead))
- continue;
- workq = headp->next_workq;
- if (workq == NULL)
- workq = TAILQ_FIRST(&headp->wqhead);
- curwqprio = workq->queueprio;
- nworkq = workq; /* starting pt */
- while (kernel_workq_count < KERNEL_WORKQ_ELEM_MAX) {
- headp->next_workq = TAILQ_NEXT(workq, wq_list);
- if (headp->next_workq == NULL)
- headp->next_workq = TAILQ_FIRST(&headp->wqhead);
-#if WQ_TRACE
- __kdebug_trace(0x9008098, kernel_workq_count, workq, 0, 1, 0);
-#endif
- val = post_nextworkitem(workq);
-
- if (val != 0) {
- /* things could have changed so reasses */
- /* If kernel queue is full , skip */
- if (kernel_workq_count >= KERNEL_WORKQ_ELEM_MAX)
- break;
- /* If anything with higher prio arrived, then reevaluate */
- if (wqreadyprio < curwqprio)
- goto loop; /* we need re evaluate again */
- /* we can post some more work items */
- found = 1;
- }
-
- /* cannot use workq here as it could be freed */
- if (TAILQ_EMPTY(&headp->wqhead))
- break;
- /* if we found nothing to run and only one workqueue in the list, skip */
- if ((val == 0) && (workq == headp->next_workq))
- break;
- workq = headp->next_workq;
- if (workq == NULL)
- workq = TAILQ_FIRST(&headp->wqhead);
- if (val != 0)
- nworkq = workq;
- /* if we found nothing to run and back to workq where we started */
- if ((val == 0) && (workq == nworkq))
- break;
- }
- if (kernel_workq_count >= KERNEL_WORKQ_ELEM_MAX)
- break;
- }
- /* nothing found to run? */
- if (found == 0)
- break;
- }
- workqueue_list_unlock();
-}
-
-static int
-post_nextworkitem(pthread_workqueue_t workq)
-{
- int error, prio;
- pthread_workitem_t witem;
- pthread_workqueue_head_t headp;
- void (*func)(pthread_workqueue_t, void *);
-
- if ((workq->flags & PTHREAD_WORKQ_SUSPEND) == PTHREAD_WORKQ_SUSPEND) {
- return(0);
- }
-#if WQ_TRACE
- __kdebug_trace(0x900809c, workq, workq->item_listhead.tqh_first, 0, 1, 0);
-#endif
- if (TAILQ_EMPTY(&workq->item_listhead)) {
- return(0);
- }
- if ((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == PTHREAD_WORKQ_BARRIER_ON)
- return(0);
-
- witem = TAILQ_FIRST(&workq->item_listhead);
- headp = workq->headp;
-#if WQ_TRACE
- __kdebug_trace(0x900809c, workq, witem, 0, 0xee, 0);
-#endif
- if ((witem->flags & PTH_WQITEM_BARRIER) == PTH_WQITEM_BARRIER) {
-#if WQ_TRACE
- __kdebug_trace(0x9000064, workq, 0, 0, 2, 0);
-#endif
-
- if ((witem->flags & PTH_WQITEM_APPLIED) != 0) {
- return(0);
- }
- /* Also barrier when nothing is there needs to be handled */
- /* Nothing to wait for */
- if (workq->kq_count != 0) {
- witem->flags |= PTH_WQITEM_APPLIED;
- workq->flags |= PTHREAD_WORKQ_BARRIER_ON;
- workq->barrier_count = workq->kq_count;
-#if WQ_TRACE
- __kdebug_trace(0x9000064, 1, workq->barrier_count, 0, 0, 0);
-#endif
- return(1);
- } else {
-#if WQ_TRACE
- __kdebug_trace(0x9000064, 2, workq->barrier_count, 0, 0, 0);
-#endif
- if (witem->func != NULL) {
- /* since we are going to drop list lock */
- witem->flags |= PTH_WQITEM_APPLIED;
- workq->flags |= PTHREAD_WORKQ_BARRIER_ON;
- workqueue_list_unlock();
- func = (void (*)(pthread_workqueue_t, void *))witem->func;
- (*func)(workq, witem->func_arg);
-#if WQ_TRACE
- __kdebug_trace(0x9000064, 3, workq->barrier_count, 0, 0, 0);
-#endif
- workqueue_list_lock();
- workq->flags &= ~PTHREAD_WORKQ_BARRIER_ON;
- }
- TAILQ_REMOVE(&workq->item_listhead, witem, item_entry);
-#if WQ_LISTTRACE
- __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0);
-#endif
- free_workitem(witem);
-#if WQ_TRACE
- __kdebug_trace(0x9000064, 4, workq->barrier_count, 0, 0, 0);
-#endif
- return(1);
- }
- } else if ((witem->flags & PTH_WQITEM_DESTROY) == PTH_WQITEM_DESTROY) {
-#if WQ_TRACE
- __kdebug_trace(0x9000068, 1, workq->kq_count, 0, 0, 0);
-#endif
- if ((witem->flags & PTH_WQITEM_APPLIED) != 0) {
- return(0);
- }
- witem->flags |= PTH_WQITEM_APPLIED;
- workq->flags |= (PTHREAD_WORKQ_BARRIER_ON | PTHREAD_WORKQ_TERM_ON);
- workq->barrier_count = workq->kq_count;
- workq->term_callback = (void (*)(struct _pthread_workqueue *,void *))witem->func;
- workq->term_callarg = witem->func_arg;
- TAILQ_REMOVE(&workq->item_listhead, witem, item_entry);
-#if WQ_LISTTRACE
- __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0);
-#endif
- if ((TAILQ_EMPTY(&workq->item_listhead)) && (workq->kq_count == 0)) {
- if (!(TAILQ_EMPTY(&workq->item_kernhead))) {
-#if WQ_TRACE
- __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 0xff, 0);
-#endif
- }
- free_workitem(witem);
- workq->flags |= PTHREAD_WORKQ_DESTROYED;
-#if WQ_TRACE
- __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 1, 0);
-#endif
- headp = __pthread_wq_head_tbl[workq->queueprio];
- if (headp->next_workq == workq) {
- headp->next_workq = TAILQ_NEXT(workq, wq_list);
- if (headp->next_workq == NULL) {
- headp->next_workq = TAILQ_FIRST(&headp->wqhead);
- if (headp->next_workq == workq)
- headp->next_workq = NULL;
- }
- }
- workq->sig = 0;
- TAILQ_REMOVE(&headp->wqhead, workq, wq_list);
- if (workq->term_callback != NULL) {
- workqueue_list_unlock();
- (*workq->term_callback)(workq, workq->term_callarg);
- workqueue_list_lock();
- }
- free_workqueue(workq);
- return(1);
- } else {
- TAILQ_INSERT_HEAD(&workq->item_listhead, witem, item_entry);
-#if WQ_LISTTRACE
- __kdebug_trace(0x90080b0, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0);
-#endif
- }
-#if WQ_TRACE
- __kdebug_trace(0x9000068, 2, workq->barrier_count, 0, 0, 0);
-#endif
- return(1);
- } else {
-#if WQ_TRACE
- __kdebug_trace(0x9000060, witem, workq, witem->func_arg, 0xfff, 0);
-#endif
- TAILQ_REMOVE(&workq->item_listhead, witem, item_entry);
-#if WQ_LISTTRACE
- __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0);
-#endif
- TAILQ_INSERT_TAIL(&workq->item_kernhead, witem, item_entry);
- if ((witem->flags & PTH_WQITEM_KERN_COUNT) == 0) {
- workq->kq_count++;
- witem->flags |= PTH_WQITEM_KERN_COUNT;
- }
- OSAtomicIncrement32Barrier(&kernel_workq_count);
- workqueue_list_unlock();
-
- prio = workq->queueprio;
- if (workq->overcommit != 0) {
- prio |= WORKQUEUE_OVERCOMMIT;
- }
-
- if (( error =__workq_kernreturn(WQOPS_QUEUE_ADD, witem, workq->affinity, prio)) == -1) {
- OSAtomicDecrement32Barrier(&kernel_workq_count);
- workqueue_list_lock();
-#if WQ_TRACE
- __kdebug_trace(0x900007c, witem, workq, witem->func_arg, workq->kq_count, 0);
-#endif
- TAILQ_REMOVE(&workq->item_kernhead, witem, item_entry);
- TAILQ_INSERT_HEAD(&workq->item_listhead, witem, item_entry);
-#if WQ_LISTTRACE
- __kdebug_trace(0x90080b0, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0);
-#endif
- if ((workq->flags & (PTHREAD_WORKQ_BARRIER_ON | PTHREAD_WORKQ_TERM_ON)) != 0)
- workq->flags |= PTHREAD_WORKQ_REQUEUED;
- } else
- workqueue_list_lock();
-#if WQ_TRACE
- __kdebug_trace(0x9000060, witem, workq, witem->func_arg, workq->kq_count, 0);
-#endif
- return(1);
- }
- /* noone should come here */
-#if 1
- printf("error in logic for next workitem\n");
- LIBC_ABORT("error in logic for next workitem");
-#endif
- return(0);
-}
-
-void
-_pthread_wqthread(pthread_t self, mach_port_t kport, void * stackaddr, pthread_workitem_t item, int reuse)
-{
- int ret;
- pthread_attr_t *attrs = &_pthread_attr_default;
- pthread_workqueue_t workq;
-#if WQ_DEBUG
- pthread_t pself;
-#endif
- int thread_reuse = 0;
- int thread_priority = 0;
- int thread_newspi = 0;
- int thread_options = 0;
-
- if (reuse & WQ_FLAG_THREAD_NEWSPI) {
- thread_reuse = reuse & WQ_FLAG_THREAD_REUSE;
- if ((reuse & WQ_FLAG_THREAD_OVERCOMMIT) != 0)
- thread_options = WORKQ_ADDTHREADS_OPTION_OVERCOMMIT;
- thread_priority = reuse & WQ_FLAG_THREAD_PRIOMASK;
- thread_newspi = 1;
- workq = NULL;
- } else {
- thread_reuse = (reuse == 0)? 0: WQ_FLAG_THREAD_REUSE;
- workq = item->workq;
- }
-
-
- if (thread_reuse == 0) {
- /* reuse is set to 0, when a thread is newly created to run a workitem */
- _pthread_struct_init(self, attrs, stackaddr, DEFAULT_STACK_SIZE, 1, 1);
- self->wqthread = 1;
- self->wqkillset = 0;
- self->parentcheck = 1;
-
- /* These are not joinable threads */
- self->detached &= ~PTHREAD_CREATE_JOINABLE;
- self->detached |= PTHREAD_CREATE_DETACHED;
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- _pthread_set_self(self);
-#endif
-#if WQ_TRACE
- __kdebug_trace(0x9000050, self, item, item->func_arg, 0, 0);
-#endif
- self->kernel_thread = kport;
- if (thread_newspi != 0) {
- self->fun = (void *(*)(void *))__libdispatch_workerfunction;
- self->arg = thread_priority;
- } else {
- self->fun = (void *(*)(void *))item->func;
- self->arg = item->func_arg;
- }
- /* Add to the pthread list */
- LOCK(_pthread_list_lock);
- TAILQ_INSERT_TAIL(&__pthread_head, self, plist);
-#if PTH_LISTTRACE
- __kdebug_trace(0x900000c, self, 0, 0, 10, 0);
-#endif
- _pthread_count++;
- UNLOCK(_pthread_list_lock);
-
-#if defined(__i386__) || defined(__x86_64__) || defined(__arm__)
- if( (self->thread_id = __thread_selfid()) == (__uint64_t)-1)
- printf("Failed to set thread_id in pthread_wqthread\n");
-#endif
-
- } else {
- /* reuse is set to 1, when a thread is resued to run another work item */
-#if WQ_TRACE
- __kdebug_trace(0x9000054, self, item, item->func_arg, 0, 0);
-#endif
- /* reset all tsd from 1 to KEYS_MAX */
- if (self == NULL)
- LIBC_ABORT("_pthread_wqthread: pthread %p setup to be NULL", self);
-
- if (thread_newspi != 0) {
- self->fun = (void *(*)(void *))__libdispatch_workerfunction;
- self->arg = NULL;
- } else {
- self->fun = (void *(*)(void *))item->func;
- self->arg = item->func_arg;
- }
- }
-
-#if WQ_DEBUG
- if (reuse == 0) {
- pself = pthread_self();
- if (self != pself) {
-#if WQ_TRACE
- __kdebug_trace(0x9000078, self, pself, item->func_arg, 0, 0);
-#endif
- printf("pthread_self not set: pself %p, passed in %p\n", pself, self);
- _pthread_set_self(self);
- pself = pthread_self();
- if (self != pself)
- printf("(2)pthread_self not set: pself %p, passed in %p\n", pself, self);
- pself = self;
- }
- } else {
- pself = pthread_self();
- if (self != pself) {
- printf("(3)pthread_self not set in reuse: pself %p, passed in %p\n", pself, self);
- LIBC_ABORT("(3)pthread_self not set in reuse: pself %p, passed in %p", pself, self);
- }
- }
-#endif /* WQ_DEBUG */
-
- if (thread_newspi != 0) {
- (*__libdispatch_workerfunction)(thread_priority, thread_options, NULL);
- _pthread_workq_return(self);
- } else {
- self->cur_workq = workq;
- self->cur_workitem = item;
- OSAtomicDecrement32Barrier(&kernel_workq_count);
-
- ret = (int)(intptr_t)(*self->fun)(self->arg);
- /* If we reach here without going through the above initialization path then don't go through
- * with the teardown code path ( e.g. setjmp/longjmp ). Instead just exit this thread.
- */
- if (self != pthread_self()) {
- pthread_exit(PTHREAD_CANCELED);
- }
-
- workqueue_exit(self, workq, item);
- }
-}
-
-static void
-workqueue_exit(pthread_t self, pthread_workqueue_t workq, pthread_workitem_t item)
-{
- pthread_workitem_t baritem;
- pthread_workqueue_head_t headp;
- void (*func)(pthread_workqueue_t, void *);
-
- workqueue_list_lock();
-
- TAILQ_REMOVE(&workq->item_kernhead, item, item_entry);
- workq->kq_count--;
-#if WQ_TRACE
- __kdebug_trace(0x9000070, self, 1, item->func_arg, workq->kq_count, 0);
-#endif
- free_workitem(item);
-
- if ((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == PTHREAD_WORKQ_BARRIER_ON) {
- workq->barrier_count--;
-#if WQ_TRACE
- __kdebug_trace(0x9000084, self, workq->barrier_count, workq->kq_count, 1, 0);
-#endif
- if (workq->barrier_count <= 0 ) {
- /* Need to remove barrier item from the list */
- baritem = TAILQ_FIRST(&workq->item_listhead);
-#if WQ_DEBUG
- if ((baritem->flags & (PTH_WQITEM_BARRIER | PTH_WQITEM_DESTROY| PTH_WQITEM_APPLIED)) == 0)
- printf("Incorect bar item being removed in barrier processing\n");
-#endif /* WQ_DEBUG */
- /* if the front item is a barrier and call back is registered, run that */
- if (((baritem->flags & PTH_WQITEM_BARRIER) == PTH_WQITEM_BARRIER) && (baritem->func != NULL)) {
- workqueue_list_unlock();
- func = (void (*)(pthread_workqueue_t, void *))baritem->func;
- (*func)(workq, baritem->func_arg);
- workqueue_list_lock();
- }
- TAILQ_REMOVE(&workq->item_listhead, baritem, item_entry);
-#if WQ_LISTTRACE
- __kdebug_trace(0x90080a8, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0);
-#endif
- free_workitem(baritem);
- workq->flags &= ~PTHREAD_WORKQ_BARRIER_ON;
-#if WQ_TRACE
- __kdebug_trace(0x9000058, self, item, item->func_arg, 0, 0);
-#endif
- if ((workq->flags & PTHREAD_WORKQ_TERM_ON) != 0) {
- headp = __pthread_wq_head_tbl[workq->queueprio];
- workq->flags |= PTHREAD_WORKQ_DESTROYED;
-#if WQ_TRACE
- __kdebug_trace(0x900006c, workq, workq->kq_count, 0, 2, 0);
-#endif
- if (headp->next_workq == workq) {
- headp->next_workq = TAILQ_NEXT(workq, wq_list);
- if (headp->next_workq == NULL) {
- headp->next_workq = TAILQ_FIRST(&headp->wqhead);
- if (headp->next_workq == workq)
- headp->next_workq = NULL;
- }
- }
- TAILQ_REMOVE(&headp->wqhead, workq, wq_list);
- workq->sig = 0;
- if (workq->term_callback != NULL) {
- workqueue_list_unlock();
- (*workq->term_callback)(workq, workq->term_callarg);
- workqueue_list_lock();
- }
- free_workqueue(workq);
- } else {
- /* if there are higher prio schedulabel item reset to wqreadyprio */
- if ((workq->queueprio < wqreadyprio) && (!(TAILQ_EMPTY(&workq->item_listhead))))
- wqreadyprio = workq->queueprio;
- }
- }
- }
-#if WQ_TRACE
- else {
- __kdebug_trace(0x9000070, self, 2, item->func_arg, workq->barrier_count, 0);
- }
-
- __kdebug_trace(0x900005c, self, item, 0, 0, 0);
-#endif
- pick_nextworkqueue_droplock();
- _pthread_workq_return(self);
-}
-
-static void
-_pthread_workq_return(pthread_t self)
-{
- __workq_kernreturn(WQOPS_THREAD_RETURN, NULL, 0, 0);
-
- /* This is the way to terminate the thread */
- _pthread_exit(self, NULL);
-}
-
-
-/* XXXXXXXXXXXXX Pthread Workqueue functions XXXXXXXXXXXXXXXXXX */
-
-int
-pthread_workqueue_setdispatch_np(void (*worker_func)(int, int, void *))
-{
- int error = 0;
-
- if (__workqueue_oldspis != 0)
- return(EPERM);
-
- __workqueue_newspis = 1;
-
- if (__libdispatch_workerfunction == NULL) {
- __libdispatch_workerfunction = worker_func;
- /* check whether the kernel supports new SPIs */
- error = __workq_kernreturn(WQOPS_QUEUE_NEWSPISUPP, NULL, 0, 0);
- if (error == -1){
- __libdispatch_workerfunction = NULL;
- error = ENOTSUP;
- __workqueue_newspis = 0;
- } else {
- /* prepare the kernel for workq action */
- (void)__workq_open();
- kernel_workq_setup = 1;
- if (__is_threaded == 0)
- __is_threaded = 1;
- __workqueue_newspis = 1;
- }
- } else {
- error = EBUSY;
- }
-
- return(error);
-}
-
-int
-pthread_workqueue_addthreads_np(int queue_priority, int options, int numthreads)
-{
- int priority = queue_priority & WQ_FLAG_THREAD_PRIOMASK;
- int error = 0;
-
- /* new spi not inited yet?? */
- if (__workqueue_newspis == 0)
- return(EPERM);
-
-
- if ((options & WORKQ_ADDTHREADS_OPTION_OVERCOMMIT) != 0)
- priority |= WORKQUEUE_OVERCOMMIT;
-
- error = __workq_kernreturn(WQOPS_QUEUE_REQTHREADS, NULL, numthreads, priority);
-
- if (error == -1)
- return(errno);
- else
- return(0);
-}
-
-int
-pthread_workqueue_create_np(pthread_workqueue_t * workqp, const pthread_workqueue_attr_t * attr)
-{
- pthread_workqueue_t wq;
- pthread_workqueue_head_t headp;
-
-#if defined(__ppc__)
- IF_ROSETTA() {
- return(ENOTSUP);
- }
-#endif
- if (__workqueue_newspis != 0)
- return(EPERM);
-
- if (__workqueue_oldspis == 0)
- __workqueue_oldspis = 1;
-
- if ((attr != NULL) && (attr->sig != PTHREAD_WORKQUEUE_ATTR_SIG)) {
- return(EINVAL);
- }
-
- if (__is_threaded == 0)
- __is_threaded = 1;
-
- workqueue_list_lock();
- if (kernel_workq_setup == 0) {
- int ret = _pthread_work_internal_init();
- if (ret != 0) {
- workqueue_list_unlock();
- return(ret);
- }
- }
-
- wq = alloc_workqueue();
-
- _pthread_workq_init(wq, attr);
-
- headp = __pthread_wq_head_tbl[wq->queueprio];
- TAILQ_INSERT_TAIL(&headp->wqhead, wq, wq_list);
- if (headp->next_workq == NULL) {
- headp->next_workq = TAILQ_FIRST(&headp->wqhead);
- }
-
- workqueue_list_unlock();
-
- *workqp = wq;
-
- return(0);
-}
-
-int
-pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp)
-{
- pthread_workitem_t witem;
-
- if (__workqueue_newspis != 0)
- return(EPERM);
-
- if (valid_workq(workq) == 0) {
- return(EINVAL);
- }
-
- workqueue_list_lock();
-
- /*
- * Allocate the workitem here as it can drop the lock.
- * Also we can evaluate the workqueue state only once.
- */
- witem = alloc_workitem();
- witem->func = workitem_func;
- witem->func_arg = workitem_arg;
- witem->workq = workq;
-
- /* alloc workitem can drop the lock, check the state */
- if ((workq->flags & (PTHREAD_WORKQ_IN_TERMINATE | PTHREAD_WORKQ_DESTROYED)) != 0) {
- free_workitem(witem);
- workqueue_list_unlock();
- *itemhandlep = 0;
- return(ESRCH);
- }
-
- if (itemhandlep != NULL)
- *itemhandlep = (pthread_workitem_handle_t *)witem;
- if (gencountp != NULL)
- *gencountp = 0;
-#if WQ_TRACE
- __kdebug_trace(0x9008090, witem, witem->func, witem->func_arg, workq, 0);
-#endif
- TAILQ_INSERT_TAIL(&workq->item_listhead, witem, item_entry);
-#if WQ_LISTTRACE
- __kdebug_trace(0x90080a4, workq, &workq->item_listhead, workq->item_listhead.tqh_first, workq->item_listhead.tqh_last, 0);
-#endif
-
- if (((workq->flags & PTHREAD_WORKQ_BARRIER_ON) == 0) && (workq->queueprio < wqreadyprio))
- wqreadyprio = workq->queueprio;
-
- pick_nextworkqueue_droplock();
-
- return(0);
-}
-
-int
-pthread_workqueue_getovercommit_np(pthread_workqueue_t workq, unsigned int *ocommp)
-{
- if (__workqueue_newspis != 0)
- return(EPERM);
-
- if (valid_workq(workq) == 0) {
- return(EINVAL);
- }
-
- if (ocommp != NULL)
- *ocommp = workq->overcommit;
- return(0);
-}
-
-
-#else /* !BUILDING_VARIANT ] [ */
-extern int __unix_conforming;
-extern int _pthread_count;
-extern int __workqueue_newspis;
-extern int __workqueue_oldspis;
-
-extern pthread_lock_t _pthread_list_lock;
-extern void _pthread_testcancel(pthread_t thread, int isconforming);
-extern int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr, int conforming);
-
-#endif /* !BUILDING_VARIANT ] */
-
-#if __DARWIN_UNIX03
-
-__private_extern__ void
-__posix_join_cleanup(void *arg)
-{
- pthread_t thread = (pthread_t)arg;
- int already_exited, res;
- void * dummy;
- semaphore_t death;
- int newstyle;
-
- LOCK(thread->lock);
- already_exited = (thread->detached & _PTHREAD_EXITED);
-
- newstyle = thread->newstyle;
-
-#if WQ_TRACE
- __kdebug_trace(0x900002c, thread, newstyle, 0, 0, 0);
-#endif
- if (newstyle == 0) {
- death = thread->death;
- if (!already_exited){
- thread->joiner = (struct _pthread *)NULL;
- UNLOCK(thread->lock);
- restore_sem_to_pool(death);
- } else {
- UNLOCK(thread->lock);
- while ((res = _pthread_reap_thread(thread,
- thread->kernel_thread,
- &dummy, 1)) == EAGAIN)
- {
- sched_yield();
- }
- restore_sem_to_pool(death);
-
- }
-
- } else {
- /* leave another thread to join */
- thread->joiner = (struct _pthread *)NULL;
- UNLOCK(thread->lock);
- }
-}
-
-#endif /* __DARWIN_UNIX03 */
-
-
-/*
- * Wait for a thread to terminate and obtain its exit value.
- */
-/*
-int
-pthread_join(pthread_t thread,
- void **value_ptr)
-
-moved to pthread_cancelable.c */
-
-/*
- * Cancel a thread
- */
-int
-pthread_cancel(pthread_t thread)
-{
-#if __DARWIN_UNIX03
- if (__unix_conforming == 0)
- __unix_conforming = 1;
-#endif /* __DARWIN_UNIX03 */
-
- if (_pthread_lookup_thread(thread, NULL, 0) != 0)
- return(ESRCH);
-
- /* if the thread is a workqueue thread, then return error */
- if (thread->wqthread != 0) {
- return(ENOTSUP);
- }
-#if __DARWIN_UNIX03
- int state;
-
- LOCK(thread->lock);
- state = thread->cancel_state |= _PTHREAD_CANCEL_PENDING;
- UNLOCK(thread->lock);
- if (state & PTHREAD_CANCEL_ENABLE)
- __pthread_markcancel(thread->kernel_thread);
-#else /* __DARWIN_UNIX03 */
- thread->cancel_state |= _PTHREAD_CANCEL_PENDING;
-#endif /* __DARWIN_UNIX03 */
- return (0);
-}
-
-void
-pthread_testcancel(void)
-{
- pthread_t self = pthread_self();
-
-#if __DARWIN_UNIX03
- if (__unix_conforming == 0)
- __unix_conforming = 1;
- _pthread_testcancel(self, 1);
-#else /* __DARWIN_UNIX03 */
- _pthread_testcancel(self, 0);
-#endif /* __DARWIN_UNIX03 */
-
-}
-
-
-/*
- * Query/update the cancelability 'state' of a thread
- */
-int
-pthread_setcancelstate(int state, int *oldstate)
-{
-#if __DARWIN_UNIX03
- if (__unix_conforming == 0) {
- __unix_conforming = 1;
- }
- return (_pthread_setcancelstate_internal(state, oldstate, 1));
-#else /* __DARWIN_UNIX03 */
- return (_pthread_setcancelstate_internal(state, oldstate, 0));
-#endif /* __DARWIN_UNIX03 */
-
-}
-
-
-
-/*
- * Query/update the cancelability 'type' of a thread
- */
-int
-pthread_setcanceltype(int type, int *oldtype)
-{
- pthread_t self = pthread_self();
-
-#if __DARWIN_UNIX03
- if (__unix_conforming == 0)
- __unix_conforming = 1;
-#endif /* __DARWIN_UNIX03 */
-
- if ((type != PTHREAD_CANCEL_DEFERRED) &&
- (type != PTHREAD_CANCEL_ASYNCHRONOUS))
- return EINVAL;
- self = pthread_self();
- LOCK(self->lock);
- if (oldtype)
- *oldtype = self->cancel_state & _PTHREAD_CANCEL_TYPE_MASK;
- self->cancel_state &= ~_PTHREAD_CANCEL_TYPE_MASK;
- self->cancel_state |= type;
- UNLOCK(self->lock);
-#if !__DARWIN_UNIX03
- _pthread_testcancel(self, 0); /* See if we need to 'die' now... */
-#endif /* __DARWIN_UNIX03 */
- return (0);
-}
-
-int
-pthread_sigmask(int how, const sigset_t * set, sigset_t * oset)
-{
-#if __DARWIN_UNIX03
- int err = 0;
-
- if (__pthread_sigmask(how, set, oset) == -1) {
- err = errno;
- }
- return(err);
-#else /* __DARWIN_UNIX03 */
- return(__pthread_sigmask(how, set, oset));
-#endif /* __DARWIN_UNIX03 */
-}
-
-/*
-int
-sigwait(const sigset_t * set, int * sig)
-
-moved to pthread_cancelable.c */
+++ /dev/null
-/*
- * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * POSIX Threads - IEEE 1003.1c
- */
-
-#ifndef _PTHREAD_H
-#define _PTHREAD_H
-
-#include <_types.h>
-#ifndef __POSIX_LIB__
-#include <pthread_impl.h>
-#endif
-#include <sched.h>
-#include <time.h>
-
-#ifndef _PTHREAD_ATTR_T
-#define _PTHREAD_ATTR_T
-typedef __darwin_pthread_attr_t pthread_attr_t;
-#endif
-
-#ifndef _PTHREAD_COND_T
-#define _PTHREAD_COND_T
-typedef __darwin_pthread_cond_t pthread_cond_t;
-#endif
-
-#ifndef _PTHREAD_CONDATTR_T
-#define _PTHREAD_CONDATTR_T
-typedef __darwin_pthread_condattr_t pthread_condattr_t;
-#endif
-
-#ifndef _PTHREAD_KEY_T
-#define _PTHREAD_KEY_T
-typedef __darwin_pthread_key_t pthread_key_t;
-#endif
-
-#ifndef _PTHREAD_MUTEX_T
-#define _PTHREAD_MUTEX_T
-typedef __darwin_pthread_mutex_t pthread_mutex_t;
-#endif
-
-#ifndef _PTHREAD_MUTEXATTR_T
-#define _PTHREAD_MUTEXATTR_T
-typedef __darwin_pthread_mutexattr_t pthread_mutexattr_t;
-#endif
-
-#ifndef _PTHREAD_ONCE_T
-#define _PTHREAD_ONCE_T
-typedef __darwin_pthread_once_t pthread_once_t;
-#endif
-
-#ifndef _PTHREAD_RWLOCK_T
-#define _PTHREAD_RWLOCK_T
-typedef __darwin_pthread_rwlock_t pthread_rwlock_t;
-#endif
-
-#ifndef _PTHREAD_RWLOCKATTR_T
-#define _PTHREAD_RWLOCKATTR_T
-typedef __darwin_pthread_rwlockattr_t pthread_rwlockattr_t;
-#endif
-
-#ifndef _PTHREAD_T
-#define _PTHREAD_T
-typedef __darwin_pthread_t pthread_t;
-#endif
-
-#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE)
-
-#ifndef _MACH_PORT_T
-#define _MACH_PORT_T
-typedef __darwin_mach_port_t mach_port_t;
-#endif
-
-#ifndef _SIGSET_T
-#define _SIGSET_T
-typedef __darwin_sigset_t sigset_t;
-#endif
-
-#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */
-
-/*
- * These symbols indicate which [optional] features are available
- * They can be tested at compile time via '#ifdef XXX'
- * The way to check for pthreads is like so:
-
- * #include <unistd.h>
- * #ifdef _POSIX_THREADS
- * #include <pthread.h>
- * #endif
-
- */
-
-/* These will be moved to unistd.h */
-
-/*
- * Note: These data structures are meant to be opaque. Only enough
- * structure is exposed to support initializers.
- * All of the typedefs will be moved to <sys/types.h>
- */
-
-#include <sys/cdefs.h>
-#include <Availability.h>
-
-__BEGIN_DECLS
-/*
- * Threads
- */
-
-
-/*
- * Cancel cleanup handler management. Note, since these are implemented as macros,
- * they *MUST* occur in matched pairs!
- */
-
-#define pthread_cleanup_push(func, val) \
- { \
- struct __darwin_pthread_handler_rec __handler; \
- pthread_t __self = pthread_self(); \
- __handler.__routine = func; \
- __handler.__arg = val; \
- __handler.__next = __self->__cleanup_stack; \
- __self->__cleanup_stack = &__handler;
-
-#define pthread_cleanup_pop(execute) \
- /* Note: 'handler' must be in this same lexical context! */ \
- __self->__cleanup_stack = __handler.__next; \
- if (execute) (__handler.__routine)(__handler.__arg); \
- }
-
-/*
- * Thread attributes
- */
-
-#define PTHREAD_CREATE_JOINABLE 1
-#define PTHREAD_CREATE_DETACHED 2
-
-#define PTHREAD_INHERIT_SCHED 1
-#define PTHREAD_EXPLICIT_SCHED 2
-
-#define PTHREAD_CANCEL_ENABLE 0x01 /* Cancel takes place at next cancellation point */
-#define PTHREAD_CANCEL_DISABLE 0x00 /* Cancel postponed */
-#define PTHREAD_CANCEL_DEFERRED 0x02 /* Cancel waits until cancellation point */
-#define PTHREAD_CANCEL_ASYNCHRONOUS 0x00 /* Cancel occurs immediately */
-
-/* Value returned from pthread_join() when a thread is canceled */
-#define PTHREAD_CANCELED ((void *) 1)
-
-/* We only support PTHREAD_SCOPE_SYSTEM */
-#define PTHREAD_SCOPE_SYSTEM 1
-#define PTHREAD_SCOPE_PROCESS 2
-
-/* We only support PTHREAD_PROCESS_PRIVATE */
-#define PTHREAD_PROCESS_SHARED 1
-#define PTHREAD_PROCESS_PRIVATE 2
-
-/*
- * Mutex protocol attributes
- */
-#define PTHREAD_PRIO_NONE 0
-#define PTHREAD_PRIO_INHERIT 1
-#define PTHREAD_PRIO_PROTECT 2
-
-/*
- * Mutex type attributes
- */
-#define PTHREAD_MUTEX_NORMAL 0
-#define PTHREAD_MUTEX_ERRORCHECK 1
-#define PTHREAD_MUTEX_RECURSIVE 2
-#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
-/*
- * RWLock variables
- */
-
-#define PTHREAD_RWLOCK_INITIALIZER {_PTHREAD_RWLOCK_SIG_init, {0}}
-/*
- * Mutex variables
- */
-
-#define PTHREAD_MUTEX_INITIALIZER {_PTHREAD_MUTEX_SIG_init, {0}}
-
-#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE)
-#define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER {_PTHREAD_ERRORCHECK_MUTEX_SIG_init, {0}}
-#define PTHREAD_RECURSIVE_MUTEX_INITIALIZER {_PTHREAD_RECURSIVE_MUTEX_SIG_init, {0}}
-#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */
-
-/*
- * Condition variable attributes
- */
-
-/*
- * Condition variables
- */
-
-#define PTHREAD_COND_INITIALIZER {_PTHREAD_COND_SIG_init, {0}}
-
-/*
- * Initialization control (once) variables
- */
-
-#define PTHREAD_ONCE_INIT {_PTHREAD_ONCE_SIG_init, {0}}
-
-/*
- * Prototypes for all PTHREAD interfaces
- */
-int pthread_atfork(void (*)(void), void (*)(void),
- void (*)(void));
-int pthread_attr_destroy(pthread_attr_t *);
-int pthread_attr_getdetachstate(const pthread_attr_t *,
- int *);
-int pthread_attr_getguardsize(const pthread_attr_t * __restrict,
- size_t * __restrict);
-int pthread_attr_getinheritsched(const pthread_attr_t * __restrict,
- int * __restrict);
-int pthread_attr_getschedparam(const pthread_attr_t * __restrict,
- struct sched_param * __restrict);
-int pthread_attr_getschedpolicy(const pthread_attr_t * __restrict,
- int * __restrict);
-int pthread_attr_getscope(const pthread_attr_t * __restrict, int * __restrict);
-int pthread_attr_getstack(const pthread_attr_t * __restrict,
- void ** __restrict, size_t * __restrict);
-int pthread_attr_getstackaddr(const pthread_attr_t * __restrict,
- void ** __restrict);
-int pthread_attr_getstacksize(const pthread_attr_t * __restrict,
- size_t * __restrict);
-int pthread_attr_init(pthread_attr_t *);
-int pthread_attr_setdetachstate(pthread_attr_t *,
- int );
-int pthread_attr_setguardsize(pthread_attr_t *, size_t );
-int pthread_attr_setinheritsched(pthread_attr_t *,
- int );
-int pthread_attr_setschedparam(pthread_attr_t * __restrict,
- const struct sched_param * __restrict);
-int pthread_attr_setschedpolicy(pthread_attr_t *,
- int );
-int pthread_attr_setscope(pthread_attr_t *, int);
-int pthread_attr_setstack(pthread_attr_t *,
- void *, size_t );
-int pthread_attr_setstackaddr(pthread_attr_t *,
- void *);
-int pthread_attr_setstacksize(pthread_attr_t *, size_t );
-int pthread_cancel(pthread_t ) __DARWIN_ALIAS(pthread_cancel);
-
-int pthread_cond_broadcast(pthread_cond_t *);
-int pthread_cond_destroy(pthread_cond_t *);
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_COND_INIT
-//End-Libc
-int pthread_cond_init(pthread_cond_t * __restrict,
- const pthread_condattr_t * __restrict) __DARWIN_ALIAS(pthread_cond_init);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_COND_INIT */
-int pthread_cond_init(pthread_cond_t * __restrict,
- const pthread_condattr_t * __restrict) LIBC_ALIAS(pthread_cond_init);
-#endif /* !LIBC_ALIAS_PTHREAD_COND_INIT */
-//End-Libc
-int pthread_cond_signal(pthread_cond_t *);
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_COND_TIMEDWAIT
-//End-Libc
-int pthread_cond_timedwait(pthread_cond_t * __restrict,
- pthread_mutex_t * __restrict,
- const struct timespec * __restrict) __DARWIN_ALIAS_C(pthread_cond_timedwait);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_COND_TIMEDWAIT */
-int pthread_cond_timedwait(pthread_cond_t * __restrict,
- pthread_mutex_t * __restrict,
- const struct timespec * __restrict) LIBC_ALIAS_C(pthread_cond_timedwait);
-#endif /* !LIBC_ALIAS_PTHREAD_COND_TIMEDWAIT */
-//End-Libc
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_COND_WAIT
-//End-Libc
-int pthread_cond_wait(pthread_cond_t * __restrict,
- pthread_mutex_t * __restrict) __DARWIN_ALIAS_C(pthread_cond_wait);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_COND_WAIT */
-int pthread_cond_wait(pthread_cond_t * __restrict,
- pthread_mutex_t * __restrict) LIBC_ALIAS_C(pthread_cond_wait);
-#endif /* !LIBC_ALIAS_PTHREAD_COND_WAIT */
-//End-Libc
-int pthread_condattr_destroy(pthread_condattr_t *);
-int pthread_condattr_init(pthread_condattr_t *);
-int pthread_condattr_getpshared(const pthread_condattr_t * __restrict,
- int * __restrict);
-int pthread_condattr_setpshared(pthread_condattr_t *,
- int );
-int pthread_create(pthread_t * __restrict,
- const pthread_attr_t * __restrict,
- void *(*)(void *),
- void * __restrict);
-int pthread_detach(pthread_t );
-int pthread_equal(pthread_t ,
- pthread_t );
-void pthread_exit(void *) __dead2;
-int pthread_getconcurrency(void);
-int pthread_getschedparam(pthread_t , int * __restrict, struct sched_param * __restrict);
-void *pthread_getspecific(pthread_key_t );
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_JOIN
-//End-Libc
-int pthread_join(pthread_t , void **) __DARWIN_ALIAS_C(pthread_join);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_JOIN */
-int pthread_join(pthread_t , void **) LIBC_ALIAS_C(pthread_join);
-#endif /* !LIBC_ALIAS_PTHREAD_JOIN */
-//End-Libc
-int pthread_key_create(pthread_key_t *, void (*)(void *));
-int pthread_key_delete(pthread_key_t );
-int pthread_mutex_destroy(pthread_mutex_t *);
-int pthread_mutex_getprioceiling(const pthread_mutex_t * __restrict, int * __restrict);
-int pthread_mutex_init(pthread_mutex_t * __restrict, const pthread_mutexattr_t * __restrict);
-int pthread_mutex_lock(pthread_mutex_t *);
-int pthread_mutex_setprioceiling(pthread_mutex_t * __restrict, int, int * __restrict);
-int pthread_mutex_trylock(pthread_mutex_t *);
-int pthread_mutex_unlock(pthread_mutex_t *);
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY
-//End-Libc
-int pthread_mutexattr_destroy(pthread_mutexattr_t *) __DARWIN_ALIAS(pthread_mutexattr_destroy);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY */
-int pthread_mutexattr_destroy(pthread_mutexattr_t *) LIBC_ALIAS(pthread_mutexattr_destroy);
-#endif /* !LIBC_ALIAS_PTHREAD_MUTEXATTR_DESTROY */
-//End-Libc
-int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t * __restrict, int * __restrict);
-int pthread_mutexattr_getprotocol(const pthread_mutexattr_t * __restrict, int * __restrict);
-int pthread_mutexattr_getpshared(const pthread_mutexattr_t * __restrict, int * __restrict);
-int pthread_mutexattr_gettype(const pthread_mutexattr_t * __restrict, int * __restrict);
-int pthread_mutexattr_init(pthread_mutexattr_t *);
-int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);
-int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int);
-int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int );
-int pthread_mutexattr_settype(pthread_mutexattr_t *, int);
-int pthread_once(pthread_once_t *, void (*)(void));
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_DESTROY
-//End-Libc
-int pthread_rwlock_destroy(pthread_rwlock_t * ) __DARWIN_ALIAS(pthread_rwlock_destroy);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_RWLOCK_DESTROY */
-int pthread_rwlock_destroy(pthread_rwlock_t * ) LIBC_ALIAS(pthread_rwlock_destroy);
-#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_DESTROY */
-//End-Libc
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_INIT
-//End-Libc
-int pthread_rwlock_init(pthread_rwlock_t * __restrict, const pthread_rwlockattr_t * __restrict) __DARWIN_ALIAS(pthread_rwlock_init);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_RWLOCK_INIT */
-int pthread_rwlock_init(pthread_rwlock_t * __restrict, const pthread_rwlockattr_t * __restrict) LIBC_ALIAS(pthread_rwlock_init);
-#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_INIT */
-//End-Libc
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK
-//End-Libc
-int pthread_rwlock_rdlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_rdlock);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK */
-int pthread_rwlock_rdlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_rdlock);
-#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_RDLOCK */
-//End-Libc
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK
-//End-Libc
-int pthread_rwlock_tryrdlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_tryrdlock);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK */
-int pthread_rwlock_tryrdlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_tryrdlock);
-#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_TRYRDLOCK */
-//End-Libc
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK
-//End-Libc
-int pthread_rwlock_trywrlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_trywrlock);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK */
-int pthread_rwlock_trywrlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_trywrlock);
-#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_TRYWRLOCK */
-//End-Libc
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK
-//End-Libc
-int pthread_rwlock_wrlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_wrlock);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK */
-int pthread_rwlock_wrlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_wrlock);
-#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_WRLOCK */
-//End-Libc
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK
-//End-Libc
-int pthread_rwlock_unlock(pthread_rwlock_t *) __DARWIN_ALIAS(pthread_rwlock_unlock);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK */
-int pthread_rwlock_unlock(pthread_rwlock_t *) LIBC_ALIAS(pthread_rwlock_unlock);
-#endif /* !LIBC_ALIAS_PTHREAD_RWLOCK_UNLOCK */
-//End-Libc
-int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
-int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * __restrict,
- int * __restrict);
-int pthread_rwlockattr_init(pthread_rwlockattr_t *);
-int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *,
- int );
-pthread_t pthread_self(void);
-
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_SETCANCELSTATE
-//End-Libc
-int pthread_setcancelstate(int , int *) __DARWIN_ALIAS(pthread_setcancelstate);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_SETCANCELSTATE */
-int pthread_setcancelstate(int , int *) LIBC_ALIAS(pthread_setcancelstate);
-#endif /* !LIBC_ALIAS_PTHREAD_SETCANCELSTATE */
-//End-Libc
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_SETCANCELTYPE
-//End-Libc
-int pthread_setcanceltype(int , int *) __DARWIN_ALIAS(pthread_setcanceltype);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_SETCANCELTYPE */
-int pthread_setcanceltype(int , int *) LIBC_ALIAS(pthread_setcanceltype);
-#endif /* !LIBC_ALIAS_PTHREAD_SETCANCELTYPE */
-//End-Libc
-int pthread_setconcurrency(int);
-int pthread_setschedparam(pthread_t ,
- int ,
- const struct sched_param *);
-int pthread_setspecific(pthread_key_t ,
- const void *);
-void pthread_testcancel(void) __DARWIN_ALIAS(pthread_testcancel);
-
-#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE)
-/* returns non-zero if pthread_create or cthread_fork have been called */
-int pthread_is_threaded_np(void);
-
-int pthread_threadid_np(pthread_t,__uint64_t*) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-
-int pthread_rwlock_longrdlock_np(pthread_rwlock_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-int pthread_rwlock_yieldwrlock_np(pthread_rwlock_t *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA);
-int pthread_rwlock_downgrade_np(pthread_rwlock_t *);
-int pthread_rwlock_upgrade_np(pthread_rwlock_t *);
-int pthread_rwlock_tryupgrade_np(pthread_rwlock_t *);
-int pthread_rwlock_held_np(pthread_rwlock_t *);
-int pthread_rwlock_rdheld_np(pthread_rwlock_t *);
-int pthread_rwlock_wrheld_np(pthread_rwlock_t *);
-
-/*SPI to set and get pthread name*/
-int pthread_getname_np(pthread_t,char*,size_t) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-int pthread_setname_np(const char*) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-/* returns non-zero if the current thread is the main thread */
-int pthread_main_np(void);
-
-/* return the mach thread bound to the pthread */
-mach_port_t pthread_mach_thread_np(pthread_t);
-size_t pthread_get_stacksize_np(pthread_t);
-void * pthread_get_stackaddr_np(pthread_t);
-
-/* Like pthread_cond_signal(), but only wake up the specified pthread */
-int pthread_cond_signal_thread_np(pthread_cond_t *, pthread_t);
-
-/* Like pthread_cond_timedwait, but use a relative timeout */
-int pthread_cond_timedwait_relative_np(pthread_cond_t *,
- pthread_mutex_t *,
- const struct timespec *);
-
-/* Like pthread_create(), but leaves the thread suspended */
-int pthread_create_suspended_np(pthread_t *,
- const pthread_attr_t *,
- void *(*)(void *),
- void *);
-int pthread_kill(pthread_t, int);
-
-pthread_t pthread_from_mach_thread_np(mach_port_t) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-
-//Begin-Libc
-#ifndef LIBC_ALIAS_PTHREAD_SIGMASK
-//End-Libc
-int pthread_sigmask(int, const sigset_t *, sigset_t *) __DARWIN_ALIAS(pthread_sigmask);
-//Begin-Libc
-#else /* LIBC_ALIAS_PTHREAD_SIGMASK */
-int pthread_sigmask(int, const sigset_t *, sigset_t *) LIBC_ALIAS(pthread_sigmask);
-#endif /* !LIBC_ALIAS_PTHREAD_SIGMASK */
-//End-Libc
-void pthread_yield_np(void);
-#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */
-__END_DECLS
-#endif /* _PTHREAD_H */
+++ /dev/null
-.\" Copyright (c) 2004 Apple Computer, Inc.
-.\"
-.Dd August 12, 2004
-.Dt PTHREAD_ATFORK 3
-.Os
-.Sh NAME
-.Nm pthread_atfork
-.Nd register handlers to be called before and after
-.Fn fork
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fn pthread_atfork "void (*prepare)(void)" "void (*parent)(void)" "void (*child)(void)"
-.Sh DESCRIPTION
-The
-.Fn pthread_atfork
-function is used to register functions to be called before and after
-.Fn fork
-The
-.Fa prepare
-handler is called before
-.Fn fork ,
-while the
-.Fa parent
-and
-.Fa child
-handlers are called after
-.Fn fork
-in the parent and child process, respectively.
-.Fa prepare
-handlers are called in reverse order of their registration, while
-.Fa parent
-and
-.Fa child
-handlers are called in the order in which they were registered. Any of the handlers may
-be NULL.
-.Pp
-Remember: only async-cancel-safe functions are allowed on the child side of
-.Fn fork
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_atfork
-function will return zero; otherwise an error number will be returned to
-indicate the error.
-.Sh ERRORS
-.Fn pthread_atfork
-will fail if:
-.Bl -tag -width Er
-.It Bq Er ENOMEM
-The system lacked the necessary resources to add another handler to the list.
-.El
-.Sh SEE ALSO
-.Xr fork 2
-.Sh STANDARDS
-.Fn pthread_atfork
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (C) 2000 Jason Evans <jasone@FreeBSD.org>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice(s), this list of conditions and the following disclaimer as
-.\" the first lines of this file unmodified other than the possible
-.\" addition of one or more copyright notices.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice(s), this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
-.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
-.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_attr.3,v 1.4.2.5 2001/08/17 15:42:51 ru Exp $
-.Dd April 28, 2000
-.Dt PTHREAD_ATTR 3
-.Os
-.Sh NAME
-.Nm pthread_attr_destroy ,
-.Nm pthread_attr_getdetachstate ,
-.Nm pthread_attr_getinheritsched ,
-.Nm pthread_attr_getschedparam ,
-.Nm pthread_attr_getschedpolicy ,
-.Nm pthread_attr_getscope ,
-.Nm pthread_attr_getstackaddr ,
-.Nm pthread_attr_getstacksize ,
-.Nm pthread_attr_init ,
-.Nm pthread_attr_setdetachstate ,
-.Nm pthread_attr_setinheritsched ,
-.Nm pthread_attr_setschedparam ,
-.Nm pthread_attr_setschedpolicy ,
-.Nm pthread_attr_setscope ,
-.Nm pthread_attr_setstackaddr ,
-.Nm pthread_attr_setstacksize
-.Nd thread attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_attr_destroy
-.Fa "pthread_attr_t *attr"
-.Fc
-.Ft int
-.Fo pthread_attr_getdetachstate
-.Fa "const pthread_attr_t *attr"
-.Fa "int *detachstate"
-.Fc
-.Ft int
-.Fo pthread_attr_getinheritsched
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "int *restrict inheritsched"
-.Fc
-.Ft int
-.Fo pthread_attr_getschedparam
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "struct sched_param *restrict param"
-.Fc
-.Ft int
-.Fo pthread_attr_getschedpolicy
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "int *restrict policy"
-.Fc
-.Ft int
-.Fo pthread_attr_getscope
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "int *restrict contentionscope"
-.Fc
-.Ft int
-.Fo pthread_attr_getstackaddr
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "void **restrict stackaddr"
-.Fc
-.Ft int
-.Fo pthread_attr_getstacksize
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "size_t *restrict stacksize"
-.Fc
-.Ft int
-.Fo pthread_attr_init
-.Fa "pthread_attr_t *attr"
-.Fc
-.Ft int
-.Fo pthread_attr_setdetachstate
-.Fa "pthread_attr_t *attr"
-.Fa "int detachstate"
-.Fc
-.Ft int
-.Fo pthread_attr_setinheritsched
-.Fa "pthread_attr_t *attr"
-.Fa "int inheritsched"
-.Fc
-.Ft int
-.Fo pthread_attr_setschedparam
-.Fa "pthread_attr_t *restrict attr"
-.Fa "const struct sched_param *restrict param"
-.Fc
-.Ft int
-.Fo pthread_attr_setschedpolicy
-.Fa "pthread_attr_t *attr"
-.Fa "int policy"
-.Fc
-.Ft int
-.Fo pthread_attr_setscope
-.Fa "pthread_attr_t *attr"
-.Fa "int contentionscope"
-.Fc
-.Ft int
-.Fo pthread_attr_setstackaddr
-.Fa "pthread_attr_t *attr"
-.Fa "void *stackaddr"
-.Fc
-.Ft int
-.Fo pthread_attr_setstacksize
-.Fa "pthread_attr_t *attr"
-.Fa "size_t stacksize"
-.Fc
-.Sh DESCRIPTION
-Thread attributes are used to specify parameters to
-.Fn pthread_create .
-One attribute object can be used in multiple calls to
-.Fn pthread_create ,
-with or without modifications between calls.
-.Pp
-The
-.Fn pthread_attr_init
-function initializes
-.Fa attr
-with all the default thread attributes.
-.Pp
-The
-.Fn pthread_attr_destroy
-function destroys
-.Fa attr .
-.Pp
-The
-.Fn pthread_attr_set*
-functions set the attribute that corresponds to each function name.
-.Pp
-The
-.Fn pthread_attr_get*
-functions copy the value of the attribute that corresponds to each function name
-to the location pointed to by the second function parameter.
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_attr_init
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er ENOMEM
-Out of memory.
-.El
-.Pp
-.Fn pthread_attr_destroy
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Fn pthread_attr_setstacksize
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.It Bq Er EINVAL
-.Fa stacksize
-is less than
-.Dv PTHREAD_STACK_MIN .
-.\" ========
-.It Bq Er EINVAL
-.Fa stacksize
-is not a multiple of the system page size.
-.El
-.Pp
-.Fn pthread_attr_setdetachstate
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr
-or
-.Fa detachstate .
-.El
-.Pp
-.Fn pthread_attr_setinheritsched
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Fn pthread_attr_setschedparam
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.It Bq Er ENOTSUP
-Invalid value for
-.Fa param .
-.El
-.Pp
-.Fn pthread_attr_setschedpolicy
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.It Bq Er ENOTSUP
-Invalid or unsupported value for
-.Fa policy .
-.El
-.Pp
-.Fn pthread_attr_setscope
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.It Bq Er ENOTSUP
-Invalid or unsupported value for
-.Fa contentionscope .
-.El
-.Sh SEE ALSO
-.Xr pthread_create 3
-.Sh STANDARDS
-.Fn pthread_attr_init ,
-.Fn pthread_attr_destroy ,
-.Fn pthread_attr_setstacksize ,
-.Fn pthread_attr_getstacksize ,
-.Fn pthread_attr_setstackaddr ,
-.Fn pthread_attr_getstackaddr ,
-.Fn pthread_attr_setdetachstate ,
-and
-.Fn pthread_attr_getdetachstate
-conform to
-.St -p1003.1-96
-.Pp
-.Fn pthread_attr_setinheritsched ,
-.Fn pthread_attr_getinheritsched ,
-.Fn pthread_attr_setschedparam ,
-.Fn pthread_attr_getschedparam ,
-.Fn pthread_attr_setschedpolicy ,
-.Fn pthread_attr_getschedpolicy ,
-.Fn pthread_attr_setscope ,
-and
-.Fn pthread_attr_getscope
-conform to
-.St -susv2
+++ /dev/null
-.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved.
-.Dd December 31, 2007
-.Dt PTHREAD_ATTR 3
-.Os
-.Sh NAME
-.Nm pthread_attr_destroy ,
-.Nm pthread_attr_init
-.Nd thread attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_attr_destroy
-.Fa "pthread_attr_t *attr"
-.Fc
-.Ft int
-.Fo pthread_attr_init
-.Fa "pthread_attr_t *attr"
-.Fc
-.Sh DESCRIPTION
-Thread attributes are used to specify parameters to
-.Fn pthread_create .
-One attribute object can be used in multiple calls to
-.Fn pthread_create ,
-with or without modifications between calls.
-.Pp
-The
-.Fn pthread_attr_init
-function initializes
-.Fa attr
-with all the default thread attributes.
-.Pp
-The
-.Fn pthread_attr_destroy
-function destroys
-.Fa attr .
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_attr_init
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er ENOMEM
-Out of memory.
-.El
-.Pp
-.Fn pthread_attr_destroy
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Sh SEE ALSO
-.Xr pthread_create 3
-.Sh STANDARDS
-.Fn pthread_attr_init ,
-.Fn pthread_attr_destroy
-conform to
-.St -p1003.1-96
-.Pp
+++ /dev/null
-.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved.
-.Dd December 31, 2007
-.Dt PTHREAD_ATTR 3
-.Os
-.Sh NAME
-.Nm pthread_attr_getdetachstate ,
-.Nm pthread_attr_setdetachstate
-.Nd thread attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_attr_getdetachstate
-.Fa "const pthread_attr_t *attr"
-.Fa "int *detachstate"
-.Fc
-.Ft int
-.Fo pthread_attr_setdetachstate
-.Fa "pthread_attr_t *attr"
-.Fa "int detachstate"
-.Fc
-.Sh DESCRIPTION
-Thread attributes are used to specify parameters to
-.Fn pthread_create .
-One attribute object can be used in multiple calls to
-.Fn pthread_create ,
-with or without modifications between calls.
-.Pp
-One of these thread attributes governs the creation state of the new thread. The new thread
-can be either created "detached" or "joinable". The constants corresponding to these states are PTHREAD_CREATE_DETACHED and PTHREAD_CREATE_JOINABLE respectively.
-Creating a "joinable" thread allows the user
-to call
-.Fn pthread_join
-and
-.Fn pthread_detach ,
-with the new thread's ID. A "detached" thread's ID cannot be used with
-.Fn pthread_join
-and
-.Fn pthread_detach .
-The default value for the "detachstate" attribute is PTHREAD_CREATE_JOINABLE.
-.Pp
-The
-.Fn pthread_attr_setdetachstate
-function sets the thread's "detachstate" attribute.
-.Pp
-The "detachstate" attribute is set within the
-.Fa attr
-argument, which can subsequently be used as an argument to
-.Fn pthread_create .
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Fn pthread_attr_getdetachstate ,
-on success, will copy the value of the thread's "detachstate" attribute
-to the location pointed to by the second function parameter.
-.Sh ERRORS
-.Fn pthread_attr_getdetachstate
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr
-.El
-.Pp
-.Fn pthread_attr_setdetachstate
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr
-or
-.Fa detachstate .
-.El
-.Pp
-.Sh SEE ALSO
-.Xr pthread_create 3 ,
-.Xr pthread_join 3 ,
-.Xr pthread_attr_init 3 ,
-.Xr pthread_detach 3
-.Sh STANDARDS
-.Fn pthread_attr_setdetachstate ,
-.Fn pthread_attr_getdetachstate
-conform to
-.St -p1003.1-96
-.Pp
+++ /dev/null
-.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved.
-.Dd December 31, 2007
-.Dt PTHREAD_ATTR 3
-.Os
-.Sh NAME
-.Nm pthread_attr_getinheritsched ,
-.Nm pthread_attr_setinheritsched
-.Nd thread attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_attr_getinheritsched
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "int *restrict inheritsched"
-.Fc
-.Ft int
-.Fo pthread_attr_setinheritsched
-.Fa "pthread_attr_t *attr"
-.Fa "int inheritsched"
-.Fc
-.Sh DESCRIPTION
-Thread attributes are used to specify parameters to
-.Fn pthread_create .
-One attribute object can be used in multiple calls to
-.Fn pthread_create ,
-with or without modifications between calls.
-.Pp
-One of the thread attributes of interest is the "inheritsched" attribute. This attribute
-controls the scheduling policy and related attributes of the newly created thread. The values of the
-"inheritsched" attribute can be either PTHREAD_INHERIT_SCHED or PTHREAD_EXPLICIT_SCHED.
-.Pp
-PTHREAD_INHERIT_SCHED
-.Pp
- Indicates that the newly created thread should inherit all it's scheduling related attributes from it's creating
-thread. It ignores the values of the relevant attributes within the
-.Fa attr
-argument.
-.Pp
-PTHREAD_EXPLICIT_SCHED
-.Pp
- Indicates that the newly created thread should set it's scheduling related attributes based on
-.Fa attr
-argument.
-.Pp
-The
-.Fn pthread_attr_setinheritsched
-functions set the "inheritsched" attribute within the
-.Fa attr
-argument to the desired value.
-.Pp
-The
-.Fn pthread_attr_getinheritsched
-functions copy the value of the "inheritsched" attribute to the location pointed to by the second function parameter.
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Sh ERRORS
-.Pp
-.Fn pthread_attr_getinheritsched
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Fn pthread_attr_setinheritsched
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Sh SEE ALSO
-.Xr pthread_create 3 ,
-.Xr pthread_attr_init 3 ,
-.Xr pthread_attr_setschedparam 3
-.Sh STANDARDS
-.Pp
-.Fn pthread_attr_setinheritsched ,
-.Fn pthread_attr_getinheritsched
-conform to
-.St -susv2
+++ /dev/null
-.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved.
-.Dd December 31, 2007
-.Dt PTHREAD_ATTR 3
-.Os
-.Sh NAME
-.Nm pthread_attr_getschedparam ,
-.Nm pthread_attr_setschedparam
-.Nd thread attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_attr_getschedparam
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "struct sched_param *restrict param"
-.Fc
-.Ft int
-.Fo pthread_attr_setschedparam
-.Fa "pthread_attr_t *restrict attr"
-.Fa "const struct sched_param *restrict param"
-.Fc
-.Sh DESCRIPTION
-Thread attributes are used to specify parameters to
-.Fn pthread_create .
-One attribute object can be used in multiple calls to
-.Fn pthread_create ,
-with or without modifications between calls.
-.Pp
-.Fn pthread_attr_getschedparam
-and
-.Fn pthread_attr_setschedparam
-get and set the scheduling parameters within the
-.Fa attr
-argument. See
-.Fd /usr/include/sched.h
-for the definition of
-.Fa struct sched_param .
-The
-.Fa sched_priority
-field of
-.Fa struct sched_param
-can be set to SCHED_OTHER, SCHED_FIFO and SCHED_RR.
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Fn pthread_attr_getschedparam ,
-on success, will copy the value of the thread's scheduling parameter attribute
-to the location pointed to by the second function parameter.
-.Sh ERRORS
-.Pp
-.Fn pthread_attr_getschedparam
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.El
-.Pp
-.Fn pthread_attr_setschedparam
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.It Bq Er ENOTSUP
-Invalid value for
-.Fa param .
-.El
-.Sh SEE ALSO
-.Xr pthread_create 3 ,
-.Xr pthread_attr_init 3 ,
-.Xr pthread_attr_setinheritsched 3
-.Sh STANDARDS
-.Pp
-.Fn pthread_attr_setschedparam ,
-.Fn pthread_attr_getschedparam
-conform to
-.St -susv2
+++ /dev/null
-.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved.
-.Dd December 31, 2007
-.Dt PTHREAD_ATTR 3
-.Os
-.Sh NAME
-.Nm pthread_attr_getschedpolicy ,
-.Nm pthread_attr_setschedpolicy
-.Nd thread attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_attr_getschedpolicy
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "int *restrict policy"
-.Fc
-.Ft int
-.Fo pthread_attr_setschedpolicy
-.Fa "pthread_attr_t *attr"
-.Fa "int policy"
-.Fc
-.Sh DESCRIPTION
-Thread attributes are used to specify parameters to
-.Fn pthread_create .
-One attribute object can be used in multiple calls to
-.Fn pthread_create ,
-with or without modifications between calls.
-.Pp
-The functions
-.Fn pthread_attr_setschedpolicy
-and
-.Fn pthread_attr_getschedpolicy ,
-set and get the attribute in the
-.Fa attr
-argument related to the scheduling policy.
-The value for the aforementioned attribute can be SCHED_FIFO, SCHED_RR and SCHED_OTHER.
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Fn pthread_attr_getschedpolicy ,
-on success, will copy the value of the thread's scheduling policy attribute
-to the location pointed to by the second function parameter.
-.Sh ERRORS
-.Pp
-.Fn pthread_attr_getschedpolicy
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Fn pthread_attr_setschedpolicy
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.It Bq Er ENOTSUP
-Invalid or unsupported value for
-.Fa policy .
-.El
-.Sh SEE ALSO
-.Xr pthread_create 3 ,
-.Xr pthread_attr_init 3 ,
-.Xr pthread_attr_setschedparam 3 ,
-.Xr pthread_attr_setinheritsched 3
-.Sh STANDARDS
-.Fn pthread_attr_setschedpolicy ,
-.Fn pthread_attr_getschedpolicy
-conform to
-.St -susv2
+++ /dev/null
-.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved.
-.Dd December 31, 2007
-.Dt PTHREAD_ATTR 3
-.Os
-.Sh NAME
-.Nm pthread_attr_getscope ,
-.Nm pthread_attr_setscope
-.Nd thread attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_attr_getscope
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "int *restrict contentionscope"
-.Fc
-.Ft int
-.Fo pthread_attr_setscope
-.Fa "pthread_attr_t *attr"
-.Fa "int contentionscope"
-.Fc
-.Sh DESCRIPTION
-Thread attributes are used to specify parameters to
-.Fn pthread_create .
-One attribute object can be used in multiple calls to
-.Fn pthread_create ,
-with or without modifications between calls.
-.Pp
-The
-.Fn pthread_attr_setscope
-and
-.Fn pthread_attr_getscope
-functions, respectively, set and get the attribute within
-.Fa attr
-argument that controls the contention scope of the thread.
-The acceptable values are PTHREAD_SCOPE_SYSTEM, indicating a scheduling contention scope that
-is system-wide, and PTHREAD_SCOPE_PROCESS, which indicates a process scheduling contention scope.
-Currently on Mac OS X we only support PTHREAD_SCOPE_SYSTEM.
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Sh ERRORS
-.Pp
-.Fn pthread_attr_getscope
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.El
-.Pp
-.Fn pthread_attr_setscope
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.It Bq Er ENOTSUP
-Invalid or unsupported value for
-.Fa contentionscope .
-.El
-.Sh SEE ALSO
-.Xr pthread_create 3 ,
-.Xr pthread_attr_init 3 ,
-.Xr pthread_attr_setinheritsched 3 ,
-.Xr pthread_attr_setschedpolicy 3 ,
-.Xr pthread_attr_setschedparam 3
-.Sh STANDARDS
-.Fn pthread_attr_setscope ,
-.Fn pthread_attr_getscope
-conform to
-.St -susv2
+++ /dev/null
-.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved.
-.Dd December 31, 2007
-.Dt PTHREAD_ATTR 3
-.Os
-.Sh NAME
-.Nm pthread_attr_getstackaddr ,
-.Nm pthread_attr_setstackaddr
-.Nd thread attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_attr_getstackaddr
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "void **restrict stackaddr"
-.Fc
-.Ft int
-.Fo pthread_attr_setstackaddr
-.Fa "pthread_attr_t *attr"
-.Fa "void *stackaddr"
-.Fc
-.Sh DESCRIPTION
-Thread attributes are used to specify parameters to
-.Fn pthread_create .
-One attribute object can be used in multiple calls to
-.Fn pthread_create ,
-with or without modifications between calls.
-.Pp
-The functions
-.Fn pthread_attr_setstackaddr
-and
-.Fn pthread_attr_getstackaddr
-respectively, set and get the address at which the stack of the newly created thread should be located.
-The stackaddr attribute is set within the
-.Fa attr
-argument, which can subsequently be used as an argument to
-.Fn pthread_create .
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Fn pthread_attr_getstackaddr
-returns the stackaddr attribute value in
-.Fa stackaddr
-if successful.
-.Sh ERRORS
-.Fn pthread_attr_setstackaddr
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.El
-.Pp
-.Fn pthread_attr_getstackaddr
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.El
-.Pp
-.Sh SEE ALSO
-.Xr pthread_create 3 ,
-.Xr pthread_attr_init 3 ,
-.Xr pthread_attr_setdetachstate 3 ,
-.Xr pthread_attr_setstacksize 3
-.Sh STANDARDS
-.Fn pthread_attr_setstackaddr ,
-.Fn pthread_attr_getstackaddr ,
-conform to
-.St -p1003.1-96
+++ /dev/null
-.\" Copyright (c) 2004-2007 Apple Inc. All rights reserved.
-.Dd December 31, 2007
-.Dt PTHREAD_ATTR 3
-.Os
-.Sh NAME
-.Nm pthread_attr_getstacksize ,
-.Nm pthread_attr_setstacksize
-.Nd thread attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_attr_getstacksize
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "size_t *restrict stacksize"
-.Fc
-.Ft int
-.Fo pthread_attr_setstacksize
-.Fa "pthread_attr_t *attr"
-.Fa "size_t stacksize"
-.Fc
-.Sh DESCRIPTION
-Thread attributes are used to specify parameters to
-.Fn pthread_create .
-One attribute object can be used in multiple calls to
-.Fn pthread_create ,
-with or without modifications between calls.
-.Pp
-The functions
-.Fn pthread_attr_setstacksize
-and
-.Fn pthread_attr_getstacksize ,
-respectively, set and get the size of the stack that is to be created for the new thread. The stack size attribute is set within the
-.Fa attr
-argument, which can subsequently be used as an argument to
-.Fn pthread_create .
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Fn pthread_attr_getstacksize
-returns the stacksize attribute value in
-.Fa stacksize
-if successful.
-.Sh ERRORS
-.Fn pthread_attr_getstacksize
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Fn pthread_attr_setstacksize
-will fail if:
-.Bl -tag -width Er
-.\" ========
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.\" ========
-.It Bq Er EINVAL
-.Fa stacksize
-is less than
-.Dv PTHREAD_STACK_MIN .
-.\" ========
-.It Bq Er EINVAL
-.Fa stacksize
-is not a multiple of the system page size.
-.El
-.Sh SEE ALSO
-.Xr pthread_create 3 ,
-.Xr pthread_attr_init 3 ,
-.Xr pthread_attr_setstackaddr 3
-.Sh STANDARDS
-.Fn pthread_attr_setstacksize ,
-.Fn pthread_attr_getstacksize
-conform to
-.St -p1003.1-96
+++ /dev/null
-.\" $FreeBSD: src/lib/libc_r/man/pthread_cancel.3,v 1.3.2.3 2001/03/06 16:46:08 ru Exp $
-.Dd January 17, 1999
-.Dt PTHREAD_CANCEL 3
-.Os
-.Sh NAME
-.Nm pthread_cancel
-.Nd cancel execution of a thread
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fn pthread_cancel "pthread_t thread"
-.Sh DESCRIPTION
-The
-.Fn pthread_cancel
-function requests that
-.Fa thread
-be canceled.
-The target thread's cancelability state and type determines
-when the cancellation takes effect.
-When the cancellation is acted on,
-the cancellation cleanup handlers for
-.Fa thread
-are called.
-When the last cancellation cleanup handler returns,
-the thread-specific data destructor functions will be called for
-.Fa thread .
-When the last destructor function returns,
-.Fa thread
-will be terminated.
-.Pp
-The cancellation processing in the target thread runs asynchronously with
-respect to the calling thread returning from
-.Fn pthread_cancel .
-.Pp
-A status of
-.Dv PTHREAD_CANCELED
-is made available to any threads joining with the target.
-The symbolic
-constant
-.Dv PTHREAD_CANCELED
-expands to a constant expression of type
-.Ft "(void *)" ,
-whose value matches no pointer to an object in memory nor the value
-.Dv NULL .
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_cancel
-functions will return zero.
-Otherwise an error number will be returned to
-indicate the error.
-.Sh ERRORS
-.Fn pthread_cancel
-will fail if:
-.Bl -tag -width Er
-.It Bq Er ESRCH
-No thread could be found corresponding to that specified by the given
-thread ID.
-.El
-.Sh SEE ALSO
-.Xr pthread_cleanup_pop 3 ,
-.Xr pthread_cleanup_push 3 ,
-.Xr pthread_exit 3 ,
-.Xr pthread_join 3 ,
-.Xr pthread_setcancelstate 3 ,
-.Xr pthread_setcanceltype 3 ,
-.Xr pthread_testcancel 3
-.Sh STANDARDS
-.Fn pthread_cancel
-conforms to
-.St -p1003.1-96 .
-.Sh AUTHORS
-This man page was written by
-.An David Leonard Aq d@openbsd.org
-for the
-.Ox
-implementation of
-.Fn pthread_cancel .
+++ /dev/null
-/*
- * Copyright (c) 2000-2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * POSIX Pthread Library
- */
-
-#include "pthread_internals.h"
-
-#include <assert.h>
-#include <stdio.h> /* For printf(). */
-#include <stdlib.h>
-#include <errno.h> /* For __mach_errno_addr() prototype. */
-#include <signal.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/sysctl.h>
-#include <sys/queue.h>
-#include <machine/vmparam.h>
-#include <mach/vm_statistics.h>
-
-extern int __unix_conforming;
-extern void __posix_join_cleanup(void *arg);
-extern pthread_lock_t _pthread_list_lock;
-extern void _pthread_testcancel(pthread_t thread, int isconforming);
-extern int _pthread_reap_thread(pthread_t th, mach_port_t kernel_thread, void **value_ptr, int conforming);
-extern int _pthread_cond_wait(pthread_cond_t *cond,
- pthread_mutex_t *mutex,
- const struct timespec *abstime,
- int isRelative,
- int isconforming);
-extern int __sigwait(const sigset_t *set, int *sig);
-
-#ifdef VARIANT_CANCELABLE
-extern int __semwait_signal(int cond_sem, int mutex_sem, int timeout, int relative, __int64_t tv_sec, __int32_t tv_nsec);
-#else
-extern int __semwait_signal(int cond_sem, int mutex_sem, int timeout, int relative, __int64_t tv_sec, __int32_t tv_nsec) __asm__("___semwait_signal_nocancel");
-#endif
-
-/*
- * Wait for a thread to terminate and obtain its exit value.
- */
-int
-pthread_join(pthread_t thread,
- void **value_ptr)
-{
- int res = 0;
- pthread_t self = pthread_self();
- mach_port_t kthport;
- int conforming = 0;
-#if !__DARWIN_UNIX03
- kern_return_t kern_res;
-#endif
-
-#if __DARWIN_UNIX03
- if (__unix_conforming == 0)
- __unix_conforming = 1;
-
-#ifdef VARIANT_CANCELABLE
- _pthread_testcancel(self, 1);
-#endif /* VARIANT_CANCELABLE */
-#endif /* __DARWIN_UNIX03 */
-
- if ((res = _pthread_lookup_thread(thread, &kthport, 1)) != 0)
- return(res);
-
- if (thread->sig == _PTHREAD_SIG)
- {
- if (thread->newstyle == 0) {
- semaphore_t death = new_sem_from_pool(); /* in case we need it */
-
- LOCK(thread->lock);
- if ((thread->detached & PTHREAD_CREATE_JOINABLE) &&
- thread->death == SEMAPHORE_NULL)
- {
-
- assert(thread->joiner == NULL);
- if (thread != self && (self == NULL || self->joiner != thread))
- {
- int already_exited = (thread->detached & _PTHREAD_EXITED);
-
- thread->death = death;
- thread->joiner = self;
- UNLOCK(thread->lock);
-
- if (!already_exited)
- {
-#if __DARWIN_UNIX03
- /* Wait for it to signal... */
- pthread_cleanup_push(__posix_join_cleanup, (void *)thread);
- do {
- res = __semwait_signal(death, 0, 0, 0, (int64_t)0, (int32_t)0);
- } while ((res < 0) && (errno == EINTR));
- pthread_cleanup_pop(0);
-
-#else /* __DARWIN_UNIX03 */
- /* Wait for it to signal... */
- do {
- PTHREAD_MACH_CALL(semaphore_wait(death), kern_res);
- } while (kern_res != KERN_SUCCESS);
-#endif /* __DARWIN_UNIX03 */
- }
-
- LOCK(_pthread_list_lock);
- TAILQ_REMOVE(&__pthread_head, thread, plist);
-#if WQ_TRACE
- __kdebug_trace(0x9000010, thread, 0, 0, 16, 0);
-#endif
- UNLOCK(_pthread_list_lock);
- /* ... and wait for it to really be dead */
- while ((res = _pthread_reap_thread(thread,
- thread->kernel_thread,
- value_ptr, __unix_conforming)) == EAGAIN)
- {
- sched_yield();
- }
-
- } else {
- UNLOCK(thread->lock);
- res = EDEADLK;
- }
- } else {
- UNLOCK(thread->lock);
- res = EINVAL;
- }
- restore_sem_to_pool(death);
- return res;
- } else {
- /* new style */
-
- semaphore_t death = SEMAPHORE_NULL; /* in case we need it */
- semaphore_t joinsem = SEMAPHORE_NULL;
-
- if (thread->joiner_notify == MACH_PORT_NULL)
- death = new_sem_from_pool();
-
- LOCK(thread->lock);
- if ((thread->detached & PTHREAD_CREATE_JOINABLE) &&
- (thread->joiner == NULL))
- {
- assert(thread->kernel_thread == kthport);
- if (thread != self && (self == NULL || self->joiner != thread))
- {
- if (thread->joiner_notify == MACH_PORT_NULL) {
- if (death == SEMAPHORE_NULL)
- LIBC_ABORT("thread %p: death == SEMAPHORE_NULL", thread);
- thread->joiner_notify = death;
- death = SEMAPHORE_NULL;
- }
- joinsem = thread->joiner_notify;
- thread->joiner = self;
- UNLOCK(thread->lock);
-
- if (death != SEMAPHORE_NULL) {
- restore_sem_to_pool(death);
- death = SEMAPHORE_NULL;
- }
-#if __DARWIN_UNIX03
- /* Wait for it to signal... */
- pthread_cleanup_push(__posix_join_cleanup, (void *)thread);
- do {
- res = __semwait_signal(joinsem, 0, 0, 0, (int64_t)0, (int32_t)0);
- } while ((res < 0) && (errno == EINTR));
- pthread_cleanup_pop(0);
-#else /* __DARWIN_UNIX03 */
- /* Wait for it to signal... */
- do {
- PTHREAD_MACH_CALL(semaphore_wait(joinsem), kern_res);
- } while (kern_res != KERN_SUCCESS);
-#endif /* __DARWIN_UNIX03 */
-
- restore_sem_to_pool(joinsem);
- res = _pthread_join_cleanup(thread, value_ptr, conforming);
- } else {
- UNLOCK(thread->lock);
- res = EDEADLK;
- }
- } else {
- UNLOCK(thread->lock);
- res = EINVAL;
- }
- if (death != SEMAPHORE_NULL)
- restore_sem_to_pool(death);
- return res;
- }/* end of new style */
- }
- return ESRCH;
-}
-
-int
-pthread_cond_wait(pthread_cond_t *cond,
- pthread_mutex_t *mutex)
-{
- int conforming;
-#if __DARWIN_UNIX03
-
- if (__unix_conforming == 0)
- __unix_conforming = 1;
-
-#ifdef VARIANT_CANCELABLE
- conforming = 1;
-#else /* !VARIANT_CANCELABLE */
- conforming = -1;
-#endif /* VARIANT_CANCELABLE */
-#else /* __DARWIN_UNIX03 */
- conforming = 0;
-#endif /* __DARWIN_UNIX03 */
- return (_pthread_cond_wait(cond, mutex, (struct timespec *)NULL, 0, conforming));
-}
-
-int
-pthread_cond_timedwait(pthread_cond_t *cond,
- pthread_mutex_t *mutex,
- const struct timespec *abstime)
-{
- int conforming;
-#if __DARWIN_UNIX03
- if (__unix_conforming == 0)
- __unix_conforming = 1;
-
-#ifdef VARIANT_CANCELABLE
- conforming = 1;
-#else /* !VARIANT_CANCELABLE */
- conforming = -1;
-#endif /* VARIANT_CANCELABLE */
-#else /* __DARWIN_UNIX03 */
- conforming = 0;
-#endif /* __DARWIN_UNIX03 */
-
- return (_pthread_cond_wait(cond, mutex, abstime, 0, conforming));
-}
-
-int
-sigwait(const sigset_t * set, int * sig)
-{
-#if __DARWIN_UNIX03
- int err = 0;
-
- if (__unix_conforming == 0)
- __unix_conforming = 1;
-
-#ifdef VARIANT_CANCELABLE
- _pthread_testcancel(pthread_self(), 1);
-#endif /* VARIANT_CANCELABLE */
-
- if (__sigwait(set, sig) == -1) {
- err = errno;
-
-#ifdef VARIANT_CANCELABLE
- _pthread_testcancel(pthread_self(), 1);
-#endif /* VARIANT_CANCELABLE */
-
- /*
- * EINTR that isn't a result of pthread_cancel()
- * is translated to 0.
- */
- if (err == EINTR) {
- err = 0;
- }
- }
- return(err);
-#else /* __DARWIN_UNIX03 */
- if (__sigwait(set, sig) == -1) {
- /*
- * EINTR that isn't a result of pthread_cancel()
- * is translated to 0.
- */
- if (errno != EINTR) {
- return -1;
- }
- }
-
- return 0;
-#endif /* __DARWIN_UNIX03 */
-}
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_cleanup_pop.3,v 1.5.2.3 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 30, 1998
-.Dt PTHREAD_CLEANUP_POP 3
-.Os
-.Sh NAME
-.Nm pthread_cleanup_pop
-.Nd call the first cleanup routine
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft void
-.Fn pthread_cleanup_pop "int execute"
-.Sh DESCRIPTION
-The
-.Fn pthread_cleanup_pop
-function pops the top cleanup routine off
-of the current thread's cleanup routine stack and, if
-.Fa execute
-is non-zero, it will execute the function.
-If there is no cleanup routine,
-.Fn pthread_cleanup_pop
-does nothing.
-.Pp
-.Fn pthread_cleanup_pop
-must be paired with a corresponding
-.Xr pthread_cleanup_push 3
-in the same lexical scope.
-.Sh RETURN VALUES
-.Fn pthread_cleanup_pop
-does not return any value.
-.Sh ERRORS
-None
-.Sh SEE ALSO
-.Xr pthread_cleanup_push 3 ,
-.Xr pthread_exit 3
-.Sh STANDARDS
-.Fn pthread_cleanup_pop
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_cleanup_push.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 30, 1998
-.Dt PTHREAD_CLEANUP_PUSH 3
-.Os
-.Sh NAME
-.Nm pthread_cleanup_push
-.Nd add a cleanup function for thread exit
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft void
-.Fo pthread_cleanup_push
-.Fa "void \*[lp]*routine\*[rp]\*[lp]void *\*[rp]"
-.Fa "void *arg"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_cleanup_push
-function adds
-.Fa routine
-to the top of the stack of cleanup handlers that
-get called when the current thread exits.
-.Pp
-When
-.Fa routine
-is called, it is passed
-.Fa arg
-as its only argument.
-.Fn pthread_cleanup_push
-must be paired with a corresponding
-.Xr pthread_cleanup_pop 3
-in the same lexical scope.
-.Sh RETURN VALUES
-.Fn pthread_cleanup_push
-does not return any value.
-.Sh ERRORS
-None
-.Sh SEE ALSO
-.Xr pthread_cleanup_pop 3 ,
-.Xr pthread_exit 3
-.Sh STANDARDS
-.Fn pthread_cleanup_push
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-/*
- * Copyright (c) 2000-2003, 2007, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-/*
- * MkLinux
- */
-
-/*
- * POSIX Pthread Library
- */
-
-#include "pthread_internals.h"
-#include <sys/time.h> /* For struct timespec and getclock(). */
-#include <stdio.h>
-
-#ifdef PLOCKSTAT
-#include "plockstat.h"
-#else /* !PLOCKSTAT */
-#define PLOCKSTAT_MUTEX_RELEASE(x, y)
-#endif /* PLOCKSTAT */
-
-extern int _pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *, int);
-extern int __unix_conforming;
-extern int usenew_mtximpl;
-
-#ifdef PR_5243343
-/* 5243343 - temporary hack to detect if we are running the conformance test */
-extern int PR_5243343_flag;
-#endif /* PR_5243343 */
-
-__private_extern__ int _pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime, int isRelative, int isconforming);
-#ifndef BUILDING_VARIANT
-static void cond_cleanup(void *arg);
-static void cond_dropwait(npthread_cond_t * cond, int error, uint32_t updateval);
-static void __pthread_cond_set_signature(npthread_cond_t * cond);
-static int _pthread_cond_destroy_locked(pthread_cond_t *cond);
-#endif
-
-#if defined(__LP64__)
-#define COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt) \
-{ \
- if (cond->misalign != 0) { \
- c_lseqcnt = &cond->c_seq[1]; \
- c_sseqcnt = &cond->c_seq[2]; \
- c_useqcnt = &cond->c_seq[0]; \
- } else { \
- /* aligned */ \
- c_lseqcnt = &cond->c_seq[0]; \
- c_sseqcnt = &cond->c_seq[1]; \
- c_useqcnt = &cond->c_seq[2]; \
- } \
-}
-#else /* __LP64__ */
-#define COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt) \
-{ \
- if (cond->misalign != 0) { \
- c_lseqcnt = &cond->c_seq[1]; \
- c_sseqcnt = &cond->c_seq[2]; \
- c_useqcnt = &cond->c_seq[0]; \
- } else { \
- /* aligned */ \
- c_lseqcnt = &cond->c_seq[0]; \
- c_sseqcnt = &cond->c_seq[1]; \
- c_useqcnt = &cond->c_seq[2]; \
- } \
-}
-#endif /* __LP64__ */
-
-
-#define _KSYN_TRACE_ 0
-
-#if _KSYN_TRACE_
-/* The Function qualifiers */
-#define DBG_FUNC_START 1
-#define DBG_FUNC_END 2
-#define DBG_FUNC_NONE 0
-
-int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
-
-#define _KSYN_TRACE_UM_LOCK 0x9000060
-#define _KSYN_TRACE_UM_UNLOCK 0x9000064
-#define _KSYN_TRACE_UM_MHOLD 0x9000068
-#define _KSYN_TRACE_UM_MDROP 0x900006c
-#define _KSYN_TRACE_UM_CVWAIT 0x9000070
-#define _KSYN_TRACE_UM_CVSIG 0x9000074
-#define _KSYN_TRACE_UM_CVBRD 0x9000078
-#define _KSYN_TRACE_UM_CDROPWT 0x90000a0
-#define _KSYN_TRACE_UM_CVCLRPRE 0x90000a4
-
-#endif /* _KSYN_TRACE_ */
-
-
-#ifndef BUILDING_VARIANT /* [ */
-
-int
-pthread_condattr_init(pthread_condattr_t *attr)
-{
- attr->sig = _PTHREAD_COND_ATTR_SIG;
- attr->pshared = _PTHREAD_DEFAULT_PSHARED;
- return (0);
-}
-
-int
-pthread_condattr_destroy(pthread_condattr_t *attr)
-{
- attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */
- return (0);
-}
-
-int
-pthread_condattr_getpshared(const pthread_condattr_t *attr,
- int *pshared)
-{
- if (attr->sig == _PTHREAD_COND_ATTR_SIG)
- {
- *pshared = (int)attr->pshared;
- return (0);
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-
-
-
-/* temp home till pshared is fixed correctly */
-int
-pthread_condattr_setpshared(pthread_condattr_t * attr, int pshared)
-{
-
- if (attr->sig == _PTHREAD_COND_ATTR_SIG)
- {
-#if __DARWIN_UNIX03
- if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED))
-#else /* __DARWIN_UNIX03 */
- if ( pshared == PTHREAD_PROCESS_PRIVATE)
-#endif /* __DARWIN_UNIX03 */
- {
- attr->pshared = pshared;
- return (0);
- } else {
- return (EINVAL); /* Invalid parameter */
- }
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-
-}
-
-__private_extern__ int
-_pthread_cond_init(pthread_cond_t *ocond,
- const pthread_condattr_t *attr,
- int conforming)
-{
- npthread_cond_t * cond = (npthread_cond_t *)ocond;
-
- cond->busy = (npthread_mutex_t *)NULL;
- cond->c_seq[0] = 0;
- cond->c_seq[1] = 0;
- cond->c_seq[2] = 0;
- cond->rfu = 0;
-
- if (((uintptr_t)cond & 0x07) != 0) {
- cond->misalign = 1;
- cond->c_seq[2] = PTH_RWS_CV_CBIT;
- } else {
- cond->misalign = 0;
- cond->c_seq[1] = PTH_RWS_CV_CBIT; /* set Sword to 0c */
- }
- if (conforming) {
- if (attr)
- cond->pshared = attr->pshared;
- else
- cond->pshared = _PTHREAD_DEFAULT_PSHARED;
- } else
- cond->pshared = _PTHREAD_DEFAULT_PSHARED;
- /*
- * For the new style mutex, interlocks are not held all the time.
- * We needed the signature to be set in the end. And we need
- * to protect against the code getting reorganized by compiler.
- * cond->sig = _PTHREAD_COND_SIG;
- */
- __pthread_cond_set_signature(cond);
- return (0);
-}
-
-int
-pthread_cond_destroy(pthread_cond_t * ocond)
-{
- npthread_cond_t *cond = (npthread_cond_t *)ocond;
- int ret;
-
- /* to provide backwards compat for apps using united condtn vars */
- if((cond->sig != _PTHREAD_COND_SIG) && (cond->sig != _PTHREAD_COND_SIG_init))
- return(EINVAL);
-
- LOCK(cond->lock);
- ret = _pthread_cond_destroy_locked(ocond);
- UNLOCK(cond->lock);
-
- return(ret);
-}
-
-static int
-_pthread_cond_destroy_locked(pthread_cond_t * ocond)
-{
- npthread_cond_t *cond = (npthread_cond_t *)ocond;
- int ret;
- volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt;
- uint32_t lcntval , ucntval, scntval;
- uint64_t oldval64, newval64;
-
-retry:
- if (cond->sig == _PTHREAD_COND_SIG)
- {
- COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt);
- lcntval = *c_lseqcnt;
- ucntval = *c_useqcnt;
- scntval = *c_sseqcnt;
-
- if ((lcntval & PTHRW_COUNT_MASK) == (scntval & PTHRW_COUNT_MASK)) {
- /* validate it is not busy */
- oldval64 = (((uint64_t)scntval) << 32);
- oldval64 |= lcntval;
- newval64 = oldval64;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
- goto retry;
- cond->sig = _PTHREAD_NO_SIG;
- ret = 0;
- } else
- ret = EBUSY;
- } else if (cond->sig == _PTHREAD_COND_SIG_init) {
- cond->sig = _PTHREAD_NO_SIG;
- ret = 0;
- } else
- ret = EINVAL; /* Not an initialized condition variable structure */
- return (ret);
-}
-
-/*
- * Signal a condition variable, waking up all threads waiting for it.
- */
-int
-pthread_cond_broadcast(pthread_cond_t *ocond)
-{
- npthread_cond_t * cond = (npthread_cond_t *)ocond;
- int sig = cond->sig;
- uint32_t flags, updateval;
- uint32_t lcntval , ucntval, scntval;
- uint64_t oldval64, newval64, mugen, cvlsgen, cvudgen, mtid=0;
- int diffgen, error = 0;
- volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt;
- uint32_t * pmtx = NULL;
- uint32_t nlval, ulval;
- int needclearpre = 0, retry_count = 0, uretry_count = 0;
- int ucountreset = 0;
-
- /* to provide backwards compat for apps using united condtn vars */
- if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init))
- return(EINVAL);
-
- if (sig != _PTHREAD_COND_SIG)
- {
- LOCK(cond->lock);
- if (cond->sig == _PTHREAD_COND_SIG_init)
- {
- _pthread_cond_init(ocond, NULL, 0);
- /* just inited nothing to post */
- UNLOCK(cond->lock);
- return (0);
- } else if (cond->sig != _PTHREAD_COND_SIG) {
- /* Not a condition variable */
- UNLOCK(cond->lock);
- return (EINVAL);
- }
- UNLOCK(cond->lock);
- }
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_START, (uint32_t)cond, 0, 0, 0, 0);
-#endif
-
- COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt);
-retry:
- lcntval = *c_lseqcnt;
- ucntval = *c_useqcnt;
- scntval = *c_sseqcnt;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, scntval, 0);
-#endif
-
- if (((lcntval & PTHRW_COUNT_MASK) == (scntval & PTHRW_COUNT_MASK)) ||
- ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK))) {
- /* validate it is spurious and return */
- oldval64 = (((uint64_t)scntval) << 32);
- oldval64 |= lcntval;
- newval64 = oldval64;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
- goto retry;
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, 0xf1f1f1f1, 0);
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_END, (uint32_t)cond, scntval, 0, 0xf1f1f1f1, 0);
-#endif
- return(0);
- }
-
- /* validate to eliminate spurious values, race snapshots */
- if (is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
- /* since ucntval may be newer, just redo */
- retry_count++;
- if (retry_count > 8192) {
- return(EAGAIN);
- } else {
- sched_yield();
- goto retry;
- }
- } else if (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
- /* since ucntval may be newer, just redo */
- uretry_count++;
- if (uretry_count > 8192) {
- /*
- * U value if not used for a while can go out of sync
- * set this to S value and try one more time.
- */
- if (ucountreset != 0)
- return(EAGAIN);
- else
- if (OSAtomicCompareAndSwap32Barrier(ucntval, (scntval & PTHRW_COUNT_MASK), (volatile int32_t *)c_useqcnt) == TRUE) {
- /* now the U is reset to S value */
- ucountreset = 1;
- uretry_count = 0;
- }
- }
- sched_yield();
- goto retry;
- }
-
- if (is_seqlower(ucntval & PTHRW_COUNT_MASK, scntval & PTHRW_COUNT_MASK) != 0) {
- /* If U < S, set U = S+diff due to intr's TO, etc */
- ulval = (scntval & PTHRW_COUNT_MASK);
- } else {
- /* If U >= S, set U = U+diff due to intr's TO, etc */
- ulval = (ucntval & PTHRW_COUNT_MASK);
- }
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, lcntval, ucntval, scntval, diffgen, 0);
-#endif
-
- diffgen = diff_genseq((lcntval & PTHRW_COUNT_MASK), (ulval & PTHRW_COUNT_MASK));
-
- /* set U = L */
- ulval = (lcntval & PTHRW_COUNT_MASK);
- if (OSAtomicCompareAndSwap32Barrier(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) {
- goto retry;
- }
-
- flags = 0;
- if (cond->pshared == PTHREAD_PROCESS_SHARED)
- flags |= _PTHREAD_MTX_OPT_PSHARED;
- pmtx = NULL;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, (uint32_t)cond, 3, diffgen, flags, 0);
-#endif
- nlval = lcntval;
-
- /* pass old u val so kernel will know the diffgen */
- mugen = 0;
- cvlsgen = ((uint64_t)scntval << 32) | nlval;
- cvudgen = ((uint64_t)ucntval << 32) | diffgen;
-
- updateval = __psynch_cvbroad(ocond, cvlsgen, cvudgen, flags, (pthread_mutex_t *)pmtx, mugen, mtid);
-
- if (updateval != (uint32_t)-1) {
-
- /* if kernel granted woke some threads, updatwe S for them as they will not access cv on their way out */
- /* Were any threads woken or bits to be set? */
- if (updateval != 0) {
-retry2:
- needclearpre = 0;
- lcntval = *c_lseqcnt;
- ucntval = *c_useqcnt;
- scntval = *c_sseqcnt;
- /* update scntval with number of expected returns and bits */
- nlval = (scntval & PTHRW_COUNT_MASK) + (updateval & PTHRW_COUNT_MASK);
- /* set bits */
- nlval |= ((scntval & PTH_RWS_CV_BITSALL) | (updateval & PTH_RWS_CV_BITSALL));
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, 0x25, lcntval, scntval, updateval, 0);
-#endif
- /* if L==S and c&p bits are set, needs clearpre */
- if (((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK))
- && ((nlval & PTH_RWS_CV_BITSALL) == PTH_RWS_CV_BITSALL)) {
- /* reset p bit but retain c bit on the sword */
- nlval &= PTH_RWS_CV_RESET_PBIT;
- needclearpre = 1;
- }
-
- oldval64 = (((uint64_t)scntval) << 32);
- oldval64 |= lcntval;
- newval64 = (((uint64_t)nlval) << 32);
- newval64 |= lcntval;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_NONE, 0x25, nlval, scntval, updateval, 0);
-#endif
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
- goto retry2;
-
- /* if L == S, then reset associated mutex */
- if ((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) {
- cond->busy = (npthread_mutex_t *)NULL;
- }
-
- if (needclearpre != 0) {
- (void)__psynch_cvclrprepost(ocond, lcntval, ucntval, nlval, 0, lcntval, flags);
- }
- }
-
- }
- error = 0;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVBRD | DBG_FUNC_END, (uint32_t)cond, 0, error, 0, 0);
-#endif
- return(error);
-}
-
-
-/*
- * Signal a condition variable, waking a specified thread.
- */
-
-int
-pthread_cond_signal_thread_np(pthread_cond_t *ocond, pthread_t thread)
-{
- npthread_cond_t * cond = (npthread_cond_t *)ocond;
- int sig = cond->sig;
- uint32_t flags, updateval;
- uint32_t lcntval , ucntval, scntval;
- uint32_t nlval, ulval=0;
- volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt;
- uint64_t oldval64, newval64, mugen, cvlsgen, mtid = 0;
- int needclearpre = 0, retry_count = 0, uretry_count = 0;
- int error, ucountreset = 0;
-
- /* to provide backwards compat for apps using united condtn vars */
-
- if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init))
- return(EINVAL);
-
- if (cond->sig != _PTHREAD_COND_SIG) {
- LOCK(cond->lock);
- if (cond->sig != _PTHREAD_COND_SIG) {
- if (cond->sig == _PTHREAD_COND_SIG_init) {
- _pthread_cond_init(ocond, NULL, 0);
- /* just inited, nothing to post yet */
- UNLOCK(cond->lock);
- return(0);
- } else {
- UNLOCK(cond->lock);
- return(EINVAL);
- }
- }
- UNLOCK(cond->lock);
- }
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_START, (uint32_t)cond, 0, 0, 0, 0);
-#endif
- COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt);
-retry:
- lcntval = *c_lseqcnt;
- ucntval = *c_useqcnt;
- scntval = *c_sseqcnt;
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, scntval, 0);
-#endif
-
- if (((lcntval & PTHRW_COUNT_MASK) == (scntval & PTHRW_COUNT_MASK)) ||
- ((thread == 0) && ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK)))) {
- /* If L <= S+U, it is spurious broadcasr */
- /* validate it is spurious and return */
- oldval64 = (((uint64_t)scntval) << 32);
- oldval64 |= lcntval;
- newval64 = oldval64;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
- goto retry;
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, 0xf1f1f1f1, 0);
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_END, (uint32_t)cond, scntval, 0, 0xf1f1f1f1, 0);
-#endif
- return(0);
- }
-
- if (thread == 0) {
- /* validate to eliminate spurious values, race snapshots */
- if (is_seqhigher((scntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
- /* since ucntval may be newer, just redo */
- retry_count++;
- if (retry_count > 8192) {
- return(EAGAIN);
- } else {
- sched_yield();
- goto retry;
- }
- } else if (is_seqhigher((ucntval & PTHRW_COUNT_MASK), (lcntval & PTHRW_COUNT_MASK))) {
- /* since ucntval may be newer, just redo */
- uretry_count++;
- if (uretry_count > 8192) {
- /*
- * U value if not used for a while can go out of sync
- * set this to S value and try one more time.
- */
- if (ucountreset != 0)
- return(EAGAIN);
- else
- if (OSAtomicCompareAndSwap32Barrier(ucntval, (scntval & PTHRW_COUNT_MASK), (volatile int32_t *)c_useqcnt) == TRUE) {
- /* now the U is reset to S value */
- ucountreset = 1;
- uretry_count = 0;
- }
- }
- sched_yield();
- goto retry;
- }
- } /* thread == 0 ) */
-
- if (thread == 0) {
- /*
- * skip manipulating U count as ESRCH from kernel cannot be handled properly.
- * S count will cover the imbalance and next signal without thread or broadcast
- * will correct it. But we need to send the right U to kernel so it will use
- * that to look for the appropriate sequenc. So the ulval is computed anyway.
- */
-
- if (is_seqlower(ucntval & PTHRW_COUNT_MASK, scntval & PTHRW_COUNT_MASK) != 0) {
- /* If U < S, set U = S+1 due to intr's TO, etc */
- ulval = (scntval & PTHRW_COUNT_MASK) + PTHRW_INC;
- } else {
- /* If U >= S, set U = U+1 due to intr's TO, etc */
- ulval = (ucntval & PTHRW_COUNT_MASK) + PTHRW_INC;
- }
-
- if (OSAtomicCompareAndSwap32Barrier(ucntval, ulval, (volatile int32_t *)c_useqcnt) != TRUE) {
- goto retry;
- }
- }
-
- flags = 0;
- if (cond->pshared == PTHREAD_PROCESS_SHARED)
- flags |= _PTHREAD_MTX_OPT_PSHARED;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, (uint32_t)cond, 3, nlval, ulval, 0);
-#endif
- nlval = lcntval;
- /* pass old u val so kernel will know the diffgen */
- mugen = 0;
- cvlsgen = ((uint64_t)scntval << 32) | nlval;
-
- updateval = __psynch_cvsignal(ocond, cvlsgen, ucntval, pthread_mach_thread_np(thread), (pthread_mutex_t *)0, mugen, mtid, flags);
-
-
- if (updateval != (uint32_t)-1) {
-
- /* if kernel granted woke some threads, updatwe S for them as they will not access cv on their way out */
- /* Were any threads woken or bits to be set? */
- if (updateval != 0) {
-retry2:
- lcntval = *c_lseqcnt;
- ucntval = *c_useqcnt;
- scntval = *c_sseqcnt;
- /* update scntval with number of expected returns and bits */
- nlval = (scntval & PTHRW_COUNT_MASK) + (updateval & PTHRW_COUNT_MASK);
- /* set bits */
- nlval |= ((scntval & PTH_RWS_CV_BITSALL) | (updateval & PTH_RWS_CV_BITSALL));
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, 0x25, 0, 0, updateval, 0);
-#endif
- /* if L==S and c&p bits are set, needs clearpre */
- if (((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK))
- && ((nlval & PTH_RWS_CV_BITSALL) == PTH_RWS_CV_BITSALL)) {
- /* reset p bit but retain c bit on the sword */
- nlval &= PTH_RWS_CV_RESET_PBIT;
- needclearpre = 1;
- } else
- needclearpre = 0;
-
- oldval64 = (((uint64_t)scntval) << 32);
- oldval64 |= lcntval;
- newval64 = (((uint64_t)nlval) << 32);
- newval64 |= lcntval;
-
-#if _KSYN_TRACE_
-(void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_NONE, 0x25, nlval, ulval, updateval, 0);
-#endif
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
- goto retry2;
-
- /* if L == S, then reset associated mutex */
- if ((nlval & PTHRW_COUNT_MASK) == (lcntval & PTHRW_COUNT_MASK)) {
- cond->busy = (npthread_mutex_t *)NULL;
- }
-
- if (needclearpre != 0) {
- (void)__psynch_cvclrprepost(ocond, lcntval, ucntval, nlval, 0, lcntval, flags);
- }
- }
- }
-
- error = 0;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVSIG | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0);
-#endif
- return (error);
-}
-
-/*
- * Signal a condition variable, waking only one thread.
- */
-int
-pthread_cond_signal(pthread_cond_t *cond)
-{
- return pthread_cond_signal_thread_np(cond, NULL);
-}
-
-/*
- * Manage a list of condition variables associated with a mutex
- */
-
-
-/*
- * Suspend waiting for a condition variable.
- * Note: we have to keep a list of condition variables which are using
- * this same mutex variable so we can detect invalid 'destroy' sequences.
- * If isconforming < 0, we skip the _pthread_testcancel(), but keep the
- * remaining conforming behavior..
- */
-__private_extern__ int
-_pthread_cond_wait(pthread_cond_t *ocond,
- pthread_mutex_t *omutex,
- const struct timespec *abstime,
- int isRelative,
- int isconforming)
-{
- int retval;
- npthread_cond_t * cond = (npthread_cond_t *)ocond;
- npthread_mutex_t * mutex = (npthread_mutex_t * )omutex;
- mach_timespec_t then = {0,0};
- struct timespec cthen = {0,0};
- int sig = cond->sig;
- int msig = mutex->sig;
- npthread_mutex_t * pmtx;
- uint32_t mtxgen, mtxugen, flags=0, updateval;
- uint32_t lcntval , ucntval, scntval;
- uint32_t nlval, ulval, savebits;
- volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt;
- uint64_t oldval64, newval64, mugen, cvlsgen;
- uint32_t * npmtx = NULL;
- int error, local_error;
-
-extern void _pthread_testcancel(pthread_t thread, int isconforming);
-
- /* to provide backwards compat for apps using united condtn vars */
- if((sig != _PTHREAD_COND_SIG) && (sig != _PTHREAD_COND_SIG_init))
- return(EINVAL);
-
- if (isconforming) {
- if((msig != _PTHREAD_MUTEX_SIG) && ((msig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP))
- return(EINVAL);
- if (isconforming > 0)
- _pthread_testcancel(pthread_self(), 1);
- }
-
- if (cond->sig != _PTHREAD_COND_SIG)
- {
- LOCK(cond->lock);
- if (cond->sig != _PTHREAD_COND_SIG) {
- if (cond->sig == _PTHREAD_COND_SIG_init) {
- _pthread_cond_init(ocond, NULL, 0);
- } else {
- UNLOCK(cond->lock);
- return(EINVAL);
- }
- }
- UNLOCK(cond->lock);
- }
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_START, (uint32_t)cond, isRelative, 0, (uint32_t)abstime, 0);
-#endif
- COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt);
-
- /* send relative time to kernel */
- if (abstime) {
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_START, 0x11111111, abstime->tv_nsec, abstime->tv_sec, 0, 0);
-#endif
- if (isRelative == 0) {
- struct timespec now;
- struct timeval tv;
- gettimeofday(&tv, NULL);
- TIMEVAL_TO_TIMESPEC(&tv, &now);
-
- /* Compute relative time to sleep */
- then.tv_nsec = abstime->tv_nsec - now.tv_nsec;
- then.tv_sec = abstime->tv_sec - now.tv_sec;
- if (then.tv_nsec < 0)
- {
- then.tv_nsec += NSEC_PER_SEC;
- then.tv_sec--;
- }
- if (((int)then.tv_sec < 0) ||
- ((then.tv_sec == 0) && (then.tv_nsec == 0)))
- {
- return ETIMEDOUT;
- }
- if (isconforming != 0) {
- cthen.tv_sec = abstime->tv_sec;
- cthen.tv_nsec = abstime->tv_nsec;
- if ((cthen.tv_sec < 0) || (cthen.tv_nsec < 0)) {
- return EINVAL;
- }
- if (cthen.tv_nsec >= NSEC_PER_SEC) {
- return EINVAL;
- }
- }
- } else {
- then.tv_sec = abstime->tv_sec;
- then.tv_nsec = abstime->tv_nsec;
- if ((then.tv_sec == 0) && (then.tv_nsec == 0)) {
- return ETIMEDOUT;
- }
- }
- if(isconforming && ((then.tv_sec < 0) || (then.tv_nsec < 0))) {
- return EINVAL;
- }
- if (then.tv_nsec >= NSEC_PER_SEC) {
- return EINVAL;
- }
- }
-
- if ((cond->busy != (npthread_mutex_t *)NULL) && (cond->busy != mutex))
- return (EINVAL);
-
- pmtx = mutex;
-retry:
- lcntval = *c_lseqcnt;
- ucntval = *c_useqcnt;
- scntval = *c_sseqcnt;
-
- oldval64 = (((uint64_t)scntval) << 32);
- oldval64 |= lcntval;
-
- /* remove c and p bits on S word */
- savebits = scntval & PTH_RWS_CV_BITSALL;
- ulval = (scntval & PTHRW_COUNT_MASK);
- nlval = lcntval + PTHRW_INC;
- newval64 = (((uint64_t)ulval) << 32);
- newval64 |= nlval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
- goto retry;
-
- cond->busy = mutex;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, lcntval, ucntval, scntval, 0);
-#endif
- retval = __mtx_droplock(pmtx, PTHRW_INC, &flags, &npmtx, &mtxgen, &mtxugen);
-
- /* TBD: cases are for normal (non owner for recursive mutex; error checking)*/
- if (retval != 0)
- return(EINVAL);
- if ((flags & _PTHREAD_MTX_OPT_NOTIFY) == 0) {
- npmtx = NULL;
- mugen = 0;
- } else
- mugen = ((uint64_t)mtxugen << 32) | mtxgen;
- flags &= ~_PTHREAD_MTX_OPT_MUTEX; /* reset the mutex bit as this is cvar */
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 3, (uint32_t)mutex, flags, 0);
-#endif
-
-
- cvlsgen = ((uint64_t)(ulval | savebits)<< 32) | nlval;
-
- if (isconforming) {
- pthread_cleanup_push(cond_cleanup, (void *)cond);
- updateval = __psynch_cvwait(ocond, cvlsgen, ucntval, (pthread_mutex_t *)npmtx, mugen, flags, (int64_t)then.tv_sec, (int32_t)then.tv_nsec);
- _pthread_testcancel(pthread_self(), isconforming);
- pthread_cleanup_pop(0);
- } else {
- updateval = __psynch_cvwait(ocond, cvlsgen, ucntval, (pthread_mutex_t *)npmtx, mugen, flags, (int64_t)then.tv_sec, (int32_t)then.tv_nsec);
-
- }
-
- retval = 0;
-
- if (updateval == (uint32_t)-1) {
- local_error = errno;
- error = local_error & 0xff;
- if (error == ETIMEDOUT) {
- retval = ETIMEDOUT;
- } else if (error == EINTR) {
- /*
- ** EINTR can be treated as a spurious wakeup unless we were canceled.
- */
- retval = 0;
- } else
- retval = EINVAL;
-//#if _KSYN_TRACE_
-// (void)__kdebug_trace(0x9000070 | 0, (uint32_t)cond, 0xf1f1f2f2, local_error, error, 0);
-//#endif
-
- /* add unlock ref to show one less waiter */
- cond_dropwait(cond, local_error, 0);
- } else {
-//#if _KSYN_TRACE_
-// (void)__kdebug_trace(0x9000070 | 0, (uint32_t)cond, 0xf3f3f4f4, updateval, 0, 0);
-//#endif
- /* succesful wait */
- if (updateval != 0) {
- /* the return due to prepost and might have bit states */
- /* update S and return for prepo if needed */
- cond_dropwait(cond, 0, updateval);
- }
- retval = 0;
- }
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_NONE, (uint32_t)cond, 4, retval, 0, 0);
-#endif
- pthread_mutex_lock(omutex);
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CVWAIT | DBG_FUNC_END, (uint32_t)cond, 0, 0, retval, 0);
-#endif
- return(retval);
-}
-
-/*
- * For the new style mutex, interlocks are not held all the time.
- * We needed the signature to be set in the end. And we need
- * to protect against the code getting reorganized by compiler.
- */
-static void
-__pthread_cond_set_signature(npthread_cond_t * cond)
-{
- cond->sig = _PTHREAD_COND_SIG;
-}
-
-
-static void
-cond_cleanup(void *arg)
-{
- npthread_cond_t *cond = (npthread_cond_t *)arg;
- pthread_mutex_t *mutex;
-
-// 4597450: begin
- pthread_t thread = pthread_self();
- int thcanceled = 0;
-
- LOCK(thread->lock);
- thcanceled = (thread->detached & _PTHREAD_WASCANCEL);
- UNLOCK(thread->lock);
-
- if (thcanceled == 0)
- return;
-
-// 4597450: end
- mutex = (pthread_mutex_t *) cond->busy;
-
- /* add unlock ref to show one less waiter */
- cond_dropwait(cond, thread->cancel_error, 0);
-
- /*
- ** Can't do anything if this fails -- we're on the way out
- */
- if (mutex != NULL)
- (void)pthread_mutex_lock(mutex);
-}
-
-#define ECVCERORR 256
-#define ECVPERORR 512
-
-void
-cond_dropwait(npthread_cond_t * cond, int error, uint32_t updateval)
-{
- int sig = cond->sig;
- pthread_cond_t * ocond = (pthread_cond_t *)cond;
- int needclearpre = 0;
- uint32_t diffgen, nlval, ulval, flags;
- uint32_t lcntval , ucntval, scntval, lval;
- volatile uint32_t * c_lseqcnt, *c_useqcnt, *c_sseqcnt;
- uint64_t oldval64, newval64;
-
- /* to provide backwards compat for apps using united condtn vars */
-
- if (sig != _PTHREAD_COND_SIG)
- return;
-
- COND_GETSEQ_ADDR(cond, c_lseqcnt, c_useqcnt, c_sseqcnt);
-
- if (error != 0) {
- lval = PTHRW_INC;
- if ((error & ECVCERORR) != 0)
- lval |= PTH_RWS_CV_CBIT;
- if ((error & ECVPERORR) != 0)
- lval |= PTH_RWS_CV_PBIT;
- } else {
- lval = updateval;
- }
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_START, (uint32_t)cond, error, updateval, 0xee, 0);
-#endif
-retry:
- lcntval = *c_lseqcnt;
- ucntval = *c_useqcnt;
- scntval = *c_sseqcnt;
-
- diffgen = diff_genseq((lcntval & PTHRW_COUNT_MASK), (scntval & PTHRW_COUNT_MASK)); /* pendig waiters */
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, lcntval, scntval, diffgen, 0);
-#endif
- if (diffgen <= 0) {
- /* TBD: Assert, should not be the case */
- /* validate it is spurious and return */
- oldval64 = (((uint64_t)scntval) << 32);
- oldval64 |= lcntval;
- newval64 = oldval64;
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
- goto retry;
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_END, (uint32_t)cond, 0, 0, 0, 0);
-#endif
- return;
- }
-
- /* update S by one */
- oldval64 = (((uint64_t)scntval) << 32);
- oldval64 |= lcntval;
-
- /* update scntval with number of expected returns and bits */
- ulval = (scntval & PTHRW_COUNT_MASK) + (lval & PTHRW_COUNT_MASK);
- /* set bits */
- ulval |= ((scntval & PTH_RWS_CV_BITSALL) | (lval & PTH_RWS_CV_BITSALL));
-
- nlval = lcntval;
-
- needclearpre = 0;
-
- /* If L==S, need to return to kernel */
- if ((nlval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) {
- if ((ulval & PTH_RWS_CV_BITSALL) == PTH_RWS_CV_BITSALL) {
- /* reset p bit but retain c bit on the sword */
- needclearpre = 1;
- ulval &= PTH_RWS_CV_RESET_PBIT;
- }
- }
-
- newval64 = (((uint64_t)ulval) << 32);
- newval64 |= nlval;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, 0xffff, nlval, ulval, 0);
-#endif
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)c_lseqcnt) != TRUE)
- goto retry;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, (uint32_t)cond, 2, 0, 0xee, 0);
-#endif
- if ((nlval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) {
- /* last usage remove the mutex */
- cond->busy = NULL;
- }
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_NONE, nlval, ucntval, ulval, PTHRW_INC, 0);
-#endif
- if (needclearpre != 0) {
- flags = 0;
- if (cond->pshared == PTHREAD_PROCESS_SHARED)
- flags |= _PTHREAD_MTX_OPT_PSHARED;
- /* reset prepost */
- (void)__psynch_cvclrprepost(ocond, nlval, ucntval, ulval, 0, nlval, flags);
- }
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_CDROPWT | DBG_FUNC_END, nlval, ucntval, ulval, PTHRW_INC, 0);
-#endif
- return;
-}
-
-
-int
-pthread_cond_timedwait_relative_np(pthread_cond_t *cond,
- pthread_mutex_t *mutex,
- const struct timespec *abstime)
-{
- return (_pthread_cond_wait(cond, mutex, abstime, 1, 0));
-}
-
-
-
-#else /* !BUILDING_VARIANT */
-
-extern int _pthread_cond_wait(pthread_cond_t *cond,
- pthread_mutex_t *mutex,
- const struct timespec *abstime,
- int isRelative,
- int isconforming);
-
-#endif /* !BUILDING_VARIANT ] */
-/*
- * Initialize a condition variable. Note: 'attr' is ignored.
- */
-
-/*
- * Initialize a condition variable. This is the public interface.
- * We can't trust the lock, so initialize it first before taking
- * it.
- */
-int
-pthread_cond_init(pthread_cond_t *cond,
- const pthread_condattr_t *attr)
-{
- int conforming;
-
-#if __DARWIN_UNIX03
- conforming = 1;
-#else /* __DARWIN_UNIX03 */
- conforming = 0;
-#endif /* __DARWIN_UNIX03 */
-
- /* lock is same offset in both structures */
- LOCK_INIT(cond->lock);
-
- return (_pthread_cond_init(cond, attr, conforming));
-}
-
-/*
-int
-pthread_cond_wait(pthread_cond_t *cond,
- pthread_mutex_t *mutex)
-
-int
-pthread_cond_timedwait(pthread_cond_t *cond,
- pthread_mutex_t *mutex,
- const struct timespec *abstime)
-
-moved to pthread_cancelable.c */
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_broadcast.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 28, 1998
-.Dt PTHREAD_COND_BROADCAST 3
-.Os
-.Sh NAME
-.Nm pthread_cond_broadcast
-.Nd unblock all threads waiting for a condition variable
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fn pthread_cond_broadcast "pthread_cond_t *cond"
-.Sh DESCRIPTION
-The
-.Fn pthread_cond_broadcast
-function unblocks all threads that are waiting for the condition variable
-.Fa cond .
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_cond_broadcast
-function will return zero.
-Otherwise, an error number will be returned
-to indicate the error.
-.Sh ERRORS
-.Fn pthread_cond_broadcast
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
-.Fa cond
-is invalid.
-.El
-.Sh SEE ALSO
-.Xr pthread_cond_destroy 3 ,
-.Xr pthread_cond_init 3 ,
-.Xr pthread_cond_signal 3 ,
-.Xr pthread_cond_timedwait 3 ,
-.Xr pthread_cond_wait 3
-.Sh STANDARDS
-.Fn pthread_cond_broadcast
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_destroy.3,v 1.6.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 28, 1998
-.Dt PTHREAD_COND_DESTROY 3
-.Os
-.Sh NAME
-.Nm pthread_cond_destroy
-.Nd destroy a condition variable
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fn pthread_cond_destroy "pthread_cond_t *cond"
-.Sh DESCRIPTION
-The
-.Fn pthread_cond_destroy
-function frees the resources allocated by the condition variable
-.Fa cond .
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_cond_destroy
-function will return zero.
-Otherwise, an error number will be returned
-to indicate the error.
-.Sh ERRORS
-.Fn pthread_cond_destroy
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EBUSY
-The variable
-.Fa cond
-is locked by another thread.
-.It Bq Er EINVAL
-The value specified by
-.Fa cond
-is invalid.
-.El
-.Sh SEE ALSO
-.Xr pthread_cond_broadcast 3 ,
-.Xr pthread_cond_init 3 ,
-.Xr pthread_cond_signal 3 ,
-.Xr pthread_cond_timedwait 3 ,
-.Xr pthread_cond_wait 3
-.Sh STANDARDS
-.Fn pthread_cond_destroy
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_init.3,v 1.6.2.5 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 28, 1998
-.Dt PTHREAD_COND_INIT 3
-.Os
-.Sh NAME
-.Nm pthread_cond_init
-.Nd create a condition variable
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_cond_init
-.Fa "pthread_cond_t *restrict cond"
-.Fa "const pthread_condattr_t *restrict attr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_cond_init
-function creates a new condition variable, with attributes specified with
-.Fa attr .
-If
-.Fa attr
-is NULL, the default attributes are used.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_cond_init
-function will return zero and put the new condition variable id into
-.Fa cond .
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_cond_init
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EAGAIN
-The system temporarily lacks the resources to create another condition
-variable.
-.It Bq Er EINVAL
-The value specified by
-.Fa attr
-is invalid.
-.It Bq Er ENOMEM
-The process cannot allocate enough memory to create another condition
-variable.
-.El
-.Sh SEE ALSO
-.Xr pthread_cond_broadcast 3 ,
-.Xr pthread_cond_destroy 3 ,
-.Xr pthread_cond_signal 3 ,
-.Xr pthread_cond_timedwait 3 ,
-.Xr pthread_cond_wait 3
-.Sh STANDARDS
-.Fn pthread_cond_init
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_signal.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 28, 1998
-.Dt PTHREAD_COND_SIGNAL 3
-.Os
-.Sh NAME
-.Nm pthread_cond_signal
-.Nd unblock a thread waiting for a condition variable
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fn pthread_cond_signal "pthread_cond_t *cond"
-.Sh DESCRIPTION
-The
-.Fn pthread_cond_signal
-function unblocks one thread waiting for the condition variable
-.Fa cond .
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_cond_signal
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_cond_signal
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
-.Fa cond
-is invalid.
-.El
-.Sh SEE ALSO
-.Xr pthread_cond_broadcast 3 ,
-.Xr pthread_cond_destroy 3 ,
-.Xr pthread_cond_init 3 ,
-.Xr pthread_cond_timedwait 3 ,
-.Xr pthread_cond_wait 3
-.Sh STANDARDS
-.Fn pthread_cond_signal
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_timedwait.3,v 1.8.2.6 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 28, 1998
-.Dt PTHREAD_COND_TIMEDWAIT 3
-.Os
-.Sh NAME
-.Nm pthread_cond_timedwait
-.Nd "wait on a condition variable for a specific amount of time"
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_cond_timedwait
-.Fa "pthread_cond_t *restrict cond"
-.Fa "pthread_mutex_t *restrict mutex"
-.Fa "const struct timespec *restrict abstime"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_cond_timedwait
-function atomically blocks the current thread waiting on the condition
-variable specified by
-.Fa cond
-and unblocks the mutex specified by
-.Fa mutex .
-The waiting thread unblocks only after another thread calls
-.Xr pthread_cond_signal 3 ,
-or
-.Xr pthread_cond_broadcast 3
-with the same condition variable, or if the system time reaches the
-time specified in
-.Fa abstime ,
-and the current thread reacquires the lock on
-.Fa mutex .
-.Pp
-Values for struct timespec can be obtained by adding the required
-time interval to the the current time obtained using
-.Xr gettimeofday 2 .
-.Pp
-.Fa Note
-that struct timeval and struct timespec use different units to specify
-the time. Hence, the user should always take care to perform the time unit
-conversions accordingly.
-.Sh EXAMPLE
-.Pp
- struct timeval tv;
- struct timespec ts;
- gettimeofday(&tv, NULL);
- ts.tv_sec = tv.tv_sec + 0;
- ts.tv_nsec = 0;
-.Pp
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_cond_timedwait
-function will return zero.
-Otherwise, an error number will be returned to
-indicate the error.
-.Sh ERRORS
-.Fn pthread_cond_timedwait
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
-.Fa cond ,
-.Fa mutex
-or
-.Fa abstime
-is invalid.
-.It Bq Er ETIMEDOUT
-The system time has reached or exceeded the time specified in
-.Fa abstime .
-.El
-.Sh SEE ALSO
-.Xr pthread_cond_broadcast 3 ,
-.Xr pthread_cond_destroy 3 ,
-.Xr pthread_cond_init 3 ,
-.Xr pthread_cond_signal 3 ,
-.Xr pthread_cond_wait 3 ,
-.Xr gettimeofday 2
-.Sh STANDARDS
-.Fn pthread_cond_timedwait
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Portions Copyright (c) 2001 Apple Computer, Inc. All Rights Reserved.
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_cond_wait.3,v 1.8.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd November 5, 2001
-.Dt PTHREAD_COND_WAIT 3
-.Os Darwin
-.Sh NAME
-.Nm pthread_cond_wait
-.Nd wait on a condition variable
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_cond_wait
-.Fa "pthread_cond_t *restrict cond"
-.Fa "pthread_mutex_t *restrict mutex"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_cond_wait
-function atomically unlocks the
-.Fa mutex
-argument and waits on the
-.Fa cond
-argument. Before returning control to the calling function,
-.Fn pthread_cond_wait
-re-acquires the
-.Fa mutex.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_cond_wait
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_cond_wait
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
-.Fa cond
-or the value specified by
-.Fa mutex
-is invalid.
-.El
-.Sh SEE ALSO
-.Xr pthread_cond_broadcast 3 ,
-.Xr pthread_cond_destroy 3 ,
-.Xr pthread_cond_init 3 ,
-.Xr pthread_cond_signal 3 ,
-.Xr pthread_cond_timedwait 3
-.Sh STANDARDS
-.Fn pthread_cond_wait
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (C) 2000 Jason Evans <jasone@FreeBSD.org>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice(s), this list of conditions and the following disclaimer as
-.\" the first lines of this file unmodified other than the possible
-.\" addition of one or more copyright notices.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice(s), this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
-.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
-.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_condattr.3,v 1.9 2001/10/01 16:09:09 ru Exp $
-.Dd April 28, 2000
-.Dt PTHREAD_CONDATTR 3
-.Os
-.Sh NAME
-.Nm pthread_condattr_destroy ,
-.Nm pthread_condattr_init
-.Nd condition attribute operations
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_condattr_destroy
-.Fa "pthread_condattr_t *attr"
-.Fc
-.Ft int
-.Fo pthread_condattr_init
-.Fa "pthread_condattr_t *attr"
-.Fc
-.Sh DESCRIPTION
-Condition attribute objects are used to specify parameters to
-.Fn pthread_cond_init .
-.Fx Ns 's
-implementation of conditions does not support any non-default
-attributes, so these functions are not very useful, though they are required to
-to be present by
-.Tn POSIX .
-.Pp
-The
-.Fn pthread_condattr_init
-function initializes a condition attribute object with the default attributes.
-.Pp
-The
-.Fn pthread_condattr_destroy
-function destroys a condition attribute object.
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_condattr_destroy
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Fn pthread_condattr_init
-will fail if:
-.Bl -tag -width Er
-.It Bq Er ENOMEM
-Out of memory.
-.El
-.Sh SEE ALSO
-.Xr pthread_cond_init 3
-.Sh STANDARDS
-.Fn pthread_condattr_init
-and
-.Fn pthread_condattr_destroy
-conform to
-.St -p1003.1-96
+++ /dev/null
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_create.3,v 1.9.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_CREATE 3
-.Os
-.Sh NAME
-.Nm pthread_create
-.Nd create a new thread
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_create
-.Fa "pthread_t *restrict thread"
-.Fa "const pthread_attr_t *restrict attr"
-.Fa "void *(*start_routine)(void *)"
-.Fa "void *restrict arg"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_create
-function is used to create a new thread, with attributes specified by
-.Fa attr ,
-within a process.
-If
-.Fa attr
-is NULL, the default attributes are used.
-If the attributes specified by
-.Fa attr
-are modified later, the thread's attributes are not affected.
-Upon successful completion,
-.Fn pthread_create
-will store the ID of the created thread in the location specified by
-.Fa thread .
-.Pp
-Upon its creation, the thread executes
-.Fa start_routine ,
-with
-.Fa arg
-as its sole argument.
-If
-.Fa start_routine
-returns, the effect is as if there was an implicit call to
-.Fn pthread_exit ,
-using the return value of
-.Fa start_routine
-as the exit status.
-Note that the thread in which
-.Fn main
-was originally invoked differs from this.
-When it returns from
-.Fn main ,
-the effect is as if there was an implicit call to
-.Fn exit ,
-using the return value of
-.Fn main
-as the exit status.
-.Pp
-The signal state of the new thread is initialized as:
-.Bl -bullet -offset indent
-.It
-The signal mask is inherited from the creating thread.
-.It
-The set of signals pending for the new thread is empty.
-.El
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_create
-function will return zero.
-Otherwise, an error number will be returned to
-indicate the error.
-.Sh ERRORS
-.Fn pthread_create
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EAGAIN
-The system lacked the necessary resources to create another thread, or
-the system-imposed limit on the total number of threads in a process
-[PTHREAD_THREADS_MAX] would be exceeded.
-.It Bq Er EINVAL
-The value specified by
-.Fa attr
-is invalid.
-.El
-.Sh SEE ALSO
-.Xr fork 2 ,
-.Xr pthread_cleanup_pop 3 ,
-.Xr pthread_cleanup_push 3 ,
-.Xr pthread_exit 3 ,
-.Xr pthread_join 3
-.Sh STANDARDS
-.Fn pthread_create
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1996-1998 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_detach.3,v 1.6.2.5 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_DETACH 3
-.Os
-.Sh NAME
-.Nm pthread_detach
-.Nd detach a thread
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_detach
-.Fa "pthread_t thread"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_detach
-function is used to indicate to the implementation that storage for the
-thread
-.Fa thread
-can be reclaimed when the thread terminates.
-If
-.Fa thread
-has not terminated,
-.Fn pthread_detach
-will not cause it to terminate.
-The effect of multiple
-.Fn pthread_detach
-calls on the same target thread is unspecified.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_detach
-function will return zero.
-Otherwise, an error number will be returned to
-indicate the error.
-Note that the function does not change the value
-of errno, as it did for some drafts of the standard.
-These early drafts
-also passed a pointer to pthread_t as the argument.
-Beware!
-.Sh ERRORS
-.Fn pthread_detach
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The implementation has detected that the value specified by
-.Fa thread
-does not refer to a joinable thread.
-.It Bq Er ESRCH
-No thread could be found corresponding to that specified by the given
-thread ID,
-.Fa thread .
-.El
-.Sh SEE ALSO
-.Xr pthread_join 3
-.Sh STANDARDS
-.Fn pthread_detach
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_equal.3,v 1.4.2.5 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_EQUAL 3
-.Os
-.Sh NAME
-.Nm pthread_equal
-.Nd compare thread IDs
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_equal
-.Fa "pthread_t t1"
-.Fa "pthread_t t2"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_equal
-function compares the thread IDs
-.Fa t1
-and
-.Fa t2 .
-.Sh RETURN VALUES
-The
-.Fn pthread_equal
-function will return non-zero if the thread IDs
-.Fa t1
-and
-.Fa t2
-correspond to the same thread. Otherwise, it will return zero.
-.Sh ERRORS
-None.
-.Sh SEE ALSO
-.Xr pthread_create 3 ,
-.Xr pthread_exit 3
-.Sh STANDARDS
-.Fn pthread_equal
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_exit.3,v 1.8.2.6 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_EXIT 3
-.Os
-.Sh NAME
-.Nm pthread_exit
-.Nd terminate the calling thread
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft void
-.Fo pthread_exit
-.Fa "void *value_ptr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_exit
-function terminates the calling thread and makes the value
-.Fa value_ptr
-available to any successful join with the terminating thread.
-Any
-cancellation cleanup handlers that have been pushed and are not yet popped
-are popped in the reverse order that they were pushed and then executed.
-After all cancellation handlers have been executed, if the thread has any
-thread-specific data, appropriate destructor functions are called in an
-unspecified order.
-Thread termination does not release any application
-visible process resources, including, but not limited to, mutexes and
-file descriptors, nor does it perform any process level cleanup
-actions, including, but not limited to, calling
-.Fn atexit
-routines that may exist.
-.Pp
-An implicit call to
-.Fn pthread_exit
-is made when a thread other than the thread in which
-.Fn main
-was first invoked returns from the start routine that was used to create
-it. The function's return value serves as the thread's exit status.
-.Pp
-The behavior of
-.Fn pthread_exit
-is undefined if called from a cancellation handler or destructor function
-that was invoked as the result of an implicit or explicit call to
-.Fn pthread_exit .
-.Pp
-After a thread has terminated, the result of access to local (auto)
-variables of the thread is undefined.
-Thus, references to local variables
-of the exiting thread should not be used for the
-.Fn pthread_exit
-.Fa value_ptr
-parameter value.
-.Pp
-The process will exit with an exit status of 0 after the last thread has
-been terminated.
-The behavior is as if the implementation called
-.Fn exit
-with a zero argument at thread termination time.
-.Sh RETURN VALUES
-The
-.Fn pthread_exit
-function cannot return to its caller.
-.Sh ERRORS
-None.
-.Sh SEE ALSO
-.Xr _exit 2 ,
-.Xr exit 3 ,
-.Xr pthread_create 3 ,
-.Xr pthread_join 3
-.Sh STANDARDS
-.Fn pthread_exit
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (C) 2000 Jason Evans <jasone@FreeBSD.org>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice(s), this list of conditions and the following disclaimer as
-.\" the first lines of this file unmodified other than the possible
-.\" addition of one or more copyright notices.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice(s), this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
-.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
-.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_schedparam.3,v 1.2.2.4 2001/08/17 15:42:52 ru Exp $
-.Dd May 1, 2000
-.Dt PTHREAD_SCHEDPARAM 3
-.Os
-.Sh NAME
-.Nm pthread_getschedparam ,
-.Nm pthread_setschedparam
-.Nd thread scheduling parameter manipulation
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_getschedparam
-.Fa "pthread_t thread"
-.Fa "int *restrict policy"
-.Fa "struct sched_param *restrict param"
-.Fc
-.Ft int
-.Fo pthread_setschedparam
-.Fa "pthread_t thread"
-.Fa "int policy"
-.Fa "const struct sched_param *param"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_getschedparam
-and
-.Fn pthread_setschedparam
-functions get and set the scheduling parameters of individual threads.
-The scheduling policy for a thread can either be
-.Dv SCHED_FIFO
-(first in, first out) or
-.Dv SCHED_RR
-(round-robin).
-The thread priority (accessed via
-.Va param->sched_priority )
-must be at least
-.Dv PTHREAD_MIN_PRIORITY
-and no more than
-.Dv PTHREAD_MAX_PRIORITY .
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_getschedparam
-will fail if:
-.Bl -tag -width Er
-.It Bq Er ESRCH
-Non-existent thread
-.Va thread .
-.El
-.Pp
-.Fn pthread_setschedparam
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Invalid value for
-.Va policy .
-.It Bq Er ENOTSUP
-Invalid value for scheduling parameters.
-.It Bq Er ESRCH
-Non-existent thread
-.Va thread .
-.El
-.Sh STANDARDS
-.Fn pthread_setschedparam
-and
-.Fn pthread_getschedparam
-conform to
-.St -susv2
+++ /dev/null
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_getspecific.3,v 1.6.2.3 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_GETSPECIFIC 3
-.Os
-.Sh NAME
-.Nm pthread_getspecific
-.Nd get a thread-specific data value
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft void *
-.Fo pthread_getspecific
-.Fa "pthread_key_t key"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_getspecific
-function returns the value that is currently bound to the specified
-.Fa key ,
-on behalf of the calling thread.
-.Pp
-The effect of calling
-.Fn pthread_getspecific
-with a
-.Fa key
-value that was not obtained from
-.Fn pthread_key_create ,
-or after a
-.Fa key
-has been deleted with
-.Fn pthread_key_delete ,
-is undefined.
-.Pp
-.Fn pthread_getspecific
-may be called from a thread-specific data destructor function.
-.Sh RETURN VALUES
-The
-.Fn pthread_getspecific
-function will return the thread-specific data value associated with the given
-.Fa key .
-If no thread-specific data value is associated with
-.Fa key ,
-the value NULL is returned.
-.Sh ERRORS
-None.
-.Sh SEE ALSO
-.Xr pthread_key_create 3 ,
-.Xr pthread_key_delete 3 ,
-.Xr pthread_setspecific 3
-.Sh STANDARDS
-.Fn pthread_getspecific
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-/*
- * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _PTHREAD_IMPL_H_
-#define _PTHREAD_IMPL_H_
-/*
- * Internal implementation details
- */
-
-/* This whole header file will disappear, so don't depend on it... */
-
-#ifndef __POSIX_LIB__
-
-/*
- * [Internal] data structure signatures
- */
-#define _PTHREAD_MUTEX_SIG_init 0x32AAABA7
-
-#define _PTHREAD_ERRORCHECK_MUTEX_SIG_init 0x32AAABA1
-#define _PTHREAD_RECURSIVE_MUTEX_SIG_init 0x32AAABA2
-#define _PTHREAD_FIRSTFIT_MUTEX_SIG_init 0x32AAABA3
-
-#define _PTHREAD_COND_SIG_init 0x3CB0B1BB
-#define _PTHREAD_ONCE_SIG_init 0x30B1BCBA
-#define _PTHREAD_RWLOCK_SIG_init 0x2DA8B3B4
-
-/*
- * POSIX scheduling policies
- */
-#define SCHED_OTHER 1
-#define SCHED_FIFO 4
-#define SCHED_RR 2
-
-#define __SCHED_PARAM_SIZE__ 4
-
-#endif /* __POSIX_LIB__ */
-
-#endif /* _PTHREAD_IMPL_H_ */
+++ /dev/null
-/*
- * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * POSIX Threads - IEEE 1003.1c
- */
-
-#ifndef _POSIX_PTHREAD_INTERNALS_H
-#define _POSIX_PTHREAD_INTERNALS_H
-
-// suppress pthread_attr_t typedef in sys/signal.h
-#define _PTHREAD_ATTR_T
-struct _pthread_attr_t; /* forward reference */
-typedef struct _pthread_attr_t pthread_attr_t;
-
-#include <assert.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <errno.h>
-#include <TargetConditionals.h>
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <libkern/OSAtomic.h>
-
-
-#ifndef __POSIX_LIB__
-#define __POSIX_LIB__
-#endif
-
-#include "posix_sched.h" /* For POSIX scheduling policy & parameter */
-#include <sys/queue.h> /* For POSIX scheduling policy & parameter */
-#include "pthread_machdep.h" /* Machine-dependent definitions. */
-#include "pthread_spinlock.h" /* spinlock definitions. */
-
-TAILQ_HEAD(__pthread_list, _pthread);
-
-extern int __pthread_lock_debug;
-extern int __pthread_lock_old;
-
-extern struct __pthread_list __pthread_head; /* head of list of open files */
-extern pthread_lock_t _pthread_list_lock;
-extern size_t pthreadsize;
-/*
- * Compiled-in limits
- */
-#if TARGET_OS_EMBEDDED
-#define _EXTERNAL_POSIX_THREAD_KEYS_MAX 256
-#define _INTERNAL_POSIX_THREAD_KEYS_MAX 256
-#define _INTERNAL_POSIX_THREAD_KEYS_END 512
-#else
-#define _EXTERNAL_POSIX_THREAD_KEYS_MAX 512
-#define _INTERNAL_POSIX_THREAD_KEYS_MAX 256
-#define _INTERNAL_POSIX_THREAD_KEYS_END 768
-#endif
-
-/*
- * Threads
- */
-#define MAXTHREADNAMESIZE 64
-#define _PTHREAD_T
-typedef struct _pthread
-{
- long sig; /* Unique signature for this structure */
- struct __darwin_pthread_handler_rec *__cleanup_stack;
- pthread_lock_t lock; /* Used for internal mutex on structure */
- uint32_t detached:8,
- inherit:8,
- policy:8,
- freeStackOnExit:1,
- newstyle:1,
- kernalloc:1,
- schedset:1,
- wqthread:1,
- wqkillset:1,
- pad:2;
- size_t guardsize; /* size in bytes to guard stack overflow */
-#if !defined(__LP64__)
- int pad0; /* for backwards compatibility */
-#endif
- struct sched_param param;
- uint32_t cancel_error;
-#if defined(__LP64__)
- uint32_t cancel_pad; /* pad value for alignment */
-#endif
- struct _pthread *joiner;
-#if !defined(__LP64__)
- int pad1; /* for backwards compatibility */
-#endif
- void *exit_value;
- semaphore_t death; /* pthread_join() uses this to wait for death's call */
- mach_port_t kernel_thread; /* kernel thread this thread is bound to */
- void *(*fun)(void*);/* Thread start routine */
- void *arg; /* Argment for thread start routine */
- int cancel_state; /* Whether thread can be cancelled */
- int err_no; /* thread-local errno */
- void *tsd[_EXTERNAL_POSIX_THREAD_KEYS_MAX + _INTERNAL_POSIX_THREAD_KEYS_MAX]; /* Thread specific data */
- void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */
- size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */
- mach_port_t reply_port; /* Cached MiG reply port */
-#if defined(__LP64__)
- int pad2; /* for natural alignment */
-#endif
- void *cthread_self; /* cthread_self() if somebody calls cthread_set_self() */
- /* protected by list lock */
- uint32_t childrun:1,
- parentcheck:1,
- childexit:1,
- pad3:29;
-#if defined(__LP64__)
- int pad4; /* for natural alignment */
-#endif
- TAILQ_ENTRY(_pthread) plist;
- void * freeaddr;
- size_t freesize;
- mach_port_t joiner_notify;
- char pthread_name[MAXTHREADNAMESIZE]; /* including nulll the name */
- int max_tsd_key;
- void * cur_workq;
- void * cur_workitem;
- uint64_t thread_id;
-} *pthread_t;
-
-/*
- * Thread attributes
- */
-struct _pthread_attr_t
-{
- long sig; /* Unique signature for this structure */
- pthread_lock_t lock;
- uint32_t detached:8,
- inherit:8,
- policy:8,
- freeStackOnExit:1,
- fastpath:1,
- schedset:1,
- reserved1:5;
- size_t guardsize; /* size in bytes to guard stack overflow */
- int reserved2; /* Should we free the stack when we exit? */
- struct sched_param param;
- void *stackaddr; /* Base of the stack (is aligned on vm_page_size boundary */
- size_t stacksize; /* Size of the stack (is a multiple of vm_page_size and >= PTHREAD_STACK_MIN) */
- boolean_t reserved3;
-};
-
-/*
- * Mutex attributes
- */
-#define _PTHREAD_MUTEX_POLICY_NONE 0
-#define _PTHREAD_MUTEX_POLICY_FAIRSHARE 1
-#define _PTHREAD_MUTEX_POLICY_FIRSTFIT 2
-#define _PTHREAD_MUTEX_POLICY_REALTIME 3
-#define _PTHREAD_MUTEX_POLICY_ADAPTIVE 4
-#define _PTHREAD_MUTEX_POLICY_PRIPROTECT 5
-#define _PTHREAD_MUTEX_POLICY_PRIINHERIT 6
-
-#define _PTHREAD_MUTEXATTR_T
-typedef struct
-{
- long sig; /* Unique signature for this structure */
- int prioceiling;
- uint32_t protocol:2, /* protocol attribute */
- type:2, /* mutex type */
- pshared:2,
- policy:3,
- rfu:23;
-} pthread_mutexattr_t;
-
-/*
- * Mutex variables
- */
-struct _pthread_mutex_options {
- uint32_t protocol:2, /* protocol */
- type:2, /* mutex type */
- pshared:2, /* mutex type */
- policy:3,
- hold:2,
- misalign:1, /* 8 byte aligned? */
- notify:1, /* CV notify field for kernel */
- mutex:1, /* used in clrprepo that it is a mutex */
- rfu:2,
- lock_count:16;
-};
-
-
-#define _PTHREAD_MTX_OPT_PSHARED 0x010
-#define _PTHREAD_MTX_OPT_HOLD 0x200 /* current owner of the mutex */
-#define _PTHREAD_MTX_OPT_NOMTX 0x400 /* no mutex refs held */
-
-#define _PTHREAD_MTX_OPT_NOTIFY 0x1000 /* notify to drop mutex handling in cvwait */
-#define _PTHREAD_MTX_OPT_MUTEX 0x2000 /* this is a mutex type */
-
-
-#define _PTHREAD_MUTEX_T
-typedef struct _pthread_mutex
-{
- long sig; /* Unique signature for this structure */
- pthread_lock_t lock; /* Used for internal mutex on structure */
- union {
- uint32_t value;
- struct _pthread_mutex_options options;
- } mtxopts;
- int16_t prioceiling;
- int16_t priority; /* Priority to restore when mutex unlocked */
- uint32_t waiters; /* Count of threads waiting for this mutex */
- pthread_t owner; /* Which thread has this mutex locked */
- struct _pthread_mutex *next, *prev; /* List of other mutexes he owns */
- struct _pthread_cond *busy; /* List of condition variables using this mutex */
- semaphore_t sem; /* Semaphore used for waiting */
- semaphore_t order;
-} pthread_mutex_t;
-
-
-typedef struct _npthread_mutex
-{
-/* keep same as pthread_mutex_t from here to .. */
- long sig; /* Unique signature for this structure */
- pthread_lock_t lock; /* Used for static init sequencing */
- union {
- uint32_t value;
- struct _pthread_mutex_options options;
- } mtxopts;
- int16_t prioceiling;
- int16_t priority; /* Priority to restore when mutex unlocked */
- uint32_t m_seq[3];
-#if defined(__LP64__)
- uint64_t m_tid; /* Which thread has this mutex locked */
- uint32_t * m_lseqaddr;
- uint32_t * m_useqaddr;
- uint32_t reserved[2];
-#else
- uint32_t * m_lseqaddr;
- uint64_t m_tid; /* Which thread has this mutex locked */
- uint32_t * m_useqaddr;
-#endif
-} npthread_mutex_t;
-
-
-
-
-/*
- * Condition variable attributes
- */
-#define _PTHREAD_CONDATTR_T
-typedef struct
-{
- long sig; /* Unique signature for this structure */
- uint32_t pshared:2, /* pshared */
- unsupported:30;
-} pthread_condattr_t;
-
-/*
- * Condition variables
- */
-#define _PTHREAD_COND_T
-typedef struct _pthread_cond
-{
- long sig; /* Unique signature for this structure */
- pthread_lock_t lock; /* Used for internal mutex on structure */
- uint32_t waiters:15, /* Number of threads waiting */
- sigspending:15, /* Number of outstanding signals */
- pshared:2;
- struct _pthread_cond *next, *prev; /* List of condition variables using mutex */
- struct _pthread_mutex *busy; /* mutex associated with variable */
- semaphore_t sem; /* Kernel semaphore */
-} pthread_cond_t;
-
-
-typedef struct _npthread_cond
-{
- long sig; /* Unique signature for this structure */
- pthread_lock_t lock; /* Used for internal mutex on structure */
- uint32_t rfu:29, /* not in use*/
- misalign: 1, /* structure is not aligned to 8 byte boundary */
- pshared:2;
- struct _npthread_mutex *busy; /* mutex associated with variable */
- uint32_t c_seq[3];
-#if defined(__LP64__)
- uint32_t reserved[3];
-#endif /* __LP64__ */
-} npthread_cond_t;
-
-/*
- * Initialization control (once) variables
- */
-#define _PTHREAD_ONCE_T
-typedef struct
-{
- long sig; /* Unique signature for this structure */
- pthread_lock_t lock; /* Used for internal mutex on structure */
-} pthread_once_t;
-
-#define _PTHREAD_RWLOCKATTR_T
-typedef struct {
- long sig; /* Unique signature for this structure */
- int pshared;
- int rfu[2]; /* reserved for future use */
-} pthread_rwlockattr_t;
-
-#define _PTHREAD_RWLOCK_T
-typedef struct {
- long sig;
- pthread_mutex_t lock; /* monitor lock */
- int state;
- pthread_cond_t read_signal;
- pthread_cond_t write_signal;
- int blocked_writers;
- int reserved;
- pthread_t owner;
- int rfu[1];
- int pshared;
-} pthread_rwlock_t;
-
-#define PTHRW_RFU_64BIT 124 /* 31 * sizeof(uint32_t) */
-#define PTHRW_RFU_32BIT 72 /* 18 * sizeof(uint32_t) */
-
-#define _PTHREAD_RWLOCK_T
-typedef struct {
- long sig;
- pthread_lock_t lock;
-#if defined(__LP64__)
- int reserv;
- volatile uint32_t rw_seq[4];
- pthread_t rw_owner;
-#else /* __LP64__ */
- volatile uint32_t rw_seq[4];
- pthread_t rw_owner;
- int reserv;
-#endif /* __LP64__ */
- volatile uint32_t * rw_lcntaddr;
- volatile uint32_t * rw_seqaddr;
- volatile uint32_t * rw_ucntaddr;
- uint32_t rw_flags;
- int misalign;
-#if defined(__LP64__)
- char rfu[PTHRW_RFU_64BIT];
-#else /* __LP64__ */
- char rfu[PTHRW_RFU_32BIT];
-#endif /* __LP64__ */
- int pshared;
-} npthread_rwlock_t;
-
-/* flags for rw_flags */
-#define PTHRW_KERN_PROCESS_SHARED 0x10
-#define PTHRW_KERN_PROCESS_PRIVATE 0x20
-#define PTHRW_KERN_PROCESS_FLAGS_MASK 0x30
-#define _PTHREAD_RWLOCK_UPGRADE_TRY 0x10000
-
-/* New model bits on Lword */
-#define PTH_RWL_KBIT 0x01 /* users cannot acquire in user mode */
-#define PTH_RWL_EBIT 0x02 /* exclusive lock in progress */
-#define PTH_RWL_WBIT 0x04 /* write waiters pending in kernel */
-#define PTH_RWL_PBIT 0x04 /* prepost (cv) pending in kernel */
-#define PTH_RWL_YBIT 0x08 /* yielding write waiters pending in kernel */
-#define PTH_RWL_RETRYBIT 0x08 /* mutex retry wait */
-#define PTH_RWL_LBIT 0x10 /* long read in progress */
-#define PTH_RWL_MTXNONE 0x10 /* indicates the cvwait does not have mutex held */
-#define PTH_RWL_UBIT 0x20 /* upgrade request pending */
-#define PTH_RWL_MTX_WAIT 0x20 /* in cvar in mutex wait */
-#define PTH_RWL_RBIT 0x40 /* reader pending in kernel(not used) */
-#define PTH_RWL_MBIT 0x40 /* overlapping grants from kernel */
-#define PTH_RWL_TRYLKBIT 0x40 /* sets try lock attempt */
-#define PTH_RWL_IBIT 0x80 /* lock reset, held untill first succeesful unlock */
-
-/* UBIT values for mutex, cvar */
-#define PTH_RWU_SBIT 0x01
-#define PTH_RWU_BBIT 0x02
-
-#define PTHRW_RWL_INIT PTH_RWL_IBIT /* reset on the lock bits (U)*/
-#define PTHRW_RWLOCK_INIT (PTH_RWL_IBIT | PTH_RWL_RBIT) /* reset on the lock bits (U)*/
-#define PTH_RWLOCK_RESET_RBIT 0xffffffbf
-
-#define PTHRW_INC 0x100
-#define PTHRW_BIT_MASK 0x000000ff
-
-#define PTHRW_UN_BIT_MASK 0x000000bf /* remove overlap bit */
-
-
-/* New model bits on Sword */
-#define PTH_RWS_SBIT 0x01 /* kernel transition seq not set yet*/
-#define PTH_RWS_IBIT 0x02 /* Sequence is not set on return from kernel */
-
-#define PTH_RWS_CV_CBIT PTH_RWS_SBIT /* kernel has cleared all info w.r.s.t CV */
-#define PTH_RWS_CV_PBIT PTH_RWS_IBIT /* kernel has prepost/fake structs only,no waiters */
-#define PTH_RWS_CV_BITSALL (PTH_RWS_CV_CBIT | PTH_RWS_CV_PBIT)
-#define PTH_RWS_CV_MBIT PTH_RWL_MBIT /* to indicate prepost return from kernel */
-#define PTH_RWS_CV_RESET_PBIT 0xfffffffd
-
-#define PTH_RWS_WSVBIT 0x04 /* save W bit */
-#define PTH_RWS_USVBIT 0x08 /* save U bit */
-#define PTH_RWS_YSVBIT 0x10 /* save Y bit */
-#define PTHRW_RWS_INIT PTH_RWS_SBIT /* reset on the lock bits (U)*/
-#define PTHRW_RWS_SAVEMASK (PTH_RWS_WSVBIT|PTH_RWS_USVBIT|PTH_RWS_YSVBIT) /*save bits mask*/
-#define PTHRW_SW_Reset_BIT_MASK 0x000000fe /* remove S bit and get rest of the bits */
-
-#define PTHRW_COUNT_SHIFT 8
-#define PTHRW_COUNT_MASK 0xffffff00
-#define PTHRW_MAX_READERS 0xffffff00
-
-
-#define PTHREAD_MTX_TID_SWITCHING (uint64_t)-1
-
-/* new L word defns */
-#define can_rwl_readinuser(x) ((((x) & (PTH_RWL_UBIT | PTH_RWL_WBIT | PTH_RWL_KBIT)) == 0)||(((x) & PTH_RWL_LBIT) != 0))
-#define can_rwl_longreadinuser(x) (((x) & (PTH_RWL_UBIT | PTH_RWL_WBIT | PTH_RWL_KBIT | PTH_RWL_YBIT)) == 0)
-#define is_rwl_ebit_set(x) (((x) & PTH_RWL_EBIT) != 0)
-#define is_rwl_eubit_set(x) (((x) & (PTH_RWL_EBIT | PTH_RWL_UBIT)) != 0)
-#define is_rwl_wbit_set(x) (((x) & PTH_RWL_WBIT) != 0)
-#define is_rwl_lbit_set(x) (((x) & PTH_RWL_LBIT) != 0)
-#define is_rwl_ebit_clear(x) (((x) & PTH_RWL_EBIT) == 0)
-#define is_rwl_lbit_clear(x) (((x) & PTH_RWL_LBIT) == 0)
-#define is_rwl_readoverlap(x) (((x) & PTH_RWL_MBIT) != 0)
-
-/* S word checks */
-#define is_rws_setseq(x) (((x) & PTH_RWS_SBIT))
-#define is_rws_setunlockinit(x) (((x) & PTH_RWS_IBIT))
-
-/* is x lower than Y */
-static inline int is_seqlower(uint32_t x, uint32_t y) {
- if (x < y) {
- if ((y-x) < (PTHRW_MAX_READERS/2))
- return(1);
- } else {
- if ((x-y) > (PTHRW_MAX_READERS/2))
- return(1);
- }
- return(0);
-}
-
-/* is x lower than or eq Y */
-static inline int is_seqlower_eq(uint32_t x, uint32_t y) {
- if (x==y)
- return(1);
- else
- return(is_seqlower(x,y));
-}
-
-/* is x greater than Y */
-static inline int is_seqhigher(uint32_t x, uint32_t y) {
- if (x > y) {
- if ((x-y) < (PTHRW_MAX_READERS/2))
- return(1);
- } else {
- if ((y-x) > (PTHRW_MAX_READERS/2))
- return(1);
- }
- return(0);
-}
-
-static inline int diff_genseq(uint32_t x, uint32_t y) {
- if (x == y) {
- return(0);
- } else if (x > y) {
- return(x-y);
- } else {
- return((PTHRW_MAX_READERS - y) + x + PTHRW_INC);
- }
-}
-
-/* keep the size to 64bytes for both 64 and 32 */
-#define _PTHREAD_WORKQUEUE_ATTR_T
-typedef struct {
- uint32_t sig;
- int queueprio;
- int overcommit;
- unsigned int resv2[13];
-} pthread_workqueue_attr_t;
-
-#define _PTHREAD_WORKITEM_T
-typedef struct _pthread_workitem {
- TAILQ_ENTRY(_pthread_workitem) item_entry; /* pthread_workitem list in prio */
- void (*func)(void *);
- void * func_arg;
- struct _pthread_workqueue * workq;
- unsigned int flags;
- unsigned int fromcache; /* padding for 64bit */
-} * pthread_workitem_t;
-
-#define PTH_WQITEM_INKERNEL_QUEUE 1
-#define PTH_WQITEM_RUNNING 2
-#define PTH_WQITEM_COMPLETED 4
-#define PTH_WQITEM_REMOVED 8
-#define PTH_WQITEM_BARRIER 0x10
-#define PTH_WQITEM_DESTROY 0x20
-#define PTH_WQITEM_NOTINLIST 0x40
-#define PTH_WQITEM_APPLIED 0x80
-#define PTH_WQITEM_KERN_COUNT 0x100
-
-/* try to fit these within multiple of pages (8 pages for now) */
-#define WORKITEM_POOL_SIZE 680
-/* ensure some multiple of the chunk is the pool size */
-#define WORKITEM_CHUNK_SIZE 40
-
-#define WORKITEM_STARTPOOL_SIZE WORKITEM_CHUNK_SIZE
-
-TAILQ_HEAD(__pthread_workitem_pool, _pthread_workitem);
-extern struct __pthread_workitem_pool __pthread_workitem_pool_head; /* head list of workitem pool */
-
-#define _PTHREAD_WORKQUEUE_HEAD_T
-typedef struct _pthread_workqueue_head {
- TAILQ_HEAD(, _pthread_workqueue) wqhead;
- struct _pthread_workqueue * next_workq;
-} * pthread_workqueue_head_t;
-
-
-/* sized to be 128 bytes both in 32 and 64bit archs */
-#define _PTHREAD_WORKQUEUE_T
-typedef struct _pthread_workqueue {
- unsigned int sig; /* Unique signature for this structure */
- pthread_lock_t lock; /* Used for internal mutex on structure */
- TAILQ_ENTRY(_pthread_workqueue) wq_list; /* workqueue list in prio */
- TAILQ_HEAD(, _pthread_workitem) item_listhead; /* pthread_workitem list in prio */
- TAILQ_HEAD(, _pthread_workitem) item_kernhead; /* pthread_workitem list in prio */
- unsigned int flags;
- size_t stacksize;
- int istimeshare;
- int importance;
- int affinity;
- int queueprio;
- int barrier_count;
- int kq_count;
- void (*term_callback)(struct _pthread_workqueue *,void *);
- void * term_callarg;
- pthread_workqueue_head_t headp;
- int overcommit;
-#if !defined(__LP64__)
- unsigned int rev2[12];
-#endif
-} * pthread_workqueue_t;
-
-#define PTHREAD_WORKQ_IN_CREATION 1
-#define PTHREAD_WORKQ_IN_TERMINATE 2
-#define PTHREAD_WORKQ_BARRIER_ON 4
-#define PTHREAD_WORKQ_TERM_ON 8
-#define PTHREAD_WORKQ_DESTROYED 0x10
-#define PTHREAD_WORKQ_REQUEUED 0x20
-#define PTHREAD_WORKQ_SUSPEND 0x40
-
-#define WORKQUEUE_POOL_SIZE 16
-TAILQ_HEAD(__pthread_workqueue_pool, _pthread_workqueue);
-extern struct __pthread_workqueue_pool __pthread_workqueue_pool_head; /* head list of workqueue pool */
-
-#include "pthread_spis.h"
-
-#if defined(__i386__) || defined(__ppc64__) || defined(__x86_64__) || (defined(__arm__) && (defined(_ARM_ARCH_7) || !defined(_ARM_ARCH_6) || !defined(__thumb__)))
-/*
- * Inside libSystem, we can use r13 or %gs directly to get access to the
- * thread-specific data area. The current thread is in the first slot.
- */
-inline static pthread_t __attribute__((__pure__))
-_pthread_self_direct(void)
-{
- pthread_t ret;
-
-#if defined(__i386__) || defined(__x86_64__)
- ret = _pthread_getspecific_direct(0);
-#elif defined(__ppc64__)
- register const pthread_t __pthread_self asm ("r13");
- ret = __pthread_self;
-#elif defined(__arm__) && defined(_ARM_ARCH_6)
- ret = _pthread_getspecific_direct(0);
-#elif defined(__arm__) && !defined(_ARM_ARCH_6)
- ret = _pthread_getspecific_direct(0);
-#endif
- return ret;
-}
-#define pthread_self() _pthread_self_direct()
-#endif
-
-#define _PTHREAD_DEFAULT_INHERITSCHED PTHREAD_INHERIT_SCHED
-#define _PTHREAD_DEFAULT_PROTOCOL PTHREAD_PRIO_NONE
-#define _PTHREAD_DEFAULT_PRIOCEILING 0
-#define _PTHREAD_DEFAULT_POLICY SCHED_OTHER
-#define _PTHREAD_DEFAULT_STACKSIZE 0x80000 /* 512K */
-#define _PTHREAD_DEFAULT_PSHARED PTHREAD_PROCESS_PRIVATE
-
-#define _PTHREAD_NO_SIG 0x00000000
-#define _PTHREAD_MUTEX_ATTR_SIG 0x4D545841 /* 'MTXA' */
-#define _PTHREAD_MUTEX_SIG 0x4D555458 /* 'MUTX' */
-#define _PTHREAD_MUTEX_SIG_init 0x32AAABA7 /* [almost] ~'MUTX' */
-#define _PTHREAD_ERRORCHECK_MUTEX_SIG_init 0x32AAABA1
-#define _PTHREAD_RECURSIVE_MUTEX_SIG_init 0x32AAABA2
-#define _PTHREAD_FIRSTFIT_MUTEX_SIG_init 0x32AAABA3
-#define _PTHREAD_MUTEX_SIG_init_MASK 0xfffffff0
-#define _PTHREAD_MUTEX_SIG_CMP 0x32AAABA0
-#define _PTHREAD_COND_ATTR_SIG 0x434E4441 /* 'CNDA' */
-#define _PTHREAD_COND_SIG 0x434F4E44 /* 'COND' */
-#define _PTHREAD_COND_SIG_init 0x3CB0B1BB /* [almost] ~'COND' */
-#define _PTHREAD_ATTR_SIG 0x54484441 /* 'THDA' */
-#define _PTHREAD_ONCE_SIG 0x4F4E4345 /* 'ONCE' */
-#define _PTHREAD_ONCE_SIG_init 0x30B1BCBA /* [almost] ~'ONCE' */
-#define _PTHREAD_SIG 0x54485244 /* 'THRD' */
-#define _PTHREAD_RWLOCK_ATTR_SIG 0x52574C41 /* 'RWLA' */
-#define _PTHREAD_RWLOCK_SIG 0x52574C4B /* 'RWLK' */
-#define _PTHREAD_RWLOCK_SIG_init 0x2DA8B3B4 /* [almost] ~'RWLK' */
-
-
-#define _PTHREAD_KERN_COND_SIG 0x12345678 /* */
-#define _PTHREAD_KERN_MUTEX_SIG 0x34567812 /* */
-#define _PTHREAD_KERN_RWLOCK_SIG 0x56781234 /* */
-
-#define _PTHREAD_CREATE_PARENT 4
-#define _PTHREAD_EXITED 8
-// 4597450: begin
-#define _PTHREAD_WASCANCEL 0x10
-// 4597450: end
-
-#if defined(DEBUG)
-#define _PTHREAD_MUTEX_OWNER_SELF pthread_self()
-#else
-#define _PTHREAD_MUTEX_OWNER_SELF (pthread_t)0x12141968
-#endif
-#define _PTHREAD_MUTEX_OWNER_SWITCHING (pthread_t)(~0)
-
-#define _PTHREAD_CANCEL_STATE_MASK 0x01
-#define _PTHREAD_CANCEL_TYPE_MASK 0x02
-#define _PTHREAD_CANCEL_PENDING 0x10 /* pthread_cancel() has been called for this thread */
-
-extern boolean_t swtch_pri(int);
-
-#ifndef PTHREAD_MACH_CALL
-#define PTHREAD_MACH_CALL(expr, ret) (ret) = (expr)
-#endif
-
-/* Prototypes. */
-
-/* Functions defined in machine-dependent files. */
-extern vm_address_t _sp(void);
-extern vm_address_t _adjust_sp(vm_address_t sp);
-extern void _pthread_setup(pthread_t th, void (*f)(pthread_t), void *sp, int suspended, int needresume);
-
-extern void _pthread_tsd_cleanup(pthread_t self);
-
-__private_extern__ void __mtx_holdlock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp, uint64_t *tidp);
-__private_extern__ int __mtx_droplock(npthread_mutex_t *mutex, uint32_t diff, uint32_t * flagp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp);
-__private_extern__ int __mtx_updatebits(npthread_mutex_t *mutex, uint32_t updateval, int firstfiti, int fromcond, uint64_t selfid);
-
-/* syscall interfaces */
-extern uint32_t __psynch_mutexwait(pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags);
-extern uint32_t __psynch_mutexdrop(pthread_mutex_t * mutex, uint32_t mgen, uint32_t ugen, uint64_t tid, uint32_t flags);
-
-extern uint32_t __psynch_cvbroad(pthread_cond_t * cv, uint64_t cvlsgen, uint64_t cvudgen, uint32_t flags, pthread_mutex_t * mutex, uint64_t mugen, uint64_t tid);
-extern uint32_t __psynch_cvsignal(pthread_cond_t * cv, uint64_t cvlsgen, uint32_t cvugen, int thread_port, pthread_mutex_t * mutex, uint64_t mugen, uint64_t tid, uint32_t flags);
-extern uint32_t __psynch_cvwait(pthread_cond_t * cv, uint64_t cvlsgen, uint32_t cvugen, pthread_mutex_t * mutex, uint64_t mugen, uint32_t flags, int64_t sec, uint32_t nsec);
-extern uint32_t __psynch_cvclrprepost(void * cv, uint32_t cvgen, uint32_t cvugen, uint32_t cvsgen, uint32_t prepocnt, uint32_t preposeq, uint32_t flags);
-extern uint32_t __psynch_rw_longrdlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags);
-extern uint32_t __psynch_rw_yieldwrlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags);
-extern int __psynch_rw_downgrade(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags);
-extern uint32_t __psynch_rw_upgrade(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags);
-extern uint32_t __psynch_rw_rdlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags);
-extern uint32_t __psynch_rw_wrlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags);
-extern uint32_t __psynch_rw_unlock(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags);
-extern uint32_t __psynch_rw_unlock2(pthread_rwlock_t * rwlock, uint32_t lgenval, uint32_t ugenval, uint32_t rw_wc, int flags);
-
-__private_extern__ semaphore_t new_sem_from_pool(void);
-__private_extern__ void restore_sem_to_pool(semaphore_t);
-__private_extern__ void _pthread_atfork_queue_init(void);
-int _pthread_lookup_thread(pthread_t thread, mach_port_t * port, int only_joinable);
-int _pthread_join_cleanup(pthread_t thread, void ** value_ptr, int conforming);
-__private_extern__ int proc_setthreadname(void * buffer, int buffersize);
-
-#endif /* _POSIX_PTHREAD_INTERNALS_H */
+++ /dev/null
-.\" Copyright (c) 1996-1998 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_join.3,v 1.7.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_JOIN 3
-.Os
-.Sh NAME
-.Nm pthread_join
-.Nd wait for thread termination
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_join
-.Fa "pthread_t thread"
-.Fa "void **value_ptr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_join
-function suspends execution of the calling thread until the target
-.Fa thread
-terminates, unless the target
-.Fa thread
-has already terminated.
-.Pp
-On return from a successful
-.Fn pthread_join
-call with a non-NULL
-.Fa value_ptr
-argument, the value passed to
-.Fn pthread_exit
-by the terminating thread is stored in the location referenced by
-.Fa value_ptr .
-When a
-.Fn pthread_join
-returns successfully, the target thread has been terminated.
-The results
-of multiple simultaneous calls to
-.Fn pthread_join ,
-specifying the same target thread, are undefined.
-If the thread calling
-.Fn pthread_join
-is cancelled, the target thread is not detached.
-.Pp
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_join
-function will return zero.
-Otherwise, an error number will be returned to
-indicate the error.
-.Sh ERRORS
-.Fn pthread_join
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EDEADLK
-A deadlock was detected or the value of
-.Fa thread
-specifies the calling thread.
-.It Bq Er EINVAL
-The implementation has detected that the value specified by
-.Fa thread
-does not refer to a joinable thread.
-.It Bq Er ESRCH
-No thread could be found corresponding to that specified by the given
-thread ID,
-.Fa thread .
-.El
-.Sh SEE ALSO
-.Xr wait 2 ,
-.Xr pthread_create 3
-.Sh STANDARDS
-.Fn pthread_join
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_key_create.3,v 1.6.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_KEY_CREATE 3
-.Os
-.Sh NAME
-.Nm pthread_key_create
-.Nd thread-specific data key creation
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_key_create
-.Fa "pthread_key_t *key"
-.Fa "void (*destructor)(void *)"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_key_create
-function creates a thread-specific data key
-that is visible to all threads in the process.
-Key values provided by
-.Fn pthread_key_create
-are opaque objects, used to locate thread-specific data.
-Although the same
-key value may be used by different threads, the values bound to the key
-by
-.Fn pthread_setspecific
-are maintained on a per-thread basis and persist for the life of the calling
-thread.
-.Pp
-Upon key creation, the value NULL is associated with the new key in all
-active threads.
-Upon thread creation, the value NULL is associated with all
-defined keys in the new thread.
-.Pp
-An optional destructor function may be associated with each key value.
-At
-thread exit, if a key value has a non-NULL destructor pointer, and the
-thread has a non-NULL value associated with the key, the function pointed
-to is called with the current associated value as its sole argument.
-The
-order of destructor calls is unspecified if more than one destructor exists
-for a thread when it exits.
-.Pp
-If, after all the destructors have been called for all non-NULL values
-with associated destructors, there are still some non-NULL values with
-associated destructors, then the process is repeated.
-If, after at least
-[PTHREAD_DESTRUCTOR_ITERATIONS] iterations of destructor calls for
-outstanding non-NULL values, there are still some non-NULL values with
-associated destructors, the implementation stops calling destructors.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_key_create
-function will store the newly created key value at the location specified by
-.Fa key
-and returns zero.
-Otherwise, an error number will be returned to indicate
-the error.
-.Sh ERRORS
-.Fn pthread_key_create
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EAGAIN
-The system lacked the necessary resources to create another thread-specific
-data key, or the system-imposed limit on the total number of keys per process
-[PTHREAD_KEYS_MAX] would be exceeded.
-.It Bq Er ENOMEM
-Insufficient memory exists to create the key.
-.El
-.Sh SEE ALSO
-.Xr pthread_getspecific 3 ,
-.Xr pthread_key_delete 3 ,
-.Xr pthread_setspecific 3
-.Sh STANDARDS
-.Fn pthread_key_create
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_key_delete.3,v 1.6.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_KEY_DELETE 3
-.Os
-.Sh NAME
-.Nm pthread_key_delete
-.Nd delete a thread-specific data key
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_key_delete
-.Fa "pthread_key_t key"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_key_delete
-function deletes a thread-specific data key, previously returned by
-.Fn pthread_key_create .
-The thread-specific data values associated with
-.Fa key
-need not be NULL at the time that
-.Fn pthread_key_delete
-is called.
-It is the responsibility of the application to free any
-application storage or perform any cleanup actions for data structures
-related to the deleted key or associated thread-specific data in any threads;
-this cleanup can be done either before or after
-.Fn pthread_key_delete
-is called.
-Any attempt to use
-.Fa key
-following the call to
-.Fn pthread_key_delete
-results in undefined behavior.
-.Pp
-The
-.Fn pthread_key_delete
-function is callable from within destructor functions.
-Destructor functions
-are not invoked by
-.Fn pthread_key_delete .
-Any destructor function that may have been associated with
-.Fa key
-will no longer be called upon thread exit.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_key_delete
-function will return zero.
-Otherwise, an error number will be returned to
-indicate the error.
-.Sh ERRORS
-.Fn pthread_key_delete
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The
-.Fa key
-value is invalid.
-.El
-.Sh SEE ALSO
-.Xr pthread_getspecific 3 ,
-.Xr pthread_key_create 3 ,
-.Xr pthread_setspecific 3
-.Sh STANDARDS
-.Fn pthread_key_delete
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-/*
- * Copyright (c) 2003-2004, 2008, 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-/*
- * MkLinux
- */
-
-/* Machine-dependent definitions for pthread internals. */
-
-#ifndef _POSIX_PTHREAD_MACHDEP_H
-#define _POSIX_PTHREAD_MACHDEP_H
-
-#ifndef __ASSEMBLER__
-
-#include <System/machine/cpu_capabilities.h>
-#ifdef __arm__
-#include <arm/arch.h>
-#endif
-#include <TargetConditionals.h>
-#include <stdint.h>
-
-/*
-** Define macros for inline pthread_getspecific() usage.
-** We reserve a number of slots for Apple internal use.
-** This number can grow dynamically, no need to fix it.
-*/
-
-/* This header contains pre defined thread specific keys */
-/* 0 is used for pthread_self */
-#define _PTHREAD_TSD_SLOT_PTHREAD_SELF 0
-/* Keys 1- 9 for use by dyld, directly or indirectly */
-#define _PTHREAD_TSD_SLOT_DYLD_1 1
-#define _PTHREAD_TSD_SLOT_DYLD_2 2
-#define _PTHREAD_TSD_SLOT_DYLD_3 3
-#define _PTHREAD_TSD_RESERVED_SLOT_COUNT 4
-/* To mirror the usage by dyld for Unwind_SjLj */
-#define _PTHREAD_TSD_SLOT_DYLD_8 8
-
-/* Keys 10 - 29 are for Libc/Libsystem internal ussage */
-/* used as __pthread_tsd_first + Num */
-#define __PTK_LIBC_LOCALE_KEY 10
-#define __PTK_LIBC_TTYNAME_KEY 11
-#define __PTK_LIBC_LOCALTIME_KEY 12
-#define __PTK_LIBC_GMTIME_KEY 13
-#define __PTK_LIBC_GDTOA_BIGINT_KEY 14
-#define __PTK_LIBC_PARSEFLOAT_KEY 15
-/* for usage by dyld */
-#define __PTK_LIBC_DYLD_Unwind_SjLj_Key 18
-
-/* Keys 20-25 for libdispactch usage */
-#define __PTK_LIBDISPATCH_KEY0 20
-#define __PTK_LIBDISPATCH_KEY1 21
-#define __PTK_LIBDISPATCH_KEY2 22
-#define __PTK_LIBDISPATCH_KEY3 23
-#define __PTK_LIBDISPATCH_KEY4 24
-#define __PTK_LIBDISPATCH_KEY5 25
-
-/* Keys 30-255 for Non Libsystem usage */
-
-/* Keys 30-39 for Graphic frameworks usage */
-#define _PTHREAD_TSD_SLOT_OPENGL 30 /* backwards compat sake */
-#define __PTK_FRAMEWORK_OPENGL_KEY 30
-#define __PTK_FRAMEWORK_GRAPHICS_KEY1 31
-#define __PTK_FRAMEWORK_GRAPHICS_KEY2 32
-#define __PTK_FRAMEWORK_GRAPHICS_KEY3 33
-#define __PTK_FRAMEWORK_GRAPHICS_KEY4 34
-#define __PTK_FRAMEWORK_GRAPHICS_KEY5 35
-#define __PTK_FRAMEWORK_GRAPHICS_KEY6 36
-#define __PTK_FRAMEWORK_GRAPHICS_KEY7 37
-#define __PTK_FRAMEWORK_GRAPHICS_KEY8 38
-#define __PTK_FRAMEWORK_GRAPHICS_KEY9 39
-
-/* Keys 40-49 for Objective-C runtime usage */
-#define __PTK_FRAMEWORK_OBJC_KEY0 40
-#define __PTK_FRAMEWORK_OBJC_KEY1 41
-#define __PTK_FRAMEWORK_OBJC_KEY2 42
-#define __PTK_FRAMEWORK_OBJC_KEY3 43
-#define __PTK_FRAMEWORK_OBJC_KEY4 44
-#define __PTK_FRAMEWORK_OBJC_KEY5 45
-#define __PTK_FRAMEWORK_OBJC_KEY6 46
-#define __PTK_FRAMEWORK_OBJC_KEY7 47
-#define __PTK_FRAMEWORK_OBJC_KEY8 48
-#define __PTK_FRAMEWORK_OBJC_KEY9 49
-
-/* Keys 50-59 for Core Foundation usage */
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY0 50
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY1 51
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY2 52
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY3 53
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY4 54
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY5 55
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY6 56
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY7 57
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY8 58
-#define __PTK_FRAMEWORK_COREFOUNDATION_KEY9 59
-
-/* Keys 60-69 for Foundation usage */
-#define __PTK_FRAMEWORK_FOUNDATION_KEY0 60
-#define __PTK_FRAMEWORK_FOUNDATION_KEY1 61
-#define __PTK_FRAMEWORK_FOUNDATION_KEY2 62
-#define __PTK_FRAMEWORK_FOUNDATION_KEY3 63
-#define __PTK_FRAMEWORK_FOUNDATION_KEY4 64
-#define __PTK_FRAMEWORK_FOUNDATION_KEY5 65
-#define __PTK_FRAMEWORK_FOUNDATION_KEY6 66
-#define __PTK_FRAMEWORK_FOUNDATION_KEY7 67
-#define __PTK_FRAMEWORK_FOUNDATION_KEY8 68
-#define __PTK_FRAMEWORK_FOUNDATION_KEY9 69
-
-/* Keys 70-79 for Core Animation/QuartzCore usage */
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY0 70
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY1 71
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY2 72
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY3 73
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY4 74
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY5 75
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY6 76
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY7 77
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY8 78
-#define __PTK_FRAMEWORK_QUARTZCORE_KEY9 79
-
-
-/* Keys 80-89 for Garbage Collection */
-#define __PTK_FRAMEWORK_OLDGC_KEY0 80
-#define __PTK_FRAMEWORK_OLDGC_KEY1 81
-#define __PTK_FRAMEWORK_OLDGC_KEY2 82
-#define __PTK_FRAMEWORK_OLDGC_KEY3 83
-#define __PTK_FRAMEWORK_OLDGC_KEY4 84
-#define __PTK_FRAMEWORK_OLDGC_KEY5 85
-#define __PTK_FRAMEWORK_OLDGC_KEY6 86
-#define __PTK_FRAMEWORK_OLDGC_KEY7 87
-#define __PTK_FRAMEWORK_OLDGC_KEY8 88
-#define __PTK_FRAMEWORK_OLDGC_KEY9 89
-
-/* Keys 90-94 for JavaScriptCore Collection */
-#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY0 90
-#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY1 91
-#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY2 92
-#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY3 93
-#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 94
-/* Keys 95 for CoreText */
-#define __PTK_FRAMEWORK_CORETEXT_KEY0 95
-
-/* Keys 110-119 for Garbage Collection */
-#define __PTK_FRAMEWORK_GC_KEY0 110
-#define __PTK_FRAMEWORK_GC_KEY1 111
-#define __PTK_FRAMEWORK_GC_KEY2 112
-#define __PTK_FRAMEWORK_GC_KEY3 113
-#define __PTK_FRAMEWORK_GC_KEY4 114
-#define __PTK_FRAMEWORK_GC_KEY5 115
-#define __PTK_FRAMEWORK_GC_KEY6 116
-#define __PTK_FRAMEWORK_GC_KEY7 117
-#define __PTK_FRAMEWORK_GC_KEY8 118
-#define __PTK_FRAMEWORK_GC_KEY9 119
-
-/*
-** Define macros for inline pthread_getspecific() usage.
-** We reserve a number of slots for Apple internal use.
-** This number can grow dynamically, no need to fix it.
-*/
-
-
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
-extern void *pthread_getspecific(unsigned long);
-extern int pthread_setspecific(unsigned long, const void *);
-/* setup destructor function for static key as it is not created with pthread_key_create() */
-int pthread_key_init_np(int, void (*)(void *));
-
-#if defined(__cplusplus)
-}
-#endif
-
-typedef int pthread_lock_t;
-
-__inline__ static int
-_pthread_has_direct_tsd(void)
-{
-#if TARGET_IPHONE_SIMULATOR
- /* Simulator will use the host implementation, so bypass the macro that is in the target code */
- return 0;
-#elif defined(__ppc__)
- int *caps = (int *)_COMM_PAGE_CPU_CAPABILITIES;
- if (*caps & kFastThreadLocalStorage) {
- return 1;
- } else {
- return 0;
- }
-#else
- return 1;
-#endif
-}
-
-#if TARGET_IPHONE_SIMULATOR || defined(__ppc__) || defined(__ppc64__) || \
- (defined(__arm__) && !defined(_ARM_ARCH_7) && defined(_ARM_ARCH_6) && defined(__thumb__))
-
-#define _pthread_getspecific_direct(key) pthread_getspecific((key))
-#define _pthread_setspecific_direct(key, val) pthread_setspecific((key), (val))
-
-#else
-
-/* To be used with static constant keys only */
-__inline__ static void *
-_pthread_getspecific_direct(unsigned long slot)
-{
- void *ret;
-#if defined(__i386__) || defined(__x86_64__)
- __asm__("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *))));
-#elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5)))
- void **__pthread_tsd;
-#if defined(__arm__) && defined(_ARM_ARCH_6)
- uintptr_t __pthread_tpid;
- __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid));
- __pthread_tsd = (void**)(__pthread_tpid & ~0x3ul);
-#elif defined(__arm__) && defined(_ARM_ARCH_5)
- register uintptr_t __pthread_tpid asm ("r9");
- __pthread_tsd = (void**)__pthread_tpid;
-#endif
- ret = __pthread_tsd[slot];
-#else
-#error no _pthread_getspecific_direct implementation for this arch
-#endif
- return ret;
-}
-
-/* To be used with static constant keys only */
-__inline__ static int
-_pthread_setspecific_direct(unsigned long slot, void * val)
-{
-#if defined(__i386__)
-#if defined(__PIC__)
- __asm__("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val));
-#else
- __asm__("movl %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "ri" (val));
-#endif
-#elif defined(__x86_64__)
- /* PIC is free and cannot be disabled, even with: gcc -mdynamic-no-pic ... */
- __asm__("movq %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val));
-#elif (defined(__arm__) && (defined(_ARM_ARCH_6) || defined(_ARM_ARCH_5)))
- void **__pthread_tsd;
-#if defined(__arm__) && defined(_ARM_ARCH_6)
- uintptr_t __pthread_tpid;
- __asm__("mrc p15, 0, %0, c13, c0, 3" : "=r" (__pthread_tpid));
- __pthread_tsd = (void**)(__pthread_tpid & ~0x3ul);
-#elif defined(__arm__) && defined(_ARM_ARCH_5)
- register uintptr_t __pthread_tpid asm ("r9");
- __pthread_tsd = (void**)__pthread_tpid;
-#endif
- __pthread_tsd[slot] = val;
-#else
-#error no _pthread_setspecific_direct implementation for this arch
-#endif
- return 0;
-}
-
-#endif
-
-#define LOCK_INIT(l) ((l) = 0)
-#define LOCK_INITIALIZER 0
-
-#endif /* ! __ASSEMBLER__ */
-#endif /* _POSIX_PTHREAD_MACHDEP_H */
+++ /dev/null
-/*
- * Copyright (c) 2000-2003, 2007, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * POSIX Pthread Library
- * -- Mutex variable support
- */
-
-#include "pthread_internals.h"
-
-#ifdef PLOCKSTAT
-#include "plockstat.h"
-#else /* !PLOCKSTAT */
-#define PLOCKSTAT_MUTEX_SPIN(x)
-#define PLOCKSTAT_MUTEX_SPUN(x, y, z)
-#define PLOCKSTAT_MUTEX_ERROR(x, y)
-#define PLOCKSTAT_MUTEX_BLOCK(x)
-#define PLOCKSTAT_MUTEX_BLOCKED(x, y)
-#define PLOCKSTAT_MUTEX_ACQUIRE(x, y, z)
-#define PLOCKSTAT_MUTEX_RELEASE(x, y)
-#endif /* PLOCKSTAT */
-
-extern int __unix_conforming;
-extern int __unix_conforming;
-
-#ifndef BUILDING_VARIANT
-__private_extern__ int usenew_mtximpl = 1;
-static void __pthread_mutex_set_signature(npthread_mutex_t * mutex);
-int __mtx_markprepost(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit);
-static int _pthread_mutex_destroy_locked(pthread_mutex_t *omutex);
-#else /* BUILDING_VARIANT */
-extern int usenew_mtximpl;
-#endif /* BUILDING_VARIANT */
-
-
-#ifdef NOTNEEDED
-#define USE_COMPAGE 1
-extern int _commpage_pthread_mutex_lock(uint32_t * lvalp, int flags, uint64_t mtid, uint32_t mask, uint64_t * tidp, int *sysret);
-#endif
-
-#include <machine/cpu_capabilities.h>
-
-int _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr, uint32_t static_type);
-
-
-#if defined(__LP64__)
-#define MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr) \
-{ \
- if (mutex->mtxopts.options.misalign != 0) { \
- lseqaddr = &mutex->m_seq[0]; \
- useqaddr = &mutex->m_seq[1]; \
- } else { \
- lseqaddr = &mutex->m_seq[1]; \
- useqaddr = &mutex->m_seq[2]; \
- } \
-}
-#else /* __LP64__ */
-#define MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr) \
-{ \
- if (mutex->mtxopts.options.misalign != 0) { \
- lseqaddr = &mutex->m_seq[1]; \
- useqaddr = &mutex->m_seq[2]; \
- }else { \
- lseqaddr = &mutex->m_seq[0]; \
- useqaddr = &mutex->m_seq[1]; \
- } \
-}
-#endif /* __LP64__ */
-
-#define _KSYN_TRACE_ 0
-
-#if _KSYN_TRACE_
-/* The Function qualifiers */
-#define DBG_FUNC_START 1
-#define DBG_FUNC_END 2
-#define DBG_FUNC_NONE 0
-
-int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
-
-#define _KSYN_TRACE_UM_LOCK 0x9000060
-#define _KSYN_TRACE_UM_UNLOCK 0x9000064
-#define _KSYN_TRACE_UM_MHOLD 0x9000068
-#define _KSYN_TRACE_UM_MDROP 0x900006c
-#define _KSYN_TRACE_UM_MUBITS 0x900007c
-#define _KSYN_TRACE_UM_MARKPP 0x90000a8
-
-#endif /* _KSYN_TRACE_ */
-
-#ifndef BUILDING_VARIANT /* [ */
-
-#define BLOCK_FAIL_PLOCKSTAT 0
-#define BLOCK_SUCCESS_PLOCKSTAT 1
-
-#ifdef PR_5243343
-/* 5243343 - temporary hack to detect if we are running the conformance test */
-extern int PR_5243343_flag;
-#endif /* PR_5243343 */
-
-/* This function is never called and exists to provide never-fired dtrace
- * probes so that user d scripts don't get errors.
- */
-__private_extern__ __attribute__((used)) void
-_plockstat_never_fired(void)
-{
- PLOCKSTAT_MUTEX_SPIN(NULL);
- PLOCKSTAT_MUTEX_SPUN(NULL, 0, 0);
-}
-
-
-/*
- * Initialize a mutex variable, possibly with additional attributes.
- * Public interface - so don't trust the lock - initialize it first.
- */
-int
-pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
-{
-#if 0
- /* conformance tests depend on not having this behavior */
- /* The test for this behavior is optional */
- if (mutex->sig == _PTHREAD_MUTEX_SIG)
- return EBUSY;
-#endif
- LOCK_INIT(mutex->lock);
- return (_pthread_mutex_init(mutex, attr, 0x7));
-}
-
-/*
- * Fetch the priority ceiling value from a mutex variable.
- * Note: written as a 'helper' function to hide implementation details.
- */
-int
-pthread_mutex_getprioceiling(const pthread_mutex_t *mutex,
- int *prioceiling)
-{
- int res;
-
- LOCK(mutex->lock);
- if (mutex->sig == _PTHREAD_MUTEX_SIG)
- {
- *prioceiling = mutex->prioceiling;
- res = 0;
- } else
- res = EINVAL; /* Not an initialized 'attribute' structure */
- UNLOCK(mutex->lock);
- return (res);
-}
-
-/*
- * Set the priority ceiling for a mutex.
- * Note: written as a 'helper' function to hide implementation details.
- */
-int
-pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
- int prioceiling,
- int *old_prioceiling)
-{
- int res;
-
- LOCK(mutex->lock);
- if (mutex->sig == _PTHREAD_MUTEX_SIG)
- {
- if ((prioceiling >= -999) ||
- (prioceiling <= 999))
- {
- *old_prioceiling = mutex->prioceiling;
- mutex->prioceiling = prioceiling;
- res = 0;
- } else
- res = EINVAL; /* Invalid parameter */
- } else
- res = EINVAL; /* Not an initialized 'attribute' structure */
- UNLOCK(mutex->lock);
- return (res);
-}
-
-/*
- * Get the priority ceiling value from a mutex attribute structure.
- * Note: written as a 'helper' function to hide implementation details.
- */
-int
-pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr,
- int *prioceiling)
-{
- if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG)
- {
- *prioceiling = attr->prioceiling;
- return (0);
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-/*
- * Get the mutex 'protocol' value from a mutex attribute structure.
- * Note: written as a 'helper' function to hide implementation details.
- */
-int
-pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr,
- int *protocol)
-{
- if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG)
- {
- *protocol = attr->protocol;
- return (0);
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-/*
- * Get the mutex 'type' value from a mutex attribute structure.
- * Note: written as a 'helper' function to hide implementation details.
- */
-int
-pthread_mutexattr_gettype(const pthread_mutexattr_t *attr,
- int *type)
-{
- if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG)
- {
- *type = attr->type;
- return (0);
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-/*
- *
- */
-int
-pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared)
-{
- if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG)
- {
- *pshared = (int)attr->pshared;
- return (0);
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-/*
- * Initialize a mutex attribute structure to system defaults.
- */
-int
-pthread_mutexattr_init(pthread_mutexattr_t *attr)
-{
- attr->prioceiling = _PTHREAD_DEFAULT_PRIOCEILING;
- attr->protocol = _PTHREAD_DEFAULT_PROTOCOL;
- attr->policy = _PTHREAD_MUTEX_POLICY_FAIRSHARE;
- attr->type = PTHREAD_MUTEX_DEFAULT;
- attr->sig = _PTHREAD_MUTEX_ATTR_SIG;
- attr->pshared = _PTHREAD_DEFAULT_PSHARED;
- return (0);
-}
-
-/*
- * Set the priority ceiling value in a mutex attribute structure.
- * Note: written as a 'helper' function to hide implementation details.
- */
-int
-pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr,
- int prioceiling)
-{
- if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG)
- {
- if ((prioceiling >= -999) ||
- (prioceiling <= 999))
- {
- attr->prioceiling = prioceiling;
- return (0);
- } else
- {
- return (EINVAL); /* Invalid parameter */
- }
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-/*
- * Set the mutex 'protocol' value in a mutex attribute structure.
- * Note: written as a 'helper' function to hide implementation details.
- */
-int
-pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr,
- int protocol)
-{
- if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG)
- {
- if ((protocol == PTHREAD_PRIO_NONE) ||
- (protocol == PTHREAD_PRIO_INHERIT) ||
- (protocol == PTHREAD_PRIO_PROTECT))
- {
- attr->protocol = protocol;
- return (0);
- } else
- {
- return (EINVAL); /* Invalid parameter */
- }
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-int
-pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *attr,
- int policy)
-{
- if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG)
- {
- if (
- (policy == _PTHREAD_MUTEX_POLICY_FAIRSHARE) ||
- (policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT)
-#if NOTYET
- ||
- (policy == _PTHREAD_MUTEX_POLICY_REALTIME) ||
- (policy == _PTHREAD_MUTEX_POLICY_ADAPTIVE) ||
- (policy == _PTHREAD_MUTEX_POLICY_PRIPROTECT) ||
- (policy == _PTHREAD_MUTEX_POLICY_PRIINHERIT)
-#endif /* NOTYET */
- )
- {
- attr->policy = policy;
- return (0);
- } else
- {
- return (EINVAL); /* Invalid parameter */
- }
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-/*
- * Set the mutex 'type' value in a mutex attribute structure.
- * Note: written as a 'helper' function to hide implementation details.
- */
-int
-pthread_mutexattr_settype(pthread_mutexattr_t *attr,
- int type)
-{
- if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG)
- {
- if ((type == PTHREAD_MUTEX_NORMAL) ||
- (type == PTHREAD_MUTEX_ERRORCHECK) ||
- (type == PTHREAD_MUTEX_RECURSIVE) ||
- (type == PTHREAD_MUTEX_DEFAULT))
- {
- attr->type = type;
- return (0);
- } else
- {
- return (EINVAL); /* Invalid parameter */
- }
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-
-int mutex_try_lock(int *x) {
- return _spin_lock_try((pthread_lock_t *)x);
-}
-
-void mutex_wait_lock(int *x) {
- for (;;) {
- if( _spin_lock_try((pthread_lock_t *)x)) {
- return;
- }
- swtch_pri(0);
- }
-}
-
-void
-cthread_yield(void)
-{
- sched_yield();
-}
-
-void
-pthread_yield_np (void)
-{
- sched_yield();
-}
-
-
-/*
- * Temp: till pshared is fixed correctly
- */
-int
-pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)
-{
-#if __DARWIN_UNIX03
- if (__unix_conforming == 0)
- __unix_conforming = 1;
-#endif /* __DARWIN_UNIX03 */
-
- if (attr->sig == _PTHREAD_MUTEX_ATTR_SIG)
- {
-#if __DARWIN_UNIX03
- if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED))
-#else /* __DARWIN_UNIX03 */
- if ( pshared == PTHREAD_PROCESS_PRIVATE)
-#endif /* __DARWIN_UNIX03 */
- {
- attr->pshared = pshared;
- return (0);
- } else {
- return (EINVAL); /* Invalid parameter */
- }
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-/*
- * Drop the mutex unlock references(from cond wait or mutex_unlock().
- *
- */
-__private_extern__ int
-__mtx_droplock(npthread_mutex_t * mutex, uint32_t diffgen, uint32_t * flagsp, uint32_t ** pmtxp, uint32_t * mgenp, uint32_t * ugenp)
-{
- pthread_t self;
- uint64_t selfid, resettid;
- int firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT);
- uint32_t lgenval, ugenval, nlval, ulval, morewaiters=0, flags;
- volatile uint32_t * lseqaddr, *useqaddr;
- uint64_t oldval64, newval64;
- int numwaiters=0, clearprepost = 0;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_START, (uint32_t)mutex, diffgen, 0, 0, 0);
-#endif
- MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr);
-
-
- flags = mutex->mtxopts.value;
- flags &= ~_PTHREAD_MTX_OPT_NOTIFY; /* no notification by default */
-
-
- if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL)
- {
- self = pthread_self();
- (void) pthread_threadid_np(self, &selfid);
-
- if (mutex->m_tid != selfid)
- {
- //LIBC_ABORT("dropping recur or error mutex not owned by the thread\n");
- PLOCKSTAT_MUTEX_ERROR((pthread_mutex_t *)mutex, EPERM);
- return(EPERM);
- } else if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE &&
- --mutex->mtxopts.options.lock_count)
- {
- PLOCKSTAT_MUTEX_RELEASE((pthread_mutex_t *)mutex, 1);
- goto out;
- }
- }
-
-
-retry:
- lgenval = *lseqaddr;
- ugenval = *useqaddr;
-
- clearprepost = 0;
-
- numwaiters = diff_genseq((lgenval & PTHRW_COUNT_MASK),(ugenval & PTHRW_COUNT_MASK)); /* pendig waiters */
-
- if (numwaiters == 0) {
- /* spurious unlocks, do not touch tid */
- oldval64 = (((uint64_t)ugenval) << 32);
- oldval64 |= lgenval;
- if ((firstfit != 0) && ((lgenval & PTH_RWL_PBIT) != 0)) {
- clearprepost = 1;
- lgenval &= ~PTH_RWL_PBIT;
- newval64 = (((uint64_t)ugenval) << 32);
- newval64 |= lgenval;
- } else
- newval64 = oldval64;
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE)
- goto retry;
- /* validated L & U to be same, this is spurious unlock */
- flags &= ~_PTHREAD_MTX_OPT_NOTIFY;
- if (clearprepost == 1)
- __psynch_cvclrprepost(mutex, lgenval, ugenval, 0, 0, lgenval, (flags | _PTHREAD_MTX_OPT_MUTEX));
-
- goto out;
- }
-
- if (numwaiters < diffgen) {
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, numwaiters, lgenval, ugenval, 0);
-#endif
- /* cannot drop more than existing number of waiters */
- diffgen = numwaiters;
- }
-
- oldval64 = (((uint64_t)ugenval) << 32);
- oldval64 |= lgenval;
- ulval = ugenval + diffgen;
- nlval = lgenval;
-
- if ((lgenval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) {
- /* do not reset Ibit, just K&E */
- nlval &= ~(PTH_RWL_KBIT | PTH_RWL_EBIT);
- flags &= ~_PTHREAD_MTX_OPT_NOTIFY;
- if ((firstfit != 0) && ((lgenval & PTH_RWL_PBIT) != 0)) {
- clearprepost = 1;
- nlval &= ~PTH_RWL_PBIT;
- }
- } else {
- /* need to signal others waiting for mutex */
- morewaiters = 1;
- flags |= _PTHREAD_MTX_OPT_NOTIFY;
- }
-
- if (((nlval & PTH_RWL_EBIT) != 0) && (firstfit != 0)) {
- nlval &= ~PTH_RWL_EBIT; /* reset Ebit so another can acquire meanwhile */
- }
-
- newval64 = (((uint64_t)ulval) << 32);
- newval64 |= nlval;
-
- resettid = mutex->m_tid;
-
- if ((lgenval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK))
- mutex->m_tid = 0;
- else if (firstfit == 0)
- mutex->m_tid = PTHREAD_MTX_TID_SWITCHING;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) != TRUE) {
- mutex->m_tid = resettid;
- goto retry;
- }
-
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0);
- (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_NONE, (uint32_t)mutex, 2, nlval, ulval, 0);
-#endif
-
- if (clearprepost != 0) {
- __psynch_cvclrprepost(mutex, nlval, ulval, 0, 0, nlval, (flags | _PTHREAD_MTX_OPT_MUTEX));
- }
-
- if (mgenp != NULL)
- *mgenp = nlval;
- if (ugenp != NULL)
- *ugenp = ulval;
-#if USE_COMPAGE
- if (pmtxp != NULL)
- *pmtxp = lseqaddr;
-#else
- if (pmtxp != NULL)
- *pmtxp = (uint32_t *)mutex;
-#endif
-
-out:
- if (flagsp != NULL)
- *flagsp = flags;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MDROP | DBG_FUNC_END, (uint32_t)mutex, flags, 0, 0, 0);
-#endif
- return(0);
-}
-
-int
-__mtx_updatebits(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit, int fromcond, uint64_t selfid)
-{
- uint32_t updateval = oupdateval;
-#if !USE_COMPAGE
- pthread_mutex_t * omutex = (pthread_mutex_t *)mutex;
-#endif
- int isebit = 0;
- uint32_t lgenval, ugenval, nval, uval, bits;
- volatile uint32_t * lseqaddr, *useqaddr;
- uint64_t oldval64, newval64;
-
- MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr);
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_START, (uint32_t)mutex, oupdateval, firstfit, fromcond, 0);
-#endif
-
-retry:
- lgenval = *lseqaddr;
- ugenval = *useqaddr;
- bits = updateval & PTHRW_BIT_MASK;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 1, lgenval, ugenval, 0);
-#endif
-
-
- if ((updateval & PTH_RWL_MTX_WAIT) != 0) {
- lgenval = (updateval & PTHRW_COUNT_MASK) | (lgenval & PTHRW_BIT_MASK);
- if (fromcond == 0) {
- /* if from mutex_lock(), it will handle the rewind */
- return(1);
- }
- /* go block in the kernel with same lgenval as returned */
- goto ml1;
- } else {
- /* firsfit might not have EBIT */
- if (firstfit != 0) {
- if ((lgenval & PTH_RWL_EBIT) != 0)
- isebit = 1;
- else
- isebit = 0;
- } else if ((lgenval & (PTH_RWL_KBIT|PTH_RWL_EBIT)) == (PTH_RWL_KBIT|PTH_RWL_EBIT)) {
- /* fairshare mutex and the bits are already set, just update tid */
- goto out;
- }
- }
-
- /* either firstfist or no E bit set */
- /* update the bits */
- oldval64 = (((uint64_t)ugenval) << 32);
- oldval64 |= lgenval;
- uval = ugenval;
- nval = lgenval | (PTH_RWL_KBIT|PTH_RWL_EBIT);
- newval64 = (((uint64_t)uval) << 32);
- newval64 |= nval;
-
- /* set s and b bit */
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) {
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 2, nval, uval, 0);
-#endif
- if ((firstfit != 0) && (isebit != 0))
- goto handleffit;
-
- goto out;
- } else {
- if (firstfit == 0)
- goto retry;
- else
- goto handleffit;
- }
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_NONE, (uint32_t)mutex, 4, nval, uval, 0);
-#endif
-
-out:
- /* succesful bits updation */
- mutex->m_tid = selfid;
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MUBITS | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0);
-#endif
- return(0);
-
-handleffit:
- /* firstfit failure */
- lgenval = *lseqaddr;
- ugenval = *useqaddr;
- if ((lgenval & PTH_RWL_EBIT) == 0)
- goto retry;
-
- if (fromcond == 0)
- return(1);
- else {
- /* called from condition variable code block again */
-ml1:
-#if USE_COMPAGE /* [ */
- updateval = __psynch_mutexwait((pthread_mutex_t *)lseqaddr, lgenval | PTH_RWL_RETRYBIT, ugenval, mutex->m_tid,
- mutex->mtxopts.value);
-#else /* USECOMPAGE ][ */
- updateval = __psynch_mutexwait(omutex, lgenval | PTH_RWL_RETRYBIT, ugenval, mutex->m_tid,
- mutex->mtxopts.value);
-#endif /* USE_COMPAGE ] */
- if (updateval == (uint32_t)-1) {
- goto ml1;
- }
-
- /* now update the bits */
- goto retry;
- }
- /* cannot reach */
- goto retry;
-}
-
-
-int
-__mtx_markprepost(npthread_mutex_t *mutex, uint32_t oupdateval, int firstfit)
-{
- uint32_t updateval = oupdateval;
- int clearprepost = 0;
- uint32_t lgenval, ugenval,flags;
- volatile uint32_t * lseqaddr, *useqaddr;
- uint64_t oldval64, newval64;
-
- MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr);
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_START, (uint32_t)mutex, oupdateval, firstfit, 0, 0);
-#endif
-
-retry:
-
- clearprepost = 0;
-
- if ((firstfit != 0) && ((updateval & PTH_RWL_PBIT) != 0)) {
- flags = mutex->mtxopts.value;
-
- lgenval = *lseqaddr;
- ugenval = *useqaddr;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_NONE, (uint32_t)mutex, 1, lgenval, ugenval, 0);
-#endif
- /* update the bits */
- oldval64 = (((uint64_t)ugenval) << 32);
- oldval64 |= lgenval;
-
- if ((lgenval & PTHRW_COUNT_MASK) == (ugenval & PTHRW_COUNT_MASK)) {
- clearprepost = 1;
- lgenval &= ~PTH_RWL_PBIT;
-
- } else {
- lgenval |= PTH_RWL_PBIT;
- }
- newval64 = (((uint64_t)ugenval) << 32);
- newval64 |= lgenval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) {
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0);
-#endif
-
- if (clearprepost != 0)
- __psynch_cvclrprepost(mutex, lgenval, ugenval, 0, 0, lgenval, (flags | _PTHREAD_MTX_OPT_MUTEX));
-
- } else {
- goto retry;
- }
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_MARKPP | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0);
-#endif
- }
- return(0);
-}
-
-/*
- * For the new style mutex, interlocks are not held all the time.
- * We needed the signature to be set in the end. And we need
- * to protect against the code getting reorganized by compiler.
- */
-static void
-__pthread_mutex_set_signature(npthread_mutex_t * mutex)
-{
- mutex->sig = _PTHREAD_MUTEX_SIG;
-}
-
-int
-pthread_mutex_lock(pthread_mutex_t *omutex)
-{
- pthread_t self;
- uint64_t selfid;
- npthread_mutex_t * mutex = (npthread_mutex_t *)omutex;
- int sig = mutex->sig;
-#if NEVERINCOMPAGE || !USE_COMPAGE
- //uint32_t oldval, newval;
-#endif
- int retval;
- int gotlock = 0, firstfit = 0;
- uint32_t updateval, lgenval, ugenval, nval, uval;
- volatile uint32_t * lseqaddr, *useqaddr;
- uint64_t oldval64, newval64;
-#if USE_COMPAGE
- int sysret = 0;
- uint32_t mask;
-#else
- int retrybit = 0;
-#endif
-
- /* To provide backwards compat for apps using mutex incorrectly */
- if ((sig != _PTHREAD_MUTEX_SIG) && ((sig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) {
- PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL);
- return(EINVAL);
- }
- if (mutex->sig != _PTHREAD_MUTEX_SIG) {
- LOCK(mutex->lock);
- if ((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK) == _PTHREAD_MUTEX_SIG_CMP) {
- /* static initializer, init the mutex */
- if(retval = _pthread_mutex_init(omutex, NULL, (mutex->sig & 0xf)) != 0){
- UNLOCK(mutex->lock);
- PLOCKSTAT_MUTEX_ERROR(omutex, retval);
- return(retval);
- }
- } else if (mutex->sig != _PTHREAD_MUTEX_SIG) {
- UNLOCK(mutex->lock);
- PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL);
- return(EINVAL);
- }
- UNLOCK(mutex->lock);
- }
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_START, (uint32_t)mutex, 0, 0, 0, 0);
-#endif
- MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr);
-
- self = pthread_self();
- (void) pthread_threadid_np(self, &selfid);
-
- if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) {
- if (mutex->m_tid == selfid) {
- if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE)
- {
- if (mutex->mtxopts.options.lock_count < USHRT_MAX)
- {
- mutex->mtxopts.options.lock_count++;
- PLOCKSTAT_MUTEX_ACQUIRE(omutex, 1, 0);
- retval = 0;
- } else {
- retval = EAGAIN;
- PLOCKSTAT_MUTEX_ERROR(omutex, retval);
- }
- } else { /* PTHREAD_MUTEX_ERRORCHECK */
- retval = EDEADLK;
- PLOCKSTAT_MUTEX_ERROR(omutex, retval);
- }
- return (retval);
- }
- }
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 1, 0, 0, 0);
-#endif
-
-#if USE_COMPAGE /* [ */
-
-ml0:
- mask = PTH_RWL_EBIT;
- retval = _commpage_pthread_mutex_lock(lseqaddr, mutex->mtxopts.value, selfid, mask, &mutex->m_tid, &sysret);
- if (retval == 0) {
- gotlock = 1;
- } else if (retval == 1) {
- gotlock = 1;
- updateval = sysret;
- /* returns 0 on succesful update */
- if (__mtx_updatebits( mutex, updateval, firstfit, 0, selfid) == 1) {
- /* could not acquire, may be locked in ffit case */
-#if USE_COMPAGE
- LIBC_ABORT("comapge implementatin looping in libc \n");
-#endif
- goto ml0;
- }
- }
-#if NEVERINCOMPAGE
- else if (retval == 3) {
- cthread_set_errno_self(sysret);
- oldval = *lseqaddr;
- uval = *useqaddr;
- newval = oldval + PTHRW_INC;
- gotlock = 0;
- /* to block in the kerenl again */
- }
-#endif
- else {
- LIBC_ABORT("comapge implementation bombed \n");
- }
-
-
-#else /* USECOMPAGE ][ */
-retry:
- lgenval = *lseqaddr;
- ugenval = *useqaddr;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0);
-#endif /* _KSYN_TRACE_ */
-
- if((lgenval & PTH_RWL_EBIT) == 0) {
- gotlock = 1;
- } else {
- gotlock = 0;
- }
-
- oldval64 = (((uint64_t)ugenval) << 32);
- oldval64 |= lgenval;
- uval = ugenval;
- nval = (lgenval + PTHRW_INC) | (PTH_RWL_EBIT|PTH_RWL_KBIT);
- newval64 = (((uint64_t)uval) << 32);
- newval64 |= nval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) {
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, nval, uval, 0);
-#endif
- if (gotlock != 0) {
- mutex->m_tid = selfid;
- goto out;
- }
- } else
- goto retry;
-
-
- retrybit = 0;
- if (gotlock == 0) {
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 3, nval, uval, 0);
-#endif
- firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT);
-ml1:
- updateval = __psynch_mutexwait(omutex, nval | retrybit, uval, mutex->m_tid,
- mutex->mtxopts.value);
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 4, updateval, 0, 0);
-#endif
- if (updateval == (uint32_t)-1) {
- goto ml1;
- }
-
- /* returns 0 on succesful update; in firstfit it may fail with 1 */
- if (__mtx_updatebits( mutex, PTHRW_INC | (PTH_RWL_KBIT | PTH_RWL_EBIT), firstfit, 0, selfid) == 1) {
- /* could not acquire, may be locked in ffit case */
- retrybit = PTH_RWL_RETRYBIT;
-#if USE_COMPAGE
- LIBC_ABORT("comapge implementatin looping in libc \n");
-
-#endif
- goto ml1;
- }
- }
-#endif /* USE_COMPAGE ] */
-
-out:
- if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE)
- mutex->mtxopts.options.lock_count = 1;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0);
-#endif
- return (0);
-}
-
-/*
- * Attempt to lock a mutex, but don't block if this isn't possible.
- */
-int
-pthread_mutex_trylock(pthread_mutex_t *omutex)
-{
- npthread_mutex_t * mutex = (npthread_mutex_t *)omutex;
- int sig = mutex->sig;
- int error = 0;
- pthread_t self;
- uint64_t selfid;
- int gotlock = 0;
- uint32_t lgenval, ugenval, nval, uval;
- volatile uint32_t * lseqaddr, *useqaddr;
- uint64_t oldval64, newval64;
-
- /* To provide backwards compat for apps using mutex incorrectly */
- if ((sig != _PTHREAD_MUTEX_SIG) && ((sig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) {
- PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL);
- return(EINVAL);
- }
-
- if (mutex->sig != _PTHREAD_MUTEX_SIG) {
- LOCK(mutex->lock);
- if ((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK) == _PTHREAD_MUTEX_SIG_CMP) {
- /* static initializer, init the mutex */
- if((error = _pthread_mutex_init(omutex, NULL, (mutex->sig & 0xf))) != 0){
- UNLOCK(mutex->lock);
- PLOCKSTAT_MUTEX_ERROR(omutex, error);
- return(error);
- }
- } else if (mutex->sig != _PTHREAD_MUTEX_SIG) {
- UNLOCK(mutex->lock);
- PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL);
- return(EINVAL);
- }
- UNLOCK(mutex->lock);
- }
-
- MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr);
-
- self = pthread_self();
- (void) pthread_threadid_np(self, &selfid);
-
- if (mutex->mtxopts.options.type != PTHREAD_MUTEX_NORMAL) {
- if (mutex->m_tid == selfid) {
- if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE)
- {
- if (mutex->mtxopts.options.lock_count < USHRT_MAX)
- {
- mutex->mtxopts.options.lock_count++;
- PLOCKSTAT_MUTEX_ACQUIRE(omutex, 1, 0);
- error = 0;
- } else {
- error = EAGAIN;
- PLOCKSTAT_MUTEX_ERROR(omutex, error);
- }
- } else { /* PTHREAD_MUTEX_ERRORCHECK */
- error = EDEADLK;
- PLOCKSTAT_MUTEX_ERROR(omutex, error);
- }
- return (error);
- }
- }
-retry:
- lgenval = *lseqaddr;
- ugenval = *useqaddr;
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, lgenval, ugenval, 0);
-#endif /* _KSYN_TRACE_ */
-
-
- oldval64 = (((uint64_t)ugenval) << 32);
- oldval64 |= lgenval;
- uval = ugenval;
-
- /* if we can acquire go ahead otherwise ensure it is still busy */
- if((lgenval & PTH_RWL_EBIT) == 0) {
- gotlock = 1;
- nval = (lgenval + PTHRW_INC) | (PTH_RWL_EBIT|PTH_RWL_KBIT);
- } else {
- nval = (lgenval | PTH_RWL_TRYLKBIT);
- gotlock = 0;
- }
-
- newval64 = (((uint64_t)uval) << 32);
- newval64 |= nval;
-
- /* set s and b bit */
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lseqaddr) == TRUE) {
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_NONE, (uint32_t)mutex, 2, nval, uval, 0);
-#endif
- if (gotlock != 0) {
- mutex->m_tid = selfid;
- if (mutex->mtxopts.options.type == PTHREAD_MUTEX_RECURSIVE)
- mutex->mtxopts.options.lock_count = 1;
- PLOCKSTAT_MUTEX_ACQUIRE(omutex, 1, 0);
- } else {
- error = EBUSY;
- PLOCKSTAT_MUTEX_ERROR(omutex, error);
- }
- } else
- goto retry;
-
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_LOCK | DBG_FUNC_END, (uint32_t)mutex, 0xfafafafa, 0, error, 0);
-#endif
- return (error);
-}
-
-/*
- * Unlock a mutex.
- * TODO: Priority inheritance stuff
- */
-int
-pthread_mutex_unlock(pthread_mutex_t *omutex)
-{
- npthread_mutex_t * mutex = (npthread_mutex_t *)omutex;
- int retval;
- uint32_t mtxgen, mtxugen, flags, notify, updateval;
- int sig = mutex->sig;
- pthread_t self;
- uint64_t selfid;
- volatile uint32_t * lseqaddr, *useqaddr;
- int firstfit = 0;
-
- /* To provide backwards compat for apps using mutex incorrectly */
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_START, (uint32_t)mutex, 0, 0, 0, 0);
-#endif
- if ((sig != _PTHREAD_MUTEX_SIG) && ((sig & _PTHREAD_MUTEX_SIG_init_MASK) != _PTHREAD_MUTEX_SIG_CMP)) {
- PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL);
- return(EINVAL);
- }
-
- if (mutex->sig != _PTHREAD_MUTEX_SIG) {
- LOCK(mutex->lock);
- if ((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK) == _PTHREAD_MUTEX_SIG_CMP) {
- /* static initializer, init the mutex */
- if((retval = _pthread_mutex_init(omutex, NULL, (mutex->sig & 0xf))) != 0){
- UNLOCK(mutex->lock);
- PLOCKSTAT_MUTEX_ERROR(omutex, retval);
- return(retval);
- }
- } else if (mutex->sig != _PTHREAD_MUTEX_SIG) {
- UNLOCK(mutex->lock);
- PLOCKSTAT_MUTEX_ERROR(omutex, EINVAL);
- return(EINVAL);
- }
- UNLOCK(mutex->lock);
- }
-
- MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr);
-
- notify = 0;
- retval = __mtx_droplock(mutex, PTHRW_INC, &flags, NULL, &mtxgen, &mtxugen);
- if (retval != 0)
- return(retval);
-
- if ((flags & _PTHREAD_MTX_OPT_NOTIFY) != 0) {
- firstfit = (mutex->mtxopts.options.policy == _PTHREAD_MUTEX_POLICY_FIRSTFIT);
-
- self = pthread_self();
- (void) pthread_threadid_np(self, &selfid);
-
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_NONE, (uint32_t)mutex, 1, mtxgen, mtxugen, 0);
-#endif
-#if USE_COMPAGE /* [ */
- if ((updateval = __psynch_mutexdrop((pthread_mutex_t *)lseqaddr, mtxgen, mtxugen, mutex->m_tid, flags)) == (uint32_t)-1)
-#else /* USECOMPAGE ][ */
- if ((updateval = __psynch_mutexdrop(omutex, mtxgen, mtxugen, mutex->m_tid, flags))== (uint32_t)-1)
-#endif /* USE_COMPAGE ] */
- {
- retval = errno;
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_END, (uint32_t)mutex, retval, 0, 0, 0);
-#endif
- if (retval == 0)
- return(0);
- else if (errno == EINTR)
- return(0);
- else {
- LIBC_ABORT("__p_mutexdrop failed with error %d\n", retval);
- return(retval);
- }
- } else if (firstfit == 1) {
- if ((updateval & PTH_RWL_PBIT) != 0) {
- __mtx_markprepost(mutex, updateval, firstfit);
- }
- }
- }
-#if _KSYN_TRACE_
- (void)__kdebug_trace(_KSYN_TRACE_UM_UNLOCK | DBG_FUNC_END, (uint32_t)mutex, 0, 0, 0, 0);
-#endif
- return(0);
-}
-
-
-/*
- * Initialize a mutex variable, possibly with additional attributes.
- */
-int
-_pthread_mutex_init(pthread_mutex_t *omutex, const pthread_mutexattr_t *attr, uint32_t static_type)
-{
- npthread_mutex_t * mutex = (npthread_mutex_t *)omutex;
-
- if (attr)
- {
- if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG)
- return (EINVAL);
- mutex->prioceiling = attr->prioceiling;
- mutex->mtxopts.options.protocol = attr->protocol;
- mutex->mtxopts.options.policy = attr->policy;
- mutex->mtxopts.options.type = attr->type;
- mutex->mtxopts.options.pshared = attr->pshared;
- } else {
- switch(static_type) {
- case 1:
- mutex->mtxopts.options.type = PTHREAD_MUTEX_ERRORCHECK;
- break;
- case 2:
- mutex->mtxopts.options.type = PTHREAD_MUTEX_RECURSIVE;
- break;
- case 3:
- /* firstfit fall thru */
- case 7:
- mutex->mtxopts.options.type = PTHREAD_MUTEX_DEFAULT;
- break;
- default:
- return(EINVAL);
- }
-
- mutex->prioceiling = _PTHREAD_DEFAULT_PRIOCEILING;
- mutex->mtxopts.options.protocol = _PTHREAD_DEFAULT_PROTOCOL;
- if (static_type != 3)
- mutex->mtxopts.options.policy = _PTHREAD_MUTEX_POLICY_FAIRSHARE;
- else
- mutex->mtxopts.options.policy = _PTHREAD_MUTEX_POLICY_FIRSTFIT;
- mutex->mtxopts.options.pshared = _PTHREAD_DEFAULT_PSHARED;
- }
-
- mutex->mtxopts.options.notify = 0;
- mutex->mtxopts.options.rfu = 0;
- mutex->mtxopts.options.hold = 0;
- mutex->mtxopts.options.mutex = 1;
- mutex->mtxopts.options.lock_count = 0;
- /* address 8byte aligned? */
- if (((uintptr_t)mutex & 0x07) != 0) {
- /* 4byte alinged */
- mutex->mtxopts.options.misalign = 1;
-#if defined(__LP64__)
- mutex->m_lseqaddr = &mutex->m_seq[0];
- mutex->m_useqaddr = &mutex->m_seq[1];
-#else /* __LP64__ */
- mutex->m_lseqaddr = &mutex->m_seq[1];
- mutex->m_useqaddr = &mutex->m_seq[2];
-#endif /* __LP64__ */
- } else {
- /* 8byte alinged */
- mutex->mtxopts.options.misalign = 0;
-#if defined(__LP64__)
- mutex->m_lseqaddr = &mutex->m_seq[1];
- mutex->m_useqaddr = &mutex->m_seq[2];
-#else /* __LP64__ */
- mutex->m_lseqaddr = &mutex->m_seq[0];
- mutex->m_useqaddr = &mutex->m_seq[1];
-#endif /* __LP64__ */
- }
- mutex->m_tid = 0;
- mutex->m_seq[0] = 0;
- mutex->m_seq[1] = 0;
- mutex->m_seq[2] = 0;
- mutex->prioceiling = 0;
- mutex->priority = 0;
- /*
- * For the new style mutex, interlocks are not held all the time.
- * We needed the signature to be set in the end. And we need
- * to protect against the code getting reorganized by compiler.
- * mutex->sig = _PTHREAD_MUTEX_SIG;
- */
- __pthread_mutex_set_signature(mutex);
- return (0);
-}
-
-
-/*
- * Destroy a mutex variable.
- */
-int
-pthread_mutex_destroy(pthread_mutex_t *omutex)
-{
- int res;
- npthread_mutex_t * mutex = (npthread_mutex_t *)omutex;
-
- LOCK(mutex->lock);
- res = _pthread_mutex_destroy_locked(omutex);
- UNLOCK(mutex->lock);
-
- return(res);
-}
-
-
-static int
-_pthread_mutex_destroy_locked(pthread_mutex_t *omutex)
-{
- int res;
- npthread_mutex_t * mutex = (npthread_mutex_t *)omutex;
- uint32_t lgenval, ugenval;
- volatile uint32_t * lseqaddr, *useqaddr;
-
-
- if (mutex->sig == _PTHREAD_MUTEX_SIG)
- {
- MUTEX_GETSEQ_ADDR(mutex, lseqaddr, useqaddr);
-
- lgenval = *(lseqaddr);
- ugenval = *(useqaddr);
- if ((mutex->m_tid == (uint64_t)0) &&
- ((lgenval & PTHRW_COUNT_MASK) == (ugenval & PTHRW_COUNT_MASK)))
- {
- mutex->sig = _PTHREAD_NO_SIG;
- res = 0;
- }
- else
- res = EBUSY;
- } else if((mutex->sig & _PTHREAD_MUTEX_SIG_init_MASK )== _PTHREAD_MUTEX_SIG_CMP) {
- mutex->sig = _PTHREAD_NO_SIG;
- res = 0;
- } else
- res = EINVAL;
-
- return (res);
-}
-
-
-#endif /* !BUILDING_VARIANT ] */
-
-/*
- * Destroy a mutex attribute structure.
- */
-int
-pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
-{
-#if __DARWIN_UNIX03
- if (__unix_conforming == 0)
- __unix_conforming = 1;
- if (attr->sig != _PTHREAD_MUTEX_ATTR_SIG)
- return (EINVAL);
-#endif /* __DARWIN_UNIX03 */
-
- attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */
- return (0);
-}
-
-
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_destroy.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 29, 1998
-.Dt PTHREAD_MUTEX_DESTROY 3
-.Os
-.Sh NAME
-.Nm pthread_mutex_destroy
-.Nd free resources allocated for a mutex
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_mutex_destroy
-.Fa "pthread_mutex_t *mutex"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_mutex_destroy
-function frees the resources allocated for
-.Fa mutex .
-.Sh RETURN VALUES
-If successful,
-.Fn pthread_mutex_destroy
-will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_mutex_destroy
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EBUSY
-.Fa Mutex
-is locked by a thread.
-.It Bq Er EINVAL
-The value specified by
-.Fa mutex
-is invalid.
-.El
-.Sh SEE ALSO
-.Xr pthread_mutex_init 3 ,
-.Xr pthread_mutex_lock 3 ,
-.Xr pthread_mutex_trylock 3 ,
-.Xr pthread_mutex_unlock 3
-.Sh STANDARDS
-.Fn pthread_mutex_destroy
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_init.3,v 1.6.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 29, 1998
-.Dt PTHREAD_MUTEX_INIT 3
-.Os
-.Sh NAME
-.Nm pthread_mutex_init
-.Nd create a mutex
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_mutex_init
-.Fa "pthread_mutex_t *restrict mutex"
-.Fa "const pthread_mutexattr_t *restrict attr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_mutex_init
-function creates a new mutex, with attributes specified with
-.Fa attr .
-If
-.Fa attr
-is NULL, the default attributes are used.
-.Sh RETURN VALUES
-If successful,
-.Fn pthread_mutex_init
-will return zero and put the new mutex id into
-.Fa mutex .
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_mutex_init
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EAGAIN
-The system temporarily lacks the resources to create another mutex.
-.It Bq Er EINVAL
-The value specified by
-.Fa attr
-is invalid.
-.It Bq Er ENOMEM
-The process cannot allocate enough memory to create another mutex.
-.El
-.Sh SEE ALSO
-.Xr pthread_mutex_destroy 3 ,
-.Xr pthread_mutex_lock 3 ,
-.Xr pthread_mutex_trylock 3 ,
-.Xr pthread_mutex_unlock 3
-.Sh STANDARDS
-.Fn pthread_mutex_init
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_lock.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 30, 1998
-.Dt PTHREAD_MUTEX_LOCK 3
-.Os
-.Sh NAME
-.Nm pthread_mutex_lock
-.Nd lock a mutex
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_mutex_lock
-.Fa "pthread_mutex_t *mutex"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_mutex_lock
-function locks
-.Fa mutex .
-If the mutex is already locked, the calling thread will block until the
-mutex becomes available.
-.Sh RETURN VALUES
-If successful,
-.Fn pthread_mutex_lock
-will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_mutex_lock
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EDEADLK
-A deadlock would occur if the thread blocked waiting for
-.Fa mutex .
-.It Bq Er EINVAL
-The value specified by
-.Fa mutex
-is invalid.
-.El
-.Sh SEE ALSO
-.Xr pthread_mutex_destroy 3 ,
-.Xr pthread_mutex_init 3 ,
-.Xr pthread_mutex_trylock 3 ,
-.Xr pthread_mutex_unlock 3
-.Sh STANDARDS
-.Fn pthread_mutex_lock
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_trylock.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 30, 1998
-.Dt PTHREAD_MUTEX_TRYLOCK 3
-.Os
-.Sh NAME
-.Nm pthread_mutex_trylock
-.Nd attempt to lock a mutex without blocking
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_mutex_trylock
-.Fa "pthread_mutex_t *mutex"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_mutex_trylock
-function locks
-.Fa mutex .
-If the mutex is already locked,
-.Fn pthread_mutex_trylock
-will not block waiting for the mutex, but will return an error condition.
-.Sh RETURN VALUES
-If successful,
-.Fn pthread_mutex_trylock
-will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_mutex_trylock
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EBUSY
-.Fa Mutex
-is already locked.
-.It Bq Er EINVAL
-The value specified by
-.Fa mutex
-is invalid.
-.El
-.Sh SEE ALSO
-.Xr pthread_mutex_destroy 3 ,
-.Xr pthread_mutex_init 3 ,
-.Xr pthread_mutex_lock 3 ,
-.Xr pthread_mutex_unlock 3
-.Sh STANDARDS
-.Fn pthread_mutex_trylock
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" Copyright (c) 1997 Brian Cully <shmit@kublai.com>
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_mutex_unlock.3,v 1.5.2.4 2001/08/17 15:42:51 ru Exp $
-.\"
-.Dd July 30, 1998
-.Dt PTHREAD_MUTEX_UNLOCK 3
-.Os
-.Sh NAME
-.Nm pthread_mutex_unlock
-.Nd unlock a mutex
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_mutex_unlock
-.Fa "pthread_mutex_t *mutex"
-.Fc
-.Sh DESCRIPTION
-If the current thread holds the lock on
-.Fa mutex ,
-then the
-.Fn pthread_mutex_unlock
-function unlocks
-.Fa mutex .
-.Pp
-Calling
-.Fn pthread_mutex_unlock
-with a
-.Fa mutex
-that the calling thread does not hold will result
-in undefined behavior.
-.Sh RETURN VALUES
-If successful,
-.Fn pthread_mutex_unlock
-will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_mutex_unlock
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
-.Fa mutex
-is invalid.
-.It Bq Er EPERM
-The current thread does not hold a lock on
-.Fa mutex .
-.El
-.Sh SEE ALSO
-.Xr pthread_mutex_destroy 3 ,
-.Xr pthread_mutex_init 3 ,
-.Xr pthread_mutex_lock 3 ,
-.Xr pthread_mutex_trylock 3
-.Sh STANDARDS
-.Fn pthread_mutex_unlock
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" $NetBSD: pthread_mutexattr.3,v 1.3 2003/07/04 08:36:06 wiz Exp $
-.\"
-.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
-.\" All rights reserved.
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. Neither the name of The NetBSD Foundation nor the names of its
-.\" contributors may be used to endorse or promote products derived
-.\" from this software without specific prior written permission.
-.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
-.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
-.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-.\" POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" Copyright (C) 2000 Jason Evans <jasone@FreeBSD.org>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice(s), this list of conditions and the following disclaimer as
-.\" the first lines of this file unmodified other than the possible
-.\" addition of one or more copyright notices.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice(s), this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
-.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
-.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libpthread/man/pthread_mutexattr.3,v 1.8 2002/09/16 19:29:29 mini Exp $
-.Dd January 30, 2003
-.Dt PTHREAD_MUTEXATTR 3
-.Os
-.Sh NAME
-.Nm pthread_mutexattr_destroy ,
-.Nm pthread_mutexattr_getprioceiling ,
-.Nm pthread_mutexattr_getprotocol ,
-.Nm pthread_mutexattr_gettype ,
-.Nm pthread_mutexattr_init ,
-.Nm pthread_mutexattr_setprioceiling ,
-.Nm pthread_mutexattr_setprotocol ,
-.Nm pthread_mutexattr_settype
-.Nd mutex attribute operations
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_mutexattr_destroy
-.Fa "pthread_mutexattr_t *attr"
-.Fc
-.Ft int
-.Fo pthread_mutexattr_getprioceiling
-.Fa "const pthread_mutexattr_t *restrict attr"
-.Fa "int *restrict prioceiling"
-.Fc
-.\" To match the SUS, this should be:
-.\" .Ft int
-.\" .Fo pthread_mutexattr_getprioceiling
-.\" .Fa "pthread_mutexattr_t *restrict attr"
-.\" .Fa "int *restrict prioceiling"
-.\" .Fc
-.Ft int
-.Fo pthread_mutexattr_getprotocol
-.Fa "const pthread_mutexattr_t *restrict attr"
-.Fa "int *restrict protocol"
-.Fc
-.\" To match the SUS, this should be:
-.\" .Ft int
-.\" .Fo pthread_mutexattr_getprotocol
-.\" .Fa "pthread_mutexattr_t *restrict attr"
-.\" .Fa "int *restrict protocol"
-.\" .Fc
-.Ft int
-.Fo pthread_mutexattr_gettype
-.Fa "const pthread_mutexattr_t *restrict attr"
-.Fa "int *restrict type"
-.Fc
-.\" To match the SUS, this should be:
-.\" .Ft int
-.\" .Fo pthread_mutexattr_gettype
-.\" .Fa "pthread_mutexattr_t *restrict attr"
-.\" .Fa "int *restrict type"
-.\" .Fc
-.Ft int
-.Fo pthread_mutexattr_init
-.Fa "pthread_mutexattr_t *attr"
-.Fc
-.Ft int
-.Fo pthread_mutexattr_setprioceiling
-.Fa "pthread_mutexattr_t *attr"
-.Fa "int prioceiling"
-.Fc
-.Ft int
-.Fo pthread_mutexattr_setprotocol
-.Fa "pthread_mutexattr_t *attr"
-.Fa "int protocol"
-.Fc
-.Ft int
-.Fo pthread_mutexattr_settype
-.Fa "pthread_mutexattr_t *attr"
-.Fa "int type"
-.Fc
-.Sh DESCRIPTION
-Mutex attributes are used to specify parameters to
-.Fn pthread_mutex_init .
-One attribute object can be used in multiple calls to
-.Fn pthread_mutex_init ,
-with or without modifications between calls.
-.Pp
-The
-.Fn pthread_mutexattr_init
-function initializes
-.Fa attr
-with all of the default mutex attributes.
-.Pp
-The
-.Fn pthread_mutexattr_destroy
-function destroys
-.Fa attr .
-.Pp
-The
-.Fn pthread_mutexattr_settype
-function sets the mutex type value of the attribute. Valid mutex types are:
-.Dv PTHREAD_MUTEX_NORMAL ,
-.Dv PTHREAD_MUTEX_ERRORCHECK ,
-.Dv PTHREAD_MUTEX_RECURSIVE ,
-and
-.Dv PTHREAD_MUTEX_DEFAULT .
-The default mutex type for
-.Fn pthread_mutexattr_init
-is
-.Dv PTHREAD_MUTEX_DEFAULT .
-.Pp
-.Dv PTHREAD_MUTEX_NORMAL
-mutexes do not check for usage errors.
-.Dv PTHREAD_MUTEX_NORMAL
-mutexes will deadlock if reentered, and result in undefined behavior if a
-locked mutex is unlocked by another thread. Attempts to unlock an already
-unlocked
-.Dv PTHREAD_MUTEX_NORMAL
-mutex will result in undefined behavior.
-.Pp
-.Dv PTHREAD_MUTEX_ERRORCHECK
-mutexes do check for usage errors.
-If an attempt is made to relock a
-.Dv PTHREAD_MUTEX_ERRORCHECK
-mutex without first dropping the lock, an error will be returned.
-If a thread attempts to unlock a
-.Dv PTHREAD_MUTEX_ERRORCHECK
-mutex that is locked by another thread, an error will be returned. If a
-thread attempts to unlock a
-.Dv PTHREAD_MUTEX_ERRORCHECK
-thread that is unlocked, an error will be returned.
-.Pp
-.Dv PTHREAD_MUTEX_RECURSIVE
-mutexes allow recursive locking.
-An attempt to relock a
-.Dv PTHREAD_MUTEX_RECURSIVE
-mutex that is already locked by the same thread succeeds. An equivalent
-number of
-.Xr pthread_mutex_unlock 3
-calls are needed before the mutex will wake another thread waiting on this
-lock. If a thread attempts to unlock a
-.Dv PTHREAD_MUTEX_RECURSIVE
-mutex that is locked by another thread, an error will be returned. If a thread attemps to unlock a
-.Dv PTHREAD_MUTEX_RECURSIVE
-thread that is unlocked, an error will be returned.
-.Pp
-.Dv PTHREAD_MUTEX_DEFAULT
-mutexes result in undefined behavior if reentered.
-Unlocking a
-.Dv PTHREAD_MUTEX_DEFAULT
-mutex locked by another thread will result in undefined behavior. Attempts to unlock an already
-unlocked
-.Dv PTHREAD_MUTEX_DEFAULT
-mutex will result in undefined behavior.
-.Pp
-.Fn pthread_mutexattr_gettype
-functions copy the type value of the attribute to the location pointed to by the second parameter.
-.Pp
-The
-.Fn pthread_mutexattr_set*
-functions set the attribute that corresponds to each function name.
-.Pp
-The
-.Fn pthread_mutexattr_get*
-functions copy the value of the attribute that corresponds to each function name
-to the location pointed to by the second function parameter.
-.Sh RETURN VALUES
-If successful, these functions return 0.
-Otherwise, an error number is returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_mutexattr_init
-will fail if:
-.Bl -tag -width Er
-.It Bq Er ENOMEM
-Out of memory.
-.El
-.Pp
-.Fn pthread_mutexattr_destroy
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Fn pthread_mutexattr_setprioceiling
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr ,
-or invalid value for
-.Fa prioceiling .
-.El
-.Pp
-.Fn pthread_mutexattr_getprioceiling
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Fn pthread_mutexattr_setprotocol
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr ,
-or invalid value for
-.Fa protocol .
-.El
-.Pp
-.Fn pthread_mutexattr_getprotocol
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Pp
-.Fn pthread_mutexattr_settype
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr ,
-or invalid value for
-.Fa type .
-.El
-.Pp
-.Fn pthread_mutexattr_gettype
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Invalid value for
-.Fa attr .
-.El
-.Sh SEE ALSO
-.Xr pthread_mutex_init 3
-.Sh STANDARDS
-.Fn pthread_mutexattr_init
-and
-.Fn pthread_mutexattr_destroy
-conform to
-.St -p1003.1-96
-.Pp
-.Fn pthread_mutexattr_setprioceiling ,
-.Fn pthread_mutexattr_getprioceiling ,
-.Fn pthread_mutexattr_setprotocol ,
-.Fn pthread_mutexattr_getprotocol ,
-.Fn pthread_mutexattr_settype ,
-and
-.Fn pthread_mutexattr_gettype
-conform to
-.St -susv2
+++ /dev/null
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_once.3,v 1.6.2.6 2001/08/17 15:42:52 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_ONCE 3
-.Os
-.Sh NAME
-.Nm pthread_once
-.Nd dynamic package initialization
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Pp
-pthread_once_t
-.Fa once_control
-= PTHREAD_ONCE_INIT;
-.Ft int
-.Fn pthread_once "pthread_once_t *once_control" "void (*init_routine)(void)"
-.Sh DESCRIPTION
-The first call to
-.Fn pthread_once
-by any thread in a process, with a given
-.Fa once_control ,
-will call the
-.Fn init_routine
-with no arguments.
-Subsequent calls to
-.Fn pthread_once
-with the same
-.Fa once_control
-will not call the
-.Fn init_routine .
-On return from
-.Fn pthread_once ,
-it is guaranteed that
-.Fn init_routine
-has completed.
-The
-.Fa once_control
-parameter is used to determine whether the associated initialization
-routine has been called.
-.Pp
-The function
-.Fn pthread_once
-is not a cancellation point.
-However, if
-.Fn init_routine
-is a cancellation point and is cancelled, the effect on
-.Fa once_control is as if
-.Fn pthread_once
-was never called.
-.Pp
-The constant
-.Fa PTHREAD_ONCE_INIT
-is defined by header
-.Aq Pa pthread.h .
-.Pp
-The behavior of
-.Fn pthread_once
-is undefined if
-.Fa once_control
-has automatic storage duration or is not initialized by
-.Fa PTHREAD_ONCE_INIT .
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_once
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-None.
-.Sh STANDARDS
-.Fn pthread_once
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-/*
- * Copyright (c) 2000-2003, 2007, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*-
- * Copyright (c) 1998 Alex Nash
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libc_r/uthread/uthread_rwlock.c,v 1.6 2001/04/10 04:19:20 deischen Exp $
- */
-
-/*
- * POSIX Pthread Library
- * -- Read Write Lock support
- * 4/24/02: A. Ramesh
- * Ported from FreeBSD
- */
-
-#include "pthread_internals.h"
-#include <stdio.h> /* For printf(). */
-
-extern int __unix_conforming;
-
-#ifdef PLOCKSTAT
-#include "plockstat.h"
-#else /* !PLOCKSTAT */
-#define PLOCKSTAT_RW_ERROR(x, y, z)
-#define PLOCKSTAT_RW_BLOCK(x, y)
-#define PLOCKSTAT_RW_BLOCKED(x, y, z)
-#define PLOCKSTAT_RW_ACQUIRE(x, y)
-#define PLOCKSTAT_RW_RELEASE(x, y)
-#endif /* PLOCKSTAT */
-
-#define READ_LOCK_PLOCKSTAT 0
-#define WRITE_LOCK_PLOCKSTAT 1
-
-#define BLOCK_FAIL_PLOCKSTAT 0
-#define BLOCK_SUCCESS_PLOCKSTAT 1
-
-/* maximum number of times a read lock may be obtained */
-#define MAX_READ_LOCKS (INT_MAX - 1)
-
-
-#ifndef BUILDING_VARIANT /* [ */
-__private_extern__ int usenew_impl = 1;
-#else /* BUILDING_VARIANT */
-extern int usenew_impl;
-#endif /* BUILDING_VARIANT */
-
-extern int PR_5243343_flag;
-
-#if defined(__LP64__)
-#define RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr) \
-{ \
- if (rwlock->misalign != 0) { \
- lcntaddr = &rwlock->rw_seq[1]; \
- seqaddr = &rwlock->rw_seq[2]; \
- ucntaddr = &rwlock->rw_seq[3]; \
- } else { \
- lcntaddr = &rwlock->rw_seq[0]; \
- seqaddr = &rwlock->rw_seq[1]; \
- ucntaddr = &rwlock->rw_seq[2]; \
- } \
-}
-#else /* __LP64__ */
-#define RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr) \
-{ \
- if (rwlock->misalign != 0) { \
- lcntaddr = &rwlock->rw_seq[1]; \
- seqaddr = &rwlock->rw_seq[2]; \
- ucntaddr = &rwlock->rw_seq[3]; \
- } else { \
- lcntaddr = &rwlock->rw_seq[0]; \
- seqaddr = &rwlock->rw_seq[1]; \
- ucntaddr = &rwlock->rw_seq[2]; \
- } \
-}
-#endif /* __LP64__ */
-
-__private_extern__ int __pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
-
-
-#define _KSYN_TRACE_ 0
-
-#if _KSYN_TRACE_
-#include <sys/sysctl.h>
-#ifndef BUILDING_VARIANT /* [ */
-static void set_enable(int);
-#endif /* !BUILDING_VARIANT ] */
-
-/* The Function qualifiers */
-#define DBG_FUNC_START 1
-#define DBG_FUNC_END 2
-#define DBG_FUNC_NONE 0
-
-int __kdebug_trace(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t);
-
-#define _KSYN_TRACE_RW_RDLOCK 0x9000080
-#define _KSYN_TRACE_RW_WRLOCK 0x9000084
-#define _KSYN_TRACE_RW_UNLOCK 0x9000088
-#define _KSYN_TRACE_RW_UNACT1 0x900808c
-#define _KSYN_TRACE_RW_UNACT2 0x9008090
-#define _KSYN_TRACE_RW_UNACTK 0x9008094
-#define _KSYN_TRACE_RW_UNACTE 0x9008098
-#define _KSYN_TRACE_RW_UNACTR 0x900809c
-#define _KSYN_TRACE_RW_TOOMANY 0x90080a0
-#define _KSYN_TRACE_RW_TRYWRLOCK 0x90080a4
-#define _KSYN_TRACE_RW_TRYRDLOCK 0x90080a8
-#endif /* _KSYN_TRACE_ */
-
-__private_extern__ void rwlock_action_onreturn(pthread_rwlock_t * rwlock, uint32_t updateval);
-__private_extern__ int rw_diffgenseq(uint32_t x, uint32_t y);
-
-#ifndef BUILDING_VARIANT /* [ */
-static uint32_t modbits(uint32_t lgenval, uint32_t updateval, uint32_t savebits);
-
-int
-pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
-{
- attr->sig = _PTHREAD_RWLOCK_ATTR_SIG;
- attr->pshared = _PTHREAD_DEFAULT_PSHARED;
- return (0);
-}
-
-int
-pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
-{
- attr->sig = _PTHREAD_NO_SIG; /* Uninitialized */
- attr->pshared = 0;
- return (0);
-}
-
-int
-pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr,
- int *pshared)
-{
- if (attr->sig == _PTHREAD_RWLOCK_ATTR_SIG)
- {
- *pshared = (int)attr->pshared;
- return (0);
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-}
-
-
-int
-pthread_rwlockattr_setpshared(pthread_rwlockattr_t * attr, int pshared)
-{
- if (attr->sig == _PTHREAD_RWLOCK_ATTR_SIG)
- {
-#if __DARWIN_UNIX03
- if (( pshared == PTHREAD_PROCESS_PRIVATE) || (pshared == PTHREAD_PROCESS_SHARED))
-#else /* __DARWIN_UNIX03 */
- if ( pshared == PTHREAD_PROCESS_PRIVATE)
-#endif /* __DARWIN_UNIX03 */
- {
- attr->pshared = pshared ;
- return (0);
- } else
- {
- return (EINVAL); /* Invalid parameter */
- }
- } else
- {
- return (EINVAL); /* Not an initialized 'attribute' structure */
- }
-
-}
-
-__private_extern__ int
-__pthread_rwlock_init(pthread_rwlock_t * orwlock, const pthread_rwlockattr_t *attr)
-{
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
-
- if ((attr != NULL) && (attr->pshared == PTHREAD_PROCESS_SHARED)) {
- rwlock->pshared = PTHREAD_PROCESS_SHARED;
- rwlock->rw_flags = PTHRW_KERN_PROCESS_SHARED;
- } else {
- rwlock->pshared = _PTHREAD_DEFAULT_PSHARED;
- rwlock->rw_flags = PTHRW_KERN_PROCESS_PRIVATE;
- }
-
- if (((uintptr_t)rwlock & 0x07) != 0) {
- rwlock->misalign = 1;
-#if defined(__LP64__)
- rwlock->rw_lcntaddr = &rwlock->rw_seq[1];
- rwlock->rw_seqaddr = &rwlock->rw_seq[2];
- rwlock->rw_ucntaddr = &rwlock->rw_seq[3];
- rwlock->rw_seq[1]= PTHRW_RWLOCK_INIT;
- rwlock->rw_seq[2]= PTHRW_RWS_INIT;
- rwlock->rw_seq[3]= 0;
-#else /* __LP64__ */
- rwlock->rw_lcntaddr = &rwlock->rw_seq[1];
- rwlock->rw_seqaddr = &rwlock->rw_seq[2];
- rwlock->rw_ucntaddr = &rwlock->rw_seq[3];
- rwlock->rw_seq[1]= PTHRW_RWLOCK_INIT;
- rwlock->rw_seq[2]= PTHRW_RWS_INIT;
- rwlock->rw_seq[3]= 0;
-#endif /* __LP64__ */
-
- } else {
- rwlock->misalign = 0;
-#if defined(__LP64__)
- rwlock->rw_lcntaddr = &rwlock->rw_seq[0];
- rwlock->rw_seqaddr = &rwlock->rw_seq[1];
- rwlock->rw_ucntaddr = &rwlock->rw_seq[2];
- rwlock->rw_seq[0]= PTHRW_RWLOCK_INIT;
- rwlock->rw_seq[1]= PTHRW_RWS_INIT;
- rwlock->rw_seq[2]= 0;
-#else /* __LP64__ */
- rwlock->rw_lcntaddr = &rwlock->rw_seq[0];
- rwlock->rw_seqaddr = &rwlock->rw_seq[1];
- rwlock->rw_ucntaddr = &rwlock->rw_seq[2];
- rwlock->rw_seq[0]= PTHRW_RWLOCK_INIT;
- rwlock->rw_seq[1]= PTHRW_RWS_INIT;
- rwlock->rw_seq[2]= 0;
-#endif /* __LP64__ */
-
- }
-
- rwlock->reserv = 0;
- rwlock->rw_owner = NULL;
-#if defined(__LP64__)
- memset(rwlock->rfu, 0, PTHRW_RFU_64BIT);
-#else
- memset(rwlock->rfu, 0, PTHRW_RFU_32BIT);
-#endif
-
- rwlock->sig = _PTHREAD_RWLOCK_SIG;
-
- return(0);
-}
-
-#if _KSYN_TRACE_
-static void
-set_enable(int val)
-{
- int mib[6];
- size_t needed = 0;
-
- mib[0] = CTL_KERN;
- mib[1] = KERN_KDEBUG;
- mib[2] = KERN_KDENABLE;
- mib[3] = val;
- mib[4] = 0;
- mib[5] = 0;
- /* best effort to stop the trace */
- (void)sysctl(mib, 4, NULL, &needed, NULL, 0);
-}
-#endif
-
-static uint32_t
-modbits(uint32_t lgenval, uint32_t updateval, uint32_t savebits)
-{
- uint32_t lval = lgenval & PTHRW_BIT_MASK;
- uint32_t uval = updateval & PTHRW_BIT_MASK;
- uint32_t rval, nlval;
-
- nlval = (lval | uval) & ~(PTH_RWL_MBIT);
-
- /* reconcile bits on the lock with what kernel needs to set */
- if ((uval & PTH_RWL_LBIT) != 0)
- nlval &= ~PTH_RWL_KBIT;
- else if (((uval & PTH_RWL_KBIT) == 0) && ((lval & PTH_RWL_WBIT) == 0))
- nlval &= ~PTH_RWL_KBIT;
-
- if (savebits !=0 ) {
- if (((savebits & PTH_RWS_WSVBIT) != 0) && ((nlval & PTH_RWL_WBIT) == 0) &&
- ((nlval & PTH_RWL_EBIT) == 0)) {
- if ((nlval & PTH_RWL_LBIT) == 0)
- nlval |= (PTH_RWL_WBIT | PTH_RWL_KBIT);
- else
- nlval |= PTH_RWL_WBIT;
- }
- if (((savebits & PTH_RWS_YSVBIT) != 0) && ((nlval & PTH_RWL_YBIT) == 0) &&
- ((nlval & PTH_RWL_EBIT) == 0)) {
- nlval |= PTH_RWL_YBIT;
- }
- if (((savebits & PTH_RWS_USVBIT) != 0) && ((nlval & PTH_RWL_EBIT) == 0)) {
- if ((nlval & PTH_RWL_LBIT) == 0)
- nlval |= (PTH_RWL_UBIT | PTH_RWL_KBIT);
- else
- nlval |= PTH_RWL_UBIT;
- }
- }
- rval = (lgenval & PTHRW_COUNT_MASK) | nlval;
- return(rval);
-}
-
-
-__private_extern__ void
-rwlock_action_onreturn(pthread_rwlock_t * orwlock, uint32_t updateval)
-{
-
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint32_t lcntval, rw_seq, newval = 0, newsval, lval, uval;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
- uint64_t oldval64, newval64;
- int setbits = 0;
- int overlap = 0;
- uint32_t savebits = 0;
- int isoverlap = 0;
-
- /* TBD: restore U bit */
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_START, updateval, 0, 0, 0, 0);
-#endif
-
- isoverlap = updateval & PTH_RWL_MBIT;
-
-loop:
- setbits = 0;
- lcntval = *lcntaddr;
- rw_seq = *seqaddr;
- savebits = 0;
-
- if (isoverlap != 0) {
- /* overlap return, just increment and inspect bits */
- setbits = 1;
- overlap = 1;
- /* set s word, increment by specified value */
- newsval = rw_seq + (updateval & PTHRW_COUNT_MASK);
- if ((newsval & PTHRW_RWS_SAVEMASK) != 0) {
- savebits = newsval & PTHRW_RWS_SAVEMASK;
- newsval &= ~PTHRW_RWS_SAVEMASK;
- }
- } else {
- /* normal return */
- if (is_rws_setunlockinit(rw_seq) != 0) {
- setbits = 1;
- /* set s word to passed in value */
- newsval = (rw_seq & PTHRW_COUNT_MASK) + (updateval & PTHRW_COUNT_MASK);
- if ((rw_seq & PTHRW_RWS_SAVEMASK) != 0) {
- savebits = rw_seq & PTHRW_RWS_SAVEMASK;
- newsval &= ~PTHRW_RWS_SAVEMASK;
- }
- } else {
- newval = lcntval;
- newsval = rw_seq;
- }
- }
- if (setbits != 0) {
- newval = modbits(lcntval, updateval, savebits);
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_NONE, rw_seq, newsval, 0xeeeeeeee, updateval, 0);
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_NONE, lcntval, newval, 0xeeeeeeee, updateval, 0);
-#endif
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
- /* Check for consistency */
- lval = lcntval & PTHRW_BIT_MASK;
- uval = updateval & PTHRW_BIT_MASK;
- }
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNACT1 | DBG_FUNC_END, rw_seq, newsval, 0xffffffff, 0, 0);
-#endif
- return;
-}
-
-/* returns are not bit shifted */
-__private_extern__ int
-rw_diffgenseq(uint32_t x, uint32_t y)
-{
- uint32_t lx = (x & PTHRW_COUNT_MASK);
- uint32_t ly = (y &PTHRW_COUNT_MASK);
-
- if (lx > ly) {
- return(lx-ly);
- } else {
- return((PTHRW_MAX_READERS - y) + lx + PTHRW_INC);
- }
-
-}
-
-#ifdef NOTYET
-/********************************************************** */
-static int pthread_rwlock_upgrade_internal(pthread_rwlock_t * orwlock, int trylock);
-
-int
-pthread_rwlock_longrdlock_np(pthread_rwlock_t * orwlock)
-{
- pthread_t self;
- uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval;
- int error = 0, retry_count = 0;
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint64_t oldval64, newval64;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
- uint64_t myid = 0;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error);
- return(error);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL);
- return(EINVAL);
- }
- UNLOCK(rwlock->lock);
- }
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-loop:
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-
- if (can_rwl_longreadinuser(lcntval))
- goto gotlock;
-
-#if __DARWIN_UNIX03
- if (is_rwl_ebit_set(lcntval)) {
- self = pthread_self();
- if(rwlock->rw_owner == self) {
- error = EDEADLK;
- goto out;
- }
- }
-#endif /* __DARWIN_UNIX03 */
-
- /* need to block in kernel */
- newval = (lcntval + PTHRW_INC);
-
- newsval = rw_seq;
- if (is_rws_setseq(rw_seq)) {
- newsval &= PTHRW_SW_Reset_BIT_MASK;
- newsval |= (newval & PTHRW_COUNT_MASK);
- }
-
- /* update lock seq and block in kernel */
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)(newsval)) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
-kblock:
- updateval = __psynch_rw_longrdlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags);
- if (updateval == (uint32_t)-1) {
- error = errno;
- } else
- error = 0;
-
- if (error == EINTR)
- goto kblock;
-
- if (error == 0) {
- rwlock_action_onreturn(orwlock, updateval);
- if ( is_rwl_lbit_clear(updateval)) {
-#if _KSYN_TRACE_
- set_enable(2);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("yieldwrlock from kernel without EBit %x: tid %x\n", updateval, (uint32_t)myid);
- /* kernel cannot wakeup without granting E bit */
- }
- goto successout;
- } else {
-#if _KSYN_TRACE_
- set_enable(2);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("yieldwrlock from kernel with unknown error %x: tid %x\n", updateval, (uint32_t)myid);
- goto out;
- }
-
-gotlock:
- if (rw_diffgenseq(lcntval, ucntval) >= PTHRW_MAX_READERS) {
- /* since ucntval may be newer, just redo */
- retry_count++;
- if (retry_count > 1024) {
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_TOOMANY | DBG_FUNC_NONE, (uint32_t)rwlock, 0XEEEEEEEE, lcntval, ucntval, 0);
-#endif
- error = EAGAIN;
- goto out;
- } else {
- sched_yield();
- goto loop;
- }
- }
-
- /* Need to update L and S word */
- newval = (lcntval + PTHRW_INC) | PTH_RWL_LBIT;
- newsval = (rw_seq + PTHRW_INC);
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
-
-successout:
- PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT);
- return(0);
-out:
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error);
- return(error);
-}
-
-int
-pthread_rwlock_yieldwrlock_np(pthread_rwlock_t * orwlock)
-{
- uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval;
- int error = 0;
-#if __DARWIN_UNIX03
- pthread_t self = pthread_self();
-#endif /* __DARWIN_UNIX03 */
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint64_t oldval64, newval64;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
- uint64_t myid = 0;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error);
- return(error);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL);
- return(EINVAL);
- }
- UNLOCK(rwlock->lock);
- }
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-loop:
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-
-#if __DARWIN_UNIX03
- if (is_rwl_ebit_set(lcntval)) {
- if (rwlock->rw_owner == self) {
- error = EDEADLK;
- goto out;
- }
- }
-#endif /* __DARWIN_UNIX03 */
-
- if (lcntval == PTHRW_RWL_INIT) {
- /* if we can acquire set L and S word */
- lcntval = PTHRW_RWL_INIT;
- newval = PTHRW_RWL_INIT | PTHRW_INC | PTH_RWL_KBIT| PTH_RWL_EBIT;
- newsval = rw_seq + PTHRW_INC;
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) == TRUE) {
- goto gotit;
- } else
- goto loop;
- }
-
- newval = (lcntval + PTHRW_INC)| PTH_RWL_YBIT;
-
- newsval = rw_seq;
- if (is_rws_setseq(rw_seq)) {
- newsval &= PTHRW_SW_Reset_BIT_MASK;
- newsval |= (newval & PTHRW_COUNT_MASK);
- }
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)(newsval)) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
-
- PLOCKSTAT_RW_BLOCK(orwlock, WRITE_LOCK_PLOCKSTAT);
-retry:
- updateval = __psynch_rw_yieldwrlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags);
- if (updateval == (uint32_t)-1) {
- error = errno;
- } else
- error = 0;
-
- if (error == EINTR)
- goto retry;
-
-
- PLOCKSTAT_RW_BLOCKED(orwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT);
- if (error != 0) {
-#if _KSYN_TRACE_
- set_enable(2);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("yieldwrlock from kernel with unknown error %x: tid %x\n", updateval, (uint32_t)myid);
- }
-
-
-out:
- if (error == 0) {
-gotit:
- rwlock_action_onreturn(orwlock, updateval);
- if ( is_rwl_ebit_clear(updateval)) {
-#if _KSYN_TRACE_
- set_enable(2);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("yieldwrlock from kernel without EBit %x: tid %x\n", updateval, (uint32_t)myid);
- }
-#if __DARWIN_UNIX03
- rwlock->rw_owner = self;
-#endif /* __DARWIN_UNIX03 */
- PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT);
- return(0);
- } else {
- PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error);
- return(error);
- }
-}
-int
-pthread_rwlock_downgrade_np(pthread_rwlock_t * orwlock)
-{
- uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval;
- int error = 0, haswbit = 0, hasubit = 0, hasybit = 0;
-#if __DARWIN_UNIX03
- pthread_t self = pthread_self();
-#endif /* __DARWIN_UNIX03 */
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint64_t oldval64, newval64;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
- uint64_t myid = 0;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error);
- return(error);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL);
- return(EINVAL);
- }
- UNLOCK(rwlock->lock);
- }
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-loop:
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-
-
- /* if not holding exclusive lock, return */
- if ((is_rwl_ebit_set(lcntval )== 0) || (rwlock->rw_owner != self)) {
- return(EINVAL);
- }
-
- /* no other waiters and be granted in user space? ? */
- if ((lcntval & PTHRW_COUNT_MASK) == (ucntval + PTHRW_INC)) {
-#if 0
- /* should have no write waiters pending */
- if (is_rwl_wbit_set(lcntval) != 0) {
-#if _KSYN_TRACE_
- set_enable(2);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("downgrade in user mode but W bit set %x: tid %x\n", lcntval, (uint32_t)myid);
- }
-#endif
- /* preserve count and remove ke bits */
- newval = lcntval & ~(PTH_RWL_EBIT | PTH_RWL_KBIT);
- /* if we can acquire set L and S word */
- newsval = rw_seq;
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) == TRUE) {
-#if __DARWIN_UNIX03
- rwlock->rw_owner = (pthread_t)0;
-#endif /* __DARWIN_UNIX03 */
- return(0);
- } else
- goto loop;
- } else {
-
- haswbit = lcntval & PTH_RWL_WBIT;
- hasubit = lcntval & PTH_RWL_UBIT;
- hasybit = lcntval & PTH_RWL_YBIT;
-
- /* reset all bits and set k */
- newval = (lcntval & PTHRW_COUNT_MASK) | PTH_RWL_KBIT;
- /* set I bit on S word */
- newsval = rw_seq | PTH_RWS_IBIT;
- if (haswbit != 0)
- newsval |= PTH_RWS_WSVBIT;
- if (hasubit != 0)
- newsval |= PTH_RWS_USVBIT;
- if (hasybit != 0)
- newsval |= PTH_RWS_YSVBIT;
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
-
-#if __DARWIN_UNIX03
- rwlock->rw_owner = 0;
-#endif /* __DARWIN_UNIX03 */
-
-retry:
- updateval = __psynch_rw_downgrade(orwlock, newval, ucntval, newsval, rwlock->rw_flags);
- if (updateval == (uint32_t)-1) {
- error = errno;
- } else
- error = 0;
-
- /* TBD: what to do with the error, EINTR ?? */
- if (error == EINTR)
- goto retry;
-
- if (error == 0) {
- rwlock_action_onreturn(orwlock, updateval);
- return(0);
- } else {
-#if _KSYN_TRACE_
- set_enable(1);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("downgrade from kernel with unknown error %x with tid %x\n", updateval, (uint32_t)myid);
- }
- /* Not reached */
- }
- return(EINVAL);
-}
-
-int
-pthread_rwlock_upgrade_np(pthread_rwlock_t * orwlock)
-{
- return(pthread_rwlock_upgrade_internal(orwlock, 0));
-}
-
-int
-pthread_rwlock_tryupgrade_np(pthread_rwlock_t *orwlock)
-{
- return(pthread_rwlock_upgrade_internal(orwlock, 1));
-}
-
-static int
-pthread_rwlock_upgrade_internal(pthread_rwlock_t * orwlock, int trylock)
-{
- uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval;
- int error = 0, flags ;
-#if __DARWIN_UNIX03
- pthread_t self = pthread_self();
-#endif /* __DARWIN_UNIX03 */
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint64_t oldval64, newval64;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
- uint64_t myid = 0;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- /* check for static initialization */
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- return(error);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- return(EINVAL);
- }
- UNLOCK(rwlock->lock);
- }
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-loop:
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-
- if (is_rwl_eubit_set(lcntval) !=0) {
- return(EBUSY);
- }
-
- /* set U and K bit and go to kernel */
- newval = (lcntval | (PTH_RWL_UBIT | PTH_RWL_KBIT));
- newsval = rw_seq;
-#if 0
- if (is_rws_setseq(rw_seq)) {
- newsval &= PTHRW_SW_Reset_BIT_MASK;
- newsval |= (newval & PTHRW_COUNT_MASK);
- }
-#endif
-
- /* update lock seq and block in kernel */
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)(newsval)) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
- flags = rwlock->rw_flags;
- if (trylock != 0) {
- flags |= _PTHREAD_RWLOCK_UPGRADE_TRY;
- }
-retry:
- updateval = __psynch_rw_upgrade(orwlock, newval, ucntval, newsval, rwlock->rw_flags);
- if (updateval == (uint32_t)-1) {
- error = errno;
- } else
- error = 0;
-
- if (error == EINTR)
- goto retry;
-
-
- if (error == 0) {
- rwlock_action_onreturn(orwlock, updateval);
- if ( is_rwl_ebit_clear(updateval)) {
-#if _KSYN_TRACE_
- set_enable(2);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("upgrade from kernel without EBit %x: tid %x\n", updateval, (uint32_t)myid);
- }
-#if __DARWIN_UNIX03
- rwlock->rw_owner = self;
-#endif /* __DARWIN_UNIX03 */
- return(0);
- } else {
- if (trylock != 0) {
- return (EBUSY);
- }
- }
-
- return(error);
-}
-
-/* Returns true if the rwlock is held for reading by any thread or held for writing by the current thread */
-int
-pthread_rwlock_held_np(pthread_rwlock_t * orwlock)
-{
- uint32_t lcntval, ucntval, rw_seq;
- int error = 0;
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- return(0);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- return(-1);
- }
- UNLOCK(rwlock->lock);
- }
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-
- if ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK))
- return(0);
-
- return(1);
-}
-
-/* Returns true if the rwlock is held for reading by any thread */
-int
-pthread_rwlock_rdheld_np(pthread_rwlock_t * orwlock)
-{
- uint32_t lcntval, ucntval, rw_seq;
- int error = 0;
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- return(0);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- return(-1);
- }
- UNLOCK(rwlock->lock);
- }
-
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-
- if ((lcntval & PTHRW_COUNT_MASK) == (ucntval & PTHRW_COUNT_MASK))
- return(0);
-
- if (is_rwl_ebit_set(lcntval) !=0) {
- return(0);
- }
- return(1);
-}
-
-/* Returns true if the rwlock is held for writing by the current thread */
-int
-pthread_rwlock_wrheld_np(pthread_rwlock_t * orwlock)
-{
- uint32_t lcntval, ucntval, rw_seq;
- pthread_t self = pthread_self();
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
- int error = 0;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- return(0);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- return(-1);
- }
- UNLOCK(rwlock->lock);
- }
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-
- if ((is_rwl_ebit_set(lcntval)) && (rwlock->rw_owner == self)) {
- return(1);
- }
- return(0);
-}
-/******************************************************/
-#endif /* NOTYET */
-
-
-#endif /* !BUILDING_VARIANT ] */
-
-int
-pthread_rwlock_destroy(pthread_rwlock_t *orwlock)
-{
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
-#if __DARWIN_UNIX03
- uint32_t rw_lcnt, rw_ucnt;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
-#endif /* __DARWIN_UNIX03 */
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG && rwlock->sig != _PTHREAD_RWLOCK_SIG_init)
- return(EINVAL);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG) {
-#if __DARWIN_UNIX03
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
- rw_lcnt = *lcntaddr;
- rw_ucnt = *ucntaddr;
-
- if((rw_lcnt & PTHRW_COUNT_MASK) != rw_ucnt)
- return(EBUSY);
-
-#endif /* __DARWIN_UNIX03 */
- //bzero(rwlock, sizeof(npthread_rwlock_t));
- rwlock->sig = _PTHREAD_NO_SIG;
- return(0);
- } else if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- rwlock->sig = _PTHREAD_NO_SIG;
- return(0);
- } else
- return(EINVAL);
-}
-
-
-int
-pthread_rwlock_init(pthread_rwlock_t * orwlock, const pthread_rwlockattr_t *attr)
-{
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
-#if __DARWIN_UNIX03
- uint32_t rw_lcnt, rw_ucnt;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
-#endif /* __DARWIN_UNIX03 */
-
-#if __DARWIN_UNIX03
- if (attr && (attr->sig != _PTHREAD_RWLOCK_ATTR_SIG)) {
- return(EINVAL);
- }
-
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG) {
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
- rw_lcnt = *lcntaddr;
- rw_ucnt = *ucntaddr;
-
- if ((rw_lcnt & PTHRW_COUNT_MASK) != rw_ucnt)
- return(EBUSY);
-
- }
-#endif
- LOCK_INIT(rwlock->lock);
- return(__pthread_rwlock_init(orwlock, attr));
-
-}
-
-int
-pthread_rwlock_rdlock(pthread_rwlock_t * orwlock)
-{
-#if __DARWIN_UNIX03
- pthread_t self;
-#endif /* __DARWIN_UNIX03 */
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval;
- int error = 0, retry_count = 0;
- uint64_t oldval64, newval64;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
- uint64_t myid = 0;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error);
- return(error);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL);
- return(EINVAL);
- }
- UNLOCK(rwlock->lock);
- }
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0);
-#endif
-loop:
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lcntval, (ucntval | 0xee), rw_seq, 0);
-#endif
-
- /* if l bit is on or u and k bit is clear, acquire lock in userland */
- if (can_rwl_readinuser(lcntval))
- goto gotlock;
-
-#if __DARWIN_UNIX03
- if (is_rwl_ebit_set(lcntval)) {
- self = pthread_self();
- if(rwlock->rw_owner == self) {
- error = EDEADLK;
- goto out;
- }
- }
-#endif /* __DARWIN_UNIX03 */
-
-
- /* Need to block in kernel , remove Rbit */
- newval = (lcntval + PTHRW_INC) & PTH_RWLOCK_RESET_RBIT;
-
- newsval = rw_seq;
- if (is_rws_setseq(rw_seq)) {
- newsval &= PTHRW_SW_Reset_BIT_MASK;
- newsval |= (newval & PTHRW_COUNT_MASK);
- }
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
-
- /* give writers priority over readers */
- PLOCKSTAT_RW_BLOCK(orwlock, READ_LOCK_PLOCKSTAT);
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lcntval, newval, newsval, 0);
-#endif
-
-retry:
- updateval = __psynch_rw_rdlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags);
-
- if (updateval == (uint32_t)-1) {
- error = errno;
- } else
- error = 0;
-
- if (error == EINTR)
- goto retry;
-
- if (error == 0) {
- rwlock_action_onreturn(orwlock, updateval);
- PLOCKSTAT_RW_BLOCKED(orwlock, READ_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT);
- PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT);
- return(0);
- } else {
- PLOCKSTAT_RW_BLOCKED(orwlock, READ_LOCK_PLOCKSTAT, BLOCK_FAIL_PLOCKSTAT);
-#if _KSYN_TRACE_
- set_enable(1);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("rdlock from kernel with unknown error %x with tid %x\n", updateval, (uint32_t)myid);
- goto out;
- }
- /* Not reached */
-
-gotlock:
- if (rw_diffgenseq(lcntval, ucntval) >= PTHRW_MAX_READERS) {
- /* since ucntval may be newer, just redo */
- retry_count++;
- if (retry_count > 1024) {
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_TOOMANY | DBG_FUNC_NONE, (uint32_t)rwlock, 0XEEEEEEEE, lcntval, ucntval, 0);
-#endif
- error = EAGAIN;
- goto out;
- } else {
- sched_yield();
- goto loop;
- }
- }
-
- /* Need to update L (remove R bit) and S word */
- newval = (lcntval + PTHRW_INC) & PTH_RWLOCK_RESET_RBIT;
- newsval = (rw_seq + PTHRW_INC);
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lcntval, newval, 0);
-#endif
-
- PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT);
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, 0, 0, 0);
-#endif
- return(0);
-out:
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error);
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_RDLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0);
-#endif
- return(error);
-}
-
-int
-pthread_rwlock_tryrdlock(pthread_rwlock_t * orwlock)
-{
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint32_t lcntval, ucntval, rw_seq, newval, newsval;
- int error = 0, retry_count = 0;
- uint64_t oldval64, newval64;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error);
- return(error);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, EINVAL);
- return(EINVAL);
- }
- UNLOCK(rwlock->lock);
- }
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-loop:
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_TRYRDLOCK | DBG_FUNC_START, (uint32_t)rwlock, lcntval, ucntval, rw_seq, 0);
-#endif
-
- /* if l bit is on or u and k bit is clear, acquire lock in userland */
- if (can_rwl_readinuser(lcntval))
- goto gotlock;
-
- error = EBUSY;
- goto out;
-
-gotlock:
- if (rw_diffgenseq(lcntval, ucntval) >= PTHRW_MAX_READERS) {
- /* since ucntval may be newer, just redo */
- retry_count++;
- if (retry_count > 1024) {
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_TOOMANY | DBG_FUNC_NONE, (uint32_t)rwlock, 0XEEEEEEEE, lcntval, ucntval, 0);
-#endif
- error = EAGAIN;
- goto out;
- } else {
- sched_yield();
- goto loop;
- }
- }
-
- /* Need to update L(remove Rbit ) and S word */
- newval = (lcntval + PTHRW_INC) & PTH_RWLOCK_RESET_RBIT;
- newsval = (rw_seq + PTHRW_INC);
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_TRYRDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lcntval, newval, 0);
-#endif
-
- PLOCKSTAT_RW_ACQUIRE(orwlock, READ_LOCK_PLOCKSTAT);
- return(0);
-
-out:
- PLOCKSTAT_RW_ERROR(orwlock, READ_LOCK_PLOCKSTAT, error);
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_TRYRDLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, error, 0, 0);
-#endif
- return(error);
-}
-
-int
-pthread_rwlock_trywrlock(pthread_rwlock_t * orwlock)
-{
-#if __DARWIN_UNIX03
- pthread_t self = pthread_self();
-#endif /* __DARWIN_UNIX03 */
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint32_t lcntval, rw_seq, newval, newsval;
- int error = 0, gotlock = 0;
- uint64_t oldval64, newval64;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error);
- return(error);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL);
- return(EINVAL);
- }
- UNLOCK(rwlock->lock);
- }
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_TRYWRLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0);
-#endif
-loop:
- lcntval = *lcntaddr;
- rw_seq = *seqaddr;
-
- /* can we acquire in userland? */
- if ((lcntval & PTH_RWL_RBIT) != 0) {
- newval = ((lcntval + PTHRW_INC) & PTHRW_COUNT_MASK) | PTH_RWL_IBIT | PTH_RWL_KBIT| PTH_RWL_EBIT;
- newsval = rw_seq + PTHRW_INC;
- gotlock = 1;
- } else
- gotlock = 0;
-
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- if (gotlock != 0) {
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
- } else
- newval64 = oldval64;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) {
- goto loop;
- }
- if (gotlock == 1) {
-#if __DARWIN_UNIX03
- rwlock->rw_owner = self;
-#endif /* __DARWIN_UNIX03 */
- PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT);
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_TRYWRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0, 0, 0, 0);
-#endif
- return(0);
- } else {
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_TRYWRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, EBUSY, 0, 0);
-#endif
-
- PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EBUSY);
- return(EBUSY);
- }
-}
-
-int
-pthread_rwlock_wrlock(pthread_rwlock_t * orwlock)
-{
-#if __DARWIN_UNIX03
- pthread_t self = pthread_self();
-#endif /* __DARWIN_UNIX03 */
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval;
- int error = 0, gotlock = 0;
- uint64_t oldval64, newval64;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
- uint64_t myid = 0;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error);
- return(error);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, EINVAL);
- return(EINVAL);
- }
- UNLOCK(rwlock->lock);
- }
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0);
-#endif
-loop:
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, lcntval, ucntval, rw_seq, 0);
-#endif
-
-#if __DARWIN_UNIX03
- if (is_rwl_ebit_set(lcntval)) {
- if(rwlock->rw_owner == self) {
- error = EDEADLK;
- goto out;
- }
- }
-#endif /* __DARWIN_UNIX03 */
-
-
- if ((lcntval & PTH_RWL_RBIT) != 0) {
- /* lock is restart state, writer can acquire the lock */
- newval = ((lcntval + PTHRW_INC) & PTHRW_COUNT_MASK) | PTH_RWL_IBIT | PTH_RWL_KBIT| PTH_RWL_EBIT;
-
- newsval = rw_seq + PTHRW_INC;
- gotlock = 1;
-
- } else {
- if (is_rwl_lbit_set(lcntval))
- newval = (lcntval + PTHRW_INC)| PTH_RWL_WBIT;
- else
- newval = (lcntval + PTHRW_INC) | PTH_RWL_KBIT| PTH_RWL_WBIT;
-
- newsval = rw_seq;
- if (is_rws_setseq(rw_seq)) {
- newsval &= PTHRW_SW_Reset_BIT_MASK;
- newsval |= (newval & PTHRW_COUNT_MASK);
- }
- gotlock = 0;
- }
-
- /* update lock seq */
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555555, lcntval, newval, 0);
-#endif
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto loop;
-
- /* lock acquired in userland itself? */
- if (gotlock != 0)
- goto gotit;
-
- /* unable to acquire in userland, transition to kernel */
-
- PLOCKSTAT_RW_BLOCK(orwlock, WRITE_LOCK_PLOCKSTAT);
-retry:
- updateval = __psynch_rw_wrlock(orwlock, newval, ucntval, newsval, rwlock->rw_flags);
- if (updateval == (uint32_t)-1) {
- error = errno;
- } else
- error = 0;
-
- if (error == EINTR) {
- goto retry;
- }
-
- if (error != 0) {
-#if _KSYN_TRACE_
- set_enable(2);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("wrlock from kernel with unknown error %x: tid %x\n", updateval, (uint32_t)myid);
- }
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x33333333, newval, updateval, 0);
-#endif
- PLOCKSTAT_RW_BLOCKED(orwlock, WRITE_LOCK_PLOCKSTAT, BLOCK_SUCCESS_PLOCKSTAT);
- if (error == 0) {
- rwlock_action_onreturn(orwlock, updateval);
-gotit:
-#if __DARWIN_UNIX03
- rwlock->rw_owner = self;
-#endif /* __DARWIN_UNIX03 */
- PLOCKSTAT_RW_ACQUIRE(orwlock, WRITE_LOCK_PLOCKSTAT);
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0);
-#endif
- return(0);
- }
-#if __DARWIN_UNIX03
-out:
-#endif /* __DARWIN_UNIX03 */
- PLOCKSTAT_RW_ERROR(orwlock, WRITE_LOCK_PLOCKSTAT, error);
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_WRLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0);
-#endif
- return(error);
-}
-
-
-int
-pthread_rwlock_unlock(pthread_rwlock_t * orwlock)
-{
- npthread_rwlock_t * rwlock = (npthread_rwlock_t *)orwlock;
- uint32_t lcntval, ucntval, rw_seq, newval, newsval, updateval, ulval;
- int error = 0, wrlock = 0, haswbit = 0, hasubit = 0, hasybit = 0;
- uint64_t oldval64, newval64;
- volatile uint32_t * lcntaddr, *ucntaddr, *seqaddr;
- uint64_t myid = 0;
-
- if (rwlock->sig != _PTHREAD_RWLOCK_SIG) {
- LOCK(rwlock->lock);
- if (rwlock->sig == _PTHREAD_RWLOCK_SIG_init) {
- if ((error = __pthread_rwlock_init(orwlock, NULL)) != 0) {
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, wrlock, error);
- return(error);
- }
- } else if (rwlock->sig != _PTHREAD_RWLOCK_SIG){
- UNLOCK(rwlock->lock);
- PLOCKSTAT_RW_ERROR(orwlock, wrlock, EINVAL);
- return(EINVAL);
- }
- UNLOCK(rwlock->lock);
- }
-
- if (rwlock->pshared == PTHREAD_PROCESS_SHARED) {
- RWLOCK_GETSEQ_ADDR(rwlock, lcntaddr, ucntaddr, seqaddr);
- } else {
- lcntaddr = rwlock->rw_lcntaddr;
- ucntaddr = rwlock->rw_ucntaddr;
- seqaddr = rwlock->rw_seqaddr;
- }
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_START, (uint32_t)rwlock, 0, 0, 0, 0);
-#endif
-loop:
- lcntval = *lcntaddr;
- ucntval = *ucntaddr;
- rw_seq = *seqaddr;
-
-
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x51515151, lcntval, ucntval, 0);
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x51515151, rw_seq, 0, 0);
-#endif
- /* check for spurious unlocks */
- if ((lcntval & PTH_RWL_RBIT) != 0) {
- newval = lcntval ;
- newsval = rw_seq;
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) == TRUE) {
- /* spurious unlock, return */
- error = EINVAL;
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x1a1b1c1d, lcntval, ucntval, 0);
-#endif
- goto succout;
- } else
- goto loop;
- }
-
- if (is_rwl_ebit_set(lcntval)) {
- wrlock = 1;
-#if __DARWIN_UNIX03
- rwlock->rw_owner = (pthread_t)0;
-#endif /* __DARWIN_UNIX03 */
- }
-
- /* update U */
-
- ulval = (ucntval + PTHRW_INC);
-
- if (OSAtomicCompareAndSwap32Barrier(ucntval, ulval, (volatile int32_t *)ucntaddr) != TRUE)
- goto loop;
-
-lp11:
- /* just validate the l and S values */
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = oldval64;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) {
- lcntval = *lcntaddr;
- rw_seq = *seqaddr;
- goto lp11;
- }
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xd1d2d3d4, lcntval, rw_seq, 0);
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xd1d2d3d4, ulval, 0, 0);
-#endif
-
- /* last unlock, note U is already updated ? */
- if((lcntval & PTHRW_COUNT_MASK) == (ulval & PTHRW_COUNT_MASK)) {
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xbbbbbbbb, lcntval, ucntval, 0);
-#endif
- /* Set L with R and init bits and set S to L */
- newval = (lcntval & PTHRW_COUNT_MASK)| PTHRW_RWLOCK_INIT;
- newsval = (lcntval & PTHRW_COUNT_MASK)| PTHRW_RWS_INIT;
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE) {
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xcccccccc, 0, 0, 0);
-#endif
- lcntval = *lcntaddr;
- rw_seq = *seqaddr;
- goto lp11;
- }
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0xdddddddd, lcntval, ucntval, 0);
-#endif
- goto succout;
- }
-
- /* if it is not exclusive or no Writer/yield pending, skip */
- if ((lcntval & (PTH_RWL_EBIT | PTH_RWL_WBIT | PTH_RWL_YBIT | PTH_RWL_KBIT)) == 0) {
- goto succout;
- }
-
- /* kernel transition needed? */
- /* U+1 == S? */
- if ((ulval + PTHRW_INC) != (rw_seq & PTHRW_COUNT_MASK)) {
- if ((lcntval & PTH_RWL_UBIT) != 0) {
- /* if U bit is set U + 2 == S ? */
- if ((ulval + PTHRW_INC + PTHRW_INC) != (rw_seq & PTHRW_COUNT_MASK))
- goto succout;
- } else
- goto succout;
- }
-
- haswbit = lcntval & PTH_RWL_WBIT;
- hasubit = lcntval & PTH_RWL_UBIT;
- hasybit = lcntval & PTH_RWL_YBIT;
-
- /* reset all bits and set k */
- newval = (lcntval & PTHRW_COUNT_MASK) | PTH_RWL_KBIT;
- /* set I bit on S word */
- newsval = rw_seq | PTH_RWS_IBIT;
- if (haswbit != 0)
- newsval |= PTH_RWS_WSVBIT;
- if (hasubit != 0)
- newsval |= PTH_RWS_USVBIT;
- if (hasybit != 0)
- newsval |= PTH_RWS_YSVBIT;
-
- oldval64 = (((uint64_t)rw_seq) << 32);
- oldval64 |= lcntval;
-
- newval64 = (((uint64_t)newsval) << 32);
- newval64 |= newval;
-
- if (OSAtomicCompareAndSwap64Barrier(oldval64, newval64, (volatile int64_t *)lcntaddr) != TRUE)
- goto lp11;
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555511, 1, ulval, 0);
-#endif
- updateval = __psynch_rw_unlock(orwlock, lcntval, ulval, newsval, rwlock->rw_flags);
- if (updateval == (uint32_t)-1) {
- error = errno;
- } else
- error = 0;
-
- if(error != 0) {
-
- /* not sure what is the scenario */
- if(error != EINTR) {
-#if _KSYN_TRACE_
- set_enable(4);
-#endif /* _KSYN_TRACE_ */
- (void)pthread_threadid_np(pthread_self(), &myid);
- LIBC_ABORT("rwunlock from kernel with unknown error %x: tid %x\n", error, (uint32_t)myid);
- goto succout;
- }
- error = 0;
- }
-
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_NONE, (uint32_t)rwlock, 0x55555522, 3, lcntval, 0);
-#endif
-
-succout:
- PLOCKSTAT_RW_RELEASE(orwlock, wrlock);
-#if _KSYN_TRACE_
- if (__pthread_lock_debug != 0)
- (void)__kdebug_trace(_KSYN_TRACE_RW_UNLOCK | DBG_FUNC_END, (uint32_t)rwlock, 0xAAAAAAAA, error, 0, 0);
-#endif
- return(0);
-}
-
+++ /dev/null
-.\" Copyright (c) 1998 Alex Nash
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_destroy.3,v 1.6 2001/10/01 16:09:09 ru Exp $
-.\"
-.Dd August 4, 1998
-.Dt PTHREAD_RWLOCK_DESTROY 3
-.Os
-.Sh NAME
-.Nm pthread_rwlock_destroy
-.Nd destroy a read/write lock
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_rwlock_destroy
-.Fa "pthread_rwlock_t *rwlock"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_rwlock_destroy
-function is used to destroy a read/write lock previously created with
-.Fn pthread_rwlock_init .
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlock_destroy
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh SEE ALSO
-.Xr pthread_rwlock_init 3
-.Sh STANDARDS
-The
-.Fn pthread_rwlock_destroy
-function is expected to conform to
-.St -susv2 .
-.Sh ERRORS
-The
-.Fn pthread_rwlock_destroy
-function will fail if:
-.Bl -tag -width Er
-.It Bq Er EPERM
-The caller does not have the privilege to perform the operation.
-.El
-.Pp
-The
-.Fn pthread_rwlock_destroy
-function may fail if:
-.Bl -tag -width Er
-.It Bq Er EBUSY
-The system has detected an attempt to destroy the object referenced by
-.Fa rwlock
-while it is locked.
-.It Bq Er EINVAL
-The value specified by
-.Fa rwlock
-is invalid.
-.El
-.Sh HISTORY
-The
-.Fn pthread_rwlock_destroy
-function first appeared in
-.Fx 3.0 .
+++ /dev/null
-.\" Copyright (c) 1998 Alex Nash
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_init.3,v 1.5 2001/10/01 16:09:09 ru Exp $
-.\"
-.Dd August 4, 1998
-.Dt PTHREAD_RWLOCK_INIT 3
-.Os
-.Sh NAME
-.Nm pthread_rwlock_init
-.Nd initialize a read/write lock
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_rwlock_init
-.Fa "pthread_rwlock_t *restrict rwlock"
-.Fa "const pthread_rwlockattr_t *restrict attr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_rwlock_init
-function is used to initialize a read/write lock, with attributes
-specified by
-.Fa attr .
-If
-.Fa attr
-is NULL, the default read/write lock attributes are used.
-.Pp
-The results of calling
-.Fn pthread_rwlock_init
-with an already initialized lock are undefined.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlock_init
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh SEE ALSO
-.Xr pthread_rwlock_destroy 3 ,
-.Xr pthread_rwlockattr_init 3 ,
-.Xr pthread_rwlockattr_setpshared 3
-.Sh STANDARDS
-The
-.Fn pthread_rwlock_init
-function is expected to conform to
-.St -susv2 .
-.Sh ERRORS
-The
-.Fn pthread_rwlock_init
-function will fail if:
-.Bl -tag -width Er
-.It Bq Er EAGAIN
-The system lacked the necessary resources (other than memory) to
-initialize the lock.
-.It Bq Er ENOMEM
-Insufficient memory exists to initialize the lock.
-.It Bq Er EPERM
-The caller does not have sufficient privilege to perform the
-operation.
-.El
-.Pp
-The
-.Fn pthread_rwlock_init
-function may fail if:
-.Bl -tag -width Er
-.It Bq Er EBUSY
-The system has detected an attempt to re-initialize the object
-referenced by
-.Fa rwlock ,
-a previously initialized but not yet destroyed read/write lock.
-.It Bq Er EINVAL
-The value specified by
-.Fa attr
-is invalid.
-.El
-.Sh HISTORY
-The
-.Fn pthread_rwlock_init
-function first appeared in
-.Fx 3.0 .
-.Sh BUGS
-The PTHREAD_PROCESS_SHARED attribute is not supported.
+++ /dev/null
-.\" Copyright (c) 1998 Alex Nash
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_rdlock.3,v 1.4 2001/10/01 16:09:09 ru Exp $
-.\"
-.Dd August 4, 1998
-.Dt PTHREAD_RWLOCK_RDLOCK 3
-.Os
-.Sh NAME
-.Nm pthread_rwlock_rdlock ,
-.Nm pthread_rwlock_tryrdlock
-.Nd acquire a read/write lock for reading
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_rwlock_rdlock
-.Fa "pthread_rwlock_t *rwlock"
-.Fc
-.Ft int
-.Fo pthread_rwlock_tryrdlock
-.Fa "pthread_rwlock_t *rwlock"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_rwlock_rdlock
-function acquires a read lock on
-.Fa rwlock ,
-provided that
-.Fa rwlock
-is not presently held for writing and no writer threads are
-presently blocked on the lock. If the read lock cannot be
-immediately acquired, the calling thread blocks until it can
-acquire the lock.
-.Pp
-The
-.Fn pthread_rwlock_tryrdlock
-function performs the same action, but does not block if the lock
-cannot be immediately obtained (i.e., the lock is held for writing
-or there are waiting writers).
-.Pp
-A thread may hold multiple concurrent read locks. If so,
-.Fn pthread_rwlock_unlock
-must be called once for each lock obtained.
-.Pp
-The results of acquiring a read lock while the calling thread holds
-a write lock are undefined.
-.Sh IMPLEMENTATION NOTES
-To prevent writer starvation, writers are favored over readers.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlock_rdlock
-and
-.Fn pthread_rwlock_tryrdlock
-functions will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh SEE ALSO
-.Xr pthread_rwlock_init 3 ,
-.Xr pthread_rwlock_trywrlock 3 ,
-.Xr pthread_rwlock_unlock 3 ,
-.Xr pthread_rwlock_wrlock 3
-.Sh STANDARDS
-The
-.Fn pthread_rwlock_rdlock
-and
-.Fn pthread_rwlock_tryrdlock
-functions are expected to conform to
-.St -susv2 .
-.Sh ERRORS
-The
-.Fn pthread_rwlock_tryrdlock
-function will fail if:
-.Bl -tag -width Er
-.It Bq Er EBUSY
-The lock could not be acquired, because a writer holds the lock or
-was blocked on it.
-.El
-.Pp
-The
-.Fn pthread_rwlock_rdlock
-and
-.Fn pthread_rwlock_tryrdlock
-functions may fail if:
-.Bl -tag -width Er
-.It Bq Er EAGAIN
-The lock could not be acquired, because the maximum number of read locks
-against
-.Fa lock
-has been exceeded.
-.It Bq Er EDEADLK
-The current thread already owns
-.Fa rwlock
-for writing.
-.It Bq Er EINVAL
-The value specified by
-.Fa rwlock
-is invalid.
-.It Bq Er ENOMEM
-Insufficient memory exists to initialize the lock (applies to
-statically initialized locks only).
-.El
-.Sh HISTORY
-The
-.Fn pthread_rwlock_rdlock
-function first appeared in
-.Fx 3.0 .
+++ /dev/null
-.\" Copyright (c) 1998 Alex Nash
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_unlock.3,v 1.4 2001/10/01 16:09:09 ru Exp $
-.\"
-.Dd August 4, 1998
-.Dt PTHREAD_RWLOCK_UNLOCK 3
-.Os
-.Sh NAME
-.Nm pthread_rwlock_unlock
-.Nd release a read/write lock
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_rwlock_unlock
-.Fa "pthread_rwlock_t *rwlock"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_rwlock_unlock
-function is used to release the read/write lock previously obtained by
-.Fn pthread_rwlock_rdlock ,
-.Fn pthread_rwlock_wrlock ,
-.Fn pthread_rwlock_tryrdlock ,
-or
-.Fn pthread_rwlock_trywrlock .
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlock_unlock
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Pp
-The results are undefined if
-.Fa rwlock
-is not held by the calling thread.
-.Sh SEE ALSO
-.Xr pthread_rwlock_rdlock 3 ,
-.Xr pthread_rwlock_wrlock 3
-.Sh STANDARDS
-The
-.Fn pthread_rwlock_unlock
-function is expected to conform to
-.St -susv2 .
-.Sh ERRORS
-The
-.Fn pthread_rwlock_unlock
-function may fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
-.Fa rwlock
-is invalid.
-.It Bq Er EPERM
-The current thread does not own the read/write lock.
-.El
-.Sh HISTORY
-The
-.Fn pthread_rwlock_unlock
-function first appeared in
-.Fx 3.0 .
+++ /dev/null
-.\" Copyright (c) 1998 Alex Nash
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlock_wrlock.3,v 1.4 2001/10/01 16:09:09 ru Exp $
-.\"
-.Dd August 4, 1998
-.Dt PTHREAD_RWLOCK_WRLOCK 3
-.Os
-.Sh NAME
-.Nm pthread_rwlock_trywrlock ,
-.Nm pthread_rwlock_wrlock
-.Nd acquire a read/write lock for writing
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_rwlock_trywrlock
-.Fa "pthread_rwlock_t *rwlock"
-.Fc
-.Ft int
-.Fo pthread_rwlock_wrlock
-.Fa "pthread_rwlock_t *rwlock"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_rwlock_wrlock
-function blocks until a write lock can be acquired against
-.Fa rwlock .
-The
-.Fn pthread_rwlock_trywrlock
-function performs the same action, but does not block if the lock
-cannot be immediately obtained.
-.Pp
-The results are undefined if the calling thread already holds the
-lock at the time the call is made.
-.Sh IMPLEMENTATION NOTES
-To prevent writer starvation, writers are favored over readers.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlock_wrlock
-and
-.Fn pthread_rwlock_trywrlock
-functions will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh SEE ALSO
-.Xr pthread_rwlock_trywrlock 3 ,
-.Xr pthread_rwlock_unlock 3 ,
-.Xr pthread_rwlock_wrlock 3
-.Sh STANDARDS
-The
-.Fn pthread_rwlock_wrlock
-and
-.Fn pthread_rwlock_trywrlock
-functions are expected to conform to
-.St -susv2 .
-.Sh ERRORS
-The
-.Fn pthread_rwlock_trywrlock
-function will fail if:
-.Bl -tag -width Er
-.It Bq Er EBUSY
-The calling thread is not able to acquire the lock without blocking.
-.El
-.Pp
-The
-.Fn pthread_rwlock_wrlock
-and
-.Fn pthread_rwlock_trywrlock
-functions may fail if:
-.Bl -tag -width Er
-.It Bq Er EDEADLK
-The calling thread already owns the read/write lock (for reading
-or writing).
-.It Bq Er EINVAL
-The value specified by
-.Fa rwlock
-is invalid.
-.It Bq Er ENOMEM
-Insufficient memory exists to initialize the lock (applies to
-statically initialized locks only).
-.El
-.Sh HISTORY
-The
-.Fn pthread_rwlock_wrlock
-function first appeared in
-.Fx 3.0 .
+++ /dev/null
-.\" Copyright (c) 1998 Alex Nash
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlockattr_destroy.3,v 1.6 2001/10/01 16:09:09 ru Exp $
-.\"
-.Dd August 4, 1998
-.Dt PTHREAD_RWLOCKATTR_DESTROY 3
-.Os
-.Sh NAME
-.Nm pthread_rwlockattr_destroy
-.Nd destroy a read/write lock
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_rwlockattr_destroy
-.Fa "pthread_rwlockattr_t *attr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_rwlockattr_destroy
-function is used to destroy a read/write lock attribute object,
-previously created with
-.Fn pthread_rwlockattr_init .
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlockattr_destroy
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh SEE ALSO
-.Xr pthread_rwlockattr_init 3
-.Sh STANDARDS
-The
-.Fn pthread_rwlockattr_destroy
-function is expected to conform to
-.St -susv2 .
-.Sh ERRORS
-.Fn pthread_rwlockattr_destroy
-may fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
-.Fa attr
-is invalid.
-.El
-.Sh HISTORY
-The
-.Fn pthread_rwlockattr_destroy
-function first appeared in
-.Fx 3.0 .
+++ /dev/null
-.\" Copyright (c) 1998 Alex Nash
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlockattr_getpshared.3,v 1.8 2001/10/01 16:09:09 ru Exp $
-.\"
-.Dd March 22, 1999
-.Dt PTHREAD_RWLOCKATTR_GETPSHARED 3
-.Os
-.Sh NAME
-.Nm pthread_rwlockattr_getpshared
-.Nd get the process shared attribute
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_rwlockattr_getpshared
-.Fa "const pthread_rwlockattr_t *restrict attr"
-.Fa "int *restrict pshared"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_rwlockattr_getpshared
-function is used to get the process-shared setting of a read/write
-lock attribute object. The setting is returned via
-.Fa pshared ,
-and may be one of two values:
-.Bl -tag -width PTHREAD_PROCESS_PRIVATE
-.It Dv PTHREAD_PROCESS_SHARED
-Any thread of any process that has access to the memory where the
-read/write lock resides can manipulate the lock.
-.It Dv PTHREAD_PROCESS_PRIVATE
-Only threads created within the same process as the thread that
-initialized the read/write lock can manipulate the lock. This is
-the default value.
-.El
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlockattr_getpshared
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh SEE ALSO
-.Xr pthread_rwlock_init 3 ,
-.Xr pthread_rwlockattr_init 3 ,
-.Xr pthread_rwlockattr_setpshared 3
-.Sh STANDARDS
-The
-.Fn pthread_rwlockattr_getpshared
-function is expected to conform to
-.St -susv2 .
-.Sh ERRORS
-.Fn pthread_rwlockattr_getpshared
-may fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
-.Fa attr
-is invalid.
-.El
-.Sh HISTORY
-The
-.Fn pthread_rwlockattr_getpshared
-function first appeared in
-.Fx 3.0 .
+++ /dev/null
-.\" Copyright (c) 1998 Alex Nash
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlockattr_init.3,v 1.6 2001/10/01 16:09:09 ru Exp $
-.\"
-.Dd August 4, 1998
-.Dt PTHREAD_RWLOCKATTR_INIT 3
-.Os
-.Sh NAME
-.Nm pthread_rwlockattr_init
-.Nd initialize a read/write lock
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_rwlockattr_init
-.Fa "pthread_rwlockattr_t *attr"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_rwlockattr_init
-function is used to initialize a read/write lock attribute object.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlockattr_init
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh SEE ALSO
-.Xr pthread_rwlock_init 3 ,
-.Xr pthread_rwlockattr_destroy 3 ,
-.Xr pthread_rwlockattr_getpshared 3 ,
-.Xr pthread_rwlockattr_setpshared 3
-.Sh STANDARDS
-The
-.Fn pthread_rwlockattr_init
-function is expected to conform to
-.St -susv2 .
-.Sh ERRORS
-.Fn pthread_rwlockattr_init
-will fail if:
-.Bl -tag -width Er
-.It Bq Er ENOMEM
-Insufficient memory exists to initialize the attribute object.
-.El
-.Sh HISTORY
-The
-.Fn pthread_rwlockattr_init
-function first appeared in
-.Fx 3.0 .
+++ /dev/null
-.\" Copyright (c) 1998 Alex Nash
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_rwlockattr_setpshared.3,v 1.7 2001/10/01 16:09:09 ru Exp $
-.\"
-.Dd August 4, 1998
-.Dt PTHREAD_RWLOCKATTR_SETPSHARED 3
-.Os
-.Sh NAME
-.Nm pthread_rwlockattr_setpshared
-.Nd set the process shared attribute
-.Sh SYNOPSIS
-.In pthread.h
-.Ft int
-.Fo pthread_rwlockattr_setpshared
-.Fa "pthread_rwlockattr_t *attr"
-.Fa "int pshared"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_rwlockattr_setpshared
-function sets the process-shared attribute of
-.Fa attr
-to the value referenced by
-.Fa pshared .
-.Fa pshared
-may be one of two values:
-.Bl -tag -width PTHREAD_PROCESS_PRIVATE
-.It Dv PTHREAD_PROCESS_SHARED
-Any thread of any process that has access to the memory where the
-read/write lock resides can manipulate the lock.
-.It Dv PTHREAD_PROCESS_PRIVATE
-Only threads created within the same process as the thread that
-initialized the read/write lock can manipulate the lock. This is
-the default value.
-.El
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlockattr_setpshared
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh SEE ALSO
-.Xr pthread_rwlock_init 3 ,
-.Xr pthread_rwlockattr_init 3 ,
-.Xr pthread_rwlockattr_setpshared 3
-.Sh STANDARDS
-The
-.Fn pthread_rwlockattr_setpshared
-function is expected to conform to
-.St -susv2 .
-.Sh ERRORS
-.Fn pthread_rwlockattr_setpshared
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The value specified by
-.Fa attr
-or
-.Fa pshared
-is invalid.
-.El
-.Sh HISTORY
-The
-.Fn pthread_rwlockattr_setpshared
-function first appeared in
-.Fx 3.0 .
-.Sh BUGS
-The
-.Dv PTHREAD_PROCESS_SHARED
-attribute is not supported.
+++ /dev/null
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_self.3,v 1.4.2.4 2001/08/17 15:42:52 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_SELF 3
-.Os
-.Sh NAME
-.Nm pthread_self
-.Nd get the calling thread's ID
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft pthread_t
-.Fn pthread_self "void"
-.Sh DESCRIPTION
-The
-.Fn pthread_self
-function returns the thread ID of the calling thread.
-.Sh RETURN VALUES
-The
-.Fn pthread_self
-function returns the thread ID of the calling thread.
-.Sh ERRORS
-None.
-.Sh SEE ALSO
-.Xr pthread_create 3 ,
-.Xr pthread_equal 3
-.Sh STANDARDS
-.Fn pthread_self
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-.\" $FreeBSD: src/lib/libc_r/man/pthread_testcancel.3,v 1.2.2.3 2001/08/17 15:42:52 ru Exp $
-.Dd January 17, 1999
-.Dt PTHREAD_TESTCANCEL 3
-.Os
-.Sh NAME
-.Nm pthread_setcancelstate ,
-.Nm pthread_setcanceltype ,
-.Nm pthread_testcancel
-.Nd set cancelability state
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_setcancelstate
-.Fa "int state"
-.Fa "int *oldstate"
-.Fc
-.Ft int
-.Fo pthread_setcanceltype
-.Fa "int type"
-.Fa "int *oldtype"
-.Fc
-.Ft void
-.Fo pthread_testcancel
-.Fa "void"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_setcancelstate
-function atomically both sets the calling thread's cancelability state
-to the indicated
-.Fa state
-and returns the previous cancelability state at the location referenced by
-.Fa oldstate .
-Legal values for
-.Fa state
-are
-.Dv PTHREAD_CANCEL_ENABLE
-and
-.Dv PTHREAD_CANCEL_DISABLE .
-.Pp
-The
-.Fn pthread_setcanceltype
-function atomically both sets the calling thread's cancelability type
-to the indicated
-.Fa type
-and returns the previous cancelability type at the location referenced by
-.Fa oldtype .
-Legal values for
-.Fa type
-are
-.Dv PTHREAD_CANCEL_DEFERRED
-and
-.Dv PTHREAD_CANCEL_ASYNCHRONOUS .
-.Pp
-The cancelability state and type of any newly created threads, including the
-thread in which
-.Fn main
-was first invoked, are
-.Dv PTHREAD_CANCEL_ENABLE
-and
-.Dv PTHREAD_CANCEL_DEFERRED
-respectively.
-.Pp
-The
-.Fn pthread_testcancel
-function creates a cancellation point in the calling thread.
-The
-.Fn pthread_testcancel
-function has no effect if cancelability is disabled.
-.Pp
-.Ss Cancelability States
-The cancelability state of a thread determines the action taken upon
-receipt of a cancellation request.
-The thread may control cancellation in
-a number of ways.
-.Pp
-Each thread maintains its own
-.Dq cancelability state
-which may be encoded in two bits:
-.Bl -hang
-.It Em Cancelability Enable
-When cancelability is
-.Dv PTHREAD_CANCEL_DISABLE ,
-cancellation requests against the target thread are held pending.
-.It Em Cancelability Type
-When cancelability is enabled and the cancelability type is
-.Dv PTHREAD_CANCEL_ASYNCHRONOUS ,
-new or pending cancellation requests may be acted upon at any time.
-When cancelability is enabled and the cancelability type is
-.Dv PTHREAD_CANCEL_DEFERRED ,
-cancellation requests are held pending until a cancellation point (see
-below) is reached.
-If cancelability is disabled, the setting of the
-cancelability type has no immediate effect as all cancellation requests
-are held pending; however, once cancelability is enabled again the new
-type will be in effect.
-.El
-.Ss Cancellation Points
-Cancellation points will occur when a thread is executing the following
-functions:
-.Fn close ,
-.Fn creat ,
-.Fn fcntl ,
-.Fn fsync ,
-.Fn msync ,
-.Fn nanosleep ,
-.Fn open ,
-.Fn pause ,
-.Fn pthread_cond_timedwait ,
-.Fn pthread_cond_wait ,
-.Fn pthread_join ,
-.Fn pthread_testcancel ,
-.Fn read ,
-.Fn sigwaitinfo ,
-.Fn sigsuspend ,
-.Fn sigwait ,
-.Fn sleep ,
-.Fn system ,
-.Fn tcdrain ,
-.Fn wait ,
-.Fn waitpid ,
-.Fn write .
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_setcancelstate
-and
-.Fn pthread_setcanceltype
-functions will return zero.
-Otherwise, an error number shall be returned to
-indicate the error.
-.Pp
-The
-.Fn pthread_setcancelstate
-and
-.Fn pthread_setcanceltype
-functions are used to control the points at which a thread may be
-asynchronously canceled.
-For cancellation control to be usable in modular
-fashion, some rules must be followed.
-.Pp
-For purposes of this discussion, consider an object to be a generalization
-of a procedure.
-It is a set of procedures and global variables written as
-a unit and called by clients not known by the object.
-Objects may depend
-on other objects.
-.Pp
-First, cancelability should only be disabled on entry to an object, never
-explicitly enabled.
-On exit from an object, the cancelability state should
-always be restored to its value on entry to the object.
-.Pp
-This follows from a modularity argument: if the client of an object (or the
-client of an object that uses that object) has disabled cancelability, it is
-because the client doesn't want to have to worry about how to clean up if the
-thread is canceled while executing some sequence of actions.
-If an object
-is called in such a state and it enables cancelability and a cancellation
-request is pending for that thread, then the thread will be canceled,
-contrary to the wish of the client that disabled.
-.Pp
-Second, the cancelability type may be explicitly set to either
-.Em deferred
-or
-.Em asynchronous
-upon entry to an object.
-But, as with the cancelability state, on exit from
-an object that cancelability type should always be restored to its value on
-entry to the object.
-.Pp
-Finally, only functions that are cancel-safe may be called from a thread that
-is asynchronously cancelable.
-.Sh ERRORS
-The function
-.Fn pthread_setcancelstate
-may fail with:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The specified state is not
-.Dv PTHREAD_CANCEL_ENABLE
-or
-.Dv PTHREAD_CANCEL_DISABLE .
-.El
-.Pp
-The function
-.Fn pthread_setcanceltype
-may fail with:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The specified state is not
-.Dv PTHREAD_CANCEL_DEFERRED
-or
-.Dv PTHREAD_CANCEL_ASYNCHRONOUS .
-.El
-.Sh SEE ALSO
-.Xr pthread_cancel 3
-.Sh STANDARDS
-.Fn pthread_testcancel
-conforms to
-.St -p1003.1-96 .
-.Sh AUTHORS
-This man page was written by
-.An David Leonard Aq d@openbsd.org
-for the
-.Ox
-implementation of
-.Xr pthread_cancel 3 .
+++ /dev/null
-.\" Copyright (c) 1996 John Birrell <jb@cimlogic.com.au>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 3. All advertising materials mentioning features or use of this software
-.\" must display the following acknowledgement:
-.\" This product includes software developed by John Birrell.
-.\" 4. Neither the name of the author nor the names of any co-contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_setspecific.3,v 1.6.2.4 2001/08/17 15:42:52 ru Exp $
-.\"
-.Dd April 4, 1996
-.Dt PTHREAD_SETSPECIFIC 3
-.Os
-.Sh NAME
-.Nm pthread_setspecific
-.Nd set a thread-specific data value
-.Sh SYNOPSIS
-.Fd #include <pthread.h>
-.Ft int
-.Fo pthread_setspecific
-.Fa "pthread_key_t key"
-.Fa "const void *value"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_setspecific
-function associates a thread-specific value with a
-.Fa key
-obtained via a previous call to
-.Fn pthread_key_create .
-Different threads may bind different values to the same key.
-These values are
-typically pointers to blocks of dynamically allocated memory that have been
-reserved for use by the calling thread.
-.Pp
-The effect of calling
-.Fn pthread_setspecific
-with a key value not obtained from
-.Fn pthread_key_create ,
-or after
-.Fa key
-has been deleted with
-.Fn pthread_key_delete ,
-is undefined.
-.Pp
-.Fn pthread_setspecific
-may be called from a thread-specific data destructor function;
-however, this may result in lost storage or infinite loops.
-.Sh RETURN VALUES
-If successful, the
-.Fn pthread_setspecific
-function will return zero.
-Otherwise, an error number will be returned to indicate the error.
-.Sh ERRORS
-.Fn pthread_setspecific
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-The
-.Fa key
-value is invalid.
-.It Bq Er ENOMEM
-Insufficient memory exists to associate the value with the
-.Fa key .
-.El
-.Sh SEE ALSO
-.Xr pthread_getspecific 3 ,
-.Xr pthread_key_create 3 ,
-.Xr pthread_key_delete 3
-.Sh STANDARDS
-.Fn pthread_setspecific
-conforms to
-.St -p1003.1-96 .
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * POSIX Threads - IEEE 1003.1c
- */
-
-#ifndef _POSIX_PTHREAD_SPINLOCK_H
-#define _POSIX_PTHREAD_SPINLOCK_H
-
-#include <mach/mach.h>
-#define __APPLE_API_PRIVATE
-#include <machine/cpu_capabilities.h>
-
-#ifndef __POSIX_LIB__
-#define __POSIX_LIB__
-#endif
-
-#include "pthread_machdep.h" /* Machine-dependent definitions. */
-
-/* Number of times to spin when the lock is unavailable and we are on a
- multiprocessor. On a uniprocessor we yield the processor immediately. */
-#define MP_SPIN_TRIES 1000
-extern int _spin_tries;
-extern int __is_threaded;
-
-/* Internal mutex locks for data structures */
-#define TRY_LOCK(v) (!__is_threaded || _spin_lock_try((pthread_lock_t *)&(v)))
-
-/* _DO_SPINLOCK_LOCK() takes a (pthread_lock_t *) */
-#define _DO_SPINLOCK_LOCK(v) _spin_lock(v)
-
-/* _DO_SPINLOCK_UNLOCK() takes a (pthread_lock_t *) */
-#define _DO_SPINLOCK_UNLOCK(v) _spin_unlock(v)
-
-/* LOCK() takes a (pthread_lock_t) */
-#define LOCK(v) \
- do { \
- if (__is_threaded) { \
- _DO_SPINLOCK_LOCK((pthread_lock_t *)&(v)); \
- } \
- } while (0)
-
-/* UNLOCK() takes a (pthread_lock_t) */
-#define UNLOCK(v) \
- do { \
- if (__is_threaded) { \
- _DO_SPINLOCK_UNLOCK((pthread_lock_t *)&(v)); \
- } \
- } while (0)
-
-/* Prototypes. */
-
-/* Functions defined in machine-dependent files. */
-extern void _spin_lock(pthread_lock_t *lockp);
-extern int _spin_lock_try(pthread_lock_t *lockp);
-extern void _spin_unlock(pthread_lock_t *lockp);
-
-#endif /* _POSIX_PTHREAD_SPINLOCK_H */
+++ /dev/null
-/*
- * Copyright (c) 2000-2011 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * Extension SPIs.
- */
-
-#ifndef _PTHREAD_SPIS_H
-#define _PTHREAD_SPIS_H
-
-
-#include <pthread.h>
-
-__BEGIN_DECLS
-
-#if (!defined(_POSIX_C_SOURCE) && !defined(_XOPEN_SOURCE)) || defined(_DARWIN_C_SOURCE)
-/* firstfit */
-#define PTHREAD_FIRSTFIT_MUTEX_INITIALIZER {_PTHREAD_FIRSTFIT_MUTEX_SIG_init, {0}}
-/*
- * Mutex attributes
- */
-#define _PTHREAD_MUTEX_POLICY_NONE 0
-#define _PTHREAD_MUTEX_POLICY_FAIRSHARE 1
-#define _PTHREAD_MUTEX_POLICY_FIRSTFIT 2
-
-/* sets the mutex policy attributes */
-int pthread_mutexattr_setpolicy_np(pthread_mutexattr_t *, int );
-
-#endif /* (!_POSIX_C_SOURCE && !_XOPEN_SOURCE) || _DARWIN_C_SOURCE */
-
-__END_DECLS
-
-#endif /* _PTHREAD_SPIS_H */
+++ /dev/null
-/*
- * Copyright (c) 2000-2003, 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * POSIX Pthread Library
- * Thread Specific Data support
- * NB: pthread_getspecific() is in a separate assembly file
- */
-
-#include "pthread_internals.h"
-
-static struct
-{
- int created; /* Set TRUE if 'create_key' used this slot */
- void (*destructor)(void *);
-} _pthread_keys[_INTERNAL_POSIX_THREAD_KEYS_END];
-static pthread_lock_t tds_lock = LOCK_INITIALIZER;
-
-/*
- * Partition _pthread_keys in a lower part that dyld can use, and an upper
- * part for libSystem. The libSystem part starts at __pthread_tsd_first = 4.
- * dyld will set this value to 1.
- * LEFT OVER TILL DYLD changes to using static (1-3) numbers
- */
-
-#ifdef DYLD_STATIC_LIBC_BUILD
-__private_extern__ int __pthread_tsd_first = 1;
-__private_extern__ int __pthread_tsd_start = 5;
-__private_extern__ int __pthread_tsd_end = 10;
-__private_extern__ int __pthread_tsd_max = 10;
-#else
-__private_extern__ int __pthread_tsd_first = 10;
-__private_extern__ int __pthread_tsd_start = _INTERNAL_POSIX_THREAD_KEYS_MAX;
-__private_extern__ int __pthread_tsd_end = _INTERNAL_POSIX_THREAD_KEYS_END;
-__private_extern__ int __pthread_tsd_max = 10;
-#endif
-/*
- * Create a new key for thread specific data
- */
-int
-pthread_key_create(pthread_key_t *key,
- void (*destructor)(void *))
-{
- int res, i;
- LOCK(tds_lock);
- res = EAGAIN; /* No 'free' keys, return EAGAIN (as per standard) */
- /* The first slot is reserved for pthread_self() */
- for (i = __pthread_tsd_start; i < __pthread_tsd_end; i++)
- {
- if (_pthread_keys[i].created == FALSE)
- {
- _pthread_keys[i].created = TRUE;
- _pthread_keys[i].destructor = destructor;
- *key = i;
- res = 0;
- break;
- }
- }
- UNLOCK(tds_lock);
- return (res);
-}
-
-/*
- * Destroy a thread specific data key
- */
-int
-pthread_key_delete(pthread_key_t key)
-{
- int res;
- LOCK(tds_lock);
- /* The first slot is reserved for pthread_self() */
- if ((key >= __pthread_tsd_start) && (key < __pthread_tsd_end))
- {
- if (_pthread_keys[key].created)
- {
- struct _pthread * p;
-
- _pthread_keys[key].created = FALSE;
- LOCK(_pthread_list_lock);
- TAILQ_FOREACH(p, &__pthread_head, plist) {
- /* It is an 32bit value no lock needed */
- p->tsd[key] = 0;
- }
- UNLOCK(_pthread_list_lock);
- res = 0;
- } else
- {
- res = EINVAL;
- }
- } else
- { /* Invalid key */
- res = EINVAL;
- }
- UNLOCK(tds_lock);
- return (res);
-}
-
-/*
- * Set the thread private value for a given key.
- * We do not take the spinlock for this or pthread_getspecific.
- * The assignment to self->tsd[] is thread-safe because we never
- * refer to the tsd[] of a thread other than pthread_self().
- * The reference to _pthread_keys[...].created could race with a
- * pthread_key_delete() but in this case the behaviour is allowed
- * to be undefined.
- */
-int
-pthread_setspecific(pthread_key_t key,
- const void *value)
-{
- int res;
- pthread_t self;
- /* The first slot is reserved for pthread_self() */
- if ((key >= __pthread_tsd_first) && (key < __pthread_tsd_end))
- {
- if ((key < __pthread_tsd_start) || _pthread_keys[key].created)
- {
- self = pthread_self();
- self->tsd[key] = (void *) value;
- res = 0;
- if ((key < __pthread_tsd_start) && (_pthread_keys[key].created == FALSE))
- _pthread_keys[key].created = TRUE;
-
- if (key > self->max_tsd_key)
- self->max_tsd_key = key;
- } else
- {
- res = EINVAL;
- }
- } else
- { /* Invalid key */
- res = EINVAL;
- }
- return (res);
-}
-
-/*
- * Clean up thread specific data as thread 'dies'
- */
-void
-_pthread_tsd_cleanup(pthread_t self)
-{
- int i, j;
- void *param;
-
- /* destroy dynamic keys first */
- for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++)
- {
- for (i = __pthread_tsd_start; i <= self->max_tsd_key; i++)
- {
- if (_pthread_keys[i].created && (param = self->tsd[i]))
- {
- self->tsd[i] = (void *)NULL;
- if (_pthread_keys[i].destructor)
- {
- (_pthread_keys[i].destructor)(param);
- }
- }
- }
- }
-
- self->max_tsd_key = 0;
-
- /*
- * The first slot is reserved for pthread_self() and there is no cleanup on it.
- * Destroy rest of the static keys next only if any destructors registered.
- */
- for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++) {
- for (i = __pthread_tsd_first; i <= __pthread_tsd_max; i++)
- {
- if (_pthread_keys[i].created && (param = self->tsd[i]))
- {
- self->tsd[i] = (void *)NULL;
- if (_pthread_keys[i].destructor)
- {
- (_pthread_keys[i].destructor)(param);
- }
- }
- }
- }
-}
-
-int
-pthread_key_init_np(int key, void (*destructor)(void *))
-{
- if ((key >= __pthread_tsd_first) && (key < __pthread_tsd_start)) {
- LOCK(tds_lock);
- _pthread_keys[key].created = TRUE;
- _pthread_keys[key].destructor = destructor;
-
- if (key > __pthread_tsd_max)
- __pthread_tsd_max = key;
- UNLOCK(tds_lock);
- return (0);
- } else
- return(EINVAL);
-}
-
-/* we need this till the switchover happens for the dyld. It get 1- 10 slot */
-void
-_pthread_keys_init()
-{
- if (__pthread_tsd_first == 1) {
- __pthread_tsd_start = 5;
- __pthread_tsd_end = 10;
- __pthread_tsd_max = 10;
- }
-
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* pthread workqueue defns */
-
-#ifndef _POSIX_PTHREAD_WORKQUEUE_H
-#define _POSIX_PTHREAD_WORKQUEUE_H
-
-#include <sys/cdefs.h>
-#include <pthread.h>
-#include <Availability.h>
-
-#define __PTHREAD_WORKQ_SIZE__ 128
-#define __PTHREAD_WORKQ_ATTR_SIZE__ 60
-
-#define PTHREAD_WORKQUEUE_SIG 0xBEBEBEBE
-#define PTHREAD_WORKQUEUE_ATTR_SIG 0xBEBEBEBE
-
-#ifndef __POSIX_LIB__
-typedef struct { unsigned int sig; char opaque[__PTHREAD_WORKQ_SIZE__];} *pthread_workqueue_t;
-typedef struct { unsigned int sig; char opaque[__PTHREAD_WORKQ_ATTR_SIZE__]; } pthread_workqueue_attr_t;
-#endif
-typedef void * pthread_workitem_handle_t;
-/* Kernel expected target concurrency of the workqueue clients for the three priority queues */
-
-#define WORKQ_HIGH_PRIOQUEUE 0 /* high priority queue */
-#define WORKQ_DEFAULT_PRIOQUEUE 1 /* default priority queue */
-#define WORKQ_LOW_PRIOQUEUE 2 /* low priority queue */
-#define WORKQ_BG_PRIOQUEUE 3 /* background priority queue */
-
-#define WORKQ_NUM_PRIOQUEUE 4
-
-extern __int32_t workq_targetconc[WORKQ_NUM_PRIOQUEUE];
-
-__BEGIN_DECLS
-int pthread_workqueue_init_np(void) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int pthread_workqueue_attr_init_np(pthread_workqueue_attr_t * attr) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int pthread_workqueue_attr_destroy_np(pthread_workqueue_attr_t * attr) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int pthread_workqueue_attr_getqueuepriority_np(const pthread_workqueue_attr_t * attr, int * qprio) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-/* WORKQ_HIGH/DEFAULT/LOW_PRIOQUEUE are the only valid values */
-int pthread_workqueue_attr_setqueuepriority_np(pthread_workqueue_attr_t * attr, int qprio) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int pthread_workqueue_attr_getovercommit_np(const pthread_workqueue_attr_t * attr, int * ocommp) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-int pthread_workqueue_attr_setovercommit_np(pthread_workqueue_attr_t * attr, int ocomm) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-
-
-int pthread_workqueue_create_np(pthread_workqueue_t * workqp, const pthread_workqueue_attr_t * attr) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-int pthread_workqueue_additem_np(pthread_workqueue_t workq, void ( *workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp) __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);
-/* If the queue value is WORKQ_NUM_PRIOQUEUE, the request for concurrency is for all queues */
-int pthread_workqueue_requestconcurrency_np(int queue, int concurrency) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-int pthread_workqueue_getovercommit_np(pthread_workqueue_t workq, unsigned int *ocommp) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-/*
- * If the arg is non zero, it enables kill on current thread.
- * If the arg of zero, it disables kill on current thread.
- */
-int __pthread_workqueue_setkill(int) __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2);
-
-/* ===================================================================================================
- * NEW SPIs for 10.8 onwards
- *
- * ===================================================================================================
- */
-
-typedef void (*pthread_workqueue_function_t)(int queue_priority, int options, void *ctxt);
-int pthread_workqueue_setdispatch_np(pthread_workqueue_function_t worker_func) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0);
-
-#define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x00000001
-int pthread_workqueue_addthreads_np(int queue_priority, int options, int numthreads) __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0);
-__END_DECLS
-
-#endif /* _POSIX_PTHREAD_WORKQUEUE_H */
-
+++ /dev/null
-/*
- * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _SCHED_H_
-#define _SCHED_H_
-
-#include <pthread_impl.h>
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-/*
- * Scheduling paramters
- */
-#ifndef __POSIX_LIB__
-struct sched_param { int sched_priority; char __opaque[__SCHED_PARAM_SIZE__]; };
-#endif
-
-extern int sched_yield(void);
-extern int sched_get_priority_min(int);
-extern int sched_get_priority_max(int);
-__END_DECLS
-
-#endif /* _SCHED_H_ */
-
+++ /dev/null
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-.text
-
-#if defined(__ppc__) || defined(__ppc64__)
-#import <architecture/ppc/asm_help.h>
-#import <architecture/ppc/pseudo_inst.h>
-
-/*
- * void *_sp(void)
- */
-
-LEAF(__sp)
- mr r3,r1
- blr
-
-/*
- * void *_adjust_sp(void *sp)
- */
-LEAF(__adjust_sp)
- subi r3,r3,0x100 /* Stack frame padding */
- blr
-
-#elif defined(__i386__)
-
-#import <architecture/i386/asm_help.h>
-/*
- * void *_sp(void)
- */
-
-LEAF(__sp,0)
- movl %esp,%eax
- ret
-
-/*
- * void *_adjust_sp(void *sp)
- */
-LEAF(__adjust_sp,0)
- movl 4(%esp),%eax
- subl $0x100,%eax
- ret
-
-#elif defined(__x86_64__)
-
-#import <architecture/i386/asm_help.h>
-/*
- * void *_sp(void)
- */
-
-LEAF(__sp,0)
- movq %rsp,%rax
- ret
-
-/*
- * void *_adjust_sp(void *sp)
- */
-LEAF(__adjust_sp,0)
- movq %rdi,%rax
- subq $0x100,%rax
- ret
-
-#elif defined(__arm__)
-
-#import <architecture/arm/asm_help.h>
-
-LEAF(__sp,0)
- mov r0,sp
- bx lr
-
-/*
- * void *_adjust_sp(void *sp)
- */
-LEAF(__adjust_sp,0)
- sub r0, r0, #0x100
- bx lr
-
-#else
-#error sp functions not defined for this architecture
-#endif
-
+++ /dev/null
-MACHINE:=`arch`
-MAKEOBJDIR:=../../obj.`arch`
-
-TESTS = pthread_atfork_test
-LDFLAGS = -nostdlib -lcrt1.o
-LDLIBS = $(MAKEOBJDIR)/libc.a /usr/local/lib/system/libnotify.a \
- /usr/local/lib/system/libm.a /usr/local/lib/system/libmCommon.a \
- -lgcc /usr/local/lib/system/libkeymgr.a \
- /usr/local/lib/system/libdyld.a /usr/local/lib/system/libmacho.a \
- $(MAKEOBJDIR)/libc.a
-CFLAGS = -I..
-
-.SUFFIXES:
-.SUFFIXES: .c
-
-.PHONY: tests
-
-tests: $(TESTS)
- @for i in $(TESTS); do \
- $$i && echo $$i passed; \
- done
-
-clean:
- rm -f $(TESTS)
-
-Makefile pthread_atfork_test.c : ;
+++ /dev/null
-#include <assert.h>
-#include <pthread.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-/*
- * Parent and child handlers are called in the order they were registered
- * prepare handlers are called in reverse order. The non-commutative
- * operations will ensure that we are calling them in the proper order.
- */
-
-static int parentval = 0;
-static int childval = 0;
-
-static void prepare1(void)
-{
- parentval *= 2;
-}
-
-static void prepare2(void)
-{
- parentval = 3;
-}
-
-static void parent1(void)
-{
- parentval += 4;
-}
-
-static void parent2(void)
-{
- parentval *= 3;
-}
-
-static void child1(void)
-{
- childval = 5;
-}
-
-static void child2(void)
-{
- childval *= 3;
-}
-
-int
-main(void)
-{
- pid_t pid, child;
- int status;
-
- assert(!pthread_atfork(prepare1, parent1, child1));
- assert(!pthread_atfork(prepare2, parent2, child2));
- pid = fork();
- assert(pid >= 0);
- if (pid == 0) {
- _exit(childval);
- } else {
- child = waitpid(pid, &status, 0);
- assert(child == pid);
- assert(WIFEXITED(status));
- assert(WEXITSTATUS(status) == 15);
- assert(parentval == 30);
- }
- return 0;
-}
+++ /dev/null
-/*
- * Copyright (c) 2000-2003, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-/*
- * MkLinux
- */
-
-/*
- * Machine specific support for thread initialization
- */
-
-#if defined(__ppc__) || defined(__ppc64__)
-#include <architecture/ppc/cframe.h>
-#elif defined(__arm__)
-#include <architecture/arm/cframe.h>
-#endif
-
-#include "pthread_internals.h"
-
-/*
- * Set up the initial state of a MACH thread
- */
-void
-_pthread_setup(pthread_t thread,
- void (*routine)(pthread_t),
- void *vsp, int suspended,
- int needresume)
-{
- kern_return_t r;
- unsigned int count;
-#if defined(__ppc__) || defined(__ppc64__)
-#if defined(__ppc__)
- ppc_thread_state_t state = {0};
- ppc_thread_state_t *ts = &state;
- thread_state_flavor_t flavor = PPC_THREAD_STATE;
- count = PPC_THREAD_STATE_COUNT;
-#elif defined(__ppc64__)
- ppc_thread_state64_t state = {0};
- ppc_thread_state64_t *ts = &state;
- thread_state_flavor_t flavor = PPC_THREAD_STATE64;
- count = PPC_THREAD_STATE64_COUNT;
-#endif
- /*
- * Set up PowerPC registers.
- */
- if (suspended) {
- PTHREAD_MACH_CALL(thread_get_state(thread->kernel_thread,
- flavor,
- (thread_state_t) &state,
- &count),
- r);
- }
- ts->srr0 = (uintptr_t)routine;
- ts->r1 = (uintptr_t)vsp - C_ARGSAVE_LEN - C_RED_ZONE;
- ts->r3 = (uintptr_t)thread;
- /* Incase of needresume, suspend is always set */
- if (suspended) {
- PTHREAD_MACH_CALL(thread_set_state(thread->kernel_thread,
- flavor,
- (thread_state_t) &state,
- count),
- r);
- if (needresume)
- PTHREAD_MACH_CALL(thread_resume(thread->kernel_thread),
- r);
- } else {
- PTHREAD_MACH_CALL(thread_create_running(mach_task_self(),
- flavor,
- (thread_state_t) ts,
- count,
- &thread->kernel_thread),
- r);
- }
-#elif defined(__i386__)
- i386_thread_state_t state = {0};
- i386_thread_state_t *ts = &state;
- int *sp = vsp;
-
- /*
- * Set up i386 registers & function call.
- */
- count = i386_THREAD_STATE_COUNT;
- if (suspended) {
- PTHREAD_MACH_CALL(thread_get_state(thread->kernel_thread,
- i386_THREAD_STATE,
- (thread_state_t) &state,
- &count),
- r);
- }
- ts->eip = (int) routine;
-
- /*
- ** We need to simulate a 16-byte aligned stack frame as if we had
- ** executed a call instruction. Since we're "pushing" one argument,
- ** we need to adjust the pointer by 12 bytes (3 * sizeof (int *))
- */
-
- sp -= 3; /* make sure stack is aligned */
- *--sp = (int) thread; /* argument to function */
- *--sp = 0; /* fake return address */
- ts->esp = (int) sp; /* set stack pointer */
- /* Incase of needresume, suspend is always set */
- if (suspended) {
- PTHREAD_MACH_CALL(thread_set_state(thread->kernel_thread,
- i386_THREAD_STATE,
- (thread_state_t) &state,
- i386_THREAD_STATE_COUNT),
- r);
- if (needresume)
- PTHREAD_MACH_CALL(thread_resume(thread->kernel_thread),
- r);
- } else {
- PTHREAD_MACH_CALL(thread_create_running(mach_task_self(),
- i386_THREAD_STATE,
- (thread_state_t) ts,
- i386_THREAD_STATE_COUNT,
- &thread->kernel_thread),
- r);
- }
-
-#elif defined(__x86_64__)
- x86_thread_state64_t state = {0};
- x86_thread_state64_t *ts = &state;
- uintptr_t *sp = vsp;
-
- /*
- * Set up x86-64 registers & function call.
- */
- count = x86_THREAD_STATE64_COUNT;
- if (suspended) {
- PTHREAD_MACH_CALL(thread_get_state(thread->kernel_thread,
- x86_THREAD_STATE64,
- (thread_state_t) &state,
- &count),
- r);
- }
- ts->rip = (uintptr_t) routine;
-
- /*
- ** We need to simulate a 16-byte aligned stack frame as if we had
- ** executed a call instruction. The stack should already be aligned
- ** before it comes to us and we don't need to push any arguments,
- ** so we shouldn't need to change it.
- */
-
- ts->rdi = (uintptr_t) thread; /* argument to function */
- *--sp = 0; /* fake return address */
- ts->rsp = (uintptr_t) sp; /* set stack pointer */
- /* Incase of needresume, suspend is always set */
- if (suspended) {
- PTHREAD_MACH_CALL(thread_set_state(thread->kernel_thread,
- x86_THREAD_STATE64,
- (thread_state_t) &state,
- x86_THREAD_STATE64_COUNT),
- r);
- if (needresume)
- PTHREAD_MACH_CALL(thread_resume(thread->kernel_thread),
- r);
- } else {
- PTHREAD_MACH_CALL(thread_create_running(mach_task_self(),
- x86_THREAD_STATE64,
- (thread_state_t) ts,
- x86_THREAD_STATE64_COUNT,
- &thread->kernel_thread),
- r);
- }
-
-#elif defined(__arm__)
- arm_thread_state_t state = {0};
- arm_thread_state_t *ts = &state;
- thread_state_flavor_t flavor = ARM_THREAD_STATE;
- count = ARM_THREAD_STATE_COUNT;
-
- if (suspended) {
- PTHREAD_MACH_CALL(thread_get_state(thread->kernel_thread,
- flavor,
- (thread_state_t) &state,
- &count),
- r);
- }
-
- ts->pc = (uintptr_t)routine;
-
- if (ts->pc & 1) {
- ts->pc &= ~1;
- ts->cpsr |= 0x20; /* PSR_THUMB */
- }
-
- ts->sp = (uintptr_t)vsp - C_ARGSAVE_LEN - C_RED_ZONE;
- ts->r[0] = (uintptr_t)thread;
-
- /* Incase of needresume, suspend is always set */
- if (suspended) {
- PTHREAD_MACH_CALL(thread_set_state(thread->kernel_thread,
- flavor,
- (thread_state_t) &state,
- count),
- r);
- if (needresume)
- PTHREAD_MACH_CALL(thread_resume(thread->kernel_thread),
- r);
- } else {
- PTHREAD_MACH_CALL(thread_create_running(mach_task_self(),
- flavor,
- (thread_state_t) ts,
- count,
- &thread->kernel_thread),
- r);
- }
-#else
-#error _pthread_setup not defined for this architecture
-#endif
-}
u = tre_mem_calloc(mem, sizeof(tre_last_matched_pre_t) +
sizeof(tre_last_matched_branch_pre_t)
- + bitstr_size(num_tags));
+ + bitstr_size(tnfa->num_tags));
if (!u)
{
status = REG_ESPACE;
node = tre_stack_pop_voidptr(stack);
start_tag = tre_stack_pop_int(stack);
b = tre_mem_calloc(mem, sizeof(tre_last_matched_branch_pre_t)
- + bitstr_size(num_tags));
+ + bitstr_size(tnfa->num_tags));
if (!b)
{
status = REG_ESPACE;
if (errcode != REG_OK)
ERROR_EXIT(errcode);
+#ifdef USE_FIRSTPOS_CHARS /* not defined */
/* If in eight bit mode, compute a table of characters that can be the
first character of a match. */
tnfa->first_char = -1;
}
else
tnfa->firstpos_chars = NULL;
+#else /* !USE_FIRSTPOS_CHARS */
+ /* Set first_char only if there is only one character that can be the
+ first character of a match */
+ tnfa->first_char = -1;
+ if (!tmp_ast_l->nullable)
+ {
+ int scanning = 1;
+ for (p = tree->firstpos; scanning && p->position >= 0; p++)
+ {
+ tre_tnfa_transition_t *j = transitions + offs[p->position];
+ while (j->state != NULL)
+ {
+ if (j->code_min <= j->code_max)
+ {
+ if (j->code_max != j->code_min || j->code_min == -1 || tnfa->first_char != -1)
+ {
+ tnfa->first_char = -1;
+ scanning = 0;
+ break;
+ }
+ tnfa->first_char = j->code_min;
+ }
+ j++;
+ }
+ }
+#ifdef TRE_DEBUG
+ if (tnfa->first_char >= 0)
+ DPRINT(("first char must be %d\n", tnfa->first_char));
+#endif /* TRE_DEBUG */
+ }
+#endif /* !USE_FIRSTPOS_CHARS */
p = tree->firstpos;
i = 0;
if (tnfa->tag_directions)
xfree(tnfa->tag_directions);
+#ifdef USE_FIRSTPOS_CHARS /* not defined */
if (tnfa->firstpos_chars)
xfree(tnfa->firstpos_chars);
+#endif /* USE_FIRSTPOS_CHARS */
if (tnfa->minimal_tags)
xfree(tnfa->minimal_tags);
tre_tnfa_transition_t *initial;
tre_tnfa_transition_t *final;
tre_submatch_data_t *submatch_data;
+#ifdef USE_FIRSTPOS_CHARS /* not defined */
char *firstpos_chars;
+#endif /* USE_FIRSTPOS_CHARS */
tre_tag_direction_t *tag_directions;
int *minimal_tags;
tre_last_matched_branch_t *last_matched_branch;
reach_pos[i].pos = -1;
/* If only one character can start a match, find it first. */
- if (tnfa->first_char >= 0 && type == STR_BYTE && str_byte)
+ if (tnfa->first_char >= 0 && str_byte)
{
const char *orig_str = str_byte;
int first = tnfa->first_char;
+ int found_high_bit = 0;
- if (len >= 0)
- str_byte = memchr(orig_str, first, (size_t)len);
- else
- str_byte = strchr(orig_str, first);
+
+ if (type == STR_BYTE)
+ {
+ if (len >= 0)
+ str_byte = memchr(orig_str, first, (size_t)len);
+ else
+ str_byte = strchr(orig_str, first);
+ }
+ else if (type == STR_MBS)
+ {
+ /*
+ * If the match character is ASCII, try to match the character
+ * directly, but if a high bit character is found, we stop there.
+ */
+ if (first < 0x80)
+ {
+ if (len >= 0)
+ {
+ int i;
+ for (i = 0; ; str_byte++, i++)
+ {
+ if (i >= len)
+ {
+ str_byte = NULL;
+ break;
+ }
+ if (*str_byte == first)
+ break;
+ if (*str_byte & 0x80)
+ {
+ found_high_bit = 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (; ; str_byte++)
+ {
+ if (!*str_byte)
+ {
+ str_byte = NULL;
+ break;
+ }
+ if (*str_byte == first)
+ break;
+ if (*str_byte & 0x80)
+ {
+ found_high_bit = 1;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ if (len >= 0)
+ {
+ int i;
+ for (i = 0; ; str_byte++, i++)
+ {
+ if (i >= len)
+ {
+ str_byte = NULL;
+ break;
+ }
+ if (*str_byte & 0x80)
+ {
+ found_high_bit = 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ for (; ; str_byte++)
+ {
+ if (!*str_byte)
+ {
+ str_byte = NULL;
+ break;
+ }
+ if (*str_byte & 0x80)
+ {
+ found_high_bit = 1;
+ break;
+ }
+ }
+ }
+ }
+ }
if (str_byte == NULL)
{
#ifndef TRE_USE_ALLOCA
return REG_NOMATCH;
}
DPRINT(("skipped %lu chars\n", (unsigned long)(str_byte - orig_str)));
- if (str_byte >= orig_str + 1)
- prev_c = (unsigned char)*(str_byte - 1);
- next_c = (unsigned char)*str_byte;
- pos = str_byte - orig_str;
- if (len < 0 || pos < len)
- str_byte++;
+ if (!found_high_bit)
+ {
+ if (str_byte >= orig_str + 1)
+ prev_c = (unsigned char)*(str_byte - 1);
+ next_c = (unsigned char)*str_byte;
+ pos = str_byte - orig_str;
+ if (len < 0 || pos < len)
+ str_byte++;
+ }
+ else
+ {
+ if (str_byte == orig_str)
+ goto no_first_optimization;
+ /*
+ * Back up one character, fix up the position, then call
+ * GET_NEXT_WCHAR() to process the multibyte character.
+ */
+ /* no need to set prev_c, since GET_NEXT_WCHAR will overwrite */
+ next_c = (unsigned char)*(str_byte - 1);
+ pos = (str_byte - 1) - orig_str;
+ GET_NEXT_WCHAR();
+ }
}
else
{
+no_first_optimization:
GET_NEXT_WCHAR();
pos = 0;
}
-#if 0
+#ifdef USE_FIRSTPOS_CHARS /* not defined */
/* Skip over characters that cannot possibly be the first character
of a match. */
if (tnfa->firstpos_chars != NULL)
}
}
}
-#endif
+#endif /* USE_FIRSTPOS_CHARS */
DPRINT(("length: %d\n", len));
DPRINT(("pos:chr/code | states and tags\n"));
/* Wide character and multibyte support. */
#ifdef TRE_STR_USER
+#error TRE_STR_USER defined
#define GET_NEXT_WCHAR() \
do { \
prev_c = next_c; \
} \
} while(/*CONSTCOND*/0)
#else /* !TRE_STR_USER */
+/*
+ * Because all multibyte encodings are exclusively single-shift encoding,
+ * with the shift codes having the high bit set, we can make an optimization
+ * for STR_MBS that only calls tre_mbrtowc_l() when a high-bit character
+ * is detected, and just do a direct copy for ASCII characters.
+ */
#define GET_NEXT_WCHAR() \
do { \
prev_c = next_c; \
- if (type == STR_BYTE) \
+ switch (type) \
{ \
+ case STR_BYTE: \
pos++; \
if (len >= 0 && pos >= len) \
next_c = '\0'; \
else \
next_c = (unsigned char)(*str_byte++); \
- } \
- else if (type == STR_WIDE) \
- { \
+ break; \
+ case STR_WIDE: \
pos++; \
if (len >= 0 && pos >= len) \
next_c = L'\0'; \
else \
next_c = *str_wide++; \
- } \
- else if (type == STR_MBS) \
- { \
- pos += pos_add_next; \
- if (str_byte == NULL) \
- next_c = L'\0'; \
+ break; \
+ case STR_MBS: \
+ pos += pos_add_next; \
+ if (__builtin_expect(len >= 0 && pos >= len, 0)) \
+ { \
+ next_c = L'\0'; \
+ pos_add_next = 1; \
+ } \
+ else if (__builtin_expect(!(*str_byte & 0x80), 1)) \
+ { \
+ next_c = (unsigned char)(*str_byte++); \
+ pos_add_next = 1; \
+ } \
else \
{ \
size_t w; \
max = len - pos; \
else \
max = 32; \
- if (max <= 0) \
+ w = tre_mbrtowc_l(&next_c, str_byte, (size_t)max, &mbstate, \
+ tnfa->loc); \
+ if (w == (size_t)-1 || w == (size_t)-2) \
+ return REG_ILLSEQ; \
+ if (w == 0 && len >= 0) \
{ \
- next_c = L'\0'; \
pos_add_next = 1; \
+ next_c = 0; \
+ str_byte++; \
} \
else \
{ \
- w = tre_mbrtowc_l(&next_c, str_byte, (size_t)max, &mbstate, \
- tnfa->loc); \
- if (w == (size_t)-1 || w == (size_t)-2) \
- return REG_ILLSEQ; \
- if (w == 0 && len >= 0) \
- { \
- pos_add_next = 1; \
- next_c = 0; \
- str_byte++; \
- } \
- else \
- { \
- pos_add_next = w; \
- str_byte += w; \
- } \
+ pos_add_next = w; \
+ str_byte += w; \
} \
} \
+ break; \
} \
} while(/*CONSTCOND*/0)
#endif /* !TRE_STR_USER */
#else /* !TRE_MULTIBYTE */
/* Wide character support, no multibyte support. */
+#error TRE_MULTIBYTE undefined
#ifdef TRE_STR_USER
#define GET_NEXT_WCHAR() \
#else /* !TRE_WCHAR */
/* No wide character or multibyte support. */
+#error TRE_WCHAR undefined
#ifdef TRE_STR_USER
#define GET_NEXT_WCHAR() \
break;
}
error:
- if (list->flags & TRE_BRACKET_MATCH_FLAG_NEGATE)
+ if (list->flags & TRE_BRACKET_MATCH_FLAG_NEGATE) {
+ if ((tnfa->cflags & REG_NEWLINE) && wc == '\n') return 0;
match = !match;
+ }
return match;
}
/*
- * Copyright (c) 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <sys/sysctl.h>
#include <sys/param.h>
#include <unistd.h>
+#include <stdlib.h>
+#include <TargetConditionals.h>
-extern void __abort(void) __dead2;
+__attribute__ ((visibility ("hidden")))
+int __chk_assert_no_overlap = 1;
-void
-__attribute__ ((noreturn))
-__chk_fail (void)
-{
- const char message[] = "[%d] detected buffer overflow";
-
- syslog(LOG_CRIT, message, getpid());
-
- __abort();
-}
--- /dev/null
+/*
+ * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "secure.h"
+
+void *
+__memccpy_chk (void *dest, const void *src, int c, size_t len, size_t dstlen)
+{
+ void *retval;
+
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail_overflow ();
+
+ /* retval is NULL if len was copied, otherwise retval is the
+ * byte *after* the last one written.
+ */
+ retval = memccpy (dest, src, c, len);
+
+ if (retval != NULL) {
+ len = (uintptr_t)retval - (uintptr_t)dest;
+ }
+
+ __chk_overlap(dest, len, src, len);
+
+ return retval;
+}
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdlib.h>
#include <string.h>
-
-extern void __chk_fail (void) __attribute__((__noreturn__));
+#include "secure.h"
void *
__memcpy_chk (void *dest, const void *src, size_t len, size_t dstlen)
{
if (__builtin_expect (dstlen < len, 0))
- __chk_fail ();
+ __chk_fail_overflow ();
+
+ /* On OS X, memcpy has supported overlapping buffers for many years.
+ * While technically, this will catch buggy code, we should not abort.
+ * if (__chk_assert_no_overlap)
+ * __chk_overlap(dest, len, src, len);
+ */
return memcpy (dest, src, len);
}
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdlib.h>
#include <string.h>
-
-extern void __chk_fail (void) __attribute__((__noreturn__));
+#include "secure.h"
void *
__memmove_chk (void *dest, const void *src, size_t len, size_t dstlen)
{
if (__builtin_expect (dstlen < len, 0))
- __chk_fail ();
+ __chk_fail_overflow ();
return memmove (dest, src, len);
}
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdlib.h>
#include <string.h>
-
-extern void __chk_fail (void) __attribute__((__noreturn__));
+#include "secure.h"
void *
__memset_chk (void *dest, int val, size_t len, size_t dstlen)
{
if (__builtin_expect (dstlen < len, 0))
- __chk_fail ();
+ __chk_fail_overflow ();
return memset (dest, val, len);
}
--- /dev/null
+/*
+ * Copyright (c) 2013 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef _SECURE_H_
+
+#include <sys/types.h>
+
+extern void __chk_fail_overflow (void) __attribute__((__noreturn__));
+extern void __chk_fail_overlap (void) __attribute__((__noreturn__));
+
+/* Assert if a -> a+an and b -> b+bn overlap.
+ * 0-lengths don't overlap anything.
+ */
+extern void __chk_overlap (const void *a, size_t an, const void *b, size_t bn);
+
+/* Do we avoid the overlap check for older APIs? */
+extern int __chk_assert_no_overlap;
+
+#endif
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
-
-extern void __chk_fail (void) __attribute__((__noreturn__));
-extern int __snprintf_chk (char * __restrict, size_t, int, size_t,
- const char * __restrict, ...);
+#include "secure.h"
int
-__snprintf_chk (char *s, size_t maxlen, int flags, size_t len,
+__snprintf_chk (char *dest, size_t len, int flags, size_t dstlen,
const char *format, ...)
{
va_list arg;
int done;
- if (__builtin_expect (maxlen > len, 0))
- __chk_fail ();
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail_overflow ();
va_start (arg, format);
- done = vsnprintf (s, maxlen, format, arg);
+ done = vsnprintf (dest, len, format, arg);
va_end (arg);
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
-
-extern void __chk_fail (void) __attribute__((__noreturn__));
-extern int __sprintf_chk (char * __restrict, int, size_t,
- const char * __restrict, ...);
+#include "secure.h"
int
-__sprintf_chk (char *s, int flags, size_t len, const char *format, ...)
+__sprintf_chk (char *dest, int flags, size_t dstlen, const char *format, ...)
{
va_list arg;
int done;
va_start (arg, format);
- if (len > (size_t) INT_MAX)
- done = vsprintf (s, format, arg);
+ if (__builtin_expect (dstlen > (size_t) INT_MAX, 0))
+ done = vsprintf (dest, format, arg);
else
{
- done = vsnprintf (s, len, format, arg);
- if (done >= 0 && (size_t) done >= len)
- __chk_fail ();
+ done = vsnprintf (dest, dstlen, format, arg);
+ if (__builtin_expect(done >= 0 && (size_t) done >= dstlen, 0))
+ __chk_fail_overflow ();
}
va_end (arg);
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdlib.h>
#include <string.h>
+#include "secure.h"
-extern void __chk_fail (void) __attribute__((__noreturn__));
-
-void *
+char *
__stpcpy_chk (char *dest, const char *src, size_t dstlen)
{
- size_t len = strlen (src);
+ char *retval = stpcpy(dest, src); // Returns a pointer to the \0
+ size_t len = retval - dest + 1;
if (__builtin_expect (dstlen < len, 0))
- __chk_fail ();
+ __chk_fail_overflow ();
+
+ if (__builtin_expect (__chk_assert_no_overlap, 1))
+ __chk_overlap(dest, len, src, len);
- return memcpy (dest, src, len + 1) + len;
+ return retval;
}
/*
- * Copyright (c) 2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2010-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdlib.h>
#include <string.h>
+#include "secure.h"
-extern void __chk_fail (void) __attribute__((__noreturn__));
-
-void *
+char *
__stpncpy_chk (char *restrict dest, char *restrict src,
size_t len, size_t dstlen)
{
+ size_t n;
+ char *retval;
+
if (__builtin_expect (dstlen < len, 0))
- __chk_fail ();
+ __chk_fail_overflow ();
+
+ retval = stpncpy (dest, src, len); // Normally returns a pointer to the \0
+ n = retval - dest + 1;
+
+ // Check if it's pointing to the location after the buffer after not writing \0
+ if (n == len + 1)
+ n--;
+
+ if (__builtin_expect (__chk_assert_no_overlap, 1))
+ __chk_overlap(dest, n, src, n);
- return stpncpy (dest, src, len);
+ return retval;
}
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
-
-extern void __chk_fail (void) __attribute__((__noreturn__));
+#include "secure.h"
char *
-__strcat_chk (char *__restrict s, const char *__restrict append,
- size_t slen)
+__strcat_chk (char *__restrict dest, const char *__restrict append,
+ size_t dstlen)
{
- char *save = s;
-
- /* Advance to the end. */
- for (; *s; ++s)
- if (__builtin_expect (slen-- == 0, 0))
- __chk_fail ();
-
- do
- {
- /* Append the string. Make sure we check before writing. */
- if (__builtin_expect (slen-- == 0, 0))
- __chk_fail ();
+ size_t len1 = strlen(dest);
+ size_t len2 = strlen(append);
- } while (*s++ = *append++);
+ if (__builtin_expect (dstlen < len1 + len2 + 1, 0))
+ __chk_fail_overflow ();
- return save;
+ if (__builtin_expect (__chk_assert_no_overlap, 1))
+ __chk_overlap(dest, len1 + len2 + 1, append, len2 + 1);
+ memcpy(dest + len1, append, len2 + 1);
+ return dest;
}
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdlib.h>
#include <string.h>
+#include "secure.h"
-extern void __chk_fail (void) __attribute__((__noreturn__));
-
-void *
+char *
__strcpy_chk (char *restrict dest, char *restrict src, size_t dstlen)
{
- size_t len = strlen (src);
+ // stpcpy returns a pointer to the \0
+ size_t len = stpcpy(dest, src) - dest + 1;
if (__builtin_expect (dstlen < len, 0))
- __chk_fail ();
+ __chk_fail_overflow ();
+
+ if (__builtin_expect (__chk_assert_no_overlap, 1))
+ __chk_overlap(dest, len, src, len);
- return memcpy (dest, src, len + 1);
+ return dest;
}
--- /dev/null
+/*
+ * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "secure.h"
+
+size_t
+__strlcat_chk (char *restrict dest, char *restrict src,
+ size_t len, size_t dstlen)
+{
+ size_t initial_srclen;
+ size_t initial_dstlen;
+
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail_overflow ();
+
+ initial_srclen = strlen(src);
+ initial_dstlen = strnlen(dest, len);
+
+ if (initial_dstlen == len)
+ return len+initial_srclen;
+
+ if (initial_srclen < len - initial_dstlen) {
+ __chk_overlap(dest, initial_srclen + initial_dstlen + 1, src, initial_srclen + 1);
+ memcpy(dest+initial_dstlen, src, initial_srclen + 1);
+ } else {
+ __chk_overlap(dest, initial_srclen + initial_dstlen + 1, src, len - initial_dstlen - 1);
+ memcpy(dest+initial_dstlen, src, len - initial_dstlen - 1);
+ dest[len-1] = '\0';
+ }
+
+ return initial_srclen + initial_dstlen;
+}
--- /dev/null
+/*
+ * Copyright (c) 2012-2013 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "secure.h"
+
+size_t
+__strlcpy_chk (char *restrict dest, char *restrict src,
+ size_t len, size_t dstlen)
+{
+ size_t retval;
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail_overflow ();
+
+ retval = strlcpy (dest, src, len);
+
+ if (retval < len)
+ len = retval + 1;
+
+ __chk_overlap(dest, len, src, len);
+
+ return retval;
+}
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdlib.h>
#include <string.h>
-
-extern void __chk_fail (void) __attribute__((__noreturn__));
+#include "secure.h"
char *
-__strncat_chk (char *restrict dest, const char *restrict src,
- size_t len, size_t dstlen)
+__strncat_chk (char *restrict dest, const char *restrict append,
+ size_t len, size_t dstlen)
{
- char *s1 = dest;
- const char *s2 = src;
+ size_t len1 = strlen(dest);
+ size_t len2 = strnlen(append, len);
- /* Advance to the end. */
- while (*s1 != 0)
- {
- if (__builtin_expect (dstlen-- == 0, 0))
- __chk_fail ();
- s1++;
- }
+ if (__builtin_expect (dstlen < len1 + len2 + 1, 0))
+ __chk_fail_overflow ();
- /* Append the string. */
- while (len > 0)
- {
- if (__builtin_expect (dstlen-- == 0, 0))
- __chk_fail ();
- if ((*s1 = *s2++) == 0)
- break;
- s1++;
- len--;
- }
- *s1 = 0;
+ if (__builtin_expect (__chk_assert_no_overlap, 1))
+ __chk_overlap(dest, len1 + len2 + 1, append, len2 + 1);
- return dest;
+ /* memmove() all but the NUL, since it might not actually be NUL */
+ memcpy(dest + len1, append, len2);
+ dest[len1 + len2] = '\0';
+ return dest;
}
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdlib.h>
#include <string.h>
+#include "secure.h"
-extern void __chk_fail (void) __attribute__((__noreturn__));
-
-void *
+char *
__strncpy_chk (char *restrict dest, char *restrict src,
size_t len, size_t dstlen)
{
+ size_t n;
+
if (__builtin_expect (dstlen < len, 0))
- __chk_fail ();
+ __chk_fail_overflow ();
+
+ // stpncpy normally returns a pointer to the \0
+ n = stpncpy (dest, src, len) - dest + 1;
+
+ // Check if it's pointing to the location after the buffer after not writing \0
+ if (n == len + 1)
+ n--;
+
+ if (__builtin_expect (__chk_assert_no_overlap, 1))
+ __chk_overlap(dest, n, src, n);
- return strncpy (dest, src, len);
+ return dest;
}
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
-
-extern void __chk_fail (void) __attribute__((__noreturn__));
-extern int __vsnprintf_chk (char * __restrict, size_t, int, size_t,
- const char * __restrict, va_list arg);
+#include "secure.h"
int
-__vsnprintf_chk (char *s, size_t maxlen, int flags, size_t len,
+__vsnprintf_chk (char *dest, size_t len, int flags, size_t dstlen,
const char *format, va_list arg)
{
int done;
- if (maxlen > len)
- __chk_fail ();
+ if (__builtin_expect (dstlen < len, 0))
+ __chk_fail_overflow ();
- done = vsnprintf (s, maxlen, format, arg);
+ done = vsnprintf (dest, len, format, arg);
return done;
}
/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2007-2013 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
-
-extern void __chk_fail (void) __attribute__((__noreturn__));
-extern int __vsprintf_chk (char * __restrict, int, size_t,
- const char * __restrict, va_list arg);
+#include "secure.h"
int
-__vsprintf_chk (char *s, int flags, size_t len, const char *format,
+__vsprintf_chk (char *dest, int flags, size_t dstlen, const char *format,
va_list arg)
{
int done;
- if (len > (size_t) INT_MAX)
- done = vsprintf (s, format, arg);
+ if (__builtin_expect (dstlen > (size_t) INT_MAX, 0))
+ done = vsprintf (dest, format, arg);
else
{
- done = vsnprintf (s, len, format, arg);
- if (done >= 0 && (size_t) done >= len)
- __chk_fail ();
+ done = vsnprintf (dest, dstlen, format, arg);
+ if (__builtin_expect (done >= 0 && (size_t) done >= dstlen, 0))
+ __chk_fail_overflow ();
}
return done;
int n;
{
struct glue *g;
- static FILE empty;
+ static const FILE empty;
FILE *p;
- static struct __sFILEX emptyx = __sFXInit;
+ static const struct __sFILEX emptyx = __sFXInit;
struct __sFILEX *fx;
g = (struct glue *)malloc(sizeof(*g) + ALIGNBYTES + n * sizeof(FILE) +
return (ret);
}
-size_t
-__fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
+/*
+ * The maximum amount to read to avoid integer overflow. INT_MAX is odd,
+ * so it make sense to make it even. We subtract (BUFSIZ - 1) to get a
+ * whole number of BUFSIZ chunks.
+ */
+#define MAXREAD (INT_MAX - (BUFSIZ - 1))
+
+/* __fread0: int sized, with size = 1 */
+static inline int
+__fread0(void * __restrict buf, int count, FILE * __restrict fp)
{
- size_t resid;
+ int resid;
char *p;
int r, ret;
- size_t total;
- /*
- * ANSI and SUSv2 require a return value of 0 if size or count are 0.
- */
- if ((resid = count * size) == 0)
- return (0);
- ORIENT(fp, -1);
- if (fp->_r < 0)
- fp->_r = 0;
- total = resid;
+ resid = count;
p = buf;
/* first deal with anything left in buffer, plus any ungetc buffers */
while (resid > (r = fp->_r)) {
break;
else if (ret) {
/* no more input: return partial result */
- return ((total - resid) / size);
+ return (count - resid);
}
}
/*
size_t n;
save = fp->_bf;
- fp->_bf._base = p;
+ fp->_bf._base = (unsigned char *)p;
fp->_bf._size = resid;
while (fp->_bf._size > 0) {
if ((ret = __srefill1(fp)) != 0) {
fp->_bf = save;
fp->_p = fp->_bf._base;
/* fp->_r = 0; already set in __srefill1 */
- return ((total - resid) / size);
+ return (count - resid);
}
fp->_bf._base += fp->_r;
fp->_bf._size -= fp->_r;
resid -= r;
if (__srefill1(fp)) {
/* no more input: return partial result */
- return ((total - resid) / size);
+ return (count - resid);
}
}
(void)memcpy((void *)p, (void *)fp->_p, resid);
}
return (count);
}
+
+size_t
+__fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
+{
+ size_t resid;
+ int r, ret;
+ size_t total;
+
+ /*
+ * ANSI and SUSv2 require a return value of 0 if size or count are 0.
+ */
+ if ((resid = count * size) == 0)
+ return (0);
+ ORIENT(fp, -1);
+ if (fp->_r < 0)
+ fp->_r = 0;
+
+ for (total = resid; resid > 0; buf += r, resid -= r) {
+ r = resid > INT_MAX ? MAXREAD : (int)resid;
+ if ((ret = __fread0(buf, r, fp)) != r) {
+ count = (total - resid + ret) / size;
+ break;
+ }
+ }
+ return (count);
+}
#include "fvwrite.h"
#include "libc_private.h"
+/*
+ * The maximum amount to write to avoid integer overflow (especially for
+ * uio_resid in struct __suio). INT_MAX is odd, so it make sense to make it
+ * even. We subtract (BUFSIZ - 1) to get a whole number of BUFSIZ chunks.
+ */
+#define MAXWRITE (INT_MAX - (BUFSIZ - 1))
+
/*
* Write `count' objects (each size `size') from memory to the given file.
* Return the number of whole objects written.
size_t size, count;
FILE * __restrict fp;
{
- size_t n;
+ size_t n, resid;
struct __suio uio;
struct __siov iov;
+ int s;
/*
* ANSI and SUSv2 require a return value of 0 if size or count are 0.
if (n == 0)
return (0);
#endif
- iov.iov_base = (void *)buf;
- uio.uio_resid = iov.iov_len = n;
uio.uio_iov = &iov;
uio.uio_iovcnt = 1;
FLOCKFILE(fp);
ORIENT(fp, -1);
- /*
- * The usual case is success (__sfvwrite returns 0);
- * skip the divide if this happens, since divides are
- * generally slow and since this occurs whenever size==0.
- */
- if (__sfvwrite(fp, &uio) != 0)
- count = (n - uio.uio_resid) / size;
+
+ for (resid = n; resid > 0; buf += s, resid -= s) {
+ s = resid > INT_MAX ? MAXWRITE : (int)resid;
+ iov.iov_base = (void *)buf;
+ uio.uio_resid = iov.iov_len = s;
+
+ /*
+ * The usual case is success (__sfvwrite returns 0);
+ * skip the divide if this happens, since divides are
+ * generally slow and since this occurs whenever size==0.
+ */
+ if (__sfvwrite(fp, &uio) != 0) {
+ count = (n - resid + s - uio.uio_resid) / size;
+ break;
+ }
+ }
FUNLOCKFILE(fp);
return (count);
}
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.\" $FreeBSD: src/lib/libc/stdio/getline.3,v 1.2 2009/04/06 13:50:04 das Exp $
+.\" $FreeBSD: src/lib/libc/stdio/getline.3,v 1.5 2012/03/29 05:02:12 eadler Exp $
.\"
-.Dd March 29, 2009
+.Dd November 30, 2010
.Dt GETLINE 3
.Os
.Sh NAME
with the newline character as the delimiter.
The delimiter character is included as part of the line, unless
the end of the file is reached.
-The caller may provide a pointer to a malloc buffer for the line in
+.Pp
+The caller may provide a pointer to a malloced buffer for the line in
.Fa *linep ,
and the capacity of that buffer in
-.Fa *linecapp ;
-if
-.Fa *linecapp
-is 0, then
-.Fa *linep
-is treated as
-.Dv NULL .
-These functions may expand the buffer as needed, as if via
-.Fn realloc ,
-and update
+.Fa *linecapp .
+These functions expand the buffer as needed, as if via
+.Fn realloc .
+If
+.Fa linep
+points to a
+.Dv NULL
+pointer, a new buffer will be allocated.
+In either case,
.Fa *linep
and
.Fa *linecapp
-accordingly.
+will be updated accordingly.
.Sh RETURN VALUES
The
.Fn getdelim
.Fn getline
functions return the number of characters written, excluding the
terminating
-.Dv NULL .
+.Dv NUL
+character.
The value \-1 is returned if an error occurs, or if end-of-file is reached.
.Sh EXAMPLES
The following code fragment reads lines from a file and
characters.
.El
.Pp
-These functions may also fail for any of the errors specified for
+These functions may also fail due to any of the errors specified for
.Fn fgets
and
.Fn malloc .
int c;
char *s;
static int warned;
- static char w[] =
+ static const char w[] =
"warning: this program uses gets(), which is unsafe.\n";
FLOCKFILE(stdin);
#include <sys/cdefs.h>
#include "xlocale_private.h"
+#include "xprintf_private.h"
#include <sys/types.h> /* for off_t */
#include <pthread.h>
#include <limits.h>
extern fpos_t _sseek(FILE *, fpos_t, int);
extern int _ftello(FILE *, fpos_t *);
extern int _fseeko(FILE *, off_t, int, int);
+extern int _vasprintf(printf_comp_t __restrict, printf_domain_t __restrict,
+ char ** __restrict, locale_t __restrict,
+ const char * __restrict, __va_list);
+extern int _vdprintf(printf_comp_t __restrict, printf_domain_t __restrict,
+ int, locale_t __restrict, const char * __restrict, va_list);
+extern int _vsnprintf(printf_comp_t __restrict, printf_domain_t __restrict,
+ char * __restrict, size_t n, locale_t __restrict,
+ const char * __restrict, __va_list);
+
extern int __fflush(FILE *fp);
extern void __fcloseall(void);
extern wint_t __fgetwc(FILE *, locale_t);
#include "libc_private.h"
#include "local.h"
-#define MAXBUFSIZE (1 << 16)
+#ifdef FEATURE_SMALL_STDIOBUF
+# define MAXBUFSIZE (1 << 12)
+#else
+# define MAXBUFSIZE (1 << 16)
+#endif
+
#define TTYBUFSIZE 4096
/*
/*
* Defining here VECTORS for all files that include this header (<rdar://problem/8466056>)
*/
-#define VECTORS
+#ifndef VECTORS
+#define VECTORS
+typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE;
+#ifdef __SSE2__
+#define V64TYPE
+#endif /* __SSE2__ */
+#endif /* VECTORS */
/*
* Flags used during conversion.
/* Size of the static argument table. */
#define STATIC_ARG_TBL_SIZE 8
-#ifdef VECTORS
-typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE;
-#ifdef __SSE2__
-#define V64TYPE
-#endif /* __SSE2__ */
-#endif /* VECTORS */
-
union arg {
int intarg;
u_int uintarg;
#include <errno.h>
#include "local.h"
-int
-vasprintf_l(str, loc, fmt, ap)
- char **str;
- locale_t loc;
- const char *fmt;
- __va_list ap;
+__private_extern__ int
+_vasprintf(printf_comp_t __restrict pc, printf_domain_t __restrict domain, char ** __restrict str, locale_t __restrict loc, const char * __restrict fmt, __va_list ap)
{
int ret;
FILE f;
f._extra = &ext;
INITEXTRA(&f);
- NORMALIZE_LOCALE(loc);
f._file = -1;
f._flags = __SWR | __SSTR | __SALC;
f._bf._base = f._p = (unsigned char *)malloc(128);
f._bf._size = f._w = 127; /* Leave room for the NUL */
f._orientation = 0;
memset(&f._mbstate, 0, sizeof(mbstate_t));
- ret = __vfprintf(&f, loc, fmt, ap);
+ ret = __v2printf(pc, domain, &f, loc, fmt, ap);
if (ret < 0) {
free(f._bf._base);
*str = NULL;
}
int
-vasprintf(str, fmt, ap)
- char **str;
- const char *fmt;
- __va_list ap;
+vasprintf_l(char ** __restrict str, locale_t __restrict loc, const char * __restrict fmt, __va_list ap)
+{
+ return _vasprintf(XPRINTF_PLAIN, NULL, str, loc, fmt, ap);
+}
+
+int
+vasprintf(char ** __restrict str, const char * __restrict fmt, __va_list ap)
{
- return vasprintf_l(str, __current_locale(), fmt, ap);
+ return _vasprintf(XPRINTF_PLAIN, NULL, str, __current_locale(), fmt, ap);
}
#include "local.h"
-int
-vdprintf_l(int fd, locale_t loc, const char * __restrict fmt, va_list ap)
+__private_extern__ int
+_vdprintf(printf_comp_t __restrict pc, printf_domain_t __restrict domain, int fd, locale_t __restrict loc, const char * __restrict fmt, va_list ap)
{
FILE f;
unsigned char buf[BUFSIZ];
f._extra = &ext;
INITEXTRA(&f);
- NORMALIZE_LOCALE(loc);
-
if (fd > SHRT_MAX) {
errno = EMFILE;
return (EOF);
f._orientation = 0;
bzero(&f._mbstate, sizeof(f._mbstate));
- if ((ret = __vfprintf(&f, loc, fmt, ap)) < 0)
+ if ((ret = __v2printf(pc, domain, &f, loc, fmt, ap)) < 0)
return (ret);
return (__fflush(&f) ? EOF : ret);
}
+int
+vdprintf_l(int fd, locale_t __restrict loc, const char * __restrict fmt, va_list ap)
+{
+ return _vdprintf(XPRINTF_PLAIN, NULL, fd, loc, fmt, ap);
+}
+
int
vdprintf(int fd, const char * __restrict fmt, va_list ap) {
- return vdprintf_l(fd, __current_locale(), fmt, ap);
+ return _vdprintf(XPRINTF_PLAIN, NULL, fd, __current_locale(), fmt, ap);
}
#include "printflocal.h"
static int __sprint(FILE *, locale_t, struct __suio *);
+#if 0
static int __sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0);
+#endif
static char *__wcsconv(wchar_t *, int, locale_t);
__private_extern__ const char *__fix_nogrouping(const char *);
return (err);
}
+#if 0
/*
* Helper function for `fprintf to unbuffered unix file': creates a
* temporary buffer. We only work on write-only files; this avoids
fp->_flags |= __SERR;
return (ret);
}
+#endif
/*
* Convert a wide character string argument for the %ls format to a multibyte
{
int ret;
- NORMALIZE_LOCALE(loc);
FLOCKFILE(fp);
- /* optimise fprintf(stderr) (and other unbuffered Unix files) */
- if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
- fp->_file >= 0)
- ret = __sbprintf(fp, loc, fmt0, ap);
- else
- ret = __vfprintf(fp, loc, fmt0, ap);
+ ret = __xvprintf(XPRINTF_PLAIN, NULL, fp, loc, fmt0, ap);
FUNLOCKFILE(fp);
return (ret);
}
vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
{
- return vfprintf_l(fp, __current_locale(), fmt0, ap);
+ int ret;
+
+ FLOCKFILE(fp);
+ ret = __xvprintf(XPRINTF_PLAIN, NULL, fp, __current_locale(), fmt0, ap);
+ FUNLOCKFILE(fp);
+ return ret;
}
/*
val = GETARG (int); \
}
-#if 0 // xprintf pending API review
- if (__use_xprintf == 0 && getenv("USE_XPRINTF"))
- __use_xprintf = 1;
- if (__use_xprintf > 0)
- return (__xvprintf(fp, loc, fmt0, ap));
-#endif
-
+ /* The following has been moved to __v2printf() */
+#if 0
/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
if (prepwrite(fp) != 0) {
errno = EBADF;
return (EOF);
}
ORIENT(fp, -1);
+#endif
convbuf = NULL;
fmt = (char *)fmt0;
int mb_cur_max;
/* `basefix' is used to avoid `if' tests in the integer scanner */
- static short basefix[17] =
+ static const short basefix[17] =
{ 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
NORMALIZE_LOCALE(loc);
int mb_cur_max = MB_CUR_MAX_L(loc);
/* `basefix' is used to avoid `if' tests in the integer scanner */
- static short basefix[17] =
+ static const short basefix[17] =
{ 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
nassigned = 0;
#include <stdio.h>
#include "local.h"
-int
-vsnprintf_l(char * __restrict str, size_t n, locale_t loc, const char * __restrict fmt,
- __va_list ap)
+__private_extern__ int
+_vsnprintf(printf_comp_t __restrict pc, printf_domain_t __restrict domain, char * __restrict str, size_t n, locale_t __restrict loc, const char * __restrict fmt, __va_list ap)
{
size_t on;
int ret;
f._extra = &ext;
INITEXTRA(&f);
- NORMALIZE_LOCALE(loc);
on = n;
if (n != 0)
n--;
f._bf._size = f._w = n;
f._orientation = 0;
memset(&f._mbstate, 0, sizeof(mbstate_t));
- ret = __vfprintf(&f, loc, fmt, ap);
+ ret = __v2printf(pc, domain, &f, loc, fmt, ap);
if (on > 0)
*f._p = '\0';
return (ret);
}
+int
+vsnprintf_l(char * __restrict str, size_t n, locale_t __restrict loc, const char * __restrict fmt,
+ __va_list ap)
+{
+ return _vsnprintf(XPRINTF_PLAIN, NULL, str, n, loc, fmt, ap);
+}
int
vsnprintf(char * __restrict str, size_t n, const char * __restrict fmt,
__va_list ap)
{
- return vsnprintf_l(str, n, __current_locale(), fmt, ap);
+ return _vsnprintf(XPRINTF_PLAIN, NULL, str, n, __current_locale(), fmt, ap);
}
f._extra = &ext;
INITEXTRA(&f);
- NORMALIZE_LOCALE(loc);
f._file = -1;
f._flags = __SWR | __SSTR;
f._bf._base = f._p = (unsigned char *)str;
f._bf._size = f._w = INT_MAX;
f._orientation = 0;
memset(&f._mbstate, 0, sizeof(mbstate_t));
- ret = __vfprintf(&f, loc, fmt, ap);
+ ret = __v2printf(XPRINTF_PLAIN, NULL, &f, loc, fmt, ap);
*f._p = 0;
return (ret);
}
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdio/xprintf.c,v 1.9 2010/03/11 17:03:32 jhb Exp $
+ */
+
+#include "namespace.h"
+#include <err.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <locale.h>
+#include <stdint.h>
+#include <assert.h>
+#include <stdarg.h>
+#include <namespace.h>
+#include <string.h>
+#include <wchar.h>
+#include <errno.h>
+#include "un-namespace.h"
+
+//#define MACHTIME
+#ifdef MACHTIME
+#include <mach/mach_time.h>
+#endif // MACHTIME
+
+#ifdef XPRINTF_PERF
+#include <libkern/OSAtomic.h>
+#endif /* XPRINTF_PERF */
+
+#include "local.h"
+#include "xprintf_private.h"
+#include "xprintf_domain.h"
+#include "fvwrite.h"
+
+/*
+ * Defining XPRINTF_DEBUG allows the __private_extern__ variable __use_xprintf
+ * to be set so that regular printf variants will use the extensible printf
+ * code path. This is normally off, and is only used to test the extensible
+ * printf code in the conformance tests.
+ */
+#ifdef XPRINTF_DEBUG
+#include <unistd.h>
+int __use_xprintf = 0;
+#endif
+
+/* private stuff -----------------------------------------------------*/
+
+union arg {
+ int intarg;
+ long longarg;
+ intmax_t intmaxarg;
+#ifndef NO_FLOATING_POINT
+ double doublearg;
+ long double longdoublearg;
+#endif
+ wint_t wintarg;
+ char *pchararg;
+ wchar_t *pwchararg;
+ void *pvoidarg;
+#ifdef VECTORS
+ VECTORTYPE vectorarg;
+ unsigned char vuchararg[16];
+ signed char vchararg[16];
+ unsigned short vushortarg[8];
+ signed short vshortarg[8];
+ unsigned int vuintarg[4];
+ signed int vintarg[4];
+ float vfloatarg[4];
+#ifdef V64TYPE
+ double vdoublearg[2];
+ unsigned long long vulonglongarg[2];
+ long long vlonglongarg[2];
+#endif /* V64TYPE */
+#endif /* VECTORS */
+};
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define to_digit(c) ((c) - '0')
+#define is_digit(c) (((unsigned)to_digit(c)) <= 9)
+
+/* various globals ---------------------------------------------------*/
+
+__private_extern__ const char __lowercase_hex[17] = "0123456789abcdef?"; /*lint !e784 */
+__private_extern__ const char __uppercase_hex[17] = "0123456789ABCDEF?"; /*lint !e784 */
+
+#define PADSIZE 16
+static char blanks[PADSIZE] =
+ {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
+static char zeroes[PADSIZE] =
+ {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
+
+/* printing and padding functions ------------------------------------*/
+
+#define NIOV 8
+
+struct __printf_io {
+ FILE *fp;
+ struct __suio uio;
+ struct __siov iov[NIOV];
+ struct __siov *iovp;
+};
+
+static void
+__printf_init(struct __printf_io *io)
+{
+
+ io->uio.uio_iov = io->iovp = &io->iov[0];
+ io->uio.uio_resid = 0;
+ io->uio.uio_iovcnt = 0;
+}
+
+__private_extern__ void
+__printf_flush(struct __printf_io *io)
+{
+
+ __sfvwrite(io->fp, &io->uio);
+ __printf_init(io);
+}
+
+__private_extern__ int
+__printf_puts(struct __printf_io *io, const void *ptr, int len)
+{
+
+
+#if 0
+ if (io->fp->_flags & __SERR)
+ return (0);
+#endif
+ if (len == 0)
+ return (0);
+ io->iovp->iov_base = __DECONST(void *, ptr);
+ io->iovp->iov_len = len;
+ io->uio.uio_resid += len;
+ io->iovp++;
+ io->uio.uio_iovcnt++;
+ if (io->uio.uio_iovcnt >= NIOV)
+ __printf_flush(io);
+ return (len);
+}
+
+__private_extern__ int
+__printf_pad(struct __printf_io *io, int howmany, int zero)
+{
+ int n;
+ const char *with;
+ int ret = 0;
+
+ if (zero)
+ with = zeroes;
+ else
+ with = blanks;
+
+ if ((n = (howmany)) > 0) {
+ while (n > PADSIZE) {
+ ret += __printf_puts(io, with, PADSIZE);
+ n -= PADSIZE;
+ }
+ ret += __printf_puts(io, with, n);
+ }
+ return (ret);
+}
+
+__private_extern__ int
+__printf_out(struct __printf_io *io, const struct printf_info *pi, const void *ptr, int len)
+{
+ int ret = 0;
+
+ if ((!pi->left) && pi->width > len)
+ ret += __printf_pad(io, pi->width - len, pi->pad == '0');
+ ret += __printf_puts(io, ptr, len);
+ if (pi->left && pi->width > len)
+ ret += __printf_pad(io, pi->width - len, pi->pad == '0');
+ return (ret);
+}
+
+
+/* percent handling -------------------------------------------------*/
+
+__private_extern__ int
+__printf_arginfo_pct(const struct printf_info *pi __unused, size_t n __unused, int *argt __unused)
+{
+
+ return (0);
+}
+
+__private_extern__ int
+__printf_render_pct(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg __unused)
+{
+
+ return (__printf_puts(io, "%", 1));
+}
+
+/* 'n' ---------------------------------------------------------------*/
+
+__private_extern__ int
+__printf_arginfo_n(const struct printf_info *pi, size_t n, int *argt)
+{
+
+ assert(n >= 1);
+ argt[0] = PA_POINTER;
+ return (1);
+}
+
+/*
+ * This is a printf_render so that all output has been flushed before it
+ * gets called.
+ */
+
+__private_extern__ int
+__printf_render_n(FILE *io __unused, const struct printf_info *pi, const void *const *arg)
+{
+
+ if (pi->is_char)
+ **((signed char **)arg[0]) = (signed char)pi->sofar;
+ else if (pi->is_short)
+ **((short **)arg[0]) = (short)pi->sofar;
+ else if (pi->is_long)
+ **((long **)arg[0]) = pi->sofar;
+ else if (pi->is_long_double)
+ **((long long **)arg[0]) = pi->sofar;
+ else if (pi->is_intmax)
+ **((intmax_t **)arg[0]) = pi->sofar;
+ else if (pi->is_ptrdiff)
+ **((ptrdiff_t **)arg[0]) = pi->sofar;
+ else if (pi->is_quad)
+ **((quad_t **)arg[0]) = pi->sofar;
+ else if (pi->is_size)
+ **((size_t **)arg[0]) = pi->sofar;
+ else
+ **((int **)arg[0]) = pi->sofar;
+
+ return (0);
+}
+
+/* dynamic array handling -------------------------------------------------*/
+#define ARRAYDELTA 8
+
+struct array {
+#ifdef XPRINTF_PERF
+ struct array *next;
+#endif /* XPRINTF_PERF */
+ void *data;
+ int itemsize;
+ int max;
+};
+
+#ifdef XPRINTF_PERF
+__private_extern__
+#else /* !XPRINTF_PERF */
+static
+#endif /* !XPRINTF_PERF */
+void
+arrayfree(struct array *a)
+{
+ if(a) free(a->data);
+}
+
+static void *
+arrayget(struct array *a, int i)
+{
+ if (i >= a->max) {
+ int oldsize = a->max * a->itemsize;
+ int newmax = i + ARRAYDELTA;
+ int newsize = newmax * a->itemsize;
+ void *newdata = realloc(a->data, newsize);
+ if(!newdata) return NULL;
+ bzero(newdata + oldsize, newsize - oldsize);
+ a->data = newdata;
+ a->max = newmax;
+ }
+ return a->data + i * a->itemsize;
+}
+
+static struct array *
+arrayinit(struct array *a, int itemsize)
+{
+ a->data = CALLOC(ARRAYDELTA, itemsize);
+ if(!a->data) return NULL;
+ a->itemsize = itemsize;
+ a->max = ARRAYDELTA;
+ return a;
+}
+
+/* dynamic array caching -------------------------------------------------*/
+/*
+ * Normally, dynamic array structures are created on the stack, and array
+ * itself is freshly allocated, and then freed when no longer needed. When
+ * the XPRINTF_PERF macro is defined, the dynamic array structures associated
+ * with all-in-one printf variants are not freed, but store in a cache for
+ * later use (dynamic array structures used for compile/execute continue to
+ * be freed after they are no longer needed). This means there should be
+ * at most one structure in the cached per thread that actually used the
+ * all-in-one printf variant.
+ *
+ * The amount of memory that is cached is fairly small, totally about 1K
+ * for three structures used by a format string using ten conversion
+ * specifiers. This is too small for purgeable memory.
+ *
+ * However, we do flush these caches in case we every are unable to allocate
+ * memory, and retry the allocation, just in case.
+ */
+#ifdef XPRINTF_PERF
+static OSQueueHead arg_type_queue = OS_ATOMIC_QUEUE_INIT;
+static OSQueueHead printf_info_queue = OS_ATOMIC_QUEUE_INIT;
+static OSQueueHead union_arg_queue = OS_ATOMIC_QUEUE_INIT;
+
+#define DEFINE_DEQUEUE(which, type) \
+static struct array * \
+which ## _dequeue(void) \
+{ \
+ struct array *a = (struct array *)OSAtomicDequeue(&which ## _queue, offsetof(struct array, next)); \
+ \
+ if (a) { \
+ bzero(a->data, a->max * a->itemsize); \
+ return a; \
+ } \
+ a = (struct array *)MALLOC(sizeof(*a)); \
+ if (!a) return NULL; \
+ if (!arrayinit(a, sizeof(type))) { \
+ free(a); \
+ return NULL; \
+ } \
+ return a; \
+}
+
+#define DEFINE_ENQUEUE(which) \
+__private_extern__ void \
+which ## _enqueue(struct array *a) \
+{ \
+ if (!a) return; \
+ OSAtomicEnqueue(&which ## _queue, a, offsetof(struct array, next)); \
+}
+
+#define DEFINE_FLUSH(which) \
+static void \
+which ## _flush(void) \
+{ \
+ struct array *a; \
+ while((a = (struct array *)OSAtomicDequeue(&which ## _queue, offsetof(struct array, next))) != NULL) { \
+ arrayfree(a); \
+ free(a); \
+ } \
+}
+
+DEFINE_DEQUEUE(arg_type, int)
+DEFINE_ENQUEUE(arg_type)
+DEFINE_FLUSH(arg_type)
+DEFINE_DEQUEUE(printf_info, struct printf_info)
+DEFINE_ENQUEUE(printf_info)
+DEFINE_FLUSH(printf_info)
+DEFINE_DEQUEUE(union_arg, union arg)
+DEFINE_ENQUEUE(union_arg)
+DEFINE_FLUSH(union_arg)
+
+static void
+flush_queues(void)
+{
+ arg_type_flush();
+ printf_info_flush();
+ union_arg_flush();
+}
+
+__private_extern__ void *
+xprintf_calloc(size_t count, size_t size)
+{
+ void *x = calloc(count, size);
+ if(!x) {
+ flush_queues();
+ x = calloc(count, size);
+ }
+ return x;
+}
+
+__private_extern__ void *
+xprintf_malloc(size_t size)
+{
+ void *x = malloc(size);
+ if(!x) {
+ flush_queues();
+ x = malloc(size);
+ }
+ return x;
+}
+
+#if 0
+void
+show_queues(void)
+{
+ struct array *a;
+ printf("arg_type:");
+ while((a = (struct array *)OSAtomicDequeue(&arg_type_queue, offsetof(struct array, next))) != NULL) printf("\n%p", a);
+ printf("\nprintf_info:");
+ while((a = (struct array *)OSAtomicDequeue(&printf_info_queue, offsetof(struct array, next))) != NULL) printf("\n%p", a);
+ printf("\nunion_arg:");
+ while((a = (struct array *)OSAtomicDequeue(&union_arg_queue, offsetof(struct array, next))) != NULL) printf("\n%p", a);
+ printf("\n");
+}
+#endif
+#endif /* XPRINTF_PERF */
+
+/* -------------------------------------------------------------------------*/
+
+__private_extern__ int
+__printf_comp(printf_comp_t restrict pc, printf_domain_t restrict domain)
+{
+ struct printf_info *pi, *pil;
+ const char *fmt;
+ int ch, pii;
+ int *argt;
+ int nextarg;
+ int maxarg;
+ int ret = 0;
+ int n;
+#ifndef XPRINTF_PERF
+ struct array piarr, argtarr;
+#endif /* XPRINTF_PERF */
+ struct array *pa, *aa;
+
+ fmt = pc->fmt;
+ maxarg = 0;
+ nextarg = 1;
+#ifdef XPRINTF_PERF
+ pa = printf_info_dequeue();
+#else /* !XPRINTF_PERF */
+ pa = arrayinit(&piarr, sizeof(*pi));
+#endif /* !XPRINTF_PERF */
+ if (!pa) {
+#ifdef XPRINTF_PERF
+ flush_queues();
+#endif /* XPRINTF_PERF */
+ return EOF;
+ }
+#ifdef XPRINTF_PERF
+ pc->pa = pa;
+ aa = arg_type_dequeue();
+#else /* !XPRINTF_PERF */
+ aa = arrayinit(&argtarr, sizeof(*argt));
+#endif /* !XPRINTF_PERF */
+ if (!aa) {
+ arrayfree(pa);
+#ifdef XPRINTF_PERF
+ free(pa);
+ flush_queues();
+#endif /* XPRINTF_PERF */
+ return EOF;
+ }
+#ifdef XPRINTF_PERF
+ pc->aa = aa;
+#endif /* XPRINTF_PERF */
+ for (pii = 0; ; pii++) {
+ pi = arrayget(pa, pii);
+ if (!pi) {
+ ret = EOF;
+ goto error;
+ }
+ pil = pi;
+ if (*fmt == '\0')
+ break;
+ pil = pi + 1;
+ pi->prec = -1;
+ pi->pad = ' ';
+#ifdef VECTORS
+ pi->vsep = 'X'; /* Illegal value, changed to defaults later. */
+#endif /* VECTORS */
+ pi->begin = pi->end = fmt;
+ while (*fmt != '\0' && *fmt != '%')
+ pi->end = ++fmt;
+ if (*fmt == '\0')
+ break;
+ fmt++;
+ for (;;) {
+ pi->spec = *fmt;
+ switch (pi->spec) {
+ case ' ':
+ /*-
+ * ``If the space and + flags both appear, the space
+ * flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (pi->showsign == 0) {
+ pi->space = 1;
+ pi->signchar = ' ';
+ }
+ fmt++;
+ continue;
+ case '#':
+ pi->alt = 1;
+ fmt++;
+ continue;
+#ifdef VECTORS
+ case ',': case ';': case ':': case '_':
+ pi->vsep = pi->spec;
+ fmt++;
+ continue;
+#endif /* VECTORS */
+ case '.':
+ pi->prec = 0;
+ fmt++;
+ if (*fmt == '*') {
+ fmt++;
+ /* Look for *nn$ and deal with it */
+ n = 0;
+ while (*fmt != '\0' && is_digit(*fmt)) {
+ n *= 10;
+ n += to_digit(*fmt);
+ fmt++;
+ }
+ if (*fmt == '$') {
+ if ((n + 1) > maxarg)
+ maxarg = (n + 1);
+ fmt++;
+ } else n = nextarg++;
+ pi->get_prec = n;
+ argt = (int *)arrayget(aa, n);
+ if (!argt) {
+ ret = EOF;
+ goto error;
+ }
+ *argt = PA_INT;
+ continue;
+ }
+ while (*fmt != '\0' && is_digit(*fmt)) {
+ pi->prec *= 10;
+ pi->prec += to_digit(*fmt);
+ fmt++;
+ }
+ continue;
+ case '-':
+ pi->left = 1;
+ fmt++;
+ continue;
+ case '+':
+ pi->showsign = 1;
+ pi->signchar = '+';
+ fmt++;
+ continue;
+ case '*':
+ fmt++;
+ /* Look for *nn$ and deal with it */
+ n = 0;
+ while (*fmt != '\0' && is_digit(*fmt)) {
+ n *= 10;
+ n += to_digit(*fmt);
+ fmt++;
+ }
+ if (*fmt == '$') {
+ if ((n + 1) > maxarg)
+ maxarg = (n + 1);
+ fmt++;
+ } else n = nextarg++;
+ pi->get_width = n;
+ argt = (int *)arrayget(aa, n);
+ if (!argt) {
+ ret = EOF;
+ goto error;
+ }
+ *argt = PA_INT;
+ continue;
+ case '%':
+ fmt++;
+ break;
+ case '\'':
+ pi->group = 1;
+ fmt++;
+ continue;
+ case '0':
+ /*-
+ * ``Note that 0 is taken as a flag, not as the
+ * beginning of a field width.''
+ * -- ANSI X3J11
+ */
+ pi->pad = '0';
+ fmt++;
+ continue;
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ n = 0;
+ while (*fmt != '\0' && is_digit(*fmt)) {
+ n *= 10;
+ n += to_digit(*fmt);
+ fmt++;
+ }
+ if (*fmt == '$') {
+ if (nextarg > maxarg)
+ maxarg = nextarg;
+ nextarg = n;
+ fmt++;
+ } else
+ pi->width = n;
+ continue;
+#if 0
+ case 'D':
+ case 'O':
+ case 'U':
+ pi->spec += ('a' - 'A');
+ pi->is_intmax = 0;
+ if (pi->is_long_double || pi->is_quad) {
+ pi->is_long = 0;
+ pi->is_long_double = 1;
+ } else {
+ pi->is_long = 1;
+ pi->is_long_double = 0;
+ }
+ fmt++;
+ break;
+#endif
+ case 'j':
+ pi->is_intmax = 1;
+ fmt++;
+ continue;
+ case 'q':
+ pi->is_long = 0;
+ pi->is_quad = 1;
+ fmt++;
+ continue;
+ case 'L':
+ pi->is_long_double = 1;
+ fmt++;
+ continue;
+ case 'h':
+ fmt++;
+ if (*fmt == 'h') {
+ fmt++;
+ pi->is_char = 1;
+ } else {
+ pi->is_short = 1;
+ }
+ continue;
+ case 'l':
+ fmt++;
+ if (*fmt == 'l') {
+ fmt++;
+ pi->is_long_double = 1;
+ pi->is_quad = 0;
+ } else {
+ pi->is_quad = 0;
+ pi->is_long = 1;
+ }
+ continue;
+ case 't':
+ pi->is_ptrdiff = 1;
+ fmt++;
+ continue;
+ case 'v':
+#ifdef VECTORS
+ pi->is_vec = 1;
+#endif /* VECTORS */
+ fmt++;
+ continue;
+ case 'z':
+ pi->is_size = 1;
+ fmt++;
+ continue;
+ default:
+ fmt++;
+ break;
+ }
+ if (printf_tbl_in_range(pi->spec)) {
+ switch(domain->type[printf_tbl_index(pi->spec)]) {
+ /* ignore PRINTF_DOMAIN_UNUSED until later */
+ case PRINTF_DOMAIN_FLAG:
+ errx(1, "Unexpected flag: %c", pi->spec);
+ case PRINTF_DOMAIN_GLIBC_API:
+ case PRINTF_DOMAIN_FBSD_API:
+ /*
+ * Insure that there are always
+ * __PRINTFMAXARG available.
+ */
+ if (!arrayget(aa, nextarg + __PRINTFMAXARG - 1)) {
+ ret = EOF;
+ goto error;
+ }
+ pi->context = domain->tbl[printf_tbl_index(pi->spec)].context;
+ pi->loc = pc->loc;
+ ch = domain->tbl[printf_tbl_index(pi->spec)].arginfo(
+ pi, __PRINTFMAXARG, arrayget(aa, nextarg));
+ if (ch > 0)
+ pi->arg[0] = (void *)(long)nextarg;
+ if (ch > 1)
+ pi->arg[1] = (void *)(long)(nextarg + 1);
+ nextarg += ch;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ if (nextarg > maxarg)
+ maxarg = nextarg;
+ pc->argt = aa->data;
+ pc->pi = pa->data;
+ pc->pil = pil;
+ pc->maxarg = ch = maxarg;
+ if (ch < 1) ch = 1;
+#ifdef XPRINTF_PERF
+ pc->ua = union_arg_dequeue();
+ if (!pc->ua) {
+ ret = EOF;
+ goto error;
+ }
+ if (!arrayget(pc->ua, ch)) {
+ union_arg_enqueue(pc->ua);
+ ret = EOF;
+ goto error;
+ }
+ pc->args = pc->ua->data;
+#else /* !XPRINTF_PERF */
+ pc->args = (union arg *)malloc(ch * sizeof(*pc->args));
+ if (!pc->args) {
+ ret = EOF;
+ goto error;
+ }
+#endif /* !XPRINTF_PERF */
+ for (pi = pc->pi; pi < pil; pi++) {
+ if (pi->arg[0]) pi->arg[0] = &pc->args[(long)pi->arg[0]];
+ if (pi->arg[1]) pi->arg[1] = &pc->args[(long)pi->arg[1]];
+ }
+#if 0
+ fprintf(stderr, "fmt0 <%s>\n", fmt0);
+ fprintf(stderr, "pil %p\n", pil);
+#endif
+ pc->domain = domain;
+
+ return (ret);
+error:
+ arrayfree(pa);
+ arrayfree(aa);
+#ifdef XPRINTF_PERF
+ free(pa);
+ free(aa);
+ flush_queues();
+#endif /* XPRINTF_PERF */
+ return (ret);
+}
+
+__private_extern__ int
+__printf_exec(printf_comp_t restrict pc, FILE * restrict fp, va_list ap)
+{
+ struct printf_info *pi;
+ int ch;
+ int ret = 0;
+ int n;
+ struct __printf_io io;
+
+ __printf_init(&io);
+ io.fp = fp;
+
+ for (ch = 1; ch < pc->maxarg; ch++) {
+#if 0
+ fprintf(stderr, "arg %d %x\n", ch, pc->argt[ch]);
+#endif
+ switch(pc->argt[ch]) {
+ case PA_CHAR:
+ pc->args[ch].intarg = (char)va_arg (ap, int);
+ break;
+ case PA_INT:
+ pc->args[ch].intarg = va_arg (ap, int);
+ break;
+ case PA_INT | PA_FLAG_SHORT:
+ pc->args[ch].intarg = (short)va_arg (ap, int);
+ break;
+ case PA_INT | PA_FLAG_LONG:
+ pc->args[ch].longarg = va_arg (ap, long);
+ break;
+ case PA_INT | PA_FLAG_INTMAX:
+ pc->args[ch].intmaxarg = va_arg (ap, intmax_t);
+ break;
+ case PA_INT | PA_FLAG_QUAD:
+ pc->args[ch].intmaxarg = va_arg (ap, quad_t);
+ break;
+ case PA_INT | PA_FLAG_LONG_LONG:
+ pc->args[ch].intmaxarg = va_arg (ap, long long);
+ break;
+ case PA_INT | PA_FLAG_SIZE:
+ pc->args[ch].intmaxarg = va_arg (ap, size_t);
+ break;
+ case PA_INT | PA_FLAG_PTRDIFF:
+ pc->args[ch].intmaxarg = (unsigned long)va_arg (ap, ptrdiff_t);
+ break;
+ case PA_WCHAR:
+ pc->args[ch].wintarg = va_arg (ap, wint_t);
+ break;
+ case PA_POINTER:
+ pc->args[ch].pvoidarg = va_arg (ap, void *);
+ break;
+ case PA_STRING:
+ pc->args[ch].pchararg = va_arg (ap, char *);
+ break;
+ case PA_WSTRING:
+ pc->args[ch].pwchararg = va_arg (ap, wchar_t *);
+ break;
+ case PA_DOUBLE:
+#ifndef NO_FLOATING_POINT
+ pc->args[ch].doublearg = va_arg (ap, double);
+#endif
+ break;
+ case PA_DOUBLE | PA_FLAG_LONG_DOUBLE:
+#ifndef NO_FLOATING_POINT
+ pc->args[ch].longdoublearg = va_arg (ap, long double);
+#endif
+ break;
+#ifdef VECTORS
+ case PA_VECTOR:
+ pc->args[ch].vectorarg = va_arg (ap, VECTORTYPE);
+ break;
+#endif /* VECTORS */
+ default:
+ errx(1, "argtype = %x (fmt = \"%s\")\n",
+ pc->argt[ch], pc->fmt);
+ }
+ }
+ for (pi = pc->pi; pi < pc->pil; pi++) {
+#if 0
+ fprintf(stderr, "pi %p", pi);
+ fprintf(stderr, " spec '%c'", pi->spec);
+ fprintf(stderr, " args %d",
+ ((uintptr_t)pi->arg[0] - (uintptr_t)pc->args) / sizeof pc->args[0]);
+ if (pi->width) fprintf(stderr, " width %d", pi->width);
+ if (pi->pad) fprintf(stderr, " pad 0x%x", pi->pad);
+ if (pi->left) fprintf(stderr, " left");
+ if (pi->showsign) fprintf(stderr, " showsign");
+ if (pi->signchar) fprintf(stderr, " signchar 0x%x", pi->signchar);
+ if (pi->prec != -1) fprintf(stderr, " prec %d", pi->prec);
+ if (pi->is_char) fprintf(stderr, " char");
+ if (pi->is_short) fprintf(stderr, " short");
+ if (pi->is_long) fprintf(stderr, " long");
+ if (pi->is_long_double) fprintf(stderr, " long_double");
+ fprintf(stderr, "\n");
+ fprintf(stderr, "\t\"%.*s\"\n", pi->end - pi->begin, pi->begin);
+#endif
+ if (pi->get_width) {
+ pi->width = pc->args[pi->get_width].intarg;
+ /*-
+ * ``A negative field width argument is taken as a
+ * - flag followed by a positive field width.''
+ * -- ANSI X3J11
+ * They don't exclude field widths read from args.
+ */
+ if (pi->width < 0) {
+ pi->left = 1;
+ pi->width = -pi->width;
+ }
+ }
+ if (pi->get_prec)
+ pi->prec = pc->args[pi->get_prec].intarg;
+ ret += __printf_puts(&io, pi->begin, pi->end - pi->begin);
+ if (pi->spec) {
+ if (!printf_tbl_in_range(pi->spec)) goto unused;
+ switch(pc->domain->type[printf_tbl_index(pi->spec)]) {
+ case PRINTF_DOMAIN_UNUSED:
+ unused:
+ {
+ char unknown = pi->spec;
+ ret += __printf_out(&io, pi, &unknown, 1);
+ break;
+ }
+ case PRINTF_DOMAIN_GLIBC_API:
+ __printf_flush(&io);
+ pi->sofar = ret;
+ ret += ((printf_function *)pc->domain->tbl[printf_tbl_index(pi->spec)].render)(
+ fp, pi, (const void *)pi->arg);
+ break;
+ case PRINTF_DOMAIN_FBSD_API:
+ pi->sofar = ret;
+ n = ((printf_render *)pc->domain->tbl[printf_tbl_index(pi->spec)].render)(
+ &io, pi, (const void *)pi->arg);
+ if (n < 0)
+ io.fp->_flags |= __SERR;
+ else
+ ret += n;
+ break;
+ }
+ }
+ }
+ __printf_flush(&io);
+ return (ret);
+}
+
+__private_extern__ int
+__v2printf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt, va_list ap)
+{
+ struct _printf_compiled spc;
+ int ret, saverrno;
+
+ /*
+ * All the printf family (including extensible printf variants) funnel
+ * down to this point. So we can do common work here, and then fork
+ * out to the appropriate handler.
+ */
+ /* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
+ if (prepwrite(fp) != 0) {
+ errno = EBADF;
+ return (EOF);
+ }
+ ORIENT(fp, -1);
+
+ if (pc == XPRINTF_PLAIN) {
+ NORMALIZE_LOCALE(loc);
+#ifdef XPRINTF_DEBUG
+ if (!__use_xprintf)
+#endif
+ return __vfprintf(fp, loc, fmt, ap);
+#ifdef XPRINTF_DEBUG
+ xprintf_domain_init();
+ domain = xprintf_domain_global;
+#endif
+ } else if (pc) {
+ pthread_mutex_lock(&pc->mutex);
+ pthread_rwlock_rdlock(&pc->domain->rwlock);
+ ret = __printf_exec(pc, fp, ap);
+ saverrno = errno;
+ pthread_rwlock_unlock(&pc->domain->rwlock);
+ pthread_mutex_unlock(&pc->mutex);
+ errno = saverrno;
+ return ret;
+ }
+ if (!domain) {
+ errno = EINVAL;
+ return EOF;
+ }
+ xprintf_domain_init();
+ bzero(&spc, sizeof(spc));
+ spc.fmt = fmt;
+ DEFAULT_CURRENT_LOCALE(loc);
+ XL_RETAIN(loc);
+ spc.loc = loc;
+ /*
+ * We don't need to lock the printf_comp_t mutex, since the
+ * printf_comp_t was just created on the stack, and is private.
+ */
+ pthread_rwlock_rdlock(&domain->rwlock);
+ if (__printf_comp(&spc, domain) < 0) {
+ saverrno = errno;
+ pthread_rwlock_unlock(&domain->rwlock);
+ XL_RELEASE(loc);
+ errno = saverrno;
+ return EOF;
+ }
+ ret = __printf_exec(&spc, fp, ap);
+ saverrno = errno;
+ pthread_rwlock_unlock(&domain->rwlock);
+ XL_RELEASE(loc);
+
+#ifdef XPRINTF_PERF
+ printf_info_enqueue(spc.pa);
+ arg_type_enqueue(spc.aa);
+ union_arg_enqueue(spc.ua);
+#else /* !XPRINTF_PERF */
+ free(spc.pi);
+ free(spc.argt);
+ free(spc.args);
+#endif /* !XPRINTF_PERF */
+ errno = saverrno;
+ return ret;
+}
+
+extern int __fflush(FILE *fp);
+
+/*
+ * Helper function for `fprintf to unbuffered unix file': creates a
+ * temporary buffer. We only work on write-only files; this avoids
+ * worries about ungetc buffers and so forth.
+ */
+static int
+__v3printf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt, va_list ap)
+{
+ int ret;
+ FILE fake;
+ struct __sFILEX extra;
+ unsigned char buf[BUFSIZ];
+
+ fake._extra = &extra;
+ INITEXTRA(&fake);
+
+ /* copy the important variables */
+ fake._flags = fp->_flags & ~__SNBF;
+ fake._file = fp->_file;
+ fake._cookie = fp->_cookie;
+ fake._write = fp->_write;
+ fake._orientation = fp->_orientation;
+ fake._mbstate = fp->_mbstate;
+
+ /* set up the buffer */
+ fake._bf._base = fake._p = buf;
+ fake._bf._size = fake._w = sizeof(buf);
+ fake._lbfsize = 0; /* not actually used, but Just In Case */
+
+ /* do the work, then copy any error status */
+ ret = __v2printf(pc, domain, &fake, loc, fmt, ap);
+ if (ret >= 0 && __fflush(&fake))
+ ret = EOF;
+ if (fake._flags & __SERR)
+ fp->_flags |= __SERR;
+ return (ret);
+}
+
+__private_extern__ int
+__xvprintf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt0, va_list ap)
+{
+ int ret;
+
+ /* optimise fprintf(stderr) (and other unbuffered Unix files) */
+ if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
+ fp->_file >= 0)
+ ret = __v3printf(pc, domain, fp, loc, fmt0, ap);
+ else
+ ret = __v2printf(pc, domain, fp, loc, fmt0, ap);
+ return ret;
+}
+
+/* extending ---------------------------------------------------------*/
+
+// No global domain support
+#if 0
+int
+register_printf_function(int spec, printf_function *render, printf_arginfo_function *arginfo)
+{
+ return register_printf_domain_function(NULL, spec, render, arginfo);
+}
+
+__private_extern__ int
+register_printf_render(int spec, printf_render *render, printf_arginfo_function *arginfo)
+{
+ return register_printf_domain_render(NULL, spec, render, arginfo);
+}
+
+int
+register_printf_render_std(const char *specs)
+{
+ return register_printf_domain_render_std(NULL, specs);
+}
+#endif
+
+#ifdef VECTORS
+/* vector support ----------------------------------------------------*/
+
+#define PRINTVECTOR(_io, _pi, _arg, _cnt, _type, _elem, _render, _ret) { \
+ int i; \
+ _type a, *ap; \
+ a = (_type)(_arg)->_elem[0]; \
+ ap = &a; \
+ (_ret) += _render((_io), (_pi), (const void *)&ap); \
+ for(i = 1; i < (_cnt); i++) { \
+ (_ret) += __printf_puts((_io), (_pi)->begin, (_pi)->end - (_pi)->begin); \
+ a = (_type)(_arg)->_elem[i]; \
+ (_ret) += _render((_io), (_pi), (const void *)&ap); \
+ } \
+}
+
+#define PRINTVECTOR_P(_io, _pi, _arg, _cnt, _elem, _render, _ret) { \
+ int i; \
+ void * a, *ap; \
+ a = (void *)(uintptr_t)(_arg)->_elem[0]; \
+ ap = &a; \
+ (_ret) += _render((_io), (_pi), (const void *)&ap); \
+ for(i = 1; i < (_cnt); i++) { \
+ (_ret) += __printf_puts((_io), (_pi)->begin, (_pi)->end - (_pi)->begin); \
+ a = (void *)(uintptr_t)(_arg)->_elem[i]; \
+ (_ret) += _render((_io), (_pi), (const void *)&ap); \
+ } \
+}
+
+__private_extern__ int
+__xprintf_vector(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
+{
+ char vsep; /* Vector separator character. */
+ const union arg *argp;
+ int ret = 0;
+ struct printf_info info = *pi;
+
+ argp = arg[0];
+ vsep = pi->vsep;
+ if (vsep == 'X') {
+ if (pi->spec == 'c')
+ vsep = '\0';
+ else
+ vsep = ' ';
+ }
+ info.begin = info.end = &vsep;
+ if (vsep) info.end++;
+ info.is_vec = 0;
+
+ if (pi->is_short) {
+ if (pi->spec == 'p') {
+ PRINTVECTOR_P(io, &info, argp, 8, vushortarg, __printf_render_ptr, ret);
+ } else {
+ PRINTVECTOR(io, &info, argp, 8, unsigned int, vushortarg, __printf_render_int, ret);
+ }
+ } else if (pi->is_long) {
+ info.is_long = 0;
+ if (pi->spec == 'p') {
+ PRINTVECTOR_P(io, &info, argp, 4, vuintarg, __printf_render_ptr, ret);
+ } else {
+ PRINTVECTOR(io, &info, argp, 4, unsigned int, vuintarg, __printf_render_int, ret);
+ }
+#ifdef V64TYPE
+ } else if (pi->is_long_double) {
+ switch (pi->spec) {
+ case 'a':
+ case 'A':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'g':
+ case 'G':
+ info.is_long_double = 0;
+ PRINTVECTOR(io, &info, argp, 2, double, vdoublearg, __printf_render_float, ret);
+ break;
+ case 'p':
+ info.is_long_double = 0;
+ PRINTVECTOR_P(io, &info, argp, 2, vulonglongarg, __printf_render_ptr, ret);
+ break;
+ case 'd':
+ case 'i':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ PRINTVECTOR(io, &info, argp, 2, unsigned long long, vulonglongarg, __printf_render_int, ret);
+ break;
+ default:
+ /*
+ * The default case should never
+ * happen.
+ */
+ case 'c':
+ info.is_long_double = 0;
+ PRINTVECTOR(io, &info, argp, 16, unsigned int, vuchararg, __printf_render_chr, ret);
+ }
+#endif /* V64TYPE */
+ } else {
+ switch (pi->spec) {
+ case 'a':
+ case 'A':
+ case 'e':
+ case 'E':
+ case 'f':
+ case 'g':
+ case 'G':
+ PRINTVECTOR(io, &info, argp, 4, double, vfloatarg, __printf_render_float, ret);
+ break;
+ default:
+ /*
+ * The default case should never
+ * happen.
+ */
+ case 'p':
+ PRINTVECTOR_P(io, &info, argp, 16, vuchararg, __printf_render_ptr, ret);
+ break;
+ case 'd':
+ case 'i':
+ case 'u':
+ case 'o':
+ case 'x':
+ case 'X':
+ info.is_char = 1;
+ PRINTVECTOR(io, &info, argp, 16, unsigned int, vuchararg, __printf_render_int, ret);
+ break;
+ case 'c':
+ PRINTVECTOR(io, &info, argp, 16, unsigned int, vuchararg, __printf_render_chr, ret);
+ }
+ }
+ return ret;
+}
+#endif /* VECTORS */
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdio/xprintf_errno.c,v 1.1 2006/01/25 12:45:24 phk Exp $
+ */
+
+#include <namespace.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <vis.h>
+#include <assert.h>
+#include <sys/time.h>
+#include "printf.h"
+#include "xprintf_private.h"
+
+__private_extern__ int
+__printf_arginfo_errno(const struct printf_info *pi __unused, size_t n, int *argt)
+{
+
+ assert(n >= 1);
+ argt[0] = PA_INT;
+ return (1);
+}
+
+__private_extern__ int
+__printf_render_errno(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg)
+{
+ int ret, error;
+ char buf[64];
+ const char *p;
+
+ ret = 0;
+ error = *((const int *)arg[0]);
+ if (error >= 0 && error < sys_nerr) {
+ p = strerror(error);
+ return (__printf_out(io, pi, p, strlen(p)));
+ }
+ sprintf(buf, "errno=%d/0x%x", error, error);
+ ret += __printf_out(io, pi, buf, strlen(buf));
+ __printf_flush(io);
+ return(ret);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdio/xprintf_float.c,v 1.1 2005/12/16 18:56:38 phk Exp $
+ */
+
+#include <namespace.h>
+#include "xlocale_private.h"
+#include <stdio.h>
+#include <wchar.h>
+#include <assert.h>
+#include <locale.h>
+#include <limits.h>
+
+#define dtoa __dtoa
+#define freedtoa __freedtoa
+
+#include <float.h>
+#include <math.h>
+#include "gdtoa.h"
+#include "floatio.h"
+#include "printf.h"
+#include "xprintf_private.h"
+#include <un-namespace.h>
+
+/*
+ * The size of the buffer we use as scratch space for integer
+ * conversions, among other things. Technically, we would need the
+ * most space for base 10 conversions with thousands' grouping
+ * characters between each pair of digits. 100 bytes is a
+ * conservative overestimate even for a 128-bit uintmax_t.
+ */
+#define BUF 100
+
+#define DEFPREC 6 /* Default FP precision */
+
+
+/* various globals ---------------------------------------------------*/
+
+
+/* padding function---------------------------------------------------*/
+
+#define PRINTANDPAD(p, ep, len, with) do { \
+ n2 = (ep) - (p); \
+ if (n2 > (len)) \
+ n2 = (len); \
+ if (n2 > 0) \
+ ret += __printf_puts(io, (p), n2); \
+ ret += __printf_pad(io, (len) - (n2 > 0 ? n2 : 0), (with)); \
+} while(0)
+
+/* misc --------------------------------------------------------------*/
+
+extern const char *__fix_nogrouping(const char *str);
+
+#define to_char(n) ((n) + '0')
+
+static int
+exponent(char *p0, int expo, int fmtch)
+{
+ char *p, *t;
+ char expbuf[MAXEXPDIG];
+
+ p = p0;
+ *p++ = fmtch;
+ if (expo < 0) {
+ expo = -expo;
+ *p++ = '-';
+ }
+ else
+ *p++ = '+';
+ t = expbuf + MAXEXPDIG;
+ if (expo > 9) {
+ do {
+ *--t = to_char(expo % 10);
+ } while ((expo /= 10) > 9);
+ *--t = to_char(expo);
+ for (; t < expbuf + MAXEXPDIG; *p++ = *t++)
+ ;
+ }
+ else {
+ /*
+ * Exponents for decimal floating point conversions
+ * (%[eEgG]) must be at least two characters long,
+ * whereas exponents for hexadecimal conversions can
+ * be only one character long.
+ */
+ if (fmtch == 'e' || fmtch == 'E')
+ *p++ = '0';
+ *p++ = to_char(expo);
+ }
+ return (p - p0);
+}
+
+/* 'f' ---------------------------------------------------------------*/
+
+__private_extern__ int
+__printf_arginfo_float(const struct printf_info *pi, size_t n, int *argt)
+{
+ assert (n > 0);
+#ifdef VECTORS
+ if (pi->is_vec)
+ argt[0] = PA_VECTOR;
+ else {
+#endif /* VECTORS */
+ argt[0] = PA_DOUBLE;
+ if (pi->is_long_double)
+ argt[0] |= PA_FLAG_LONG_DOUBLE;
+#ifdef VECTORS
+ }
+#endif /* VECTORS */
+ return (1);
+}
+
+/*
+ * We can decompose the printed representation of floating
+ * point numbers into several parts, some of which may be empty:
+ *
+ * [+|-| ] [0x|0X] MMM . NNN [e|E|p|P] [+|-] ZZ
+ * A B ---C--- D E F
+ *
+ * A: 'sign' holds this value if present; '\0' otherwise
+ * B: ox[1] holds the 'x' or 'X'; '\0' if not hexadecimal
+ * C: cp points to the string MMMNNN. Leading and trailing
+ * zeros are not in the string and must be added.
+ * D: expchar holds this character; '\0' if no exponent, e.g. %f
+ * F: at least two digits for decimal, at least one digit for hex
+ */
+
+__private_extern__ int
+__printf_render_float(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
+{
+ int prec; /* precision from format; <0 for N/A */
+ char *dtoaresult; /* buffer allocated by dtoa */
+ char expchar; /* exponent character: [eEpP\0] */
+ char *cp;
+ int expt; /* integer value of exponent */
+ int signflag; /* true if float is negative */
+ char *dtoaend; /* pointer to end of converted digits */
+ char sign; /* sign prefix (' ', '+', '-', or \0) */
+ int size; /* size of converted field or string */
+ int ndig; /* actual number of digits returned by dtoa */
+ int expsize; /* character count for expstr */
+ char expstr[MAXEXPDIG+2]; /* buffer for exponent string: e+ZZZ */
+ int nseps; /* number of group separators with ' */
+ int nrepeats; /* number of repeats of the last group */
+ const char *grouping; /* locale specific numeric grouping rules */
+ int lead; /* sig figs before decimal or group sep */
+ long double ld;
+ double d;
+ int realsz; /* field size expanded by dprec, sign, etc */
+ int dprec; /* a copy of prec if [diouxX], 0 otherwise */
+ char ox[2]; /* space for 0x; ox[1] is either x, X, or \0 */
+ int prsize; /* max size of printed field */
+ int ret; /* return value accumulator */
+ const char *decimal_point; /* locale specific decimal point */
+ int decimal_point_len; /* length of locale specific decimal point */
+ int n2; /* XXX: for PRINTANDPAD */
+ const char *thousands_sep; /* locale specific thousands separator */
+ int thousands_sep_len; /* length of locale specific thousands separator */
+ char buf[BUF]; /* buffer with space for digits of uintmax_t */
+ const char *xdigs;
+ int flag;
+
+#ifdef VECTORS
+ if (pi->is_vec) return __xprintf_vector(io, pi, arg);
+#endif /* VECTORS */
+
+ prec = pi->prec;
+ ox[1] = '\0';
+ sign = pi->signchar;
+ flag = 0;
+ ret = 0;
+
+ thousands_sep = localeconv_l(pi->loc)->thousands_sep;
+ thousands_sep_len = strlen(thousands_sep);
+ grouping = NULL;
+ if (pi->group)
+ grouping = __fix_nogrouping(localeconv_l(pi->loc)->grouping);
+ decimal_point = localeconv_l(pi->loc)->decimal_point;
+ decimal_point_len = strlen(decimal_point);
+ dprec = -1;
+
+ switch(pi->spec) {
+ case 'a':
+ case 'A':
+ if (pi->spec == 'a') {
+ ox[1] = 'x';
+ xdigs = __lowercase_hex;
+ expchar = 'p';
+ } else {
+ ox[1] = 'X';
+ xdigs = __uppercase_hex;
+ expchar = 'P';
+ }
+ if (prec >= 0)
+ prec++;
+ if (pi->is_long_double) {
+ ld = *((long double *)arg[0]);
+ dtoaresult = cp =
+ __hldtoa(ld, xdigs, prec,
+ &expt, &signflag, &dtoaend);
+ } else {
+ d = *((double *)arg[0]);
+ dtoaresult = cp =
+ __hdtoa(d, xdigs, prec,
+ &expt, &signflag, &dtoaend);
+ }
+ if (prec < 0)
+ prec = dtoaend - cp;
+ if (expt == INT_MAX)
+ ox[1] = '\0';
+ goto fp_common;
+ case 'e':
+ case 'E':
+ expchar = pi->spec;
+ if (prec < 0) /* account for digit before decpt */
+ prec = DEFPREC + 1;
+ else
+ prec++;
+ break;
+ case 'f':
+ case 'F':
+ expchar = '\0';
+ break;
+ case 'g':
+ case 'G':
+ expchar = pi->spec - ('g' - 'e');
+ if (prec == 0)
+ prec = 1;
+ break;
+ default:
+ assert(pi->spec == 'f');
+ }
+
+ if (prec < 0)
+ prec = DEFPREC;
+ if (pi->is_long_double) {
+ ld = *((long double *)arg[0]);
+ dtoaresult = cp =
+ __ldtoa(&ld, expchar ? 2 : 3, prec,
+ &expt, &signflag, &dtoaend);
+ } else {
+ d = *((double *)arg[0]);
+ dtoaresult = cp =
+ dtoa(d, expchar ? 2 : 3, prec,
+ &expt, &signflag, &dtoaend);
+ if (expt == 9999)
+ expt = INT_MAX;
+ }
+fp_common:
+ if (signflag)
+ sign = '-';
+ if (expt == INT_MAX) { /* inf or nan */
+ if (*cp == 'N') {
+ cp = (pi->spec >= 'a') ? "nan" : "NAN";
+ sign = '\0';
+ } else
+ cp = (pi->spec >= 'a') ? "inf" : "INF";
+ size = 3;
+ flag = 1;
+ goto here;
+ }
+ ndig = dtoaend - cp;
+ if (pi->spec == 'g' || pi->spec == 'G') {
+ if (expt > -4 && expt <= prec) {
+ /* Make %[gG] smell like %[fF] */
+ expchar = '\0';
+ if (pi->alt)
+ prec -= expt;
+ else
+ prec = ndig - expt;
+ if (prec < 0)
+ prec = 0;
+ } else {
+ /*
+ * Make %[gG] smell like %[eE], but
+ * trim trailing zeroes if no # flag.
+ */
+ if (!pi->alt)
+ prec = ndig;
+ }
+ }
+ if (expchar) {
+ expsize = exponent(expstr, expt - 1, expchar);
+ size = expsize + prec;
+ if (prec > 1 || pi->alt)
+ ++size;
+ } else {
+ /* space for digits before decimal point */
+ if (expt > 0)
+ size = expt;
+ else /* "0" */
+ size = 1;
+ /* space for decimal pt and following digits */
+ if (prec || pi->alt)
+ size += prec + 1;
+ if (grouping && expt > 0) {
+ /* space for thousands' grouping */
+ nseps = nrepeats = 0;
+ lead = expt;
+ while (*grouping != CHAR_MAX) {
+ if (lead <= *grouping)
+ break;
+ lead -= *grouping;
+ if (*(grouping+1)) {
+ nseps++;
+ grouping++;
+ } else
+ nrepeats++;
+ }
+ size += nseps + nrepeats;
+ } else
+ lead = expt;
+ }
+
+here:
+ /*
+ * All reasonable formats wind up here. At this point, `cp'
+ * points to a string which (if not flags&LADJUST) should be
+ * padded out to `width' places. If flags&ZEROPAD, it should
+ * first be prefixed by any sign or other prefix; otherwise,
+ * it should be blank padded before the prefix is emitted.
+ * After any left-hand padding and prefixing, emit zeroes
+ * required by a decimal [diouxX] precision, then print the
+ * string proper, then emit zeroes required by any leftover
+ * floating precision; finally, if LADJUST, pad with blanks.
+ *
+ * Compute actual size, so we know how much to pad.
+ * size excludes decimal prec; realsz includes it.
+ */
+ realsz = dprec > size ? dprec : size;
+ if (sign)
+ realsz++;
+ if (ox[1])
+ realsz += 2;
+
+ prsize = pi->width > realsz ? pi->width : realsz;
+
+ /* right-adjusting blank padding */
+ if (pi->pad != '0' && pi->left == 0)
+ ret += __printf_pad(io, pi->width - realsz, 0);
+
+ /* prefix */
+ if (sign)
+ ret += __printf_puts(io, &sign, 1);
+
+ if (ox[1]) { /* ox[1] is either x, X, or \0 */
+ ox[0] = '0';
+ ret += __printf_puts(io, ox, 2);
+ }
+
+ /* right-adjusting zero padding */
+ if (pi->pad == '0' && pi->left == 0)
+ ret += __printf_pad(io, pi->width - realsz, 1);
+
+ /* leading zeroes from decimal precision */
+ ret += __printf_pad(io, dprec - size, 1);
+
+ if (flag)
+ ret += __printf_puts(io, cp, size);
+ else {
+ /* glue together f_p fragments */
+ if (!expchar) { /* %[fF] or sufficiently short %[gG] */
+ if (expt <= 0) {
+ ret += __printf_puts(io, "0", 1);
+ if (prec || pi->alt)
+ ret += __printf_puts(io, decimal_point, decimal_point_len);
+ ret += __printf_pad(io, -expt, 1);
+ /* already handled initial 0's */
+ prec += expt;
+ } else {
+ PRINTANDPAD(cp, dtoaend, lead, 1);
+ cp += lead;
+ if (grouping) {
+ while (nseps>0 || nrepeats>0) {
+ if (nrepeats > 0)
+ nrepeats--;
+ else {
+ grouping--;
+ nseps--;
+ }
+ ret += __printf_puts(io, thousands_sep, thousands_sep_len);
+ PRINTANDPAD(cp,dtoaend,
+ *grouping, 1);
+ cp += *grouping;
+ }
+ if (cp > dtoaend)
+ cp = dtoaend;
+ }
+ if (prec || pi->alt)
+ ret += __printf_puts(io, decimal_point, decimal_point_len);
+ }
+ PRINTANDPAD(cp, dtoaend, prec, 1);
+ } else { /* %[eE] or sufficiently long %[gG] */
+ if (prec > 1 || pi->alt) {
+ buf[0] = *cp++;
+ memcpy(buf + 1, decimal_point, decimal_point_len);
+ ret += __printf_puts(io, buf, decimal_point_len + 1);
+ ret += __printf_puts(io, cp, ndig-1);
+ ret += __printf_pad(io, prec - ndig, 1);
+ } else /* XeYYY */
+ ret += __printf_puts(io, cp, 1);
+ ret += __printf_puts(io, expstr, expsize);
+ }
+ }
+ /* left-adjusting padding (always blank) */
+ if (pi->left)
+ ret += __printf_pad(io, pi->width - realsz, 0);
+
+ __printf_flush(io);
+ if (dtoaresult != NULL)
+ freedtoa(dtoaresult);
+
+ return (ret);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdio/xprintf_hexdump.c,v 1.1 2005/12/16 18:56:38 phk Exp $
+ */
+
+#include <namespace.h>
+#include <stdio.h>
+#include <wchar.h>
+#include <stdint.h>
+#include <assert.h>
+#include <sys/time.h>
+#include "printf.h"
+#include "xprintf_private.h"
+
+__private_extern__ int
+__printf_arginfo_hexdump(const struct printf_info *pi, size_t n, int *argt)
+{
+
+ assert(n >= 2);
+ argt[0] = PA_POINTER;
+ argt[1] = PA_INT;
+ return (2);
+}
+
+__private_extern__ int
+__printf_render_hexdump(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
+{
+ unsigned char *p;
+ unsigned u, l, j, a;
+ char buf[100], *q;
+ int ret;
+
+ if (pi->width > 0 && pi->width < 16)
+ l = pi->width;
+ else
+ l = 16;
+ p = *((unsigned char **)arg[0]);
+ u = *((unsigned *)arg[1]);
+
+ ret = 0;
+ a = 0;
+ while (u > 0) {
+ q = buf;
+ if (pi->showsign)
+ q += sprintf(q, " %04x", a);
+ for (j = 0; j < l && j < u; j++)
+ q += sprintf(q, " %02x", p[j]);
+ if (pi->alt) {
+ for (; j < l; j++)
+ q += sprintf(q, " ");
+ q += sprintf(q, " |");
+ for (j = 0; j < l && j < u; j++) {
+ if (p[j] < ' ' || p[j] > '~')
+ *q++ = '.';
+ else
+ *q++ = p[j];
+ }
+ for (; j < l; j++)
+ *q++ = ' ';
+ *q++ = '|';
+ }
+ if (l < u)
+ j = l;
+ else
+ j = u;
+ p += j;
+ u -= j;
+ a += j;
+ if (u > 0)
+ *q++ = '\n';
+ ret += __printf_puts(io, buf + 1, q - (buf + 1));
+ __printf_flush(io);
+ }
+ return (ret);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdio/xprintf_int.c,v 1.2 2005/12/22 14:23:54 cognet Exp $
+ */
+
+#include <namespace.h>
+#include <err.h>
+#include <sys/types.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <locale.h>
+#include <stdint.h>
+#include <assert.h>
+#include <namespace.h>
+#include <string.h>
+#include <wchar.h>
+#include <un-namespace.h>
+
+#include "printf.h"
+#include "xprintf_private.h"
+
+/* private stuff -----------------------------------------------------*/
+
+union arg {
+ int intarg;
+ u_int uintarg;
+ long longarg;
+ u_long ulongarg;
+ intmax_t intmaxarg;
+ uintmax_t uintmaxarg;
+};
+
+/*
+ * Macros for converting digits to letters and vice versa
+ */
+#define to_char(n) ((n) + '0')
+
+/* various globals ---------------------------------------------------*/
+
+/*
+ * The size of the buffer we use for integer conversions.
+ * Technically, we would need the most space for base 10
+ * conversions with thousands' grouping characters between
+ * each pair of digits: 39 digits for 128 bit intmax_t plus
+ * 20 grouping characters (which may be multibyte).
+ * Use a bit more for better alignment of stuff.
+ */
+#define BUF 128
+
+/* misc --------------------------------------------------------------*/
+
+extern const char *__fix_nogrouping(const char *str);
+
+/*
+ * Convert an unsigned long to ASCII for printf purposes, returning
+ * a pointer to the first character of the string representation.
+ * Octal numbers can be forced to have a leading zero; hex numbers
+ * use the given digits.
+ */
+static char *
+__ultoa(u_long val, char *endp, int base, const char *xdigs,
+ int needgrp, const char *thousep, int thousep_len, const char *grp)
+{
+ char *cp = endp;
+ long sval;
+ int ndig;
+
+ /*
+ * Handle the three cases separately, in the hope of getting
+ * better/faster code.
+ */
+ switch (base) {
+ case 10:
+ if (val < 10) { /* many numbers are 1 digit */
+ *--cp = to_char(val);
+ return (cp);
+ }
+ ndig = 0;
+ /*
+ * On many machines, unsigned arithmetic is harder than
+ * signed arithmetic, so we do at most one unsigned mod and
+ * divide; this is sufficient to reduce the range of
+ * the incoming value to where signed arithmetic works.
+ */
+ if (val > LONG_MAX) {
+ *--cp = to_char(val % 10);
+ ndig++;
+ sval = val / 10;
+ } else
+ sval = val;
+ do {
+ *--cp = to_char(sval % 10);
+ ndig++;
+ /*
+ * If (*grp == CHAR_MAX) then no more grouping
+ * should be performed.
+ */
+ if (needgrp && ndig == *grp && *grp != CHAR_MAX
+ && sval > 9) {
+ cp -= thousep_len;
+ memcpy(cp, thousep, thousep_len);
+ ndig = 0;
+ /*
+ * If (*(grp+1) == '\0') then we have to
+ * use *grp character (last grouping rule)
+ * for all next cases
+ */
+ if (*(grp+1) != '\0')
+ grp++;
+ }
+ sval /= 10;
+ } while (sval != 0);
+ break;
+
+ case 8:
+ do {
+ *--cp = to_char(val & 7);
+ val >>= 3;
+ } while (val);
+ break;
+
+ case 16:
+ do {
+ *--cp = xdigs[val & 15];
+ val >>= 4;
+ } while (val);
+ break;
+
+ default: /* oops */
+ assert(base == 16);
+ }
+ return (cp);
+}
+
+
+/* Identical to __ultoa, but for intmax_t. */
+static char *
+__ujtoa(uintmax_t val, char *endp, int base, const char *xdigs,
+ int needgrp, const char *thousep, int thousep_len, const char *grp)
+{
+ char *cp = endp;
+ intmax_t sval;
+ int ndig;
+
+ switch (base) {
+ case 10:
+ if (val < 10) {
+ *--cp = to_char(val % 10);
+ return (cp);
+ }
+ ndig = 0;
+ if (val > INTMAX_MAX) {
+ *--cp = to_char(val % 10);
+ ndig++;
+ sval = val / 10;
+ } else
+ sval = val;
+ do {
+ *--cp = to_char(sval % 10);
+ ndig++;
+ /*
+ * If (*grp == CHAR_MAX) then no more grouping
+ * should be performed.
+ */
+ if (needgrp && *grp != CHAR_MAX && ndig == *grp
+ && sval > 9) {
+ cp -= thousep_len;
+ memcpy(cp, thousep, thousep_len);
+ ndig = 0;
+ /*
+ * If (*(grp+1) == '\0') then we have to
+ * use *grp character (last grouping rule)
+ * for all next cases
+ */
+ if (*(grp+1) != '\0')
+ grp++;
+ }
+ sval /= 10;
+ } while (sval != 0);
+ break;
+
+ case 8:
+ do {
+ *--cp = to_char(val & 7);
+ val >>= 3;
+ } while (val);
+ break;
+
+ case 16:
+ do {
+ *--cp = xdigs[val & 15];
+ val >>= 4;
+ } while (val);
+ break;
+
+ default:
+ abort();
+ }
+ return (cp);
+}
+
+
+/* 'd' ---------------------------------------------------------------*/
+
+__private_extern__ int
+__printf_arginfo_int(const struct printf_info *pi, size_t n, int *argt)
+{
+ assert (n > 0);
+ argt[0] = PA_INT;
+#ifdef VECTORS
+ if (pi->is_vec)
+ argt[0] = PA_VECTOR;
+ else
+#endif /* VECTORS */
+ if (pi->is_ptrdiff)
+ argt[0] |= PA_FLAG_PTRDIFF;
+ else if (pi->is_size)
+ argt[0] |= PA_FLAG_SIZE;
+ else if (pi->is_long)
+ argt[0] |= PA_FLAG_LONG;
+ else if (pi->is_intmax)
+ argt[0] |= PA_FLAG_INTMAX;
+ else if (pi->is_quad)
+ argt[0] |= PA_FLAG_QUAD;
+ else if (pi->is_long_double)
+ argt[0] |= PA_FLAG_LONG_LONG;
+ else if (pi->is_short)
+ argt[0] |= PA_FLAG_SHORT;
+ else if (pi->is_char)
+ argt[0] = PA_CHAR;
+ return (1);
+}
+
+__private_extern__ int
+__printf_render_int(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
+{
+ const union arg *argp;
+ char buf[BUF];
+ char *p, *pe;
+ char ns, l;
+ int rdx, sign, zext, ngrp;
+ const char *nalt, *digit;
+ const char *thousands_sep; /* locale specific thousands separator */
+ int thousands_sep_len; /* locale specific thousands separator length */
+ const char *grouping; /* locale specific numeric grouping rules */
+ uintmax_t uu;
+ int ret;
+
+#ifdef VECTORS
+ if (pi->is_vec) return __xprintf_vector(io, pi, arg);
+#endif /* VECTORS */
+
+ ret = 0;
+ nalt = NULL;
+ digit = __lowercase_hex;
+ ns = '\0';
+ pe = buf + sizeof buf - 1;
+
+ if (pi->group) {
+ thousands_sep = localeconv_l(pi->loc)->thousands_sep;
+ thousands_sep_len = strlen(thousands_sep);
+ grouping = __fix_nogrouping(localeconv_l(pi->loc)->grouping);
+ ngrp = 1;
+ } else {
+ thousands_sep = NULL;
+ thousands_sep_len = 0;
+ grouping = NULL;
+ ngrp = 0;
+ }
+
+ switch(pi->spec) {
+ case 'd':
+ case 'i':
+ rdx = 10;
+ sign = 1;
+ break;
+ case 'X':
+ digit = __uppercase_hex;
+ /*FALLTHOUGH*/
+ case 'x':
+ rdx = 16;
+ sign = 0;
+ break;
+ case 'u':
+ case 'U':
+ rdx = 10;
+ sign = 0;
+ break;
+ case 'o':
+ case 'O':
+ rdx = 8;
+ sign = 0;
+ break;
+ default:
+ fprintf(stderr, "pi->spec = '%c'\n", pi->spec);
+ assert(1 == 0);
+ }
+ argp = arg[0];
+
+ if (sign)
+ ns = pi->signchar;
+
+ if (pi->is_long_double || pi->is_quad || pi->is_intmax ||
+ pi->is_size || pi->is_ptrdiff) {
+ if (sign && argp->intmaxarg < 0) {
+ uu = -argp->intmaxarg;
+ ns = '-';
+ } else
+ uu = argp->uintmaxarg;
+ } else if (pi->is_long) {
+ if (sign && argp->longarg < 0) {
+ uu = (u_long)-argp->longarg;
+ ns = '-';
+ } else
+ uu = argp->ulongarg;
+ } else if (pi->is_short) {
+ if (sign && (short)argp->intarg < 0) {
+ uu = -(short)argp->intarg;
+ ns = '-';
+ } else
+ uu = (unsigned short)argp->uintarg;
+ } else if (pi->is_char) {
+ if (sign && (signed char)argp->intarg < 0) {
+ uu = -(signed char)argp->intarg;
+ ns = '-';
+ } else
+ uu = (unsigned char)argp->uintarg;
+ } else {
+ if (sign && argp->intarg < 0) {
+ uu = (unsigned)-argp->intarg;
+ ns = '-';
+ } else
+ uu = argp->uintarg;
+ }
+ if (uu <= ULONG_MAX)
+ p = __ultoa(uu, pe, rdx, digit, ngrp, thousands_sep, thousands_sep_len, grouping);
+ else
+ p = __ujtoa(uu, pe, rdx, digit, ngrp, thousands_sep, thousands_sep_len, grouping);
+
+ l = 0;
+ if (uu == 0) {
+ /*-
+ * ``The result of converting a zero value with an
+ * explicit precision of zero is no characters.''
+ * -- ANSI X3J11
+ *
+ * ``The C Standard is clear enough as is. The call
+ * printf("%#.0o", 0) should print 0.''
+ * -- Defect Report #151
+ */
+ ;
+ if (pi->prec == 0 && !(pi->alt && rdx == 8))
+ p = pe;
+ } else if (pi->alt) {
+ if (rdx == 8)
+ *--p = '0';
+ if (rdx == 16) {
+ if (pi->spec == 'x')
+ nalt = "0x";
+ else
+ nalt = "0X";
+ l += 2;
+ }
+ }
+ l += pe - p;
+ if (ns)
+ l++;
+
+ /*-
+ * ``... diouXx conversions ... if a precision is
+ * specified, the 0 flag will be ignored.''
+ * -- ANSI X3J11
+ */
+ if (pi->prec > (pe - p))
+ zext = pi->prec - (pe - p);
+ else if (pi->prec != -1)
+ zext = 0;
+ else if (pi->pad == '0' && pi->width > l && !pi->left)
+ zext = pi->width - l;
+ else
+ zext = 0;
+
+ l += zext;
+
+ while (zext > 0 && p > buf) {
+ *--p = '0';
+ zext--;
+ }
+
+ if (l < BUF) {
+ if (ns) {
+ *--p = ns;
+ } else if (nalt != NULL) {
+ *--p = nalt[1];
+ *--p = nalt[0];
+ }
+ if (pi->width > (pe - p) && !pi->left) {
+ l = pi->width - (pe - p);
+ while (l > 0 && p > buf) {
+ *--p = ' ';
+ l--;
+ }
+ if (l)
+ ret += __printf_pad(io, l, 0);
+ }
+ } else {
+ if (!pi->left && pi->width > l)
+ ret += __printf_pad(io, pi->width - l, 0);
+ if (ns != '\0')
+ ret += __printf_puts(io, &ns, 1);
+ else if (nalt != NULL)
+ ret += __printf_puts(io, nalt, 2);
+ if (zext > 0)
+ ret += __printf_pad(io, zext, 1);
+ }
+
+ ret += __printf_puts(io, p, pe - p);
+ if (pi->width > ret && pi->left)
+ ret += __printf_pad(io, pi->width - ret, 0);
+ __printf_flush(io);
+ return (ret);
+}
+
+/* 'p' ---------------------------------------------------------------*/
+
+__private_extern__ int
+__printf_arginfo_ptr(const struct printf_info *pi __unused, size_t n, int *argt)
+{
+
+ assert (n > 0);
+#ifdef VECTORS
+ if (pi->is_vec)
+ argt[0] = PA_VECTOR;
+ else
+#endif /* VECTORS */
+ argt[0] = PA_POINTER;
+ return (1);
+}
+
+__private_extern__ int
+__printf_render_ptr(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
+{
+ struct printf_info p2;
+ uintmax_t u;
+ const void *p;
+
+#ifdef VECTORS
+ if (pi->is_vec) return __xprintf_vector(io, pi, arg);
+#endif /* VECTORS */
+
+ /*-
+ * ``The argument shall be a pointer to void. The
+ * value of the pointer is converted to a sequence
+ * of printable characters, in an implementation-
+ * defined manner.''
+ * -- ANSI X3J11
+ */
+ u = (uintmax_t)(uintptr_t) *((void **)arg[0]);
+ p2 = *pi;
+
+ p2.spec = 'x';
+ p2.alt = 1;
+ p2.is_long_double = 1;
+ p = &u;
+ return (__printf_render_int(io, &p2, &p));
+}
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/include/printf.h,v 1.5 2011/03/06 17:45:37 pjd Exp $
+ */
+
+#ifndef _XPRINTF_PRIVATE_H_
+#define _XPRINTF_PRIVATE_H_
+
+#include <printf.h>
+#include <pthread.h>
+
+#ifndef VECTORS
+#define VECTORS
+typedef __attribute__ ((vector_size(16))) unsigned char VECTORTYPE;
+#ifdef __SSE2__
+#define V64TYPE
+#endif /* __SSE2__ */
+#endif /* !VECTORS */
+
+/* FreeBSD extension */
+struct __printf_io;
+typedef int printf_render(struct __printf_io *, const struct printf_info *, const void *const *);
+
+#if 0
+int register_printf_render(int spec, printf_render *render, printf_arginfo_function *arginfo);
+#endif
+
+/*
+ * Unlike register_printf_domain_function(), register_printf_domain_render()
+ * doesn't have a context pointer, because none of the internal rendering
+ * functions use it.
+ */
+int register_printf_domain_render(printf_domain_t, int, printf_render *, printf_arginfo_function *);
+
+/* xprintf.c */
+extern const char __lowercase_hex[17];
+extern const char __uppercase_hex[17];
+
+void __printf_flush(struct __printf_io *io);
+int __printf_puts(struct __printf_io *io, const void *ptr, int len);
+int __printf_pad(struct __printf_io *io, int n, int zero);
+int __printf_out(struct __printf_io *io, const struct printf_info *pi, const void *ptr, int len);
+
+int __v2printf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt0, va_list ap);
+int __xvprintf(printf_comp_t restrict pc, printf_domain_t restrict domain, FILE * restrict fp, locale_t restrict loc, const char * restrict fmt0, va_list ap);
+extern int __use_xprintf;
+
+printf_arginfo_function __printf_arginfo_pct;
+printf_render __printf_render_pct;
+
+printf_arginfo_function __printf_arginfo_n;
+printf_function __printf_render_n;
+
+#ifdef VECTORS
+printf_render __xprintf_vector;
+#endif /* VECTORS */
+
+#ifdef XPRINTF_PERF
+#define CALLOC(x,y) xprintf_calloc((x),(y))
+#define MALLOC(x) xprintf_malloc((x))
+void *xprintf_calloc(size_t, size_t) __attribute__((__malloc__));
+void *xprintf_malloc(size_t) __attribute__((__malloc__));
+#else /* !XPRINTF_PERF */
+#define CALLOC(x,y) calloc((x),(y))
+#define MALLOC(x) malloc((x))
+#endif /* !XPRINTF_PERF */
+
+/* xprintf_domain.c */
+void __xprintf_domain_init(void);
+extern pthread_once_t __xprintf_domain_once;
+#ifdef XPRINTF_DEBUG
+extern printf_domain_t xprintf_domain_global;
+#endif
+#ifdef XPRINTF_PERF
+struct array; /* forward reference */
+void arrayfree(struct array *);
+#endif
+
+#define xprintf_domain_init() pthread_once(&__xprintf_domain_once, __xprintf_domain_init)
+
+/* xprintf_errno.c */
+printf_arginfo_function __printf_arginfo_errno;
+printf_render __printf_render_errno;
+
+/* xprintf_float.c */
+printf_arginfo_function __printf_arginfo_float;
+printf_render __printf_render_float;
+
+/* xprintf_hexdump.c */
+printf_arginfo_function __printf_arginfo_hexdump;
+printf_render __printf_render_hexdump;
+
+/* xprintf_int.c */
+printf_arginfo_function __printf_arginfo_ptr;
+printf_arginfo_function __printf_arginfo_int;
+printf_render __printf_render_ptr;
+printf_render __printf_render_int;
+
+/* xprintf_quoute.c */
+printf_arginfo_function __printf_arginfo_quote;
+printf_render __printf_render_quote;
+
+/* xprintf_str.c */
+printf_arginfo_function __printf_arginfo_chr;
+printf_render __printf_render_chr;
+printf_arginfo_function __printf_arginfo_str;
+printf_render __printf_render_str;
+
+/* xprintf_time.c */
+printf_arginfo_function __printf_arginfo_time;
+printf_render __printf_render_time;
+
+/* xprintf_vis.c */
+printf_arginfo_function __printf_arginfo_vis;
+printf_render __printf_render_vis;
+
+#ifdef XPRINTF_PERF
+struct array; /* forward reference */
+#endif /* XPRINTF_PERF */
+struct _printf_compiled {
+ pthread_mutex_t mutex;
+#ifdef XPRINTF_PERF
+ struct array *aa;
+ struct array *pa;
+ struct array *ua;
+#endif /* XPRINTF_PERF */
+ const char *fmt;
+ printf_domain_t domain;
+ locale_t loc;
+ struct printf_info *pi;
+ struct printf_info *pil;
+ int *argt;
+ union arg *args;
+ int maxarg;
+};
+
+#define XPRINTF_PLAIN ((printf_comp_t)-1)
+
+int __printf_comp(printf_comp_t restrict, printf_domain_t restrict);
+int __printf_exec(printf_comp_t restrict, FILE * restrict, va_list);
+
+#ifdef XPRINTF_PERF
+void arg_type_enqueue(struct array *);
+void print_info_enqueue(struct array *);
+void union_arg_enqueue(struct array *);
+#endif /* XPRINTF_PERF */
+
+#endif /* !_XPRINTF_PRIVATE_H_ */
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdio/xprintf_quote.c,v 1.2 2006/03/02 08:53:45 phk Exp $
+ */
+
+#include <namespace.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <wchar.h>
+#include <vis.h>
+#include <assert.h>
+#include <sys/time.h>
+#include "printf.h"
+#include "xprintf_private.h"
+
+__private_extern__ int
+__printf_arginfo_quote(const struct printf_info *pi __unused, size_t n, int *argt)
+{
+
+ assert(n >= 1);
+ argt[0] = PA_POINTER;
+ return (1);
+}
+
+__private_extern__ int
+__printf_render_quote(struct __printf_io *io, const struct printf_info *pi __unused, const void *const *arg)
+{
+ const char *str, *p, *t, *o;
+ char r[5];
+ int i, ret;
+
+ str = *((const char *const *)arg[0]);
+ if (str == NULL)
+ return (__printf_out(io, pi, "\"(null)\"", 8));
+ if (*str == '\0')
+ return (__printf_out(io, pi, "\"\"", 2));
+
+ for (i = 0, p = str; *p; p++)
+ if (isspace(*p) || *p == '\\' || *p == '"')
+ i++;
+ if (!i)
+ return (__printf_out(io, pi, str, strlen(str)));
+
+ ret = __printf_out(io, pi, "\"", 1);
+ for (t = p = str; *p; p++) {
+ o = NULL;
+ if (*p == '\\')
+ o = "\\\\";
+ else if (*p == '\n')
+ o = "\\n";
+ else if (*p == '\r')
+ o = "\\r";
+ else if (*p == '\t')
+ o = "\\t";
+ else if (*p == ' ')
+ o = " ";
+ else if (*p == '"')
+ o = "\\\"";
+ else if (isspace(*p)) {
+ sprintf(r, "\\%03o", *p);
+ o = r;
+ } else
+ continue;
+ if (p != t)
+ ret += __printf_out(io, pi, t, p - t);
+ ret += __printf_out(io, pi, o, strlen(o));
+ t = p + 1;
+ }
+ if (p != t)
+ ret += __printf_out(io, pi, t, p - t);
+ ret += __printf_out(io, pi, "\"", 1);
+ __printf_flush(io);
+ return(ret);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdio/xprintf_str.c,v 1.1 2005/12/16 18:56:38 phk Exp $
+ */
+
+#include <namespace.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <stdint.h>
+#include <assert.h>
+#include <wchar.h>
+#include "printf.h"
+#include "xprintf_private.h"
+
+/*
+ * Convert a wide character string argument for the %ls format to a multibyte
+ * string representation. If not -1, prec specifies the maximum number of
+ * bytes to output, and also means that we can't assume that the wide char.
+ * string ends is null-terminated.
+ */
+static char *
+__wcsconv(wchar_t *wcsarg, int prec, locale_t loc)
+{
+ static const mbstate_t initial;
+ mbstate_t mbs;
+ char buf[MB_LEN_MAX];
+ wchar_t *p;
+ char *convbuf;
+ size_t clen, nbytes;
+
+ /* Allocate space for the maximum number of bytes we could output. */
+ if (prec < 0) {
+ p = wcsarg;
+ mbs = initial;
+ nbytes = wcsrtombs_l(NULL, (const wchar_t **)&p, 0, &mbs, loc);
+ if (nbytes == (size_t)-1)
+ return (NULL);
+ } else {
+ /*
+ * Optimisation: if the output precision is small enough,
+ * just allocate enough memory for the maximum instead of
+ * scanning the string.
+ */
+ if (prec < 128)
+ nbytes = prec;
+ else {
+ nbytes = 0;
+ p = wcsarg;
+ mbs = initial;
+ for (;;) {
+ clen = wcrtomb_l(buf, *p++, &mbs, loc);
+ if (clen == 0 || clen == (size_t)-1 ||
+ (int)(nbytes + clen) > prec)
+ break;
+ nbytes += clen;
+ }
+ }
+ }
+ if ((convbuf = MALLOC(nbytes + 1)) == NULL)
+ return (NULL);
+
+ /* Fill the output buffer. */
+ p = wcsarg;
+ mbs = initial;
+ if ((nbytes = wcsrtombs_l(convbuf, (const wchar_t **)&p,
+ nbytes, &mbs, loc)) == (size_t)-1) {
+ free(convbuf);
+ return (NULL);
+ }
+ convbuf[nbytes] = '\0';
+ return (convbuf);
+}
+
+
+/* 's' ---------------------------------------------------------------*/
+
+__private_extern__ int
+__printf_arginfo_str(const struct printf_info *pi, size_t n, int *argt)
+{
+
+ assert (n > 0);
+ if (pi->is_long || pi->spec == 'C')
+ argt[0] = PA_WSTRING;
+ else
+ argt[0] = PA_STRING;
+ return (1);
+}
+
+__private_extern__ int
+__printf_render_str(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
+{
+ const char *p;
+ wchar_t *wcp;
+ char *convbuf;
+ int l;
+
+ if (pi->is_long || pi->spec == 'S') {
+ wcp = *((wint_t **)arg[0]);
+ if (wcp == NULL)
+ return (__printf_out(io, pi, "(null)", 6));
+ convbuf = __wcsconv(wcp, pi->prec, pi->loc);
+ if (convbuf == NULL)
+ return (-1);
+ l = __printf_out(io, pi, convbuf, strlen(convbuf));
+ __printf_flush(io);
+ free(convbuf);
+ return (l);
+ }
+ p = *((char **)arg[0]);
+ if (p == NULL)
+ return (__printf_out(io, pi, "(null)", 6));
+ l = strlen(p);
+ if (pi->prec >= 0 && pi->prec < l)
+ l = pi->prec;
+ return (__printf_out(io, pi, p, l));
+}
+
+/* 'c' ---------------------------------------------------------------*/
+
+__private_extern__ int
+__printf_arginfo_chr(const struct printf_info *pi, size_t n, int *argt)
+{
+
+ assert (n > 0);
+#ifdef VECTORS
+ if (pi->is_vec)
+ argt[0] = PA_VECTOR;
+ else
+#endif /* VECTORS */
+ if (pi->is_long || pi->spec == 'C')
+ argt[0] = PA_WCHAR;
+ else
+ argt[0] = PA_INT;
+ return (1);
+}
+
+__private_extern__ int
+__printf_render_chr(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
+{
+ int i;
+ wint_t ii;
+ unsigned char c;
+ static const mbstate_t initial; /* XXX: this is bogus! */
+ mbstate_t mbs;
+ size_t mbseqlen;
+ char buf[MB_CUR_MAX_L(pi->loc)];
+
+#ifdef VECTORS
+ if (pi->is_vec) return __xprintf_vector(io, pi, arg);
+#endif /* VECTORS */
+
+ if (pi->is_long || pi->spec == 'C') {
+ int ret;
+ ii = *((wint_t *)arg[0]);
+
+ mbs = initial;
+ mbseqlen = wcrtomb_l(buf, (wchar_t)ii, &mbs, pi->loc);
+ if (mbseqlen == (size_t) -1)
+ return (-1);
+ ret = __printf_out(io, pi, buf, mbseqlen);
+ __printf_flush(io);
+ return ret;
+ }
+ i = *((int *)arg[0]);
+ c = i;
+ i = __printf_out(io, pi, &c, 1);
+ __printf_flush(io);
+ return (i);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdio/xprintf_time.c,v 1.6 2011/03/06 19:47:46 pjd Exp $
+ */
+#include <namespace.h>
+#include <stdio.h>
+#include <wchar.h>
+#include <stdint.h>
+#include <assert.h>
+#include <sys/time.h>
+#include "printf.h"
+#include "xprintf_private.h"
+
+__private_extern__ int
+__printf_arginfo_time(const struct printf_info *pi, size_t n, int *argt)
+{
+
+ assert(n >= 1);
+ argt[0] = PA_POINTER;
+ return (1);
+}
+#define MINUTE 60
+#define HOUR (60 * MINUTE)
+#define DAY (24 * HOUR)
+#define YEAR (365 * DAY)
+
+__private_extern__ int
+__printf_render_time(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
+{
+ char buf[100];
+ char *p;
+ struct timeval *tv;
+ struct timespec *ts;
+ time_t *tp;
+ intmax_t t, tx;
+ int i, prec, nsec, ret;
+
+ if (pi->is_long) {
+ tv = *((struct timeval **)arg[0]);
+ t = tv->tv_sec;
+ nsec = tv->tv_usec * 1000;
+ prec = 6;
+ } else if (pi->is_long_double) {
+ ts = *((struct timespec **)arg[0]);
+ t = ts->tv_sec;
+ nsec = ts->tv_nsec;
+ prec = 9;
+ } else {
+ tp = *((time_t **)arg[0]);
+ t = *tp;
+ nsec = 0;
+ prec = 0;
+ }
+ if (pi->is_long || pi->is_long_double) {
+ if (pi->prec >= 0)
+ prec = pi->prec;
+ if (prec == 0)
+ nsec = 0;
+ }
+
+ p = buf;
+ if (pi->alt) {
+ tx = t;
+ if (t >= YEAR) {
+ p += sprintf(p, "%jdy", t / YEAR);
+ t %= YEAR;
+ }
+ if (tx >= DAY && (t != 0 || prec != 0)) {
+ p += sprintf(p, "%jdd", t / DAY);
+ t %= DAY;
+ }
+ if (tx >= HOUR && (t != 0 || prec != 0)) {
+ p += sprintf(p, "%jdh", t / HOUR);
+ t %= HOUR;
+ }
+ if (tx >= MINUTE && (t != 0 || prec != 0)) {
+ p += sprintf(p, "%jdm", t / MINUTE);
+ t %= MINUTE;
+ }
+ if (t != 0 || tx == 0 || prec != 0)
+ p += sprintf(p, "%jds", t);
+ } else {
+ p += sprintf(p, "%jd", (intmax_t)t);
+ }
+ if (prec != 0) {
+ for (i = prec; i < 9; i++)
+ nsec /= 10;
+ p += sprintf(p, ".%.*d", prec, nsec);
+ }
+ ret = __printf_out(io, pi, buf, p - buf);
+ __printf_flush(io);
+ return (ret);
+}
--- /dev/null
+/*-
+ * Copyright (c) 2005 Poul-Henning Kamp
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/lib/libc/stdio/xprintf_vis.c,v 1.2 2006/01/25 12:45:24 phk Exp $
+ */
+
+#include <namespace.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <vis.h>
+#include <assert.h>
+#include <sys/time.h>
+#include "printf.h"
+#include "xprintf_private.h"
+
+__private_extern__ int
+__printf_arginfo_vis(const struct printf_info *pi, size_t n, int *argt)
+{
+
+ assert(n >= 1);
+ argt[0] = PA_POINTER;
+ return (1);
+}
+
+__private_extern__ int
+__printf_render_vis(struct __printf_io *io, const struct printf_info *pi, const void *const *arg)
+{
+ char *p, *buf;
+ unsigned l;
+ int ret;
+
+ ret = 0;
+ p = *((char **)arg[0]);
+ if (p == NULL)
+ return (__printf_out(io, pi, "(null)", 6));
+ if (pi->prec >= 0)
+ l = pi->prec;
+ else
+ l = strlen(p);
+ buf = MALLOC(l * 4 + 1);
+ if (buf == NULL)
+ return (-1);
+ if (pi->showsign)
+ ret = strvisx(buf, p, l, VIS_WHITE | VIS_HTTPSTYLE);
+ else if (pi->pad == '0')
+ ret = strvisx(buf, p, l, VIS_WHITE | VIS_OCTAL);
+ else if (pi->alt)
+ ret = strvisx(buf, p, l, VIS_WHITE);
+ else
+ ret = strvisx(buf, p, l, VIS_WHITE | VIS_CSTYLE | VIS_OCTAL);
+ ret += __printf_out(io, pi, buf, ret);
+ __printf_flush(io);
+ free(buf);
+ return(ret);
+}
--- /dev/null
+.Dd Aug 19, 2012
+.Dt XPRINTF 3
+.Os Darwin
+.Sh NAME
+.Nm asxprintf , dxprintf , fxprintf , sxprintf , xprintf ,
+.Nm vasxprintf , vdxprintf , vfxprintf , vsxprintf , vxprintf
+.Nd extensible printf
+.Sh SYNOPSIS
+.In printf.h
+.Ft int
+.Fn asxprintf "char ** restrict ret" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ...
+.Ft int
+.Fn dxprintf "int fd" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ...
+.Ft int
+.Fn fxprintf "FILE * restrict stream" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ...
+.Ft int
+.Fn sxprintf "char * restrict str" "size_t size" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ...
+.Ft int
+.Fn xprintf "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" ...
+.In stdarg.h
+.Ft int
+.Fn vasxprintf "char ** restrict ret" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap"
+.Ft int
+.Fn vdxprintf "int fd" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap"
+.Ft int
+.Fn vfxprintf "FILE * restrict stream" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap"
+.Ft int
+.Fn vsxprintf "char * restrict str" "size_t size" "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap"
+.Ft int
+.Fn vxprintf "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict format" "va_list ap"
+.Sh DESCRIPTION
+These extensible printf (see
+.Xr xprintf 5 )
+variants behave like their normal printf counterparts
+(see
+.Xr printf 3 )
+without
+.Sq Li x
+in the name (except
+.Fn sxprintf
+and
+.Fn vsxprintf
+behave like
+.Fn snprintf
+and
+.Fn vsnprintf ,
+respectively).
+.Pp
+The
+.Va domain
+argument must be a pointer to a printf domain structure, as returned by one of
+the functions described in
+.Xr xprintf_domain 3 .
+The
+.Va loc
+argument should be an extended locale (see
+.Xr xlocale 3 )
+or NULL, which means to use the current locale in effect (either the per-thread
+locale if set, or the global locale by default).
+.Sh SEE ALSO
+.Xr printf 3 ,
+.Xr xlocale 3 ,
+.Xr xprintf_domain 3 ,
+.Xr xprintf 5
--- /dev/null
+.Dd Aug 19, 2012
+.Dt XPRINTF 5
+.Os Darwin
+.Sh NAME
+.Nm xprintf
+.Nd extensible printf
+.Sh SYNOPSIS
+.In printf.h
+.Ft "typedef int"
+.Fn printf_arginfo_function "const struct printf_info *info" "size_t n" "int *argtypes"
+.Ft "typedef int"
+.Fn printf_function "FILE *stream" "const struct printf_info *info" "const void *const *args"
+.Sh DESCRIPTION
+The standard
+.Xr printf 3
+family of routines provides a convenient way to convert one or more arguments
+to various forms for output, under the control of a format string.
+The format string may contain any number of conversion specifications, which
+start with the
+.Sq Li %
+character and end with a conversion specifier character (like
+.Sq Li d
+or
+.Sq Li f ) ,
+with conversion flag characters in-between.
+.Pp
+Extensible printf is an enhancement that allows adding new (user-defined)
+conversion specifiers, or modifying/removing existing ones.
+The implementation of extensible printf in Mac OS X is derived from the
+FreeBSD version, which is based on the one in GNU libc (GLIBC).
+Documentation for the GLIBC version is available at:
+.Pp
+.Li http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html
+.Pp
+The main problem with the usual forms of extensible printf is that
+changes to
+.Xr printf 3
+are program-wide.
+But this is unsafe, since frameworks,
+libraries or some other thread could change printf behavior in ways
+unexpected by the main program, or the latter could unexpectedly affect the
+former.
+.Pp
+So instead, the implementation used in Mac OS X makes
+changes to conversion specifiers within printf domains,
+which are independent structures containing the specifier definitions.
+These domains are created as described in
+.Xr xprintf_domain 3 ,
+and once set up, it can be passed to a
+.Xr xprintf 3
+variant along with the format string and arguments to generate output.
+The standard
+.Xr printf 3
+behavior is never affected.
+.Pp
+To define a new conversion specifier, two function typedefs are defined, and
+the user must provide two functions based on these typedefs.
+These functions will get called from extensible printf while processing
+the corresponding conversion specification.
+.Pp
+During the first of three phases of extensible printf processing, the format
+string is parsed, and for each conversion specification, a
+.Vt struct printf_info
+is created, containing the option flags specified in the
+conversion specification as well as other settings.
+Important fields in
+.Vt struct printf_info
+are:
+.Bl -tag -width ".Va is_long_double"
+.It Va alt
+Boolean value whether the
+.Sq Li #
+flag was specified.
+.It Va context
+A
+.Vt void *
+pointer to arbitrary data specified in the original call to
+.Xr register_printf_domain_function 3 .
+.It Va group
+Boolean value whether the
+.Sq Li '
+flag was specified.
+.It Va is_char
+Boolean value whether the
+.Sq Li hh
+flag was specified.
+.It Va is_intmax
+Boolean value whether the
+.Sq Li j
+flag was specified.
+.It Va is_long
+Boolean value whether the
+.Sq Li l
+flag was specified.
+.It Va is_long_double
+Boolean value whether the
+.Sq Li L
+or
+.Sq Li ll
+flags were specified.
+.It Va is_ptrdiff
+Boolean value whether the
+.Sq Li t
+flag was specified.
+.It Va is_quad
+Boolean value whether the
+.Sq Li q
+flag was specified.
+.It Va is_short
+Boolean value whether the
+.Sq Li h
+flag was specified.
+.It Va is_size
+Boolean value whether the
+.Sq Li z
+flag was specified.
+.It Va is_vec
+Boolean value whether the
+.Sq Li v
+flag was specified.
+.It Va left
+Boolean value whether the
+.Sq Li -
+flag was specified.
+.It Va loc
+The extended locale (see
+.Xr xlocale 3 )
+specified by the extensible printf caller (never
+.Dv NULL ) .
+.It Va pad
+The padding character; either
+.Sq Li 0
+or space.
+.It Va prec
+The value of the optional precision.
+-1 means the precision was unspecified.
+.It Va showsign
+Boolean value whether the
+.Sq Li +
+flag was specified.
+.It Va signchar
+The sign character, either
+.Sq Li + ,
+space or zero if none.
+.It Va space
+Boolean value whether the space flag was specified.
+.It Va spec
+The specifier character itself.
+.It Va vsep
+The separator character between vector items (using the
+.Sq Li v
+flag).
+Can be any one of the four characters
+.Dq Li ,:;_
+or
+.Sq Li X
+if no separator character was specified (meaning that a space is used as the
+separator, unless the specifier is
+.Sq Li c ,
+in which case no separator is used).
+.It Va width
+The value of the minimum field width (defaults to zero).
+.El
+.Pp
+All other structure fields are either unused or private (and shouldn't be
+used).
+.Pp
+This
+.Vt struct printf_info
+structure is then passed to the corresponding
+.Nm printf_arginfo_function
+callback function.
+The callback function should return the number of consecutive arguments the
+specifier handles, including zero (the maximum number of consecutive arguments
+a single specifier can handle is
+.Dv __PRINTFMAXARG ,
+which is currently set to 2, but could be increased in the future if there is
+need).
+.Pp
+The callback function is also passed an integer array and the length of that
+array; the length will typically be
+.Dv __PRINTFMAXARG .
+The function should fill out the array up to the number of arguments it expects,
+using the following values:
+.Bl -tag -width ".Dv PA_POINTER"
+.It Dv PA_CHAR
+The argument type is an
+.Vt int
+cast to a
+.Vt char .
+.It Dv PA_DOUBLE
+The argument type is a
+.Vt double .
+OR-ing
+.Dv PA_DOUBLE
+with
+.Dv PA_FLAG_LONG_DOUBLE
+specifies a
+.Vt "long double"
+type.
+.It Dv PA_FLOAT
+(Defined but unused; best to avoid, since
+.Vt float
+is automatically promoted to
+.Vt double
+anyways.)
+.It Dv PA_INT
+The argument type is
+.Vt int
+(either signed or unsigned).
+The size can be adjusted by OR-ing the following values to
+.Dv PA_INT :
+.Bl -tag -width ".Dv PA_FLAG_LONG_LONG"
+.It Dv PA_FLAG_INTMAX
+The integer is the size of a
+.Vt intmax_t .
+.It Dv PA_FLAG_LONG
+The integer is the size of a
+.Vt long .
+.It Dv PA_FLAG_LONG_LONG
+The integer is the size of a
+.Vt "long long" .
+.It Dv PA_FLAG_PTRDIFF
+The integer is the size of a
+.Vt ptrdiff_t .
+.It Dv PA_FLAG_QUAD
+The integer is the size of a
+.Vt quad_t
+(deprecated).
+.It Dv PA_FLAG_SHORT
+The integer is the size of a
+.Vt short .
+.It Dv PA_FLAG_SIZE
+The integer is the size of a
+.Vt size_t .
+.El
+.It Dv PA_POINTER
+The argument type is a pointer type, cast to a
+.Vt "void *" .
+.It Dv PA_STRING
+The argument type is a null-terminated character string
+.Vt ( "char *" ) .
+.It Dv PA_VECTOR
+The argument type is an AltiVec or SSE vector (16 bytes).
+.It Dv PA_WCHAR
+The argument type is a
+.Vt wchar_t .
+.It Dv PA_WSTRING
+The argument type is a null-terminated wide character string
+.Vt ( "wchar_t *" ) .
+.El
+.Pp
+After the
+.Nm printf_arginfo_function
+returns, phase 2 of extensible printf processing involves converting the
+argument according to the types specified by the returned type array.
+Note that positional arguments are dealt with here as well.
+.Pp
+Then in phase 3, output is generated, either from the text in-between the
+conversion specifications, or by calling the so-called rendering functions
+associated with each conversion specifier (with typedef
+.Nm printf_function ) .
+The rendering function is passed the same
+.Vt struct printf_info
+structure, as well as an array of pointers to each of the arguments converted
+in phase 2 that it is responsible for.
+The callback should write its output to the provided output
+stdio stream, and then return the number of characters written.
+.Sh EXAMPLE
+Here is an example that demonstrates many of the features of extensible printf:
+.Bd -literal
+#include <stdio.h>
+#include <stdlib.h>
+#include <printf.h>
+#include <locale.h>
+#include <xlocale.h>
+#include <err.h>
+
+/* The Coordinate type */
+typedef struct {
+ double x;
+ double y;
+} Coordinate;
+
+#define L (1 << 0)
+#define P (1 << 1)
+
+/* The renderer callback for Coordinate */
+static int
+print_coordinate (FILE *stream, const struct printf_info *info,
+ const void *const *args)
+{
+ const Coordinate *c;
+ int width, ret, which = 0;
+ char fmt[32];
+ char *bp, *cp, *ep;
+ /* The optional coordinate labels */
+ const char **labels = (const char **)info->context;
+
+ /* Get the argument pointer to a Coordinate */
+ c = *((const Coordinate **) (args[0]));
+
+ /* Set up the format string */
+ cp = fmt;
+ if(info->alt) *cp++ = '(';
+ bp = cp;
+ if(labels) {
+ which |= L;
+ *cp++ = '%';
+ *cp++ = 's';
+ }
+ *cp++ = '%';
+ if(info->group) *cp++ = '\e'';
+ *cp++ = '*';
+ if(info->prec >= 0) {
+ which |= P;
+ *cp++ = '.';
+ *cp++ = '*';
+ }
+ *cp++ = 'l';
+ *cp++ = 'f';
+ ep = cp;
+ if(info->alt) *cp++ = ',';
+ *cp++ = ' ';
+ while(bp < ep) *cp++ = *bp++;
+ if(info->alt) *cp++ = ')';
+ *cp = 0;
+
+ width = info->left ? -info->width : info->width;
+
+ /* Output to the given stream */
+ switch(which) {
+ case 0:
+ ret = fprintf_l(stream, info->loc, fmt, width, c->x, width, c->y);
+ break;
+ case L:
+ ret = fprintf_l(stream, info->loc, fmt, labels[0], width, c->x,
+ labels[1], width, c->y);
+ break;
+ case P:
+ ret = fprintf_l(stream, info->loc, fmt, width, info->prec, c->x,
+ width, info->prec, c->y);
+ break;
+ case (L | P):
+ ret = fprintf_l(stream, info->loc, fmt, labels[0], width,
+ info->prec, c->x, labels[1], width, info->prec,
+ c->y);
+ break;
+ }
+
+ return ret;
+}
+
+/* The arginfo callback for Coordinate */
+static int
+coordinate_arginfo (const struct printf_info *info, size_t n,
+ int *argtypes)
+{
+ /* We always take exactly one argument and this is a pointer to the
+ structure.. */
+ if (n > 0)
+ argtypes[0] = PA_POINTER;
+ return 1;
+}
+
+int
+main (void)
+{
+ Coordinate mycoordinate = {12345.6789, 3.141593};
+ printf_domain_t domain;
+ locale_t loc;
+ const char *labels[] = {"x=", "y="};
+
+ /* Set up a domain to add support for Coordinate conversion */
+ domain = new_printf_domain();
+ if(!domain)
+ err(1, "new_printf_domain");
+ /* Set up an extended locale to test locale support */
+ loc = newlocale(LC_ALL_MASK, "uk_UA.UTF-8", NULL);
+ if(!loc)
+ err(1, "newlocale");
+
+ /* Register the callbacks for Coordinates in the domain */
+ register_printf_domain_function (domain, 'C', print_coordinate,
+ coordinate_arginfo, NULL);
+
+ /* Print the coordinate using the current locale (C). */
+ xprintf(domain, NULL, "|%'C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'14C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'-14.2C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'#C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'#14C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'#-14.2C|\en", &mycoordinate);
+
+ printf("-------------\en");
+ /* Reregister the callbacks, specifying coordinate labels
+ * and setting the global locale (notice thousands separator) */
+ register_printf_domain_function (domain, 'C', print_coordinate,
+ coordinate_arginfo, labels);
+ if(setlocale(LC_ALL, "en_US.UTF-8") == NULL)
+ errx(1, "setlocale");
+
+ /* Reprint with labels */
+ xprintf(domain, NULL, "|%'C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'14C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'-14.2C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'#C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'#14C|\en", &mycoordinate);
+ xprintf(domain, NULL, "|%'#-14.2C|\en", &mycoordinate);
+
+ printf("-------------\en");
+ /* Now print with the test locale (notice decimal point and
+ * thousands separator) */
+ xprintf(domain, loc, "|%'C|\en", &mycoordinate);
+ xprintf(domain, loc, "|%'14C|\en", &mycoordinate);
+ xprintf(domain, loc, "|%'-14.2C|\en", &mycoordinate);
+ xprintf(domain, loc, "|%'#C|\en", &mycoordinate);
+ xprintf(domain, loc, "|%'#14C|\en", &mycoordinate);
+ xprintf(domain, loc, "|%'#-14.2C|\en", &mycoordinate);
+
+ return 0;
+}
+.Ed
+.Pp
+This example defines a Coordinate type, that consists of a pair of doubles.
+We create a conversion specifier that displays a Coordinate type, either just
+as two floating point numbers, or with the
+.Sq Li #
+(alternate form) flag, as parenthesized numbers separated by a comma.
+Note the use of
+.Nm printf_l
+to do the actual output; this is using regular printf from within an extensible
+printf renderer callback.
+The use of
+.Nm printf_l
+also insures correct handling of extended locales.
+.Pp
+The output of the programs looks like:
+.Bd -literal
+|12345.678900 3.141593|
+| 12345.678900 3.141593|
+|12345.68 3.14 |
+|(12345.678900, 3.141593)|
+|( 12345.678900, 3.141593)|
+|(12345.68 , 3.14 )|
+-------------
+|x=12,345.678900 y=3.141593|
+|x= 12,345.678900 y= 3.141593|
+|x=12,345.68 y=3.14 |
+|(x=12,345.678900, y=3.141593)|
+|(x= 12,345.678900, y= 3.141593)|
+|(x=12,345.68 , y=3.14 )|
+-------------
+|x=12 345,678900 y=3,141593|
+|x= 12 345,678900 y= 3,141593|
+|x=12 345,68 y=3,14 |
+|(x=12 345,678900, y=3,141593)|
+|(x= 12 345,678900, y= 3,141593)|
+|(x=12 345,68 , y=3,14 )|
+.Ed
+.Pp
+Notice:
+.Bl -bullet
+.It
+Field width, precision and left adjustment are applied to each of the numbers.
+.It
+The alternate form, using parenthesized numbers separated by a comma.
+.It
+In the second group of six, the thousands separator corresponds to the
+global locale setting
+.Pq Li en_US.UTF-8 .
+.It
+The second and third group have a label for each number, provide through
+the user-defined context argument.
+.It
+The third group has the decimal point and thousands separator of the extended
+locale argument
+.Pq Li uk_UA.UTF-8 .
+.El
+.Sh PERFORMANCE
+Because of the three phase processing of extensible printf, as well as the
+use of two callbacks for each conversion specifier, performance is
+considerably slower than the one pass, highly optimized regular
+.Xr printf 3 .
+Recursive use of
+.Xr printf 3
+from within an extensible printf renderer callback
+(as in the
+.Sx EXAMPLE
+above) adds additional overhead.
+.Pp
+To ameliorate some of this slowness, the concept of separate compilation
+and execution phases has be added to extensible printf.
+The functions in
+.Xr xprintf_comp 3
+allow the creation of pre-compiled extensible printf structures (performing
+phase one of extensible printf processing).
+These pre-compiled structures can then be passed to the printf variants in
+.Xr xprintf_exec 3
+to produce the actual output (performing phases 2 and 3).
+The compilation phase need only be done once, while execution can be performed
+any number of times.
+.Pp
+A simple example of use is:
+.Bd -literal
+ printf_comp_t pc = new_printf_comp(domain, loc, "%d: %C\en");
+ for(i = 0; i = sizeof(coords) / sizeof(*coords); i++) {
+ xprintf_exec(pc, i, &coords[i]);
+ }
+ free_printf_comp(pc);
+.Ed
+.Pp
+Here,
+.Va coords
+is a array containing
+.Vt Coordinate
+structures that are to be printed and the
+.Va domain
+and
+.Va loc
+variables are as from
+.Sx EXAMPLE
+above.
+(Error checking on the return value from
+.Fn new_printf_comp
+is not shown).
+.Sh SEE ALSO
+.Xr printf 3 ,
+.Xr xlocale 3 ,
+.Xr xprintf 3 ,
+.Xr xprintf_comp 3 ,
+.Xr xprintf_domain 3 ,
+.Xr xprintf_exec 3
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#define __va_list __darwin_va_list
+
+#include <printf.h>
+#include <stdarg.h>
+#include <local.h>
+#include <xprintf_private.h>
+
+int
+asxprintf(char ** __restrict ret, printf_domain_t __restrict domain,
+ locale_t __restrict loc, const char * __restrict format, ...)
+{
+ int iret;
+ va_list ap;
+
+ va_start(ap, format);
+ iret = _vasprintf(NULL, domain, ret, loc, format, ap);
+ va_end(ap);
+ return iret;
+}
+
+int
+dxprintf(int fd, printf_domain_t __restrict domain, locale_t __restrict loc,
+ const char * __restrict format, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, format);
+ ret = _vdprintf(NULL, domain, fd, loc, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+fxprintf(FILE * __restrict stream, printf_domain_t __restrict domain,
+ locale_t __restrict loc, const char * __restrict format, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, format);
+ ret = __xvprintf(NULL, domain, stream, loc, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+sxprintf(char * __restrict str, size_t size, printf_domain_t __restrict domain,
+ locale_t __restrict loc, const char * __restrict format, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, format);
+ ret = _vsnprintf(NULL, domain, str, size, loc, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+xprintf(printf_domain_t __restrict domain, locale_t __restrict loc,
+ const char * __restrict format, ...)
+{
+ int ret;
+ va_list ap;
+
+ va_start(ap, format);
+ ret = __xvprintf(NULL, domain, stdout, loc, format, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+vasxprintf(char ** __restrict ret, printf_domain_t __restrict domain,
+ locale_t __restrict loc, const char * __restrict format, va_list ap)
+{
+ return _vasprintf(NULL, domain, ret, loc, format, ap);
+}
+
+int
+vdxprintf(int fd, printf_domain_t __restrict domain, locale_t __restrict loc,
+ const char * __restrict format, va_list ap)
+{
+ return _vdprintf(NULL, domain, fd, loc, format, ap);
+}
+
+int
+vfxprintf(FILE * __restrict stream, printf_domain_t __restrict domain,
+ locale_t __restrict loc, const char * __restrict format, va_list ap)
+{
+ return __xvprintf(NULL, domain, stream, loc, format, ap);
+}
+
+int
+vsxprintf(char * __restrict str, size_t size, printf_domain_t __restrict domain,
+ locale_t __restrict loc, const char * __restrict format, va_list ap)
+{
+ return _vsnprintf(NULL, domain, str, size, loc, format, ap);
+}
+
+int
+vxprintf(printf_domain_t __restrict domain, locale_t __restrict loc,
+ const char * __restrict format, va_list ap)
+{
+ return __xvprintf(NULL, domain, stdout, loc, format, ap);
+}
--- /dev/null
+.Dd Aug 19, 2012
+.Dt XPRINTF_COMP 3
+.Os Darwin
+.Sh NAME
+.Nm free_printf_comp , new_printf_comp
+.Nd extensible printf compilation
+.Sh SYNOPSIS
+.In printf.h
+.Ft void
+.Fn free_printf_comp "printf_comp_t pc"
+.Ft printf_comp_t
+.Fn new_printf_comp "printf_domain_t restrict domain" "locale_t restrict loc" "const char * restrict fmt"
+.Sh DESCRIPTION
+To ameliorate some of the slowness caused by the extra overhead in
+extensible printf (see
+.Xr xprintf 5 ) ,
+a compile/execute mechanism has been created.
+The
+.Fn new_printf_comp
+function compiles the given format string, along with a printf domain
+(see
+.Xr xprintf_domain 3 )
+and an extended locale
+(see
+.Xr xlocale 3 ) ,
+and returns a
+.Ft printf_comp_t
+structure.
+The domain may not be
+.Dv NULL ,
+but the locale can be
+.Dv NULL ,
+which means to use the current locale, either the per-thread locale if it
+was set, or else the global locale.
+Because the
+.Ft printf_comp_t
+structure records the domain and locale, care should be taken if either
+of these are changed.
+.Pp
+Once a
+.Ft printf_comp_t
+structure is created, it can be passed to one of the extensible printf
+execution variants, described in
+.Xr xprintf_exec 3 ,
+along with the necessary arguments.
+Creating the
+.Ft printf_comp_t
+structure needs to be done only once, but it can be passed
+to extensible printf execution variants any number of times.
+.Pp
+When the
+.Ft printf_comp_t
+structure is no longer needed, it should be passed to
+.Fn free_printf_comp
+to release internal memory.
+.Sh RETURN VALUES
+The
+.Fn new_printf_comp
+function returns the new structure, or
+.Dv NULL
+on error (usually NULL domain or out of memory condition).
+.Sh SEE ALSO
+.Xr xlocale 3 ,
+.Xr xprintf_domain 3 ,
+.Xr xprintf_exec 3 ,
+.Xr xprintf 5
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <xlocale_private.h>
+#include <printf.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include "xprintf_domain.h"
+#include "xprintf_private.h"
+
+void
+free_printf_comp(printf_comp_t pc)
+{
+ if(!pc) return;
+ XL_RELEASE(pc->loc);
+#ifdef XPRINTF_PERF
+ arrayfree(pc->pa);
+ free(pc->pa);
+ arrayfree(pc->aa);
+ free(pc->aa);
+ arrayfree(pc->ua);
+ free(pc->ua);
+#else /* !XPRINTF_PERF */
+ free(pc->pi);
+ free(pc->argt);
+ free(pc->args);
+#endif /* !XPRINTF_PERF */
+ pthread_mutex_destroy(&pc->mutex);
+ free(pc);
+}
+
+printf_comp_t
+new_printf_comp(printf_domain_t restrict domain, locale_t loc, const char * restrict fmt)
+{
+ int ret, saverrno;
+ printf_comp_t restrict pc;
+
+ if(!domain) {
+ errno = EINVAL;
+ return NULL;
+ }
+ pc = MALLOC(sizeof(*pc) + strlen(fmt) + 1);
+ if(!pc) return NULL;
+ bzero(pc, sizeof(*pc));
+ pc->mutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
+ pc->fmt = (const char *)(pc + 1);
+ strcpy((char *)pc->fmt, fmt);
+ DEFAULT_CURRENT_LOCALE(loc);
+ XL_RETAIN(loc);
+ pc->loc = loc;
+ xprintf_domain_init();
+ pthread_rwlock_rdlock(&domain->rwlock);
+ ret = __printf_comp(pc, domain);
+ saverrno = errno;
+ pthread_rwlock_unlock(&domain->rwlock);
+ if(ret < 0) {
+ XL_RELEASE(loc);
+ pthread_mutex_destroy(&pc->mutex);
+ free(pc);
+ errno = saverrno;
+ return NULL;
+ }
+ return pc;
+}
--- /dev/null
+.Dd Aug 19, 2012
+.Dt XPRINTF_DOMAIN 3
+.Os Darwin
+.Sh NAME
+.Nm copy_printf_domain , free_printf_domain , new_printf_domain ,
+.Nm register_printf_domain_function , register_printf_domain_render_std
+.Nd extensible printf domains
+.Sh SYNOPSIS
+.In printf.h
+.Ft printf_domain_t
+.Fn copy_printf_domain "printf_domain_t domain"
+.Ft void
+.Fn free_printf_domain "printf_domain_t domain"
+.Ft printf_domain_t
+.Fn new_printf_domain void
+.Ft int
+.Fn register_printf_domain_function "printf_domain_t domain" "int spec" "printf_function *render" "printf_arginfo_function *arginfo", "void *context"
+.Ft int
+.Fn register_printf_domain_render_std "printf_domain_t domain" "const char *specs"
+.Sh DESCRIPTION
+A printf domain is an extensible printf (see
+.Xr xprintf 5 )
+structure defining a set of conversion specifiers that
+will be used in calls to the routines discussed in
+.Xr xprintf 3
+and
+.Xr xprintf_comp 3 .
+Domains can be modified independently of one another, and do not affect the
+behavior of the normal printf calls in
+.Xr printf 3 .
+.Pp
+To create a new domain, call
+.Fn new_printf_domain ;
+the standard POSIX conversion specifiers are defined by default.
+To make a copy of an existing domain, use
+.Fn copy_printf_domain .
+When a domain is no longer needed, call
+.Fn free_printf_domain
+to release the associated memory.
+.Pp
+The
+.Fn register_printf_domain_function
+function is used to add, modify or remove conversion specifiers for a
+given domain.
+The
+.Fa spec
+argument is the specifier character, which can be any printable (non-control)
+ASCII character,
+except for those characters that are used as flag/option characters.
+The set of flag/option characters includes the space character, and the
+following:
+.Pp
+.Dl # $ ' * + \&, - \&. 0 1 2 3 4 5 6 7 8 9 \&: \&; L _ h j l q t v z
+.Pp
+Two user-defined callback function must also be given; see
+.Xr xprintf 5
+for a description of these callback functions and an example of use.
+Setting either or both callbacks to
+.Dv NULL
+deletes the given specifier from the domain.
+Note that while it is permissible to redefine the standard conversion
+specifiers, it is not usually recommended as it may cause confusion.
+.Pp
+The
+.Fn register_printf_domain_render_std
+function is used to add pre-defined conversion specifiers to the given domain.
+The
+.Fa specs
+argument is a null-terminated C string containing one or more of the following
+specifier characters:
+.Bl -tag -width ".Li H"
+.It Li H
+Hex dump.
+The
+.Sq Li H
+specifier takes two arguments; the first is a pointer to the data to
+dump, while the second argument is the length of the data, given as type
+.Vt unsigned .
+Normally, 16 characters are displayed per line, as pairs of hex characters
+separated by spaces.
+Specifying a field width less than 16 will display that number of characters
+per line.
+Setting the
+.Sq Li +
+(showsign) flag will prefix each line with the hex offset of the beginning
+character in that line.
+Setting the
+.Sq Li #
+(alternate form) flag will postfix an ASCII representation to each line, with
+.Sq Li \&.
+representing non-printable characters.
+.It Li M
+Errno.
+The
+.Sq Li M
+specifier displayed the text representation of the given
+.Vt int
+argument, expected to be a valid
+.Va errno
+value (as returned by
+.Xr strerror 3 ) .
+Invalid errno values are represent by the
+.Dq Li errno=
+string followed by the decimal and hex values of the argument.
+.It Li Q
+Quoted.
+The
+.Sq Li Q
+specifier displays a null-terminated string argument as a C string, with
+leading and trailing double quotes.
+Newlines, carriage-returns and tabs are represented by
+.Sq Li \en ,
+.Sq Li \er
+and
+.Sq Li \et ,
+respectively, while backslashes and double quotes are preceeded with a
+backslash.
+All other whitespace characters not including space itself (those in which
+.Xr isspace 3
+returns true) are displayed as octal escape sequences (a backslash followed by
+three octal digits).
+All other characters print as themselves.
+.It Li T
+time_t/timeval/timespec.
+The
+.Sq Li T
+specifier displays the three types of time values as a single decimal value.
+The argument should be a pointer to the time value to be converted.
+Setting the appropriate flags indicates which type is indicated:
+.Bl -tag -width ".Pq none"
+.It Li ll
+The
+.Sq Li ll
+(long long) flag indicates the argument points to a
+.Vt struct timespec
+structure.
+The default precision is 9.
+.It Li l
+The
+.Sq Li l
+(long) flag indicates the argument points to a
+.Vt struct timeval
+structure.
+The default precision is 6.
+.It Pq none
+By default, the argument points to a
+.Vt time_t
+value.
+The default precision is 0 (the fractional part is not displayed).
+.El
+.Pp
+If the
+.Sq Li #
+(alternate form) flag is specified, the value is displayed in years, days,
+hours, minutes and seconds, as in:
+.Dq Li 3y123d21h59m59s.987654
+(zero values are not displayed at all).
+Note that the years are 365 days (no leap days).
+.It Li V
+String vis.
+The
+.Sq Li V
+specifier uses
+.Xr strvisx 3
+to display the null-terminated C string argument.
+The precision value can be used to limit the amount of the string that is
+processed (defaults to the entire string).
+.Pp
+Flag values can be used to obtain different encodings:
+.Bl -tag -width "(none)"
+.It Li +
+The
+.Sq Li +
+(showsign) flag uses the
+.Dq Li VIS_WHITE | VIS_HTTPSTYLE
+flag value to
+.Xr strvisx 3 .
+.It Li 0
+The
+.Sq Li 0
+(leading zero) flag uses the
+.Dq Li VIS_WHITE | VIS_OCTAL
+flag value to
+.Xr strvisx 3 .
+.It Li #
+The
+.Sq Li #
+(alternate form) flag uses the
+.Dq Li VIS_WHITE
+flag value to
+.Xr strvisx 3 .
+.It Pq none
+The default flag value to
+.Xr strvisx 3
+is
+.Dq Li VIS_WHITE | VIS_CSTYLE | VIS_OCTAL .
+.El
+.El
+.Sh RETURN VALUES
+The
+.Fn new_printf_domain
+and
+.Fn copy_printf_domain
+functions return the new domain, or
+.Dv NULL
+on failure (usually out of memory condition).
+.Pp
+The
+.Fn register_printf_domain_function
+and
+.Fn register_printf_domain_render_std
+return zero on success and \-1 on failure (usually due to an improper specifier
+character or out of memory condition).
+.Sh SEE ALSO
+.Xr printf 3 ,
+.Xr strvisx 3 ,
+.Xr xprintf 3 ,
+.Xr xprintf_comp 3 ,
+.Xr xprintf 5
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <printf.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "xprintf_domain.h"
+#include "xprintf_private.h"
+
+/* These are flag characters and can never be used as conversion specifiers */
+static const char _printf_tbl_flags[] = "#$'*+,-.0123456789:;L_hjlqtvz";
+
+struct _printf_tbl_defaults_fbsd {
+ const char *spec;
+ printf_arginfo_function *arginfo;
+ printf_render *render;
+};
+static struct _printf_tbl_defaults_fbsd _printf_tbl_defaults_fbsd[] = {
+ {"%", __printf_arginfo_pct, __printf_render_pct},
+ {"AEFGaefg", __printf_arginfo_float, __printf_render_float},
+ {"Cc", __printf_arginfo_chr, __printf_render_chr},
+ {"DOUXdioux", __printf_arginfo_int, __printf_render_int},
+ {"Ss", __printf_arginfo_str, __printf_render_str},
+ {"p", __printf_arginfo_ptr, __printf_render_ptr},
+};
+struct _printf_tbl_defaults_glibc {
+ const char *spec;
+ printf_arginfo_function *arginfo;
+ printf_function *render;
+};
+static struct _printf_tbl_defaults_glibc _printf_tbl_defaults_glibc[] = {
+ {"n", __printf_arginfo_n, __printf_render_n},
+};
+
+static printf_domain_t xprintf_domain_default;
+#ifdef XPRINTF_DEBUG
+__private_extern__ printf_domain_t xprintf_domain_global = NULL;
+#endif
+
+__private_extern__ pthread_once_t __xprintf_domain_once = PTHREAD_ONCE_INIT;
+
+__private_extern__ void
+__xprintf_domain_init(void)
+{
+ xprintf_domain_default = (printf_domain_t)calloc(
+#ifdef XPRINTF_DEBUG
+ 2,
+#else
+ 1,
+#endif
+ sizeof(*xprintf_domain_default));
+ if(xprintf_domain_default == NULL)
+ LIBC_ABORT("No memory");
+
+ xprintf_domain_default->rwlock = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER;
+ {
+ const char *cp;
+ for(cp = _printf_tbl_flags; *cp; cp++)
+ xprintf_domain_default->type[printf_tbl_index(*cp)] = PRINTF_DOMAIN_FLAG;
+ }
+ {
+ struct _printf_tbl_defaults_fbsd *d = _printf_tbl_defaults_fbsd;
+ int n = sizeof(_printf_tbl_defaults_fbsd) / sizeof(*_printf_tbl_defaults_fbsd);
+ for(; n > 0; d++, n--) {
+ for(const char *cp = d->spec; *cp; cp++) {
+ xprintf_domain_default->type[printf_tbl_index(*cp)] = PRINTF_DOMAIN_FBSD_API;
+ xprintf_domain_default->tbl[printf_tbl_index(*cp)] = (struct _printf_tbl){d->arginfo, d->render, NULL};
+ }
+ }
+ }
+ {
+ struct _printf_tbl_defaults_glibc *d = _printf_tbl_defaults_glibc;
+ int n = sizeof(_printf_tbl_defaults_glibc) / sizeof(*_printf_tbl_defaults_glibc);
+ for(; n > 0; d++, n--) {
+ for(const char *cp = d->spec; *cp; cp++) {
+ xprintf_domain_default->type[printf_tbl_index(*cp)] = PRINTF_DOMAIN_GLIBC_API;
+ xprintf_domain_default->tbl[printf_tbl_index(*cp)] = (struct _printf_tbl){d->arginfo, d->render, NULL};
+ }
+ }
+ }
+#ifdef XPRINTF_DEBUG
+ xprintf_domain_global = xprintf_domain_default + 1;
+ *xprintf_domain_global = *xprintf_domain_default;
+#endif
+}
+
+printf_domain_t
+copy_printf_domain(printf_domain_t src)
+{
+ printf_domain_t restrict copy;
+
+ if(!src) {
+ errno = EINVAL;
+ return NULL;
+ }
+ copy = (printf_domain_t)MALLOC(sizeof(*copy));
+ if(!copy) return NULL;
+ xprintf_domain_init();
+ pthread_rwlock_rdlock(&src->rwlock);
+ *copy = *src;
+ pthread_rwlock_unlock(&src->rwlock);
+ copy->rwlock = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER;
+ return copy;
+}
+
+void
+free_printf_domain(printf_domain_t d)
+{
+ if(!d) return;
+ pthread_rwlock_destroy(&d->rwlock);
+ free(d);
+}
+
+printf_domain_t
+new_printf_domain(void)
+{
+ printf_domain_t restrict d;
+
+ xprintf_domain_init();
+
+ d = (printf_domain_t)MALLOC(sizeof(*d));
+ if(!d) return NULL;
+ *d = *xprintf_domain_default;
+ return d;
+}
+
+int
+register_printf_domain_function(printf_domain_t d, int spec, printf_function *render, printf_arginfo_function *arginfo, void *context)
+{
+ xprintf_domain_init();
+
+ if(!d || !printf_tbl_in_range(spec)) {
+ errno = EINVAL;
+ return -1;
+ }
+ xprintf_domain_init();
+
+ switch(d->type[printf_tbl_index(spec)]) {
+ case PRINTF_DOMAIN_FLAG:
+ errno = EINVAL;
+ return -1;
+ default:
+ pthread_rwlock_wrlock(&d->rwlock);
+ if(!render || !arginfo) {
+ d->type[printf_tbl_index(spec)] = PRINTF_DOMAIN_UNUSED;
+ } else {
+ d->type[printf_tbl_index(spec)] = PRINTF_DOMAIN_GLIBC_API;
+ d->tbl[printf_tbl_index(spec)] = (struct _printf_tbl){arginfo, render, context};
+ }
+ pthread_rwlock_unlock(&d->rwlock);
+ }
+
+ return 0;
+}
+
+__private_extern__ int
+register_printf_domain_render(printf_domain_t d, int spec, printf_render *render, printf_arginfo_function *arginfo)
+{
+ xprintf_domain_init();
+
+ if(!d || !printf_tbl_in_range(spec)) {
+ errno = EINVAL;
+ return -1;
+ }
+ xprintf_domain_init();
+
+ switch(d->type[printf_tbl_index(spec)]) {
+ case PRINTF_DOMAIN_FLAG:
+ errno = EINVAL;
+ return -1;
+ default:
+ pthread_rwlock_wrlock(&d->rwlock);
+ if(!render || !arginfo) {
+ d->type[printf_tbl_index(spec)] = PRINTF_DOMAIN_UNUSED;
+ } else {
+ d->type[printf_tbl_index(spec)] = PRINTF_DOMAIN_FBSD_API;
+ d->tbl[printf_tbl_index(spec)] = (struct _printf_tbl){arginfo, render, NULL};
+ }
+ pthread_rwlock_unlock(&d->rwlock);
+ }
+
+ return 0;
+}
+
+int
+register_printf_domain_render_std(printf_domain_t d, const char *specs)
+{
+ int ret = 0;
+
+ for (; *specs != '\0'; specs++) {
+ switch (*specs) {
+ case 'H':
+ ret = register_printf_domain_render(d, *specs,
+ __printf_render_hexdump,
+ __printf_arginfo_hexdump);
+ break;
+ case 'M':
+ ret = register_printf_domain_render(d, *specs,
+ __printf_render_errno,
+ __printf_arginfo_errno);
+ break;
+ case 'Q':
+ ret = register_printf_domain_render(d, *specs,
+ __printf_render_quote,
+ __printf_arginfo_quote);
+ break;
+ case 'T':
+ ret = register_printf_domain_render(d, *specs,
+ __printf_render_time,
+ __printf_arginfo_time);
+ break;
+ case 'V':
+ ret = register_printf_domain_render(d, *specs,
+ __printf_render_vis,
+ __printf_arginfo_vis);
+ break;
+ default:
+ errno = EINVAL;
+ return (-1);
+ }
+ if(ret < 0) return ret;
+ }
+ return (0);
+}
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#ifndef __XPRINTF_DOMAIN_H_
+#define __XPRINTF_DOMAIN_H_
+
+#include <sys/cdefs.h>
+#include <printf.h>
+#include <pthread.h>
+
+#define PRINTF_TBL_FIRST '!'
+#define PRINTF_TBL_LAST '~'
+#define PRINTF_TBL_SIZE (PRINTF_TBL_LAST - PRINTF_TBL_FIRST + 1)
+
+#define printf_tbl_index(x) ((x) - PRINTF_TBL_FIRST)
+#define printf_tbl_in_range(x) ((x) >= PRINTF_TBL_FIRST && (x) <= PRINTF_TBL_LAST)
+
+enum {
+ PRINTF_DOMAIN_UNUSED = 0,
+ PRINTF_DOMAIN_GLIBC_API,
+ PRINTF_DOMAIN_FBSD_API,
+ PRINTF_DOMAIN_FLAG,
+};
+#define printf_domain_fbsd_api(d,x) ((d)->type[x] == PRINTF_DOMAIN_FBSD_API)
+#define printf_domain_flag(d,x) ((d)->type[x] == PRINTF_DOMAIN_FLAG)
+#define printf_domain_glibc_api(d,x) ((d)->type[x] == PRINTF_DOMAIN_GLIBC_API)
+#define printf_domain_unused(d,x) ((d)->type[x] == PRINTF_DOMAIN_UNUSED)
+
+struct _printf_tbl {
+ printf_arginfo_function *arginfo;
+ void *render; /* either typedef printf_function or printf_render */
+ void *context;
+};
+struct _printf_domain {
+ pthread_rwlock_t rwlock;
+ char type[PRINTF_TBL_SIZE];
+ struct _printf_tbl tbl[PRINTF_TBL_SIZE];
+};
+
+__BEGIN_DECLS
+__END_DECLS
+
+#endif /* __XPRINTF_DOMAIN_H_ */
--- /dev/null
+.Dd Aug 19, 2012
+.Dt XPRINTF_EXEC 3
+.Os Darwin
+.Sh NAME
+.Nm asxprintf_exec , dxprintf_exec , fxprintf_exec , sxprintf_exec ,
+.Nm xprintf_exec , vasxprintf_exec , vdxprintf_exec , vfxprintf_exec ,
+.Nm vsxprintf_exec , vxprintf_exec
+.Nd execute-only extensible printf execution
+.Sh SYNOPSIS
+.In printf.h
+.Ft int
+.Fn asxprintf_exec "char ** restrict ret" "printf_comp_t restrict pc" ...
+.Ft int
+.Fn dxprintf_exec "int fd" "printf_comp_t restrict pc" ...
+.Ft int
+.Fn fxprintf_exec "FILE * restrict stream" "printf_comp_t restrict pc" ...
+.Ft int
+.Fn sxprintf_exec "char * restrict str" "size_t size" "printf_comp_t restrict pc" ...
+.Ft int
+.Fn xprintf_exec "printf_comp_t restrict pc" ...
+.In stdarg.h
+.Ft int
+.Fn vasxprintf_exec "char ** restrict ret" "printf_comp_t restrict pc" "va_list ap"
+.Ft int
+.Fn vdxprintf_exec "int fd" "printf_comp_t restrict pc" "va_list ap"
+.Ft int
+.Fn vfxprintf_exec "FILE * restrict stream" "printf_comp_t restrict pc" "va_list ap"
+.Ft int
+.Fn vsxprintf_exec "char * restrict str" "size_t size" "printf_comp_t restrict pc" "va_list ap"
+.Ft int
+.Fn vxprintf_exec "printf_comp_t restrict pc" "va_list ap"
+.Sh DESCRIPTION
+These functions are execute-only, extensible printf (see
+.Xr xprintf 5 )
+variants, taking a
+.Ft printf_comp_t
+structure created by the format string compilation routine
+.Xr new_printf_comp 3 .
+All these variants behave like their normal printf counterparts (see
+.Xr printf 3 )
+without
+.Sq Li x
+and
+.Dq Li _exec
+in the name (except
+.Fn sxprintf_exec
+and
+.Fn vsxprintf_exec
+behave like
+.Fn snprintf
+and
+.Fn vsnprintf ,
+respectively).
+.Sh SEE ALSO
+.Xr printf 3 ,
+.Xr xprintf_comp 3 ,
+.Xr xprintf 5
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#define __va_list __darwin_va_list
+
+#include <printf.h>
+#include <stdarg.h>
+#include <errno.h>
+#include <local.h>
+#include <xprintf_private.h>
+
+int
+asxprintf_exec(char ** __restrict ret,
+ printf_comp_t __restrict pc, ...)
+{
+ int iret;
+ va_list ap;
+
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(ap, pc);
+ iret = _vasprintf(pc, NULL, ret, NULL, NULL, ap);
+ va_end(ap);
+ return iret;
+}
+
+int
+dxprintf_exec(int fd, printf_comp_t __restrict pc, ...)
+{
+ int ret;
+ va_list ap;
+
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(ap, pc);
+ ret = _vdprintf(pc, NULL, fd, NULL, NULL, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+fxprintf_exec(FILE * __restrict stream,
+ printf_comp_t __restrict pc, ...)
+{
+ int ret;
+ va_list ap;
+
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(ap, pc);
+ ret = __xvprintf(pc, NULL, stream, NULL, NULL, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+sxprintf_exec(char * __restrict str, size_t size,
+ printf_comp_t __restrict pc, ...)
+{
+ int ret;
+ va_list ap;
+
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(ap, pc);
+ ret = _vsnprintf(pc, NULL, str, size, NULL, NULL, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+xprintf_exec(printf_comp_t __restrict pc, ...)
+{
+ int ret;
+ va_list ap;
+
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ va_start(ap, pc);
+ ret = __xvprintf(pc, NULL, stdout, NULL, NULL, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+vasxprintf_exec(char ** __restrict ret,
+ printf_comp_t __restrict pc, va_list ap)
+{
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return _vasprintf(pc, NULL, ret, NULL, NULL, ap);
+}
+
+int
+vdxprintf_exec(int fd, printf_comp_t __restrict pc,
+ va_list ap)
+{
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return _vdprintf(pc, NULL, fd, NULL, NULL, ap);
+}
+
+int
+vfxprintf_exec(FILE * __restrict stream,
+ printf_comp_t __restrict pc, va_list ap)
+{
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return __xvprintf(pc, NULL, stream, NULL, NULL, ap);
+}
+
+int
+vsxprintf_exec(char * __restrict str, size_t size,
+ printf_comp_t __restrict pc, va_list ap)
+{
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return _vsnprintf(pc, NULL, str, size, NULL, NULL, ap);
+}
+
+int
+vxprintf_exec(printf_comp_t __restrict pc, va_list ap)
+{
+ if (!pc) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ return __xvprintf(pc, NULL, stdout, NULL, NULL, ap);
+}
#include <stddef.h>
#include <unistd.h>
#include <pthread.h>
+#include <pthread_workqueue.h>
#include "un-namespace.h"
#include "libc_private.h"
/* <rdar://problem/7397932> abort() should call pthread_kill to deliver a signal to the aborting thread
* This helps gdb focus on the thread calling abort()
*/
- if (__is_threaded) {
- /* Block all signals on all other threads */
- sigset_t fullmask;
- sigfillset(&fullmask);
- (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
-
- /* <rdar://problem/8400096> Set the workqueue killable */
- __pthread_workqueue_setkill(1);
-
- (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
- (void)pthread_kill(pthread_self(), SIGABRT);
- } else {
- (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
- (void)kill(getpid(), SIGABRT);
- }
+
+ /* Block all signals on all other threads */
+ sigset_t fullmask;
+ sigfillset(&fullmask);
+ (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
+
+ /* <rdar://problem/8400096> Set the workqueue killable */
+ __pthread_workqueue_setkill(1);
+
+ (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
+ (void)pthread_kill(pthread_self(), SIGABRT);
+
usleep(TIMEOUT); /* give time for signal to happen */
/*
/* <rdar://problem/7397932> abort() should call pthread_kill to deliver a signal to the aborting thread
* This helps gdb focus on the thread calling abort()
*/
- if (__is_threaded) {
- /* Block all signals on all other threads */
- sigset_t fullmask;
- sigfillset(&fullmask);
- (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
-
- /* <rdar://problem/8400096> Set the workqueue killable */
- __pthread_workqueue_setkill(1);
-
- (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
- (void)pthread_kill(pthread_self(), SIGABRT);
- } else {
- (void)_sigprocmask(SIG_SETMASK, &act.sa_mask, NULL);
- (void)kill(getpid(), SIGABRT);
- }
+
+ /* Block all signals on all other threads */
+ sigset_t fullmask;
+ sigfillset(&fullmask);
+ (void)_sigprocmask(SIG_SETMASK, &fullmask, NULL);
+
+ /* <rdar://problem/8400096> Set the workqueue killable */
+ __pthread_workqueue_setkill(1);
+
+ (void)pthread_sigmask(SIG_SETMASK, &act.sa_mask, NULL);
+ (void)pthread_kill(pthread_self(), SIGABRT);
+
usleep(TIMEOUT); /* give time for signal to happen */
/* If for some reason SIGABRT was not delivered, we exit using __builtin_trap
#endif /* __BLOCKS__ */
#include "libc_private.h"
+#include <TargetConditionals.h>
+
#define ATEXIT_FN_EMPTY 0
#define ATEXIT_FN_STD 1
#define ATEXIT_FN_CXA 2
}
_MUTEX_UNLOCK(&atexit_mutex);
}
+
+#if !TARGET_IPHONE_SIMULATOR && (__i386__ || __x86_64__)
+/*
+ * Support for thread_local in C++, using existing _tlv_atexit() in libdyld
+ */
+
+void _tlv_atexit(void(*f)(void*), void* arg); /* in libdyld */
+
+void
+__cxa_thread_atexit(void(*f)(void*), void* arg)
+{
+ _tlv_atexit(f, arg);
+}
+#endif
#include "atexit.h"
#include "libc_private.h"
+#include <TargetConditionals.h>
+
void (*__cleanup)(void);
-extern void __exit(int);
+extern void __exit(int) __attribute__((noreturn));
+#if !TARGET_IPHONE_SIMULATOR && (__i386__ || __x86_64__)
+extern void _tlv_exit();
+#endif
/*
* Exit, flushing stdio buffers if necessary.
*/
void
-exit(status)
- int status;
+exit(int status)
{
+#if !TARGET_IPHONE_SIMULATOR && (__i386__ || __x86_64__)
+ _tlv_exit(); // C++11 requires thread_local objects to be destroyed before global objects
+#endif
__cxa_finalize(NULL);
if (__cleanup)
(*__cleanup)();
respectively,
with an equal sign
.Dq Li \&= .
+The behavior is undefined when an equal sign appears at any other location in
+.Fa name .
.Pp
The
.Fn getenv
.Sh DESCRIPTION
.Bf -symbolic
These interfaces are obsoleted by
-.Xr random 3 .
+.Xr arc4random 3 .
.Ef
.Pp
The
.Fa seed
must be supplied by the caller.
.Sh SEE ALSO
+.Xr arc4random 3 ,
.Xr random 3 ,
.Xr random 4
.Sh STANDARDS
static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdlib/rand.c,v 1.17 2007/12/11 20:39:32 ache Exp $");
+__FBSDID("$FreeBSD$");
#include "namespace.h"
#include <sys/time.h> /* for sranddev() */
* secure random(4) interface.
*/
void
-sranddev()
+sranddev(void)
{
int fd, done;
done = 0;
- fd = _open("/dev/random", O_RDONLY, 0);
+ fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0);
if (fd >= 0) {
if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next))
done = 1;
if (!done) {
struct timeval tv;
- unsigned long junk;
gettimeofday(&tv, NULL);
- srand((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk);
+ srand((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec);
}
}
static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95";
#endif /* LIBC_SCCS and not lint */
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdlib/random.c,v 1.25 2007/01/09 00:28:10 imp Exp $");
+__FBSDID("$FreeBSD$");
-/*
- * We always compile with __DARWIN_UNIX03 set to one, relying on the fact that
- * (for non-LP64) sizeof(int) == sizeof(long) == sizeof(size_t), so that we
- * don't have to have two different versions of the prototypes. For LP64,
- * we only support the POSIX-compatible prototypes.
- */
+#ifdef __APPLE__
+// Always compile with __DARWIN_UNIX03=1 prototypes.
+// Applications using legacy interfaces (i386 only) use types of the same size:
+// sizeof(int) == sizeof(long) == sizeof(size_t)
#undef __DARWIN_UNIX03
#define __DARWIN_UNIX03 1
+#endif // __APPLE__
+
+#include "namespace.h"
#include "namespace.h"
#include <sys/time.h> /* for srandomdev() */
#include <fcntl.h> /* for srandomdev() */
static int rand_sep = SEP_3;
static uint32_t *end_ptr = &randtbl[DEG_3 + 1];
-static inline uint32_t good_rand(int32_t) __attribute__((always_inline));
-
-static inline uint32_t good_rand (x)
- int32_t x;
+static inline uint32_t
+good_rand(int32_t x)
{
#ifdef USE_WEAK_SEEDING
/*
* for default usage relies on values produced by this routine.
*/
void
-srandom(x)
- unsigned x;
+#ifdef __APPLE__
+srandom(unsigned int x)
+#else
+srandom(unsigned long x)
+#endif
{
int i, lim;
* a fixed seed.
*/
void
-srandomdev()
+srandomdev(void)
{
int fd, done;
size_t len;
len = rand_deg * sizeof state[0];
done = 0;
- fd = _open("/dev/random", O_RDONLY, 0);
+ fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0);
if (fd >= 0) {
if (_read(fd, (void *) state, len) == (ssize_t) len)
done = 1;
if (!done) {
struct timeval tv;
- unsigned long junk;
gettimeofday(&tv, NULL);
- srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec ^ junk);
+ srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec);
return;
}
* complain about mis-alignment, but you should disregard these messages.
*/
char *
-initstate(seed, arg_state, n)
- unsigned seed; /* seed for R.N.G. */
- char *arg_state; /* pointer to state array */
- size_t n; /* # bytes of state info */
+#ifdef __APPLE__
+initstate(unsigned int seed, char *arg_state, size_t n)
+#else
+initstate(unsigned long seed, char *arg_state, long n)
+#endif
{
char *ostate = (char *)(&state[-1]);
uint32_t *int_arg_state = (uint32_t *)arg_state;
if (n < BREAK_0) {
(void)fprintf(stderr,
"random: not enough state (%ld bytes); ignored.\n", n);
- return(0);
+ return (0);
}
if (n < BREAK_1) {
rand_type = TYPE_0;
int_arg_state[0] = rand_type;
else
int_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
- return(ostate);
+ return (ostate);
}
/*
* complain about mis-alignment, but you should disregard these messages.
*/
char *
-setstate(arg_state)
- const char *arg_state; /* pointer to state array */
+setstate(const char *arg_state)
{
uint32_t *new_state = (uint32_t *)arg_state;
uint32_t type = new_state[0] % MAX_TYPES;
fptr = &state[(rear + rand_sep) % rand_deg];
}
end_ptr = &state[rand_deg]; /* set end_ptr too */
- return(ostate);
+ return (ostate);
}
/*
* Returns a 31-bit random number.
*/
long
-random()
+random(void)
{
uint32_t i;
uint32_t *f, *r;
fptr = f; rptr = r;
}
- return((long)i);
+ return ((long)i);
}
*/
#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/stdlib/reallocf.c,v 1.4 2002/03/22 21:53:10 obrien Exp $");
+__FBSDID("$FreeBSD$");
#include <stdlib.h>
void *nptr;
nptr = realloc(ptr, size);
- if (!nptr && ptr)
+
+ /*
+ * When the System V compatibility option (malloc "V" flag) is
+ * in effect, realloc(ptr, 0) frees the memory and returns NULL.
+ * So, to avoid double free, call free() only when size != 0.
+ * realloc(ptr, 0) can't fail when ptr != NULL.
+ */
+ if (!nptr && ptr && size != 0)
free(ptr);
return (nptr);
}
.Fa resolved_name
was non-NULL, it will
contains the pathname which caused the problem.
+.Sh VARIANTS
+Defining
+.Dv _DARWIN_C_SOURCE
+or
+.Dv _DARWIN_BETTER_REALPATH
+before including stdio.h will cause the provided implementation of
+.Fn realpath
+to use F_GETPATH from
+.Xr fcntl 2
+to discover the path.
.Sh ERRORS
The function
.Fn realpath
};
#ifndef BUILDING_VARIANT
-__private_extern__ struct attrlist _rp_alist = {
+__private_extern__ const struct attrlist _rp_alist = {
ATTR_BIT_MAP_COUNT,
0,
ATTR_CMN_NAME | ATTR_CMN_DEVID | ATTR_CMN_OBJTYPE | ATTR_CMN_OBJID,
0,
};
#else /* BUILDING_VARIANT */
-__private_extern__ struct attrlist _rp_alist;
+__private_extern__ const struct attrlist _rp_alist;
#endif /* BUILDING_VARIANT */
extern char * __private_getcwd(char *, size_t, int);
errno = ENAMETOOLONG;
goto error_return;
}
- if (getattrlist(resolved, &_rp_alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) {
+ if (getattrlist(resolved, (void *)&_rp_alist, &attrs, sizeof(attrs), FSOPT_NOFOLLOW) == 0) {
useattrs = 1;
islink = (attrs.type == VLNK);
dev = attrs.dev;
symlink[slen] = '/';
symlink[slen + 1] = 0;
}
- left_len = strlcat(symlink, left, sizeof(left));
+ left_len = strlcat(symlink, left, sizeof(symlink));
if (left_len >= sizeof(left)) {
errno = ENAMETOOLONG;
goto error_return;
static pthread_mutex_t __systemfn_mutex = PTHREAD_MUTEX_INITIALIZER;
extern int __unix_conforming;
-#ifdef VARIANT_CANCELABLE
-extern void _pthread_testcancel(pthread_t thread, int isconforming);
-#endif /* VARIANT_CANCELABLE */
#endif /* __DARWIN_UNIX03 */
int
if (__unix_conforming == 0)
__unix_conforming = 1;
#ifdef VARIANT_CANCELABLE
- _pthread_testcancel(pthread_self(), 1);
+ pthread_testcancel();
#endif /* VARIANT_CANCELABLE */
#endif /* __DARWIN_UNIX03 */
}
static int
-get_groups(int size, char *grouping) {
+get_groups(int size, const char *grouping) {
int chars = 0;
int padded;
- char *grouping;
+ const char *grouping;
char decimal_point;
char thousands_sep;
char *
ptsname(int fd)
{
- static char ptsnamebuf[ 128]; /* ioctl knows length */
+ static char *ptsnamebuf = NULL;
int error;
char *retval = NULL;
struct stat sbuf;
+ if (ptsnamebuf == NULL) {
+ ptsnamebuf = malloc(128); // defined by TIOCPTYGNAME
+ }
+
error = ioctl(fd, TIOCPTYGNAME, ptsnamebuf);
if (!error) {
/*
* POSIX: Handle device rename test case, which is expected
* to fail if the pty has been renamed.
*/
- if (stat(ptsnamebuf, &sbuf) == 0)
+ if (stat(ptsnamebuf, &sbuf) == 0) {
retval = ptsnamebuf;
+ }
}
return (retval);
.Tn UTC ,
January 1, 1970; see
.Xr time 3 ) .
+When encountering an error, these functions return
+.Dv NULL
+and set
+.Dv errno
+to an appropriate value.
.Pp
The function
.Fn localtime
#define WILDABBR " "
#endif /* !defined WILDABBR */
-static char wildabbr[] = "WILDABBR";
+static const char wildabbr[] = "WILDABBR";
/*
* In June 2004 it was decided UTC was a more appropriate default time
#ifdef NOTIFY_TZ
typedef struct {
int token;
- int notify_was_off;
int is_set;
} notify_tz_t;
static const char * getsecs(const char * strp, long * secsp);
static const char * getoffset(const char * strp, long * offsetp);
static const char * getrule(const char * strp, struct rule * rulep);
+#ifdef NOTIFY_TZ
+static void gmtload(struct state * sp, char *path);
+#else /* ! NOTIFY_TZ */
static void gmtload(struct state * sp);
+#endif /* NOTIFY_TZ */
#ifdef __LP64__
static struct tm * gmtsub(const time_t * timep, long offset,
struct tm * tmp);
const struct tm * btmp);
static time_t transtime(time_t janfirst, int year,
const struct rule * rulep, long offset);
+#ifdef NOTIFY_TZ
+static int tzload(const char * name, struct state * sp, char *path);
+#else /* ! NOTIFY_TZ */
static int tzload(const char * name, struct state * sp);
+#endif /* NOTIFY_TZ */
static int tzparse(const char * name, struct state * sp,
int lastditch);
static pthread_mutex_t gmt_mutex = PTHREAD_MUTEX_INITIALIZER;
char * tzname[2] = {
- wildabbr,
- wildabbr
+ (char *)wildabbr,
+ (char *)wildabbr
};
/*
} \
}
#endif /* NOTIFY_TZ_LOG */
-/*--------------------------------------------------------------------
- * __notify_78945668_info__ is a global variable (defined in Libnotify)
- * that can be used to disable the notify mechanism. Set to a negative
- * value to disable. It can then be set back to zero to re-enable.
- *-------------------------------------------------------------------- */
-extern int __notify_78945668_info__;
-
-/*--------------------------------------------------------------------
- * fullname is used to pass the actual path of the timezone file to the
- * notify routines. If it is a nil string, that means no timezone file
- * is being used.
- *-------------------------------------------------------------------- */
-static char * fullname = NULL;
-
-static notify_tz_t gmt_notify = {-1, 0, 0};
-static notify_tz_t lcl_notify = {-1, 0, 0};
-static char notify_tz_name[] = NOTIFY_TZ_NAME;
+
+static notify_tz_t gmt_notify = {-1, 0};
+static notify_tz_t lcl_notify = {-1, 0};
+static const char notify_tz_name[] = NOTIFY_TZ_NAME;
#endif /* NOTIFY_TZ */
static long
#define NEED_DAYLIGHT 4
#define NEED_ALL (NEED_STD | NEED_DST | NEED_DAYLIGHT)
- tzname[0] = wildabbr;
- tzname[1] = wildabbr;
+ tzname[0] = (char *)wildabbr;
+ tzname[1] = (char *)wildabbr;
#ifdef USG_COMPAT
daylight = 0;
_st_set_timezone(0);
unsigned int nstat;
int ncheck;
- if (__notify_78945668_info__ < 0) {
-#ifdef NOTIFY_TZ_DEBUG
- if(!p->notify_was_off) NOTIFY_TZ_PRINTF("notify_check_tz: setting %s_notify->notify_was_off\n", (p == &lcl_notify ? "lcl" : "gmt"));
-#endif /* NOTIFY_TZ_DEBUG */
- p->notify_was_off = 1;
- return;
- }
- /* force rereading the timezone file if notify was off */
- if (p->notify_was_off) {
-#ifdef NOTIFY_TZ_DEBUG
- NOTIFY_TZ_PRINTF("notify_check_tz: saw %s_notify->notify_was_off\n", (p == &lcl_notify ? "lcl" : "gmt"));
-#endif /* NOTIFY_TZ_DEBUG */
- p->is_set = 0;
- p->notify_was_off = 0;
- return;
- }
if (p->token < 0)
return;
nstat = notify_check(p->token, &ncheck);
unsigned int nstat;
int ncheck;
- if (__notify_78945668_info__ < 0)
- return;
/*----------------------------------------------------------------
* Since we don't record the last time zone filename, just cancel
* (which should remove the file monitor) and setup from scratch
* Otherwise use com.apple.system.timezone.<fullpath>
*----------------------------------------------------------------*/
if (TZDEFAULT && strcmp(file, TZDEFAULT) == 0)
- name = notify_tz_name;
+ name = (char *)notify_tz_name;
else {
name = alloca(sizeof(notify_tz_name) + strlen(file) + 1);
if (name == NULL) {
#endif /* NOTIFY_TZ */
static int
+#ifdef NOTIFY_TZ
+tzload(name, sp, path)
+#else /* ! NOTIFY_TZ */
tzload(name, sp)
+#endif /* NOTIFY_TZ */
const char * name;
struct state * const sp;
+#ifdef NOTIFY_TZ
+char * path; /* copy full path if non-NULL */
+#endif /* NOTIFY_TZ */
{
const char * p;
int i;
if ((name[0] == ':' && name[1] == '/') ||
name[0] == '/' || strchr(name, '.'))
name = NULL;
+#ifdef NOTIFY_TZ
+ if (path)
+ *path = 0; /* default to empty string on error */
+#endif /* NOTIFY_TZ */
if (name == NULL && (name = TZDEFAULT) == NULL)
return -1;
{
** to hold the longest file name string that the implementation
** guarantees can be opened."
*/
-#ifdef NOTIFY_TZ
- if (!fullname) {
- fullname = malloc(FILENAME_MAX + 1);
- if (!fullname)
- return -1;
- }
-#else /* ! NOTIFY_TZ */
char fullname[FILENAME_MAX + 1];
-#endif /* NOTIFY_TZ */
if (name[0] == ':')
++name;
if (!doaccess) {
if ((p = TZDIR) == NULL)
return -1;
-#ifdef NOTIFY_TZ
- if ((strlen(p) + 1 + strlen(name) + 1) >= (FILENAME_MAX + 1))
-#else /* ! NOTIFY_TZ */
if ((strlen(p) + 1 + strlen(name) + 1) >= sizeof fullname)
-#endif /* NOTIFY_TZ */
return -1;
(void) strcpy(fullname, p);
(void) strcat(fullname, "/");
name = fullname;
}
#ifdef NOTIFY_TZ
- else
- strcpy(fullname, name);
+ if (path) {
+ if (strlen(name) > FILENAME_MAX)
+ return -1;
+ strcpy(path, name);
+ }
#endif /* NOTIFY_TZ */
if (doaccess && access(name, R_OK) != 0)
return -1;
return -1;
}
}
- load_result = tzload(TZDEFRULES, sp);
#ifdef NOTIFY_TZ
- *fullname = 0; /* mark fullname as invalid */
+ load_result = tzload(TZDEFRULES, sp, NULL);
+#else /* !NOTIFY_TZ */
+ load_result = tzload(TZDEFRULES, sp);
#endif /* NOTIFY_TZ */
if (load_result != 0)
sp->leapcnt = 0; /* so, we're off a little */
}
static void
+#ifdef NOTIFY_TZ
+gmtload(sp, path)
+#else /* ! NOTIFY_TZ */
gmtload(sp)
+#endif /* NOTIFY_TZ */
struct state * const sp;
+#ifdef NOTIFY_TZ
+char *path;
+#endif /* NOTIFY_TZ */
{
+#ifdef NOTIFY_TZ
+ if (tzload(gmt, sp, path) != 0)
+#else /* ! NOTIFY_TZ */
if (tzload(gmt, sp) != 0)
+#endif /* NOTIFY_TZ */
(void) tzparse(gmt, sp, TRUE);
}
}
}
#endif /* defined ALL_STATE */
+#ifdef NOTIFY_TZ
+ {
+ char fullname[FILENAME_MAX + 1];
+ if (tzload((char *) NULL, lclptr, fullname) != 0)
+ /*
+ * If fullname is empty (an error occurred) then
+ * default to the UTC path
+ */
+ gmtload(lclptr, *fullname ? NULL : fullname);
+ notify_register_tz(fullname, &lcl_notify);
+ }
+#else /* ! NOTIFY_TZ */
if (tzload((char *) NULL, lclptr) != 0)
gmtload(lclptr);
-#ifdef NOTIFY_TZ
- notify_register_tz(fullname, &lcl_notify);
#endif /* NOTIFY_TZ */
settzname();
_RWLOCK_UNLOCK(&lcl_rwlock);
lclptr->ttis[0].tt_abbrind = 0;
(void) strcpy(lclptr->chars, gmt);
#ifdef NOTIFY_TZ
- if (fullname)
- *fullname = 0;
+ notify_register_tz(NULL, &lcl_notify);
#endif /* NOTIFY_TZ */
- } else if (tzload(name, lclptr) != 0)
+ } else
+#ifdef NOTIFY_TZ
+ {
+ char fullname[FILENAME_MAX + 1];
+ /*
+ * parsedOK indicates whether tzparse() was called and
+ * succeeded. This means that TZ is a time conversion
+ * specification, so we don't need to register for
+ * notifications.
+ */
+ int parsedOK = FALSE;
+ if (tzload(name, lclptr, fullname) != 0)
+ if (name[0] == ':' || !(parsedOK = tzparse(name, lclptr, FALSE) == 0))
+ /*
+ * If fullname is empty (an error occurred) then
+ * default to the UTC path
+ */
+ (void) gmtload(lclptr, *fullname ? NULL : fullname);
+ notify_register_tz(parsedOK ? NULL : fullname, &lcl_notify);
+ }
+#else /* ! NOTIFY_TZ */
+ if (tzload(name, lclptr) != 0)
if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
(void) gmtload(lclptr);
-#ifdef NOTIFY_TZ
- notify_register_tz(fullname, &lcl_notify);
#endif /* NOTIFY_TZ */
settzname();
_RWLOCK_UNLOCK(&lcl_rwlock);
#endif /* NOTIFY_TZ */
gmtptr = (struct state *) malloc(sizeof *gmtptr);
if (gmtptr != NULL)
-#ifdef NOTIFY_TZ
- {
-#endif /* NOTIFY_TZ */
#endif /* defined ALL_STATE */
- gmtload(gmtptr);
#ifdef NOTIFY_TZ
+ {
+ char fullname[FILENAME_MAX + 1];
+ gmtload(gmtptr, fullname);
notify_register_tz(fullname, &gmt_notify);
-#ifdef ALL_STATE
}
-#endif
+#else /* ! NOTIFY_TZ */
+ gmtload(gmtptr);
#endif /* NOTIFY_TZ */
gmt_is_set = TRUE;
}
#define HAVE_STRERROR 1
#define HAVE_UNISTD_H 1
#define LOCALE_HOME _PATH_LOCALE
-#define TZDIR "/usr/share/zoneinfo"
+/* #define TZDIR "/usr/share/zoneinfo" */
#endif /* ndef TM_GMTOFF */
/*
#define PAD_ZERO 3
#ifndef BUILDING_VARIANT
-static const char* fmt_padding[][4] = {
+static const char * const fmt_padding[][4] = {
/* DEFAULT, LESS, SPACE, ZERO */
#define PAD_FMT_MONTHDAY 0
#define PAD_FMT_HMS 0
enum {CONVERT_NONE, CONVERT_GMT, CONVERT_ZONE};
-#define _strptime(b,f,t,c,l) _strptime0(b,f,t,c,l,-1,0,-1)
+#define _strptime(b,f,t,c,l) _strptime0(b,f,t,c,l,-1,0,-1,-1,'U')
+
+#define WEEK_U 'U'
+#define WEEK_V 'V'
+#define WEEK_W 'W'
+
+static int
+calcweeknum(struct tm *tm, int weeknum, int wday, int year, int kind)
+{
+ struct tm t;
+ int off;
+
+ bzero(&t, sizeof(t));
+ t.tm_mday = kind == WEEK_V ? 4 : 1;
+ t.tm_hour = 12; /* avoid any DST effects */
+ t.tm_year = year;
+ if (mktime(&t) == (time_t)-1) return 0;
+ off = t.tm_wday;
+
+ bzero(&t, sizeof(t));
+ if (kind != WEEK_U) {
+ off = (off + 6) % 7;
+ wday = (wday + 6) % 7;
+ }
+ if (kind == WEEK_V) {
+ t.tm_mday = 7 * weeknum + wday - off - 3;
+ } else {
+ if(off == 0) off = 7;
+ t.tm_mday = 7 * weeknum + wday - off + 1;
+ }
+ t.tm_hour = 12; /* avoid any DST effects */
+ t.tm_year = year;
+ if (mktime(&t) == (time_t)-1) return 0;
+
+ tm->tm_mday = t.tm_mday;
+ tm->tm_mon = t.tm_mon;
+ tm->tm_yday = t.tm_yday;
+ return 1;
+}
static char *
-_strptime0(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t loc, int year, int yday, int wday)
+_strptime0(const char *buf, const char *fmt, struct tm *tm, int *convp, locale_t loc, int year, int yday, int wday, int weeknum, int weekkind)
{
char c;
const char *ptr;
break;
case 'U': /* Sunday week */
+ case 'V': /* ISO 8601 week */
case 'W': /* Monday week */
if (!isdigit_l((unsigned char)*buf, loc))
return 0;
}
if (i > 53)
return 0;
+ if (c == 'V' && i < 1)
+ return 0;
- /* Calculate yday if we have enough data */
+ weeknum = i;
+ weekkind = c;
+
+ /* Calculate mon/mday/yday if we have enough data */
if ((year != -1) && (wday != -1)) {
- struct tm mktm;
- mktm.tm_year = year;
- mktm.tm_mon = 0;
- mktm.tm_mday = 1;
- mktm.tm_sec = 1;
- mktm.tm_min = mktm.tm_hour = 0;
- mktm.tm_isdst = 0;
- mktm.tm_gmtoff = 0;
- if (mktime(&mktm) != -1) {
- /* yday0 == Jan 1 == mktm.tm_wday */
- int delta = wday - mktm.tm_wday;
- if (!wday && c =='W')
- i++; /* Sunday is part of the following week */
- yday = 7 * i + delta;
- if (yday < 0)
- yday += 7;
- tm->tm_yday = yday;
- }
+ if (!calcweeknum(tm, weeknum, wday, year, weekkind)) return 0;
}
if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%')
if (i == 7)
i = 0;
tm->tm_wday = wday = i;
+
+ /* Calculate mon/mday/yday if we have enough data */
+ if ((year != -1) && (weeknum != -1)) {
+ if (!calcweeknum(tm, weeknum, wday, year, weekkind)) return 0;
+ }
+
buf++;
if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%')
if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%')
ptr++;
- ret = _strptime0(buf, ptr, tm, convp, loc, tm->tm_year, yday, wday);
+ ret = _strptime0(buf, ptr, tm, convp, loc, tm->tm_year, yday, wday, weeknum, weekkind);
if (ret) return ret;
/* Failed, so try 4-digit year */
*tm = savetm;
tm->tm_year = year = i;
+ /* Calculate mon/mday/yday if we have enough data */
+ if ((weeknum != -1) && (wday != -1)) {
+ if (!calcweeknum(tm, weeknum, wday, year, weekkind)) return 0;
+ }
+
if (*buf != 0 && isspace_l((unsigned char)*buf, loc))
while (*ptr != 0 && !isspace_l((unsigned char)*ptr, loc) && *ptr != '%')
ptr++;
*/
#ifndef TZDIR
+#ifdef UNIFDEF_TZDIR_SYMLINK
+#define TZDIR "/var/db/timezone/zoneinfo" /* Time zone object file directory */
+#else /* !UNIFDEF_TZDIR_SYMLINK */
#define TZDIR "/usr/share/zoneinfo" /* Time zone object file directory */
+#endif /* UNIFDEF_TZDIR_SYMLINK */
#endif /* !defined TZDIR */
#ifndef TZDEFAULT
+++ /dev/null
-/*
- * Copyright (c) 1987, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bcmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/bcmp.c,v 1.6 2007/01/09 00:28:11 imp Exp $");
-
-#include <strings.h>
-
-/*
- * bcmp -- vax cmpc3 instruction
- */
-int
-bcmp(const void *b1, const void *b2, size_t length)
-{
- char *p1, *p2;
-
- if (length == 0)
- return (0);
- p1 = (char *)b1;
- p2 = (char *)b2;
- do
- if (*p1++ != *p2++)
- break;
- while (--length);
- return (length);
-}
.Sh SYNOPSIS
.In strings.h
.Ft void
-.Fn bcopy "const void *s1" "void *s2" "size_t n"
+.Fn bcopy "const void *src" "void *dst" "size_t len"
.Sh DESCRIPTION
The
.Fn bcopy
function
copies
-.Fa n
+.Fa len
bytes from string
-.Fa s1
+.Fa src
to string
-.Fa s2 .
+.Fa dst .
The two strings may overlap.
If
-.Fa n
+.Fa len
is zero, no bytes are copied.
.Sh SEE ALSO
.Xr memccpy 3 ,
for
.St -p1003.1-2001
compliance.
+.Pp
+.Fn bcopy
+was deprecated in
+.St -p1003.1-2001
+and removed in
+.St -p1003.1-2008 .
+++ /dev/null
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
for
.St -p1003.1-2001
compliance.
+.Pp
+.Fn bzero
+was deprecated in
+.St -p1003.1-2001
+and removed in
+.St -p1003.1-2008 .
+++ /dev/null
-.\" Copyright (c) 1990, 1991, 1993
-.\" The Regents of the University of California. All rights reserved.
-.\"
-.\" This code is derived from software contributed to Berkeley by
-.\" Chris Torek.
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice, this list of conditions and the following disclaimer.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice, this list of conditions and the following disclaimer in the
-.\" documentation and/or other materials provided with the distribution.
-.\" 4. Neither the name of the University nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-.\" SUCH DAMAGE.
-.\"
-.\" @(#)ffs.3 8.2 (Berkeley) 4/19/94
-.\" $FreeBSD: src/lib/libc/string/ffs.3,v 1.13 2009/01/13 13:19:42 kib Exp $
-.\"
-.Dd October 26, 2008
-.Dt FFS 3
-.Os
-.Sh NAME
-.Nm ffs ,
-.Nm ffsl ,
-.Nm fls ,
-.Nm flsl
-.Nd find first or last bit set in a bit string
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In strings.h
-.Ft int
-.Fn ffs "int i"
-.Ft int
-.Fn ffsl "long i"
-.Ft int
-.Fn fls "int i"
-.Ft int
-.Fn flsl "long i"
-.Sh DESCRIPTION
-The
-.Fn ffs
-and
-.Fn ffsl
-functions find the first bit set
-(beginning with the least significant bit)
-in
-.Fa i
-and return the index of that bit.
-.Pp
-The
-.Fn fls
-and
-.Fn flsl
-functions find the last bit set in
-.Fa i
-and return the index of that bit.
-.Pp
-Bits are numbered starting at 1 (the least significant bit).
-A return value of zero from any of these functions means that the
-argument was zero.
-.Sh SEE ALSO
-.Xr bitstring 3
-.Sh HISTORY
-The
-.Fn ffs
-function appeared in
-.Bx 4.3 .
-Its prototype existed previously in
-.In string.h
-before it was moved to
-.In strings.h
-for
-.St -p1003.1-2001
-compliance.
-.Pp
-The
-.Fn ffsl ,
-.Fn fls ,
-and
-.Fn flsl
-functions appeared in
-.Fx 5.3 .
.In string.h
.Ft void *
.Fo memccpy
-.Fa "void *restrict s1"
-.Fa "const void *restrict s2"
+.Fa "void *restrict dst"
+.Fa "const void *restrict src"
.Fa "int c"
.Fa "size_t n"
.Fc
.Fn memccpy
function
copies bytes from string
-.Fa s2
+.Fa src
to string
-.Fa s1 .
+.Fa dst .
If the character
.Fa c
(as converted to an unsigned char) occurs in the string
-.Fa s2 ,
+.Fa src ,
the copy stops and a pointer to the byte after the copy of
.Fa c
in the string
-.Fa s1
+.Fa dst
is returned.
Otherwise,
.Fa n
+++ /dev/null
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memccpy.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/memccpy.c,v 1.7 2009/02/03 17:58:20 danger Exp $");
-
-#include <string.h>
-
-void *
-memccpy(void *t, const void *f, int c, size_t n)
-{
-
- if (n) {
- unsigned char *tp = t;
- const unsigned char *fp = f;
- unsigned char uc = c;
- do {
- if ((*tp++ = *fp++) == uc)
- return (tp);
- } while (--n != 0);
- }
- return (0);
-}
+++ /dev/null
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memchr.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/memchr.c,v 1.8 2009/02/07 19:34:44 imp Exp $");
-
-#include <string.h>
-
-void *
-memchr(const void *s, int c, size_t n)
-{
- if (n != 0) {
- const unsigned char *p = s;
-
- do {
- if (*p++ == (unsigned char)c)
- return ((void *)(p - 1));
- } while (--n != 0);
- }
- return (NULL);
-}
+++ /dev/null
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memcmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/memcmp.c,v 1.6 2009/02/03 17:58:20 danger Exp $");
-
-#include <string.h>
-
-/*
- * Compare memory regions.
- */
-int
-memcmp(const void *s1, const void *s2, size_t n)
-{
- if (n != 0) {
- const unsigned char *p1 = s1, *p2 = s2;
-
- do {
- if (*p1++ != *p2++)
- return (*--p1 - *--p2);
- } while (--n != 0);
- }
- return (0);
-}
.In string.h
.Ft void *
.Fo memcpy
-.Fa "void *restrict s1"
-.Fa "const void *restrict s2"
+.Fa "void *restrict dst"
+.Fa "const void *restrict src"
.Fa "size_t n"
.Fc
.Sh DESCRIPTION
copies
.Fa n
bytes from memory area
-.Fa s2
+.Fa src
to memory area
-.Fa s1 .
+.Fa dst .
If
-.Fa s1
+.Fa dst
and
-.Fa s2
+.Fa src
overlap, behavior is undefined.
Applications in which
-.Fa s1
+.Fa dst
and
-.Fa s2
+.Fa src
might overlap should use
.Xr memmove 3
instead.
.Fn memcpy
function
returns the original value of
-.Fa s1 .
+.Fa dst .
.Sh SEE ALSO
.Xr bcopy 3 ,
.Xr memccpy 3 ,
+++ /dev/null
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#define MEMCOPY
-#include "bcopy.c"
.Sh SYNOPSIS
.In string.h
.Ft void *
-.Fo memmove
-.Fa "void *s1"
-.Fa "const void *s2"
-.Fa "size_t n"
-.Fc
+.Fn memmove "void *dst" "const void *src" "size_t len"
.Sh DESCRIPTION
The
.Fn memmove
function
copies
-.Fa n
+.Fa len
bytes from string
-.Fa s2
+.Fa src
to string
-.Fa s1 .
+.Fa dst .
The two strings may overlap;
the copy is always done in a non-destructive manner.
.Sh RETURN VALUES
The
.Fn memmove
function returns the original value of
-.Fa s1 .
+.Fa dst .
.Sh SEE ALSO
.Xr bcopy 3 ,
.Xr memccpy 3 ,
+++ /dev/null
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#define MEMMOVE
-#include "bcopy.c"
.\" SUCH DAMAGE.
.\"
.\" @(#)memset.3 8.1 (Berkeley) 6/4/93
-.\" $FreeBSD: src/lib/libc/string/memset.3,v 1.9 2009/04/07 13:42:53 trasz Exp $
+.\" $FreeBSD: src/lib/libc/string/memset.3,v 1.10 2010/02/04 11:23:28 ru Exp $
.\"
.Dd June 4, 1993
.Dt MEMSET 3
.Fa len
bytes of value
.Fa c
-(converted to an unsigned char) to the byte string
+(converted to an
+.Vt "unsigned char" )
+to the string
.Fa b .
.Sh RETURN VALUES
The
.Sh SEE ALSO
.Xr bzero 3 ,
.Xr memset_pattern 3 ,
+.Xr memset_s.3 ,
.Xr swab 3 ,
.Xr wmemset 3
.Sh STANDARDS
+++ /dev/null
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Mike Hibler and Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)memset.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/memset.c,v 1.9 2007/01/09 00:28:12 imp Exp $");
-
-#include <sys/types.h>
-
-#include <limits.h>
-
-#define wsize sizeof(u_int)
-#define wmask (wsize - 1)
-
-#ifdef BZERO
-#include <strings.h>
-
-#define RETURN return
-#define VAL 0
-#define WIDEVAL 0
-
-void
-bzero(void *dst0, size_t length)
-#else
-#include <string.h>
-
-#define RETURN return (dst0)
-#define VAL c0
-#define WIDEVAL c
-
-void *
-memset(void *dst0, int c0, size_t length)
-#endif
-{
- size_t t;
-#ifndef BZERO
- u_int c;
-#endif
- u_char *dst;
-
- dst = dst0;
- /*
- * If not enough words, just fill bytes. A length >= 2 words
- * guarantees that at least one of them is `complete' after
- * any necessary alignment. For instance:
- *
- * |-----------|-----------|-----------|
- * |00|01|02|03|04|05|06|07|08|09|0A|00|
- * ^---------------------^
- * dst dst+length-1
- *
- * but we use a minimum of 3 here since the overhead of the code
- * to do word writes is substantial.
- */
- if (length < 3 * wsize) {
- while (length != 0) {
- *dst++ = VAL;
- --length;
- }
- RETURN;
- }
-
-#ifndef BZERO
- if ((c = (u_char)c0) != 0) { /* Fill the word. */
- c = (c << 8) | c; /* u_int is 16 bits. */
-#if UINT_MAX > 0xffff
- c = (c << 16) | c; /* u_int is 32 bits. */
-#endif
-#if UINT_MAX > 0xffffffff
- c = (c << 32) | c; /* u_int is 64 bits. */
-#endif
- }
-#endif
- /* Align destination by filling in bytes. */
- if ((t = (long)dst & wmask) != 0) {
- t = wsize - t;
- length -= t;
- do {
- *dst++ = VAL;
- } while (--t != 0);
- }
-
- /* Fill words. Length was >= 2*words so we know t >= 1 here. */
- t = length / wsize;
- do {
- *(u_int *)dst = WIDEVAL;
- dst += wsize;
- } while (--t != 0);
-
- /* Mop up trailing bytes, if any. */
- t = length & wmask;
- if (t != 0)
- do {
- *dst++ = VAL;
- } while (--t != 0);
- RETURN;
-}
+++ /dev/null
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/strchr.c,v 1.2 2002/03/22 21:53:19 obrien Exp $");
-
-#define STRCHR
-#include "index.c"
+++ /dev/null
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
.In string.h
.Ft char *
.Fo stpcpy
-.Fa "char *s1"
-.Fa "const char *s2"
+.Fa "char *dst"
+.Fa "const char *src"
.Fc
.Ft char *
.Fo stpncpy
-.Fa "char *restrict s1"
-.Fa "const char *restrict s2"
+.Fa "char *restrict dst"
+.Fa "const char *restrict src"
.Fa "size_t n"
.Fc
.Ft char *
.Fo strcpy
-.Fa "char *restrict s1"
-.Fa "const char *restrict s2"
+.Fa "char *restrict dst"
+.Fa "const char *restrict src"
.Fc
.Ft char *
.Fo strncpy
-.Fa "char *restrict s1"
-.Fa "const char *restrict s2"
+.Fa "char *restrict dst"
+.Fa "const char *restrict src"
.Fa "size_t n"
.Fc
.Sh DESCRIPTION
.Fn strcpy
functions
copy the string
-.Fa s2
+.Fa src
to
-.Fa s1
+.Fa dst
(including the terminating
.Ql \e0
character).
functions copy at most
.Fa n
characters from
-.Fa s2
+.Fa src
into
-.Fa s1 .
+.Fa dst .
If
-.Fa s2
+.Fa src
is less than
.Fa n
characters long,
the remainder of
-.Fa s1
+.Fa dst
is filled with
.Ql \e0
characters.
Otherwise,
-.Fa s1
+.Fa dst
is
.Em not
terminated.
.Fn strncpy
functions
return
-.Fa s1 .
+.Fa dst .
The
.Fn stpcpy
and
functions return a pointer to the terminating
.Ql \e0
character of
-.Fa s1 .
+.Fa dst .
If
.Fn stpncpy
does not terminate
-.Fa s1
+.Fa dst
with a
.Dv NUL
character, it instead returns a pointer to
-.Li s1[n]
+.Li dst[n]
(which does not necessarily refer to a valid memory location.)
.Sh EXAMPLES
The following sets
#include <errno.h>
#include <string.h>
#include <stdio.h>
+#include <stdlib.h>
#define UPREFIX "Unknown error"
return (retval);
}
+
+__private_extern__ char *__strerror_ebuf = NULL;
#else /* BUILDING_VARIANT */
__private_extern__ void __errstr(int, char *, size_t);
+
+extern char *__strerror_ebuf;
#endif /* !BUILDING_VARIANT */
char *
strerror(int num)
{
- static char ebuf[NL_TEXTMAX];
+ // Dynamically allocate a big buffer to receive the text then shrink it
+ // down to the actual size needed.
+ size_t ebufsiz = NL_TEXTMAX;
+ if (__strerror_ebuf == NULL) {
+ __strerror_ebuf = calloc(1, ebufsiz);
+ if (__strerror_ebuf == NULL) {
+ return NULL;
+ }
+ }
+
+ if (strerror_r(num, __strerror_ebuf, ebufsiz) != 0) {
#if !__DARWIN_UNIX03
- if (strerror_r(num, ebuf, sizeof(ebuf)) != 0)
- errno = EINVAL;
-#else
- (void)strerror_r(num, ebuf, sizeof(ebuf));
+ errno = EINVAL;
#endif
- return (ebuf);
+ }
+ return __strerror_ebuf;
}
+++ /dev/null
-/*
- * Copyright (c) 1989, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strncmp.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libc/string/strncmp.c,v 1.7 2009/02/03 17:58:20 danger Exp $");
-
-#include <string.h>
-
-int
-strncmp(const char *s1, const char *s2, size_t n)
-{
-
- if (n == 0)
- return (0);
- do {
- if (*s1 != *s2++)
- return (*(const unsigned char *)s1 -
- *(const unsigned char *)(s2 - 1));
- if (*s1++ == '\0')
- break;
- } while (--n != 0);
- return (0);
-}
const wchar_t *t, *t2;
wchar_t *tt = NULL, *tt2 = NULL;
wchar_t *tr = NULL, *tr2 = NULL;
- wchar_t w, w2;
struct __collate_st_info *info;
NORMALIZE_LOCALE(loc);
--- /dev/null
+.\"
+.\" Copyright (c) 2012 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Alan Barrett
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.\" $NetBSD$
+.\"
+.Dd February 21, 2012
+.Dt MEMSET_S 3
+.Os
+.Sh NAME
+.Nm memset_s
+.Nd copy a value to all bytes of a memory buffer
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.Fd "#define __STDC_WANT_LIB_EXT1__ 1
+.In string.h
+.Ft errno_t
+.Fn memset_s "void *s" "rsize_t smax" "int c" "rsize_t n"
+.Sh DESCRIPTION
+The
+.Fn memset_s
+function copies the value
+.Fa c
+(converted to an unsigned char)
+into each of the first
+.Fa n
+bytes of the memory buffer whose starting address is given by
+.Fa s .
+.Pp
+It is a runtime-consrtaints violation if
+.Fa s
+is a null pointer,
+or if either of
+.Fa smax
+or
+.Fa n
+is larger than
+.Dv RSIZE_MAX ,
+or if
+.Fa smax
+is smaller than
+.Fa n .
+If there is a runtime-constraints violation, and if
+.Fa s
+is not a null pointer,
+and if
+.Fa smax
+is not larger than
+.Dv RSIZE_MAX ,
+then, before reporting the runtime-constraints violation,
+.Fn memset_s
+copies
+.Fa smax
+bytes to the destination.
+.Pp
+In contrast to the
+.Xr memset 3
+function,
+calls to
+.Fn memset_s
+will never be
+.Dq optimised away
+by a compiler.
+This property is required by the following sentences in
+section K.3.7.4.1 of
+.St -isoC-2011 :
+.Bd -filled -offset indent
+Unlike
+.Fn memset ,
+any call to the
+.Fn memset_s
+function shall be evaluated strictly according to the rules of
+the abstract machine as described in (5.1.2.3).
+That is, any call to the
+.Fn memset_s
+function shall assume that the memory indicated by
+.Fa s
+and
+.Fa n
+may be accessible in the future and thus must contain
+the values indicated by
+.Fa c .
+.Ed
+.Sh RETURN VALUES
+The
+.Fn memset_s
+function returns zero for success, or a non-zero error code
+if there was a runtime-constraints violation.
+.Sh ERRORS
+.Fn memset_s
+returns the following error codes.
+It does not store the error code in the global
+.Va errno
+variable:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa s
+argument was a null pointer.
+.It Bq Er E2BIG
+One or both of
+.Fa smax
+or
+.Fa n
+was larger than
+.Dv RSIZE_MAX .
+.It Bq Er EOVERFLOW
+.Fa n
+was larger than
+.Fa smax .
+.El
+.
+.Sh SEE ALSO
+.Xr memset 3 .
+.Sh STANDARDS
+The
+.Fn memset_s
+function conforms to
+.St -isoC-2011 ,
+except that the
+.Fn set_constraint_handler_s
+interface is not supported.
--- /dev/null
+/* $NetBSD$ */
+
+/*-
+ * Copyright (c) 2012 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Alan Barrett
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ISO/IEC 9899:2011 section K.3.7.4.1 The memset_s function
+ */
+
+#include <sys/cdefs.h>
+
+__RCSID("$NetBSD$");
+
+#define __STDC_WANT_LIB_EXT1__ 1
+#include <errno.h>
+#include <stdint.h>
+#include <string.h>
+
+#undef memset_s /* in case it was defined as a macro */
+#undef memset /* in case it was defined as a macro */
+
+errno_t
+memset_s(void *s, rsize_t smax, int c, rsize_t n)
+{
+ errno_t err = 0;
+
+ if (s == NULL)
+ return EINVAL;
+ if (smax > RSIZE_MAX)
+ return E2BIG;
+
+ if (n > RSIZE_MAX) {
+ err = E2BIG;
+ n = smax;
+ }
+
+ if (n > smax) {
+ err = EOVERFLOW;
+ n = smax;
+ }
+
+ memset(s, c, n);
+
+ return err;
+}
--- /dev/null
+__platform_bzero _bzero
+__platform_memccpy _memccpy
+__platform_memchr _memchr
+__platform_memcmp _memcmp
+__platform_memcmp _bcmp
+__platform_memmove _memmove
+__platform_memmove _memcpy
+__platform_memset _memset
+__platform_memset_pattern16 _memset_pattern16
+__platform_memset_pattern4 _memset_pattern4
+__platform_memset_pattern8 _memset_pattern8
+__platform_strchr _strchr
+__platform_strcmp _strcmp
+__platform_strncmp _strncmp
--- /dev/null
+/*
+ * Copyright (c) 2013 Apple, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <platform/string.h>
+
+void bcopy(const void *src, void *dst, size_t n) {
+ _platform_memmove(dst, src, n);
+}
+++ /dev/null
-/*
- * Copyright (c) 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-#include <stdio.h>
-
-void
-bcopy(const void *src0, void *dst0, size_t length);
-
-void
-memset_pattern4(void *b, const void *pattern4, size_t len)
-{
- char * start = (char *)b;
- char * p = (char *)b;
- while ((start + len) - p >= 4) {
- bcopy(pattern4, p, 4);
- p += 4;
- }
- if ((start + len) - p != 0) {
- bcopy(pattern4, p, (start + len) - p);
- }
-}
-
-void
-memset_pattern8(void *b, const void *pattern8, size_t len)
-{
- char * start = (char *)b;
- char * p = (char *)b;
- while ((start + len) - p >= 8) {
- bcopy(pattern8, p, 8);
- p += 8;
- }
- if ((start + len) - p != 0) {
- bcopy(pattern8, p, (start + len) - p);
- }
-
-}
-
-void
-memset_pattern16(void *b, const void *pattern16, size_t len)
-{
- char * start = (char *)b;
- char * p = (char *)b;
- while ((start + len) - p >= 16) {
- bcopy(pattern16, p, 16);
- p += 16;
- }
- if ((start + len) - p != 0) {
- bcopy(pattern16, p, (start + len) - p);
- }
-}
if (srclen < maxlen-dstlen) {
memcpy(dst+dstlen, src, srclen+1);
} else {
- memcpy(dst+dstlen, src, maxlen-1);
- dst[dstlen+maxlen-1] = '\0';
+ memcpy(dst+dstlen, src, maxlen-dstlen-1);
+ dst[maxlen-1] = '\0';
}
return dstlen + srclen;
}
+++ /dev/null
-CIRCLEQ_ENTRY M
-CIRCLEQ_HEAD M
-CIRCLEQ_INIT M
-CIRCLEQ_INSERT_AFTER M
-CIRCLEQ_INSERT_BEFORE M
-CIRCLEQ_INSERT_HEAD M
-CIRCLEQ_INSERT_TAIL M
-CIRCLEQ_REMOVE M
-LIST_ENTRY M
-LIST_HEAD M
-LIST_INIT M
-LIST_INSERT_AFTER M
-LIST_REMOVE M
-TAILQ_ENTRY M
-TAILQ_HEAD M
-TAILQ_INIT M
-TAILQ_INSERT_AFTER M
-TAILQ_INSERT_HEAD M
-TAILQ_INSERT_TAIL M
-TAILQ_REMOVE M
-_longjmp
-_setjmp
-abort
-abs
-acl_add
-acl_canocicalize_principal
-acl_check
-acl_delete
-acl_exact_match
-acl_initialize
-acos
-acosh
-addch
-addstr
-alarm
-alloca
-alphasort
-arc
-asctime
-asin
-asinh
-assert
-atan
-atan2
-atanh
-atexit
-atof
-atoi
-atol
-bcmp
-bcopy
-bit_alloc M
-bit_clear M
-bit_decl M
-bit_ffc M
-bit_ffs M
-bit_nclear M
-bit_nset M
-bit_test M
-bitstr_size M
-box
-bsearch
-bypot
-bzero
-cabs
-calloc
-cbreak
-cbrt
-ceil
-cfgetispeed
-cfgetospeed
-cfmakeraw
-cfsetispeed
-cfsetospeed
-cfsetspeed
-cgetcap
-cgetclose
-cgetent
-cgetfirst
-cgetmatch
-cgetnext
-cgetnum
-cgetset
-cgetstr
-cgetustr
-circle
-clear
-clearerr
-clearok
-clock
-closedir
-closelog
-closepl
-clrtobot
-clrtoeol
-confstr
-cont
-copysign
-cos
-cosh
-crypt
-ctermid
-ctime
-daemon
-dbopen
-delch
-delwin
-des_cbc_cksum
-des_cbc_encrypt
-des_cipher
-des_ecb_encrypt
-des_pcbc_encrypt
-des_quad_cksum
-des_random_key
-des_read_password
-des_set_key
-des_setkey
-des_string_to_key
-devanme
-diffti8me
-dirfd
-div
-dleteln
-dn_comp
-dn_expand
-drem
-echo
-ectv
-edata
-encrypt
-end
-endfsent
-endgrent
-endhostent
-endnetent
-endnetgrent
-endprotoent
-endpwent
-endservent
-endttyent
-endusershell
-endwin
-er
-erase
-erf
-erfc
-err
-errx
-etext
-etfc
-execl
-execle
-execlp
-exect
-execv
-execvp
-exit
-exp
-expm1
-fabs
-fclose
-fctv
-fdopen
-feof
-ferror
-fflush
-ffs
-fgetc
-fgetline
-fgetln
-fgetpos
-fgets
-fileno
-finite
-floor
-flusok
-fmin MP
-fmod
-fmount MP
-fnmatch
-fopen
-fprintf
-fpurge
-fputc
-fputs
-fread
-free
-freopen
-frexp
-fropen
-fscanf
-fseek
-fsetpos
-ftell
-ftime
-fts_children
-fts_close
-fts_open
-fts_read
-fts_set
-funopen
-fwopen
-fwrite
-gamma
-gcd MP
-gctv
-getbsize
-getc
-getcap
-getch
-getchar
-getcwd
-getdiskbyname
-getenv
-getfsent
-getfsfile
-getfsspec
-getgrent
-getgrgid
-getgrnam
-getgrouplist
-gethostbyaddr
-gethostbyname
-gethostent
-gethostid
-gethostname
-getloadavg
-getmntinfo
-getmntopts
-getmode
-getnetbyaddr
-getnetbyname
-getnetent
-getnetgrent
-getopt
-getpagesize
-getpass
-getprotobyname
-getprotobynumber
-getprotoent
-getpw
-getpwent
-getpwnam
-getpwuid
-gets
-getservbyname
-getservbyport
-getservent
-getstr
-getsubopt
-gettmode
-getttyent
-getttynam
-getusershell
-getw
-getwd
-getyx
-glob
-globfree
-gmtime
-group_from_gid
-gtty
-heapsort
-herror
-htonl
-htons
-hypot
-inch
-index
-inet_addr
-inet_aton
-inet_lnaof
-inet_makeaddr
-inet_netof
-inet_network
-inet_ntoa
-infnan
-initgroups
-initscr
-initstate
-innetgr
-insch
-insetln
-insque
-invert MP
-isalnum
-isalpha
-isascii
-isatty
-isblank
-iscntrl
-isdigit
-isgraph
-isinf
-islower
-isnan
-iso_addr
-iso_ntoa
-isprint
-ispunct
-isspace
-isupper
-isxdigit
-itom MP
-j0
-j1
-jn
-krb_err_txt
-krb_get_admhst
-krb_get_cred
-krb_get_krbhst
-krb_get_lrealm
-krb_get_phost
-krb_kntoln
-krb_mk_err
-krb_mk_priv
-krb_mk_req
-krb_mk_safe
-krb_net_read
-krb_net_write
-krb_rd_err
-krb_rd_priv
-krb_rd_req
-krb_rd_safe
-krb_realmofhost
-krb_recvauth
-krb_sendauth
-krb_set_key
-krb_set_tkt_string
-kuserok
-kvm_close
-kvm_getargv
-kvm_getenvv
-kvm_geterr
-kvm_getfiles
-kvm_getloadavg
-kvm_getprocs
-kvm_nlist
-kvm_open
-kvm_openfiles
-kvm_read
-kvm_write
-label
-labs
-ldexp
-ldiv
-leaveok
-lfind
-lgamma
-line
-linemod
-link_addr
-link_ntoa
-localeconv
-localtime
-log
-log10
-log1p
-logb
-longjmp
-longjmperror
-longname
-lsearch
-m_in MP
-m_out MP
-madd MP
-malloc
-mamcpy
-mblen
-mbmb
-mbrrune
-mbrune
-mbstowcs
-mbtowc
-mcmp MP
-mdiv MP
-memccpy
-memchr
-memcmp
-memcpy
-memmove
-memset
-mergesort
-min MP
-mkstemp
-mktemp
-mktime
-modf
-moncontrol
-monstartup
-mount MP
-move
-move MP
-mpool_close
-mpool_filter
-mpool_get
-mpool_new
-mpool_open
-mpool_put
-mpool_sync
-msqrt MP
-msub MP
-mult MP
-mvcur
-newein
-nice
-nl
-nlist
-nocbreak
-noecho
-nonl
-noraw
-ns_addr
-ns_ntoa
-ntohl
-ntohs
-omin MP
-omount MP
-opendir
-openlog
-openpl
-optarg
-opterr
-optind
-optopt
-optreset
-overlay
-overwrite
-pause
-pclose
-perror
-point
-popen
-pow
-pow MP
-printf
-printw
-psignal
-putc
-putchar
-putenv
-puts
-putw
-qsort
-radixsort
-raise
-rand
-random
-raw
-rcmd
-re_comp
-re_exec
-readdir
-realloc
-realpath
-refresh
-regcomp
-regerror
-regexec
-regfree
-regsub
-remove
-remque
-res_init
-res_mkquery
-res_query
-res_send
-res_serach
-resetty
-rewind
-rewinddir
-rexec
-rindex
-rint
-rpow MP
-rresvport
-ruserok
-savetty
-scalb
-scandir
-scanf
-scanw
-scroll
-scrollok
-sdiv MP
-seekdir
-setbuf
-setbuffer
-setenv
-setfsent
-setgrent
-setgroupent
-sethostent
-sethostid
-sethostname
-setinvalidrunt
-setjmp
-setkey
-setlinebuf
-setlocale
-setlogmask
-setmode
-setnetent
-setnetgrent
-setpassent
-setprotoent
-setpwent
-setrgid
-setruid
-setrunelocale
-setservent
-setstate
-setterm
-setttyent
-setusershell
-setvbuf
-sgetrune
-sigaddset
-sigdelset
-sigemptyset
-sigfillset
-siginterrupt
-sigismember
-siglongjmp
-signal
-signgam
-sigsetjmp
-sin
-sinh
-sleep
-snprintf
-space
-sprintf
-sputrune
-sqrt
-sradixsort
-srand
-sreandom
-sscanf
-standend
-standout
-stderr
-stdin
-stdout
-strcasecmp
-strcat
-strchr
-strcmp
-strcoll
-strcpy
-strcspn
-strdup
-strerror
-strftime
-strlen
-strmode
-strncasecmp
-strncat
-strncmp
-strncpy
-strpbrk
-strrchr
-strsep
-strspc
-strspn
-strstr
-strtod
-strtok
-strtol
-strtoq
-strtoul
-strtouq
-strunvis
-strvis
-strvisx
-strxfrm
-stty
-subwin
-swab
-sys_errlist
-sys_nerr
-sys_siglist
-sys_signame
-sysconf
-sysctl
-syslog
-system
-tan
-tanh
-tcdrain
-tcflow
-tcflush
-tcgetattr
-tcgetpgrp
-tcsendbreak
-tcsetattr
-tcsetpgrp
-telldir
-tempnam
-tf_close
-tf_get_cred
-tf_get_pinst
-tf_get_pname
-tf_init
-tgetent
-tgetflag
-tgetnum
-tgetstr
-tgoto
-time
-times
-timezone
-tmpfile
-tmpnam
-toascii
-tolower
-touchline
-touchoverlap
-touchwin
-toupper
-tputs
-ttynam
-ttyslot
-tzset
-tzsetwall
-ualarm
-uname
-unctrl
-ungetc
-unsetenv
-unvis
-user_from_uid
-usleep
-utime
-va_arg M
-va_end M
-va_start M
-valloc
-verr
-verrx
-vfprintf
-vfscanf
-vis
-vlimit
-vprintf
-vscanf
-vsnprintf
-vsprintf
-vsscanf
-vsyslog
-vtimes
-vwarn
-vwarnx
-waddch
-waddstr
-warn
-warnx
-wclear
-wclreol
-wclrtobot
-wcstombs
-wctomb
-wdelch
-wdeleteln
-werase
-wgetch
-wgetstr
-winch
-winsch
-winsertln
-wmove
-wprintw
-wrefreash
-wscanw
-wstandend
-wstandout
-y0
-y1
-yn
+++ /dev/null
-creat (obsoleted by open)
-killpg
-ptarce
-setregid
-setreuid
-sigblock (obsoleted by sigprocmask)
-sigpause (obsoleted by sigsuspend)
-sigsetmask (obsoleted by sigprocmask)
-sigvec (obsoleted by sigaction)
+++ /dev/null
-madvise UNIX
-mincore UNIX
-mlock UNIX
-mprotect UNIX
-msync UNIX
-munlock UNIX
-sigpending POSIX
-sigstack compat[sigaltstack]
#include <libkern/OSThermalNotification.h>
#include <notify.h>
+#define OSThermalAlert "com.apple.system.thermalalert"
+#define OSThermalDecision "com.apple.system.thermaldecision"
#define OSThermalStatusName "com.apple.system.thermalstatus"
+#define OSThermalPressureLevelName "com.apple.system.thermalpressurelevel"
-const char * const kOSThermalNotificationName = OSThermalStatusName;
+const char * const kOSThermalNotificationAlert = OSThermalAlert;
+const char * const kOSThermalNotificationDecision = OSThermalDecision;
+const char * const kOSThermalNotificationName = OSThermalStatusName;
+const char * const kOSThermalNotificationPressureLevelName = OSThermalPressureLevelName;
static const char * const kOSThermalMitigationNames[kOSThermalMitigationCount] = {
OSThermalStatusName,
for (p = apple; p && *p; p++) {
if (strstr(*p, "stack_guard") == *p) {
__guard_from_kernel(*p);
- if (__stack_chk_guard[0] != 0)
+ bzero((void*)*p, strlen(*p));
+ if (__stack_chk_guard[0] != 0) {
return;
+ }
}
}
+++ /dev/null
-sigmask
-WCOREDUMP
-
+++ /dev/null
-accept
-access
-acct
-adjtime
-bind
-brk
-sbrk
-chdir
-fchdir
-chflags
-creat
-fchflags
-chmod
-fchmod
-chown
-fchown
-lchown
-chroot
-close
-connect
-dup
-dup2
-execve
-_exit
-fcntl
-fhopen
-flock
-fork
-fsync
-getdirentries
-getdtablesize
-getfh
-getfsstat
-getgid
-getegid
-getgroups
-getitimer
-setitimer
-getlogin
-setlogin
-getpeername
-getpgrp
-getpid
-getppid
-getpriority
-setpriority
-getrlimit
-setrlimit
-getrusage
-getsockname
-getsockopt
-setsockopt
-gettimeofday
-settimeofday
-getuid
-geteuid
-ioctl
-kill
-killpg
-link
-listen
-lseek
-madvise
-mincore
-mkdir
-mkfifo
-mknod
-mlock
-munlock
-mmap
-mount
-unmount
-mprotect
-msync
-munmap
-nfsclnt
-nfssvc
-open
-pathconf
-fpathconf
-pipe
-profil
-pthread_kill
-pthread_sigmask
-ptrace
-quotactl
-read
-readv
-readlink
-reboot
-recv
-recvfrom
-recvmsg
-rename
-revoke
-rmdir
-select
-send
-sendto
-sendmsg
-setgroups
-setpgid
-setpgrp
-setregid
-setreuid
-setsid
-setuid
-seteuid
-setgid
-setegid
-shutdown
-sigaction
-sigaltstack
-sigblock
-sigpause
-sigpending
-sigprocmask
-sigreturn
-sigsetmask
-sigstack
-sigsuspend
-sigvec
-sigwait
-socket
-socketpair
-stat
-lstat
-fstat
-statfs
-fstatfs
-swapon
-symlink
-sync
-syscall
-__syscall
-truncate
-ftruncate
-umask
-unlink
-utimes
-vfork
-wait
-waitpid
-wait3
-wait4
-waitid
-write
-writev
* __libc_init() is called from libSystem_initializer()
*/
+#include <limits.h>
#include <stdint.h>
-#include <pthread.h>
-#include <pthread_machdep.h>
+#include <string.h>
#include <machine/cpu_capabilities.h>
+#include <TargetConditionals.h>
+#if TARGET_IPHONE_SIMULATOR
+extern void __chk_init(void);
+extern void __xlocale_init(void);
+
+void
+_libc_sim_init(void) {
+ __chk_init();
+ __xlocale_init();
+}
+
+#else /* TARGET_IPHONE_SIMULATOR */
struct ProgramVars; /* forward reference */
extern void _program_vars_init(const struct ProgramVars *vars);
extern void _libc_fork_init(void (*prepare)(void), void (*parent)(void), void (*child)(void));
-extern void _init_clock_port();
-extern pthread_lock_t _malloc_lock;
+extern void _init_clock_port(void);
+extern void __chk_init(void);
extern void __xlocale_init(void);
-extern void __pthread_pfz_setup(const char *apple[]);
extern void __guard_setup(const char *apple[]);
-extern void __malloc_entropy_setup(const char *apple[]);
-extern int usenew_impl;
-
-__private_extern__ uintptr_t commpage_pfz_base;
-
-#ifdef PR_5243343
-/* 5243343 - temporary hack to detect if we are running the conformance test */
-#include <stdlib.h>
-__private_extern__ int PR_5243343_flag = 0;
-#endif /* PR_5243343 */
-__private_extern__ int __pthread_lock_debug = 0;
-__private_extern__ int __pthread_lock_old = 0;
-
void
__libc_init(const struct ProgramVars *vars, void (*atfork_prepare)(void), void (*atfork_parent)(void), void (*atfork_child)(void), const char *apple[])
{
_program_vars_init(vars);
_libc_fork_init(atfork_prepare, atfork_parent, atfork_child);
- LOCK_INIT(_malloc_lock);
_init_clock_port();
+ __chk_init();
__xlocale_init();
__guard_setup(apple);
- __pthread_pfz_setup(apple);
- __malloc_entropy_setup(apple);
-
-
-#ifdef PR_5243343
- /* 5243343 - temporary hack to detect if we are running the conformance test */
- if(getenv("TET_EXECUTE"))
- PR_5243343_flag = 1;
-#endif /* PR_5243343 */
-#if defined(__i386__) || defined(__x86_64__)
- if(getenv("__PTHREAD_LOCK_DEBUG__"))
- __pthread_lock_debug = 1;
- if(getenv("__PTHREAD_LOCK_OLD__")) {
- __pthread_lock_old = 1;
- usenew_impl = 0;
- }
-#endif
-
}
+#endif /* TARGET_IPHONE_SIMULATOR */
/*
* _libc_fork_child() is called from Libsystem's libSystem_atfork_child()
*/
+#include <TargetConditionals.h>
+#include "CrashReporterClient.h"
-extern void _asl_fork_child();
extern void _arc4_fork_child();
-extern void _init_clock_port();
-extern void _dirhelper_fork_child();
+#if !TARGET_IPHONE_SIMULATOR
+extern void _init_clock_port(void);
+#endif
+extern void _dirhelper_fork_child(void);
+void _libc_fork_child(void); // todo: private_extern?
void
_libc_fork_child(void)
{
- _asl_fork_child();
+ CRSetCrashLogMessage("crashed on child side of fork pre-exec");
+
_arc4_fork_child();
+#if !TARGET_IPHONE_SIMULATOR
_init_clock_port();
+#endif
_dirhelper_fork_child();
}
+++ /dev/null
-.Dd May 26, 2004
-.Dt ATOMIC 3
-.Os Darwin
-.Sh NAME
-.Nm OSAtomicAdd32 ,
-.Nm OSAtomicAdd32Barrier ,
-.Nm OSAtomicIncrement32 ,
-.Nm OSAtomicIncrement32Barrier ,
-.Nm OSAtomicDecrement32 ,
-.Nm OSAtomicDecrement32Barrier ,
-.Nm OSAtomicOr32 ,
-.Nm OSAtomicOr32Barrier ,
-.Nm OSAtomicOr32Orig ,
-.Nm OSAtomicOr32OrigBarrier ,
-.Nm OSAtomicAnd32 ,
-.Nm OSAtomicAnd32Barrier ,
-.Nm OSAtomicAnd32Orig ,
-.Nm OSAtomicAnd32OrigBarrier ,
-.Nm OSAtomicXor32 ,
-.Nm OSAtomicXor32Barrier ,
-.Nm OSAtomicXor32Orig ,
-.Nm OSAtomicXor32OrigBarrier ,
-.Nm OSAtomicAdd64 ,
-.Nm OSAtomicAdd64Barrier ,
-.Nm OSAtomicIncrement64 ,
-.Nm OSAtomicIncrement64Barrier ,
-.Nm OSAtomicDecrement64 ,
-.Nm OSAtomicDecrement64Barrier ,
-.Nm OSAtomicCompareAndSwapInt ,
-.Nm OSAtomicCompareAndSwapIntBarrier ,
-.Nm OSAtomicCompareAndSwapLong ,
-.Nm OSAtomicCompareAndSwapLongBarrier ,
-.Nm OSAtomicCompareAndSwapPtr ,
-.Nm OSAtomicCompareAndSwapPtrBarrier ,
-.Nm OSAtomicCompareAndSwap32 ,
-.Nm OSAtomicCompareAndSwap32Barrier ,
-.Nm OSAtomicCompareAndSwap64 ,
-.Nm OSAtomicCompareAndSwap64Barrier ,
-.Nm OSAtomicTestAndSet ,
-.Nm OSAtomicTestAndSetBarrier ,
-.Nm OSAtomicTestAndClear ,
-.Nm OSAtomicTestAndClearBarrier ,
-.Nm OSSpinLockTry ,
-.Nm OSSpinLockLock ,
-.Nm OSSpinLockUnlock ,
-.Nm OSAtomicEnqueue ,
-.Nm OSAtomicDequeue
-.Nd atomic add, increment, decrement, or, and, xor, compare and swap, test and set, test and clear, spinlocks, and lockless queues
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In libkern/OSAtomic.h
-.Ft int32_t
-.Fn OSAtomicAdd32 "int32_t theAmount" "volatile int32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicAdd32Barrier "int32_t theAmount" "volatile int32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicIncrement32 "volatile int32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicIncrement32Barrier "volatile int32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicDecrement32 "volatile int32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicDecrement32Barrier "volatile int32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicOr32 "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicOr32Barrier "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicAnd32 "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicAnd32Barrier "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicXor32 "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicXor32Barrier "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicOr32Orig "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicOr32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicAnd32Orig "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicAnd32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicXor32Orig "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int32_t
-.Fn OSAtomicXor32OrigBarrier "uint32_t theMask" "volatile uint32_t *theValue"
-.Ft int64_t
-.Fn OSAtomicAdd64 "int64_t theAmount" "volatile int64_t *theValue"
-.Ft int64_t
-.Fn OSAtomicAdd64Barrier "int64_t theAmount" "volatile int64_t *theValue"
-.Ft int64_t
-.Fn OSAtomicIncrement64 "volatile int64_t *theValue"
-.Ft int64_t
-.Fn OSAtomicIncrement64Barrier "volatile int64_t *theValue"
-.Ft int64_t
-.Fn OSAtomicDecrement64 "volatile int64_t *theValue"
-.Ft int64_t
-.Fn OSAtomicDecrement64Barrier "volatile int64_t *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwapInt "int oldValue" "int newValue" "volatile int *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwapIntBarrier "int oldValue" "int newValue" "volatile int *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwapLong "long oldValue" "long newValue" "volatile long *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwapLongBarrier "long oldValue" "long newValue" "volatile long *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwapPtr "void* oldValue" "void* newValue" "void* volatile *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwapPtrBarrier "void* oldValue" "void* newValue" "void* volatile *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwap32 "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwap32Barrier "int32_t oldValue" "int32_t newValue" "volatile int32_t *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwap64 "int64_t oldValue" "int64_t newValue" "volatile int64_t *theValue"
-.Ft bool
-.Fn OSAtomicCompareAndSwap64Barrier "int64_t oldValue" "int64_t newValue" "volatile int64_t *theValue"
-.Ft bool
-.Fn OSAtomicTestAndSet "uint32_t n" "volatile void *theAddress"
-.Ft bool
-.Fn OSAtomicTestAndSetBarrier "uint32_t n" "volatile void *theAddress"
-.Ft bool
-.Fn OSAtomicTestAndClear "uint32_t n" "volatile void *theAddress"
-.Ft bool
-.Fn OSAtomicTestAndClearBarrier "uint32_t n" "volatile void *theAddress"
-.Ft bool
-.Fn OSSpinLockTry "OSSpinLock *lock"
-.Ft void
-.Fn OSSpinLockLock "OSSpinLock *lock"
-.Ft void
-.Fn OSSpinLockUnlock "OSSpinLock *lock"
-.Ft void
-.Fn OSAtomicEnqueue "OSQueueHead *list" "void *new" "size_t offset"
-.Ft void*
-.Fn OSAtomicDequeue "OSQueueHead *list" "size_t offset"
-.Sh DESCRIPTION
-These functions are thread and multiprocessor safe. For each function, there
-is a version that does and another that does not incorporate a memory barrier.
-Barriers strictly order memory access on a weakly-ordered
-architecture such as PPC. All loads and stores executed in sequential program
-order before the barrier will complete before any load or store executed after
-the barrier. On a uniprocessor, the barrier operation is typically a nop.
-On a multiprocessor, the barrier can be quite expensive.
-.Pp
-Most code will want to use the barrier functions to ensure that memory shared
-between threads is properly synchronized. For example, if you want to initialize
-a shared data structure and then atomically increment a variable to indicate
-that the initialization is complete, then you must use OSAtomicIncrement32Barrier()
-to ensure that the stores to your data structure complete before the atomic add.
-Likewise, the consumer of that data structure must use OSAtomicDecrement32Barrier(),
-in order to ensure that their loads of the structure are not executed before
-the atomic decrement. On the other hand,
-if you are simply incrementing a global counter, then it is safe and potentially much
-faster to use OSAtomicIncrement32(). If you are unsure which version to use, prefer
-the barrier variants as they are safer.
-.Pp
-The logical (and, or, xor) and bit test operations are layered on top of the
-.Fn OSAtomicCompareAndSwap
-primitives. There are four versions of each logical operation, depending on whether
-or not there is a barrier, and whether the return value is the result of the
-operation (eg,
-.Fn OSAtomicOr32
-) or the original value before the operation (eg,
-.Fn OSAtomicOr32Orig
-).
-.Pp
-The memory address
-.Fa theValue
-must be naturally aligned, ie 32-bit aligned for 32-bit operations and 64-bit
-aligned for 64-bit operations.
-.Pp
-The 64-bit operations are not implemented for 32-bit processes on PPC platforms.
-.Pp
-The
-.Fn OSAtomicCompareAndSwap
-operations compare
-.Fa oldValue
-to
-.Fa *theValue ,
-and set
-.Fa *theValue
-to
-.Fa newValue
-if the comparison is equal. The comparison and assignment
-occur as one atomic operation.
-.Pp
-.Fn OSAtomicTestAndSet
-and
-.Fn OSAtomicTestAndClear
-operate on bit (0x80 >> (
-.Fa n
-& 7)) of byte ((char*)
-.Fa theAddress
-+ (
-.Fa n
->> 3)). They set the named bit to either 1 or 0, respectively.
-.Fa theAddress
-need not be aligned.
-.Pp
-The routines
-.Fn OSAtomicEnqueue
-and
-.Fn OSAtomicDequeue
-operate on singly linked LIFO queues. Ie, a dequeue operation will return the
-most recently enqueued element, or NULL if the list is empty. The operations
-are lockless, and barriers are used as necessary to permit thread-safe access to
-the queue element.
-.Fa offset
-is the offset in bytes to the link field in the queue element. For example:
-.Bd -literal -offset indent
- typedef struct elem {
- long data1;
- struct elem *link;
- int data2;
- } elem_t;
-
- elem_t fred, mary, *p;
-
- OSQueueHead q = OS_ATOMIC_QUEUE_INIT;
-
- OSAtomicEnqueue( &q, &fred, offsetof(elem_t,link) );
- OSAtomicEnqueue( &q, &mary, offsetof(elem_t,link) );
-
- p = OSAtomicDequeue( &q, offsetof(elem_t,link) );
-
-.Ed
-In this example, the call of
-.Fn OSAtomicDequeue
-will return a ptr to mary.
-.Sh RETURN VALUES
-The arithmetic operations return the new value, after the operation has been performed.
-The boolean operations come in two styles, one of which returns the new value, and one
-of which (the "Orig" versions) returns the old.
-The compare-and-swap operations return true if the comparison was equal, ie if the swap occured.
-The bit test and set/clear operations return the original value of the bit.
-The dequeue operation returns the most recently enqueued element, or NULL if the list in empty.
-.Sh SEE ALSO
-.Xr spinlock 3 ,
-.Xr barrier 3
-.Sh HISTORY
-Most of these functions first appeared in Mac OS 10.4 (Tiger). The "Orig" forms of the
-boolean operations, the "int", "long" and "ptr" forms of compare-and-swap, and lockless
-enqueue/dequeue first appeared in Mac OS 10.5 (Leopard).
+++ /dev/null
-.Dd May 26, 2004
-.Dt BARRIER 3
-.Os Darwin
-.Sh NAME
-.Nm OSMemoryBarrier
-.Nd memory barrier to order loads and stores
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In libkern/OSAtomic.h
-.Ft void
-.Fn OSMemoryBarrier "void"
-.Sh DESCRIPTION
-.Fn OSMemoryBarrier
-strictly orders memory accesses in a weakly ordered memory model such as with PowerPC,
-by creating a barrier. All loads and stores executed in sequential program order before
-the barrier will complete with respect to the memory coherence mechanism, before any
-load or store executed after the barrier. Used with an atomic operation, the barrier
-can be used to create custom synchronization protocols as an alternative to the
-spinlock or queue/dequeue operations. Note that this barrier does not order uncached loads
-and stores. On a uniprocessor, the barrier operation is typically optimized into a nop.
-.Sh SEE ALSO
-.Xr atomic 3 ,
-.Xr spinlock 3
+++ /dev/null
-.Dd September 21, 2006
-.Dt CACHE 3
-.Os Darwin
-.Sh NAME
-.Nm sys_cache_control ,
-.Nm sys_icache_invalidate ,
-.Nm sys_dcache_flush
-.Nd cache control
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In libkern/OSCacheControl.h
-.Ft int
-.Fn sys_cache_control "int function" "void *start" "size_t len"
-.Ft void
-.Fn sys_icache_invalidate "void *start" "size_t len"
-.Ft void
-.Fn sys_dcache_flush "void *start" "size_t len"
-.Sh DESCRIPTION
-.Pp
-These functions operate on every cache line containing one of the
-.Fa len
-bytes of memory pointed to by
-.Fa start .
-Normally the operations apply to every
-processor in the system, but the exact semantics of these
-operations is platform dependent. They should be used with caution.
-.Pp
-.Fn sys_cache_control
-performs the operation specified by
-.Fa function .
-Refer to the header file for a list of currently supported functions.
-.Pp
-.Fn sys_icache_invalidate
-prepares memory for execution, typically by invalidating the instruction
-cache for the indicated range. This should be called
-after writing machine instructions to memory, and before
-executing them. On IA32 processors this function is a NOP, because
-their instruction caches are coherent.
-.Pp
-.Fn sys_dcache_flush
-writes modified data cache lines to main memory,
-and then invalidates all lines in the range being operated on.
-It can be useful when dealing with cache incoherent
-devices or DMA.
-.Sh RETURN VALUES
-.Fn sys_cache_control
-returns zero on success, ENOTSUP if
-.Fa function
-is not valid.
-.Sh SEE ALSO
-.Xr atomic 3 ,
-.Xr barrier 3
-.Sh HISTORY
-These functions first appeared in Mac OS 10.5 (Leopard).
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <sys/ucontext.h>
-#include <errno.h>
-
-/* stubs for ppc64 and i386, until real support is available */
-int getcontext(ucontext_t *u) { errno = ENOTSUP; return -1; }
-void makecontext(ucontext_t *u, void (*f)(void), int a, ...) {}
-int setcontext(const ucontext_t *u) { errno = ENOTSUP; return -1; }
-int swapcontext(ucontext_t * __restrict u1, const ucontext_t * __restrict u2) { errno = ENOTSUP; return -1; }
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
- */
-/*
- * The world-renowned global variable
- */
-#include <pthread_internals.h>
-
-#undef errno
-extern int errno;
-int *__error(void) {
- pthread_t self = pthread_self();
- /* If we're not a detached pthread, just return the global errno */
- if ((self == (pthread_t)0) || (self->sig != _PTHREAD_SIG)) {
- return &errno;
- }
- return &self->err_no;
-}
-
-int cthread_errno(void) {
- return *__error();
-}
-
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
+#include <TargetConditionals.h>
+#if TARGET_IPHONE_SIMULATOR
+extern pid_t (*_host_fork)(void);
+#else
extern pid_t __fork(void);
-extern void _cthread_fork_prepare();
-extern void _cthread_fork_parent();
-extern void _cthread_fork_child();
+#endif
static void (*_libSystem_atfork_prepare)(void) = 0;
static void (*_libSystem_atfork_parent)(void) = 0;
static void (*_libSystem_atfork_child)(void) = 0;
-__private_extern__ void _libc_fork_init(void (*prepare)(void), void (*parent)(void), void (*child)(void))
+#if !TARGET_IPHONE_SIMULATOR
+__private_extern__
+#endif
+void _libc_fork_init(void (*prepare)(void), void (*parent)(void), void (*child)(void))
{
_libSystem_atfork_prepare = prepare;
_libSystem_atfork_parent = parent;
// Reader beware: this __fork() call is yet another wrapper around the actual syscall
// and lives inside libsyscall. The fork syscall needs some cuddling by asm before it's
// allowed to see the big wide C world.
+#if TARGET_IPHONE_SIMULATOR
+ // _host_fork is yet another layer of wrapping that lives in the simulator's libSystem
+ ret = _host_fork();
+#else
ret = __fork();
+#endif
if (-1 == ret)
{
// __fork already set errno for us
+++ /dev/null
-.Dd July 18, 2006
-.Dt getiopolicy_np 3
-.Os
-.Sh NAME
-.Nm getiopolicy_np, setiopolicy_np
-.Nd manipulate the I/O policy of a process or thread
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In sys/resource.h
-.Ft int
-.Fn getiopolicy_np "int iotype" "int scope"
-.Ft int
-.Fn setiopolicy_np "int iotype" "int scope" "int policy"
-.Sh DESCRIPTION
-The
-.Fn getiopolicy_np
-and
-.Fn setiopolicy_np
-functions are provided to get or set the I/O policy of the current process
-or the current thread. The policy of the I/O of the given type
-.Fa iotype
-can be get or set for the given
-.Fa scope .
-.Pp
-The I/O type is specified in the argument
-.Fa iotype .
-The currently supported I/O type is
-.Dv IOPOL_TYPE_DISK ,
-which means the I/O policy for I/Os to local disks can be get or set. I/Os to
-local disks are I/Os sent to the media without going through a network,
-including I/Os to internal and external hard drives, optical media in internal
-and external drives, flash drives, floppy disks, ram disks, and mounted disk
-images which reside on these media, but not including remote volumes mounted
-through networks (AFP, SMB, NFS, etc) or disk images residing on remote volumes.
-.Pp
-The scope that the I/O policy takes effect is specified in the argument
-.Fa scope
-as follows:
-.Bl -tag -width IOPOL_SCOPE_PROCESS
-.It IOPOL_SCOPE_PROCESS
-The I/O policy of all I/Os issued by the current process is get or set.
-.It IOPOL_SCOPE_THREAD
-The I/O policy of all I/Os issued by the current thread is get or set.
-.El
-.Pp
-In
-.Fn getiopolicy_np ,
-the I/O policy of the given I/O type and scope is returned. In
-.Fn setiopolicy_np ,
-the argument
-.Fa policy
-is an integer which contains the new I/O policy to be set for the given I/O
-type and scope. The I/O policy can have the following values:
-.Bl -tag -width IOPOL_PASSIVEXX
-.It IOPOL_DEFAULT
-This is the default I/O policy for the first process and every new created thread.
-.It IOPOL_NORMAL
-I/Os with NORMAL policy are called NORMAL I/Os. They are handled by the
-system using best-effort.
-.It IOPOL_THROTTLE
-I/Os with THROTTLE policy are called THROTTLE I/Os. If a THROTTLE I/O request
-occurs within a small time window (usually a fraction of a second) of another
-NORMAL I/O request, the thread that issues the THROTTLE I/O is forced to sleep
-for a certain interval. This slows down the thread that issues the THROTTLE I/O
-so that NORMAL I/Os can utilize most of the disk I/O bandwidth.
-Furthermore, a NORMAL I/O request may bypass a previously issued THROTTLE I/O
-request in kernel or driver queues and be sent to the device first.
-In some circumstances, very large THROTTLE I/O requests will be broken
-into smaller requests which are then issued serially.
-.It IOPOL_PASSIVE
-The PASSIVE I/Os are a special type of NORMAL I/O that are processed the same as
-NORMAL I/Os but are ignored by the THROTTLE I/Os so that the threads issuing
-THROTTLE I/Os are not slowed down by PASSIVE I/Os. The PASSIVE I/O policy is
-useful for server type applications. The I/Os generated by these applications
-are called passive I/Os because these I/Os are caused directly or indirectly by
-the I/O requests they receive from client applications. For example, when an
-image file is mounted by DiskImages, DiskImages generate passive I/Os.
-DiskImages should mark these I/Os using the PASSIVE I/O policy so that when
-client applications that issue THROTTLE I/Os access the volume managed by
-DiskImages, these client applications will not be slowed down by the I/Os
-generated by DiskImages.
-.El
-.Pp
-The I/O policy of a new created process is inherited from its parent
-process. The I/O policy of an I/O request depends on the I/O policy of
-both the current thread and the current process. If the I/O policy of the
-current thread is IOPOL_DEFAULT, the I/O policy of the current process is
-used; if the I/O policy of the current thread is not IOPOL_DEFAULT, the
-I/O policy of the current thread overrides the I/O policy of the current
-process; if the I/O policy of the current process is IOPOL_DEFAULT, the
-policy of I/Os issued by this process is NORMAL. For example, given the
-following thread and process I/O policy in the first two columns, the I/O
-policy of all I/Os issued by the thread is given in the third column:
-.Bl -column "Process I/O ScopeXXX" "Thread I/O ScopeXXX" "I/O Policy" -offset indent
-.It Sy "Process I/O Policy Thread I/O Policy I/O Policy"
-.It "DEFAULT DEFAULT NORMAL"
-.It "DEFAULT PASSIVE PASSIVE"
-.It "THROTTLE DEFAULT THROTTLE"
-.It "THROTTLE PASSIVE PASSIVE"
-.It "PASSIVE NORMAL NORMAL"
-.El
-.Pp
-The thread or process with THROTTLE I/O policy enabled may be slowed down when
-it issues reads, but will not be slowed down when it issues writes.
-If it issues far more writes than reads (e.g., an application
-downloading large amounts of data through the network), these writes compete with the
-normal I/Os of other processes and may have an adverse effect on the I/O
-throughput or latency of those processes.
-.Pp
-.Sh RETURN VALUES
-The
-.Fn getiopolicy_np
-call returns the I/O policy of the given I/O type and scope. If error
-happens, -1 is returned. The
-.Fn setiopolicy_np
-call returns 0 if there is no error, or -1 if there is an error. When error
-happens, the error code is stored in the external variable
-.Fa errno .
-.Sh ERRORS
-.Fn Getiopolicy_np
-and
-.Fn setiopolicy_np
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Io_type or scope is not one of the values defined in this manual.
-.El
-.Pp
-In addition to the errors indicated above,
-.Fn setiopolicy_np
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-Policy is not one of the values defined in this manual.
-.El
-.Sh NOTES
-The thread or process with THROTTLE I/O policy enabled will be generally
-prevented from having an adverse effect on the throughput or latency of
-the normal I/Os of other processes.
-However, there are a few considerations that users of the THROTTLE I/O policy should keep in mind:
-.Pp
-Consider using the
-.Dv F_NOCACHE
-.Xr fcntl 2
-command to prevent caching when using the THROTTLE I/O policy.
-This will reduce contention for available caches with NORMAL I/O.
-.Pp
-Large read requests will automatically be broken up into smaller requests
-to avoid stalling NORMAL I/O requests.
-However, due to the consistency guarantees provided to contiguous writes,
-this can not be done automatically for large writes.
-If a thread or process with THROTTLE I/O policy enabled will be issuing
-large writes, consider the use of the
-.Dv F_SINGLE_WRITER
-.Xr fcntl 2
-command.
-This will indicate to the system that there is only one thread writing to
-the file and allow automatic division of large writes.
-.Pp
-Write-heavy THROTTLE I/O workloads may fill a drive’s track (write) cache.
-Subsequent NORMAL I/O writes must then wait for enough of the track cache
-to be flushed before they can continue.
-If the writes issued as THROTTLE I/O are small and not contiguous, many
-seeks may be incurred before space is available for a subsequent NORMAL
-I/O write.
-Issuers of THROTTLE I/O should attempt to issue their writes sequentially
-or to locations in a single small area of the drive (i.e. different
-positions in the same file) to ensure good spacial locality.
-.Pp
-The
-.Dv F_FULLFSYNC
-.Xr fcntl 2
-command can cause very long system-wide IO stalls.
-Users of THROTTLE I/O should issue this command only if absolutely necessary.
-.Sh SEE ALSO
-.Xr nice 3 ,
-.Xr getpriority 2 ,
-.Xr setpriority 2 ,
-.Xr fcntl 2 ,
-.Xr open 2 ,
-.Xr renice 8
-.Sh HISTORY
-The
-.Fn getiopolicy_np
-and
-.Fn setiopolicy_np
-function call first appeared in Mac OS X 10.5 (Leopard) .
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-#include <errno.h>
-#include <sys/resource.h>
-
-extern int __iopolicysys(int, struct _iopol_param_t *);
-
-int
-getiopolicy_np(int iotype, int scope)
-{
- int policy, error;
- struct _iopol_param_t iop_param;
-
- if (iotype != IOPOL_TYPE_DISK ||
- (scope != IOPOL_SCOPE_PROCESS && scope != IOPOL_SCOPE_THREAD)) {
- errno = EINVAL;
- policy = -1;
- goto exit;
- }
-
- iop_param.iop_scope = scope;
- iop_param.iop_iotype = iotype;
- error = __iopolicysys(IOPOL_CMD_GET, &iop_param);
- if (error != 0) {
- errno = error;
- policy = -1;
- goto exit;
- }
-
- policy = iop_param.iop_policy;
-
- exit:
- return policy;
-}
-
-int
-setiopolicy_np(int iotype, int scope, int policy)
-{
- /* kernel validates the indiv values, no need to repeat it */
- struct _iopol_param_t iop_param;
-
- iop_param.iop_scope = scope;
- iop_param.iop_iotype = iotype;
- iop_param.iop_policy = policy;
-
- return( __iopolicysys(IOPOL_CMD_SET, &iop_param));
-}
/*
- * Copyright (c) 2006-2008 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2006-2012 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* [SPN] Support for _POSIX_SPAWN
*/
-#include <sys/types.h> /* for user_size_t */
#include <spawn.h>
#include <spawn_private.h>
#include <sys/spawn_internal.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h> /* for OPEN_MAX, PATH_MAX */
-#include <stddef.h> /* for offsetof() */
#include <string.h> /* for strlcpy() */
#include <paths.h> /* for _PATH_DEFPATH */
#include <sys/stat.h> /* for struct stat */
-#include <mach/port.h>
-#include <mach/exception_types.h>
-
-#if TARGET_OS_EMBEDDED
-#include <sys/kern_memorystatus.h>
-#endif
-
-/*
- * posix_spawnattr_init
- *
- * Description: Initialize a spawn attributes object attr with default values
- *
- * Parameters: attr The spawn attributes object to be
- * initialized
- *
- * Returns: 0 Success
- * ENOMEM Insufficient memory exists to
- * initialize the spawn attributes object.
- *
- * Note: As an implementation detail, the externally visibily type
- * posix_spawnattr_t is defined to be a void *, and initialization
- * involves allocation of a memory object. Subsequent changes to
- * the spawn attributes may result in reallocation under the
- * covers.
- *
- * Reinitialization of an already initialized spawn attributes
- * object will result in memory being leaked. Because spawn
- * attributes are not required to be used in conjunction with a
- * static initializer, there is no way to distinguish a spawn
- * attribute with stack garbage from one that's been initialized.
- * This is arguably an API design error.
- */
-int
-posix_spawnattr_init(posix_spawnattr_t *attr)
-{
- _posix_spawnattr_t *psattrp = (_posix_spawnattr_t *)attr;
- int err = 0;
-
- if ((*psattrp = (_posix_spawnattr_t)malloc(sizeof(struct _posix_spawnattr))) == NULL) {
- err = ENOMEM;
- } else {
-
- /*
- * The default value of this attribute shall be as if no
- * flags were set
- */
- (*psattrp)->psa_flags = 0;
-
- /*
- * The default value of this attribute shall be an empty
- * signal set
- */
- (*psattrp)->psa_sigdefault = 0;
-
- /* The default value of this attribute is unspecified */
- (*psattrp)->psa_sigmask = 0;
-
- /* The default value of this attribute shall be zero */
- (*psattrp)->psa_pgroup = 0; /* doesn't matter */
-
- /* Default is no binary preferences, i.e. use normal grading */
- memset((*psattrp)->psa_binprefs, 0,
- sizeof((*psattrp)->psa_binprefs));
-
- /* Default is no port actions to take */
- (*psattrp)->psa_ports = NULL;
-
- /*
- * The default value of this attribute shall be an no
- * process control on resource starvation
- */
- (*psattrp)->psa_pcontrol = 0;
-
- /*
- * The default value of this attribute shall be an no
- * process control on resource starvation
- */
- (*psattrp)->psa_apptype = 0;
-
-#if TARGET_OS_EMBEDDED
- /* Jetsam related */
- (*psattrp)->psa_jetsam_flags = 0;
- (*psattrp)->psa_priority = DEFAULT_JETSAM_PRIORITY;
- (*psattrp)->psa_high_water_mark = -1;
-#endif
-
- /* Default is no CPU usage monitor active. */
- (*psattrp)->psa_cpumonitor_percent = 0;
- (*psattrp)->psa_cpumonitor_interval = 0;
- }
-
- return (err);
-}
-
-
-/*
- * posix_spawnattr_destroy
- *
- * Description: Destroy a spawn attributes object that was previously
- * initialized via posix_spawnattr_init() by freeing any
- * memory associated with it and setting it to an invalid value.
- *
- * Parameters: attr The spawn attributes object to be
- * destroyed.
- *
- * Returns: 0 Success
- *
- * Notes: The destroyed spawn attribute results in the void * pointer
- * being set to NULL; subsequent use without reinitialization
- * will result in explicit program failure (rather than merely
- * "undefined behaviour").
- *
- * NOTIMP: Allowed failures (checking NOT required):
- * EINVAL The value specified by attr is invalid.
- */
-static int posix_spawn_destroyportactions_np(posix_spawnattr_t *);
-
-int
-posix_spawnattr_destroy(posix_spawnattr_t *attr)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- posix_spawn_destroyportactions_np(attr);
-
- free(psattr);
- *attr = NULL;
-
- return (0);
-}
-
-
-/*
- * posix_spawnattr_setflags
- *
- * Description: Set the spawn flags attribute for the spawn attribute object
- * referred to by 'attr'.
- *
- * Parameters: attr The spawn attributes object whose flags
- * are to be set
- * flags The flags value to set
- *
- * Returns: 0 Success
- *
- * NOTIMP: Allowed failures (checking NOT required):
- * EINVAL The value specified by attr is invalid.
- * EINVAL The value of the attribute being set is not valid.
- */
-int
-posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- psattr->psa_flags = flags;
-
- return (0);
-}
-
-
-/*
- * posix_spawnattr_getflags
- *
- * Description: Retrieve the spawn attributes flag for the spawn attributes
- * object referenced by 'attr' and place them in the memory
- * location referenced by 'flagsp'
- *
- * Parameters: attr The spawn attributes object whose flags
- * are to be retrieved
- * flagsp A pointer to a short value to receive
- * the flags
- *
- * Returns: 0 Success
- *
- * Implicit Returns:
- * *flagps (modified) The flags value from the spawn
- * attributes object
- *
- * NOTIMP: Allowed failures (checking NOT required):
- * EINVAL The value specified by attr is invalid.
- * EINVAL The value of the attribute being set is not valid.
- */
-int
-posix_spawnattr_getflags(const posix_spawnattr_t * __restrict attr,
- short * __restrict flagsp)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- *flagsp = psattr->psa_flags;
-
- return (0);
-}
-
-
-/*
- * posix_spawnattr_getsigdefault
- *
- * Description: Retrieve the set of signals to be set to default according to
- * the spawn attribute value referenced by 'attr' and place the
- * result into the memory containing the sigset_t referenced by
- * 'sigdefault'
- *
- * Parameters: attr The spawn attributes object whose
- * signal set for default signals is to
- * be retrieved
- * sigdefault A pointer to the sigset_t to receive
- * the signal set
- *
- * Returns: 0 Success
- *
- * Implicit Returns:
- * *sigdefault (modified) The signal set of signals to default
- * from the spawn attributes object
- */
-int
-posix_spawnattr_getsigdefault(const posix_spawnattr_t * __restrict attr,
- sigset_t * __restrict sigdefault)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- *sigdefault = psattr->psa_sigdefault;
-
- return (0);
-}
-
-
-/*
- * posix_spawnattr_getpgroup
- *
- * Description: Obtain the value of the spawn process group attribute from the
- * spawn attributes object referenced by 'attr' and place the
- * results in the memory location referenced by 'pgroup'
- *
- * Parameters: attr The spawn attributes object whose
- * process group information is to be
- * retrieved
- * pgroup A pointer to the pid_t to receive the
- * process group
- *
- * Returns: 0 Success
- *
- * Implicit Returns:
- * *pgroup (modified) The process group information from the
- * spawn attributes object
- */
-int
-posix_spawnattr_getpgroup(const posix_spawnattr_t * __restrict attr,
- pid_t * __restrict pgroup)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- *pgroup = psattr->psa_pgroup;
-
- return (0);
-}
-
-
-/*
- * posix_spawnattr_getsigmask
- *
- * Description: Obtain the value of the spawn signal mask attribute from the
- * spawn attributes object referenced by 'attr' and place the
- * result into the memory containing the sigset_t referenced by
- * 'sigmask'
- *
- * Parameters: attr The spawn attributes object whose
- * signal set for masked signals is to
- * be retrieved
- * sigmask A pointer to the sigset_t to receive
- * the signal set
- *
- * Returns: 0 Success
- *
- * Implicit Returns:
- * *sigmask (modified) The signal set of signals to mask
- * from the spawn attributes object
- */
-int
-posix_spawnattr_getsigmask(const posix_spawnattr_t * __restrict attr,
- sigset_t * __restrict sigmask)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- *sigmask = psattr->psa_sigmask;
-
- return (0);
-}
-
-/*
- * posix_spawnattr_getbinpref_np
- *
- * Description: Obtain the value of the spawn binary preferences attribute from
- * the spawn attributes object referenced by 'attr' and place the
- * result into the memory referenced by 'pref'.
- *
- * Parameters: attr The spawn attributes object whose
- * binary preferences are to be retrieved
- * count The size of the cpu_type_t array
- * pref An array of cpu types
- * ocount The actual number copied
- *
- * Returns: 0 No binary preferences found
- * > 0 The number of cpu types (less than
- * count) copied over from 'attr'.
- *
- * Implicit Returns:
- * *pref (modified) The binary preferences array
- * from the spawn attributes object
- */
-int
-posix_spawnattr_getbinpref_np(const posix_spawnattr_t * __restrict attr,
- size_t count, cpu_type_t *pref, size_t * __restrict ocount)
-{
- _posix_spawnattr_t psattr;
- int i = 0;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- for (i = 0; i < count && i < 4; i++) {
- pref[i] = psattr->psa_binprefs[i];
- }
-
- if (ocount)
- *ocount = i;
- return 0;
-}
-
-
-/*
- * posix_spawnattr_getpcontrol_np
- *
- * Description: Retrieve the process control property set default according to
- * the spawn attribute value referenced by 'attr' and place the
- * result into the memory containing the control referenced by
- * 'pcontrol'
- *
- * Parameters: attr The spawn attributes object whose
- * signal set for default signals is to
- * be retrieved
- * pcontrol A pointer to an int to receive
- * the process control info
- *
- * Returns: 0 Success
- *
- * Implicit Returns:
- * *pcontrol (modified) The signal set of signals to default
- * from the spawn attributes object
- */
-int
-posix_spawnattr_getpcontrol_np(const posix_spawnattr_t * __restrict attr,
- int * __restrict pcontrol)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- *pcontrol = psattr->psa_pcontrol;
-
- return (0);
-}
-
-/*
- * posix_spawnattr_getapptype_np
- *
- * Description: Retrieve the process specific behaviors and app launch typea
- * spawn attribute value referenced by 'attr' and place the
- * result into the memory containing the control referenced by
- * 'apptype'
- *
- * Parameters: attr The spawn attributes object whose
- * signal set for default signals is to
- * be retrieved
- * apptype A pointer to an int to receive
- * the process control info
- *
- * Returns: 0 Success
- *
- * Implicit Returns:
- * *pcontrol (modified) The signal set of signals to default
- * from the spawn attributes object
- */
-int
-posix_spawnattr_getapptype_np(const posix_spawnattr_t * __restrict attr,
- int * __restrict apptype)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- *apptype = psattr->psa_apptype;
-
- return (0);
-}
-
-/*
- * posix_spawnattr_setsigdefault
- *
- * Description: Set the set of signals to be set to default for the spawn
- * attribute value referenced by 'attr' from the memory
- * containing the sigset_t referenced by 'sigdefault'
- *
- * Parameters: attr The spawn attributes object whose
- * signal set for default signals is to
- * be set
- * sigdefault A pointer to the sigset_t from which to
- * obtain the signal set
- *
- * Returns: 0 Success
- */
-int
-posix_spawnattr_setsigdefault(posix_spawnattr_t * __restrict attr,
- const sigset_t * __restrict sigdefault)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- psattr->psa_sigdefault = *sigdefault;
-
- return (0);
-}
-
-
-/*
- * posix_spawnattr_setpgroup
- *
- * Description: Set the value of the spawn process group attribute for the
- * spawn attributes object referenced by 'attr' from the value
- * of 'pgroup'
- *
- * Parameters: attr The spawn attributes object for which
- * the process group information is to be
- * set
- * pgroup The process group to set
- *
- * Returns: 0 Success
- */
-int
-posix_spawnattr_setpgroup(posix_spawnattr_t * attr, pid_t pgroup)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- psattr->psa_pgroup = pgroup;
-
- return (0);
-}
-
-
-/*
- * posix_spawnattr_setsigmask
- *
- * Description: Set the set of signals to be masked for the spawn attribute
- * value referenced by 'attr' from the memory containing the
- * sigset_t referenced by 'sigmask'
- *
- * Parameters: attr The spawn attributes object whose
- * signal set for masked signals is to
- * be set
- * sigmask A pointer to the sigset_t from which to
- * obtain the signal set
- *
- * Returns: 0 Success
- */
-int
-posix_spawnattr_setsigmask(posix_spawnattr_t * __restrict attr,
- const sigset_t * __restrict sigmask)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- psattr->psa_sigmask = *sigmask;
-
- return (0);
-}
-
-
-/*
- * posix_spawnattr_setbinpref_np
- *
- * Description: Set the universal binary preferences for the spawn attribute
- * value referenced by 'attr' from the memory containing the
- * cpu_type_t array referenced by 'pref', size of 'count'
- *
- * Parameters: attr The spawn attributes object whose
- * binary preferences are to be set
- * count Size of the array pointed to by 'pref'
- * pref cpu_type_t array of binary preferences
- * ocount The actual number copied
- *
- * Returns: 0 No preferences copied
- * > 0 Number of preferences copied
- *
- * Note: The posix_spawnattr_t currently only holds four cpu_type_t's.
- * If the caller provides more preferences than this limit, they
- * will be ignored, as reflected in the return value.
- */
-int
-posix_spawnattr_setbinpref_np(posix_spawnattr_t * __restrict attr,
- size_t count, cpu_type_t *pref, size_t * __restrict ocount)
-{
- _posix_spawnattr_t psattr;
- int i = 0;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- for (i = 0; i < count && i < 4; i++) {
- psattr->psa_binprefs[i] = pref[i];
- }
-
- /* return number of binprefs copied over */
- if (ocount)
- *ocount = i;
- return 0;
-}
-
-
-/*
- * posix_spawnattr_setpcontrol_np
- *
- * Description: Set the process control property according to
- * attribute value referenced by 'attr' from the memory
- * containing the int value 'pcontrol'
- *
- * Parameters: attr The spawn attributes object whose
- * signal set for default signals is to
- * be set
- * pcontrol An int value of the process control info
- *
- * Returns: 0 Success
- */
-int
-posix_spawnattr_setpcontrol_np(posix_spawnattr_t * __restrict attr,
- const int pcontrol)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- psattr->psa_pcontrol = pcontrol;
-
- return (0);
-}
-
-
-/*
- * posix_spawnattr_setapptype_np
- *
- * Description: Set the process specific behaviors and app launch type
- * attribute value referenced by 'attr' from the memory
- * containing the int value 'apptype'
- *
- * Parameters: attr The spawn attributes object whose
- * signal set for default signals is to
- * be set
- * apptype An int value of the apptype info
- *
- * Returns: 0 Success
- */
-int
-posix_spawnattr_setapptype_np(posix_spawnattr_t * __restrict attr,
- const int apptype)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- psattr->psa_apptype = apptype;
-
- return (0);
-}
-
-/*
- * posix_spawn_createportactions_np
- * Description: create a new posix_spawn_port_actions struct and link
- * it into the posix_spawnattr.
- */
-static int
-posix_spawn_createportactions_np(posix_spawnattr_t *attr)
-{
- _posix_spawnattr_t psattr;
- _posix_spawn_port_actions_t acts;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- acts = (_posix_spawn_port_actions_t)malloc(PS_PORT_ACTIONS_SIZE(2));
- if (acts == NULL)
- return ENOMEM;
-
- acts->pspa_alloc = 2;
- acts->pspa_count = 0;
-
- psattr->psa_ports = acts;
- return 0;
-}
-
-/*
- * posix_spawn_growportactions_np
- * Description: Enlarge the size of portactions if necessary
- */
-static int
-posix_spawn_growportactions_np(posix_spawnattr_t *attr)
-{
- _posix_spawnattr_t psattr;
- _posix_spawn_port_actions_t acts;
- int newnum;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- acts = psattr->psa_ports;
- if (acts == NULL)
- return EINVAL;
-
- /* Double number of port actions allocated for */
- newnum = 2 * acts->pspa_alloc;
- acts = realloc(acts, PS_PORT_ACTIONS_SIZE(newnum));
- if (acts == NULL)
- return ENOMEM;
-
- acts->pspa_alloc = newnum;
- return 0;
-}
-
-/*
- * posix_spawn_destroyportactions_np
- * Description: clean up portactions struct in posix_spawnattr_t attr
- */
-static int
-posix_spawn_destroyportactions_np(posix_spawnattr_t *attr)
-{
- _posix_spawnattr_t psattr;
- _posix_spawn_port_actions_t acts;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- acts = psattr->psa_ports;
- if (acts == NULL)
- return EINVAL;
-
- free(acts);
- return 0;
-}
-
-
-/*
- * posix_spawnattr_setspecialport_np
- *
- * Description: Set a new value for a mach special port in the spawned task.
- *
- * Parameters: attr The spawn attributes object for the
- * new process
- * new_port The new value for the special port
- * which The particular port to be set
- * (see task_set_special_port for details)
- *
- * Returns: 0 Success
- * ENOMEM Couldn't allocate memory
- */
-int
-posix_spawnattr_setspecialport_np(
- posix_spawnattr_t *attr,
- mach_port_t new_port,
- int which)
-{
- _posix_spawnattr_t psattr;
- int err = 0;
- _ps_port_action_t *action;
- _posix_spawn_port_actions_t ports;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- ports = psattr->psa_ports;
- /* Have any port actions been created yet? */
- if (ports == NULL) {
- err = posix_spawn_createportactions_np(attr);
- if (err)
- return err;
- ports = psattr->psa_ports;
- }
-
- /* Is there enough room? */
- if (ports->pspa_alloc == ports->pspa_count) {
- err = posix_spawn_growportactions_np(attr);
- if (err)
- return err;
- }
-
- /* Add this action to next spot in array */
- action = &ports->pspa_actions[ports->pspa_count];
- action->port_type = PSPA_SPECIAL;
- action->new_port = new_port;
- action->which = which;
-
- ports->pspa_count++;
- return err;
-}
-
-/*
- * posix_spawnattr_setexceptionports_np
- *
- * Description: Set a new port for a set of exception ports in the spawned task.
- *
- * Parameters: attr The spawn attributes object for the
- * new process
- * mask A bitfield indicating which exceptions
- * to associate the port with
- * new_port The new value for the exception port
- * behavior The default behavior for the port
- * flavor The default flavor for the port
- * (see task_set_exception_ports)
- *
- * Returns: 0 Success
- */
-int
-posix_spawnattr_setexceptionports_np(
- posix_spawnattr_t *attr,
- exception_mask_t mask,
- mach_port_t new_port,
- exception_behavior_t behavior,
- thread_state_flavor_t flavor)
-{
- _posix_spawnattr_t psattr;
- int err = 0;
- _ps_port_action_t *action;
- _posix_spawn_port_actions_t ports;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- ports = psattr->psa_ports;
- /* Have any port actions been created yet? */
- if (ports == NULL) {
- err = posix_spawn_createportactions_np(attr);
- if (err)
- return err;
- ports = psattr->psa_ports;
- }
-
- /* Is there enough room? */
- if (ports->pspa_alloc == ports->pspa_count) {
- err = posix_spawn_growportactions_np(attr);
- if (err)
- return err;
- }
-
- /* Add this action to next spot in array */
- action = &ports->pspa_actions[ports->pspa_count];
- action->port_type = PSPA_EXCEPTION;
- action->mask = mask;
- action->new_port = new_port;
- action->behavior = behavior;
- action->flavor = flavor;
-
- ports->pspa_count++;
- return err;
-}
-
-/*
- * posix_spawnattr_setauditsessionport_np
- *
- * Description: Set the audit session port rights attribute in the spawned task.
- * This is used to securely set the audit session information for
- * the new task.
- *
- * Parameters: attr The spawn attributes object for the
- * new process
- * au_sessionport The audit session send port right
- *
- * Returns: 0 Success
- */
-int
-posix_spawnattr_setauditsessionport_np(
- posix_spawnattr_t *attr,
- mach_port_t au_sessionport)
-{
- _posix_spawnattr_t psattr;
- int err = 0;
- _ps_port_action_t *action;
- _posix_spawn_port_actions_t ports;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
- ports = psattr->psa_ports;
- /* Have any port actions been created yet? */
- if (ports == NULL) {
- err = posix_spawn_createportactions_np(attr);
- if (err)
- return err;
- ports = psattr->psa_ports;
- }
-
- /* Is there enough room? */
- if (ports->pspa_alloc == ports->pspa_count) {
- err = posix_spawn_growportactions_np(attr);
- if (err)
- return err;
- }
-
- /* Add this action to next spot in array */
- action = &ports->pspa_actions[ports->pspa_count];
- action->port_type = PSPA_AU_SESSION;
- action->new_port = au_sessionport;
-
- ports->pspa_count++;
- return err;
-}
-
-
-/*
- * posix_spawn_file_actions_init
- *
- * Description: Initialize a spawn file actions object attr with default values
- *
- * Parameters: file_actions The spawn file actions object to be
- * initialized
- *
- * Returns: 0 Success
- * ENOMEM Insufficient memory exists to
- * initialize the spawn file actions
- * object.
- *
- * Note: As an implementation detail, the externally visibily type
- * posix_spawn_file_actions_t is defined to be a void *, and
- * initialization involves allocation of a memory object.
- * Subsequent changes to the spawn file actions may result in
- * reallocation under the covers.
- *
- * Reinitialization of an already initialized spawn file actions
- * object will result in memory being leaked. Because spawn
- * file actions are not required to be used in conjunction with a
- * static initializer, there is no way to distinguish a spawn
- * file actions with stack garbage from one that's been
- * initialized. This is arguably an API design error.
- */
-int
-posix_spawn_file_actions_init(posix_spawn_file_actions_t *file_actions)
-{
- _posix_spawn_file_actions_t *psactsp = (_posix_spawn_file_actions_t *)file_actions;
- int err = 0;
-
- if ((*psactsp = (_posix_spawn_file_actions_t)malloc(PSF_ACTIONS_SIZE(PSF_ACTIONS_INIT_COUNT))) == NULL) {
- err = ENOMEM;
- } else {
- (*psactsp)->psfa_act_alloc = PSF_ACTIONS_INIT_COUNT;
- (*psactsp)->psfa_act_count = 0;
- }
-
- return (err);
-}
-
-
-/*
- * posix_spawn_file_actions_destroy
- *
- * Description: Destroy a spawn file actions object that was previously
- * initialized via posix_spawn_file_actions_init() by freeing any
- * memory associated with it and setting it to an invalid value.
- *
- * Parameters: attr The spawn file actions object to be
- * destroyed.
- *
- * Returns: 0 Success
- *
- * Notes: The destroyed spawn file actions results in the void * pointer
- * being set to NULL; subsequent use without reinitialization
- * will result in explicit program failure (rather than merely
- * "undefined behaviour").
- *
- * NOTIMP: Allowed failures (checking NOT required):
- * EINVAL The value specified by file_actions is invalid.
- */
-int
-posix_spawn_file_actions_destroy(posix_spawn_file_actions_t *file_actions)
-{
- _posix_spawn_file_actions_t psacts;
-
- if (file_actions == NULL || *file_actions == NULL)
- return EINVAL;
-
- psacts = *(_posix_spawn_file_actions_t *)file_actions;
- free(psacts);
- *file_actions = NULL;
-
- return (0);
-}
-
-
-/*
- * _posix_spawn_file_actions_grow
- *
- * Description: Grow the available list of file actions associated with the
- * pointer to the structure provided; replace the contents of the
- * pointer as a side effect.
- *
- * Parameters: psactsp Pointer to _posix_spawn_file_actions_t
- * to grow
- *
- * Returns: 0 Success
- * ENOMEM Insufficient memory for operation
- *
- * Notes: This code is common to all posix_spawn_file_actions_*()
- * functions, since we use a naieve data structure implementation
- * at present. Future optimization will likely change this.
- */
-static int
-_posix_spawn_file_actions_grow(_posix_spawn_file_actions_t *psactsp)
-{
- int new_alloc = (*psactsp)->psfa_act_alloc * 2;
- _posix_spawn_file_actions_t new_psacts;
-
- /*
- * XXX may want to impose an administrative limit here; POSIX does
- * XXX not provide for an administrative error return in this case,
- * XXX so it's probably acceptable to just fail catastrophically
- * XXX instead of implementing one.
- */
- if ((new_psacts = (_posix_spawn_file_actions_t)realloc((*psactsp), PSF_ACTIONS_SIZE(new_alloc))) == NULL) {
- return (ENOMEM);
- }
- new_psacts->psfa_act_alloc = new_alloc;
- *psactsp = new_psacts;
-
- return (0);
-}
-
-
-/*
- * posix_spawn_file_actions_addopen
- *
- * Description: Add an open action to the object referenced by 'file_actions'
- * that will cause the file named by 'path' to be attempted to be
- * opened with flags 'oflag' and mode 'mode', and, if successful,
- * return as descriptor 'filedes' to the spawned process.
- *
- * Parameters: file_actions File action object to augment
- * filedes fd that open is to use
- * path path to file to open
- * oflag open file flags
- * mode open file mode
- *
- * Returns: 0 Success
- * EBADF The value specified by fildes is
- * negative or greater than or equal to
- * {OPEN_MAX}.
- * ENOMEM Insufficient memory exists to add to
- * the spawn file actions object.
- *
- * NOTIMP: Allowed failures (checking NOT required):
- * EINVAL The value specified by file_actions is invalid.
- */
-int
-posix_spawn_file_actions_addopen(
- posix_spawn_file_actions_t * __restrict file_actions,
- int filedes, const char * __restrict path, int oflag,
- mode_t mode)
-{
- _posix_spawn_file_actions_t *psactsp;
- _psfa_action_t *psfileact;
-
- if (file_actions == NULL || *file_actions == NULL)
- return EINVAL;
-
- psactsp = (_posix_spawn_file_actions_t *)file_actions;
- /* Range check; required by POSIX */
- if (filedes < 0 || filedes >= OPEN_MAX)
- return (EBADF);
-
- /* If we do not have enough slots, grow the structure */
- if ((*psactsp)->psfa_act_count == (*psactsp)->psfa_act_alloc) {
- /* need to grow file actions structure */
- if (_posix_spawn_file_actions_grow(psactsp))
- return (ENOMEM);
- }
-
- /*
- * Allocate next available slot and fill it out
- */
- psfileact = &(*psactsp)->psfa_act_acts[(*psactsp)->psfa_act_count++];
-
- psfileact->psfaa_type = PSFA_OPEN;
- psfileact->psfaa_filedes = filedes;
- psfileact->psfaa_openargs.psfao_oflag = oflag;
- psfileact->psfaa_openargs.psfao_mode = mode;
- strlcpy(psfileact->psfaa_openargs.psfao_path, path, PATH_MAX);
-
- return (0);
-}
-
-
-/*
- * posix_spawn_file_actions_addclose
- *
- * Description: Add a close action to the object referenced by 'file_actions'
- * that will cause the file referenced by 'filedes' to be
- * attempted to be closed in the spawned process.
- *
- * Parameters: file_actions File action object to augment
- * filedes fd to close
- *
- * Returns: 0 Success
- * EBADF The value specified by fildes is
- * negative or greater than or equal to
- * {OPEN_MAX}.
- * ENOMEM Insufficient memory exists to add to
- * the spawn file actions object.
- *
- * NOTIMP: Allowed failures (checking NOT required):
- * EINVAL The value specified by file_actions is invalid.
- */
-int
-posix_spawn_file_actions_addclose(posix_spawn_file_actions_t *file_actions,
- int filedes)
-{
- _posix_spawn_file_actions_t *psactsp;
- _psfa_action_t *psfileact;
-
- if (file_actions == NULL || *file_actions == NULL)
- return EINVAL;
-
- psactsp = (_posix_spawn_file_actions_t *)file_actions;
- /* Range check; required by POSIX */
- if (filedes < 0 || filedes >= OPEN_MAX)
- return (EBADF);
-
- /* If we do not have enough slots, grow the structure */
- if ((*psactsp)->psfa_act_count == (*psactsp)->psfa_act_alloc) {
- /* need to grow file actions structure */
- if (_posix_spawn_file_actions_grow(psactsp))
- return (ENOMEM);
- }
-
- /*
- * Allocate next available slot and fill it out
- */
- psfileact = &(*psactsp)->psfa_act_acts[(*psactsp)->psfa_act_count++];
-
- psfileact->psfaa_type = PSFA_CLOSE;
- psfileact->psfaa_filedes = filedes;
-
- return (0);
-}
-
-
-/*
- * posix_spawn_file_actions_adddup2
- *
- * Description: Add a dup2 action to the object referenced by 'file_actions'
- * that will cause the file referenced by 'filedes' to be
- * attempted to be dup2'ed to the descriptor 'newfiledes' in the
- * spawned process.
- *
- * Parameters: file_actions File action object to augment
- * filedes fd to dup2
- * newfiledes fd to dup2 it to
- *
- * Returns: 0 Success
- * EBADF The value specified by either fildes
- * or by newfiledes is negative or greater
- * than or equal to {OPEN_MAX}.
- * ENOMEM Insufficient memory exists to add to
- * the spawn file actions object.
- *
- * NOTIMP: Allowed failures (checking NOT required):
- * EINVAL The value specified by file_actions is invalid.
- */
-int
-posix_spawn_file_actions_adddup2(posix_spawn_file_actions_t *file_actions,
- int filedes, int newfiledes)
-{
- _posix_spawn_file_actions_t *psactsp;
- _psfa_action_t *psfileact;
-
- if (file_actions == NULL || *file_actions == NULL)
- return EINVAL;
-
- psactsp = (_posix_spawn_file_actions_t *)file_actions;
- /* Range check; required by POSIX */
- if (filedes < 0 || filedes >= OPEN_MAX ||
- newfiledes < 0 || newfiledes >= OPEN_MAX)
- return (EBADF);
-
- /* If we do not have enough slots, grow the structure */
- if ((*psactsp)->psfa_act_count == (*psactsp)->psfa_act_alloc) {
- /* need to grow file actions structure */
- if (_posix_spawn_file_actions_grow(psactsp))
- return (ENOMEM);
- }
-
- /*
- * Allocate next available slot and fill it out
- */
- psfileact = &(*psactsp)->psfa_act_acts[(*psactsp)->psfa_act_count++];
-
- psfileact->psfaa_type = PSFA_DUP2;
- psfileact->psfaa_filedes = filedes;
- psfileact->psfaa_openargs.psfao_oflag = newfiledes;
-
- return (0);
-}
-
-/*
- * posix_spawn_file_actions_addinherit_np
- *
- * Description: Add the "inherit" action to the object referenced by
- * 'file_actions' that will cause the file referenced by
- * 'filedes' to continue to be available in the spawned
- * process via the same descriptor.
- *
- * Inheritance is the normal default behaviour for
- * file descriptors across exec and spawn; but if the
- * POSIX_SPAWN_CLOEXEC_DEFAULT flag is set, the usual
- * default is reversed for the purposes of the spawn
- * invocation. Any pre-existing descriptors that
- * need to be made available to the spawned process can
- * be marked explicitly as 'inherit' via this interface.
- * Otherwise they will be automatically closed.
- *
- * Note that any descriptors created via the other file
- * actions interfaces are automatically marked as 'inherit'.
- *
- * Parameters: file_actions File action object to augment
- * filedes fd to inherit.
- *
- * Returns: 0 Success
- * EBADF The value specified by fildes is
- * negative or greater than or equal to
- * {OPEN_MAX}.
- * ENOMEM Insufficient memory exists to add to
- * the spawn file actions object.
- *
- * NOTIMP: Allowed failures (checking NOT required):
- * EINVAL The value specified by file_actions is invalid.
- */
-int
-posix_spawn_file_actions_addinherit_np(posix_spawn_file_actions_t *file_actions,
- int filedes)
-{
- _posix_spawn_file_actions_t *psactsp;
- _psfa_action_t *psfileact;
-
- if (file_actions == NULL || *file_actions == NULL)
- return (EINVAL);
-
- psactsp = (_posix_spawn_file_actions_t *)file_actions;
- /* Range check; required by POSIX */
- if (filedes < 0 || filedes >= OPEN_MAX)
- return (EBADF);
-
-#if defined(POSIX_SPAWN_CLOEXEC_DEFAULT) // TODO: delete this check
- /* If we do not have enough slots, grow the structure */
- if ((*psactsp)->psfa_act_count == (*psactsp)->psfa_act_alloc) {
- /* need to grow file actions structure */
- if (_posix_spawn_file_actions_grow(psactsp))
- return (ENOMEM);
- }
-
- /*
- * Allocate next available slot and fill it out
- */
- psfileact = &(*psactsp)->psfa_act_acts[(*psactsp)->psfa_act_count++];
-
- psfileact->psfaa_type = PSFA_INHERIT;
- psfileact->psfaa_filedes = filedes;
-#endif
- return (0);
-}
-
-int
-posix_spawnattr_setcpumonitor(posix_spawnattr_t * __restrict attr,
- uint64_t percent, uint64_t interval)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL || percent == 0 || percent > 100)
- return (EINVAL);
-
- psattr = *(_posix_spawnattr_t *)attr;
-
- psattr->psa_cpumonitor_percent = percent;
- psattr->psa_cpumonitor_interval = interval;
-
- return (0);
-}
-
-int
-posix_spawnattr_getcpumonitor(posix_spawnattr_t * __restrict attr,
- uint64_t *percent, uint64_t *interval)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return (EINVAL);
-
- psattr = *(_posix_spawnattr_t *)attr;
-
- *percent = psattr->psa_cpumonitor_percent;
- *interval = psattr->psa_cpumonitor_interval;
-
- return (0);
-}
-
-#if TARGET_OS_EMBEDDED
-/*
- * posix_spawnattr_setjetsam
- *
- * Description: Set jetsam attributes for the spawn attribute object
- * referred to by 'attr'.
- *
- * Parameters: flags The flags value to set
- * priority Relative jetsam priority
- * high_water_mark Value in pages; resident page
- * counts above this level can
- * result in termination
- *
- * Returns: 0 Success
- */
-int
-posix_spawnattr_setjetsam(posix_spawnattr_t * __restrict attr,
- short flags, int priority, int high_water_mark)
-{
- _posix_spawnattr_t psattr;
-
- if (attr == NULL || *attr == NULL)
- return EINVAL;
-
- psattr = *(_posix_spawnattr_t *)attr;
-
- psattr->psa_jetsam_flags = flags;
- psattr->psa_priority = priority;
- psattr->psa_high_water_mark = high_water_mark;
-
- return (0);
-}
-#endif
/*
* posix_spawnp
done:
return (err);
}
-
-
-/*
- * posix_spawn
- *
- * Description: Create a new process from the process image corresponding to
- * the supplied 'path' argument.
- *
- * Parameters: pid Pointer to pid_t to receive the
- * PID of the spawned process, if
- * successful and 'pid' != NULL
- * path Path of image file to spawn
- * file_actions spawn file actions object which
- * describes file actions to be
- * performed during the spawn
- * attrp spawn attributes object which
- * describes attributes to be
- * applied during the spawn
- * argv argument vector array; NULL
- * terminated
- * envp environment vector array; NULL
- * terminated
- *
- * Returns: 0 Success
- * !0 An errno value indicating the
- * cause of the failure to spawn
- *
- * Notes: Unlike other system calls, the return value of this system
- * call is expected to either be a 0 or an errno, rather than a
- * 0 or a -1, with the 'errno' variable being set.
- */
-extern int __posix_spawn(pid_t * __restrict, const char * __restrict,
- struct _posix_spawn_args_desc *,
- char *const argv[ __restrict], char *const envp[ __restrict]);
-
-int
-posix_spawn(pid_t * __restrict pid, const char * __restrict path,
- const posix_spawn_file_actions_t *file_actions,
- const posix_spawnattr_t * __restrict attrp,
- char *const argv[ __restrict], char *const envp[ __restrict])
-{
- int saveerrno = errno;
- int ret;
- /*
- * Only do extra work if we have file actions or attributes to push
- * down. We use a descriptor to push this information down, since we
- * want to have size information, which will let us (1) preallocate a
- * single chunk of memory for the copyin(), and (2) allow us to do a
- * single copyin() per attributes or file actions as a monlithic block.
- *
- * Note: A future implementation may attempt to do the same
- * thing for the argv/envp data, which could potentially
- * result in a performance improvement due to increased
- * kernel efficiency, even though it would mean copying
- * the data in user space.
- */
- if ((file_actions != NULL && (*file_actions != NULL) && (*(_posix_spawn_file_actions_t *)file_actions)->psfa_act_count > 0) || attrp != NULL) {
- struct _posix_spawn_args_desc ad;
-
- memset(&ad, 0, sizeof(ad));
- if (attrp != NULL && *attrp != NULL) {
- _posix_spawnattr_t psattr = *(_posix_spawnattr_t *)attrp;
- ad.attr_size = sizeof(struct _posix_spawnattr);
- ad.attrp = psattr;
-
- if (psattr->psa_ports != NULL) {
- ad.port_actions = psattr->psa_ports;
- ad.port_actions_size = PS_PORT_ACTIONS_SIZE(
- ad.port_actions->pspa_count);
- }
- }
- if (file_actions != NULL && *file_actions != NULL) {
- _posix_spawn_file_actions_t psactsp =
- *(_posix_spawn_file_actions_t *)file_actions;
-
- if (psactsp->psfa_act_count > 0) {
- ad.file_actions_size = PSF_ACTIONS_SIZE(psactsp->psfa_act_count);
- ad.file_actions = psactsp;
- }
- }
-
- ret = __posix_spawn(pid, path, &ad, argv, envp);
- } else
- ret = __posix_spawn(pid, path, NULL, argv, envp);
-
- if (ret < 0)
- ret = errno;
- errno = saveerrno;
- return ret;
-}
-
+++ /dev/null
-.\" Darwin
-.\"
-.\" Copyright (C) 2000 Jason Evans <jasone@FreeBSD.org>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice(s), this list of conditions and the following disclaimer as
-.\" the first lines of this file unmodified other than the possible
-.\" addition of one or more copyright notices.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice(s), this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
-.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
-.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_kill.3,v 1.8 2001/10/01 16:09:09 ru Exp $
-.Dd Feb 05, 2002
-.Dt PTHREAD_KILL 2
-.Os
-.Sh NAME
-.Nm pthread_kill
-.Nd send a signal to a specified thread
-.Sh SYNOPSIS
-.In signal.h
-.Ft int
-.Fn pthread_kill "pthread_t thread" "int sig"
-.Sh DESCRIPTION
-The
-.Fn pthread_kill
-function sends a signal, specified by
-.Fa sig ,
-to a thread, specified by
-.Fa thread .
-If
-.Fa sig
-is 0, error checking is performed, but no signal is actually sent.
-.Sh RETURN VALUES
-If successful,
-.Fn pthread_kill
-returns 0.
-Otherwise, an error number is returned.
-.Sh ERRORS
-.Fn pthread_kill
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-.Fa sig
-is an invalid or unsupported signal number.
-.It Bq Er ESRCH
-.Fa thread
-is an invalid thread ID.
-.El
-.Sh LEGACY SYNOPSIS
-.Fd #include <pthread.h>
-.Fd #include <signal.h>
-.Pp
-The include file
-.In pthread.h
-is necessary.
-.Sh SEE ALSO
-.Xr kill 2 ,
-.Xr pthread_self 3 ,
-.Xr raise 3 ,
-.Xr compat 5
-.Sh STANDARDS
-.Fn pthread_kill
-conforms to ISO/IEC 9945-1:1996 (``POSIX.1'')
+++ /dev/null
-.\" Copyright (C) 2000 Jason Evans <jasone@FreeBSD.org>.
-.\" All rights reserved.
-.\"
-.\" Redistribution and use in source and binary forms, with or without
-.\" modification, are permitted provided that the following conditions
-.\" are met:
-.\" 1. Redistributions of source code must retain the above copyright
-.\" notice(s), this list of conditions and the following disclaimer as
-.\" the first lines of this file unmodified other than the possible
-.\" addition of one or more copyright notices.
-.\" 2. Redistributions in binary form must reproduce the above copyright
-.\" notice(s), this list of conditions and the following disclaimer in
-.\" the documentation and/or other materials provided with the
-.\" distribution.
-.\"
-.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
-.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
-.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-.\" BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-.\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-.\" OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-.\"
-.\" $FreeBSD: src/lib/libc_r/man/pthread_sigmask.3,v 1.9 2001/10/01 16:09:09 ru Exp $
-.Dd April 27, 2000
-.Dt PTHREAD_SIGMASK 2
-.Os
-.Sh NAME
-.Nm pthread_sigmask
-.Nd examine and/or change a thread's signal mask
-.Sh SYNOPSIS
-.In signal.h
-.Ft int
-.Fo pthread_sigmask
-.Fa "int how"
-.Fa "const sigset_t *restrict set"
-.Fa "sigset_t *restrict oset"
-.Fc
-.Sh DESCRIPTION
-The
-.Fn pthread_sigmask
-function examines and/or changes the calling thread's signal mask.
-.Pp
-If
-.Fa set
-is not
-.Dv NULL ,
-it specifies a set of signals to be modified, and
-.Fa how
-specifies what to set the signal mask to:
-.Bl -tag -width SIG_UNBLOCK
-.It Dv SIG_BLOCK
-Union of the current mask and
-.Fa set .
-.It Dv SIG_UNBLOCK
-Intersection of the current mask and the complement of
-.Fa set .
-.It Dv SIG_SETMASK
-.Fa set .
-.El
-.Pp
-If
-.Fa oset
-is not NULL, the previous signal mask is stored in the location pointed to by
-.Fa oset .
-.Pp
-.Dv SIGKILL
-and
-.Dv SIGSTOP
-cannot be blocked, and will be silently ignored if included in the signal mask.
-.Sh RETURN VALUES
-If successful,
-.Fn pthread_sigmask
-returns 0.
-Otherwise, an error is returned.
-.Sh ERRORS
-.Fn pthread_sigmask
-will fail if:
-.Bl -tag -width Er
-.It Bq Er EINVAL
-.Fa how
-is not one of the defined values.
-.El
-.Sh LEGACY SYNOPSIS
-.Fd #include <pthread.h>
-.Fd #include <signal.h>
-.Pp
-The include file
-.In pthread.h
-is necessary.
-.Sh SEE ALSO
-.Xr sigaction 2 ,
-.Xr sigpending 2 ,
-.Xr sigprocmask 2 ,
-.Xr sigsuspend 2 ,
-.Xr sigsetops 3 ,
-.Xr compat 5
-.Sh STANDARDS
-.Fn pthread_sigmask
-conforms to ISO/IEC 9945-1:1996 (``POSIX.1'')
+++ /dev/null
-/*
- * Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
- *
- * This file contains global data and the size of the global data can NOT
- * change or otherwise it would make the shared library incompatable. This
- * data has been padded so new signals can be added. Also see gen/siglist.c
- */
-
-#include "sigcatch.h"
-
-/*
- * Actually declare the global data.
- */
-sigcatch_t sigcatch[PADDING] = { (sigcatch_t)0 };
-
-
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/* Copyright (c) 1992 NeXT Computer, Inc. All rights reserved.
- *
- * File: libc/m98k/sigcatch.h
- *
- * Header file for sigtramp data structures.
- */
-
-#include <sys/signal.h>
-
-/*
- * Constants
- */
-#define PADDING 50
-
-/*
- * Type definitions.
- */
-typedef void (*sigcatch_t)(int, int, struct sigcontext *);
-
-/*
- * Global data.
- */
-extern sigcatch_t sigcatch[PADDING];
+++ /dev/null
-/*
- * Copyright (c) 1999, 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
- */
-#import "sigcatch.h"
-#import <sys/types.h>
-#import <signal.h>
-#import <strings.h>
-#import <unistd.h>
-#import <ucontext.h>
-#import <mach/thread_status.h>
-
-extern int __sigreturn(ucontext_t *, int);
-
-/*
- * sigvec registers _sigtramp as the handler for any signal requiring
- * user-mode intervention. All _sigtramp does is find the real handler,
- * calls it, then sigreturn's.
- *
- * Note that the kernel saves/restores all of our register state.
- */
-
-/* On i386, i386/sys/_sigtramp.s defines this. */
-#if defined(__DYNAMIC__) && ! defined(__i386__)
-int __in_sigtramp = 0;
-#endif
-
-/* These defn should match the kernel one */
-#define UC_TRAD 1
-#define UC_FLAVOR 30
-#if defined(__ppc__) || defined(__ppc64__)
-#define UC_TRAD64 20
-#define UC_TRAD64_VEC 25
-#define UC_FLAVOR_VEC 35
-#define UC_FLAVOR64 40
-#define UC_FLAVOR64_VEC 45
-#define UC_DUAL 50
-#define UC_DUAL_VEC 55
-
- /* The following are valid mcontext sizes */
-#define UC_FLAVOR_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int))
-
-#define UC_FLAVOR_VEC_SIZE ((PPC_THREAD_STATE_COUNT + PPC_EXCEPTION_STATE_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int))
-
-#define UC_FLAVOR64_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT) * sizeof(int))
-
-#define UC_FLAVOR64_VEC_SIZE ((PPC_THREAD_STATE64_COUNT + PPC_EXCEPTION_STATE64_COUNT + PPC_FLOAT_STATE_COUNT + PPC_VECTOR_STATE_COUNT) * sizeof(int))
-#endif
-
-#define UC_SET_ALT_STACK 0x40000000
-#define UC_RESET_ALT_STACK 0x80000000
-
-#if defined(__ppc__)
-/* This routine will be replaced by an assembly soon */
-static int
-restore64_state(mcontext_t mctx, mcontext64_t mctx64, int sigstyle)
-{
- if (mctx->ss.srr0 != (unsigned int)mctx64->ss.srr0)
- return(0);
- if (mctx->ss.srr1 != (unsigned int)mctx64->ss.srr1)
- return(0);
- if (mctx->ss.r0 != (unsigned int)mctx64->ss.r0)
- return(0);
- if (mctx->ss.r1 != (unsigned int)mctx64->ss.r1)
- return(0);
- if (mctx->ss.r2 != (unsigned int)mctx64->ss.r2)
- return(0);
- if (mctx->ss.r3 != (unsigned int)mctx64->ss.r3)
- return(0);
- if (mctx->ss.r4 != (unsigned int)mctx64->ss.r4)
- return(0);
- if (mctx->ss.r5 != (unsigned int)mctx64->ss.r5)
- return(0);
- if (mctx->ss.r6 != (unsigned int)mctx64->ss.r6)
- return(0);
- if (mctx->ss.r7 != (unsigned int)mctx64->ss.r7)
- return(0);
- if (mctx->ss.r8 != (unsigned int)mctx64->ss.r8)
- return(0);
- if (mctx->ss.r9 != (unsigned int)mctx64->ss.r9)
- return(0);
- if (mctx->ss.r10 != (unsigned int)mctx64->ss.r10)
- return(0);
- if (mctx->ss.r11 != (unsigned int)mctx64->ss.r11)
- return(0);
- if (mctx->ss.r12 != (unsigned int)mctx64->ss.r12)
- return(0);
- if (mctx->ss.r13 != (unsigned int)mctx64->ss.r13)
- return(0);
- if (mctx->ss.r14 != (unsigned int)mctx64->ss.r14)
- return(0);
- if (mctx->ss.r15 != (unsigned int)mctx64->ss.r15)
- return(0);
- if (mctx->ss.r16 != (unsigned int)mctx64->ss.r16)
- return(0);
- if (mctx->ss.r17 != (unsigned int)mctx64->ss.r17)
- return(0);
- if (mctx->ss.r18 != (unsigned int)mctx64->ss.r18)
- return(0);
- if (mctx->ss.r19 != (unsigned int)mctx64->ss.r19)
- return(0);
- if (mctx->ss.r20 != (unsigned int)mctx64->ss.r20)
- return(0);
- if (mctx->ss.r21 != (unsigned int)mctx64->ss.r21)
- return(0);
- if (mctx->ss.r22 != (unsigned int)mctx64->ss.r22)
- return(0);
- if (mctx->ss.r23 != (unsigned int)mctx64->ss.r23)
- return(0);
- if (mctx->ss.r24 != (unsigned int)mctx64->ss.r24)
- return(0);
- if (mctx->ss.r25 != (unsigned int)mctx64->ss.r25)
- return(0);
- if (mctx->ss.r26 != (unsigned int)mctx64->ss.r26)
- return(0);
- if (mctx->ss.r27 != (unsigned int)mctx64->ss.r27)
- return(0);
- if (mctx->ss.r28 != (unsigned int)mctx64->ss.r28)
- return(0);
- if (mctx->ss.r29 != (unsigned int)mctx64->ss.r29)
- return(0);
- if (mctx->ss.r30 != (unsigned int)mctx64->ss.r30)
- return(0);
- if (mctx->ss.r31 != (unsigned int)mctx64->ss.r31)
- return(0);
-
- if (mctx->ss.cr != mctx64->ss.cr)
- return(0);
- if (mctx->ss.xer != (unsigned int)mctx64->ss.xer)
- return(0);
- if (mctx->ss.lr != (unsigned int)mctx64->ss.lr)
- return(0);
- if (mctx->ss.ctr != (unsigned int)mctx64->ss.ctr)
- return(0);
-
- if (bcmp(&mctx->fs, &mctx64->fs, (PPC_FLOAT_STATE_COUNT * sizeof(int))))
- return(0);
- if ((sigstyle == UC_DUAL_VEC) && bcmp(&mctx->vs, &mctx64->vs, (PPC_VECTOR_STATE_COUNT * sizeof(int))))
- return(0);
-
- return(1);
-
-}
-
-/* This routine is called from ppc/sys/_sigtramp.s on return from
- sa_handler. */
-
-void
-__finish_sigtramp(
- ucontext_t *uctx,
- int sigstyle
-) {
- int ctxstyle = UC_FLAVOR;
- mcontext_t mctx;
- mcontext64_t mctx64;
-
- if ((sigstyle == UC_DUAL) || (sigstyle == UC_DUAL_VEC)) {
- mctx = uctx->uc_mcontext;
- mctx64 = (mcontext64_t)((char *)(uctx->uc_mcontext) + sizeof(struct mcontext));
- /* restore 64bit state ? */
- if (restore64_state(mctx, mctx64, sigstyle)) {
- uctx->uc_mcontext = (void *)mctx64;
- if (sigstyle == UC_DUAL) {
- uctx->uc_mcsize = UC_FLAVOR64_SIZE;
- ctxstyle = UC_FLAVOR64;
- } else {
- uctx->uc_mcsize = UC_FLAVOR64_VEC_SIZE;
- ctxstyle = UC_FLAVOR64_VEC;
- }
- } else {
- if (sigstyle == UC_DUAL)
- ctxstyle = UC_FLAVOR;
- else
- ctxstyle = UC_FLAVOR_VEC;
- }
- } else
- ctxstyle = sigstyle;
-
-#if defined(__DYNAMIC__)
- __in_sigtramp--;
-#endif
-
- __sigreturn (uctx, ctxstyle);
-}
-
-#endif /* ppc */
-
-/*
- * Reset the kernel's idea of the use of an alternate stack; this is used by
- * both longjmp() and siglongjmp(). Nothing other than this reset is needed,
- * since restoring the registers and other operations that would normally be
- * done by sigreturn() are handled in user space, so we do not pass a user
- * context (in PPC, a user context is not the same as a jmpbuf mcontext, due
- * to having more than one set of registers, etc., for the various 32/64 etc.
- * contexts)..
- */
-void
-_sigunaltstack(int set)
-{
- /* sigreturn(uctx, ctxstyle); */
- /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */
- __sigreturn (NULL, (set == SS_ONSTACK) ? UC_SET_ALT_STACK : UC_RESET_ALT_STACK);
-}
-
-/* On these architectures, _sigtramp is implemented in assembly to
- ensure it matches its DWARF unwind information. */
-#if ! defined (__ppc__) && ! defined (__ppc64__) && ! defined (__i386__) \
- && ! defined (__x86_64__)
-
-void
-_sigtramp(
- union __sigaction_u __sigaction_u,
- int sigstyle,
- int sig,
- siginfo_t *sinfo,
- ucontext_t *uctx
-) {
- int ctxstyle = UC_FLAVOR;
-
-#if defined(__DYNAMIC__)
- __in_sigtramp++;
-#endif
-
- if (sigstyle == UC_TRAD)
- sa_handler(sig);
- else {
- sa_sigaction(sig, sinfo, uctx);
- }
-
-#if defined(__DYNAMIC__)
- __in_sigtramp--;
-#endif
- /* sigreturn(uctx, ctxstyle); */
- /* syscall (SYS_SIGRETURN, uctx, ctxstyle); */
- __sigreturn (uctx, ctxstyle);
-}
-
-#endif /* not ppc nor ppc64 nor i386 nor x86_64 */
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-/*
- * File: slot_name.c
- * Author: Avadis Tevanian, Jr.
- *
- * Copyright (C) 1987, Avadis Tevanian, Jr.
- *
- * Convert machine slot values to human readable strings.
- *
- * HISTORY
- * 26-Jan-88 Mary Thompson (mrt) at Carnegie Mellon
- * added case for CUP_SUBTYPE_RT_APC
- *
- * 28-Feb-87 Avadis Tevanian (avie) at Carnegie-Mellon University
- * Created.
- *
- */
-
-#include <mach-o/arch.h>
-#include <stddef.h>
-
-/*
- * Convert the specified cpu_type/cpu_subtype pair to their
- * human readable form.
- */
-void slot_name(cpu_type, cpu_subtype, cpu_name, cpu_subname)
- cpu_type_t cpu_type;
- cpu_subtype_t cpu_subtype;
- char **cpu_name, **cpu_subname;
-{
- register char *name = "Unknown CPU";
- register char *subname = "";
- const NXArchInfo *ai = NXGetArchInfoFromCpuType(cpu_type, cpu_subtype);
- if (ai != NULL) {
- name = (char *)ai->name;
- subname = (char *)ai->description;
- }
- *cpu_name = name;
- *cpu_subname = subname;
-}
+++ /dev/null
-.Dd May 26, 2004
-.Dt SPINLOCK 3
-.Os Darwin
-.Sh NAME
-.Nm OSSpinLockTry ,
-.Nm OSSpinLockLock ,
-.Nm OSSpinLockUnlock
-.Nd atomic spin lock synchronization primitives
-.Sh LIBRARY
-.Lb libc
-.Sh SYNOPSIS
-.In libkern/OSAtomic.h
-.Ft bool
-.Fn OSSpinLockTry "OSSpinLock *lock"
-.Ft void
-.Fn OSSpinLockLock "OSSpinLock *lock"
-.Ft void
-.Fn OSSpinLockUnlock "OSSpinLock *lock"
-.Sh DESCRIPTION
-Spin locks are a simple, fast, thread-safe synchronization primitive that is
-suitable in situations where contention is expected to be low. The spinlock
-operations use memory barriers to synchronize access to shared memory protected
-by the lock. Preemption is possible while the lock is held.
-.Pp
-.Ft OSSpinLock
-is an integer type. The convention is that unlocked is zero, and locked is nonzero.
-Locks must be naturally aligned and cannot be in cache-inhibited memory.
-.Pp
-.Fn OSSpinLockLock
-will spin if the lock is already held, but employs various strategies to back off,
-making it immune to most priority-inversion livelocks. But because it can spin, it
-may be inefficient in some situations.
-.Pp
-.Fn OSSpinLockTry
-immediately returns false if the lock was held, true if it took the lock.
-It does not spin.
-.Pp
-.Fn OSSpinLockUnlock
-unconditionally unlocks the lock by zeroing it.
-.Sh RETURN VALUES
-.Fn OSSpinLockTry
-returns true if it took the lock, false if the lock was already held.
-.Sh SEE ALSO
-.Xr atomic 3 ,
-.Xr barrier 3
+++ /dev/null
-/*
- * Copyright (c) 1999, 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Mach Operating System
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * HISTORY
- * 22-July-93 Blaine Garst
- * fixed kernel cache set up of cproc info
- *
- * 05-April-90 Morris Meyer (mmeyer) at NeXT
- * Fixed bug in cproc_fork_child() where the first cproc would
- * try doing a msg_rpc() with an invalid reply port.
- *
- */
-
-/*
- * cprocs.c - by Eric Cooper
- *
- * Implementation of cprocs (lightweight processes)
- * and primitive synchronization operations.
- */
-#include "pthread_internals.h"
-#include <stdlib.h>
-#include "cthreads.h"
-#include "cthread_internals.h"
-#include <mach/message.h>
-
-/*
- * C Threads imports:
- */
-extern void stack_init();
-extern void alloc_stack(), _dealloc_stack();
-
-/*
- * Mach imports:
- */
-extern mach_port_t mach_thread_self();
-extern boolean_t swtch_pri();
-
-#ifdef CTHREADS_DEBUG
-private void
-print_cproc(p)
- cproc_t p;
-{
- char *s;
-
- switch (p->state) {
- case CPROC_RUNNING:
- s = "";
- break;
- case CPROC_SPINNING:
- s = "+";
- break;
- case CPROC_BLOCKED:
- s = "*";
- break;
- default:
- ASSERT(SHOULDNT_HAPPEN);
- }
- printf(" %x(%s)%s",
- p->id,
- cthread_name(p->incarnation), s);
-}
-
-private void
-print_cproc_queue(name, queue)
- const char * name;
- cthread_queue_t queue;
-{
- printf("[%s] %s:", cthread_name(cthread_self()), name);
- cthread_queue_map(queue, cproc_t, print_cproc);
- printf("\n");
-}
-#endif /* CTHREADS_DEBUG */
-
-#ifdef CTHREADS_DEBUG
-private cproc_t cprocs = NO_CPROC; /* linked list of cprocs */
-
-private void
-print_all_cprocs()
-{
- cproc_t p;
-
- printf("[%s] cprocs:", cthread_name(cthread_self()));
- for (p = cprocs; p != NO_CPROC; p = p->link)
- print_cproc(p);
- printf("\n");
-}
-#endif /* CTHREADS_DEBUG */
-
-/*
- * Routines for supporting fork() of multi-threaded programs.
- */
-
-void
-_cproc_fork_child()
-/*
- * Called in the child after a fork(). Resets cproc data structures to
- * coincide with the reality that we now have a single cproc and cthread.
- */
-{
- pthread_t pself;
-
- pself = pthread_self();
- pself->reply_port = MACH_PORT_NULL;
-}
-
-/*
- * Support for a per-thread UNIX errno.
- */
-
-#undef errno
-extern int errno;
-extern int *__error(void);
-extern int __pthread_canceled(int);
-
-void
-cthread_set_errno_self(int error, int nocancel)
-{
- int *ep = __error();
- extern int __unix_conforming;
- pthread_t self = NULL;
- int check_cancel = __unix_conforming && !nocancel;
-
- if (check_cancel && ((error & 0xff) == EINTR) && (__pthread_canceled(0) == 0)) {
- self = pthread_self();
- if (self != NULL)
- self->cancel_error = error;
- pthread_exit(PTHREAD_CANCELED);
- }
-
- if (ep != &errno) {
- *ep = error;
- }
-
- errno = error;
-}
-
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Mach Operating System
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-
-/*
- * HISTORY
- * 08-Mar-90 Avadis Tevanian, Jr. (avie) at NeXT
- * Added errno field to cproc structure.
- *
- */
-
-/*
- * cthread_internals.h - by Eric Cooper
- *
- * Private definitions for the C Threads implementation.
- *
- * The cproc structure is used for different implementations
- * of the basic schedulable units that execute cthreads.
- *
- * MTHREAD MACH threads; single address space,
- * kernel-mode preemptive scheduling
- */
-#include <assert.h>
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-
-/*
- * Low-level thread implementation.
- * This structure must agree with struct ur_cthread in cthreads.h
- */
-typedef struct cproc {
- struct cproc *next; /* for lock, condition, and ready queues */
- struct cproc *incarnation; /* for cthread_self() */
- int state;
- mach_port_t reply_port; /* for mig_get_reply_port() */
-
- mach_port_t wait_port;
-
- int id;
- struct cproc *link; /* so all cprocs can be found
- after a fork() */
- int flags;
-
- unsigned int stack_base;
- unsigned int stack_size;
- int error;
-
-} *cproc_t;
-
-#define NO_CPROC ((cproc_t) 0)
-#define cproc_self() ((cproc_t) ur_cthread_self())
-extern void cthread_set_self(cproc_t p);
-
-/*
- * Possible cproc states.
- */
-#define CPROC_RUNNING 0
-#define CPROC_SPINNING 1
-#define CPROC_BLOCKED 2
-
-/*
- * The cproc flag bits.
- */
-#define CPROC_INITIAL_STACK 0x1
-#define CPROC_NOCACHE_THREAD /* Don't try to cache this cthread on exit */
-
-/*
- * C Threads imports:
- */
-#ifdef __STRICT_BSD__
-extern char *malloc();
-#endif /* __STRICT_BSD__ */
-
-/*
- * Mach imports:
- */
-extern void mach_error();
-
-/*
- * C library imports:
- */
-#ifdef __STRICT_BSD__
-extern exit();
-#else
-#include <stdlib.h>
-#endif /* __STRICT_BSD__ */
-
-/*
- * Macro for MACH kernel calls.
- */
-#ifndef MACH_CALL
-#define MACH_CALL(expr, ret) { \
- if (((ret) = (expr)) != KERN_SUCCESS) { \
- mach_error(#expr, (ret)); \
- assert(0); \
- } \
-}
-#endif
-
-/*
- * Debugging support.
- */
-#ifdef CTHREADS_DEBUG
-
-#define private
-#define TRACE(x) if (cthread_debug) x ; else
-extern int cthread_debug;
-
-/*
- * C library imports:
- */
-#include <stdio.h>
-#include <stdlib.h>
-#else /* CTHREADS_DEBUG */
-
-#define private static
-#define TRACE(x)
-
-#endif /* DEBUG */
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * cthreads.c - by Eric Cooper
- *
- * Implementation of cthread_fork, cthread_join, cthread_exit, etc.
- * HISTORY
- * 22-July-93 Blaine Garst
- * fixed association of read_thread info
- * fixed kernel cache set up of cproc info
- *
- */
-#include "pthread_internals.h"
-#include <stdlib.h>
-#include <sys/queue.h>
-#include "cthreads.h"
-#include "cthread_internals.h"
-/*
- * C Threads imports:
- */
-extern void cproc_init();
-extern thread_port_t cproc_create();
-extern void mig_init();
-extern void _pthread_set_self(pthread_t);
-
-extern void pthread_workqueue_atfork_prepare(void);
-extern void pthread_workqueue_atfork_parent(void);
-extern void pthread_workqueue_atfork_child(void);
-/*
- * Mach imports:
- */
-extern void mig_fork_child();
-
-/*
- * C library imports:
- */
-extern int _setjmp(jmp_buf env);
-extern void _longjmp(jmp_buf env, int val);
-
-/*
- * Thread status bits.
- */
-#define T_MAIN 0x1
-#define T_RETURNED 0x2
-#define T_DETACHED 0x4
-
-#ifdef CTHREADS_DEBUG
-int cthread_debug = FALSE;
-#endif /* CTHREADS_DEBUG */
-
-/*
- * Routines for supporting fork() of multi-threaded programs.
- */
-
-
-extern void _malloc_fork_prepare(), _malloc_fork_parent();
-extern void _malloc_fork_child();
-extern void fork_mach_init();
-extern void _cproc_fork_child(), _stack_fork_child();
-extern void _asl_fork_child(void);
-extern void _pthread_fork_child(pthread_t);
-extern void _pthread_fork_child_postinit();
-extern void _notify_fork_child(void);
-
-static pthread_t psaved_self = 0;
-static pthread_lock_t psaved_self_global_lock = LOCK_INITIALIZER;
-static pthread_lock_t pthread_atfork_lock = LOCK_INITIALIZER;
-struct pthread_atfork_entry {
- TAILQ_ENTRY(pthread_atfork_entry) qentry;
- void (*prepare)(void);
- void (*parent)(void);
- void (*child)(void);
-};
-static TAILQ_HEAD(pthread_atfork_queue_head, pthread_atfork_entry) pthread_atfork_queue = TAILQ_HEAD_INITIALIZER(pthread_atfork_queue);
-
-int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
-{
- struct pthread_atfork_entry *e;
-
- e = malloc(sizeof(struct pthread_atfork_entry));
- if (e == NULL)
- return (ENOMEM);
-
- e->prepare = prepare;
- e->parent = parent;
- e->child = child;
-
- _spin_lock(&pthread_atfork_lock);
- TAILQ_INSERT_TAIL(&pthread_atfork_queue, e, qentry);
- _spin_unlock(&pthread_atfork_lock);
-
- return 0;
-}
-
-void _cthread_fork_prepare()
-/*
- * Prepare cthreads library to fork() a multi-threaded program. All cthread
- * library critical section locks are acquired before a fork() and released
- * afterwards to insure no cthread data structure is left in an inconsistent
- * state in the child, which comes up with only the forking thread running.
- */
-{
- struct pthread_atfork_entry *e;
-
- _spin_lock(&pthread_atfork_lock);
-#ifdef TAILQ_FOREACH_REVERSE_LEGACY_ORDER
- TAILQ_FOREACH_REVERSE(e, &pthread_atfork_queue, qentry, pthread_atfork_queue_head)
-#else /* !TAILQ_FOREACH_REVERSE_LEGACY_ORDER */
- TAILQ_FOREACH_REVERSE(e, &pthread_atfork_queue, pthread_atfork_queue_head, qentry)
-#endif /* TAILQ_FOREACH_REVERSE_LEGACY_ORDER */
- {
- if (e->prepare != NULL)
- e->prepare();
- }
-
- _spin_lock(&psaved_self_global_lock);
- psaved_self = pthread_self();
- _spin_lock(&psaved_self->lock);
- _malloc_fork_prepare();
-
- pthread_workqueue_atfork_prepare();
-}
-
-void _cthread_fork_parent()
-/*
- * Called in the parent process after a fork syscall.
- * Releases locks acquired by cthread_fork_prepare().
- */
-{
- struct pthread_atfork_entry *e;
-
- _malloc_fork_parent();
- _spin_unlock(&psaved_self->lock);
- _spin_unlock(&psaved_self_global_lock);
-
- TAILQ_FOREACH(e, &pthread_atfork_queue, qentry) {
- if (e->parent != NULL)
- e->parent();
- }
- _spin_unlock(&pthread_atfork_lock);
-
- pthread_workqueue_atfork_parent();
-}
-
-void _cthread_fork_child()
-/*
- * Called in the child process after a fork syscall. Releases locks acquired
- * by cthread_fork_prepare(). Deallocates cthread data structures which
- * described other threads in our parent. Makes this thread the main thread.
- */
-{
- pthread_t p = psaved_self;
-
- _pthread_set_self(p);
- _spin_unlock(&psaved_self_global_lock);
- mig_fork_child();
- _malloc_fork_child();
- p->kernel_thread = mach_thread_self();
- p->reply_port = mach_reply_port();
- p->__cleanup_stack = NULL;
- p->death = MACH_PORT_NULL;
- p->joiner = NULL;
- p->detached |= _PTHREAD_CREATE_PARENT;
- _spin_unlock(&p->lock);
-
- _pthread_fork_child(p);
-}
-
-void _cthread_fork_child_postinit()
-{
- struct pthread_atfork_entry *e;
-
- __is_threaded = 0;
-
- _pthread_fork_child_postinit();
- mig_init(1); /* enable multi-threaded mig interfaces */
-
- pthread_workqueue_atfork_child();
-
- TAILQ_FOREACH(e, &pthread_atfork_queue, qentry) {
- if (e->child != NULL)
- e->child();
- }
- LOCK_INIT(pthread_atfork_lock);
-}
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Cthreads.
- */
-
-#ifndef _CTHREADS_
-#define _CTHREADS_ 1
-
-#if defined(__cplusplus)
-#define __DECLBEGIN extern "C" {
-#define __DECLEND }
-#else
-#define __DECLBEGIN
-#define __DECLEND
-#endif
-
-typedef void *any_t;
-
-/*
- * Spin locks.
- */
-__DECLBEGIN
-extern void spin_unlock(int *p);
-extern void spin_lock(int *p);
-__DECLEND
-
-#include <mach/mach_types.h>
-#include <mach/boolean.h>
-
-#ifndef MACRO_BEGIN
-
-#define NEVER FALSE
-
-#define MACRO_BEGIN do {
-#define MACRO_END } while (NEVER)
-
-#endif /* MACRO_BEGIN */
-
-/*
- * C Threads package initialization.
- */
-__DECLBEGIN
-extern void cthread_init();
-__DECLEND
-
-#include <stdlib.h>
-
-/*
- * Queues.
- */
-typedef struct cthread_queue {
- struct cthread_queue_item *head;
- struct cthread_queue_item *tail;
-} *cthread_queue_t;
-
-typedef struct cthread_queue_item {
- struct cthread_queue_item *next;
-} *cthread_queue_item_t;
-
-#define NO_QUEUE_ITEM ((cthread_queue_item_t) 0)
-
-#define QUEUE_INITIALIZER { NO_QUEUE_ITEM, NO_QUEUE_ITEM }
-
-#define cthread_queue_alloc() ((cthread_queue_t) calloc(1, sizeof(struct cthread_queue)))
-#define cthread_queue_init(q) ((q)->head = (q)->tail = 0)
-#define cthread_queue_free(q) free((any_t) (q))
-
-#define cthread_queue_enq(q, x) \
- MACRO_BEGIN \
- (x)->next = 0; \
- if ((q)->tail == 0) \
- (q)->head = (cthread_queue_item_t) (x); \
- else \
- (q)->tail->next = (cthread_queue_item_t) (x); \
- (q)->tail = (cthread_queue_item_t) (x); \
- MACRO_END
-
-#define cthread_queue_preq(q, x) \
- MACRO_BEGIN \
- if ((q)->tail == 0) \
- (q)->tail = (cthread_queue_item_t) (x); \
- ((cthread_queue_item_t) (x))->next = (q)->head; \
- (q)->head = (cthread_queue_item_t) (x); \
- MACRO_END
-
-#define cthread_queue_head(q, t) ((t) ((q)->head))
-
-#define cthread_queue_deq(q, t, x) \
- MACRO_BEGIN \
- if (((x) = (t) ((q)->head)) != 0 && \
- ((q)->head = (cthread_queue_item_t) ((x)->next)) == 0) \
- (q)->tail = 0; \
- MACRO_END
-
-#define cthread_queue_map(q, t, f) \
- MACRO_BEGIN \
- register cthread_queue_item_t x, next; \
- for (x = (cthread_queue_item_t) ((q)->head); x != 0; x = next) { \
- next = x->next; \
- (*(f))((t) x); \
- } \
- MACRO_END
-
-
-/*
- * Mutex objects.
- */
-typedef struct mutex {
- int lock;
- char *name;
-} *mutex_t;
-
-#define MUTEX_INITIALIZER { 0, 0 }
-
-#define mutex_alloc() ((mutex_t) calloc(1, sizeof(struct mutex)))
-#define mutex_init(m) ((m)->lock = 0)
-#define mutex_set_name(m, x) ((m)->name = (x))
-#define mutex_name(m) ((m)->name != 0 ? (m)->name : "?")
-#define mutex_clear(m) /* nop */
-#define mutex_free(m) free((any_t) (m))
-
-#define mutex_lock(m) \
- MACRO_BEGIN \
- if (! mutex_try_lock(m)) mutex_wait_lock(m); \
- MACRO_END
-
-__DECLBEGIN
-extern int mutex_try_lock(mutex_t m); /* nonblocking */
-extern void mutex_wait_lock(mutex_t m); /* blocking */
-extern void mutex_unlock(mutex_t m);
-__DECLEND
-
-/*
- * Condition variables.
- */
-typedef struct condition {
- int lock;
- struct cthread_queue queue;
- char *name;
-} *condition_t;
-
-#define CONDITION_INITIALIZER { 0, QUEUE_INITIALIZER, 0 }
-
-#define condition_alloc() ((condition_t) calloc(1, sizeof(struct condition)))
-#define condition_init(c) MACRO_BEGIN (c)->lock = 0; cthread_queue_init(&(c)->queue); MACRO_END
-#define condition_set_name(c, x) ((c)->name = (x))
-#define condition_name(c) ((c)->name != 0 ? (c)->name : "?")
-#define condition_clear(c) MACRO_BEGIN condition_broadcast(c); spin_lock(&(c)->lock); MACRO_END
-#define condition_free(c) MACRO_BEGIN condition_clear(c); free((any_t) (c)); MACRO_END
-
-#define condition_signal(c) \
- MACRO_BEGIN \
- if ((c)->queue.head) cond_signal(c); \
- MACRO_END
-
-#define condition_broadcast(c) \
- MACRO_BEGIN \
- if ((c)->queue.head) cond_broadcast(c); \
- MACRO_END
-
-__DECLBEGIN
-extern void cond_signal(condition_t c);
-extern void cond_broadcast(condition_t c);
-extern void condition_wait(condition_t c, mutex_t m);
-__DECLEND
-
-/*
- * Threads.
- */
-
-typedef any_t (*cthread_fn_t)(any_t arg);
-
-#import <setjmp.h>
-
-typedef struct cthread {
- struct cthread *next;
- thread_port_t real_thread;
- struct mutex lock;
- struct condition done;
- int state;
-#if defined(__cplusplus)
- jmp_buf catchBuf;
-#else
- jmp_buf catch;
-#endif
- cthread_fn_t func;
- any_t arg;
- any_t result;
- const char *name;
- any_t data;
-} *cthread_t;
-
-#define NO_CTHREAD ((cthread_t) 0)
-
-__DECLBEGIN
-extern cthread_t cthread_fork(cthread_fn_t func, any_t arg);
-extern void cthread_detach(cthread_t t);
-extern any_t cthread_join(cthread_t t);
-extern void cthread_yield(void);
-extern void cthread_exit(any_t result);
-extern kern_return_t cthread_priority(
- cthread_t t,
- int priority,
- boolean_t set_max);
-extern kern_return_t cthread_max_priority(
- cthread_t t,
- mach_port_t pset,
- int max_priority);
-extern kern_return_t cthread_abort(cthread_t t);
-__DECLEND
-
-/*
- * This structure must agree with struct cproc in cthread_internals.h
- */
-typedef struct ur_cthread {
- struct ur_cthread *next;
- cthread_t incarnation;
-} *ur_cthread_t;
-
-__DECLBEGIN
-extern int cthread_sp(void);
-
-extern int cthread_stack_mask;
-
-extern ur_cthread_t ur_cthread_self(void);
-#define cthread_thread(c) (c->real_thread)
-extern void cthread_set_errno_self(int e, int nocancel);
-extern int cthread_errno(void);
-#define cthread_assoc(id, t) (((ur_cthread_t) (id))->incarnation = (t))
-#define cthread_self() (ur_cthread_self()->incarnation)
-
-extern void cthread_set_name(cthread_t t, const char *name);
-extern const char *cthread_name(cthread_t t);
-extern int cthread_count(void);
-extern void cthread_set_limit(int n);
-extern int cthread_limit(void);
-__DECLEND
-
-#define cthread_set_data(t, x) ((t)->data = (x))
-#define cthread_data(t) ((t)->data)
-
-/*
- * Spin locks.
- */
-#define spin_unlock(p) (*(p) = 0)
-
-/*
- * Mutex locks.
- */
-#define mutex_unlock(m) ((m)->lock = 0)
-
-
-/*
- * Debugging support.
- */
-#ifdef CTHREADS_DEBUG
-
-#ifndef ASSERT
-/*
- * Assertion macro, similar to <assert.h>
- */
-#import <stdio.h>
-#define ASSERT(p) \
- MACRO_BEGIN \
- if (!(p)) { \
- fprintf(stderr, \
- "File %s, line %d: assertion p failed.\n", \
- __FILE__, __LINE__); \
- abort(); \
- } \
- MACRO_END
-
-#endif /* ASSERT */
-
-#define SHOULDNT_HAPPEN 0
-
-extern int cthread_debug;
-
-#else /* CTHREADS_DEBUG */
-
-#ifndef ASSERT
-#define ASSERT(p)
-#endif /* ASSERT */
-
-#endif /* CTHREADS_DEBUG */
-
-#endif /* _CTHREADS_ */
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Mach Operating System
- * Copyright (c) 1989 Carnegie-Mellon University
- * All rights reserved. The CMU software License Agreement specifies
- * the terms and conditions for use and redistribution.
- */
-/*
- * mig_support.c - by Mary Thompson
- *
- * Routines to set and deallocate the mig reply port for the current thread.
- * Called from mig-generated interfaces.
- */
-#include <mach/mach.h>
-#include <pthread_internals.h>
-#include <pthread.h>
-
-#include "cthreads.h"
-#include "cthread_internals.h"
-
-pthread_lock_t reply_port_lock;
-extern mach_port_t _pthread_reply_port(pthread_t);
-static mach_port_t _task_reply_port = MACH_PORT_NULL;
-
-/*
- * called in new child...
- * clear lock to cover case where the parent had
- * a thread holding this lock while another thread
- * did the fork()
- */
-void mig_fork_child()
-{
- UNLOCK(reply_port_lock);
-}
-
-/*
- * Called by mach_init with 0 before cthread_init is
- * called and again with 1 at the end of cthread_init.
- */
-void
-mig_init(init_done)
- int init_done;
-{
- if (init_done == 0) {
- LOCK_INIT(reply_port_lock);
- _task_reply_port = mach_reply_port();
- }
-}
-
-/*
- * Called by mig interface code whenever a reply port is needed.
- * Tracing is masked during this call; otherwise, a call to printf()
- * can result in a call to malloc() which eventually reenters
- * mig_get_reply_port() and deadlocks.
- */
-mach_port_t _mig_get_reply_port()
-{
- pthread_t pself;
-
- pself = pthread_self();
- if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) {
- return pself->reply_port;
- }
- return MACH_PORT_NULL;
-}
-
-void _mig_set_reply_port(mach_port_t port)
-{
- pthread_t pself;
- pself = pthread_self();
-
- if ((pself != (pthread_t)NULL) && (pself->sig == _PTHREAD_SIG)) {
- pself->reply_port = port;
- }
-}
int which;
#endif /* UTMP_COMPAT */
+ struct _utmpx *def_utx = __default_utx();
+
bzero(&utx, sizeof(utx));
strncpy(utx.ut_line, line, sizeof(utx.ut_line));
utx.ut_type = UTMPX_AUTOFILL_MASK | UTMPX_DEAD_IF_CORRESPONDING_MASK | DEAD_PROCESS;
(void)gettimeofday(&utx.ut_tv, NULL);
- UTMPX_LOCK(&__utx__);
- __setutxent(&__utx__);
- ux = __pututxline(&__utx__, &utx);
- __endutxent(&__utx__);
+ UTMPX_LOCK(def_utx);
+ __setutxent(def_utx);
+ ux = __pututxline(def_utx, &utx);
+ __endutxent(def_utx);
if (!ux) {
- UTMPX_UNLOCK(&__utx__);
+ UTMPX_UNLOCK(def_utx);
return 0;
}
#ifdef UTMP_COMPAT
_write_utmp(&u, 1);
}
#endif /* UTMP_COMPAT */
- UTMPX_UNLOCK(&__utx__);
+ UTMPX_UNLOCK(def_utx);
return 1;
}
int
_mkpath_np(const char *path, mode_t omode, const char ** firstdir)
{
- char *apath = NULL;
+ char *apath = NULL, *opath = NULL, *s, *sn, *sl;
unsigned int depth = 0;
mode_t chmod_mode = 0;
int retval = 0;
goto mkpath_exit;
}
+ sl = s = apath + strlen(apath) - 1;
+ do {
+ sn = s;
+ /* Strip off trailing /., see <rdar://problem/14351794> */
+ if (s - 1 > apath && *s == '.' && *(s - 1) == '/')
+ s -= 2;
+ /* Strip off trailing /, see <rdar://problem/11592386> */
+ if (s > apath && *s == '/')
+ s--;
+ } while (s < sn);
+ if (s < sl) {
+ s[1] = '\0';
+ path = opath = strdup(apath);
+ if (opath == NULL) {
+ retval = ENOMEM;
+ goto mkpath_exit;
+ }
+ }
+
while (1) {
/* Increase our depth and try making that directory */
- char *s = strrchr(apath, '/');
+ s = strrchr(apath, '/');
if (!s) {
/* We should never hit this under normal circumstances,
* but it can occur due to really unfortunate timing
while (depth > 1) {
/* Decrease our depth and make that directory */
- char *s = strrchr(apath, '\0');
+ s = strrchr(apath, '\0');
*s = '/';
depth--;
mkpath_exit:
free(apath);
+ free(opath);
errno = old_errno;
return retval;
#endif /* AF_LINK */
#endif /* SIOCGENADDR */
#endif /* SIOCGIFHWADDR */
- if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
+ /*
+ * Skip interfaces that return either 00:00:00:00:00:00 or
+ * 02:00:00:00:00:00.
+ */
+ if ((!a[0] || a[0] == 0x02) && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
continue;
if (node_id) {
memcpy(node_id, a, 6);
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Copyright (c) 2001 Daniel Eischen <deischen@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(__x86_64__)
-
-#include <architecture/i386/asm_help.h>
-
-/*
- * _ctx_start((void *func)(int arg1, ..., argn),
- * int arg1, ..., argn, ucontext_t *ucp)
- *
- * %rdi - func
- * %rsi - arg1
- * %rdx - arg2
- * %rcx - arg3
- * %r8 - arg4
- * %r9 - arg5
- * WRONG!
- * (8*(n-6))(%rsp) - argn
- * (8*(n + 1))(%rsp) - ucp, %rbp setup to point here (base of stack)
- */
-TEXT
-LABEL(__ctx_start)
- popq %rax /* accounted for in makecontext() */
- /* makecontext will simulate 6 parameters at least */
- /* Or it could just set these in the mcontext... */
- popq %rdi
- popq %rsi
- popq %rdx
- popq %rcx
- popq %r8
- popq %r9
-
- callq *%rax /* call start function */
- movq %r12, %rsp /*
- * setup stack for completion routine;
- * ucp is now at top of stack
- */
- movq (%rsp), %rdi
- CALL_EXTERN(__ctx_done) /* should never return */
- int $5 /* trap */
-
-#endif /* __x86_64__ */
+++ /dev/null
-/*
- * Copyright (c) 2007,2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#if defined(__x86_64__)
-
-#include <architecture/i386/asm_help.h>
-
-#define MCONTEXT_SS_RAX 16
-#define MCONTEXT_SS_RBX 24
-#define MCONTEXT_SS_RCX 32
-#define MCONTEXT_SS_RDX 40
-#define MCONTEXT_SS_RDI 48
-#define MCONTEXT_SS_RSI 56
-#define MCONTEXT_SS_RBP 64
-#define MCONTEXT_SS_RSP 72
-#define MCONTEXT_SS_R8 80
-#define MCONTEXT_SS_RIP 144
-#define MCONTEXT_SS_RFLAGS 152
-
-TEXT
-LABEL(__setcontext)
- /* struct mcontext_t * %rdi */
-#if DEBUG
- movq MCONTEXT_SS_RSI(%rdi), %rsi
- movq MCONTEXT_SS_RCX(%rdi), %rcx
- movq MCONTEXT_SS_R8+0(%rdi), %r8
- movq MCONTEXT_SS_R8+8(%rdi), %r9
- movq MCONTEXT_SS_R8+16(%rdi), %r10
- movq MCONTEXT_SS_R8+24(%rdi), %r11
-#endif
- movq MCONTEXT_SS_RBX(%rdi), %rbx
- movq MCONTEXT_SS_R8+32(%rdi), %r12
- movq MCONTEXT_SS_R8+40(%rdi), %r13
- movq MCONTEXT_SS_R8+48(%rdi), %r14
- movq MCONTEXT_SS_R8+56(%rdi), %r15
-
- movq MCONTEXT_SS_RSP(%rdi), %rsp
- movq MCONTEXT_SS_RBP(%rdi), %rbp
-
- xorl %eax, %eax /* force x=getcontext(); ... setcontext(); to keep x==0 */
-
-#if DEBUG
- movq MCONTEXT_SS_RIP(%rdi), %rdx
- movq MCONTEXT_SS_RDI(%rdi), %rdi
- jmp *%rdx
-#else
- jmp *MCONTEXT_SS_RIP(%rdi)
-#endif
-
-#endif /* __x86_64__ */
+++ /dev/null
-/*
- * Copyright (c) 2008 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-/*
- * This routine provides fast access to the logical cpu number
- * of the calling processor assuming no pre-emption occurs. This number
- * is encoded in the bottom 12-bits of the limit field of the IDTR (the
- * Interrupt Descriptor Table Register). The SIDT instruction is used in
- * userspace to read this register and thus to gain access to the cpu number.
- * The IDTR is loaded by the kernel for each processor at startup - see
- * osfmk/i386/mp_desc.c.
- */
-
-/* return logical cpu number in %rax */
-
- .private_extern _cpu_number
-_cpu_number:
- push %rbp
- mov %rsp,%rbp
- sub $16,%rsp // space to read IDTR
-
- sidt (%rsp) // store limit:base on stack
- movw (%rsp), %ax // get limit
- and $0xfff, %rax // mask off lower 12 bits to return
-
- mov %rbp,%rsp
- pop %rbp
- ret
+++ /dev/null
-/*
- * Copyright (c) 2007,2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#if defined(__x86_64__)
-
-#include <architecture/i386/asm_help.h>
-
-#define MCONTEXT_SS_RAX 16
-#define MCONTEXT_SS_RBX 24
-#define MCONTEXT_SS_RCX 32
-#define MCONTEXT_SS_RDX 40
-#define MCONTEXT_SS_RDI 48
-#define MCONTEXT_SS_RSI 56
-#define MCONTEXT_SS_RBP 64
-#define MCONTEXT_SS_RSP 72
-#define MCONTEXT_SS_R8 80
-#define MCONTEXT_SS_RIP 144
-#define MCONTEXT_SS_RFLAGS 152
-
-TEXT
-LABEL(_getcontext)
- /* struct ucontext_t * $rdi */
- push %rbp
- movq %rsp, %rbp
- movq %rsp, %rsi
- CALL_EXTERN(_getmcontext) /* getmcontext(uctx, sp) */
- pop %rbp
-
-#if DEBUG
- movq $0, MCONTEXT_SS_RAX(%rax)
- movq $0, MCONTEXT_SS_RDX(%rax)
- movq $0, MCONTEXT_SS_RCX(%rax)
- movq $0, MCONTEXT_SS_RDI(%rax)
- movq $0, MCONTEXT_SS_RSI(%rax)
- movq $0, MCONTEXT_SS_R8(%rax)
- movq $0, MCONTEXT_SS_R8+8(%rax)
- movq $0, MCONTEXT_SS_R8+16(%rax)
- movq $0, MCONTEXT_SS_R8+24(%rax)
- movq $0, MCONTEXT_SS_RFLAGS(%rax)
-#endif
-
- movq %rbp, MCONTEXT_SS_RBP(%rax)
- movq %rbx, MCONTEXT_SS_RBX(%rax)
- movq %r12, MCONTEXT_SS_R8+32(%rax)
- movq %r13, MCONTEXT_SS_R8+40(%rax)
- movq %r14, MCONTEXT_SS_R8+48(%rax)
- movq %r15, MCONTEXT_SS_R8+56(%rax)
- movq (%rsp), %rcx /* return address */
- movq %rcx, MCONTEXT_SS_RIP(%rax)
- leaq 8(%rsp), %rcx
- movq %rcx, MCONTEXT_SS_RSP(%rax)
- xorl %eax, %eax
- ret
-
-#endif /* __x86_64__ */
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#if defined(__x86_64__)
-
-#define _XOPEN_SOURCE 600L
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
-#include <signal.h>
-#include <ucontext.h>
-
-extern size_t pthread_get_stacksize_np(pthread_t);
-extern void *pthread_get_stackaddr_np(pthread_t);
-#ifdef __DYNAMIC__
-extern int __in_sigtramp;
-#endif /* __DYNAMIC_ */
-
-__private_extern__ mcontext_t
-getmcontext(ucontext_t *uctx, void *sp)
-{
- pthread_t self = pthread_self();
- mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data;
- size_t stacksize = pthread_get_stacksize_np(self);
- stack_t stack;
-
- uctx->uc_stack.ss_sp = sp;
- uctx->uc_stack.ss_flags = 0;
-
- if (0 == sigaltstack(NULL, &stack)) {
- if (stack.ss_flags & SS_ONSTACK) {
- uctx->uc_stack = stack;
- stacksize = stack.ss_size;
- }
- }
-
- if (stacksize == 0) { /* main thread doesn't have pthread stack size */
- struct rlimit rlim;
- if (0 == getrlimit(RLIMIT_STACK, &rlim))
- stacksize = rlim.rlim_cur;
- }
-
- uctx->uc_stack.ss_size = stacksize;
-
- if (uctx->uc_mcontext != mctx) {
- uctx->uc_mcontext = mctx;
-
-#ifdef __DYNAMIC__
- uctx->uc_link = (ucontext_t*)(uintptr_t)__in_sigtramp; /* non-zero if in signal handler */
-#else /* !__DYNAMIC__ */
- uctx->uc_link = 0;
-#endif /* __DYNAMIC__ */
-
- }
-
- sigprocmask(0, NULL, &uctx->uc_sigmask);
- return mctx;
-}
-
-#endif /* __x86_64__ */
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- * Copyright (c) 2003-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
- #include <machine/cpu_capabilities.h>
-
-
- .text
- .align 4, 0x00
-
-/* void sys_icache_invalidate(addr_t start, int length) */
-
- .globl _sys_icache_invalidate
-_sys_icache_invalidate:
- // This is a NOP on intel processors, since the intent of the API
- // is to make data executable, and Intel L1Is are coherent with L1D.
- ret
-
-
-/* void sys_dcache_flush(addr_t start, int length) */
-
- .globl _sys_dcache_flush
-_sys_dcache_flush:
- testq %rsi,%rsi // length 0?
- jz 2f // yes
- mfence // ensure previous stores make it to memory
- clflush -1(%rdi,%rsi) // make sure last line is flushed
-1:
- clflush (%rdi) // flush a line
- addq $64,%rdi
- subq $64,%rsi
- ja 1b
- mfence // make sure memory is updated before we return
-2:
- ret
+++ /dev/null
-/*
- * Copyright (c) 2007, 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Copyright (c) 2001 Daniel M. Eischen <deischen@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(__x86_64__)
-
-#define _XOPEN_SOURCE
-#include <sys/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/signal.h>
-#include <sys/ucontext.h>
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ucontext.h>
-#include <unistd.h>
-
-/* Prototypes */
-extern void _ctx_start(ucontext_t *, int argc, ...);
-
-void
-_ctx_done (ucontext_t *ucp)
-{
- if (ucp->uc_link == NULL)
- exit(0);
- else {
- /*
- * Since this context has finished, don't allow it
- * to be restarted without being reinitialized (via
- * setcontext or swapcontext).
- */
- ucp->uc_mcsize = 0;
-
- /* Set context to next one in link */
- /* XXX - what to do for error, abort? */
- setcontext((const ucontext_t *)ucp->uc_link);
- LIBC_ABORT("setcontext failed"); /* should never get here */
- }
-}
-
-void
-makecontext(ucontext_t *ucp, void (*start)(), int argc, ...)
-{
- va_list ap;
- char *stack_top;
- intptr_t *argp;
- int i;
-
- if (ucp == NULL)
- return;
- else if ((ucp->uc_stack.ss_sp == NULL) ||
- (ucp->uc_stack.ss_size < MINSIGSTKSZ)) {
- /*
- * This should really return -1 with errno set to ENOMEM
- * or something, but the spec says that makecontext is
- * a void function. At least make sure that the context
- * isn't valid so it can't be used without an error.
- */
- ucp->uc_mcsize = 0;
- }
- /* XXX - Do we want to sanity check argc? */
- else if ((argc < 0) || (argc > NCARGS)) {
- ucp->uc_mcsize = 0;
- }
- /* Make sure the context is valid. */
- else {
- /*
- * Arrange the stack as follows:
- *
- * _ctx_start() - context start wrapper
- * start() - user start routine
- * arg1 - first argument, aligned(16)
- * ...
- * argn
- * ucp - this context, %rbp points here
- *
- * When the context is started, control will return to
- * the context start wrapper which will pop the user
- * start routine from the top of the stack. After that,
- * the top of the stack will be setup with all arguments
- * necessary for calling the start routine. When the
- * start routine returns, the context wrapper then sets
- * the stack pointer to %rbp which was setup to point to
- * the base of the stack (and where ucp is stored). It
- * will then call _ctx_done() to swap in the next context
- * (uc_link != 0) or exit the program (uc_link == 0).
- */
- mcontext_t mc;
-
- stack_top = (char *)(ucp->uc_stack.ss_sp +
- ucp->uc_stack.ss_size - sizeof(intptr_t));
-
-
- /* Give 6 stack slots to _ctx_start */
- int minargc = 6;
- if (argc > minargc)
- minargc = argc;
-
- /*
- * Adjust top of stack to allow for 3 pointers (return
- * address, _ctx_start, and ucp) and argc arguments.
- * We allow the arguments to be pointers also. The first
- * argument to the user function must be properly aligned.
- */
-
- stack_top = stack_top - (sizeof(intptr_t) * (1 + minargc));
- stack_top = (char *)((intptr_t)stack_top & ~15);
- stack_top = stack_top - (2 * sizeof(intptr_t));
- argp = (intptr_t *)stack_top;
-
- /*
- * Setup the top of the stack with the user start routine
- * followed by all of its aguments and the pointer to the
- * ucontext. We need to leave a spare spot at the top of
- * the stack because setcontext will move rip to the top
- * of the stack before returning.
- */
- *argp = (intptr_t)_ctx_start; /* overwritten with same value */
- argp++;
- *argp = (intptr_t)start;
- argp++;
-
- /* Add all the arguments: */
- va_start(ap, argc);
- for (i = 0; i < argc; i++) {
- *argp = va_arg(ap, intptr_t);
- argp++;
- }
- va_end(ap);
-
- /* Always provide space for ctx_start to pop the parameter registers */
- for (;argc < minargc; argc++) {
- *argp++ = 0;
- }
-
- /* Keep stack aligned */
- if (argc & 1) {
- *argp++ = 0;
- }
-
- /* The ucontext is placed at the bottom of the stack. */
- *argp = (intptr_t)ucp;
-
- /*
- * Set the machine context to point to the top of the
- * stack and the program counter to the context start
- * wrapper. Note that setcontext() pushes the return
- * address onto the top of the stack, so allow for this
- * by adjusting the stack downward 1 slot. Also set
- * %r12 to point to the base of the stack where ucp
- * is stored.
- */
- mc = ucp->uc_mcontext;
- /* Use callee-save and match _ctx_start implementation */
- mc->__ss.__r12 = (intptr_t)argp;
- mc->__ss.__rbp = 0;
- mc->__ss.__rsp = (intptr_t)stack_top + sizeof(caddr_t);
- mc->__ss.__rip = (intptr_t)_ctx_start;
- }
-}
-
-#endif /* __x86_64__ */
+++ /dev/null
-/*
- * Copyright (c) 2007, 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#if defined(__x86_64__)
-
-#define _XOPEN_SOURCE 600L
-#include <ucontext.h>
-#undef _XOPEN_SOURCE
-#undef _POSIX_C_SOURCE /* sigsetmask() */
-#include <signal.h>
-
-extern int _setcontext(const mcontext_t);
-
-int
-setcontext(const ucontext_t *uctx)
-{
- mcontext_t mctx = (mcontext_t)&uctx->__mcontext_data;
- ucontext_t *_uctx = (ucontext_t *)uctx;
- if (mctx != _uctx->uc_mcontext)
- _uctx->uc_mcontext = mctx;
- sigsetmask(uctx->uc_sigmask);
- return _setcontext(mctx);
-}
-
-#endif /* __x86_64__ */
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1980 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)setjmperr.c 5.4 (Berkeley) 6/27/88";
-#endif /* LIBC_SCCS and not lint */
-
-#include <unistd.h>
-
-/*
- * This routine is called from longjmp() when an error occurs.
- * Programs that wish to exit gracefully from this error may
- * write their own versions.
- * If this routine returns, the program is aborted.
- */
-
-void
-longjmperror()
-{
-#define ERRMSG "longjmp botch\n"
- write(2, ERRMSG, sizeof(ERRMSG) - 1);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, 2009 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-/*
- * Copyright (c) 2001 Daniel M. Eischen <deischen@freebsd.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(__x86_64__)
-
-#include <sys/cdefs.h>
-#include <sys/param.h>
-#include <sys/signal.h>
-#include <ucontext.h>
-
-#include <errno.h>
-#include <stddef.h>
-
-#define uc_flags uc_onstack
-#define UCF_SWAPPED 0x80000000
-
-int
-swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
-{
- int ret;
-
- if ((oucp == NULL) || (ucp == NULL)) {
- errno = EINVAL;
- return (-1);
- }
- oucp->uc_flags &= ~UCF_SWAPPED;
- ret = getcontext(oucp);
- if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) {
- oucp->uc_flags |= UCF_SWAPPED;
- ret = setcontext(ucp);
- }
- return (ret);
-}
-
-#endif /* __x86_64__ */
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <mach/i386/syscall_sw.h>
-
-/* Subroutine to make a preempt syscall. Called when we notice %ebx is
- * nonzero after returning from a PFZ subroutine. Not in PFZ.
- *
- * All registers preserved (but does clear the %ebx preemption flag).
- */
- .align 2
- .private_extern _preempt
-_preempt:
- pushq %rax
- pushq %rcx
- pushq %r11
- movl $(SYSCALL_CONSTRUCT_MACH(58)),%eax /* 58 = pfz_exit */
- xorl %ebx,%ebx
- syscall
- popq %r11
- popq %rcx
- popq %rax
- ret
-
-/* Subroutine to back off if we cannot get the spinlock. Called
- * after a few attempts inline in the PFZ subroutines. This code is
- * not in the PFZ.
- * %rdi = ptr to queue head structure
- * %ebx = preemption flag (nonzero if preemption pending)
- * Uses: %rax.
- */
- .align 2
- .private_extern _backoff
-_backoff:
- testl %ebx,%ebx // does kernel want to preempt us?
- jz 1f // no
- call _preempt
-1:
- pause // SMT-friendly backoff
- cmpl $0,16(%rdi) // sniff the lockword
- jnz 1b // loop if still taken
- ret // lockword is free, so reenter PFZ
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "pthread_machdep.h"
-
-.text
-.align 2, 0x90
-.globl _pthread_getspecific
-_pthread_getspecific:
- movq %gs:(,%rdi,8),%rax
- ret
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include <architecture/i386/asm_help.h>
-
-#define PTHRW_LVAL 0
-#define PTHRW_UVAL 4
-
- .text
- .align 2
- .globl __commpage_pthread_mutex_lock
-__commpage_pthread_mutex_lock:
- pushq %rbp // set up frame for backtrace
- movq %rsp,%rbp
- pushq %rbx
- xorl %ebx,%ebx // clear "preemption pending" flag
- movl $(_COMM_PAGE_SPIN_COUNT), %eax
-1:
- testl PTHRW_LVAL(%rdi),%ecx // is mutex available?
- jz 2f // yes, it is available
- pause
- decl %eax // decrement max spin count
- jnz 1b // keep spinning
-2:
- movq _commpage_pfz_base(%rip),%rcx
- addq $(_COMM_TEXT_PFZ_MUTEX_LOCK_OFFSET), %rcx
- call *%rcx
- testl %ebx,%ebx // pending preemption?
- jz 1f // no
- call _preempt
-1:
- popq %rbx
- popq %rbp
- ret
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "pthread_machdep.h"
-
-.text
-.align 2, 0x90
-.globl _pthread_self
-_pthread_self:
- movq %gs:0,%rax
- ret
+++ /dev/null
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <mach/i386/syscall_sw.h>
-
-.text
-.align 2, 0x90
-.globl ___pthread_set_self
-___pthread_set_self:
- movl $0, %esi // 0 as the second argument
- movl $ SYSCALL_CONSTRUCT_MDEP(3), %eax // Machine-dependent syscall number 3
- MACHDEP_SYSCALL_TRAP
- ret
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "pthread_machdep.h"
-
-.text
-.align 2, 0x90
-.globl _start_wqthread
-_start_wqthread:
-// This routine is never called directly by user code, jumped from kernel
- push %rbp
- mov %rsp,%rbp
- sub $24,%rsp // align the stack
- call __pthread_wqthread
- leave
- ret
-
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include "pthread_machdep.h"
-
-.text
-.align 2, 0x90
-.globl _thread_start
-_thread_start:
-// This routine is never called directly by user code, jumped from kernel
- push %rbp
- mov %rsp,%rbp
- sub $24,%rsp // align the stack
- call __pthread_start
- leave
- ret
-
+++ /dev/null
- .globl ___bzero
-___bzero:
- jmp _bzero
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse42)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bcopy, sse3x)
-
-static const platfunc_descriptor *bcopy_platfunc_descriptors[] = {
- PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse42),
- PLATFUNC_DESCRIPTOR_REFERENCE(bcopy, sse3x),
- 0
-};
-
-void *bcopy_chooser() __asm__("_bcopy");
-void *bcopy_chooser() {
- __asm__(".desc _bcopy, 0x100");
- return find_platform_function((const platfunc_descriptor **) bcopy_platfunc_descriptors);
-}
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-/*
- * The bcopy/memcpy loops, tuned for 64-bit Pentium-M class processors with
- * Supplemental SSE3 and 64-byte cache lines. This is the 64-bit version.
- *
- * The following #defines are tightly coupled to the u-architecture:
- */
-
-#define kShort 80 // too short to bother with SSE (must be >=80)
-#define kVeryLong (500*1024) // large enough for non-temporal stores (>=8192 and <2GB)
-#define kFastUCode ((16*1024)-15) // cutoff for microcode fastpath for "rep/movsl"
-
-// void bcopy(const void *src, void *dst, size_t len);
-
-PLATFUNC_FUNCTION_START_GENERIC(bcopy, sse3x, 64, 5)
-LZero:
- pushq %rbp // set up a frame for backtraces
- movq %rsp,%rbp
- movq %rsi,%rax // copy dest ptr
- movq %rdi,%rsi // xchange source and dest ptrs
- movq %rax,%rdi
- subq %rsi,%rax // (dest - source)
- cmpq %rdx,%rax // must move in reverse if (dest - source) < length
- jb LReverseIsland
- cmpq $(kShort),%rdx // long enough to bother with SSE?
- jbe LShort // no
- jmp LNotShort
-
-//
-// void *memcpy(void *dst, const void *src, size_t len);
-// void *memmove(void *dst, const void *src, size_t len);
-//
-
-PLATFUNC_FUNCTION_START_GENERIC(memcpy, sse3x, 64, 0) // void *memcpy(void *dst, const void *src, size_t len)
-PLATFUNC_FUNCTION_START_GENERIC(memmove, sse3x, 64, 0) // void *memmove(void *dst, const void *src, size_t len)
- pushq %rbp // set up a frame for backtraces
- movq %rsp,%rbp
- movq %rdi,%r11 // save return value here
- movq %rdi,%rax
- subq %rsi,%rax // (dest - source)
- cmpq %rdx,%rax // must move in reverse if (dest - source) < length
- jb LReverseIsland
- cmpq $(kShort),%rdx // long enough to bother with SSE?
- ja LNotShort // yes
-
-// Handle short forward copies. As the most common case, this is the fall-through path.
-// rdx = length (<= kShort)
-// rsi = source ptr
-// rdi = dest ptr
-
-LShort:
- movl %edx,%ecx // copy length using 32-bit operation
- shrl $2,%ecx // get #doublewords
- jz LLeftovers
-2: // loop copying doublewords
- movl (%rsi),%eax
- addq $4,%rsi
- movl %eax,(%rdi)
- addq $4,%rdi
- decl %ecx
- jnz 2b
-LLeftovers: // handle leftover bytes (0..3) in last word
- andl $3,%edx // any leftover bytes?
- jz 5f
-4: // loop copying bytes
- movb (%rsi),%al
- incq %rsi
- movb %al,(%rdi)
- incq %rdi
- decl %edx
- jnz 4b
-5:
- movq %r11,%rax // get return value (dst ptr) for memcpy/memmove
- popq %rbp
- ret
-
-
-LReverseIsland: // keep the "jb" above a short branch...
- jmp LReverse // ...because reverse moves are uncommon
-
-
-// Handle forward moves that are long enough to justify use of SSE.
-// First, 16-byte align the destination.
-// rdx = length (> kShort)
-// rsi = source ptr
-// rdi = dest ptr
-
-LNotShort:
- cmpq $(kVeryLong),%rdx // long enough to justify heavyweight loops?
- jae LVeryLong // use very-long-operand path
- movl %edi,%ecx // copy low half of destination ptr
- negl %ecx
- andl $15,%ecx // get #bytes to align destination
- jz LDestAligned // already aligned
- subl %ecx,%edx // decrement length
- rep // align destination
- movsb
-
-
-// Destination is now aligned. Dispatch to one of sixteen loops over 64-byte chunks,
-// based on the alignment of the source. All vector loads and stores are aligned.
-// Even though this means we have to shift and repack vectors, doing so is much faster
-// than unaligned loads. Since kShort>=80 and we've moved at most 15 bytes already,
-// there is at least one chunk. When we enter the copy loops, the following registers
-// are set up:
-// rdx = residual length (0..63)
-// rcx = -(length to move), a multiple of 64 less than 2GB
-// rsi = ptr to 1st source byte not to move (unaligned)
-// rdi = ptr to 1st dest byte not to move (aligned)
-
-LDestAligned:
- movq %rdx,%rcx // copy length
- movl %esi,%eax // copy low half of source address
- andl $63,%edx // get remaining bytes for LShort
- andl $15,%eax // mask to low 4 bits of source address
- andq $-64,%rcx // get number of bytes we will copy in inner loop
- leaq LTable(%rip), %r8
- addq %rcx,%rsi // point to 1st byte not copied
- addq %rcx,%rdi
- movl (%r8,%rax,4),%eax // get offset of routine
- negq %rcx // now generate offset to 1st byte to be copied
- addq %r8,%rax // generate address of copy loop
- jmp *%rax // enter copy loop, selected by source alignment
-
- .align 2
-LTable: // table of copy loop addresses
-// force generation of assembly-time constants. Otherwise assembler
-// creates subtractor relocations relative to first external symbol,
-// and this file has none
- .set LMod0Offset, LMod0 - LTable
- .set LMod1Offset, LMod1 - LTable
- .set LMod2Offset, LMod2 - LTable
- .set LMod3Offset, LMod3 - LTable
- .set LMod4Offset, LMod4 - LTable
- .set LMod5Offset, LMod5 - LTable
- .set LMod6Offset, LMod6 - LTable
- .set LMod7Offset, LMod7 - LTable
- .set LMod8Offset, LMod8 - LTable
- .set LMod9Offset, LMod9 - LTable
- .set LMod10Offset, LMod10 - LTable
- .set LMod11Offset, LMod11 - LTable
- .set LMod12Offset, LMod12 - LTable
- .set LMod13Offset, LMod13 - LTable
- .set LMod14Offset, LMod14 - LTable
- .set LMod15Offset, LMod15 - LTable
- .long LMod0Offset
- .long LMod1Offset
- .long LMod2Offset
- .long LMod3Offset
- .long LMod4Offset
- .long LMod5Offset
- .long LMod6Offset
- .long LMod7Offset
- .long LMod8Offset
- .long LMod9Offset
- .long LMod10Offset
- .long LMod11Offset
- .long LMod12Offset
- .long LMod13Offset
- .long LMod14Offset
- .long LMod15Offset
-
-
-// Very long forward moves. These are at least several pages. They are special cased
-// and aggressively optimized, not so much because they are common or useful, but
-// because they are subject to benchmark. There isn't enough room for them in the
-// area reserved on the platfunc for bcopy, so we put them elsewhere. We call
-// the longcopy routine using the normal ABI:
-// rdi = dest
-// rsi = source
-// rdx = length (>= kVeryLong bytes)
-
-LVeryLong:
- pushq %r11 // save return value
- call _longcopy // call very long operand routine
- popq %rax // pop return value
- popq %rbp
- ret
-
-
-// On Pentium-M, the microcode for "rep/movsl" is faster than SSE for 16-byte
-// aligned operands from about 32KB up to kVeryLong for the hot cache case, and from
-// about 256 bytes up to kVeryLong for cold caches. This is because the microcode
-// avoids having to read destination cache lines that will be completely overwritten.
-// The cutoff we use (ie, kFastUCode) must somehow balance the two cases, since
-// we do not know if the destination is in cache or not.
-
-Lfastpath:
- addq %rcx,%rsi // restore ptrs to 1st byte of source and dest
- addq %rcx,%rdi
- negl %ecx // make length positive (known to be < 2GB)
- orl %edx,%ecx // restore total #bytes remaining to move
- cld // we'll move forward
- shrl $2,%ecx // compute #words to move
- rep // the u-code will optimize this
- movsl
- jmp LLeftovers // handle 0..3 leftover bytes
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 0000
-
-LMod0:
- cmpl $(-kFastUCode),%ecx // %rcx == -length, where (length < kVeryLong)
- jle Lfastpath // long enough for fastpath in microcode
- jmp 1f
- .align 4,0x90 // 16-byte align inner loops
-1: // loop over 64-byte chunks
- movdqa (%rsi,%rcx),%xmm0
- movdqa 16(%rsi,%rcx),%xmm1
- movdqa 32(%rsi,%rcx),%xmm2
- movdqa 48(%rsi,%rcx),%xmm3
-
- movdqa %xmm0,(%rdi,%rcx)
- movdqa %xmm1,16(%rdi,%rcx)
- movdqa %xmm2,32(%rdi,%rcx)
- movdqa %xmm3,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 0001
-
-LMod1:
- movdqa -1(%rsi,%rcx),%xmm0 // prime the loop by loading 1st quadword
-1: // loop over 64-byte chunks
- movdqa 15(%rsi,%rcx),%xmm1
- movdqa 31(%rsi,%rcx),%xmm2
- movdqa 47(%rsi,%rcx),%xmm3
- movdqa 63(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $1,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $1,%xmm2,%xmm3
- palignr $1,%xmm1,%xmm2
- palignr $1,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 0010
-
-LMod2:
- movdqa -2(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 14(%rsi,%rcx),%xmm1
- movdqa 30(%rsi,%rcx),%xmm2
- movdqa 46(%rsi,%rcx),%xmm3
- movdqa 62(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $2,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $2,%xmm2,%xmm3
- palignr $2,%xmm1,%xmm2
- palignr $2,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 0011
-
-LMod3:
- movdqa -3(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 13(%rsi,%rcx),%xmm1
- movdqa 29(%rsi,%rcx),%xmm2
- movdqa 45(%rsi,%rcx),%xmm3
- movdqa 61(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $3,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $3,%xmm2,%xmm3
- palignr $3,%xmm1,%xmm2
- palignr $3,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 0100
-// We use the float single data type in order to use "movss" to merge vectors.
-
-LMod4:
- movaps -4(%rsi,%rcx),%xmm0 // 4-byte aligned: prime the loop
- jmp 1f
- .align 4,0x90
-1: // loop over 64-byte chunks
- movaps 12(%rsi,%rcx),%xmm1
- movaps 28(%rsi,%rcx),%xmm2
- movss %xmm1,%xmm0 // copy low 4 bytes of source into destination
- pshufd $(0x39),%xmm0,%xmm0 // rotate right 4 bytes (mask -- 00 11 10 01)
- movaps 44(%rsi,%rcx),%xmm3
- movss %xmm2,%xmm1
- pshufd $(0x39),%xmm1,%xmm1
- movaps 60(%rsi,%rcx),%xmm4
- movss %xmm3,%xmm2
- pshufd $(0x39),%xmm2,%xmm2
-
- movaps %xmm0,(%rdi,%rcx)
- movss %xmm4,%xmm3
- pshufd $(0x39),%xmm3,%xmm3
- movaps %xmm1,16(%rdi,%rcx)
- movaps %xmm2,32(%rdi,%rcx)
- movaps %xmm4,%xmm0
- movaps %xmm3,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 0101
-
-LMod5:
- movdqa -5(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 11(%rsi,%rcx),%xmm1
- movdqa 27(%rsi,%rcx),%xmm2
- movdqa 43(%rsi,%rcx),%xmm3
- movdqa 59(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $5,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $5,%xmm2,%xmm3
- palignr $5,%xmm1,%xmm2
- palignr $5,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 0110
-
-LMod6:
- movdqa -6(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 10(%rsi,%rcx),%xmm1
- movdqa 26(%rsi,%rcx),%xmm2
- movdqa 42(%rsi,%rcx),%xmm3
- movdqa 58(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $6,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $6,%xmm2,%xmm3
- palignr $6,%xmm1,%xmm2
- palignr $6,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 0111
-
-LMod7:
- movdqa -7(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 9(%rsi,%rcx),%xmm1
- movdqa 25(%rsi,%rcx),%xmm2
- movdqa 41(%rsi,%rcx),%xmm3
- movdqa 57(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $7,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $7,%xmm2,%xmm3
- palignr $7,%xmm1,%xmm2
- palignr $7,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 1000
-// We use the float double data type in order to use "shufpd" to shift by 8 bytes.
-
-LMod8:
- cmpl $(-kFastUCode),%ecx // %rcx == -length, where (length < kVeryLong)
- jle Lfastpath // long enough for fastpath in microcode
- movapd -8(%rsi,%rcx),%xmm0 // 8-byte aligned: prime the loop
- jmp 1f
- .align 4,0x90
-1: // loop over 64-byte chunks
- movapd 8(%rsi,%rcx),%xmm1
- movapd 24(%rsi,%rcx),%xmm2
- shufpd $01,%xmm1,%xmm0 // %xmm0 <- shr( %xmm0 || %xmm1, 8 bytes)
- movapd 40(%rsi,%rcx),%xmm3
- shufpd $01,%xmm2,%xmm1
- movapd 56(%rsi,%rcx),%xmm4
- shufpd $01,%xmm3,%xmm2
-
- movapd %xmm0,(%rdi,%rcx)
- shufpd $01,%xmm4,%xmm3
- movapd %xmm1,16(%rdi,%rcx)
- movapd %xmm2,32(%rdi,%rcx)
- movapd %xmm4,%xmm0
- movapd %xmm3,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 1001
-
-LMod9:
- movdqa -9(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 7(%rsi,%rcx),%xmm1
- movdqa 23(%rsi,%rcx),%xmm2
- movdqa 39(%rsi,%rcx),%xmm3
- movdqa 55(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $9,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $9,%xmm2,%xmm3
- palignr $9,%xmm1,%xmm2
- palignr $9,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 1010
-
-LMod10:
- movdqa -10(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 6(%rsi,%rcx),%xmm1
- movdqa 22(%rsi,%rcx),%xmm2
- movdqa 38(%rsi,%rcx),%xmm3
- movdqa 54(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $10,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $10,%xmm2,%xmm3
- palignr $10,%xmm1,%xmm2
- palignr $10,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 1011
-
-LMod11:
- movdqa -11(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 5(%rsi,%rcx),%xmm1
- movdqa 21(%rsi,%rcx),%xmm2
- movdqa 37(%rsi,%rcx),%xmm3
- movdqa 53(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $11,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $11,%xmm2,%xmm3
- palignr $11,%xmm1,%xmm2
- palignr $11,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 1100
-// We use the float single data type in order to use "movss" to merge vectors.
-
-LMod12:
- movss (%rsi,%rcx),%xmm0 // prefetch 1st four bytes of source, right justified
- jmp 1f
- .align 4,0x90
-1: // loop over 64-byte chunks
- pshufd $(0x93),4(%rsi,%rcx),%xmm1 // load and rotate right 12 bytes (mask -- 10 01 00 11)
- pshufd $(0x93),20(%rsi,%rcx),%xmm2
- pshufd $(0x93),36(%rsi,%rcx),%xmm3
- pshufd $(0x93),52(%rsi,%rcx),%xmm4
-
- movaps %xmm4,%xmm5
- movss %xmm3,%xmm4 // copy low 4 bytes of source into destination
- movss %xmm2,%xmm3
- movss %xmm1,%xmm2
- movss %xmm0,%xmm1
-
- movaps %xmm1,(%rdi,%rcx)
- movaps %xmm2,16(%rdi,%rcx)
- movaps %xmm5,%xmm0
- movaps %xmm3,32(%rdi,%rcx)
- movaps %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 1101
-
-LMod13:
- movdqa -13(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 3(%rsi,%rcx),%xmm1
- movdqa 19(%rsi,%rcx),%xmm2
- movdqa 35(%rsi,%rcx),%xmm3
- movdqa 51(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $13,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $13,%xmm2,%xmm3
- palignr $13,%xmm1,%xmm2
- palignr $13,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 1110
-
-LMod14:
- movdqa -14(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 2(%rsi,%rcx),%xmm1
- movdqa 18(%rsi,%rcx),%xmm2
- movdqa 34(%rsi,%rcx),%xmm3
- movdqa 50(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $14,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $14,%xmm2,%xmm3
- palignr $14,%xmm1,%xmm2
- palignr $14,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for medium length operands in which low four bits of %rsi == 1111
-
-LMod15:
- movdqa -15(%rsi,%rcx),%xmm0 // prime the loop by loading 1st source dq
-1: // loop over 64-byte chunks
- movdqa 1(%rsi,%rcx),%xmm1
- movdqa 17(%rsi,%rcx),%xmm2
- movdqa 33(%rsi,%rcx),%xmm3
- movdqa 49(%rsi,%rcx),%xmm4
-
- movdqa %xmm0,%xmm5
- movdqa %xmm4,%xmm0
-
- palignr $15,%xmm3,%xmm4 // dest <- shr( dest || source, imm*8 )
- palignr $15,%xmm2,%xmm3
- palignr $15,%xmm1,%xmm2
- palignr $15,%xmm5,%xmm1
-
- movdqa %xmm1,(%rdi,%rcx)
- movdqa %xmm2,16(%rdi,%rcx)
- movdqa %xmm3,32(%rdi,%rcx)
- movdqa %xmm4,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz 1b
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Reverse moves. These are not optimized as aggressively as their forward
-// counterparts, as they are only used with destructive overlap.
-// rdx = length
-// rsi = source ptr
-// rdi = dest ptr
-
-LReverse:
- addq %rdx,%rsi // point to end of strings
- addq %rdx,%rdi
- cmpq $(kShort),%rdx // long enough to bother with SSE?
- ja LReverseNotShort // yes
-
-// Handle reverse short copies.
-// edx = length (<= kShort)
-// rsi = one byte past end of source
-// rdi = one byte past end of dest
-
-LReverseShort:
- movl %edx,%ecx // copy length
- shrl $3,%ecx // #quadwords
- jz 3f
-1:
- subq $8,%rsi
- movq (%rsi),%rax
- subq $8,%rdi
- movq %rax,(%rdi)
- decl %ecx
- jnz 1b
-3:
- andl $7,%edx // bytes?
- jz 5f
-4:
- decq %rsi
- movb (%rsi),%al
- decq %rdi
- movb %al,(%rdi)
- decl %edx
- jnz 4b
-5:
- movq %r11,%rax // get return value (dst ptr) for memcpy/memmove
- popq %rbp
- ret
-
-// Handle a reverse move long enough to justify using SSE.
-// rdx = length (> kShort)
-// rsi = one byte past end of source
-// rdi = one byte past end of dest
-
-LReverseNotShort:
- movl %edi,%ecx // copy destination
- andl $15,%ecx // get #bytes to align destination
- je LReverseDestAligned // already aligned
- subq %rcx,%rdx // adjust length
-1: // loop copying 1..15 bytes
- decq %rsi
- movb (%rsi),%al
- decq %rdi
- movb %al,(%rdi)
- decl %ecx
- jnz 1b
-
-// Destination is now aligned. Prepare for reverse loops.
-
-LReverseDestAligned:
- movq %rdx,%rcx // copy length
- andl $63,%edx // get remaining bytes for LReverseShort
- andq $-64,%rcx // get number of bytes we will copy in inner loop
- subq %rcx,%rsi // point to endpoint of copy
- subq %rcx,%rdi
- testl $15,%esi // is source aligned too?
- jnz LReverseUnalignedLoop // no
-
-LReverseAlignedLoop: // loop over 64-byte chunks
- movdqa -16(%rsi,%rcx),%xmm0
- movdqa -32(%rsi,%rcx),%xmm1
- movdqa -48(%rsi,%rcx),%xmm2
- movdqa -64(%rsi,%rcx),%xmm3
-
- movdqa %xmm0,-16(%rdi,%rcx)
- movdqa %xmm1,-32(%rdi,%rcx)
- movdqa %xmm2,-48(%rdi,%rcx)
- movdqa %xmm3,-64(%rdi,%rcx)
-
- subq $64,%rcx
- jne LReverseAlignedLoop
-
- jmp LReverseShort // copy remaining 0..63 bytes and done
-
-
-// Reverse, unaligned loop. LDDQU==MOVDQU on these machines.
-
-LReverseUnalignedLoop: // loop over 64-byte chunks
- movdqu -16(%rsi,%rcx),%xmm0
- movdqu -32(%rsi,%rcx),%xmm1
- movdqu -48(%rsi,%rcx),%xmm2
- movdqu -64(%rsi,%rcx),%xmm3
-
- movdqa %xmm0,-16(%rdi,%rcx)
- movdqa %xmm1,-32(%rdi,%rcx)
- movdqa %xmm2,-48(%rdi,%rcx)
- movdqa %xmm3,-64(%rdi,%rcx)
-
- subq $64,%rcx
- jne LReverseUnalignedLoop
-
- jmp LReverseShort // copy remaining 0..63 bytes and done
-
-PLATFUNC_DESCRIPTOR(bcopy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2)
-PLATFUNC_DESCRIPTOR(memcpy,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2)
-PLATFUNC_DESCRIPTOR(memmove,sse3x,kHasSSE2|kHasSupplementalSSE3|kCache64,kHasSSE4_2)
+++ /dev/null
-/*
- * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-/*
- * The bcopy/memcpy loops, tuned for Nehalem. This is the 64-bit version.
- *
- * The following #defines are tightly coupled to the u-architecture:
- */
-
-#define kShort 80 // too short to bother with SSE (must be >=80)
-
-
-// void bcopy(const void *src, void *dst, size_t len);
-
-PLATFUNC_FUNCTION_START(bcopy, sse42, 64, 5)
- pushq %rbp // set up a frame for backtraces
- movq %rsp,%rbp
- movq %rsi,%rax // copy dest ptr
- movq %rdi,%rsi // xchange source and dest ptrs
- movq %rax,%rdi
- subq %rsi,%rax // (dest - source)
- cmpq %rdx,%rax // must move in reverse if (dest - source) < length
- jb LReverseIsland
- cmpq $(kShort),%rdx // long enough to bother with SSE?
- jbe LShort // no
- jmp LNotShort
-
-//
-// void *memcpy(void *dst, const void *src, size_t len);
-// void *memmove(void *dst, const void *src, size_t len);
-//
-
-PLATFUNC_FUNCTION_START(memcpy, sse42, 64, 0) // void *memcpy(void *dst, const void *src, size_t len)
-PLATFUNC_FUNCTION_START(memmove, sse42, 64, 0) // void *memmove(void *dst, const void *src, size_t len)
- pushq %rbp // set up a frame for backtraces
- movq %rsp,%rbp
- movq %rdi,%r11 // save return value here
- movq %rdi,%rax
- subq %rsi,%rax // (dest - source)
- cmpq %rdx,%rax // must move in reverse if (dest - source) < length
- jb LReverseIsland
- cmpq $(kShort),%rdx // long enough to bother with SSE?
- ja LNotShort // yes
-
-// Handle short forward copies. As the most common case, this is the fall-through path.
-// rdx = length (<= kShort)
-// rsi = source ptr
-// rdi = dest ptr
-
-LShort:
- movl %edx,%ecx // copy length using 32-bit operation
- shrl $2,%ecx // get #doublewords
- jz 3f
-2: // loop copying doublewords
- movl (%rsi),%eax
- addq $4,%rsi
- movl %eax,(%rdi)
- addq $4,%rdi
- decl %ecx
- jnz 2b
-3: // handle leftover bytes (0..3) in last word
- andl $3,%edx // any leftover bytes?
- jz 5f
-4: // loop copying bytes
- movb (%rsi),%al
- incq %rsi
- movb %al,(%rdi)
- incq %rdi
- decl %edx
- jnz 4b
-5:
- movq %r11,%rax // get return value (dst ptr) for memcpy/memmove
- popq %rbp
- ret
-
-
-LReverseIsland: // keep the "jb" above a short branch...
- jmp LReverse // ...because reverse moves are uncommon
-
-
-// Handle forward moves that are long enough to justify use of SSE.
-// First, 16-byte align the destination.
-// rdx = length (> kShort)
-// rsi = source ptr
-// rdi = dest ptr
-
-LNotShort:
- movl %edi,%ecx // copy low half of destination ptr
- negl %ecx
- andl $15,%ecx // get #bytes to align destination
- jz LDestAligned // already aligned
- subl %ecx,%edx // decrement length
-1: // loop copying 1..15 bytes
- movb (%rsi),%al
- inc %rsi
- movb %al,(%rdi)
- inc %rdi
- dec %ecx
- jnz 1b
-
-
-// Destination is now aligned. Nehalem does a great job with unaligned SSE loads,
-// so we use MOVDQU rather than aligned loads and shifts. Since kShort>=80, we
-// know there is at least one 64-byte chunk to move.
-// When we enter the copy loops, the following registers are set up:
-// rdx = residual length (0..63)
-// rcx = -(length to move), a multiple of 64 less than 2GB
-// rsi = ptr to 1st source byte not to move (unaligned)
-// rdi = ptr to 1st dest byte not to move (aligned)
-
-LDestAligned:
- movq %rdx,%rcx // copy length
- andl $63,%edx // get remaining bytes for LShort
- andq $-64,%rcx // get number of bytes we will copy in inner loop
- addq %rcx,%rsi // point to 1st byte not copied
- addq %rcx,%rdi
- negq %rcx // now generate offset to 1st byte to be copied
- testl $15,%esi // source also aligned?
- jnz LUnalignedLoop
- jmp LAlignedLoop
-
-
-// Forward loop for aligned operands.
-
- .align 4,0x90 // 16-byte align inner loops
-LAlignedLoop: // loop over 64-byte chunks
- movdqa (%rsi,%rcx),%xmm0
- movdqa 16(%rsi,%rcx),%xmm1
- movdqa 32(%rsi,%rcx),%xmm2
- movdqa 48(%rsi,%rcx),%xmm3
-
- movdqa %xmm0,(%rdi,%rcx)
- movdqa %xmm1,16(%rdi,%rcx)
- movdqa %xmm2,32(%rdi,%rcx)
- movdqa %xmm3,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz LAlignedLoop
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Forward loop for unaligned operands.
-
- .align 4,0x90 // 16-byte align inner loops
-LUnalignedLoop: // loop over 64-byte chunks
- movdqu (%rsi,%rcx),%xmm0
- movdqu 16(%rsi,%rcx),%xmm1
- movdqu 32(%rsi,%rcx),%xmm2
- movdqu 48(%rsi,%rcx),%xmm3
-
- movdqa %xmm0,(%rdi,%rcx)
- movdqa %xmm1,16(%rdi,%rcx)
- movdqa %xmm2,32(%rdi,%rcx)
- movdqa %xmm3,48(%rdi,%rcx)
-
- addq $64,%rcx
- jnz LUnalignedLoop
-
- jmp LShort // copy remaining 0..63 bytes and done
-
-
-// Reverse moves. These are only used with destructive overlap.
-// rdx = length
-// rsi = source ptr
-// rdi = dest ptr
-
-LReverse:
- addq %rdx,%rsi // point to end of strings
- addq %rdx,%rdi
- cmpq $(kShort),%rdx // long enough to bother with SSE?
- ja LReverseNotShort // yes
-
-// Handle reverse short copies.
-// edx = length (<= kShort)
-// rsi = one byte past end of source
-// rdi = one byte past end of dest
-
-LReverseShort:
- movl %edx,%ecx // copy length
- shrl $3,%ecx // #quadwords
- jz 3f
-1:
- subq $8,%rsi
- movq (%rsi),%rax
- subq $8,%rdi
- movq %rax,(%rdi)
- decl %ecx
- jnz 1b
-3:
- andl $7,%edx // bytes?
- jz 5f
-4:
- decq %rsi
- movb (%rsi),%al
- decq %rdi
- movb %al,(%rdi)
- decl %edx
- jnz 4b
-5:
- movq %r11,%rax // get return value (dst ptr) for memcpy/memmove
- popq %rbp
- ret
-
-// Handle a reverse move long enough to justify using SSE.
-// rdx = length (> kShort)
-// rsi = one byte past end of source
-// rdi = one byte past end of dest
-
-LReverseNotShort:
- movl %edi,%ecx // copy destination
- andl $15,%ecx // get #bytes to align destination
- jz LReverseDestAligned // already aligned
- subq %rcx,%rdx // adjust length
-1: // loop copying 1..15 bytes
- decq %rsi
- movb (%rsi),%al
- decq %rdi
- movb %al,(%rdi)
- decl %ecx
- jnz 1b
-
-// Destination is now aligned. Prepare for reverse loops.
-
-LReverseDestAligned:
- movq %rdx,%rcx // copy length
- andl $63,%edx // get remaining bytes for LReverseShort
- andq $-64,%rcx // get number of bytes we will copy in inner loop
- subq %rcx,%rsi // point to endpoint of copy
- subq %rcx,%rdi
- testl $15,%esi // is source aligned too?
- jnz LReverseUnalignedLoop // no
-
-LReverseAlignedLoop: // loop over 64-byte chunks
- movdqa -16(%rsi,%rcx),%xmm0
- movdqa -32(%rsi,%rcx),%xmm1
- movdqa -48(%rsi,%rcx),%xmm2
- movdqa -64(%rsi,%rcx),%xmm3
-
- movdqa %xmm0,-16(%rdi,%rcx)
- movdqa %xmm1,-32(%rdi,%rcx)
- movdqa %xmm2,-48(%rdi,%rcx)
- movdqa %xmm3,-64(%rdi,%rcx)
-
- subq $64,%rcx
- jne LReverseAlignedLoop
-
- jmp LReverseShort // copy remaining 0..63 bytes and done
-
-
-// Reverse, unaligned loop. LDDQU==MOVDQU on these machines.
-
-LReverseUnalignedLoop: // loop over 64-byte chunks
- movdqu -16(%rsi,%rcx),%xmm0
- movdqu -32(%rsi,%rcx),%xmm1
- movdqu -48(%rsi,%rcx),%xmm2
- movdqu -64(%rsi,%rcx),%xmm3
-
- movdqa %xmm0,-16(%rdi,%rcx)
- movdqa %xmm1,-32(%rdi,%rcx)
- movdqa %xmm2,-48(%rdi,%rcx)
- movdqa %xmm3,-64(%rdi,%rcx)
-
- subq $64,%rcx
- jne LReverseUnalignedLoop
-
- jmp LReverseShort // copy remaining 0..63 bytes and done
-
-
-PLATFUNC_DESCRIPTOR(bcopy,sse42,kHasSSE4_2,0)
-PLATFUNC_DESCRIPTOR(memcpy,sse42,kHasSSE4_2,0)
-PLATFUNC_DESCRIPTOR(memmove,sse42,kHasSSE4_2,0)
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse42)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(bzero, sse2)
-
-static const platfunc_descriptor *bzero_platfunc_descriptors[] = {
- PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse42),
- PLATFUNC_DESCRIPTOR_REFERENCE(bzero, sse2),
- 0
-};
-
-void *bzero_chooser() __asm__("_bzero");
-void *bzero_chooser() {
- __asm__(".desc _bzero, 0x100");
- return find_platform_function((const platfunc_descriptor **) bzero_platfunc_descriptors);
-}
+++ /dev/null
-/*
- * Copyright (c) 2008 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-/*
- * Bzero, tuned for processors with SSE4.2 and 64-byte cache lines, ie Nehalem.
- * We don't actually use SSE4.2, but rather use it to identify Nehalem.
- * This is the 64-bit version.
- *
- * We do not use nontemporal operations, but use MOVDQA in preference to REP/STOS.
- *
- * This routine is also used for memset(p,0,n), which is a common case
- * since gcc sometimes silently maps bzero() into memset(). As a result,
- * we always load the original ptr into %eax before returning.
- */
-
-#define kShort 80 // too short to bother with SSE (must be >=80)
-
-
-// void bzero(void *b, size_t len);
-
-PLATFUNC_FUNCTION_START(bzero, sse42, 64, 5)
- pushq %rbp // set up a frame for backtraces
- movq %rsp,%rbp
- xorl %eax,%eax // set fill data to 0
- movq %rdi,%r11 // save original ptr as return value
- cmpq $(kShort),%rsi // long enough for SSE?
- jg LNotShort // yes
-
-// Here for short operands or the end of long ones.
-// %esi = length (<= kShort)
-// %rdi = ptr
-// %eax = zero
-
-Lshort:
- cmpl $12,%esi // long enough to word align?
- jge 3f // yes
- test %esi,%esi // length==0?
- jz 6f
-1:
- movb %al,(%rdi) // zero a byte
- incq %rdi
- decl %esi
- jnz 1b
- jmp 6f
-2:
- movb %al,(%rdi) // zero a byte
- incq %rdi
- decl %esi
-3:
- testl $3,%edi // is ptr doubleword aligned?
- jnz 2b // no
- movl %esi,%ecx // copy length
- shrl $2,%esi // #doublewords to store
-4:
- movl %eax,(%rdi) // zero an aligned doubleword
- addq $4,%rdi
- decl %esi
- jnz 4b
- andl $3,%ecx // mask down to #bytes at end (0..3)
- jz 6f // none
-5:
- movb %al,(%rdi) // zero a byte
- incq %rdi
- decl %ecx
- jnz 5b
-6:
- movq %r11,%rax // set return value in case this was a call of memset()
- popq %rbp
- ret
-
-
-// We will be using SSE, so align ptr.
-// %rsi = length (> kShort)
-// %rdi = ptr
-// %eax = zero
-
-LNotShort:
- testl $3,%edi // 4-byte aligned?
- jz 2f // yes
- movb %al,(%rdi) // zero another byte
- incq %rdi
- decq %rsi
- jmp LNotShort
-1: // zero doublewords until 16-byte aligned
- movl %eax,(%rdi)
- addq $4,%rdi
- subq $4,%rsi
-2:
- testl $15,%edi // 16-byte aligned?
- jnz 1b // no
-
-// Destination is now 16-byte aligned. Prepare to loop over 64-byte chunks.
-// %rsi = length (> (kShort-15))
-// %rdi = ptr (aligned)
-// %eax = zero
-
-LDestAligned:
- movq %rsi,%rcx
- andl $63,%esi // mask down to residual length (0..63)
- andq $-64,%rcx // get #bytes we will zero in this loop
- pxor %xmm0,%xmm0 // zero an SSE register
- addq %rcx,%rdi // increment ptr by length to move
- negq %rcx // negate length to move
- jmp 1f
-
-// Loop over 64-byte chunks, storing into cache.
-
- .align 4,0x90 // keep inner loops 16-byte aligned
-1:
- movdqa %xmm0,(%rdi,%rcx)
- movdqa %xmm0,16(%rdi,%rcx)
- movdqa %xmm0,32(%rdi,%rcx)
- movdqa %xmm0,48(%rdi,%rcx)
- addq $64,%rcx
- jne 1b
-
- jmp Lshort
-
-
-PLATFUNC_DESCRIPTOR(bzero,sse42,kHasSSE4_2,0)
+++ /dev/null
-/*
- * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
- .text
-
- .align 2
- .globl _ffs
-_ffs:
- movl $(-1), %edx
- bsfl %edi, %eax
- cmovel %edx, %eax
- incl %eax
- ret
-
-
- .align 2
- .globl _ffsl
-_ffsl:
- movl $(-1), %edx
- bsfq %rdi, %rax
- cmovel %edx, %eax
- incl %eax
- ret
-
-
- .align 2
- .globl _fls
-_fls:
- movl $(-1), %edx
- bsrl %edi, %eax
- cmovel %edx, %eax
- incl %eax
- ret
-
-
- .align 2
- .globl _flsl
-_flsl:
- movl $(-1), %edx
- bsrq %rdi, %rax
- cmovel %edx, %eax
- incl %eax
- ret
+++ /dev/null
-/*
- * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-
-/*
- * The bcopy/memcpy loops for very long operands, tuned for 64-bit
- * Pentium-M class processors with Supplemental SSE3 and 64-byte cache lines.
- * This is the 64-bit version.
- *
- * The following #defines are tightly coupled to the u-architecture:
- */
-
-#define kBigChunk (256*1024) // outer loop chunk size for kVeryLong sized operands
-
-
-// Very long forward moves. These are at least several pages, so we loop over big
-// chunks of memory (kBigChunk in size.) We first prefetch the chunk, and then copy
-// it using non-temporal stores. Hopefully all the reads occur in the prefetch loop,
-// so the copy loop reads from L2 and writes directly to memory (with write combining.)
-// This minimizes bus turnaround and maintains good DRAM page locality.
-// Note that for this scheme to work, kVeryLong must be a large fraction of L2 cache
-// size. Otherwise, it is counter-productive to bypass L2 on the stores.
-//
-// We are called from the platfunc bcopy loops when they encounter very long
-// operands, with the standard ABI:
-// rdi = dest ptr
-// rsi = source ptr
-// rdx = length (>= 8kb, probably much bigger)
-
-// void longcopy(const void *dest, void *sou, size_t len)
-
- .private_extern _longcopy
-_longcopy:
- pushq %rbp // set up a frame for backtraces
- movq %rsp,%rbp
- movl %edi,%eax // copy dest ptr
- negl %eax
- andl $63,%eax // get #bytes to cache line align destination
- jz LBigChunkLoop // already aligned
-
- // Cache line align destination, so temporal stores in copy loops work right.
- // The recursive call returns with the source and dest ptrs properly updated.
-
- subq %rax,%rdx // get length remaining after dest is aligned
- pushq %rdx // save length remaining
- movl %eax,%edx // #bytes to copy to align destination
- call _memcpy
- popq %rdx // recover adjusted length
-
-// Loop over big chunks.
-// rdx = length remaining (>= 4096)
-// rdi = dest (64-byte aligned)
-// rsi = source (may be unaligned)
-
-LBigChunkLoop:
- movl $(kBigChunk),%r8d // assume we can do a full chunk
- cmpq %r8,%rdx // do we have a full chunk left to do?
- cmovbl %edx,%r8d // if not, only move what we have left
- andl $-4096,%r8d // we work in page multiples
- xorl %eax,%eax // initialize chunk offset
- jmp LTouchLoop
-
-// Touch in the next chunk. We try to keep the prefetch unit in "kick-start" mode,
-// by touching two adjacent cache lines every 8 lines of each page, in four slices.
-// Because the source may be unaligned, we use byte loads to touch.
-// rdx = length remaining (including this chunk)
-// rdi = ptr to start of dest chunk
-// rsi = ptr to start of source chunk
-// r8d = chunk length (multiples of pages, less than 2**32)
-// ecx = scratch reg used to read a byte of each cache line
-// eax = chunk offset
-
- .align 4,0x90 // 16-byte align inner loops
-LTouchLoop:
- movzb (%rsi,%rax),%ecx // touch line 0, 2, 4, or 6 of page
- movzb 1*64(%rsi,%rax),%ecx // touch line 1, 3, 5, or 7
- movzb 8*64(%rsi,%rax),%ecx // touch line 8, 10, 12, or 14
- movzb 9*64(%rsi,%rax),%ecx // etc
-
- movzb 16*64(%rsi,%rax),%ecx
- movzb 17*64(%rsi,%rax),%ecx
- movzb 24*64(%rsi,%rax),%ecx
- movzb 25*64(%rsi,%rax),%ecx
-
- movzb 32*64(%rsi,%rax),%ecx
- movzb 33*64(%rsi,%rax),%ecx
- movzb 40*64(%rsi,%rax),%ecx
- movzb 41*64(%rsi,%rax),%ecx
-
- movzb 48*64(%rsi,%rax),%ecx
- movzb 49*64(%rsi,%rax),%ecx
- movzb 56*64(%rsi,%rax),%ecx
- movzb 57*64(%rsi,%rax),%ecx
-
- subl $-128,%eax // next slice of page (adding 128 w 8-bit immediate)
- testl $512,%eax // done with this page?
- jz LTouchLoop // no, next of four slices
- addl $(4096-512),%eax // move on to next page
- cmpl %eax,%r8d // done with this chunk?
- jnz LTouchLoop // no, do next page
-
- // The chunk has been pre-fetched, now copy it using non-temporal stores.
- // There are two copy loops, depending on whether the source is 16-byte aligned
- // or not.
-
- movl %r8d,%ecx // copy chunk size to a reg that doesn't use REX prefix
- addq %rcx,%rsi // increment ptrs by chunk length
- addq %rcx,%rdi
- subq %rcx,%rdx // adjust remaining length
- negq %rcx // prepare loop index (counts up to 0)
- testl $15,%esi // is source 16-byte aligned?
- jnz LVeryLongUnaligned // no
- jmp LVeryLongAligned
-
- .align 4,0x90 // 16-byte align inner loops
-LVeryLongAligned: // aligned loop over 128-bytes
- movdqa (%rsi,%rcx),%xmm0
- movdqa 16(%rsi,%rcx),%xmm1
- movdqa 32(%rsi,%rcx),%xmm2
- movdqa 48(%rsi,%rcx),%xmm3
- movdqa 64(%rsi,%rcx),%xmm4
- movdqa 80(%rsi,%rcx),%xmm5
- movdqa 96(%rsi,%rcx),%xmm6
- movdqa 112(%rsi,%rcx),%xmm7
-
- movntdq %xmm0,(%rdi,%rcx)
- movntdq %xmm1,16(%rdi,%rcx)
- movntdq %xmm2,32(%rdi,%rcx)
- movntdq %xmm3,48(%rdi,%rcx)
- movntdq %xmm4,64(%rdi,%rcx)
- movntdq %xmm5,80(%rdi,%rcx)
- movntdq %xmm6,96(%rdi,%rcx)
- movntdq %xmm7,112(%rdi,%rcx)
-
- subq $-128,%rcx // add 128 with an 8-bit immediate
- jnz LVeryLongAligned
- jmp LVeryLongChunkEnd
-
- .align 4,0x90 // 16-byte align inner loops
-LVeryLongUnaligned: // unaligned loop over 128-bytes
- movdqu (%rsi,%rcx),%xmm0
- movdqu 16(%rsi,%rcx),%xmm1
- movdqu 32(%rsi,%rcx),%xmm2
- movdqu 48(%rsi,%rcx),%xmm3
- movdqu 64(%rsi,%rcx),%xmm4
- movdqu 80(%rsi,%rcx),%xmm5
- movdqu 96(%rsi,%rcx),%xmm6
- movdqu 112(%rsi,%rcx),%xmm7
-
- movntdq %xmm0,(%rdi,%rcx)
- movntdq %xmm1,16(%rdi,%rcx)
- movntdq %xmm2,32(%rdi,%rcx)
- movntdq %xmm3,48(%rdi,%rcx)
- movntdq %xmm4,64(%rdi,%rcx)
- movntdq %xmm5,80(%rdi,%rcx)
- movntdq %xmm6,96(%rdi,%rcx)
- movntdq %xmm7,112(%rdi,%rcx)
-
- subq $-128,%rcx // add 128 with an 8-bit immediate
- jnz LVeryLongUnaligned
-
-LVeryLongChunkEnd:
- cmpq $4096,%rdx // at least another page to go?
- jae LBigChunkLoop // yes
-
- // Done. Call memcpy() again to handle the 0-4095 bytes at the end.
- // We still have the args in the right registers:
- // rdi = destination ptr
- // rsi = source ptr
- // rdx = length remaining (0..4095)
-
- sfence // required by non-temporal stores
- testl %edx,%edx // anything left to copy?
- jz 1f
- call _memcpy
-1:
- popq %rbp // restore frame ptr
- ret
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// *************** ***********
-// * M E M C M P * and * B C M P *
-// *************** ***********
-//
-// int memcmp(const char *s1, const char *s2, size_t len);
-// int bcmp(const char *s1, const char *s2, size_t len);
-//
-// Bcmp returns (+,0,-), whereas memcmp returns the true difference
-// between the first differing bytes, but we treat them identically.
-//
-// We optimize the compare by doing it with SSE. This introduces
-// a complication: if we blindly did vector loads from both sides until
-// finding a difference, we might get a spurious page fault by
-// reading bytes past the difference. To avoid this, we never do a load
-// that crosses a page boundary.
-
-#define kShort 18 // too short for vectors (must be >16)
-
- .text
- .align 4
-
- .globl _memcmp
- .globl _bcmp
-
-_memcmp: // int memcmp(const char *s1,const char *s2,size_t len);
-_bcmp: // int bcmp(const char *s1,const char *s2,size_t len);
- cmpq $(kShort),%rdx // worth accelerating?
- ja LNotShort // yes
-
-
-// Too short to bother with parallel compares. Loop over bytes.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-// %edx = length (<= kShort)
-
-LShort:
- testl %edx,%edx // 0-length?
- jnz LShortLoop // no
- xorq %rax,%rax // return 0
- jmp LExit
- .align 4,0x90 // align inner loops to optimize I-fetch
-LShortLoop: // loop over bytes
- movzb (%rdi),%eax // get LHS byte
- movzb (%rsi),%ecx // get RHS byte
- addq $1,%rdi
- addq $1,%rsi
- subl %ecx,%eax // compare them
- jnz LExit // done if not equal
- subq $1,%rdx // decrement length
- jnz LShortLoop
-LExit: // return value is in %eax
- ret
-
-LNotEqual: // here from LLoopOverBytes with LHS in eax
- movzb (%rsi),%ecx // get RHS byte
- subl %ecx,%eax // generate return value (nonzero)
- ret
-
-
-// Loop over bytes until we reach end of a page.
-// %rdi = LHS ptr
-// %edi = RHS ptr
-// %rdx = length remaining after end of loop (i.e., already adjusted)
-// %ecx = #bytes until next page (1..15)
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%rdi),%eax // get LHS byte
- addq $1,%rdi
- cmpb (%rsi),%al // compare to RHS byte
- jnz LNotEqual // done if not equal
- addq $1,%rsi
- subl $1,%ecx // more to go?
- jnz LLoopOverBytes
-
-
-// Long enough to justify overhead of setting up vector compares. In order to
-// avoid spurious page faults, we loop over:
-//
-// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4
-//
-// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte
-// comparison until reaching the next page, then resume the vector comparison.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-// %rdx = length (> kShort)
-
-LNotShort:
- movq %rdi,%rax // copy ptrs
- movq %rsi,%rcx
- andq $4095,%rax // mask down to page offsets
- andq $4095,%rcx
- cmpq %rax,%rcx // which is bigger?
- cmova %rcx,%rax // %eax = max(LHS offset, RHS offset);
- movl $4096,%ecx
- subl %eax,%ecx // get #bytes to next page crossing
- cmpq %rdx,%rcx // will operand run out first?
- cmova %edx,%ecx // get min(length remaining, bytes to page end)
- movl %ecx,%eax
- shrl $4,%ecx // get #chunks till end of operand or page
- jnz LLoopOverChunks // enter vector loop
-
-// Too near page end for vectors.
-
- subq %rax,%rdx // adjust length remaining
- movl %eax,%ecx // %ecx <- #bytes to page end
- cmpq $(kShort),%rdx // will there be enough after we cross page for vectors?
- ja LLoopOverBytes // yes
- addq %rax,%rdx // no, restore total length remaining
- jmp LShortLoop // compare rest byte-by-byte (%ecx != 0)
-
-
-// Loop over 16-byte chunks.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-// %rdx = length remaining
-// %ecx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%rdi),%xmm0 // get LHS
- movdqu (%rsi),%xmm1 // get RHS
- addq $16,%rdi
- pcmpeqb %xmm1,%xmm0 // compare LHS to RHS
- addq $16,%rsi
- pmovmskb %xmm0,%eax // collect comparison result bits (1 if equal)
- subq $16,%rdx // adjust length remaining
- xorl $0xFFFF,%eax // all equal?
- jne LDifferent // no, we found differing bytes
- subl $1,%ecx // more to go?
- jnz LLoopOverChunks
-
- cmpq $(kShort),%rdx // a lot more to compare?
- jbe LShort // no
- jmp LNotShort // compute distance to next page crossing etc
-
-
-// Found a difference.
-// %rdi = LHS ptr, already advanced by 16
-// %rsi = RHS ptr, already advanced by 16
-// %eax = complemented compare vector (ie, 0 == equal)
-
-LDifferent:
- bsf %eax,%edx // which byte differed?
- subq $16,%rdi // point to byte 0 while we wait for bit scan
- subq $16,%rsi
- movzb (%rdi,%rdx),%eax // get LHS byte
- movzb (%rsi,%rdx),%ecx // get RHS byte
- subl %ecx,%eax // compute difference (ie, return value)
- ret
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse42)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memcpy, sse3x)
-
-static const platfunc_descriptor *memcpy_platfunc_descriptors[] = {
- PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse42),
- PLATFUNC_DESCRIPTOR_REFERENCE(memcpy, sse3x),
- 0
-};
-
-void *memcpy_chooser() __asm__("_memcpy");
-void *memcpy_chooser() {
- __asm__(".desc _memcpy, 0x100");
- return find_platform_function((const platfunc_descriptor **) memcpy_platfunc_descriptors);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse42)
-PLATFUNC_DESCRIPTOR_PROTOTYPE(memmove, sse3x)
-
-static const platfunc_descriptor *memmove_platfunc_descriptors[] = {
- PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse42),
- PLATFUNC_DESCRIPTOR_REFERENCE(memmove, sse3x),
- 0
-};
-
-void *memmove_chooser() __asm__("_memmove");
-void *memmove_chooser() {
- __asm__(".desc _memmove, 0x100");
- return find_platform_function((const platfunc_descriptor **) memmove_platfunc_descriptors);
-}
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-
-
-/* This file contains the following functions:
- *
- * void *memset(void *b, int c, size_t len);
- * void memset_pattern4(void *b, const void *c4, size_t len);
- * void memset_pattern8(void *b, const void *c8, size_t len);
- * void memset_pattern16(void *b, const void *c16, size_t len);
- *
- * Calls of memset() with c==0 are routed to the bzero() routine. Most of the
- * others go to _memset_pattern, which is entered as follows:
- * %rdi = ptr to memory to set (aligned)
- * %edx = length (which can be short, though we bias in favor of long operands)
- * %xmm0 = the pattern to store
- * Return conditions:
- * %eax, %edi, %esi, %ecx, and %edx all trashed
- *
- * NB: we avoid "stos" family of instructions (stosl, stosb), as they are very slow
- * on P4s and probably other processors.
- */
-
-#define kShort 255 // for nonzero memset(), too short for commpage
-
-
- .text
- .globl _memset
- .align 2
-_memset: // void *memset(void *b, int c, size_t len);
- andl $0xFF,%esi // (c==0) ?
- jnz LNonzero // not a bzero
-
- movq %rdx,%rsi // put count where bzero() expects it
- jmp _bzero // enter _bzero
-
-
-// Handle memset of a nonzero value.
-
-LNonzero:
- movq %rdi,%r8 // preserve the original pointer so we can return it
- movl %esi,%eax // replicate byte in %esi into all four bytes
- shll $8,%esi
- orl %esi,%eax
- movl %eax,%esi
- shll $16,%esi
- orl %esi,%eax // now %eax has "c" in all 4 bytes
- cmpq $(kShort),%rdx // is operand too short for SSE?
- ja LCallCommpage // no
-
- // Nonzero memset() too short to call commpage.
- // %eax = replicated 4-byte pattern
- // %rdi = ptr
- // %edx = length (<= kShort)
-
- cmpl $16,%edx // long enough to word align?
- jge 3f // yes
- test %edx,%edx // length==0?
- jz 6f
-1:
- movb %al,(%rdi) // pack in a byte
- addq $1,%rdi
- subl $1,%edx
- jnz 1b
- jmp 6f
-2:
- movb %al,(%rdi) // pack in a byte
- addq $1,%rdi
- subl $1,%edx
-3:
- test $3,%edi // is ptr doubleword aligned?
- jnz 2b // no
- movl %edx,%ecx // copy length
- shrl $2,%edx // #doublewords to store
-4:
- movl %eax,(%rdi) // store aligned doubleword
- addq $4,%rdi
- subl $1,%edx
- jnz 4b
- andl $3,%ecx // any leftover bytes?
- jz 6f // no
-5:
- movb %al,(%rdi) // pack in a byte
- addq $1,%rdi
- subl $1,%ecx
- jnz 5b
-6:
- movq %r8,%rax // get return value (ie, original ptr)
- ret
-
- // Nonzero memset() is long enough to call commpage.
- // %eax = replicated 4-byte pattern
- // %rdi = ptr
- // %rdx = length (> kShort)
-
-LCallCommpage:
- movd %eax,%xmm0 // move %eax to low 4 bytes of %xmm0
- pshufd $(0x00),%xmm0,%xmm0 // replicate across the vector
- movq %rdi,%rcx // copy dest ptr
- negl %ecx
- andl $15,%ecx // get #bytes to align ptr
- jz 2f // skip if already aligned
- subq %rcx,%rdx // decrement length
-1:
- movb %al,(%rdi) // pack in a byte
- addq $1,%rdi
- subl $1,%ecx
- jnz 1b
-2: // ptr aligned, length long enough to justify
- call Lmemset_pattern // call commpage to do the heavy lifting
- movq %r8,%rax // get return value (ie, original ptr)
- ret
-
-
- // Handle memset of a 16-byte pattern.
-
- .globl _memset_pattern16
- .align 2, 0x90
-_memset_pattern16: // void memset_pattern16(void *b, const void *c16, size_t len);
- movdqu (%rsi),%xmm0 // load the pattern
- jmp LAlignPtr
-
-
- // Handle memset of an 8-byte pattern.
-
- .globl _memset_pattern8
- .align 2, 0x90
-_memset_pattern8: // void memset_pattern8(void *b, const void *c8, size_t len);
- movq (%rsi),%xmm0 // load pattern into low 8 bytes
- punpcklqdq %xmm0,%xmm0 // replicate into all 16
- jmp LAlignPtr
-
- // Handle memset of a 4-byte pattern.
-
- .globl _memset_pattern4
- .align 2, 0x90
-_memset_pattern4: // void memset_pattern4(void *b, const void *c4, size_t len);
- movd (%rsi),%xmm0 // load pattern into low 4 bytes
- pshufd $(0x00),%xmm0,%xmm0 // replicate the 4 bytes across the vector
-
-
- // Align ptr if necessary. We must rotate the pattern right for each byte we
- // store while aligning the ptr. Since there is no rotate instruction in SSE3,
- // we have to synthesize the rotates.
- // %rdi = ptr
- // %rdx = length
- // %xmm0 = pattern
-
-LAlignPtr: // NB: can drop down to here!
- cmpq $100,%rdx // long enough to bother aligning ptr?
- movq %rdi,%rcx // copy ptr
- jb LReady // not long enough
- negl %ecx
- andl $15,%ecx // get #bytes to align ptr
- jz LReady // already aligned
- subq %rcx,%rdx // adjust length
-
- test $1,%cl // 1-byte store required?
- movd %xmm0,%eax // get 4 low bytes in %eax
- jz 2f // no
- movdqa %xmm0,%xmm1 // copy pattern so we can shift in both directions
- movb %al,(%rdi) // pack in the low-order byte
- psrldq $1,%xmm0 // shift pattern right 1 byte
- addq $1,%rdi
- pslldq $15,%xmm1 // shift pattern left 15 bytes
- shrl $8,%eax // in case 2-byte store is required
- por %xmm1,%xmm0 // complete right rotate of pattern by 1 byte
-2:
- test $2,%cl // 2-byte store required?
- jz 4f // no
- psrldq $2,%xmm0 // shift pattern down 2 bytes
- movw %ax,(%rdi) // pack in next two bytes
- pinsrw $7,%eax,%xmm0 // insert low word of %eax into high word of %xmm0
- addq $2,%rdi // adjust ptr
-4:
- test $4,%cl // 4-byte store required?
- jz 8f // no
- movd %xmm0,(%rdi) // store low 4 bytes of %xmm0
- pshufd $(0x39),%xmm0,%xmm0 // rotate %xmm0 right 4 bytes (mask == 00 11 10 01)
- addq $4,%rdi // adjust ptr
-8:
- test $8,%cl // 8-byte store required?
- jz LReady // no
- movq %xmm0,(%rdi) // store low 8 bytes of %xmm0
- pshufd $(0x4e),%xmm0,%xmm0 // rotate %xmm0 right 8 bytes (mask == 01 00 11 10)
- addq $8,%rdi // adjust ptr
-
- // Ptr is aligned if practical, we're ready to call commpage to do the heavy lifting.
-
-LReady:
- call Lmemset_pattern // call commpage to do the heavy lifting
- ret
-
-
-#define kLShort 63
-#define kVeryLong (1024*1024)
-
-Lmemset_pattern:
- cmpq $(kLShort),%rdx // long enough to bother aligning?
- ja LNotShort // yes
- jmp LShort // no
-
- // Here for short operands or the end of long ones.
- // %rdx = length (<= kLShort)
- // %rdi = ptr (may not be not aligned)
- // %xmm0 = pattern
-
-LUnalignedStore16:
- movdqu %xmm0,(%rdi) // stuff in another 16 bytes
- subl $16,%edx
- addq $16,%rdi
-LShort:
- cmpl $16,%edx // room for another vector?
- jge LUnalignedStore16 // yes
-LLessThan16: // here at end of copy with < 16 bytes remaining
- test $8,%dl // 8-byte store required?
- jz 2f // no
- movq %xmm0,(%rdi) // pack in 8 low bytes
- psrldq $8,%xmm0 // then shift vector down 8 bytes
- addq $8,%rdi
-2:
- test $4,%dl // 4-byte store required?
- jz 3f // no
- movd %xmm0,(%rdi) // pack in 4 low bytes
- psrldq $4,%xmm0 // then shift vector down 4 bytes
- addq $4,%rdi
-3:
- andl $3,%edx // more to go?
- jz 5f // no
- movd %xmm0,%eax // move remainders out into %eax
-4: // loop on up to three bytes
- movb %al,(%rdi) // pack in next byte
- shrl $8,%eax // shift next byte into position
- incq %rdi
- dec %edx
- jnz 4b
-5: ret
-
-// Long enough to justify aligning ptr. Note that we have to rotate the
-// pattern to account for any alignment. We do this by doing two unaligned
-// stores, and then an aligned load from the middle of the two stores.
-// This will stall on store forwarding alignment mismatch, and the unaligned
-// stores can be pretty slow too, but the alternatives aren't any better.
-// Fortunately, in most cases our caller has already aligned the ptr.
-// %rdx = length (> kLShort)
-// %rdi = ptr (may not be aligned)
-// %xmm0 = pattern
-
-LNotShort:
- movl %edi,%ecx // copy low bits of dest ptr
- negl %ecx
- andl $15,%ecx // mask down to #bytes to 16-byte align
- jz LAligned // skip if already aligned
- movdqu %xmm0,(%rdi) // store 16 unaligned bytes
- movdqu %xmm0,16(%rdi) // and 16 more, to be sure we have an aligned chunk
- addq %rcx,%rdi // now point to the aligned chunk
- subq %rcx,%rdx // adjust remaining count
- movdqa (%rdi),%xmm0 // get the rotated pattern (probably stalling)
- addq $16,%rdi // skip past the aligned chunk
- subq $16,%rdx
-
-// Set up for 64-byte loops.
-// %rdx = length remaining
-// %rdi = ptr (aligned)
-// %xmm0 = rotated pattern
-
-LAligned:
- movq %rdx,%rcx // copy length remaining
- andl $63,%edx // mask down to residual length (0..63)
- andq $-64,%rcx // %ecx <- #bytes we will zero in by-64 loop
- jz LNoMoreChunks // no 64-byte chunks
- addq %rcx,%rdi // increment ptr by length to move
- cmpq $(kVeryLong),%rcx // long enough to justify non-temporal stores?
- jge LVeryLong // yes
- negq %rcx // negate length to move
- jmp 1f
-
-// Loop over 64-byte chunks, storing into cache.
-
- .align 4,0x90 // keep inner loops 16-byte aligned
-1:
- movdqa %xmm0,(%rdi,%rcx)
- movdqa %xmm0,16(%rdi,%rcx)
- movdqa %xmm0,32(%rdi,%rcx)
- movdqa %xmm0,48(%rdi,%rcx)
- addq $64,%rcx
- jne 1b
-
- jmp LNoMoreChunks
-
-// Very long operands: use non-temporal stores to bypass cache.
-
-LVeryLong:
- negq %rcx // negate length to move
- jmp 1f
-
- .align 4,0x90 // keep inner loops 16-byte aligned
-1:
- movntdq %xmm0,(%rdi,%rcx)
- movntdq %xmm0,16(%rdi,%rcx)
- movntdq %xmm0,32(%rdi,%rcx)
- movntdq %xmm0,48(%rdi,%rcx)
- addq $64,%rcx
- jne 1b
-
- sfence // required by non-temporal stores
- jmp LNoMoreChunks
-
-// Handle leftovers: loop by 16.
-// %edx = length remaining (<64)
-// %edi = ptr (aligned)
-// %xmm0 = rotated pattern
-
-LLoopBy16:
- movdqa %xmm0,(%rdi) // pack in 16 more bytes
- subl $16,%edx // decrement count
- addq $16,%rdi // increment ptr
-LNoMoreChunks:
- cmpl $16,%edx // more to go?
- jge LLoopBy16 // yes
- jmp LLessThan16 // handle up to 15 remaining bytes
+++ /dev/null
-/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// ***************
-// * S T R C M P *
-// ***************
-//
-// int strcmp(const char *s1, const char *s2);
-//
-// We optimize the compare by doing it in parallel, using SSE. This introduces
-// a complication: if we blindly did vector loads from both sides until
-// finding a difference (or 0), we might get a spurious page fault by
-// reading bytes past the difference. To avoid this, we never do a load
-// that crosses a page boundary.
-
- .text
- .globl _strcmp
-
- .align 4
-_strcmp: // int strcmp(const char *s1,const char *s2);
-
-// In order to avoid spurious page faults, we loop over:
-//
-// min( bytes_in_LHS_page, bytes_in_RHS_page) >> 4
-//
-// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte
-// comparison until reaching the next page, then resume the vector comparison.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-
-LNextChunk:
- movl %edi,%eax // copy low 4 bytes of each ptr
- movl %esi,%edx
- andl $4095,%eax // mask down to page offsets
- andl $4095,%edx
- cmpl %eax,%edx // which is bigger?
- cmova %edx,%eax // %eax = max(LHS offset, RHS offset);
- movl $4096,%edx
- subl %eax,%edx // get #bytes to next page crossing
- movl %edx,%eax
- shrl $4,%edx // get #chunks till end of operand or page
- jnz LLoopOverChunks // enter vector loop
- movl %eax,%edx // no chunks...
- jmp LLoopOverBytes // ...so loop over bytes until page end
-
-
-// Loop over bytes.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-// %edx = byte count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%rdi),%eax // get LHS byte
- movzb (%rsi),%ecx // get RHS byte
- addq $1,%rdi
- addq $1,%rsi
- testl %eax,%eax // 0?
- jz LExit0 // yes, we're done
- subl %ecx,%eax // compare them
- jnz LExit // done if not equal
- subl $1,%edx // more to go?
- jnz LLoopOverBytes
-
- jmp LNextChunk // we've come to end of page
-
-
-// Loop over 16-byte chunks.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-// %edx = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%rdi),%xmm1 // get LHS
- movdqu (%rsi),%xmm2 // get RHS
- pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads
- addq $16,%rdi
- pcmpeqb %xmm1,%xmm2 // compare LHS to RHS
- pcmpeqb %xmm1,%xmm0 // compare LHS to 0s
- addq $16,%rsi
- pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS
- pmovmskb %xmm0,%ecx // get result mask for 0 check
- xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal"
- orl %ecx,%eax // combine the masks and check for 1-bits
- jnz LFoundDiffOr0 // we found differing bytes or a 0-byte
- subl $1,%edx // more to go?
- jnz LLoopOverChunks
-
- jmp LNextChunk // compare up to next page boundary
-
-
-// Found a zero and/or a difference in vector compare.
-// %rdi = LHS ptr, already advanced by 16
-// %rsi = RHS ptr, already advanced by 16
-// %eax = bit n set if bytes n differed or were 0
-
-LFoundDiffOr0:
- bsf %eax,%edx // which byte differed or was 0?
- subq $16,%rdi // point to start of vectors while we wait for bit scan
- subq $16,%rsi
- movzb (%rdi,%rdx),%eax // get LHS byte
- movzb (%rsi,%rdx),%ecx // get RHS byte
- subl %ecx,%eax // compute difference (ie, return value)
- ret
-
-
-// Found a zero and/or difference in byte loop.
-// %eax = LHS byte
-// %ecx = RHS byte
-
-LExit0:
- subl %ecx,%eax // compute difference (ie, return value)
-LExit: // here with difference already in %eax
- ret
/*
- * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* Please see the License for the specific language governing rights and
* limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ *
+ * This file implements strcpy( ) for the x86_64 architecture.
*/
+.globl _strcpy
-// ***************
-// * S T R C P Y *
-// ***************
-//
-// char *strcpy(const char *dst, const char *src);
-//
-// We optimize the move by doing it vector parallel. This introduces
-// a complication: if we blindly did vector load/stores until finding
-// a 0, we might get a spurious page fault by touching bytes past it.
-// To avoid this, we never do a load that crosses a page boundary,
-// and never store a byte we don't have to.
-//
-// We align the destination, because unaligned vector stores are slow.
+/*****************************************************************************
+ * Macros *
+ *****************************************************************************/
+
+.macro EstablishFrame
+ push %rbp
+ mov %rsp, %rbp
+.endm
- .text
- .globl _strcpy
+.macro ClearFrameAndReturn
+ pop %rbp
+ ret
+.endm
+
+/*****************************************************************************
+ * Entrypoint *
+ *****************************************************************************/
- .align 4
-_strcpy: // char *strcpy(const char *dst, const char *src);
- movq %rdi,%rcx // preserve dest ptr so we can return it
- movl %edi,%edx // copy low 4 bytes of dest ptr
- negl %edx
- andl $15,%edx // how many bytes to align dest ptr?
- jnz LLoopOverBytes // not aligned, so go do so
-
-
-// In order to avoid spurious page faults, we loop until nearing the source page
-// end. Then we revert to a byte-by-byte loop for 16 bytes until the page is crossed,
-// then resume the vector loop.
-// %rsi = source ptr (unaligned)
-// %rdi = dest ptr (aligned)
+.text
+.align 5
+_strcpy:
+// char *strcpy(char * restrict d, const char * restrict s);
+//
+// copies the string s to d, and returns d. We look for NUL bytes using
+// pcmpeqb on 16-byte aligned blocks. Although this may read past the
+// end of the string, because all access is aligned, it will never
+// read past the end of the string across a page boundary, or even
+// accross a cacheline.
+ EstablishFrame
+ mov %rsi, %rcx
-LNextChunk:
- movl %esi,%eax // copy low 4 bytes of source ptr
- movl $4096,%edx
- andl $4095,%eax // get offset into source page
- subl %eax,%edx // get #bytes remaining in source page
- shrl $4,%edx // get #chunks till end of page
- jnz LLoopOverChunks // enter vector loop
- movl $16,%edx // move 16 bytes to cross page but keep dest aligned
- jmp LLoopOverBytes
+// Load the 16-byte block containing the first byte of the string, and
+// compare each byte to zero. If any NUL bytes are present in this
+// block, the corresponding *bit* in esi will be set to 1.
+ and $-16, %rsi
+ pxor %xmm0, %xmm0
+ pcmpeqb (%rsi), %xmm0
+ pmovmskb %xmm0, %eax
+// The 16 bytes that we checked for NUL included some bytes preceeding
+// the start of the string, if s is not 16-byte aligned. We create a
+// mask based on the alignment of s which covers only those bits
+// corresponding to bytes that do not preceed s, and check for NULs
+// only in those bits. If we find one, the string is too small to use
+// a vector copy, so jump to dedicated small-buffer implementation.
+ and $0xf, %rcx
+ or $-1, %rdx
+ shl %cl, %rdx
+ and %edx, %eax
+ jnz L_strcpyGPR
-// Loop over bytes.
-// %rsi = source ptr
-// %rdi = dest ptr
-// %edx = byte count
+// Check the next 16-byte block for NUL. If none are found, that guarantees
+// that the string is at least 16 bytes long, which means that we can use a
+// single unaligned vector copy to handle any edging at the start of the
+// string. If instead a NUL is found, fall into the byte-by-byte copy loop.
+ movdqa 16(%rsi), %xmm1
+ pxor %xmm0, %xmm0
+ pcmpeqb %xmm1, %xmm0
+ pmovmskb %xmm0, %edx
+ test %edx, %edx
+ jz L_strcpySSE
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%rsi),%eax // get source byte
- addq $1,%rsi
- movb %al,(%rdi) // pack into dest
- addq $1,%rdi
- testl %eax,%eax // 0?
- jz LDone // yes, we're done
- subl $1,%edx // more to go?
- jnz LLoopOverBytes
-
- jmp LNextChunk // we've come to end of page
+/*****************************************************************************
+ * GPR copy implementation *
+ *****************************************************************************/
+// There is at least one NUL in the 32 aligned bytes containing the start
+// of the string being copied. We assemble a bitmap for those 32 bytes from
+// eax and edx, then shift it right by cl to throw out any bits preceeding
+// the start of the string. We can then identify the position of the
+// first NUL byte using BSF.
+ shl $16, %edx
+ or %edx, %eax
+L_strcpyGPR:
+ shr %cl, %eax
+ bsf %eax, %edx
+// Restore the original source pointer, and copy the destination pointer
+// to rax so that it is returned on exit.
+ add %rcx, %rsi
+ mov %rdi, %rax
+ add $1, %rdx
+ call _memcpy
+ ClearFrameAndReturn
+/*
+// At this point we simply need to copy rdx + 1 bytes from rsi to rdi. If
+// the length is >= 8, start by doing a word-by-word copy; otherwise, use
+// a byte-by-byte copy loop.
+ sub $7, %rdx // 7 instead of 8 to account for NUL
+ jb 1f
+0: mov (%rsi,%rdx),%rcx
+ mov %rcx, (%rdi,%rdx)
+ sub $8, %rdx
+ jae 0b
+1: add $8, %rdx
+ jz 3f
+2: movzb -1(%rsi,%rdx),%rcx
+ movb %cl, -1(%rdi,%rdx)
+ sub $1, %rdx
+ jnz 2b
+3: ClearFrameAndReturn
+ */
-// Loop over 16-byte chunks.
-// %rsi = source ptr (unaligned)
-// %rdi = dest ptr (aligned)
-// %edx = chunk count
+/*****************************************************************************
+ * SSE copy implementation *
+ *****************************************************************************/
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%rsi),%xmm1 // get source
- pxor %xmm0,%xmm0 // get some 0s
- addq $16,%rsi
- pcmpeqb %xmm1,%xmm0 // compare source to 0s
- pmovmskb %xmm0,%eax // get result mask for 0 check
- testl %eax,%eax // any 0s?
- jnz LFound0 // yes, exit loop
- movdqa %xmm1,(%rdi) // no 0s so do aligned store into destination
- addq $16,%rdi
- subl $1,%edx // more to go?
- jnz LLoopOverChunks
-
- movl $16,%edx // move 16 bytes
- jmp LLoopOverBytes // cross page but keep dest aligned
-
+L_strcpySSE:
+// Begin by doing a single unaligned vector copy for edging. We no longer
+// have the original source pointer, but we can reconstruct it as rsi + rcx.
+ movdqu (%rsi,%rcx),%xmm0
+ movdqu %xmm0, (%rdi)
+// Next copy the original destination pointer to rax so that it is returned
+// on exit, and adjust the destination pointer to correspond to rsi.
+ mov %rdi, %rax
+ sub %rcx, %rdi
+ xor %rcx, %rcx
+// Main copy loop: store the 16 bytes loaded in the previous iteration of the
+// loop, as they are already known to not contain a NUL. The load the next
+// 16 bytes and check for NUL.
+0: movdqu %xmm1, 16(%rdi,%rcx)
+ add $16, %rcx
+ movdqa 16(%rsi,%rcx),%xmm1
+ pxor %xmm0, %xmm0
+ pcmpeqb %xmm1, %xmm0
+ pmovmskb %xmm0, %edx
+ test %edx, %edx
+ jz 0b
-// Found a zero in the vector. Figure out where it is, and store the bytes
-// up to it.
-// %rdi = dest ptr (aligned)
-// %eax = result mask
-// %xmm1 = source vector
+// Cleanup: at least one of the bytes in the last 16 that were loaded was
+// NUL. The corresponding bits of dx are set, and all other bits are zero.
+// Thus, we can use BSF to find the position of the first NUL. Once we have
+// this information, we use an unaligned copy that runs precisely up to this
+// position to handle edging.
+ bsf %edx, %edx
+ add %rdx, %rcx
+ movdqu 1(%rsi,%rcx),%xmm0 // offset is 1 so that we copy the trailing
+ movdqu %xmm0, 1(%rdi,%rcx) // NUL byte as well.
+ ClearFrameAndReturn
-LFound0:
- bsf %eax,%edx // find first 0
- addl $1,%edx // we need to store the 0 too
- test $16,%dl // was 0 last byte?
- jz 8f // no
- movdqa %xmm1,(%rdi) // yes, store entire vector
- jmp LDone
-8:
- test $8,%dl // 8-byte store required?
- jz 4f // no
- movq %xmm1,(%rdi) // pack in 8 low bytes
- psrldq $8,%xmm1 // then shift vector down 8 bytes
- addq $8,%rdi
-4:
- test $4,%dl // 4-byte store required?
- jz 3f // no
- movd %xmm1,(%rdi) // pack in 4 low bytes
- psrldq $4,%xmm1 // then shift vector down 4 bytes
- addq $4,%rdi
-3:
- andl $3,%edx // more to go?
- jz LDone // no
- movd %xmm1,%eax // move remainders out of vector into %eax
-1: // loop on up to three bytes
- movb %al,(%rdi) // pack in next byte
- shrl $8,%eax // shift next byte into position
- addq $1,%rdi
- dec %edx
- jnz 1b
-
-LDone:
- movq %rcx,%rax // original dest ptr is return value
- ret
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// *****************
-// * S T R L C A T *
-// *****************
-//
-// size_t strlcat(char *dst, const char *src, size_t size);
-//
-// Using 8- or 16-byte parallel loops introduce a complication:
-// if we blindly did parallel load/stores until finding
-// a 0, we might get a spurious page fault by touching bytes past it.
-// To avoid this, we never do a load that crosses a page boundary,
-// or store unnecessary bytes.
-//
-// The word parallel test for 0s relies on the following inobvious
-// but very efficient test:
-// x = dataWord + 0xFEFEFEFF
-// y = ~dataWord & 0x80808080
-// if (x & y) == 0 then no zero found
-// The test maps any non-zero byte to zero, and any zero byte to 0x80,
-// with one exception: 0x01 bytes preceeding the first zero are also
-// mapped to 0x80.
-//
-// On Core2 class machines, this algorithm seems to be faster than the
-// naive byte-by-byte version for operands longer than about 11 bytes.
-
- .text
- .globl _strlcat
-
-
-
-// Use SSE to find the 0-byte at current end of buffer.
-// This is just a minor variant of strlen().
-// Initial registers:
-// %rdi = dest or buffer ptr
-// %rsi = source ptr
-// %rdx = size
-
- .align 4
-_strlcat: // size_t *strlcat(char *dst, const char *src, size_t size);
- movl %edi,%ecx // copy buffer ptr
- movq %rdi,%r10 // save copies of buffer ptr and length
- movq %rdx,%r11
- andq $(-16),%rdi // 16-byte align buffer ptr
- pxor %xmm0,%xmm0 // get some 0s
- andl $15,%ecx // get #bytes in dq before start of buffer
- movl $16,%r8d
- orl $(-1),%eax
- subl %ecx,%r8d // #bytes from buffer start to end of dq
- subq %r8,%rdx // does buffer end before end of dq?
- jb LShortBuf1 // yes, drop into byte-by-byte mode
- movdqa (%rdi),%xmm1 // get first aligned chunk of buffer
- addq $16,%rdi
- pcmpeqb %xmm0,%xmm1 // check for 0s
- shl %cl,%eax // create mask for the bytes of aligned dq in operand
- pmovmskb %xmm1,%ecx // collect mask of 0-bytes
- andl %eax,%ecx // mask out any 0s that occur before buffer start
- jnz 2f // found end of buffer
-1:
- subq $16,%rdx // another dq in buffer?
- jb LShortBuf2 // no, drop into byte-by-byte mode
- movdqa (%rdi),%xmm1 // get next chunk
- addq $16,%rdi
- pcmpeqb %xmm0,%xmm1 // check for 0s
- pmovmskb %xmm1,%ecx // collect mask of 0-bytes
- testl %ecx,%ecx // any 0-bytes?
- jz 1b // no
-2:
- bsf %ecx,%ecx // find first 1-bit (ie, first 0-byte)
- subq $16,%rdi // back up ptr into buffer
- addq $16,%rdx // recover length remaining as of start of dq
- addq %rcx,%rdi // point to 0-byte
- subq %rcx,%rdx // compute #bytes remaining in buffer
-
-
-// Copy byte-by-byte until source is 8-byte aligned.
-// %rdi = points to 1st byte available in buffer
-// %rsi = src ptr
-// %rdx = buffer length remaining (ie, starting at %rdi)
-// %r10 = original buffer ptr
-
- movl %esi,%ecx // copy source ptr
- negl %ecx
- andl $7,%ecx // how many bytes to align source ptr?
- jz LAligned // already aligned
-
-
-// Loop over bytes.
-// %rdi = dest ptr
-// %rsi = source ptr
-// %rdx = length remaining in buffer
-// %ecx = number of bytes to copy (>0, may not fit in buffer)
-// %r10 = original buffer ptr
-
-LLoopOverBytes:
- movzb (%rsi),%eax // get source byte before checking buffer length
- testq %rdx,%rdx // buffer full?
- jz L0NotFound // yes
- incq %rsi
- decq %rdx
- movb %al,(%rdi) // pack into dest
- incq %rdi
- testl %eax,%eax // 0?
- jz LDone // yes, done
- decl %ecx // more to go?
- jnz LLoopOverBytes
-
-
-// Source is aligned. Loop over quadwords until end of buffer. We
-// align the source, rather than the dest, to avoid getting spurious page faults.
-// %rdi = dest ptr (unaligned)
-// %rsi = source ptr (quadword aligned)
-// %rdx = length remaining in buffer
-// %r10 = original buffer ptr
-
-LAligned:
- movl $9,%ecx // if buffer almost exhausted, prepare to copy rest byte-by-byte
- cmpq $8,%rdx // enough for at least one quadword?
- jb LLoopOverBytes
- movq $0xFEFEFEFEFEFEFEFF,%r8 // get magic constants
- movq $0x8080808080808080,%r9
-
-
-// Loop over quadwords.
-// %rdi = dest ptr (unaligned)
-// %rsi = source ptr (quadword aligned)
-// %rdx = length remaining in buffer (>=8)
-// %r8 = 0xFEFEFEFEFEFEFEFF
-// %r9 = 0x8080808080808080
-// %r10 = original buffer ptr
-
-LLoopOverQuads:
- movq (%rsi),%rax // get next 8 bytes of source
- subq $8,%rdx
- addq $8,%rsi
- movq %rax,%r11 // make 2 copies of quadword
- movq %rax,%rcx
- notq %r11 // use magic word-parallel test for 0s
- addq %r8,%rcx
- andq %r9,%r11
- testq %rcx,%r11
- jnz L0Found // one of the bytes of %rax is a 0
- movq %rax,(%rdi) // pack 8 bytes into destination
- addq $8,%rdi
- cmpq $8,%rdx // room in buffer for another quadword?
- jae LLoopOverQuads // yes
-
- movl %edx,%ecx // copy leftovers in byte loop
- jmp LLoopOverBytes
-
-// Found a 0-byte in the quadword of source. Store a byte at a time until the 0.
-// %rdi = dest ptr (unaligned)
-// %rax = last word of source, known to have a 0-byte
-// %r10 = original buffer ptr
-
-LNextByte:
- shrq $8,%rax // next byte
-L0Found:
- movb %al,(%rdi) // pack in next byte
- incq %rdi
- testb %al,%al // 0?
- jnz LNextByte
-
-
-// Done storing string.
-// %rdi = ptr to byte after 0-byte
-// %r10 = original buffer ptr
-
-LDone:
- subq %r10,%rdi // subtract original dest ptr to get length stored
- lea -1(%rdi),%rax // minus one for 0-byte, and move to return value
- ret
-
-// Buffer filled but 0-byte not found. We return the length of the buffer plus the length
-// of the source string. This is not optimized, as it is an error condition.
-// %edi = dest ptr (ie, 1 past end of buffer)
-// %esi = source ptr (ptr to 1st byte that does not fit)
-// %rdx = 0 (ie, length remaining in buffer)
-// %r10 = original buffer ptr
-
-L0NotFound:
- movq %rdi,%rax // buffer end...
- subq %r10,%rax // ...minus start is buffer length
- jz LScanSourceTo0 // buffer is null so cannot store a 0
- movb %dl,-1(%rdi) // store a 0 at end of buffer to delimit string
-
-
-// Scan source to end.
-// %rsi = ptr to rest of source
-// %rax = return value so far
-
-LScanSourceTo0:
- movzb (%rsi),%ecx // get next byte of source
- incq %rsi
- incq %rax // increment length
- testl %ecx,%ecx // 0?
- jnz LScanSourceTo0
- decq %rax // don't count the 0-byte
- ret
-
-
-// Buffer too short to reach end of even one 16-byte aligned chunk.
-// %rsi = src ptr
-// %r10 = original buffer ptr
-// %r11 = original buffer length
-
-LShortBuf1:
- movq %r10,%rdi // recover buffer ptr
- movq %r11,%rdx // recover buffer length
- jmp LShortBuf3
-
-
-// Out of aligned dq's of buffer, 0-byte still not found.
-// %rsi = src ptr
-// %rdi = ptr to 1st buffer byte not checked for 0
-// %rdx = length remaining - 16
-// %r10 = original buffer ptr
-// %r11 = original buffer length
-
-LShortBuf2:
- addq $16,%rdx // recover length remaining
-LShortBuf3:
- movq %r11,%rax // in case we goto LScanSourceTo0
- movl $17,%ecx // in case we goto LLoopOverBytes
-1:
- testq %rdx,%rdx // no 0s in buffer at all?
- jz LScanSourceTo0 // yes, cannot store a 0
- cmpb $0,(%rdi) // is this the 0?
- jz LLoopOverBytes // yes, append source
- incq %rdi
- decq %rdx
- jmp 1b // loop looking for 0
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// *****************
-// * S T R L C P Y *
-// *****************
-//
-// size_t strlcpy(char *dst, const char *src, size_t size);
-//
-// We optimize the move by doing it quadword parallel. This introduces
-// a complication: if we blindly did quadword load/stores until finding
-// a 0, we might get a spurious page fault by touching bytes past it.
-// To avoid this, we never do a load that crosses a page boundary,
-// or store unnecessary bytes.
-//
-// The test for 0s relies on the following inobvious but very efficient
-// word-parallel test:
-// x = dataWord + 0xFEFEFEFF
-// y = ~dataWord & 0x80808080
-// if (x & y) == 0 then no zero found
-// The test maps any non-zero byte to zero, and any zero byte to 0x80,
-// with one exception: 0x01 bytes preceeding the first zero are also
-// mapped to 0x80.
-
- .text
- .globl _strlcpy
-
-// When initially entered:
-// %rdi = dest buffer ptr
-// %rsi = source ptr
-// %rdx = length
-
- .align 4
-_strlcpy: // size_t *strlcpy(char *dst, const char *src, size_t size);
- movl %esi,%ecx // copy source ptr
- movq %rdi,%r10 // copy dest ptr
- negl %ecx
- andl $7,%ecx // how many bytes to align source ptr?
- jz LAligned // already aligned
-
-
-// Loop over bytes.
-// %rdi = dest ptr
-// %rsi = source ptr
-// %rdx = length remaining in buffer
-// %ecx = number of bytes to copy (>0, may not fit in buffer)
-// %r10 = original dest ptr
-
-LLoopOverBytes:
- movzb (%rsi),%eax // get source byte before checking buffer length
- testq %rdx,%rdx // buffer full?
- jz L0NotFound // yes
- incq %rsi
- decq %rdx
- movb %al,(%rdi) // pack into dest
- incq %rdi
- testl %eax,%eax // 0?
- jz LDone // yes, done
- decl %ecx // more to go?
- jnz LLoopOverBytes
-
-
-// Source is aligned. Loop over quadwords until end of buffer. We
-// align the source, rather than the dest, to avoid getting spurious page faults.
-// %rdi = dest ptr (unaligned)
-// %rsi = source ptr (quadword aligned)
-// %rdx = length remaining in buffer
-// %r10 = original dest ptr
-
-LAligned:
- movl $9,%ecx // if buffer almost exhausted, prepare to copy rest byte-by-byte
- cmpq $8,%rdx // enough for at least one word?
- jb LLoopOverBytes
- movq $0xFEFEFEFEFEFEFEFF,%rcx // load magic constants
- movq $0x8080808080808080,%r11
-
-
-// Loop over quadwords.
-// %rdi = dest ptr (unaligned)
-// %rsi = source ptr (word aligned)
-// %rdx = length remaining in buffer (>=8)
-// %rcx = 0xFEFEFEFEFEFEFEFF
-// %r11 = 0x8080808080808080
-// %r10 = original dest ptr
-
-LLoopOverQuads:
- movq (%rsi),%rax // get next 8 bytes of source
- subq $8,%rdx
- addq $8,%rsi
- movq %rax,%r8 // make 2 copies of quadword
- movq %rax,%r9
- notq %r8 // use magic word-parallel test for 0s
- addq %rcx,%r9
- andq %r11,%r8
- testq %r8,%r9
- jnz L0Found // one of the bytes of %rax is a 0
- movq %rax,(%rdi) // pack 8 bytes into destination
- addq $8,%rdi
- cmpq $8,%rdx // room in buffer for another quadword?
- jae LLoopOverQuads // yes
-
- movl %edx,%ecx // copy leftovers in byte loop
- jmp LLoopOverBytes
-
-// Found a 0-byte in the quadword of source. Store a byte at a time until the 0.
-// %rdi = dest ptr (unaligned)
-// %rax = last quadword of source, known to have a 0-byte
-// %r10 = original dest ptr
-
-LNextByte:
- shrq $8,%rax // next byte
-L0Found:
- movb %al,(%rdi) // pack in next byte
- incq %rdi
- testb %al,%al // 0?
- jnz LNextByte
-
-// Done storing string.
-// %rdi = ptr to byte after 0-byte
-// %r10 = original dest ptr
-
-LDone:
- subq %r10,%rdi // subtract original dest ptr to get length stored
- lea -1(%rdi),%rax // minus one for 0-byte, and move to return value
- ret
-
-// Buffer filled but 0-byte not found. We return the length of the source string.
-// This is not optimized, as it is an error condition.
-// %rdi = dest ptr (ie, 1 past end of buffer)
-// %rsi = source ptr (ptr to 1st byte that does not fit)
-// %r10 = original dest ptr
-
-L0NotFound:
- movq %rdi,%rax // end of buffer...
- subq %r10,%rax // ...minus start is buffer length
- jz 1f // 0-length buffer, cannot store a 0
- xorl %edx,%edx // get a 0
- movb %dl,-1(%rdi) // store a 0 at end of buffer to delimit string
-1:
- movzb (%rsi),%ecx // get next byte of source
- incq %rsi
- incq %rax
- testl %ecx,%ecx // 0?
- jnz 1b
- decq %rax // don't count the 0-byte
- ret
/*
- * Copyright (c) 2005-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2005-2012 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*
- * @APPLE_LICENSE_HEADER_END@
+ * This file implements strlen( ) for the x86_64 architecture.
*/
-/*
- * Strlen, for processors with SSE3.
- *
- * Note that all memory references must be aligned, in order to avoid spurious
- * page faults. Thus we have to load the aligned 16-byte chunk containing the
- * first byte of the operand, then mask out false 0s that may occur before the
- * first byte.
- *
- * We favor the fall-through (ie, short operand) path.
- */
+.globl _strlen
- .text
- .globl _strlen
- .align 4, 0x90
-_strlen: // size_t strlen(char *b);
- pxor %xmm0,%xmm0 // zero %xmm0
- movl %edi,%ecx // copy low half of ptr
- movq %rdi,%rdx // make another full copy
- andq $(-16),%rdi // 16-byte align ptr
- orl $(-1),%eax
- pcmpeqb (%rdi),%xmm0 // check whole qw for 0s
- andl $15,%ecx // get #bytes in aligned dq before operand
- shl %cl,%eax // create mask for the bytes of aligned dq in operand
- pmovmskb %xmm0,%ecx // collect mask of 0-bytes
- andl %eax,%ecx // mask out any 0s that occur before 1st byte
- jz LEnterLoop // no 0-bytes (ie, 1-bits), so enter by-16 loop
-
-// We've found a 0-byte.
-// %rdi = aligned address of 16-byte block containing the terminating 0-byte
-// %ecx = compare bit vector
+/*****************************************************************************
+ * Macros *
+ *****************************************************************************/
-LFoundIt:
- bsf %ecx,%eax // find first 1-bit (ie, first 0-byte)
- subq %rdx,%rdi // get length to start of 16-byte block while we wait
- addq %rdi,%rax // add bytes in 16-byte block
+.macro EstablishFrame
+ push %rbp
+ mov %rsp, %rbp
+.endm
+
+.macro ClearFrameAndReturn
+ pop %rbp
ret
-
-// Loop over aligned 16-byte blocks:
-// %rdi = address of previous block
+.endm
+
+/*****************************************************************************
+ * Entrypoint *
+ *****************************************************************************/
+
+.text
+.align 5
+_strlen:
+// size_t strlen(const char *s);
+//
+// returns the length of the string s (i.e. the distance in bytes from
+// s to the first NUL byte following s). We look for NUL bytes using
+// pcmpeqb on 16-byte aligned blocks. Although this may read past the
+// end of the string, because all access is aligned, it will never
+// read past the end of the string across a page boundary, or even
+// accross a cacheline.
+ EstablishFrame
+ mov %rdi, %rcx
+ mov %rdi, %rdx
+
+// Load the 16-byte block containing the first byte of the string, and
+// compare each byte to zero. If any NUL bytes are present in this
+// block, the corresponding *bit* in esi will be set to 1.
+ and $-16, %rdi
+ pxor %xmm0, %xmm0
+ pcmpeqb (%rdi), %xmm0
+ pmovmskb %xmm0, %esi
+
+// The 16 bytes that we checked for NUL included some bytes preceeding
+// the start of the string, if s is not 16-byte aligned. We create a
+// mask based on the alignment of s which covers only those bits
+// corresponding to bytes that do not preceed s, and check for NULs
+// only in those bits. If we do not find one, we jump to our main
+// search loop.
+ and $0xf, %rcx
+ or $-1, %rax
+ shl %cl, %rax
+ and %eax, %esi
+ jz L_loop
-LEnterLoop:
- pxor %xmm0,%xmm0 // get some 0-bytes
- addq $16,%rdi // advance ptr
-LLoop:
- movdqa (%rdi),%xmm1 // get next chunk
- addq $16,%rdi
- pcmpeqb %xmm0,%xmm1 // check for 0s
- pmovmskb %xmm1,%ecx // collect mask of 0-bytes
- test %ecx,%ecx // any 0-bytes?
- jz LLoop // no 0-bytes, so get next dq
+L_foundNUL:
+// The last 16-byte block that we searched contained at least one NUL.
+// We use bsf to identify the first NUL, and compute the distance from
+// that byte to the start of the string.
+ bsf %esi, %eax
+ sub %rdx, %rdi
+ add %rdi, %rax
+ ClearFrameAndReturn
- subq $16,%rdi // back up ptr
- jmp LFoundIt
+.align 4
+L_loop:
+// Main search loop: check for NUL in a 16-byte block, continuing
+// loop until one is found.
+ add $16, %rdi
+ pxor %xmm0, %xmm0
+ pcmpeqb (%rdi), %xmm0
+ pmovmskb %xmm0, %esi
+ test %esi, %esi
+ jz L_loop
+ jmp L_foundNUL
+++ /dev/null
-/*
- * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-// *****************
-// * S T R N C M P *
-// *****************
-//
-// int strncmp(const char *s1, const char *s2, size_t len);
-//
-// We optimize the compare by doing it vector parallel. This introduces
-// a complication: if we blindly did vector loads from both sides until
-// finding a difference (or 0), we might get a spurious page fault by
-// reading bytes past the difference. To avoid this, we never do a load
-// that crosses a page boundary.
-
-#define kShort 20 // too short for vectors (must be >16)
-
- .text
- .globl _strncmp
-
- .align 4
-_strncmp: // int strncmp(const char *s1, const char *s2, size_t len);
- cmpq $(kShort),%rdx // worth accelerating?
- ja LNotShort // yes
-
-
-// Too short to bother with parallel compares. Loop over bytes.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-// %edx = length (<= kShort)
-
-LShort:
- testl %edx,%edx // 0-length?
- jnz LShortLoop // no
- jmp LReturn0 // yes, return 0
- .align 4,0x90 // align inner loops to optimize I-fetch
-LShortLoop: // loop over bytes
- movzb (%rdi),%eax // get LHS byte
- movzb (%rsi),%ecx // get RHS byte
- incq %rdi
- incq %rsi
- testl %eax,%eax // LHS==0 ?
- jz LNotEqual // yes, this terminates comparison
- cmpl %ecx,%eax // compare them (sub won't fuse, but cmp will)
- jnz LNotEqual // done if not equal
- decl %edx // decrement length
- jnz LShortLoop
-LReturn0:
- xorl %eax,%eax // all bytes equal, so return 0
- ret
-
-LNotEqual: // LHS in eax, RHS in ecx
- subl %ecx,%eax // generate return value (nonzero)
- ret
-
-
-// Loop over bytes until we reach end of a page.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-// %rdx = length remaining after end of loop (ie, already adjusted)
-// %r8d = #bytes until next page (1..15)
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverBytes:
- movzb (%rdi),%eax // get LHS byte
- movzb (%rsi),%ecx // get RHS byte
- incq %rdi
- incq %rsi
- testl %eax,%eax // LHS==0 ?
- jz LNotEqual // yes, this terminates comparison
- cmpl %ecx,%eax // compare them (sub won't fuse, but cmp will)
- jnz LNotEqual // done if not equal
- decl %r8d // more to go?
- jnz LLoopOverBytes
-
-
-// Long enough to justify overhead of setting up vector compares. In order to
-// avoid spurious page faults, we loop over:
-//
-// min( length, bytes_in_LHS_page, bytes_in_RHS_page) >> 4
-//
-// 16-byte chunks. When we near a page end, we have to revert to a byte-by-byte
-// comparison until reaching the next page, then resume the vector comparison.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-// %rdx = length (> kShort)
-
-LNotShort:
- movl %edi,%eax // copy ptrs
- movl %esi,%r8d
- andl $4095,%eax // mask down to page offsets
- andl $4095,%r8d
- cmpl %eax,%r8d // which is bigger?
- cmova %r8d,%eax // %eax = max(LHS offset, RHS offset);
- movl $4096,%r8d
- subl %eax,%r8d // get #bytes to next page crossing
- cmpq %rdx,%r8 // will operand run out first?
- cmova %rdx,%r8 // get min(length remaining, bytes to page end)
- movl %r8d,%eax // copy #bytes
- shrl $4,%r8d // get #chunks till end of operand or page
- testl %r8d,%r8d // test %r8d for 0 without partial flag update stall
- jnz LLoopOverChunks // enter vector loop
-
-// Too near page end for vectors.
-
- subq %rax,%rdx // adjust length remaining
- movl %eax,%r8d // %r8d <- #bytes to page end
- cmpq $(kShort),%rdx // will there be enough after we cross page for vectors?
- ja LLoopOverBytes // yes
- addq %rax,%rdx // no, restore total length remaining
- jmp LShortLoop // compare rest byte-by-byte (%rdx != 0)
-
-
-// Loop over 16-byte chunks.
-// %rdi = LHS ptr
-// %rsi = RHS ptr
-// %rdx = length remaining
-// %r8d = chunk count
-
- .align 4,0x90 // align inner loops to optimize I-fetch
-LLoopOverChunks:
- movdqu (%rdi),%xmm1 // get LHS
- movdqu (%rsi),%xmm2 // get RHS
- pxor %xmm0,%xmm0 // get some 0s in the shadow of the loads
- addq $16,%rdi
- pcmpeqb %xmm1,%xmm2 // compare LHS to RHS
- pcmpeqb %xmm1,%xmm0 // compare LHS to 0s
- addq $16,%rsi
- pmovmskb %xmm2,%eax // get result mask for comparison of LHS and RHS
- pmovmskb %xmm0,%ecx // get result mask for 0 check
- subq $16,%rdx // decrement length remaining
- xorl $0xFFFF,%eax // complement compare mask so 1 means "not equal"
- orl %ecx,%eax // combine the masks and check for 1-bits
- jnz LFoundDiffOr0 // we found differing bytes or a 0-byte
- decl %r8d // more to go?
- jnz LLoopOverChunks // yes
-
- cmpq $(kShort),%rdx // a lot more to compare?
- jbe LShort // no
- jmp LNotShort // compute distance to next page crossing etc
-
-
-// Found a zero and/or a difference in vector compare.
-// %rdi = LHS ptr, already advanced by 16
-// %rsi = RHS ptr, already advanced by 16
-// %eax = bit n set if bytes n differed or were 0
-
-LFoundDiffOr0:
- bsf %eax,%edx // which byte differed or was 0?
- movzb -16(%rdi,%rdx),%eax // get LHS byte
- movzb -16(%rsi,%rdx),%edx // get RHS byte
- subl %edx,%eax // compute difference (ie, return value)
- ret
LZeroBuffer:
movq %rdx,%rsi // remaining buffer size (2nd argument)
+ subq $8,%rsp // align stack to 16B before call
call _bzero
+ addq $8,%rsp // restore stack
LDone:
movq %r8,%rax // original dest ptr is return value
--- /dev/null
+/*
+ * Copyright (c) 2012 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ *
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ *
+ * This file implements strnlen( ) for the x86_64 architecture.
+ */
+
+.globl _strnlen
+
+/*****************************************************************************
+ * Macros *
+ *****************************************************************************/
+
+.macro EstablishFrame
+ push %rbp
+ mov %rsp, %rbp
+.endm
+
+.macro ClearFrameAndReturn
+ pop %rbp
+ ret
+.endm
+
+/*****************************************************************************
+ * Entrypoint *
+ *****************************************************************************/
+
+.text
+.align 4
+_strnlen:
+// size_t strnlen(char *s, size_t maxlen);
+
+// If maxlen is larger than any object that can be allocated, we know a priori
+// that it does not effect the operation of the function in any way; we can
+// simply call strlen instead, which is more efficient and makes handling the
+// edge cases here much cleaner.
+ test %rsi, %rsi
+ js _strlen
+
+// The strnlen() function attempts to compute the length of s, but never
+// scans beyond the first maxlen bytes of s.
+//
+// Thus, we need to early-out without doing any reads at all if maxlen == 0.
+ EstablishFrame
+ mov %rsi, %rax
+ jz L_maxlenExhausted
+
+// We are going to check the string in aligned 16-byte blocks. The first such
+// block may contain characters that preceed the start of the string, so we
+// construct a mask based on the string's alignment to use in processing this
+// initial block. We also need to account for these characters in maxlen.
+ mov %rdi, %rcx
+ and $0xf, %rcx
+ or $-1, %rdx
+ shl %cl, %rdx // mask
+ add %rcx, %rsi // adjust maxlen
+
+// Load the 16-byte block containing the start of the string. If any NUL
+// bytes are present in this block, the corresponding *bit* in ecx will be 1.
+// We check only the bits that are set in the mask, to avoid detecting NULs
+// that preceed the start of the string.
+ and $-16, %rdi
+ pxor %xmm0, %xmm0
+ pcmpeqb (%rdi), %xmm0
+ pmovmskb %xmm0, %ecx
+ and %rdx, %rcx
+ jnz L_foundNUL
+
+// Now subtract 16 from maxlen. If this causes a borrow, then we exhausted
+// maxlen somewhere in this 16-byte block (formally, we have read past maxlen
+// bytes, but that is not a problem; because the accesses are all aligned, we
+// cannot read accross a page--or even cacheline--boundary, so the observable
+// behavior is not different from if we had stopped at maxlen). If the result
+// is exactly zero, we need to stop before reading the *next* 16 bytes.
+ sub $16, %rsi
+ jbe L_maxlenExhausted
+
+L_loop:
+ add $16, %rdi
+ pxor %xmm0, %xmm0
+ pcmpeqb (%rdi), %xmm0
+ pmovmskb %xmm0, %ecx
+ test %rcx, %rcx
+ jnz L_foundNUL
+ sub $16, %rsi
+ ja L_loop
+
+L_maxlenExhausted:
+// If we exhaust maxlen bytes without finding a NUL, we return maxlen.
+ ClearFrameAndReturn
+
+L_foundNUL:
+// The last 16-byte block that we searched contained at least one NUL.
+// We use bsf to identify the first NUL.
+ bsf %rcx, %rdx
+// Handle the case where the NUL that we found is preceeded by the maxlen'th
+// byte of the string, returning maxlen.
+ cmp %rdx, %rsi
+ jb L_maxlenExhausted
+// Otherwise, return the length of the string.
+ sub %rsi, %rax
+ add %rdx, %rax
+ ClearFrameAndReturn
+++ /dev/null
-/*
- * Copyright (c) 2007 Apple Inc. All rights reserved.
- * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-#include <architecture/i386/asm_help.h>
-
-#define DECLARE(x) \
- .align 2, 0x90 ; \
- .globl x ; \
- .globl x ## Barrier ; \
-x: ; \
-x ## Barrier:
-
-.text
-
-#define ATOMIC_UP 0
-#define ATOMIC_MP 1
-#define ATOMIC_RET_ORIG 0
-#define ATOMIC_RET_NEW 1
-
-// compare and exchange 32-bit
-// xchg32 <new> <dst> <mp>
-.macro xchg32
- .if $2 == ATOMIC_MP
- lock
- .endif
- cmpxchgl $0, ($1)
-.endm
-
-// xchg64 <new> <dst> <mp>
-.macro xchg64
- .if $2 == ATOMIC_MP
- lock
- .endif
- cmpxchg $0, ($1)
-.endm
-
-#define ATOMIC_ARITHMETIC(instr, orig, mp) \
- movl (%rsi), %eax /* get 2nd arg -> eax */ ;\
-1: movl %eax, %edx /* copy value to new reg */ ;\
- instr %edi, %edx /* apply instr to %edx with arg2 */ ;\
- xchg32 %edx, %rsi, mp /* do the compare swap (see macro above) */ ;\
- jnz 1b /* jump if failed */ ;\
- .if orig == 1 /* to return the new value, overwrite eax */ ;\
- movl %edx, %eax /* return the new value */ ;\
- .endif
-
-// Used in OSAtomicTestAndSet( uint32_t n, void *value ), assumes ABI parameter loctions
-// Manpage says bit to test/set is (0x80 >> (n & 7)) of byte (addr + (n >> 3))
-#define ATOMIC_BIT_OP(instr, mp) \
- xorl $7, %edi /* bit position is numbered big endian so convert to little endian */ ;\
- shlq $3, %rsi ;\
- addq %rdi, %rsi /* generate bit address */ ;\
- movq %rsi, %rdi ;\
- andq $31, %rdi /* keep bit offset in range 0..31 */ ;\
- xorq %rdi, %rsi /* 4-byte align address */ ;\
- shrq $3, %rsi /* get 4-byte aligned address */ ;\
- .if mp == ATOMIC_MP /* don't plant the lock in UP code */ ;\
- lock /* lock the bit test */ ;\
- .endif ;\
- instr %edi, (%rsi) /* do the bit test, supplied into the macro */ ;\
- setc %al ;\
- movzbl %al,%eax /* widen in case caller assumes we return an int */
-
-// uint32_t OSAtomicAnd32( uint32_t mask, uint32_t *value);
-PLATFUNC_FUNCTION_START(OSAtomicAnd32, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicAnd32Barrier, up, 64, 2)
- ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Barrier, mp, 64, 2)
- ATOMIC_ARITHMETIC(andl, ATOMIC_RET_NEW, ATOMIC_MP)
- ret
-
-// uint32_t OSAtomicOr32( uint32_t mask, uint32_t *value);
-PLATFUNC_FUNCTION_START(OSAtomicOr32, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicOr32Barrier, up, 64, 2)
- ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Barrier, mp, 64, 2)
- ATOMIC_ARITHMETIC(orl, ATOMIC_RET_NEW, ATOMIC_MP)
- ret
-
-// uint32_t OSAtomicXor32( uint32_t mask, uint32_t *value);
-PLATFUNC_FUNCTION_START(OSAtomicXor32, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicXor32Barrier, up, 64, 2)
- ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Barrier, mp, 64, 2)
- ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_NEW, ATOMIC_MP)
- ret
-
-// uint32_t OSAtomicAnd32Orig( uint32_t mask, uint32_t *value);
-PLATFUNC_FUNCTION_START(OSAtomicAnd32Orig, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicAnd32OrigBarrier, up, 64, 2)
- ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32Orig, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAnd32OrigBarrier, mp, 64, 2)
- ATOMIC_ARITHMETIC(andl, ATOMIC_RET_ORIG, ATOMIC_MP)
- ret
-
-// uint32_t OSAtomicOr32Orig( uint32_t mask, uint32_t *value);
-PLATFUNC_FUNCTION_START(OSAtomicOr32Orig, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicOr32OrigBarrier, up, 64, 2)
- ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32Orig, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicOr32OrigBarrier, mp, 64, 2)
- ATOMIC_ARITHMETIC(orl, ATOMIC_RET_ORIG, ATOMIC_MP)
- ret
-
-// uint32_t OSAtomicXor32Orig( uint32_t mask, uint32_t *value);
-PLATFUNC_FUNCTION_START(OSAtomicXor32Orig, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicXor32OrigBarrier, up, 64, 2)
- ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32Orig, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicXor32OrigBarrier, mp, 64, 2)
- ATOMIC_ARITHMETIC(xorl, ATOMIC_RET_ORIG, ATOMIC_MP)
- ret
-
-// bool OSAtomicCompareAndSwap32( int32_t old, int32_t new, int32_t *value);
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapInt, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapIntBarrier, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap32Barrier, up, 64, 2)
- movl %edi, %eax
- xchg32 %esi, %rdx, ATOMIC_UP
- sete %al
- movzbl %al,%eax // widen in case caller assumes we return an int
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapInt, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapIntBarrier, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap32Barrier, mp, 64, 2)
- movl %edi, %eax
- xchg32 %esi, %rdx, ATOMIC_MP
- sete %al
- movzbl %al,%eax // widen in case caller assumes we return an int
- ret
-
-// bool OSAtomicCompareAndSwap64( int64_t old, int64_t new, int64_t *value);
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtr, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapPtrBarrier, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLong, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwapLongBarrier, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicCompareAndSwap64Barrier, up, 64, 2)
- mov %rdi, %rax
- xchg64 %rsi, %rdx, ATOMIC_UP
- sete %al
- movzbl %al,%eax // widen in case caller assumes we return an int
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtr, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapPtrBarrier, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLong, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwapLongBarrier, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicCompareAndSwap64Barrier, mp, 64, 2)
- mov %rdi, %rax
- xchg64 %rsi, %rdx, ATOMIC_MP
- sete %al
- movzbl %al,%eax // widen in case caller assumes we return an int
- ret
-
-// int32_t OSAtomicAdd32( int32_t amt, int32_t *value );
-PLATFUNC_FUNCTION_START(OSAtomicAdd32, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicAdd32Barrier, up, 64, 2)
- movl %edi, %eax // save amt to add
- xaddl %edi, (%rsi) // swap and add value, returns old value in %edi
- addl %edi, %eax // add old value to amt as return value
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd32Barrier, mp, 64, 2)
- movl %edi, %eax // save amt to add
- lock // lock prefix breaks tabs ;)
- xaddl %edi, (%rsi) // swap and add value, returns old value in %edi
- addl %edi, %eax // add old value to amt as return value
- ret
-
-// int64_t OSAtomicAdd64( int64_t amt, int64_t *value );
-PLATFUNC_FUNCTION_START(OSAtomicAdd64, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicAdd64Barrier, up, 64, 2)
- movq %rdi, %rax // save amt to add
- xadd %rdi, (%rsi) // swap and add value, returns old value in %rsi
- addq %rdi, %rax // add old value to amt as return value
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicAdd64Barrier, mp, 64, 2)
- movq %rdi, %rax // save amt to add
- lock
- xadd %rdi, (%rsi) // swap and add value, returns old value in %rsi
- addq %rdi, %rax // add old value to amt as return value
- ret
-
-// bool OSAtomicTestAndSet( uint32_t n, void *value );
-PLATFUNC_FUNCTION_START(OSAtomicTestAndSet, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicTestAndSetBarrier, up, 64, 2)
- ATOMIC_BIT_OP(btsl, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSet, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndSetBarrier, mp, 64, 2)
- ATOMIC_BIT_OP(btsl, ATOMIC_MP)
- ret
-
-// bool OSAtomicTestAndClear( uint32_t n, void *value );
-PLATFUNC_FUNCTION_START(OSAtomicTestAndClear, up, 64, 2)
-PLATFUNC_FUNCTION_START(OSAtomicTestAndClearBarrier, up, 64, 2)
- ATOMIC_BIT_OP(btrl, ATOMIC_UP)
- ret
-
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClear, mp, 64, 2)
-PLATFUNC_FUNCTION_START_GENERIC(OSAtomicTestAndClearBarrier, mp, 64, 2)
- ATOMIC_BIT_OP(btrl, ATOMIC_MP)
- ret
-
-// void OSMemoryBarrier( void );
- .align 2, 0x90
- .globl _OSMemoryBarrier
-_OSMemoryBarrier:
- mfence
- ret
-
-/*
- * typedef volatile struct {
- * void *opaque1; <-- ptr to 1st queue element or null
- * long opaque2; <-- generation count
- * } OSQueueHead;
- *
- * void OSAtomicEnqueue( OSQueueHead *list, void *new, size_t offset);
- */
- .align 2
- .globl _OSAtomicEnqueue
-_OSAtomicEnqueue: // %rdi == list head, %rsi == new, %rdx == offset
- pushq %rbx
- movq %rsi,%rbx // %rbx == new
- movq %rdx,%rsi // %rsi == offset
- movq (%rdi),%rax // %rax == ptr to 1st element in Q
- movq 8(%rdi),%rdx // %rdx == current generation count
-1:
- movq %rax,(%rbx,%rsi)// link to old list head from new element
- movq %rdx,%rcx
- incq %rcx // increment generation count
- lock // always lock for now...
- cmpxchg16b (%rdi) // ...push on new element
- jnz 1b
- popq %rbx
- ret
-
-
- /* void* OSAtomicDequeue( OSQueueHead *list, size_t offset); */
- .align 2
- .globl _OSAtomicDequeue
-_OSAtomicDequeue: // %rdi == list head, %rsi == offset
- pushq %rbx
- movq (%rdi),%rax // %rax == ptr to 1st element in Q
- movq 8(%rdi),%rdx // %rdx == current generation count
-1:
- testq %rax,%rax // list empty?
- jz 2f // yes
- movq (%rax,%rsi),%rbx // point to 2nd in Q
- movq %rdx,%rcx
- incq %rcx // increment generation count
- lock // always lock for now...
- cmpxchg16b (%rdi) // ...pop off 1st element
- jnz 1b
-2:
- popq %rbx
- ret // ptr to 1st element in Q still in %rax
-
-/*
- * typedef volatile struct {
- * void *opaque1; <-- ptr to first queue element or null
- * void *opaque2; <-- ptr to last queue element or null
- * int opaque3; <-- spinlock
- * } OSFifoQueueHead;
- *
- * void OSAtomicFifoEnqueue( OSFifoQueueHead *list, void *new, size_t offset);
- */
- .align 2
- .globl _OSAtomicFifoEnqueue
-_OSAtomicFifoEnqueue:
- pushq %rbx
- xorl %ebx,%ebx // clear "preemption pending" flag
- movq _commpage_pfz_base(%rip),%rcx
- addq $(_COMM_TEXT_PFZ_ENQUEUE_OFFSET), %rcx
- call *%rcx
- testl %ebx,%ebx // pending preemption?
- jz 1f
- call _preempt // call into the kernel to pfz_exit
-1:
- popq %rbx
- ret
-
-
-/* void* OSAtomicFifoDequeue( OSFifoQueueHead *list, size_t offset); */
- .align 2
- .globl _OSAtomicFifoDequeue
-_OSAtomicFifoDequeue:
- pushq %rbx
- xorl %ebx,%ebx // clear "preemption pending" flag
- movq _commpage_pfz_base(%rip), %rcx
- movq %rsi,%rdx // move offset to %rdx to be like the Enqueue case
- addq $(_COMM_TEXT_PFZ_DEQUEUE_OFFSET), %rcx
- call *%rcx
- testl %ebx,%ebx // pending preemption?
- jz 1f
- call _preempt // call into the kernel to pfz_exit
-1:
- popq %rbx
- ret // ptr to 1st element in Q in %rax
-
-// Local Variables:
-// tab-width: 8
-// End:
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
- *
- * HISTORY
- * 20-Apr-92 Bruce Martin (bmartin@next.com)
- * Created from M68K sources.
- */
-
-/*
- * C library -- _setjmp, _longjmp
- *
- * _longjmp(a,v)
- * will generate a "return(v)" from
- * the last call to
- * _setjmp(a)
- * by restoring registers from the stack,
- * The previous signal state is NOT restored.
- *
- */
-
-#include <architecture/i386/asm_help.h>
-
-#define JB_RBX 0
-#define JB_RBP 8
-#define JB_RSP 16
-#define JB_R12 24
-#define JB_R13 32
-#define JB_R14 40
-#define JB_R15 48
-#define JB_RIP 56
-#define JB_RFLAGS 64
-#define JB_MXCSR 72
-#define JB_FPCONTROL 76
-#define JB_MASK 80
-
-LEAF(__setjmp, 0)
- // %rdi is a jmp_buf (struct sigcontext *)
-
- // now build sigcontext
- movq %rbx, JB_RBX(%rdi)
- movq %rbp, JB_RBP(%rdi)
- movq %r12, JB_R12(%rdi)
- movq %r13, JB_R13(%rdi)
- movq %r14, JB_R14(%rdi)
- movq %r15, JB_R15(%rdi)
-
- // RIP is set to the frame return address value
- movq (%rsp), %rax
- movq %rax, JB_RIP(%rdi)
- // RSP is set to the frame return address plus 8
- leaq 8(%rsp), %rax
- movq %rax, JB_RSP(%rdi)
-
- // save fp control word
- fnstcw JB_FPCONTROL(%rdi)
-
- // save MXCSR
- stmxcsr JB_MXCSR(%rdi)
-
- // return 0
- xorl %eax, %eax
- ret
-
-
-LEAF(__longjmp, 0)
- fninit // Clear all FP exceptions
- // %rdi is a jmp_buf (struct sigcontext *)
- // %esi is the return value
- movl %esi, %eax
- testl %esi, %esi
- jnz 1f
- incl %eax
-
- // general registers
-1:
- movq JB_RBX(%rdi), %rbx
- movq JB_RBP(%rdi), %rbp
- movq JB_RSP(%rdi), %rsp
- movq JB_R12(%rdi), %r12
- movq JB_R13(%rdi), %r13
- movq JB_R14(%rdi), %r14
- movq JB_R15(%rdi), %r15
-
- // restore FP control word
- fldcw JB_FPCONTROL(%rdi)
-
- // restore MXCSR
- ldmxcsr JB_MXCSR(%rdi)
-
-
- // Make sure DF is reset
- cld
-
- jmp *JB_RIP(%rdi)
+++ /dev/null
-/*
- * Copyright (c) 2007, 2011 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <sys/syscall.h>
-
-#define UC_TRAD 1
-#define UC_FLAVOR 30
-
-/* Structure fields for ucontext and mcontext. */
-#define UCONTEXT_UC_MCONTEXT 48
-
-#define MCONTEXT_ES_EXCEPTION 0
-#define MCONTEXT_SS_RAX 16
-#define MCONTEXT_SS_RBX 24
-#define MCONTEXT_SS_RCX 32
-#define MCONTEXT_SS_RDX 40
-#define MCONTEXT_SS_RDI 48
-#define MCONTEXT_SS_RSI 56
-#define MCONTEXT_SS_RBP 64
-#define MCONTEXT_SS_RSP 72
-#define MCONTEXT_SS_R8 80
-#define MCONTEXT_SS_RIP 144
-
-/* register use:
- %rbx uctx
-
-void
-_sigtramp(
- union __sigaction_u __sigaction_u, %rdi
- int sigstyle, %rsi
- int sig, %rdx
- siginfo_t *sinfo, %rcx
- ucontext_t *uctx %r8
-)
-*/
-
- .globl __sigtramp
- .text
- .align 4,0x90
-__sigtramp:
-Lstart:
- /* Although this routine does not need any stack frame, various parts
- of the OS can't analyse the stack without them. */
- pushq %rbp
- movq %rsp, %rbp
-
- movq %rdi, %rax # set up address for call
-
-#if defined(__DYNAMIC__)
- incl ___in_sigtramp(%rip)
-#endif
- /* Save uctx in %rbx. */
- movq %r8, %rbx
- /* Call the signal handler.
- Some variants are not supposed to get the last two parameters,
- but the test to prevent this is more expensive than just passing
- them. */
- movl %edx, %edi
- movq %rcx, %rsi
- movq %r8, %rdx
-Lcall_start:
- call *%rax
-Lcall_end:
-#if defined(__DYNAMIC__)
- decl ___in_sigtramp(%rip)
-#endif
- movq %rbx, %rdi
- movl $ UC_FLAVOR, %esi
- callq ___sigreturn
- ret
-Lend:
-
-/* DWARF unwind table #defines. */
-#define DW_CFA_advance_loc_4 0x44
-#define DW_CFA_def_cfa 0x0c
-#define DW_CFA_def_cfa_expression 0x0F
-#define DW_CFA_expression 0x10
-#define DW_CFA_val_expression 0x16
-#define DW_CFA_offset(column) 0x80+(column)
-
-/* DWARF expression #defines. */
-#define DW_OP_deref 0x06
-#define DW_OP_const1u 0x08
-#define DW_OP_dup 0x12
-#define DW_OP_drop 0x13
-#define DW_OP_over 0x14
-#define DW_OP_pick 0x15
-#define DW_OP_swap 0x16
-#define DW_OP_rot 0x17
-#define DW_OP_abs 0x19
-#define DW_OP_and 0x1a
-#define DW_OP_div 0x1b
-#define DW_OP_minus 0x1c
-#define DW_OP_mod 0x1d
-#define DW_OP_mul 0x1e
-#define DW_OP_neg 0x1f
-#define DW_OP_not 0x20
-#define DW_OP_or 0x21
-#define DW_OP_plus 0x22
-#define DW_OP_plus_uconst 0x23
-#define DW_OP_shl 0x24
-#define DW_OP_shr 0x25
-#define DW_OP_shra 0x26
-#define DW_OP_xor 0x27
-#define DW_OP_skip 0x2f
-#define DW_OP_bra 0x28
-#define DW_OP_eq 0x29
-#define DW_OP_ge 0x2A
-#define DW_OP_gt 0x2B
-#define DW_OP_le 0x2C
-#define DW_OP_lt 0x2D
-#define DW_OP_ne 0x2E
-#define DW_OP_lit(n) 0x30+(n)
-#define DW_OP_breg(n) 0x70+(n)
-#define DW_OP_deref_size 0x94
-
-/* The location expression we'll use. */
-
-#define loc_expr_for_reg(regno, offs) \
- .byte DW_CFA_expression, regno, 5 /* block length */, \
- DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \
- DW_OP_plus_uconst, offs
-
-/* For r8 through r13 */
-#define loc_expr_rN(regno) \
- loc_expr_for_reg(regno, MCONTEXT_SS_R8+(8*(regno-8)))
-
-/* For r14 through r15 */
-#define loc_expr_rN_long(regno) \
- .byte DW_CFA_expression, regno, 6 /* block length */, \
- DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, \
- DW_OP_plus_uconst, MCONTEXT_SS_R8+(8*(regno-8)), 1
-
- /* Unwind tables. */
- .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support
-EH_frame1:
- .set L$set$0,LECIE1-LSCIE1
- .long L$set$0 # Length of Common Information Entry
-LSCIE1:
- .long 0 # CIE Identifier Tag
- .byte 0x1 # CIE Version
- .ascii "zRS\0" # CIE Augmentation
- .byte 0x1 # uleb128 0x1; CIE Code Alignment Factor
- .byte 0x78 # sleb128 -8; CIE Data Alignment Factor
- .byte 0x10 # CIE RA Column
- .byte 0x1 # uleb128 0x1; Augmentation size
- .byte 0x10 # FDE Encoding (pcrel)
- .byte DW_CFA_def_cfa
- .byte 0x7 # uleb128 0x5
- .byte 0x8 # uleb128 0x4
- .byte DW_CFA_offset(16)
- .byte 0x1 # uleb128 0x1
- .byte DW_CFA_offset(16) // duplicate DW_CFA_offset (rip, -8) tells linker to not make compact unwind
- .byte 0x1 # uleb128 0x1
- .align 3
-LECIE1:
- .globl _sigtramp.eh
-_sigtramp.eh:
-LSFDE1:
- .set L$set$1,LEFDE1-LASFDE1
- .long L$set$1 # FDE Length
-LASFDE1:
- .long LASFDE1-EH_frame1 # FDE CIE offset
- .quad Lstart-. # FDE initial location
- .set L$set$2,Lend-Lstart
- .quad L$set$2 # FDE address range
- .byte 0x0 # uleb128 0x0; Augmentation size
-
- /* Now for the expressions, which all compute
- uctx->uc_mcontext->register
- for each register.
-
- Describe even the registers that are not call-saved because they
- might be being used in the prologue to save other registers.
- Only integer registers are described at present. */
-
- loc_expr_for_reg (0, MCONTEXT_SS_RAX)
- loc_expr_for_reg (1, MCONTEXT_SS_RDX)
- loc_expr_for_reg (2, MCONTEXT_SS_RCX)
- loc_expr_for_reg (3, MCONTEXT_SS_RBX)
- loc_expr_for_reg (4, MCONTEXT_SS_RSI)
- loc_expr_for_reg (5, MCONTEXT_SS_RDI)
- loc_expr_for_reg (6, MCONTEXT_SS_RBP)
- loc_expr_for_reg (7, MCONTEXT_SS_RSP)
- loc_expr_rN (8)
- loc_expr_rN (9)
- loc_expr_rN (10)
- loc_expr_rN (11)
- loc_expr_rN (12)
- loc_expr_rN (13)
- loc_expr_rN_long (14)
- loc_expr_rN_long (15)
-
- /* The Intel architecture classifies exceptions into three categories,
- 'faults' which put the address of the faulting instruction
- in EIP, 'traps' which put the following instruction in EIP,
- and 'aborts' which don't typically report the instruction
- causing the exception.
-
- The traps are #BP and #OF. */
-
- .byte DW_CFA_val_expression, 16
- .set L$set$3,Lpc_end-Lpc_start
- .byte L$set$3
-Lpc_start:
- /* Push the mcontext address twice. */
- .byte DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref, DW_OP_dup
- /* Find the value of EIP. */
- .byte DW_OP_plus_uconst, MCONTEXT_SS_RIP, MCONTEXT_SS_RIP >> 7
- .byte DW_OP_deref, DW_OP_swap
- /* Determine the exception type. */
- .byte DW_OP_plus_uconst, MCONTEXT_ES_EXCEPTION, DW_OP_deref_size, 4
- /* Check whether it is #BP (3) or #OF (4). */
- .byte DW_OP_dup, DW_OP_lit(3), DW_OP_ne
- .byte DW_OP_swap, DW_OP_lit(4), DW_OP_ne, DW_OP_and
- /* If it is not, then add 1 to the instruction address, so as to point
- within or past the faulting instruction. */
- .byte DW_OP_plus
-Lpc_end:
-
- /* The CFA will have been saved as the value of RSP (it is not
- RSP+8). */
- .byte DW_CFA_def_cfa_expression
- .set L$set$4,Lcfa_end-Lcfa_start
- .byte L$set$4
-Lcfa_start:
- .byte DW_OP_breg(3), UCONTEXT_UC_MCONTEXT, DW_OP_deref
- .byte DW_OP_plus_uconst, MCONTEXT_SS_RSP, DW_OP_deref
-Lcfa_end:
-
- .align 3
-LEFDE1:
-
- .subsections_via_symbols
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-#define RESOLVER_UP_MP(symbol) \
- PLATFUNC_DESCRIPTOR(symbol, up, kUP, 0); \
- PLATFUNC_DESCRIPTOR(symbol, mp, 0, kUP); \
- static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \
- PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \
- PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \
- 0 \
- }; \
- void* symbol ## _chooser() __asm__("_" #symbol); \
- void* symbol ## _chooser() { \
- __asm__(".symbol_resolver _" #symbol); \
- return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \
- }
-
-RESOLVER_UP_MP(OSAtomicAnd32)
-RESOLVER_UP_MP(OSAtomicAnd32Barrier)
-RESOLVER_UP_MP(OSAtomicOr32)
-RESOLVER_UP_MP(OSAtomicOr32Barrier)
-RESOLVER_UP_MP(OSAtomicXor32)
-RESOLVER_UP_MP(OSAtomicXor32Barrier)
-RESOLVER_UP_MP(OSAtomicAnd32Orig)
-RESOLVER_UP_MP(OSAtomicAnd32OrigBarrier)
-RESOLVER_UP_MP(OSAtomicOr32Orig)
-RESOLVER_UP_MP(OSAtomicOr32OrigBarrier)
-RESOLVER_UP_MP(OSAtomicXor32Orig)
-RESOLVER_UP_MP(OSAtomicXor32OrigBarrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapInt)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapIntBarrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwap32)
-RESOLVER_UP_MP(OSAtomicCompareAndSwap32Barrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapPtr)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapPtrBarrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapLong)
-RESOLVER_UP_MP(OSAtomicCompareAndSwapLongBarrier)
-RESOLVER_UP_MP(OSAtomicCompareAndSwap64)
-RESOLVER_UP_MP(OSAtomicCompareAndSwap64Barrier)
-RESOLVER_UP_MP(OSAtomicAdd32)
-RESOLVER_UP_MP(OSAtomicAdd32Barrier)
-RESOLVER_UP_MP(OSAtomicAdd64)
-RESOLVER_UP_MP(OSAtomicAdd64Barrier)
-RESOLVER_UP_MP(OSAtomicTestAndSet)
-RESOLVER_UP_MP(OSAtomicTestAndSetBarrier)
-RESOLVER_UP_MP(OSAtomicTestAndClear)
-RESOLVER_UP_MP(OSAtomicTestAndClearBarrier)
+++ /dev/null
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <sys/appleapiopts.h>
-#include <machine/cpu_capabilities.h>
-
-#define NSEC_PER_SEC 1000*1000*1000
-#define NSEC_PER_USEC 1000
-
- .private_extern ___commpage_gettimeofday
- .align 4, 0x90
-___commpage_gettimeofday:
-// %rdi = ptr to timeval
- pushq %rbp // set up a frame for backtraces
- pushq %r12 // push callee-saved registers we want to use
- pushq %r13
- pushq %r14
- subq $8, %rsp
- movq %rsp,%rbp
- movq %rdi,%r12 // save ptr to timeval
- movq $(_COMM_PAGE_TIME_DATA_START),%r13
-0:
- movl _GTOD_GENERATION(%r13),%r14d // get generation (0 if disabled)
- testl %r14d,%r14d // disabled?
- jz 4f
-
- call _mach_absolute_time // get %rax <- nanotime()
-
- movl _GTOD_SEC_BASE(%r13),%r8d // get _COMM_PAGE_TIMESTAMP
- subq _GTOD_NS_BASE(%r13),%rax // generate nanoseconds since timestamp
- cmpl _GTOD_GENERATION(%r13),%r14d // has data changed out from under us?
- jne 0b
-
- movl $ NSEC_PER_SEC,%ecx
- movq %rax,%rdx
- shrq $32,%rdx // get high half of delta in %edx
- divl %ecx // %eax <- seconds since timestamp, %edx <- nanoseconds
- addl %eax,%r8d // add seconds elapsed to timestamp seconds
-
- movl $ NSEC_PER_USEC,%ecx
- movl %edx,%eax
- xorl %edx,%edx
- divl %ecx // divide residual ns by 1000 to get residual us in %eax
-
- movq %r8,(%r12) // store 64-bit seconds into timeval
- movl %eax,8(%r12) // store 32-bit useconds into timeval
- xorl %eax,%eax // return 0 for success
-3:
- addq $8, %rsp
- popq %r14
- popq %r13
- popq %r12
- popq %rbp
- ret
-4: // fail
- movl $1,%eax
- jmp 3b
+++ /dev/null
-/*
- * Copyright (c) 2003-2007 Apple Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <sys/appleapiopts.h>
-#include <machine/cpu_capabilities.h>
-
-/*
- * 64-bit version _mach_absolute_time. We return the 64-bit nanotime in %rax.
- *
- * The algorithm we use is:
- *
- * ns = ((((rdtsc - rnt_tsc_base)<<rnt_shift)*rnt_tsc_scale) / 2**32) + rnt_ns_base;
- *
- * rnt_shift, a constant computed during initialization, is the smallest value for which:
- *
- * tscFreq << rnt_shift) > SLOW_TSC_THRESHOLD
- *
- * Where SLOW_TSC_THRESHOLD is about 10e9. Since most processor's tscFreqs are greater
- * than 1GHz, rnt_shift is usually 0. rnt_tsc_scale is also a 32-bit constant:
- *
- * rnt_tsc_scale = (10e9 * 2**32) / (tscFreq << rnt_shift);
- *
- */
- .globl _mach_absolute_time
-_mach_absolute_time:
- pushq %rbp // set up a frame for backtraces
- movq %rsp,%rbp
- movq $(_COMM_PAGE_TIME_DATA_START),%rsi
-1:
- movl _NT_GENERATION(%rsi),%r8d // get generation
- testl %r8d,%r8d // if 0, data is being changed...
- jz 1b // ...so loop until stable
- lfence
- rdtsc // edx:eax := tsc
- lfence
- shlq $32,%rdx // rax := ((edx << 32) | eax), ie 64-bit tsc
- orq %rdx,%rax
-
- /*
- * Prior to supporting "slow" processors, xnu always set _NT_SHIFT to 32.
- * Now it defaults to 0, unless the processor is slow. In order to maintain
- * compatibility with both old and new versions of xnu, we mask the shift
- * down to 0x1F, which maps the old default (32) into the new default (0).
- */
- movl _NT_SHIFT(%rsi),%ecx
- andl $0x1F,%ecx // *** remove this line once 10.9 is GM ***
- subq _NT_TSC_BASE(%rsi), %rax // rax := (tsc - base_tsc)
- shlq %cl,%rax // rax := (tsc - base_tsc) << NT_SHIFT
- movl _NT_SCALE(%rsi),%ecx
- mulq %rcx // rdx:rax := ((tsc - base_tsc)<<shift) * scale
- shrdq $32,%rdx,%rax // divide by 2**32
- addq _NT_NS_BASE(%rsi),%rax // (((tsc - base_tsc) * scale) >> 32) + ns_base
-
- cmpl _NT_GENERATION(%rsi),%r8d // did the data change during computation?
- jne 1b
- popq %rbp
- ret
+++ /dev/null
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
- */
-/*
- * NeXT 386 setjmp/longjmp
- *
- * Written by Bruce Martin, NeXT Inc. 4/9/92
- */
-
-/*
- * C library -- setjmp, longjmp
- *
- * longjmp(a,v)
- * will generate a "return(v)" from
- * the last call to
- * setjmp(a)
- * by restoring registers from the stack,
- * The previous value of the signal mask is
- * restored.
- *
- */
-
-#include <architecture/i386/asm_help.h>
-
-#define JB_RBX 0
-#define JB_RBP 8
-#define JB_RSP 16
-#define JB_R12 24
-#define JB_R13 32
-#define JB_R14 40
-#define JB_R15 48
-#define JB_RIP 56
-#define JB_RFLAGS 64
-#define JB_MXCSR 72
-#define JB_FPCONTROL 76
-#define JB_MASK 80
-#define JB_SAVEMASK 84 // sigsetjmp/siglongjmp only
-#define JB_ONSTACK 88
-
-#define STACK_SSFLAGS 16 // offsetof(stack_t, ss_flags)
-
-LEAF(_sigsetjmp, 0)
- // %rdi is sigjmp_buf * jmpbuf;
- // %esi is int savemask
- movl %esi, JB_SAVEMASK(%rdi) // jmpbuf[_JBLEN] = savemask;
- cmpl $0, %esi // if savemask != 0
- jne _setjmp // setjmp(jmpbuf);
- jmp L_do__setjmp // else _setjmp(jmpbuf);
-
-LEAF(_setjmp, 0)
- pushq %rdi // Preserve the jmp_buf across the call
- movl $1, %edi // how = SIG_BLOCK
- xorq %rsi, %rsi // set = NULL
- subq $16, %rsp // Allocate space for the return from sigprocmask + 8 to align stack
- movq %rsp, %rdx // oset = allocated space
- CALL_EXTERN(_sigprocmask)
- popq %rax // Save the mask
- addq $8, %rsp // Restore the stack to before we align it
- movq (%rsp), %rdi // jmp_buf (struct sigcontext *). Leave pointer on the stack for _sigaltstack call)
- movl %eax, JB_MASK(%rdi)
-
- // Get current sigaltstack status (stack_t)
- subq $32, %rsp // 24 bytes for a stack_t, + 8 for the jmp_buf pointer, + 8 is correctly aligned
- movq %rsp, %rsi // oss
- xorq %rdi, %rdi // ss == NULL
- CALL_EXTERN(_sigaltstack) // sigaltstack(NULL, oss)
- movl STACK_SSFLAGS(%rsp), %eax // oss.ss_flags
- movq 32(%rsp), %rdi // jmpbuf (will be first argument to subsequent call)
- movl %eax, JB_ONSTACK(%rdi) // Store ss_flags in jmpbuf
- addq $40, %rsp // restore %rsp
-
-L_do__setjmp:
- BRANCH_EXTERN(__setjmp)
-
-LEAF(_siglongjmp, 0)
- // %rdi is sigjmp_buf * jmpbuf;
- cmpl $0, JB_SAVEMASK(%rdi) // if jmpbuf[_JBLEN] != 0
- jne _longjmp // longjmp(jmpbuf, var);
- jmp L_do__longjmp // else _longjmp(jmpbuf, var);
-
-LEAF(_longjmp, 0)
- // %rdi is address of jmp_buf (saved context)
- pushq %rdi // Preserve the jmp_buf across the call
- pushq %rsi // Preserve the value across the call
- pushq JB_MASK(%rdi) // Put the mask on the stack
- movq $3, %rdi // how = SIG_SETMASK
- movq %rsp, %rsi // set = address where we stored the mask
- xorq %rdx, %rdx // oset = NULL
- CALL_EXTERN_AGAIN(_sigprocmask)
-
- // Restore sigaltstack status
- movq 16(%rsp), %rdi // Grab jmpbuf but leave it on the stack
- movl JB_ONSTACK(%rdi), %edi // Pass old state to _sigunaltstack()
- CALL_EXTERN(__sigunaltstack)
- addq $8, %rsp // Restore stack
- popq %rsi
- popq %rdi // Pass jmpbuf to _longjmp
-
-L_do__longjmp:
- BRANCH_EXTERN(__longjmp) // else
-END(_longjmp)
+++ /dev/null
-/*
- * Copyright (c) 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#include <machine/cpu_capabilities.h>
-#include "platfunc.h"
-
-#define RESOLVER_UP_MP(symbol) \
- PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, up); \
- PLATFUNC_DESCRIPTOR_PROTOTYPE(symbol, mp); \
- static const platfunc_descriptor* symbol ## _platfunc_descriptors[] = { \
- PLATFUNC_DESCRIPTOR_REFERENCE(symbol, mp), \
- PLATFUNC_DESCRIPTOR_REFERENCE(symbol, up), \
- 0 \
- }; \
- void* symbol ## _chooser() __asm__("_" #symbol); \
- void* symbol ## _chooser() { \
- __asm__(".symbol_resolver _" #symbol); \
- return find_platform_function((const platfunc_descriptor**) symbol ## _platfunc_descriptors); \
- }
-
-RESOLVER_UP_MP(OSSpinLockTry)
-RESOLVER_UP_MP(_spin_lock_try)
-RESOLVER_UP_MP(OSSpinLockLock)
-RESOLVER_UP_MP(_spin_lock)
-RESOLVER_UP_MP(spin_lock)
+++ /dev/null
-/*
- * Copyright (c) 2003-2009 Apple, Inc. All rights reserved.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. The rights granted to you under the License
- * may not be used to create, or enable the creation or redistribution of,
- * unlawful or unlicensed copies of an Apple operating system, or to
- * circumvent, violate, or enable the circumvention or violation of, any
- * terms of an Apple operating system software license agreement.
- *
- * Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
- */
-
-#include <sys/appleapiopts.h>
-#include <machine/cpu_capabilities.h>
-#include <mach/i386/syscall_sw.h>
-#include "platfunc.h"
-
-PLATFUNC_FUNCTION_START(OSSpinLockTry, up, 64, 4)
-PLATFUNC_FUNCTION_START(_spin_lock_try, up, 64, 4)
- xorl %eax, %eax
- orl $-1, %edx
- cmpxchgl %edx, (%rdi)
- setz %dl
- movzbl %dl, %eax
- ret
-PLATFUNC_DESCRIPTOR(OSSpinLockTry,up,kUP,0)
-PLATFUNC_DESCRIPTOR(_spin_lock_try,up,kUP,0)
-
-
-PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockTry, mp, 64, 4)
-PLATFUNC_FUNCTION_START_GENERIC(_spin_lock_try, mp, 64, 4)
- xorl %eax, %eax
- orl $-1, %edx
- lock
- cmpxchgl %edx, (%rdi)
- setz %dl
- movzbl %dl, %eax
- ret
-PLATFUNC_DESCRIPTOR(OSSpinLockTry,mp,0,kUP)
-PLATFUNC_DESCRIPTOR(_spin_lock_try,mp,0,kUP)
-
-
-PLATFUNC_FUNCTION_START(OSSpinLockLock, up, 64, 4)
-PLATFUNC_FUNCTION_START(_spin_lock, up, 64, 4)
-PLATFUNC_FUNCTION_START(spin_lock, up, 64, 4)
- movq %rdi,%r8
-0:
- xorl %eax, %eax
- orl $-1, %edx
- cmpxchgl %edx, (%r8)
- jnz 1f
- ret
-1:
- /* failed to get lock so relinquish the processor immediately on UP */
- xorl %edi,%edi /* THREAD_NULL */
- movl $1,%esi /* SWITCH_OPTION_DEPRESS */
- movl $1,%edx /* 1 ms */
- movl $(SYSCALL_CONSTRUCT_MACH(61)),%eax /* 61 = thread_switch */
- syscall
- jmp 0b
-PLATFUNC_DESCRIPTOR(OSSpinLockLock,up,kUP,0)
-PLATFUNC_DESCRIPTOR(_spin_lock,up,kUP,0)
-PLATFUNC_DESCRIPTOR(spin_lock,up,kUP,0)
-
-
-PLATFUNC_FUNCTION_START_GENERIC(OSSpinLockLock, mp, 64, 4)
-PLATFUNC_FUNCTION_START_GENERIC(_spin_lock, mp, 64, 4)
-PLATFUNC_FUNCTION_START_GENERIC(spin_lock, mp, 64, 4)
- movq %rdi,%r8
-0:
- xorl %eax, %eax
- orl $-1, %edx
- lock
- cmpxchgl %edx, (%r8)
- jnz 1f
- ret
-1:
- xorl %eax, %eax
- movl $(MP_SPIN_TRIES), %edx
-2: /* spin for awhile before relinquish */
- pause
- cmpl %eax, (%r8)
- jz 0b
- decl %edx
- jnz 2b
- /* failed to get lock after spinning so relinquish */
- xorl %edi,%edi /* THREAD_NULL */
- movl $1,%esi /* SWITCH_OPTION_DEPRESS */
- movl $1,%edx /* 1 ms */
- movl $(SYSCALL_CONSTRUCT_MACH(61)),%eax /* 61 = thread_switch */
- syscall
- jmp 0b
-PLATFUNC_DESCRIPTOR(OSSpinLockLock,mp,0,kUP)
-PLATFUNC_DESCRIPTOR(_spin_lock,mp,0,kUP)
-PLATFUNC_DESCRIPTOR(spin_lock,mp,0,kUP)
-
-// void OSSpinLockUnlock( OSSpinLock *lock );
- .align 2, 0x90
- .globl _OSSpinLockUnlock
- .globl _spin_unlock
- .globl __spin_unlock
-_OSSpinLockUnlock:
-_spin_unlock:
-__spin_unlock:
- movl $0, (%rdi)
- ret
-
# Skip script during installhdrs
if [ "$ACTION" == installhdrs ]; then exit 0; fi
+# BUILD_ARCHIVES needs to be set in the project settings
+if [ -z "$BUILD_ARCHIVES" ]; then exit 0; fi
-ARCHIVES=(Platform Base FreeBSD FreeBSD_gcc NetBSD TRE vCancelable vDarwinExtsn vDarwinExtsnCancelable vPre1050 vLegacy vInode32)
+[ ! -d "$BUILT_PRODUCTS_DIR" ] && mkdir -p "$BUILT_PRODUCTS_DIR"
+[ ! -d "$DERIVED_FILES_DIR" ] && mkdir -p "$DERIVED_FILES_DIR"
NORMAL_LIST="$BUILT_PRODUCTS_DIR/normal.linklist"
DEBUG_LIST="$BUILT_PRODUCTS_DIR/debug.linklist"
INTERPOSABLE_LIST="$DERIVED_FILES_DIR/interposable.list"
+UNEXPORT_LIST="$DERIVED_FILES_DIR/unexport.list"
rm -f $NORMAL_LIST
rm -f $DEBUG_LIST
rm -f $INTERPOSABLE_LIST
+rm -f $UNEXPORT_LIST
-for x in ${ARCHIVES[@]}; do
+for x in ${BUILD_ARCHIVES[@]}; do
nm -AUamgf "$BUILT_PRODUCTS_DIR/lib${x}.a" 2>/dev/null | \
grep '__TEXT,__text' | \
- grep -v '\[symbol resolver\]' | \
- grep -vE '\$VARIANT\$(m|u)p' | \
+ grep -vE '\$VARIANT' | \
awk '{ print $NF }' >> $INTERPOSABLE_LIST
- echo "-l$x" >> $NORMAL_LIST
- echo "-l${x}_debug" >> $DEBUG_LIST
+ nm -AUamgf "$BUILT_PRODUCTS_DIR/lib${x}.a" 2>/dev/null | \
+ awk '/\$VARIANT/ { print $NF }' >> $UNEXPORT_LIST
+
+ echo "$BUILT_PRODUCTS_DIR/lib${x}.a" >> $NORMAL_LIST
+ echo "$BUILT_PRODUCTS_DIR/lib${x}_debug.a" >> $DEBUG_LIST
done
touch "$BUILT_PRODUCTS_DIR/deps.c"
--- /dev/null
+#include "libc.xcconfig"
+
+BUILD_ARCHIVES = Base FreeBSD TRE vCancelable vDarwinExtsn
+BUILD_VARIANTS = normal
+EXECUTABLE_PREFIX = lib
+INSTALL_PATH = /usr/local/lib/eOS
+OTHER_LDFLAGS = -filelist $(BUILT_PRODUCTS_DIR)/$(CURRENT_VARIANT).linklist
+PRODUCT_NAME = c_eOS
+SKIP_INSTALL = YES
+SKIP_INSTALL[sdk=iphoneos*] = NO
+STRIP_INSTALLED_PRODUCT = NO
+VARIANT = EOS
+VERSIONING_SYSTEM = apple-generic
+
+// Variants. All variants contain all source files but all excluded. Specific variants then include the files they need.
+EXCLUDED_SOURCE_FILE_NAMES = *
+EXCLUDED_SOURCE_FILE_NAMES[sdk=iphoneos*] = $(VARIANT_EOS_EXCLUDED_FILES)
+INCLUDED_SOURCE_FILE_NAMES =
+INCLUDED_SOURCE_FILE_NAMES[sdk=iphoneos*] = $(VARIANT_EOS_INCLUDED_FILES)
+VARIANT_PREPROCESSOR_MACROS = -UBUILDING_VARIANT -DVARIANT_DYLD -DVARIANT_EOS -DVARIANT_CANCELABLE -DVARIANT_DARWINEXTSN -U__DARWIN_NON_CANCELABLE -D__DARWIN_NON_CANCELABLE=0
+
+SYSTEM_FRAMEWORK_HEADERS = $(DERIVED_FILES_DIR)/System.framework/Versions/B/PrivateHeaders
+HEADER_SEARCH_PATHS = $(FreeBSD_SEARCH_PATHS) $(inherited)
+
+// EOS (libc_eOS.a)
+VARIANT_EOS_EXCLUDED_FILES = *
+VARIANT_EOS_INCLUDED_FILES = secure/*.c $(ARCH_FAMILY_$(CURRENT_ARCH))/*/*.c $(ARCH_FAMILY_$(CURRENT_ARCH))/*/*.S $(ARCH_FAMILY_$(CURRENT_ARCH))/*/*.s
my $regex = $2;
$nested++;
- if ($ENV{$envvar} !~ /$regex/) {
+ if (!defined($ENV{$envvar}) || ($ENV{$envvar} !~ /$regex/)) {
$skip += 1;
}
}
}
elsif ($unifdef == 1) {
+ if ($platformName eq "macosx") {
+ $unifdefs{"__OSX_OPEN_SOURCE__"} = 1;
+ }
# assume FEATURE_BLOCKS was on by default
$unifdefs{"UNIFDEF_BLOCKS"} = 1;
$unifdefs{"UNIFDEF_LEGACY_64_APIS"} = defined($features{"FEATURE_LEGACY_64_APIS"});
$unifdefs{"UNIFDEF_LEGACY_RUNE_APIS"} = defined($features{"FEATURE_LEGACY_RUNE_APIS"});
$unifdefs{"UNIFDEF_LEGACY_UTMP_APIS"} = defined($features{"FEATURE_LEGACY_UTMP_APIS"});
$unifdefs{"UNIFDEF_MOVE_LOCALTIME"} = defined($features{"FEATURE_MOVE_LOCALTIME"});
+ $unifdefs{"UNIFDEF_TZDIR_SYMLINK"} = defined($features{"FEATURE_TZDIR_SYMLINK"});
my $output = "";
for my $d (keys %unifdefs) {
my $platform_mtime = (stat($platformPath))[9];
my $header_mtime = (stat($featuresHeader))[9];
- if ($header_mtime > $platform_mtime) {
+ if (defined($header_mtime) && defined($platform_mtime) && ($header_mtime > $platform_mtime)) {
exit 0;
}
printf HEADER "/* #undef UNIFDEF_MOVE_LOCALTIME */\n";
}
+ if (defined($features{"FEATURE_TZDIR_SYMLINK"})) {
+ printf HEADER "#define UNIFDEF_TZDIR_SYMLINK 1\n";
+ } else {
+ printf HEADER "/* #undef UNIFDEF_TZDIR_SYMLINK */\n";
+ }
+
if (defined($features{"FEATURE_ONLY_1050_VARIANTS"})) {
printf HEADER "#if !__DARWIN_ONLY_VERS_1050\n";
printf HEADER "# error Feature mismatch: __DARWIN_ONLY_VERS_1050 == 0\n";
printf HEADER "/* #undef __APPLE_PR3417676_HACK__ */\n";
}
- if (defined($features{"FEATURE_PATCH_5243343"})) {
- printf HEADER "#define PR_5243343 1\n";
- } else {
- printf HEADER "/* #undef PR_5243343 */\n";
- }
-
if (defined($features{"FEATURE_PLOCKSTAT"})) {
printf HEADER "#define PLOCKSTAT 1\n";
} else {
printf HEADER "/* #undef LIBC_NO_LIBCRASHREPORTERCLIENT */\n";
}
- if (defined($features{"FEATURE_MEMORYSTATUS"})) {
- printf HEADER "#define CONFIG_MEMORYSTATUS 1\n";
+ if (defined($features{"FEATURE_SMALL_STDIOBUF"})) {
+ printf HEADER "#define FEATURE_SMALL_STDIOBUF 1\n";
+ } else {
+ printf HEADER "/* #undef FEATURE_SMALL_STDIOBUF */\n";
+ }
+
+ if (defined($features{"FEATURE_XPRINTF_PERF"})) {
+ printf HEADER "#define XPRINTF_PERF 1\n";
} else {
- printf HEADER "/* #undef CONFIG_MEMORYSTATUS */\n";
+ printf HEADER "/* #undef XPRINTF_PERF */\n";
}
printf HEADER "#endif // _LIBC_FEATURES_H_\n";
INSTALLMODE=$([[ `id -u` -eq 0 ]] && echo 444 || echo 644)
INSTHDRS=(
- ${SRCROOT}/darwin/libproc.h
${SRCROOT}/gen/get_compat.h
${SRCROOT}/gen/execinfo.h
)
INC_INSTHDRS=(
NSSystemDirectories.h _locale.h _structs.h _types.h _wctype.h _xlocale.h aio.h alloca.h \
- ar.h asl.h assert.h asm.h bitstring.h cpio.h crt_externs.h ctype.h db.h dirent.h disktab.h err.h \
+ ar.h assert.h asm.h bitstring.h cpio.h crt_externs.h ctype.h db.h dirent.h disktab.h err.h \
errno.h fcntl.h fmtmsg.h fnmatch.h fsproperties.h fstab.h fts.h ftw.h getopt.h glob.h inttypes.h \
iso646.h langinfo.h libc.h libgen.h limits.h locale.h memory.h monetary.h monitor.h mpool.h ndbm.h \
- nlist.h paths.h poll.h ranlib.h readpassphrase.h regex.h runetype.h search.h \
- semaphore.h setjmp.h sgtty.h signal.h spawn.h stab.h standards.h stdbool.h stddef.h stdio.h stdint.h \
+ nlist.h paths.h printf.h poll.h ranlib.h readpassphrase.h regex.h runetype.h search.h \
+ semaphore.h sgtty.h signal.h stab.h standards.h stdbool.h stddef.h stdio.h stdint.h \
stdlib.h strhash.h string.h stringlist.h strings.h struct.h sysexits.h syslog.h tar.h termios.h time.h \
- timeconv.h ttyent.h ucontext.h ulimit.h unistd.h util.h utime.h vis.h wchar.h wctype.h \
+ timeconv.h ttyent.h ulimit.h unistd.h util.h utime.h vis.h wchar.h wctype.h \
wordexp.h xlocale.h
)
if [ "x${FEATURE_LEGACY_RUNE_APIS}" == "x1" ]; then
${SRCROOT}/include/NetBSD/utmpx.h
${SRCROOT}/stdtime/FreeBSD/tzfile.h
)
-INC_PTHREADHDRS=(
- ${SRCROOT}/pthreads/pthread.h
- ${SRCROOT}/pthreads/pthread_spis.h
- ${SRCROOT}/pthreads/pthread_impl.h
- ${SRCROOT}/pthreads/sched.h
-)
-INSTHDRS=( "${INSTHDRS[@]}" "${INC_INSTHDRS[@]}" "${INC_PTHREADHDRS[@]}" )
+INSTHDRS=( "${INSTHDRS[@]}" "${INC_INSTHDRS[@]}" )
-INC_ARPA_INSTHDRS=( ftp.h nameser_compat.h telnet.h tftp.h )
+INC_ARPA_INSTHDRS=( ftp.h inet.h nameser_compat.h telnet.h tftp.h )
ARPA_INSTHDRS=( "${INC_ARPA_INSTHDRS[@]/#/${SRCROOT}/include/arpa/}" )
-INC_LIBKERN_INSTHDRS=( OSAtomic.h OSCacheControl.h )
if [ "x${FEATURE_MEM_THERM_NOTIFICATION_APIS}" == "x1" ]; then
- INC_LIBKERN_INSTHDRS+=( OSMemoryNotification.h OSThermalNotification.h )
+ INC_LIBKERN_INSTHDRS=( OSMemoryNotification.h OSThermalNotification.h )
+ LIBKERN_INSTHDRS=( "${INC_LIBKERN_INSTHDRS[@]/#/${SRCROOT}/include/libkern/}" )
fi
-LIBKERN_INSTHDRS=( "${INC_LIBKERN_INSTHDRS[@]/#/${SRCROOT}/include/libkern/}" )
-
-MALLOC_INSTHDRS=( ${SRCROOT}/include/malloc/malloc.h )
INC_PROTO_INSTHDRS=(routed.h rwhod.h talkd.h timed.h )
PROTO_INSTHDRS=( "${INC_PROTO_INSTHDRS[@]/#/${SRCROOT}/include/protocols/}" )
)
XLOCALE_INSTHDRS=( "${INC_XLOCALE_INSTHDRS[@]/#/${SRCROOT}/include/xlocale/}" )
+TYPES_INSTHDRS=(
+ ${SRCROOT}/include/_types/_intmax_t.h
+ ${SRCROOT}/include/_types/_nl_item.h
+ ${SRCROOT}/include/_types/_uint16_t.h
+ ${SRCROOT}/include/_types/_uint32_t.h
+ ${SRCROOT}/include/_types/_uint64_t.h
+ ${SRCROOT}/include/_types/_uint8_t.h
+ ${SRCROOT}/include/_types/_uintmax_t.h
+ ${SRCROOT}/include/_types/_wctrans_t.h
+ ${SRCROOT}/include/_types/_wctype_t.h
+)
+
LOCALHDRS=(
${SRCROOT}/darwin/dirhelper.defs
${SRCROOT}/darwin/dirhelper_priv.h
- ${SRCROOT}/darwin/libproc.h
- ${SRCROOT}/darwin/libproc_internal.h
- ${SRCROOT}/gen/asl_core.h
- ${SRCROOT}/gen/asl_file.h
- ${SRCROOT}/gen/asl_ipc.defs
- ${SRCROOT}/gen/asl_legacy1.h
- ${SRCROOT}/gen/asl_msg.h
- ${SRCROOT}/gen/asl_private.h
- ${SRCROOT}/gen/asl_store.h
- ${SRCROOT}/gen/assumes.h
- ${SRCROOT}/gen/_simple.h
- ${SRCROOT}/gen/stack_logging.h
+ ${SRCROOT}/gen/assumes.h
${SRCROOT}/gen/utmpx_thread.h
- ${SRCROOT}/include/spawn_private.h
${SRCROOT}/nls/FreeBSD/msgcat.h
- ${SRCROOT}/pthreads/pthread_workqueue.h
)
+OS_LOCALHDRS=( ${SRCROOT}/os/assumes.h ${SRCROOT}/os/base.h ${SRCROOT}/os/trace.h )
+
PRIV_INSTHDRS=(
- ${SRCROOT}/gen/stack_logging.h
- ${SRCROOT}/pthreads/pthread_machdep.h
${SRCROOT}/stdlib/FreeBSD/atexit.h
)
${SRCROOT}/db/btree/FreeBSD/bt_extern.h
)
-SYS_INSTHDRS=( ${SRCROOT}/include/sys/acl.h ${SRCROOT}/include/sys/statvfs.h )
+SYS_INSTHDRS=( ${SRCROOT}/include/sys/acl.h ${SRCROOT}/include/sys/rbtree.h ${SRCROOT}/include/sys/statvfs.h )
PRIVUUID_INSTHDRS=( ${SRCROOT}/uuid/namespace.h )
${MKDIR} ${INCDIR}/arpa
${MKDIR} ${INCDIR}/secure
${MKDIR} ${INCDIR}/sys
${MKDIR} ${INCDIR}/xlocale
+${MKDIR} ${INCDIR}/_types
${INSTALL} -m ${INSTALLMODE} ${INSTHDRS[@]} ${INCDIR}
${INSTALL} -m ${INSTALLMODE} ${ARPA_INSTHDRS[@]} ${INCDIR}/arpa
+if [ "x${FEATURE_MEM_THERM_NOTIFICATION_APIS}" == "x1" ]; then
${INSTALL} -m ${INSTALLMODE} ${LIBKERN_INSTHDRS[@]} ${INCDIR}/libkern
-${INSTALL} -m ${INSTALLMODE} ${MALLOC_INSTHDRS[@]} ${INCDIR}/malloc
+fi
${INSTALL} -m ${INSTALLMODE} ${PROTO_INSTHDRS[@]} ${INCDIR}/protocols
${INSTALL} -m ${INSTALLMODE} ${SECURE_INSTHDRS[@]} ${INCDIR}/secure
${INSTALL} -m ${INSTALLMODE} ${SYS_INSTHDRS[@]} ${INCDIR}/sys
${INSTALL} -m ${INSTALLMODE} ${XLOCALE_INSTHDRS[@]} ${INCDIR}/xlocale
+${INSTALL} -m ${INSTALLMODE} ${TYPES_INSTHDRS[@]} ${INCDIR}/_types
${MKDIR} ${LOCINCDIR}
+${MKDIR} ${LOCINCDIR}/os
${INSTALL} -m ${INSTALLMODE} ${LOCALHDRS[@]} ${LOCINCDIR}
+${INSTALL} -m ${INSTALLMODE} ${OS_LOCALHDRS[@]} ${LOCINCDIR}/os
${MKDIR} ${PRIVHDRS}/btree
${MKDIR} ${PRIVHDRS}/machine
${MKDIR} ${PRIVHDRS}/uuid
${ED} - $i < ${SRCROOT}/xcodescripts/strip-header.ed &&
${CHMOD} u-w $i || exit 1;
done
-for i in `${FIND} "${DSTROOT}" -name \*.h -print0 | ${XARGS} -0 ${FGREP} -l UNIFDEF`; do
+for i in `${FIND} "${DSTROOT}" -name \*.h -print0 | ${XARGS} -0 ${FGREP} -l -e UNIFDEF -e OPEN_SOURCE`; do
${CHMOD} u+w $i &&
${CP} $i $i.orig &&
${ECHO} ${UNIFDEF} ${UNIFDEFARGS} $i.orig \> $i &&
// Standard settings
SUPPORTED_PLATFORMS = macosx iphoneos iphonesimulator
-SRCROOT_SEARCH_PATHS = $(SRCROOT)/include $(SRCROOT)/gen $(SRCROOT)/locale $(SRCROOT)/locale/FreeBSD $(SRCROOT)/pthreads $(SRCROOT)/stdtime/FreeBSD
+SRCROOT_SEARCH_PATHS = $(SRCROOT) $(SRCROOT)/include $(SRCROOT)/gen $(SRCROOT)/locale $(SRCROOT)/locale/FreeBSD $(SRCROOT)/stdtime/FreeBSD
SYSTEM_FRAMEWORK_HEADERS = $(SDKROOT)/System/Library/Frameworks/System.framework/PrivateHeaders
-HEADER_SEARCH_PATHS = $($(TARGET_NAME)_SEARCH_PATHS) $(DERIVED_FILES_DIR)/dtrace $(DERIVED_FILES_DIR)/$(CURRENT_ARCH) $(SRCROOT_SEARCH_PATHS) $(SYSTEM_FRAMEWORK_HEADERS) $(SDKROOT)/usr/local/include $(inherited)
+HEADER_SEARCH_PATHS = $($(TARGET_NAME)_SEARCH_PATHS) $(DERIVED_FILES_DIR)/dtrace $(SRCROOT_SEARCH_PATHS) $(SYSTEM_FRAMEWORK_HEADERS) $(SDKROOT)/usr/local/include $(inherited)
ALWAYS_SEARCH_USER_PATHS = YES
USE_HEADERMAP = NO
BUILD_VARIANTS = normal
GCC_SYMBOLS_PRIVATE_EXTERN = NO
GCC_DYNAMIC_NO_PIC = NO
GCC_THUMB_SUPPORT = YES
+GCC_TREAT_IMPLICIT_FUNCTION_DECLARATIONS_AS_ERRORS = YES;
+GCC_WARN_UNINITIALIZED_AUTOS = YES;
+GCC_WARN_UNUSED_VARIABLE = YES;
+GCC_WARN_ABOUT_RETURN_TYPE = YES;
+WARNING_CFLAGS = "-Wall";
+
COPY_PHASE_STRIP = NO
SKIP_INSTALL = YES
INSTALLHDRS_SCRIPT_PHASE = YES
LD_DYLIB_INSTALL_NAME = /usr/lib/system/$(EXECUTABLE_NAME)
BUILD_VARIANTS = normal debug
+BUILD_ARCHIVES = Platform Base FreeBSD NetBSD TRE vCancelable vDarwinExtsn vDarwinExtsnCancelable vPre1050 vLegacy vInode32 FortifySource
+// clang is desired over llvm-gcc for OSAtomics. However, it isn't capable of building armv6 correctly.
GCC_VERSION = com.apple.compilers.llvm.clang.1_0
GCC_VERSION[arch=armv6] = com.apple.compilers.llvmgcc42
INSTALL_PATH[sdk=iphonesimulator*] = $(SDKROOT)/usr/lib/system
BASE_PREPROCESSOR_MACROS = __LIBC__ __DARWIN_UNIX03=1 __DARWIN_64_BIT_INO_T=1 __DARWIN_NON_CANCELABLE=1 __DARWIN_VERS_1050=1 _FORTIFY_SOURCE=0
-OTHER_CFLAGS = -fdollars-in-identifiers $($(TARGET_NAME)_CFLAGS) $(VARIANT_PREPROCESSOR_MACROS)
+OTHER_CFLAGS = -fdollars-in-identifiers -fno-common -fverbose-asm $($(TARGET_NAME)_CFLAGS) $(VARIANT_PREPROCESSOR_MACROS)
OTHER_CFLAGS_debug = -fstack-protector -fno-inline -O0 -DDEBUG=1
GCC_PREPROCESSOR_DEFINITIONS = $(BASE_PREPROCESSOR_MACROS)
-GCC_PREPROCESSOR_DEFINITIONS[sdk=iphoneos*] = $(BASE_PREPROCESSOR_MACROS) LIBC_NO_LIBCRASHREPORTERCLIENT=1
-GCC_PREPROCESSOR_DEFINITIONS[sdk=iphonesimulator*] = $(BASE_PREPROCESSOR_MACROS) LIBC_NO_LIBCRASHREPORTERCLIENT=1
+GCC_PREPROCESSOR_DEFINITIONS[sdk=iphone*] = $(BASE_PREPROCESSOR_MACROS) LIBC_NO_LIBCRASHREPORTERCLIENT=1
// libsystem_c.dylib linking
CR_LDFLAGS[sdk=macosx*] = -lCrashReporterClient
LIBCOMPILER_RT_LDFLAGS = -lcompiler_rt
-LIBSYSTEM_C_LDFLAGS = -all_load -nostdlib -L/usr/lib/system -Wl,-interposable_list,$(DERIVED_FILES_DIR)/interposable.list -umbrella System $(CR_LDFLAGS) -lSystem -lsystem_kernel $(LIBCOMPILER_RT_LDFLAGS) @$(BUILT_PRODUCTS_DIR)/$(CURRENT_VARIANT).linklist
-LIBSYSTEM_C_LDFLAGS[sdk=iphonesimulator*] =
+LIBCOMPILER_RT_LDFLAGS[sdk=iphonesimulator*] = -lcompiler_rt_sim
+LIBMALLOC_LDFLAGS = -lsystem_malloc
+LIBMALLOC_LDFLAGS[sdk=iphonesimulator*] =
+LIBPLATFORM_LDFLAGS = -lsystem_platform
+LIBPLATFORM_LDFLAGS[sdk=iphonesimulator*] =
+LIBPTHREAD_LDFLAGS = -lsystem_pthread
+LIBPTHREAD_LDFLAGS[sdk=iphonesimulator*] =
+LIBSYSCALL_LDFLAGS = -lsystem_kernel
+LIBSYSCALL_LDFLAGS[sdk=iphonesimulator*] =
+LIBM_LDFLAGS = -lsystem_m
+LIBM_LDFLAGS[sdk=iphonesimulator*] = -lsystem_sim_m
+LIBDYLD_LDFLAGS = -ldyld
+LIBDYLD_LDFLAGS[sdk=iphonesimulator*] = -ldyld_sim
+LIBSYSTEM_C_LDFLAGS = -all_load -nostdlib -L/usr/lib/system -umbrella System $(CR_LDFLAGS) $(LIBCOMPILER_RT_LDFLAGS) $(LIBDYLD_LDFLAGS) $(LIBSYSCALL_LDFLAGS) $(LIBM_LDFLAGS) $(LIBMALLOC_LDFLAGS) $(LIBPLATFORM_LDFLAGS) $(LIBPTHREAD_LDFLAGS) $(UPWARD_LDFLAGS) -Wl,-interposable_list,$(DERIVED_FILES_DIR)/interposable.list -Wl,-unexported_symbols_list,$(DERIVED_FILES_DIR)/unexport.list -Wl,-alias_list,$(SRCROOT)/string/alias.list @$(BUILT_PRODUCTS_DIR)/$(CURRENT_VARIANT).linklist
+
+// TODO: Remove upward links - mostly <rdar://problem/13183469>, macho is for assumes.c
+UPWARD_LDFLAGS = -Wl,-upward-ldispatch -Wl,-upward-llaunch -Wl,-upward-lmacho -Wl,-upward-lsystem_asl -Wl,-upward-lsystem_blocks -Wl,-upward-lsystem_info -Wl,-upward-lsystem_notify -Wl,-upward-lxpc
+UPWARD_LDFLAGS[sdk=iphonesimulator*] = -Wl,-upward-ldispatch -Wl,-upward-lmacho_sim -Wl,-upward-lsystem_sim_blocks -Wl,-upward-lsystem_sim_info -Wl,-upward-lnotify_sim -Wl,-upward-lxpc -Wl,-upward-lSystem
// libPlatform.a architectures
ARCH_FAMILY = $(ARCH_FAMILY_$(CURRENT_ARCH))
ARCH_FAMILY_armv7f = arm
ARCH_FAMILY_armv7k = arm
+// Platform target
+Platform_INCLUDED_SOURCE_FILE_NAMES = $(Platform_INCLUDED_SOURCE_FILE_NAMES_$(PLATFORM_NAME))
+Platform_INCLUDED_SOURCE_FILE_NAMES_macosx = $(Platform_INCLUDED_SOURCE_FILE_NAMES_gen) $(Platform_INCLUDED_SOURCE_FILE_NAMES_stdlib) $(Platform_INCLUDED_SOURCE_FILE_NAMES_string) $(Platform_INCLUDED_SOURCE_FILE_NAMES_sys)
+Platform_INCLUDED_SOURCE_FILE_NAMES_iphoneos = $(Platform_INCLUDED_SOURCE_FILE_NAMES_gen) $(Platform_INCLUDED_SOURCE_FILE_NAMES_stdlib) $(Platform_INCLUDED_SOURCE_FILE_NAMES_string) $(Platform_INCLUDED_SOURCE_FILE_NAMES_sys)
+Platform_INCLUDED_SOURCE_FILE_NAMES_iphonesimulator = $(Platform_INCLUDED_SOURCE_FILE_NAMES_gen) $(Platform_INCLUDED_SOURCE_FILE_NAMES_stdlib) $(Platform_INCLUDED_SOURCE_FILE_NAMES_string)
+
+Platform_INCLUDED_SOURCE_FILE_NAMES_gen = $(ARCH_FAMILY)/gen/*.c $(ARCH_FAMILY)/gen/*.s $(ARCH_FAMILY)/gen/*.S
+Platform_INCLUDED_SOURCE_FILE_NAMES_stdlib = $(ARCH_FAMILY)/stdlib/*.c $(ARCH_FAMILY)/stdlib/*.s $(ARCH_FAMILY)/stdlib/*.S
+Platform_INCLUDED_SOURCE_FILE_NAMES_string = $(ARCH_FAMILY)/string/*.c $(ARCH_FAMILY)/string/*.s $(ARCH_FAMILY)/string/*.S
+Platform_INCLUDED_SOURCE_FILE_NAMES_sys = $(ARCH_FAMILY)/sys/*.c $(ARCH_FAMILY)/sys/*.s $(ARCH_FAMILY)/sys/*.S
+
// FreeBSD target
FreeBSD_CFLAGS = -include $(SRCROOT)/fbsdcompat/_fbsd_compat_.h
FreeBSD_SEARCH_PATHS = $(SRCROOT)/fbsdcompat $(SRCROOT)/gdtoa $(SRCROOT)/gdtoa/FreeBSD
FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7f = $(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7)
FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv6 = $(FreeBSD_INCLUDED_SOURCE_FILE_NAMES_armv7)
-// FreeBSD_gcc target
-FreeBSD_gcc_CFLAGS = -include $(SRCROOT)/fbsdcompat/_fbsd_compat_.h
-FreeBSD_gcc_SEARCH_PATHS = $(SRCROOT)/fbsdcompat $(SRCROOT)/gdtoa $(SRCROOT)/gdtoa/FreeBSD
-
// NetBSD target
NetBSD_CFLAGS = -include $(SRCROOT)/nbsdcompat/_nbsd_compat_.h
NetBSD_SEARCH_PATHS = $(SRCROOT)/nbsdcompat
// Files per architecture to exclude from the non-platform builds (because optimised versions exist in Platform)
BASE_EXCLUDED_SOURCE_FILE_NAMES = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_$(CURRENT_ARCH)) $(BASE_EXCLUDED_SOURCE_FILE_NAMES_$(PLATFORM_NAME))
-BASE_EXCLUDED_SOURCE_FILE_NAMES_x86_64 = MKGetTimeBaseInfo.c bcmp.c context-stubs.c kvm.c memcmp.c memset.c memset_pattern.c nlist.c strcpy.c strlcat.c strlcpy.c strlen.c strncmp.c strncpy.c
-BASE_EXCLUDED_SOURCE_FILE_NAMES_i386 = bcmp.c context-stubs.c memcmp.c memset.c memset_pattern.c strcpy.c strlcat.c strlcpy.c strlen.c strncmp.c strncpy.c
-BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7 = bcmp.c memcmp.c memset.c memset_pattern.c strchr.c strlen.c strncmp.c strnlen.c strstr.c
+BASE_EXCLUDED_SOURCE_FILE_NAMES_x86_64 = kvm.c nlist.c strcpy.c strlen.c strncpy.c strnlen.c
+BASE_EXCLUDED_SOURCE_FILE_NAMES_i386 = strcpy.c strlcat.c strlcpy.c strlen.c strncpy.c
+BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7 = strlen.c strnlen.c strstr.c
BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7s = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7)
BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7k = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7)
BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7f = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7)
BASE_EXCLUDED_SOURCE_FILE_NAMES_armv6 = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_armv7)
+// utmp/utmpx doesn't really fit in iOS, and this has some dependence on
+// libasl, so ignore it for now.
+BASE_EXCLUDED_SOURCE_FILE_NAMES_sim_utmpx = utmpx-darwin.c utmpx.c logwtmp.c
+
+// Others which at one point in time were tied too closely to the host.
+// It's probably a good idea to have only one set of functions accessing the
+// environment at a given time, but the rest may not need to be excluded
+// any more. This should be investigated.
+BASE_EXCLUDED_SOURCE_FILE_NAMES_sim_misc = thread_stack_pcs.c backtrace.c getenv.c putenv.c setenv.c stack_protector.c crt_externs.c gettimeofday.c
+
+BASE_EXCLUDED_SOURCE_FILE_NAMES_sim = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_sim_utmpx) $(BASE_EXCLUDED_SOURCE_FILE_NAMES_sim_misc)
+
// Rune support isn't included on iOS but there's no better way to exclude their complication
BASE_EXCLUDED_SOURCE_FILE_NAMES_macosx = OSMemoryNotification.c OSThermalNotification.c
BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos = frune.c login.c logout.c mbrune.c runedepreciated.c setinvalidrune.c getmntinfo64.c
-BASE_EXCLUDED_SOURCE_FILE_NAMES_iphonesimulator = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos)
+BASE_EXCLUDED_SOURCE_FILE_NAMES_iphonesimulator = $(BASE_EXCLUDED_SOURCE_FILE_NAMES_sim) $(BASE_EXCLUDED_SOURCE_FILE_NAMES_iphoneos)
// <rdar://problem/9513665> - collate.c crashes llvm-gcc on armv6 with -Os + -gdwarf-2
COLLATE_C_CFLAGS_macosx_armv6 = -O1
// ARMv6 thumb doesn't support all the instructions needed for OSAtomics
OSATOMIC_C_CFLAGS_macosx_armv6 = -mno-thumb
OSATOMIC_C_CFLAGS_iphoneos_armv6 = -mno-thumb
+
+// Make sure that OSAtomic isn't build unoptimised, otherwise the inlines
+// don't do what they are designed to do.
+OSATOMIC_C_CFLAGS = -Os -momit-leaf-frame-pointer $(OSATOMIC_C_CFLAGS_$(PLATFORM_NAME)_$(CURRENT_ARCH))
${FILES}
EOF
)
+
+ # This is a subshell, the real exit is after the loop.
+ if [ -z "${SOURCE}" ]; then
+ echo "Error: ${first} not found"
+ exit 1
+ fi
+
SECTION=$(echo ${first} | tail -c 2)
DESTDIR=${DSTROOT}/usr/share/man/man${SECTION}
done
done
+if [ $? -ne 0 ]; then
+ echo "Exiting due to previous error(s)."
+ exit 1
+fi
+
# grrr, uuid special case
for page in libuuid.3 uuid_clear.3 uuid_compare.3 uuid_copy.3 uuid_generate.3 uuid_is_null.3 uuid_parse.3 uuid_unparse.3; do
SECTION=$(echo ${page} | tail -c 2)
+++ /dev/null
-#!/bin/bash -e
-
-export MIG=`xcrun -find mig`
-export MIGCC=`xcrun -find cc`
-
-BASE=`basename ${SCRIPT_INPUT_FILE_0} .defs`.h
-
-for a in ${ARCHS}; do
- mkdir -p "${DERIVED_FILE_DIR}/${a}"
- "${MIG}" -arch $a -header "${DERIVED_FILE_DIR}/${a}/${BASE}" \
- -sheader /dev/null -user /dev/null \
- -server /dev/null "${SCRIPT_INPUT_FILE_0}"
-done
VARIANT_CANCELABLE_MACROS = -DVARIANT_CANCELABLE
-VARIANT_CANCELABLE_INCLUDE = $(VARIANT_CANCELABLE_INCLUDE_compat) $(VARIANT_CANCELABLE_INCLUDE_gen) $(VARIANT_CANCELABLE_INCLUDE_net) $(VARIANT_CANCELABLE_INCLUDE_pthreads) $(VARIANT_CANCELABLE_INCLUDE_sys)
+VARIANT_CANCELABLE_INCLUDE = $(VARIANT_CANCELABLE_INCLUDE_$(PLATFORM_NAME))
+VARIANT_CANCELABLE_INCLUDE_macosx = $(VARIANT_CANCELABLE_INCLUDE_compat) $(VARIANT_CANCELABLE_INCLUDE_gen) $(VARIANT_CANCELABLE_INCLUDE_net) $(VARIANT_CANCELABLE_INCLUDE_sys)
+VARIANT_CANCELABLE_INCLUDE_iphoneos = $(VARIANT_CANCELABLE_INCLUDE_compat) $(VARIANT_CANCELABLE_INCLUDE_gen) $(VARIANT_CANCELABLE_INCLUDE_net) $(VARIANT_CANCELABLE_INCLUDE_sys)
+VARIANT_CANCELABLE_INCLUDE_iphonesimulator = $(VARIANT_CANCELABLE_INCLUDE_compat) $(VARIANT_CANCELABLE_INCLUDE_gen) $(VARIANT_CANCELABLE_INCLUDE_net) $(VARIANT_CANCELABLE_INCLUDE_sys)
VARIANT_CANCELABLE_INCLUDE_compat = creat.c sigcompat.c
VARIANT_CANCELABLE_INCLUDE_gen = lockf.c nanosleep.c pause.c pselect.c sleep.c termios.c usleep.c wait.c waitpid.c
VARIANT_CANCELABLE_INCLUDE_net = recv.c send.c
-VARIANT_CANCELABLE_INCLUDE_pthreads = pthread_cancelable.c
VARIANT_CANCELABLE_INCLUDE_sys = system.c
// $DARWINEXTSN
// Legacy symbols
VARIANT_LEGACY_MACROS = -U__DARWIN_UNIX03 -D__DARWIN_UNIX03=0 -U__DARWIN_64_BIT_INO_T -D__DARWIN_64_BIT_INO_T=0 -DVARIANT_LEGACY
-VARIANT_LEGACY_INCLUDE = $(VARIANT_LEGACY_INCLUDE_$(CURRENT_ARCH))
-VARIANT_LEGACY_INCLUDE_i386 = $(VARIANT_LEGACY_INCLUDE_compat) $(VARIANT_LEGACY_INCLUDE_gdtoa) $(VARIANT_LEGACY_INCLUDE_gen) $(VARIANT_LEGACY_INCLUDE_locale) $(VARIANT_LEGACY_INCLUDE_net) $(VARIANT_LEGACY_INCLUDE_pthreads) $(VARIANT_LEGACY_INCLUDE_regex) $(VARIANT_LEGACY_INCLUDE_stdio) $(VARIANT_LEGACY_INCLUDE_stdlib) $(VARIANT_LEGACY_INCLUDE_stdtime) $(VARIANT_LEGACY_INCLUDE_string) $(VARIANT_LEGACY_INCLUDE_sys)
+VARIANT_LEGACY_INCLUDE = $(VARIANT_LEGACY_INCLUDE_$(PLATFORM_NAME))
+VARIANT_LEGACY_INCLUDE_macosx = $(VARIANT_LEGACY_INCLUDE_$(PLATFORM_NAME)_$(CURRENT_ARCH))
+VARIANT_LEGACY_INCLUDE_macosx_i386 = $(VARIANT_LEGACY_INCLUDE_compat) $(VARIANT_LEGACY_INCLUDE_gdtoa) $(VARIANT_LEGACY_INCLUDE_gen) $(VARIANT_LEGACY_INCLUDE_locale) $(VARIANT_LEGACY_INCLUDE_net) $(VARIANT_LEGACY_INCLUDE_regex) $(VARIANT_LEGACY_INCLUDE_stdio) $(VARIANT_LEGACY_INCLUDE_stdlib) $(VARIANT_LEGACY_INCLUDE_stdtime) $(VARIANT_LEGACY_INCLUDE_string) $(VARIANT_LEGACY_INCLUDE_sys)
VARIANT_LEGACY_INCLUDE_compat = creat.c setregid.c setreuid.c sigcompat.c killpg.c
VARIANT_LEGACY_INCLUDE_gdtoa = gdtoa-strtof.c gdtoa-strtod.c gdtoa-strtodg.c
VARIANT_LEGACY_INCLUDE_gen = clock.c closedir.c confstr.c crypt.c fnmatch.c lockf.c nanosleep.c nftw.c nice.c opendir.c pause.c popen.c pselect.c rewinddir.c seekdir.c setmode.c sleep.c telldir.c termios.c timezone.c ttyname.c usleep.c wait.c waitpid.c
VARIANT_LEGACY_INCLUDE_locale = wcsftime.c
VARIANT_LEGACY_INCLUDE_net = recv.c send.c
-VARIANT_LEGACY_INCLUDE_pthreads = pthread.c pthread_cancelable.c pthread_cond.c pthread_mutex.c pthread_rwlock.c
VARIANT_LEGACY_INCLUDE_regex = regcomp.c
VARIANT_LEGACY_INCLUDE_stdio = fdopen.c fopen.c fputs.c freopen.c fwrite.c tempnam.c
VARIANT_LEGACY_INCLUDE_stdlib = getopt.c putenv.c realpath.c setenv.c system.c
VARIANT_INODE32_MACROS = -U__DARWIN_64_BIT_INO_T -D__DARWIN_64_BIT_INO_T=0 -DVARIANT_INODE32
-VARIANT_INODE32_INCLUDE = $(VARIANT_INODE32_INCLUDE_$(CURRENT_ARCH))
-VARIANT_INODE32_INCLUDE_i386 = $(VARIANT_INODE32_INCLUDE_gen) $(VARIANT_INODE32_INCLUDE_sys)
-VARIANT_INODE32_INCLUDE_x86_64 = $(VARIANT_INODE32_INCLUDE_gen) $(VARIANT_INODE32_INCLUDE_sys)
+VARIANT_INODE32_INCLUDE = $(VARIANT_INODE32_INCLUDE_$(PLATFORM_NAME))
+VARIANT_INODE32_INCLUDE_macosx = $(VARIANT_INODE32_INCLUDE_$(PLATFORM_NAME)_$(CURRENT_ARCH))
+VARIANT_INODE32_INCLUDE_macosx_i386 = $(VARIANT_INODE32_INCLUDE_gen) $(VARIANT_INODE32_INCLUDE_sys)
+VARIANT_INODE32_INCLUDE_macosx_x86_64 = $(VARIANT_INODE32_INCLUDE_gen) $(VARIANT_INODE32_INCLUDE_sys)
VARIANT_INODE32_INCLUDE_gen = fts.c getmntinfo.c glob.c nftw.c opendir.c readdir.c rewinddir.c scandir.c seekdir.c telldir.c scandir_b.c
VARIANT_INODE32_INCLUDE_sys = statx_np.c
VARIANT_DYLD_INCLUDE = $(VARIANT_DYLD_INCLUDE_generic) $(VARIANT_DYLD_INCLUDE_$(CURRENT_ARCH))
-VARIANT_DYLD_INCLUDE_generic = $(VARIANT_DYLD_INCLUDE_gen) $(VARIANT_DYLD_INCLUDE_pthreads) $(VARIANT_DYLD_INCLUDE_stdlib) $(VARIANT_DYLD_INCLUDE_string) $(VARIANT_DYLD_INCLUDE_sys) $(VARIANT_DYLD_INCLUDE_threads)
-VARIANT_DYLD_INCLUDE_gen = _simple.c arc4random.c closedir.c dirfd.c getcwd.c getpagesize.c nanosleep.c opendir.c readdir.c scandir.c sysctl.c sysctlbyname.c telldir.c usleep.c
-VARIANT_DYLD_INCLUDE_pthreads = pthread.c pthread_mutex.c pthread_tsd.c
+VARIANT_DYLD_INCLUDE_generic = $(VARIANT_DYLD_INCLUDE_gen) $(VARIANT_DYLD_INCLUDE_stdlib) $(VARIANT_DYLD_INCLUDE_string) $(VARIANT_DYLD_INCLUDE_sys)
+VARIANT_DYLD_INCLUDE_gen = arc4random.c closedir.c dirfd.c getcwd.c getpagesize.c nanosleep.c opendir.c readdir.c scandir.c sysctl.c sysctlbyname.c telldir.c usleep.c
VARIANT_DYLD_INCLUDE_stdlib = atexit.c exit.c gettimeofday.c heapsort.c merge.c qsort.c reallocf.c realpath.c
-VARIANT_DYLD_INCLUDE_string = strcat.c strchr.c strcpy.c strdup.c strlcat.c strlcpy.c strncmp.c strnlen.c strrchr.c strstr.c
-VARIANT_DYLD_INCLUDE_sys = errno.c
-VARIANT_DYLD_INCLUDE_threads = mig_support.c
+VARIANT_DYLD_INCLUDE_string = bcopy.c libplatform.s strcat.c strchr.c strcpy.c strdup.c strlcat.c strlcpy.c strncmp.c strnlen.c strrchr.c strstr.c
+VARIANT_DYLD_INCLUDE_sys = __libc_init.c
-VARIANT_DYLD_INCLUDE_x86_64 = x86_64/pthreads/pthread_set_self.s x86_64/pthreads/pthread_self.s x86_64/pthreads/pthread_getspecific.s x86_64/pthreads/preempt.s x86_64/string/__bzero.s x86_64/string/bcopy_sse3x.s x86_64/string/bzero_sse2.s x86_64/string/ffs.s x86_64/string/longcopy_sse3x.s x86_64/string/strcmp.s x86_64/string/strlen.s x86_64/string/strncpy.s x86_64/sys/OSAtomic.s x86_64/sys/i386_gettimeofday_asm.s x86_64/sys/spinlocks_asm.s x86_64/sys/nanotime.s
-
-VARIANT_DYLD_INCLUDE_i386 = i386/gen/icacheinval.s i386/gen/cpu_number.s i386/pthreads/preempt.s i386/pthreads/pthread_set_self.s i386/pthreads/pthread_self.s i386/pthreads/pthread_getspecific.s i386/string/__bzero.s i386/string/bcopy_scalar.s i386/string/bzero_scalar.s i386/string/ffs.s i386/string/memcmp.s i386/string/memset_pattern_sse2.s i386/string/strcmp.s i386/string/strlen.s i386/string/strncpy.s i386/sys/OSAtomic.s i386/sys/i386_gettimeofday_asm.s i386/sys/mach_absolute_time_asm.s i386/sys/spinlocks_asm.s
-
-VARIANT_DYLD_INCLUDE_armv7 = arm/gen/icacheinval.s arm/pthreads/pthread_getspecific.s arm/pthreads/pthread_self.s arm/pthreads/pthread_set_self.s arm/string/bcopy_Generic.s arm/string/bzero_Generic.s arm/string/ffs.s arm/string/strcmp.s arm/string/strlen.s arm/string/strnlen.s strncpy.c arm/sys/OSAtomic.c arm/sys/OSAtomicUP.c arm/sys/OSAtomic_resolvers.c arm/sys/Spinlocks.c arm/sys/SpinlocksUP.c arm/sys/SpinlocksWFE.c arm/sys/arm_commpage_gettimeofday.c arm/sys/mach_absolute_time.s
+VARIANT_DYLD_INCLUDE_x86_64 = x86_64/string/strcpy.s x86_64/string/strlen.s x86_64/string/strncpy.s x86_64/string/strnlen.s strstr.c
+VARIANT_DYLD_INCLUDE_i386 = i386/string/strcpy.s i386/string/strlen.s i386/string/strncpy.s strnlen.c strstr.c
+VARIANT_DYLD_INCLUDE_armv7 = strcpy.c arm/string/strlen.s strncpy.c arm/string/strnlen.s arm/string/strstr.s
VARIANT_DYLD_INCLUDE_armv7s = $(VARIANT_DYLD_INCLUDE_armv7)
VARIANT_DYLD_INCLUDE_armv7k = $(VARIANT_DYLD_INCLUDE_armv7)
VARIANT_DYLD_INCLUDE_armv7f = $(VARIANT_DYLD_INCLUDE_armv7)
-VARIANT_DYLD_INCLUDE_armv6 = $(VARIANT_DYLD_INCLUDE_armv7) arm/sys/OSAtomic-v4.c
-