branch-updates.diff 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680
  1. diff --git a/arch/arm/syscall_arch.h b/arch/arm/syscall_arch.h
  2. index a877b2cf..624e992e 100644
  3. --- a/arch/arm/syscall_arch.h
  4. +++ b/arch/arm/syscall_arch.h
  5. @@ -101,3 +101,10 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
  6. #define SYSCALL_FADVISE_6_ARG
  7. #define SYSCALL_IPC_BROKEN_MODE
  8. +
  9. +#define VDSO_USEFUL
  10. +#define VDSO_CGT32_SYM "__vdso_clock_gettime"
  11. +#define VDSO_CGT32_VER "LINUX_2.6"
  12. +#define VDSO_CGT_SYM "__vdso_clock_gettime64"
  13. +#define VDSO_CGT_VER "LINUX_2.6"
  14. +#define VDSO_CGT_WORKAROUND 1
  15. diff --git a/compat/time32/__xstat.c b/compat/time32/__xstat.c
  16. index acfbd3cc..e52b5deb 100644
  17. --- a/compat/time32/__xstat.c
  18. +++ b/compat/time32/__xstat.c
  19. @@ -3,22 +3,22 @@
  20. struct stat32;
  21. -int __fxstat64(int ver, int fd, struct stat32 *buf)
  22. +int __fxstat(int ver, int fd, struct stat32 *buf)
  23. {
  24. return __fstat_time32(fd, buf);
  25. }
  26. -int __fxstatat64(int ver, int fd, const char *path, struct stat32 *buf, int flag)
  27. +int __fxstatat(int ver, int fd, const char *path, struct stat32 *buf, int flag)
  28. {
  29. return __fstatat_time32(fd, path, buf, flag);
  30. }
  31. -int __lxstat64(int ver, const char *path, struct stat32 *buf)
  32. +int __lxstat(int ver, const char *path, struct stat32 *buf)
  33. {
  34. return __lstat_time32(path, buf);
  35. }
  36. -int __xstat64(int ver, const char *path, struct stat32 *buf)
  37. +int __xstat(int ver, const char *path, struct stat32 *buf)
  38. {
  39. return __stat_time32(path, buf);
  40. }
  41. diff --git a/compat/time32/aio_suspend_time32.c b/compat/time32/aio_suspend_time32.c
  42. index ed5119bd..d99cb651 100644
  43. --- a/compat/time32/aio_suspend_time32.c
  44. +++ b/compat/time32/aio_suspend_time32.c
  45. @@ -7,5 +7,3 @@ int __aio_suspend_time32(const struct aiocb *const cbs[], int cnt, const struct
  46. return aio_suspend(cbs, cnt, ts32 ? (&(struct timespec){
  47. .tv_sec = ts32->tv_sec, .tv_nsec = ts32->tv_nsec}) : 0);
  48. }
  49. -
  50. -weak_alias(aio_suspend, aio_suspend64);
  51. diff --git a/compat/time32/fstat_time32.c b/compat/time32/fstat_time32.c
  52. index 3e084398..e5d52022 100644
  53. --- a/compat/time32/fstat_time32.c
  54. +++ b/compat/time32/fstat_time32.c
  55. @@ -13,5 +13,3 @@ int __fstat_time32(int fd, struct stat32 *restrict st32)
  56. if (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));
  57. return r;
  58. }
  59. -
  60. -weak_alias(fstat, fstat64);
  61. diff --git a/compat/time32/fstatat_time32.c b/compat/time32/fstatat_time32.c
  62. index 85dcb008..31d42e63 100644
  63. --- a/compat/time32/fstatat_time32.c
  64. +++ b/compat/time32/fstatat_time32.c
  65. @@ -13,5 +13,3 @@ int __fstatat_time32(int fd, const char *restrict path, struct stat32 *restrict
  66. if (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));
  67. return r;
  68. }
  69. -
  70. -weak_alias(fstatat, fstatat64);
  71. diff --git a/compat/time32/lstat_time32.c b/compat/time32/lstat_time32.c
  72. index c1257a14..28cb5a0b 100644
  73. --- a/compat/time32/lstat_time32.c
  74. +++ b/compat/time32/lstat_time32.c
  75. @@ -13,5 +13,3 @@ int __lstat_time32(const char *restrict path, struct stat32 *restrict st32)
  76. if (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));
  77. return r;
  78. }
  79. -
  80. -weak_alias(lstat, lstat64);
  81. diff --git a/compat/time32/stat_time32.c b/compat/time32/stat_time32.c
  82. index 8c6121da..b154b0f9 100644
  83. --- a/compat/time32/stat_time32.c
  84. +++ b/compat/time32/stat_time32.c
  85. @@ -13,5 +13,3 @@ int __stat_time32(const char *restrict path, struct stat32 *restrict st32)
  86. if (!r) memcpy(st32, &st, offsetof(struct stat, st_atim));
  87. return r;
  88. }
  89. -
  90. -weak_alias(stat, stat64);
  91. diff --git a/configure b/configure
  92. index ca5cbc0b..853bf05e 100755
  93. --- a/configure
  94. +++ b/configure
  95. @@ -353,6 +353,14 @@ tryflag CFLAGS_C99FSE -fexcess-precision=standard \
  96. || { test "$ARCH" = i386 && tryflag CFLAGS_C99FSE -ffloat-store ; }
  97. tryflag CFLAGS_C99FSE -frounding-math
  98. +#
  99. +# Semantically we want to insist that our sources follow the
  100. +# C rules for type-based aliasing, but most if not all real-world
  101. +# compilers are known or suspected to have critical bugs in their
  102. +# type-based aliasing analysis. See for example GCC bug 107107.
  103. +#
  104. +tryflag CFLAGS_C99FSE -fno-strict-aliasing
  105. +
  106. #
  107. # We may use the may_alias attribute if __GNUC__ is defined, so
  108. # if the compiler defines __GNUC__ but does not provide it,
  109. @@ -723,11 +731,6 @@ fi
  110. test "$SUBARCH" \
  111. && printf "configured for %s variant: %s\n" "$ARCH" "$ARCH$SUBARCH"
  112. -case "$ARCH$SUBARCH" in
  113. -arm) ASMSUBARCH=el ;;
  114. -*) ASMSUBARCH=$SUBARCH ;;
  115. -esac
  116. -
  117. #
  118. # Some archs (powerpc) have different possible long double formats
  119. # that the compiler can be configured for. The logic for whether this
  120. diff --git a/include/aio.h b/include/aio.h
  121. index 453c41b7..a938fcad 100644
  122. --- a/include/aio.h
  123. +++ b/include/aio.h
  124. @@ -49,7 +49,7 @@ int aio_fsync(int, struct aiocb *);
  125. int lio_listio(int, struct aiocb *__restrict const *__restrict, int, struct sigevent *__restrict);
  126. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  127. +#if defined(_LARGEFILE64_SOURCE)
  128. #define aiocb64 aiocb
  129. #define aio_read64 aio_read
  130. #define aio_write64 aio_write
  131. diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h
  132. index 581925a4..9c1327a1 100644
  133. --- a/include/arpa/nameser.h
  134. +++ b/include/arpa/nameser.h
  135. @@ -188,6 +188,36 @@ typedef enum __ns_type {
  136. ns_t_sink = 40,
  137. ns_t_opt = 41,
  138. ns_t_apl = 42,
  139. + ns_t_ds = 43,
  140. + ns_t_sshfp = 44,
  141. + ns_t_ipseckey = 45,
  142. + ns_t_rrsig = 46,
  143. + ns_t_nsec = 47,
  144. + ns_t_dnskey = 48,
  145. + ns_t_dhcid = 49,
  146. + ns_t_nsec3 = 50,
  147. + ns_t_nsec3param = 51,
  148. + ns_t_tlsa = 52,
  149. + ns_t_smimea = 53,
  150. + ns_t_hip = 55,
  151. + ns_t_ninfo = 56,
  152. + ns_t_rkey = 57,
  153. + ns_t_talink = 58,
  154. + ns_t_cds = 59,
  155. + ns_t_cdnskey = 60,
  156. + ns_t_openpgpkey = 61,
  157. + ns_t_csync = 62,
  158. + ns_t_spf = 99,
  159. + ns_t_uinfo = 100,
  160. + ns_t_uid = 101,
  161. + ns_t_gid = 102,
  162. + ns_t_unspec = 103,
  163. + ns_t_nid = 104,
  164. + ns_t_l32 = 105,
  165. + ns_t_l64 = 106,
  166. + ns_t_lp = 107,
  167. + ns_t_eui48 = 108,
  168. + ns_t_eui64 = 109,
  169. ns_t_tkey = 249,
  170. ns_t_tsig = 250,
  171. ns_t_ixfr = 251,
  172. @@ -196,6 +226,11 @@ typedef enum __ns_type {
  173. ns_t_maila = 254,
  174. ns_t_any = 255,
  175. ns_t_zxfr = 256,
  176. + ns_t_uri = 256,
  177. + ns_t_caa = 257,
  178. + ns_t_avc = 258,
  179. + ns_t_ta = 32768,
  180. + ns_t_dlv = 32769,
  181. ns_t_max = 65536
  182. } ns_type;
  183. @@ -430,12 +465,48 @@ typedef struct {
  184. #define T_NAPTR ns_t_naptr
  185. #define T_A6 ns_t_a6
  186. #define T_DNAME ns_t_dname
  187. +#define T_DS ns_t_ds
  188. +#define T_SSHFP ns_t_sshfp
  189. +#define T_IPSECKEY ns_t_ipseckey
  190. +#define T_RRSIG ns_t_rrsig
  191. +#define T_NSEC ns_t_nsec
  192. +#define T_DNSKEY ns_t_dnskey
  193. +#define T_DHCID ns_t_dhcid
  194. +#define T_NSEC3 ns_t_nsec3
  195. +#define T_NSEC3PARAM ns_t_nsec3param
  196. +#define T_TLSA ns_t_tlsa
  197. +#define T_SMIMEA ns_t_smimea
  198. +#define T_HIP ns_t_hip
  199. +#define T_NINFO ns_t_ninfo
  200. +#define T_RKEY ns_t_rkey
  201. +#define T_TALINK ns_t_talink
  202. +#define T_CDS ns_t_cds
  203. +#define T_CDNSKEY ns_t_cdnskey
  204. +#define T_OPENPGPKEY ns_t_openpgpkey
  205. +#define T_CSYNC ns_t_csync
  206. +#define T_SPF ns_t_spf
  207. +#define T_UINFO ns_t_uinfo
  208. +#define T_UID ns_t_uid
  209. +#define T_GID ns_t_gid
  210. +#define T_UNSPEC ns_t_unspec
  211. +#define T_NID ns_t_nid
  212. +#define T_L32 ns_t_l32
  213. +#define T_L64 ns_t_l64
  214. +#define T_LP ns_t_lp
  215. +#define T_EUI48 ns_t_eui48
  216. +#define T_EUI64 ns_t_eui64
  217. +#define T_TKEY ns_t_tkey
  218. #define T_TSIG ns_t_tsig
  219. #define T_IXFR ns_t_ixfr
  220. #define T_AXFR ns_t_axfr
  221. #define T_MAILB ns_t_mailb
  222. #define T_MAILA ns_t_maila
  223. #define T_ANY ns_t_any
  224. +#define T_URI ns_t_uri
  225. +#define T_CAA ns_t_caa
  226. +#define T_AVC ns_t_avc
  227. +#define T_TA ns_t_ta
  228. +#define T_DLV ns_t_dlv
  229. #define C_IN ns_c_in
  230. #define C_CHAOS ns_c_chaos
  231. diff --git a/include/dirent.h b/include/dirent.h
  232. index 650ecf64..2d8fffb2 100644
  233. --- a/include/dirent.h
  234. +++ b/include/dirent.h
  235. @@ -56,7 +56,7 @@ int getdents(int, struct dirent *, size_t);
  236. int versionsort(const struct dirent **, const struct dirent **);
  237. #endif
  238. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  239. +#if defined(_LARGEFILE64_SOURCE)
  240. #define dirent64 dirent
  241. #define readdir64 readdir
  242. #define readdir64_r readdir_r
  243. diff --git a/include/elf.h b/include/elf.h
  244. index 86e2f0bb..9e980a29 100644
  245. --- a/include/elf.h
  246. +++ b/include/elf.h
  247. @@ -385,7 +385,8 @@ typedef struct {
  248. #define SHT_PREINIT_ARRAY 16
  249. #define SHT_GROUP 17
  250. #define SHT_SYMTAB_SHNDX 18
  251. -#define SHT_NUM 19
  252. +#define SHT_RELR 19
  253. +#define SHT_NUM 20
  254. #define SHT_LOOS 0x60000000
  255. #define SHT_GNU_ATTRIBUTES 0x6ffffff5
  256. #define SHT_GNU_HASH 0x6ffffff6
  257. @@ -754,7 +755,10 @@ typedef struct {
  258. #define DT_PREINIT_ARRAY 32
  259. #define DT_PREINIT_ARRAYSZ 33
  260. #define DT_SYMTAB_SHNDX 34
  261. -#define DT_NUM 35
  262. +#define DT_RELRSZ 35
  263. +#define DT_RELR 36
  264. +#define DT_RELRENT 37
  265. +#define DT_NUM 38
  266. #define DT_LOOS 0x6000000d
  267. #define DT_HIOS 0x6ffff000
  268. #define DT_LOPROC 0x70000000
  269. diff --git a/include/fcntl.h b/include/fcntl.h
  270. index b664cdc4..515f255d 100644
  271. --- a/include/fcntl.h
  272. +++ b/include/fcntl.h
  273. @@ -195,7 +195,7 @@ ssize_t tee(int, int, size_t, unsigned);
  274. #define loff_t off_t
  275. #endif
  276. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  277. +#if defined(_LARGEFILE64_SOURCE)
  278. #define F_GETLK64 F_GETLK
  279. #define F_SETLK64 F_SETLK
  280. #define F_SETLKW64 F_SETLKW
  281. diff --git a/include/ftw.h b/include/ftw.h
  282. index b15c062a..d0445e8a 100644
  283. --- a/include/ftw.h
  284. +++ b/include/ftw.h
  285. @@ -29,7 +29,7 @@ struct FTW {
  286. int ftw(const char *, int (*)(const char *, const struct stat *, int), int);
  287. int nftw(const char *, int (*)(const char *, const struct stat *, int, struct FTW *), int, int);
  288. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  289. +#if defined(_LARGEFILE64_SOURCE)
  290. #define ftw64 ftw
  291. #define nftw64 nftw
  292. #endif
  293. diff --git a/include/glob.h b/include/glob.h
  294. index 4a562a20..fed06745 100644
  295. --- a/include/glob.h
  296. +++ b/include/glob.h
  297. @@ -39,7 +39,7 @@ void globfree(glob_t *);
  298. #define GLOB_NOMATCH 3
  299. #define GLOB_NOSYS 4
  300. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  301. +#if defined(_LARGEFILE64_SOURCE)
  302. #define glob64 glob
  303. #define globfree64 globfree
  304. #define glob64_t glob_t
  305. diff --git a/include/netdb.h b/include/netdb.h
  306. index d096c781..3af065e2 100644
  307. --- a/include/netdb.h
  308. +++ b/include/netdb.h
  309. @@ -44,6 +44,7 @@ struct addrinfo {
  310. #define EAI_NONAME -2
  311. #define EAI_AGAIN -3
  312. #define EAI_FAIL -4
  313. +#define EAI_NODATA -5
  314. #define EAI_FAMILY -6
  315. #define EAI_SOCKTYPE -7
  316. #define EAI_SERVICE -8
  317. diff --git a/include/stdio.h b/include/stdio.h
  318. index d1ed01f0..cb858618 100644
  319. --- a/include/stdio.h
  320. +++ b/include/stdio.h
  321. @@ -205,7 +205,7 @@ typedef struct _IO_cookie_io_functions_t {
  322. FILE *fopencookie(void *, const char *, cookie_io_functions_t);
  323. #endif
  324. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  325. +#if defined(_LARGEFILE64_SOURCE)
  326. #define tmpfile64 tmpfile
  327. #define fopen64 fopen
  328. #define freopen64 freopen
  329. diff --git a/include/stdlib.h b/include/stdlib.h
  330. index b507ca33..b117a452 100644
  331. --- a/include/stdlib.h
  332. +++ b/include/stdlib.h
  333. @@ -163,7 +163,7 @@ double strtod_l(const char *__restrict, char **__restrict, struct __locale_struc
  334. long double strtold_l(const char *__restrict, char **__restrict, struct __locale_struct *);
  335. #endif
  336. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  337. +#if defined(_LARGEFILE64_SOURCE)
  338. #define mkstemp64 mkstemp
  339. #define mkostemp64 mkostemp
  340. #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
  341. diff --git a/include/strings.h b/include/strings.h
  342. index db0960b4..b7a5ea08 100644
  343. --- a/include/strings.h
  344. +++ b/include/strings.h
  345. @@ -5,6 +5,7 @@
  346. extern "C" {
  347. #endif
  348. +#include <features.h>
  349. #define __NEED_size_t
  350. #define __NEED_locale_t
  351. diff --git a/include/sys/mman.h b/include/sys/mman.h
  352. index 80a3baae..3d5d0f9c 100644
  353. --- a/include/sys/mman.h
  354. +++ b/include/sys/mman.h
  355. @@ -141,7 +141,7 @@ int mincore (void *, size_t, unsigned char *);
  356. int shm_open (const char *, int, mode_t);
  357. int shm_unlink (const char *);
  358. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  359. +#if defined(_LARGEFILE64_SOURCE)
  360. #define mmap64 mmap
  361. #define off64_t off_t
  362. #endif
  363. diff --git a/include/sys/resource.h b/include/sys/resource.h
  364. index 3068328d..e8bfbe1f 100644
  365. --- a/include/sys/resource.h
  366. +++ b/include/sys/resource.h
  367. @@ -95,7 +95,7 @@ int prlimit(pid_t, int, const struct rlimit *, struct rlimit *);
  368. #define RLIM_NLIMITS RLIMIT_NLIMITS
  369. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  370. +#if defined(_LARGEFILE64_SOURCE)
  371. #define RLIM64_INFINITY RLIM_INFINITY
  372. #define RLIM64_SAVED_CUR RLIM_SAVED_CUR
  373. #define RLIM64_SAVED_MAX RLIM_SAVED_MAX
  374. diff --git a/include/sys/sendfile.h b/include/sys/sendfile.h
  375. index e7570d8e..253a041b 100644
  376. --- a/include/sys/sendfile.h
  377. +++ b/include/sys/sendfile.h
  378. @@ -10,7 +10,7 @@ extern "C" {
  379. ssize_t sendfile(int, int, off_t *, size_t);
  380. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  381. +#if defined(_LARGEFILE64_SOURCE)
  382. #define sendfile64 sendfile
  383. #define off64_t off_t
  384. #endif
  385. diff --git a/include/sys/stat.h b/include/sys/stat.h
  386. index 10d446c4..e6d0049c 100644
  387. --- a/include/sys/stat.h
  388. +++ b/include/sys/stat.h
  389. @@ -98,7 +98,7 @@ int lchmod(const char *, mode_t);
  390. #define S_IEXEC S_IXUSR
  391. #endif
  392. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  393. +#if defined(_LARGEFILE64_SOURCE)
  394. #define stat64 stat
  395. #define fstat64 fstat
  396. #define lstat64 lstat
  397. diff --git a/include/sys/statfs.h b/include/sys/statfs.h
  398. index 6f4c6230..7a2e11cd 100644
  399. --- a/include/sys/statfs.h
  400. +++ b/include/sys/statfs.h
  401. @@ -18,7 +18,7 @@ typedef struct __fsid_t {
  402. int statfs (const char *, struct statfs *);
  403. int fstatfs (int, struct statfs *);
  404. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  405. +#if defined(_LARGEFILE64_SOURCE)
  406. #define statfs64 statfs
  407. #define fstatfs64 fstatfs
  408. #define fsblkcnt64_t fsblkcnt_t
  409. diff --git a/include/sys/statvfs.h b/include/sys/statvfs.h
  410. index 793490b6..57a6b806 100644
  411. --- a/include/sys/statvfs.h
  412. +++ b/include/sys/statvfs.h
  413. @@ -42,7 +42,7 @@ int fstatvfs (int, struct statvfs *);
  414. #define ST_NODIRATIME 2048
  415. #define ST_RELATIME 4096
  416. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  417. +#if defined(_LARGEFILE64_SOURCE)
  418. #define statvfs64 statvfs
  419. #define fstatvfs64 fstatvfs
  420. #define fsblkcnt64_t fsblkcnt_t
  421. diff --git a/include/sys/types.h b/include/sys/types.h
  422. index 0c35541d..3363374f 100644
  423. --- a/include/sys/types.h
  424. +++ b/include/sys/types.h
  425. @@ -71,7 +71,7 @@ typedef unsigned long long u_quad_t;
  426. #include <sys/select.h>
  427. #endif
  428. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  429. +#if defined(_LARGEFILE64_SOURCE)
  430. #define blkcnt64_t blkcnt_t
  431. #define fsblkcnt64_t fsblkcnt_t
  432. #define fsfilcnt64_t fsfilcnt_t
  433. diff --git a/include/sys/uio.h b/include/sys/uio.h
  434. index 00f73a2f..90e5939e 100644
  435. --- a/include/sys/uio.h
  436. +++ b/include/sys/uio.h
  437. @@ -29,7 +29,7 @@ ssize_t writev (int, const struct iovec *, int);
  438. #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
  439. ssize_t preadv (int, const struct iovec *, int, off_t);
  440. ssize_t pwritev (int, const struct iovec *, int, off_t);
  441. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  442. +#if defined(_LARGEFILE64_SOURCE)
  443. #define preadv64 preadv
  444. #define pwritev64 pwritev
  445. #define off64_t off_t
  446. diff --git a/include/unistd.h b/include/unistd.h
  447. index 212263a7..5bc7f798 100644
  448. --- a/include/unistd.h
  449. +++ b/include/unistd.h
  450. @@ -198,7 +198,7 @@ ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
  451. pid_t gettid(void);
  452. #endif
  453. -#if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  454. +#if defined(_LARGEFILE64_SOURCE)
  455. #define lseek64 lseek
  456. #define pread64 pread
  457. #define pwrite64 pwrite
  458. @@ -425,6 +425,8 @@ pid_t gettid(void);
  459. #define _SC_XOPEN_STREAMS 246
  460. #define _SC_THREAD_ROBUST_PRIO_INHERIT 247
  461. #define _SC_THREAD_ROBUST_PRIO_PROTECT 248
  462. +#define _SC_MINSIGSTKSZ 249
  463. +#define _SC_SIGSTKSZ 250
  464. #define _CS_PATH 0
  465. #define _CS_POSIX_V6_WIDTH_RESTRICTED_ENVS 1
  466. @@ -467,6 +469,8 @@ pid_t gettid(void);
  467. #define _CS_POSIX_V7_LPBIG_OFFBIG_LINTFLAGS 1147
  468. #define _CS_V6_ENV 1148
  469. #define _CS_V7_ENV 1149
  470. +#define _CS_POSIX_V7_THREADS_CFLAGS 1150
  471. +#define _CS_POSIX_V7_THREADS_LDFLAGS 1151
  472. #ifdef __cplusplus
  473. }
  474. diff --git a/ldso/dlstart.c b/ldso/dlstart.c
  475. index 20d50f2c..259f5e18 100644
  476. --- a/ldso/dlstart.c
  477. +++ b/ldso/dlstart.c
  478. @@ -140,6 +140,21 @@ hidden void _dlstart_c(size_t *sp, size_t *dynv)
  479. size_t *rel_addr = (void *)(base + rel[0]);
  480. *rel_addr = base + rel[2];
  481. }
  482. +
  483. + rel = (void *)(base+dyn[DT_RELR]);
  484. + rel_size = dyn[DT_RELRSZ];
  485. + size_t *relr_addr = 0;
  486. + for (; rel_size; rel++, rel_size-=sizeof(size_t)) {
  487. + if ((rel[0]&1) == 0) {
  488. + relr_addr = (void *)(base + rel[0]);
  489. + *relr_addr++ += base;
  490. + } else {
  491. + for (size_t i=0, bitmap=rel[0]; bitmap>>=1; i++)
  492. + if (bitmap&1)
  493. + relr_addr[i] += base;
  494. + relr_addr += 8*sizeof(size_t)-1;
  495. + }
  496. + }
  497. #endif
  498. stage2_func dls2;
  499. diff --git a/ldso/dynlink.c b/ldso/dynlink.c
  500. index 5b9c8be4..7b47b163 100644
  501. --- a/ldso/dynlink.c
  502. +++ b/ldso/dynlink.c
  503. @@ -29,7 +29,9 @@
  504. #define realloc __libc_realloc
  505. #define free __libc_free
  506. -static void error(const char *, ...);
  507. +static void error_impl(const char *, ...);
  508. +static void error_noop(const char *, ...);
  509. +static void (*error)(const char *, ...) = error_noop;
  510. #define MAXP2(a,b) (-(-(a)&-(b)))
  511. #define ALIGN(x,y) ((x)+(y)-1 & -(y))
  512. @@ -208,7 +210,8 @@ static void decode_vec(size_t *v, size_t *a, size_t cnt)
  513. size_t i;
  514. for (i=0; i<cnt; i++) a[i] = 0;
  515. for (; v[0]; v+=2) if (v[0]-1<cnt-1) {
  516. - a[0] |= 1UL<<v[0];
  517. + if (v[0] < 8*sizeof(long))
  518. + a[0] |= 1UL<<v[0];
  519. a[v[0]] = v[1];
  520. }
  521. }
  522. @@ -334,6 +337,39 @@ static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
  523. return find_sym2(dso, s, need_def, 0);
  524. }
  525. +static struct symdef get_lfs64(const char *name)
  526. +{
  527. + static const char *p, lfs64_list[] =
  528. + "aio_cancel\0aio_error\0aio_fsync\0aio_read\0aio_return\0"
  529. + "aio_suspend\0aio_write\0alphasort\0creat\0fallocate\0"
  530. + "fgetpos\0fopen\0freopen\0fseeko\0fsetpos\0fstat\0"
  531. + "fstatat\0fstatfs\0fstatvfs\0ftello\0ftruncate\0ftw\0"
  532. + "getdents\0getrlimit\0glob\0globfree\0lio_listio\0"
  533. + "lockf\0lseek\0lstat\0mkostemp\0mkostemps\0mkstemp\0"
  534. + "mkstemps\0mmap\0nftw\0open\0openat\0posix_fadvise\0"
  535. + "posix_fallocate\0pread\0preadv\0prlimit\0pwrite\0"
  536. + "pwritev\0readdir\0scandir\0sendfile\0setrlimit\0"
  537. + "stat\0statfs\0statvfs\0tmpfile\0truncate\0versionsort\0"
  538. + "__fxstat\0__fxstatat\0__lxstat\0__xstat\0";
  539. + size_t l;
  540. + char buf[16];
  541. + for (l=0; name[l]; l++) {
  542. + if (l >= sizeof buf) goto nomatch;
  543. + buf[l] = name[l];
  544. + }
  545. + if (!strcmp(name, "readdir64_r"))
  546. + return find_sym(&ldso, "readdir_r", 1);
  547. + if (l<2 || name[l-2]!='6' || name[l-1]!='4')
  548. + goto nomatch;
  549. + buf[l-=2] = 0;
  550. + for (p=lfs64_list; *p; p++) {
  551. + if (!strcmp(buf, p)) return find_sym(&ldso, buf, 1);
  552. + while (*p) p++;
  553. + }
  554. +nomatch:
  555. + return (struct symdef){ 0 };
  556. +}
  557. +
  558. static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride)
  559. {
  560. unsigned char *base = dso->base;
  561. @@ -387,6 +423,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
  562. def = (sym->st_info>>4) == STB_LOCAL
  563. ? (struct symdef){ .dso = dso, .sym = sym }
  564. : find_sym(ctx, name, type==REL_PLT);
  565. + if (!def.sym) def = get_lfs64(name);
  566. if (!def.sym && (sym->st_shndx != SHN_UNDEF
  567. || sym->st_info>>4 != STB_WEAK)) {
  568. if (dso->lazy && (type==REL_PLT || type==REL_GOT)) {
  569. @@ -513,6 +550,23 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri
  570. }
  571. }
  572. +static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size)
  573. +{
  574. + unsigned char *base = dso->base;
  575. + size_t *reloc_addr;
  576. + for (; relr_size; relr++, relr_size-=sizeof(size_t))
  577. + if ((relr[0]&1) == 0) {
  578. + reloc_addr = laddr(dso, relr[0]);
  579. + *reloc_addr++ += (size_t)base;
  580. + } else {
  581. + int i = 0;
  582. + for (size_t bitmap=relr[0]; (bitmap>>=1); i++)
  583. + if (bitmap&1)
  584. + reloc_addr[i] += (size_t)base;
  585. + reloc_addr += 8*sizeof(size_t)-1;
  586. + }
  587. +}
  588. +
  589. static void redo_lazy_relocs()
  590. {
  591. struct dso *p = lazy_head, *next;
  592. @@ -866,7 +920,7 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size)
  593. case ENOENT:
  594. case ENOTDIR:
  595. case EACCES:
  596. - break;
  597. + return 0;
  598. default:
  599. return -1;
  600. }
  601. @@ -1355,13 +1409,17 @@ static void reloc_all(struct dso *p)
  602. 2+(dyn[DT_PLTREL]==DT_RELA));
  603. do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2);
  604. do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3);
  605. -
  606. - if (head != &ldso && p->relro_start != p->relro_end &&
  607. - mprotect(laddr(p, p->relro_start), p->relro_end-p->relro_start, PROT_READ)
  608. - && errno != ENOSYS) {
  609. - error("Error relocating %s: RELRO protection failed: %m",
  610. - p->name);
  611. - if (runtime) longjmp(*rtld_fail, 1);
  612. + if (!DL_FDPIC)
  613. + do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]);
  614. +
  615. + if (head != &ldso && p->relro_start != p->relro_end) {
  616. + long ret = __syscall(SYS_mprotect, laddr(p, p->relro_start),
  617. + p->relro_end-p->relro_start, PROT_READ);
  618. + if (ret != 0 && ret != -ENOSYS) {
  619. + error("Error relocating %s: RELRO protection failed: %m",
  620. + p->name);
  621. + if (runtime) longjmp(*rtld_fail, 1);
  622. + }
  623. }
  624. p->relocated = 1;
  625. @@ -1756,6 +1814,9 @@ void __dls3(size_t *sp, size_t *auxv)
  626. env_preload = getenv("LD_PRELOAD");
  627. }
  628. + /* Activate error handler function */
  629. + error = error_impl;
  630. +
  631. /* If the main program was already loaded by the kernel,
  632. * AT_PHDR will point to some location other than the dynamic
  633. * linker's program headers. */
  634. @@ -2345,7 +2406,7 @@ int dl_iterate_phdr(int(*callback)(struct dl_phdr_info *info, size_t size, void
  635. return ret;
  636. }
  637. -static void error(const char *fmt, ...)
  638. +static void error_impl(const char *fmt, ...)
  639. {
  640. va_list ap;
  641. va_start(ap, fmt);
  642. @@ -2359,3 +2420,7 @@ static void error(const char *fmt, ...)
  643. __dl_vseterr(fmt, ap);
  644. va_end(ap);
  645. }
  646. +
  647. +static void error_noop(const char *fmt, ...)
  648. +{
  649. +}
  650. diff --git a/src/aio/aio.c b/src/aio/aio.c
  651. index a1a3e791..d7e063bf 100644
  652. --- a/src/aio/aio.c
  653. +++ b/src/aio/aio.c
  654. @@ -82,6 +82,8 @@ static size_t io_thread_stack_size;
  655. static struct aio_queue *__aio_get_queue(int fd, int need)
  656. {
  657. + sigset_t allmask, origmask;
  658. + int masked = 0;
  659. if (fd < 0) {
  660. errno = EBADF;
  661. return 0;
  662. @@ -93,6 +95,9 @@ static struct aio_queue *__aio_get_queue(int fd, int need)
  663. if ((!map || !map[a] || !map[a][b] || !map[a][b][c] || !(q=map[a][b][c][d])) && need) {
  664. pthread_rwlock_unlock(&maplock);
  665. if (fcntl(fd, F_GETFD) < 0) return 0;
  666. + sigfillset(&allmask);
  667. + masked = 1;
  668. + pthread_sigmask(SIG_BLOCK, &allmask, &origmask);
  669. pthread_rwlock_wrlock(&maplock);
  670. if (!io_thread_stack_size) {
  671. unsigned long val = __getauxval(AT_MINSIGSTKSZ);
  672. @@ -119,6 +124,7 @@ static struct aio_queue *__aio_get_queue(int fd, int need)
  673. if (q) pthread_mutex_lock(&q->lock);
  674. out:
  675. pthread_rwlock_unlock(&maplock);
  676. + if (masked) pthread_sigmask(SIG_SETMASK, &origmask, 0);
  677. return q;
  678. }
  679. @@ -401,18 +407,26 @@ void __aio_atfork(int who)
  680. if (who<0) {
  681. pthread_rwlock_rdlock(&maplock);
  682. return;
  683. + } else if (!who) {
  684. + pthread_rwlock_unlock(&maplock);
  685. + return;
  686. }
  687. - if (who>0 && map) for (int a=0; a<(-1U/2+1)>>24; a++)
  688. + aio_fd_cnt = 0;
  689. + if (pthread_rwlock_tryrdlock(&maplock)) {
  690. + /* Obtaining lock may fail if _Fork was called nor via
  691. + * fork. In this case, no further aio is possible from
  692. + * child and we can just null out map so __aio_close
  693. + * does not attempt to do anything. */
  694. + map = 0;
  695. + return;
  696. + }
  697. + if (map) for (int a=0; a<(-1U/2+1)>>24; a++)
  698. if (map[a]) for (int b=0; b<256; b++)
  699. if (map[a][b]) for (int c=0; c<256; c++)
  700. if (map[a][b][c]) for (int d=0; d<256; d++)
  701. map[a][b][c][d] = 0;
  702. - pthread_rwlock_unlock(&maplock);
  703. + /* Re-initialize the rwlock rather than unlocking since there
  704. + * may have been more than one reference on it in the parent.
  705. + * We are not a lock holder anyway; the thread in the parent was. */
  706. + pthread_rwlock_init(&maplock, 0);
  707. }
  708. -
  709. -weak_alias(aio_cancel, aio_cancel64);
  710. -weak_alias(aio_error, aio_error64);
  711. -weak_alias(aio_fsync, aio_fsync64);
  712. -weak_alias(aio_read, aio_read64);
  713. -weak_alias(aio_write, aio_write64);
  714. -weak_alias(aio_return, aio_return64);
  715. diff --git a/src/aio/aio_suspend.c b/src/aio/aio_suspend.c
  716. index 1c1060e3..1f0c9aaa 100644
  717. --- a/src/aio/aio_suspend.c
  718. +++ b/src/aio/aio_suspend.c
  719. @@ -9,7 +9,7 @@ int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec
  720. {
  721. int i, tid = 0, ret, expect = 0;
  722. struct timespec at;
  723. - volatile int dummy_fut, *pfut;
  724. + volatile int dummy_fut = 0, *pfut;
  725. int nzcnt = 0;
  726. const struct aiocb *cb = 0;
  727. @@ -73,7 +73,3 @@ int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec
  728. }
  729. }
  730. }
  731. -
  732. -#if !_REDIR_TIME64
  733. -weak_alias(aio_suspend, aio_suspend64);
  734. -#endif
  735. diff --git a/src/aio/lio_listio.c b/src/aio/lio_listio.c
  736. index 0799c15d..a672812f 100644
  737. --- a/src/aio/lio_listio.c
  738. +++ b/src/aio/lio_listio.c
  739. @@ -139,5 +139,3 @@ int lio_listio(int mode, struct aiocb *restrict const *restrict cbs, int cnt, st
  740. return 0;
  741. }
  742. -
  743. -weak_alias(lio_listio, lio_listio64);
  744. diff --git a/src/conf/confstr.c b/src/conf/confstr.c
  745. index 02cb1aa2..3d417284 100644
  746. --- a/src/conf/confstr.c
  747. +++ b/src/conf/confstr.c
  748. @@ -7,7 +7,7 @@ size_t confstr(int name, char *buf, size_t len)
  749. const char *s = "";
  750. if (!name) {
  751. s = "/bin:/usr/bin";
  752. - } else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>33U) {
  753. + } else if ((name&~4U)!=1 && name-_CS_POSIX_V6_ILP32_OFF32_CFLAGS>35U) {
  754. errno = EINVAL;
  755. return 0;
  756. }
  757. diff --git a/src/conf/sysconf.c b/src/conf/sysconf.c
  758. index 3baaed32..60d3e745 100644
  759. --- a/src/conf/sysconf.c
  760. +++ b/src/conf/sysconf.c
  761. @@ -4,6 +4,7 @@
  762. #include <sys/resource.h>
  763. #include <signal.h>
  764. #include <sys/sysinfo.h>
  765. +#include <sys/auxv.h>
  766. #include "syscall.h"
  767. #include "libc.h"
  768. @@ -19,6 +20,8 @@
  769. #define JT_AVPHYS_PAGES JT(9)
  770. #define JT_ZERO JT(10)
  771. #define JT_DELAYTIMER_MAX JT(11)
  772. +#define JT_MINSIGSTKSZ JT(12)
  773. +#define JT_SIGSTKSZ JT(13)
  774. #define RLIM(x) (-32768|(RLIMIT_ ## x))
  775. @@ -165,6 +168,9 @@ long sysconf(int name)
  776. [_SC_XOPEN_STREAMS] = JT_ZERO,
  777. [_SC_THREAD_ROBUST_PRIO_INHERIT] = -1,
  778. [_SC_THREAD_ROBUST_PRIO_PROTECT] = -1,
  779. +
  780. + [_SC_MINSIGSTKSZ] = JT_MINSIGSTKSZ,
  781. + [_SC_SIGSTKSZ] = JT_SIGSTKSZ,
  782. };
  783. if (name >= sizeof(values)/sizeof(values[0]) || !values[name]) {
  784. @@ -212,6 +218,13 @@ long sysconf(int name)
  785. mem *= si.mem_unit;
  786. mem /= PAGE_SIZE;
  787. return (mem > LONG_MAX) ? LONG_MAX : mem;
  788. + case JT_MINSIGSTKSZ & 255:
  789. + case JT_SIGSTKSZ & 255: ;
  790. + long val = __getauxval(AT_MINSIGSTKSZ);
  791. + if (val < MINSIGSTKSZ) val = MINSIGSTKSZ;
  792. + if (values[name] == JT_SIGSTKSZ)
  793. + val += SIGSTKSZ - MINSIGSTKSZ;
  794. + return val;
  795. case JT_ZERO & 255:
  796. return 0;
  797. }
  798. diff --git a/src/dirent/alphasort.c b/src/dirent/alphasort.c
  799. index bee672eb..ab2624e2 100644
  800. --- a/src/dirent/alphasort.c
  801. +++ b/src/dirent/alphasort.c
  802. @@ -5,5 +5,3 @@ int alphasort(const struct dirent **a, const struct dirent **b)
  803. {
  804. return strcoll((*a)->d_name, (*b)->d_name);
  805. }
  806. -
  807. -weak_alias(alphasort, alphasort64);
  808. diff --git a/src/dirent/readdir.c b/src/dirent/readdir.c
  809. index 569fc705..5a03b363 100644
  810. --- a/src/dirent/readdir.c
  811. +++ b/src/dirent/readdir.c
  812. @@ -25,5 +25,3 @@ struct dirent *readdir(DIR *dir)
  813. dir->tell = de->d_off;
  814. return de;
  815. }
  816. -
  817. -weak_alias(readdir, readdir64);
  818. diff --git a/src/dirent/readdir_r.c b/src/dirent/readdir_r.c
  819. index e2a818f3..0d5de5f5 100644
  820. --- a/src/dirent/readdir_r.c
  821. +++ b/src/dirent/readdir_r.c
  822. @@ -25,5 +25,3 @@ int readdir_r(DIR *restrict dir, struct dirent *restrict buf, struct dirent **re
  823. *result = buf;
  824. return 0;
  825. }
  826. -
  827. -weak_alias(readdir_r, readdir64_r);
  828. diff --git a/src/dirent/scandir.c b/src/dirent/scandir.c
  829. index 7ee195dd..7456b9b8 100644
  830. --- a/src/dirent/scandir.c
  831. +++ b/src/dirent/scandir.c
  832. @@ -43,5 +43,3 @@ int scandir(const char *path, struct dirent ***res,
  833. *res = names;
  834. return cnt;
  835. }
  836. -
  837. -weak_alias(scandir, scandir64);
  838. diff --git a/src/dirent/versionsort.c b/src/dirent/versionsort.c
  839. index d4c48923..97696105 100644
  840. --- a/src/dirent/versionsort.c
  841. +++ b/src/dirent/versionsort.c
  842. @@ -6,6 +6,3 @@ int versionsort(const struct dirent **a, const struct dirent **b)
  843. {
  844. return strverscmp((*a)->d_name, (*b)->d_name);
  845. }
  846. -
  847. -#undef versionsort64
  848. -weak_alias(versionsort, versionsort64);
  849. diff --git a/src/fcntl/creat.c b/src/fcntl/creat.c
  850. index 8f8aab64..c9c43910 100644
  851. --- a/src/fcntl/creat.c
  852. +++ b/src/fcntl/creat.c
  853. @@ -4,5 +4,3 @@ int creat(const char *filename, mode_t mode)
  854. {
  855. return open(filename, O_CREAT|O_WRONLY|O_TRUNC, mode);
  856. }
  857. -
  858. -weak_alias(creat, creat64);
  859. diff --git a/src/fcntl/open.c b/src/fcntl/open.c
  860. index 1d817a2d..4c3c8275 100644
  861. --- a/src/fcntl/open.c
  862. +++ b/src/fcntl/open.c
  863. @@ -19,5 +19,3 @@ int open(const char *filename, int flags, ...)
  864. return __syscall_ret(fd);
  865. }
  866. -
  867. -weak_alias(open, open64);
  868. diff --git a/src/fcntl/openat.c b/src/fcntl/openat.c
  869. index ad165ec3..83a9e0d0 100644
  870. --- a/src/fcntl/openat.c
  871. +++ b/src/fcntl/openat.c
  872. @@ -15,5 +15,3 @@ int openat(int fd, const char *filename, int flags, ...)
  873. return syscall_cp(SYS_openat, fd, filename, flags|O_LARGEFILE, mode);
  874. }
  875. -
  876. -weak_alias(openat, openat64);
  877. diff --git a/src/fcntl/posix_fadvise.c b/src/fcntl/posix_fadvise.c
  878. index 75b8e1ae..07346d21 100644
  879. --- a/src/fcntl/posix_fadvise.c
  880. +++ b/src/fcntl/posix_fadvise.c
  881. @@ -14,5 +14,3 @@ int posix_fadvise(int fd, off_t base, off_t len, int advice)
  882. __SYSCALL_LL_E(len), advice);
  883. #endif
  884. }
  885. -
  886. -weak_alias(posix_fadvise, posix_fadvise64);
  887. diff --git a/src/fcntl/posix_fallocate.c b/src/fcntl/posix_fallocate.c
  888. index c57a24ae..80a65cbf 100644
  889. --- a/src/fcntl/posix_fallocate.c
  890. +++ b/src/fcntl/posix_fallocate.c
  891. @@ -6,5 +6,3 @@ int posix_fallocate(int fd, off_t base, off_t len)
  892. return -__syscall(SYS_fallocate, fd, 0, __SYSCALL_LL_E(base),
  893. __SYSCALL_LL_E(len));
  894. }
  895. -
  896. -weak_alias(posix_fallocate, posix_fallocate64);
  897. diff --git a/src/include/sys/stat.h b/src/include/sys/stat.h
  898. new file mode 100644
  899. index 00000000..59339bee
  900. --- /dev/null
  901. +++ b/src/include/sys/stat.h
  902. @@ -0,0 +1,9 @@
  903. +#ifndef SYS_STAT_H
  904. +#define SYS_STAT_H
  905. +
  906. +#include "../../../include/sys/stat.h"
  907. +
  908. +hidden int __fstat(int, struct stat *);
  909. +hidden int __fstatat(int, const char *restrict, struct stat *restrict, int);
  910. +
  911. +#endif
  912. diff --git a/src/internal/dynlink.h b/src/internal/dynlink.h
  913. index 51c0639f..830354eb 100644
  914. --- a/src/internal/dynlink.h
  915. +++ b/src/internal/dynlink.h
  916. @@ -93,7 +93,7 @@ struct fdpic_dummy_loadmap {
  917. #endif
  918. #define AUX_CNT 32
  919. -#define DYN_CNT 32
  920. +#define DYN_CNT 37
  921. typedef void (*stage2_func)(unsigned char *, size_t *);
  922. diff --git a/src/internal/fork_impl.h b/src/internal/fork_impl.h
  923. index 5892c13b..354e733b 100644
  924. --- a/src/internal/fork_impl.h
  925. +++ b/src/internal/fork_impl.h
  926. @@ -2,7 +2,6 @@
  927. extern hidden volatile int *const __at_quick_exit_lockptr;
  928. extern hidden volatile int *const __atexit_lockptr;
  929. -extern hidden volatile int *const __dlerror_lockptr;
  930. extern hidden volatile int *const __gettext_lockptr;
  931. extern hidden volatile int *const __locale_lockptr;
  932. extern hidden volatile int *const __random_lockptr;
  933. @@ -17,3 +16,4 @@ extern hidden volatile int *const __vmlock_lockptr;
  934. hidden void __malloc_atfork(int);
  935. hidden void __ldso_atfork(int);
  936. +hidden void __pthread_key_atfork(int);
  937. diff --git a/src/internal/syscall.h b/src/internal/syscall.h
  938. index d5f294d4..4a446157 100644
  939. --- a/src/internal/syscall.h
  940. +++ b/src/internal/syscall.h
  941. @@ -58,7 +58,7 @@ hidden long __syscall_ret(unsigned long),
  942. #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
  943. #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
  944. -static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, long c, long d, long e, long f)
  945. +static inline long __alt_socketcall(int sys, int sock, int cp, syscall_arg_t a, syscall_arg_t b, syscall_arg_t c, syscall_arg_t d, syscall_arg_t e, syscall_arg_t f)
  946. {
  947. long r;
  948. if (cp) r = __syscall_cp(sys, a, b, c, d, e, f);
  949. @@ -71,9 +71,9 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
  950. return r;
  951. }
  952. #define __socketcall(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 0, \
  953. - (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))
  954. + __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f))
  955. #define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \
  956. - (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))
  957. + __scc(a), __scc(b), __scc(c), __scc(d), __scc(e), __scc(f))
  958. /* fixup legacy 16-bit junk */
  959. @@ -201,43 +201,43 @@ static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, l
  960. #define SYS_sendfile SYS_sendfile64
  961. #endif
  962. -#ifndef SYS_timer_settime
  963. +#ifdef SYS_timer_settime32
  964. #define SYS_timer_settime SYS_timer_settime32
  965. #endif
  966. -#ifndef SYS_timer_gettime
  967. +#ifdef SYS_timer_gettime32
  968. #define SYS_timer_gettime SYS_timer_gettime32
  969. #endif
  970. -#ifndef SYS_timerfd_settime
  971. +#ifdef SYS_timerfd_settime32
  972. #define SYS_timerfd_settime SYS_timerfd_settime32
  973. #endif
  974. -#ifndef SYS_timerfd_gettime
  975. +#ifdef SYS_timerfd_gettime32
  976. #define SYS_timerfd_gettime SYS_timerfd_gettime32
  977. #endif
  978. -#ifndef SYS_clock_settime
  979. +#ifdef SYS_clock_settime32
  980. #define SYS_clock_settime SYS_clock_settime32
  981. #endif
  982. -#ifndef SYS_clock_gettime
  983. +#ifdef SYS_clock_gettime32
  984. #define SYS_clock_gettime SYS_clock_gettime32
  985. #endif
  986. -#ifndef SYS_clock_getres
  987. +#ifdef SYS_clock_getres_time32
  988. #define SYS_clock_getres SYS_clock_getres_time32
  989. #endif
  990. -#ifndef SYS_clock_nanosleep
  991. +#ifdef SYS_clock_nanosleep_time32
  992. #define SYS_clock_nanosleep SYS_clock_nanosleep_time32
  993. #endif
  994. -#ifndef SYS_gettimeofday
  995. +#ifdef SYS_gettimeofday_time32
  996. #define SYS_gettimeofday SYS_gettimeofday_time32
  997. #endif
  998. -#ifndef SYS_settimeofday
  999. +#ifdef SYS_settimeofday_time32
  1000. #define SYS_settimeofday SYS_settimeofday_time32
  1001. #endif
  1002. diff --git a/src/ldso/dlerror.c b/src/ldso/dlerror.c
  1003. index afe59253..dae0f3a9 100644
  1004. --- a/src/ldso/dlerror.c
  1005. +++ b/src/ldso/dlerror.c
  1006. @@ -3,8 +3,7 @@
  1007. #include <stdarg.h>
  1008. #include "pthread_impl.h"
  1009. #include "dynlink.h"
  1010. -#include "lock.h"
  1011. -#include "fork_impl.h"
  1012. +#include "atomic.h"
  1013. #define malloc __libc_malloc
  1014. #define calloc __libc_calloc
  1015. @@ -23,28 +22,31 @@ char *dlerror()
  1016. return s;
  1017. }
  1018. -static volatile int freebuf_queue_lock[1];
  1019. -static void **freebuf_queue;
  1020. -volatile int *const __dlerror_lockptr = freebuf_queue_lock;
  1021. +/* Atomic singly-linked list, used to store list of thread-local dlerror
  1022. + * buffers for deferred free. They cannot be freed at thread exit time
  1023. + * because, by the time it's known they can be freed, the exiting thread
  1024. + * is in a highly restrictive context where it cannot call (even the
  1025. + * libc-internal) free. It also can't take locks; thus the atomic list. */
  1026. +
  1027. +static void *volatile freebuf_queue;
  1028. void __dl_thread_cleanup(void)
  1029. {
  1030. pthread_t self = __pthread_self();
  1031. - if (self->dlerror_buf && self->dlerror_buf != (void *)-1) {
  1032. - LOCK(freebuf_queue_lock);
  1033. - void **p = (void **)self->dlerror_buf;
  1034. - *p = freebuf_queue;
  1035. - freebuf_queue = p;
  1036. - UNLOCK(freebuf_queue_lock);
  1037. - }
  1038. + if (!self->dlerror_buf || self->dlerror_buf == (void *)-1)
  1039. + return;
  1040. + void *h;
  1041. + do {
  1042. + h = freebuf_queue;
  1043. + *(void **)self->dlerror_buf = h;
  1044. + } while (a_cas_p(&freebuf_queue, h, self->dlerror_buf) != h);
  1045. }
  1046. hidden void __dl_vseterr(const char *fmt, va_list ap)
  1047. {
  1048. - LOCK(freebuf_queue_lock);
  1049. - void **q = freebuf_queue;
  1050. - freebuf_queue = 0;
  1051. - UNLOCK(freebuf_queue_lock);
  1052. + void **q;
  1053. + do q = freebuf_queue;
  1054. + while (q && a_cas_p(&freebuf_queue, q, 0) != q);
  1055. while (q) {
  1056. void **p = *q;
  1057. diff --git a/src/legacy/ftw.c b/src/legacy/ftw.c
  1058. index 506bd29c..e757fc6f 100644
  1059. --- a/src/legacy/ftw.c
  1060. +++ b/src/legacy/ftw.c
  1061. @@ -7,5 +7,3 @@ int ftw(const char *path, int (*fn)(const char *, const struct stat *, int), int
  1062. * actually undefined, but works on all real-world machines. */
  1063. return nftw(path, (int (*)())fn, fd_limit, FTW_PHYS);
  1064. }
  1065. -
  1066. -weak_alias(ftw, ftw64);
  1067. diff --git a/src/linux/epoll.c b/src/linux/epoll.c
  1068. index 93baa814..e56e8f4c 100644
  1069. --- a/src/linux/epoll.c
  1070. +++ b/src/linux/epoll.c
  1071. @@ -5,6 +5,7 @@
  1072. int epoll_create(int size)
  1073. {
  1074. + if (size<=0) return __syscall_ret(-EINVAL);
  1075. return epoll_create1(0);
  1076. }
  1077. diff --git a/src/linux/fallocate.c b/src/linux/fallocate.c
  1078. index 7d68bc8f..9146350e 100644
  1079. --- a/src/linux/fallocate.c
  1080. +++ b/src/linux/fallocate.c
  1081. @@ -7,6 +7,3 @@ int fallocate(int fd, int mode, off_t base, off_t len)
  1082. return syscall(SYS_fallocate, fd, mode, __SYSCALL_LL_E(base),
  1083. __SYSCALL_LL_E(len));
  1084. }
  1085. -
  1086. -#undef fallocate64
  1087. -weak_alias(fallocate, fallocate64);
  1088. diff --git a/src/linux/getdents.c b/src/linux/getdents.c
  1089. index 796c1e5c..97f76e14 100644
  1090. --- a/src/linux/getdents.c
  1091. +++ b/src/linux/getdents.c
  1092. @@ -8,5 +8,3 @@ int getdents(int fd, struct dirent *buf, size_t len)
  1093. if (len>INT_MAX) len = INT_MAX;
  1094. return syscall(SYS_getdents, fd, buf, len);
  1095. }
  1096. -
  1097. -weak_alias(getdents, getdents64);
  1098. diff --git a/src/linux/membarrier.c b/src/linux/membarrier.c
  1099. index 343f7360..f64fe7e1 100644
  1100. --- a/src/linux/membarrier.c
  1101. +++ b/src/linux/membarrier.c
  1102. @@ -35,7 +35,7 @@ int __membarrier(int cmd, int flags)
  1103. __tl_lock();
  1104. sem_init(&barrier_sem, 0, 0);
  1105. struct sigaction sa = {
  1106. - .sa_flags = SA_RESTART,
  1107. + .sa_flags = SA_RESTART | SA_ONSTACK,
  1108. .sa_handler = bcast_barrier
  1109. };
  1110. memset(&sa.sa_mask, -1, sizeof sa.sa_mask);
  1111. diff --git a/src/linux/prlimit.c b/src/linux/prlimit.c
  1112. index 3df9ffba..fcf45aab 100644
  1113. --- a/src/linux/prlimit.c
  1114. +++ b/src/linux/prlimit.c
  1115. @@ -21,6 +21,3 @@ int prlimit(pid_t pid, int resource, const struct rlimit *new_limit, struct rlim
  1116. }
  1117. return r;
  1118. }
  1119. -
  1120. -#undef prlimit64
  1121. -weak_alias(prlimit, prlimit64);
  1122. diff --git a/src/linux/sendfile.c b/src/linux/sendfile.c
  1123. index 9afe6dd6..fc1577d3 100644
  1124. --- a/src/linux/sendfile.c
  1125. +++ b/src/linux/sendfile.c
  1126. @@ -5,5 +5,3 @@ ssize_t sendfile(int out_fd, int in_fd, off_t *ofs, size_t count)
  1127. {
  1128. return syscall(SYS_sendfile, out_fd, in_fd, ofs, count);
  1129. }
  1130. -
  1131. -weak_alias(sendfile, sendfile64);
  1132. diff --git a/src/malloc/mallocng/free.c b/src/malloc/mallocng/free.c
  1133. index 418a085c..43f32aad 100644
  1134. --- a/src/malloc/mallocng/free.c
  1135. +++ b/src/malloc/mallocng/free.c
  1136. @@ -119,7 +119,7 @@ void free(void *p)
  1137. if (((uintptr_t)(start-1) ^ (uintptr_t)end) >= 2*PGSZ && g->last_idx) {
  1138. unsigned char *base = start + (-(uintptr_t)start & (PGSZ-1));
  1139. size_t len = (end-base) & -PGSZ;
  1140. - if (len) {
  1141. + if (len && USE_MADV_FREE) {
  1142. int e = errno;
  1143. madvise(base, len, MADV_FREE);
  1144. errno = e;
  1145. diff --git a/src/malloc/mallocng/glue.h b/src/malloc/mallocng/glue.h
  1146. index 151c48b8..77f4c812 100644
  1147. --- a/src/malloc/mallocng/glue.h
  1148. +++ b/src/malloc/mallocng/glue.h
  1149. @@ -24,6 +24,8 @@
  1150. #define realloc __libc_realloc
  1151. #define free __libc_free
  1152. +#define USE_MADV_FREE 0
  1153. +
  1154. #if USE_REAL_ASSERT
  1155. #include <assert.h>
  1156. #else
  1157. diff --git a/src/misc/getrlimit.c b/src/misc/getrlimit.c
  1158. index 2ab2f0f4..a5558d81 100644
  1159. --- a/src/misc/getrlimit.c
  1160. +++ b/src/misc/getrlimit.c
  1161. @@ -6,12 +6,13 @@
  1162. int getrlimit(int resource, struct rlimit *rlim)
  1163. {
  1164. - unsigned long k_rlim[2];
  1165. int ret = syscall(SYS_prlimit64, 0, resource, 0, rlim);
  1166. if (!ret) {
  1167. FIX(rlim->rlim_cur);
  1168. FIX(rlim->rlim_max);
  1169. }
  1170. +#ifdef SYS_getrlimit
  1171. + unsigned long k_rlim[2];
  1172. if (!ret || errno != ENOSYS)
  1173. return ret;
  1174. if (syscall(SYS_getrlimit, resource, k_rlim) < 0)
  1175. @@ -21,6 +22,7 @@ int getrlimit(int resource, struct rlimit *rlim)
  1176. FIX(rlim->rlim_cur);
  1177. FIX(rlim->rlim_max);
  1178. return 0;
  1179. +#else
  1180. + return ret;
  1181. +#endif
  1182. }
  1183. -
  1184. -weak_alias(getrlimit, getrlimit64);
  1185. diff --git a/src/misc/lockf.c b/src/misc/lockf.c
  1186. index 16a80bec..0162442b 100644
  1187. --- a/src/misc/lockf.c
  1188. +++ b/src/misc/lockf.c
  1189. @@ -28,5 +28,3 @@ int lockf(int fd, int op, off_t size)
  1190. errno = EINVAL;
  1191. return -1;
  1192. }
  1193. -
  1194. -weak_alias(lockf, lockf64);
  1195. diff --git a/src/misc/mntent.c b/src/misc/mntent.c
  1196. index eabb8200..d404fbe3 100644
  1197. --- a/src/misc/mntent.c
  1198. +++ b/src/misc/mntent.c
  1199. @@ -2,6 +2,7 @@
  1200. #include <string.h>
  1201. #include <mntent.h>
  1202. #include <errno.h>
  1203. +#include <limits.h>
  1204. static char *internal_buf;
  1205. static size_t internal_bufsize;
  1206. @@ -21,7 +22,8 @@ int endmntent(FILE *f)
  1207. struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int buflen)
  1208. {
  1209. - int cnt, n[8], use_internal = (linebuf == SENTINEL);
  1210. + int n[8], use_internal = (linebuf == SENTINEL);
  1211. + size_t len, i;
  1212. mnt->mnt_freq = 0;
  1213. mnt->mnt_passno = 0;
  1214. @@ -39,10 +41,14 @@ struct mntent *getmntent_r(FILE *f, struct mntent *mnt, char *linebuf, int bufle
  1215. errno = ERANGE;
  1216. return 0;
  1217. }
  1218. - cnt = sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d",
  1219. +
  1220. + len = strlen(linebuf);
  1221. + if (len > INT_MAX) continue;
  1222. + for (i = 0; i < sizeof n / sizeof *n; i++) n[i] = len;
  1223. + sscanf(linebuf, " %n%*s%n %n%*s%n %n%*s%n %n%*s%n %d %d",
  1224. n, n+1, n+2, n+3, n+4, n+5, n+6, n+7,
  1225. &mnt->mnt_freq, &mnt->mnt_passno);
  1226. - } while (cnt < 2 || linebuf[n[0]] == '#');
  1227. + } while (linebuf[n[0]] == '#' || n[1]==len);
  1228. linebuf[n[1]] = 0;
  1229. linebuf[n[3]] = 0;
  1230. diff --git a/src/misc/nftw.c b/src/misc/nftw.c
  1231. index 8dcff7fe..fcd25a73 100644
  1232. --- a/src/misc/nftw.c
  1233. +++ b/src/misc/nftw.c
  1234. @@ -138,5 +138,3 @@ int nftw(const char *path, int (*fn)(const char *, const struct stat *, int, str
  1235. pthread_setcancelstate(cs, 0);
  1236. return r;
  1237. }
  1238. -
  1239. -weak_alias(nftw, nftw64);
  1240. diff --git a/src/misc/setrlimit.c b/src/misc/setrlimit.c
  1241. index 8340aee0..edb413fa 100644
  1242. --- a/src/misc/setrlimit.c
  1243. +++ b/src/misc/setrlimit.c
  1244. @@ -12,12 +12,14 @@ struct ctx {
  1245. int err;
  1246. };
  1247. +#ifdef SYS_setrlimit
  1248. static void do_setrlimit(void *p)
  1249. {
  1250. struct ctx *c = p;
  1251. if (c->err>0) return;
  1252. c->err = -__syscall(SYS_setrlimit, c->res, c->lim);
  1253. }
  1254. +#endif
  1255. int setrlimit(int resource, const struct rlimit *rlim)
  1256. {
  1257. @@ -29,6 +31,7 @@ int setrlimit(int resource, const struct rlimit *rlim)
  1258. rlim = &tmp;
  1259. }
  1260. int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
  1261. +#ifdef SYS_setrlimit
  1262. if (ret != -ENOSYS) return __syscall_ret(ret);
  1263. struct ctx c = {
  1264. @@ -42,6 +45,7 @@ int setrlimit(int resource, const struct rlimit *rlim)
  1265. return -1;
  1266. }
  1267. return 0;
  1268. +#else
  1269. + return __syscall_ret(ret);
  1270. +#endif
  1271. }
  1272. -
  1273. -weak_alias(setrlimit, setrlimit64);
  1274. diff --git a/src/mman/mmap.c b/src/mman/mmap.c
  1275. index eff88d82..43e5e029 100644
  1276. --- a/src/mman/mmap.c
  1277. +++ b/src/mman/mmap.c
  1278. @@ -37,5 +37,3 @@ void *__mmap(void *start, size_t len, int prot, int flags, int fd, off_t off)
  1279. }
  1280. weak_alias(__mmap, mmap);
  1281. -
  1282. -weak_alias(mmap, mmap64);
  1283. diff --git a/src/network/gai_strerror.c b/src/network/gai_strerror.c
  1284. index 9596580e..56b71503 100644
  1285. --- a/src/network/gai_strerror.c
  1286. +++ b/src/network/gai_strerror.c
  1287. @@ -6,7 +6,7 @@ static const char msgs[] =
  1288. "Name does not resolve\0"
  1289. "Try again\0"
  1290. "Non-recoverable error\0"
  1291. - "Unknown error\0"
  1292. + "Name has no usable address\0"
  1293. "Unrecognized address family or invalid length\0"
  1294. "Unrecognized socket type\0"
  1295. "Unrecognized service\0"
  1296. diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c
  1297. index efaab306..64ad259a 100644
  1298. --- a/src/network/getaddrinfo.c
  1299. +++ b/src/network/getaddrinfo.c
  1300. @@ -16,6 +16,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru
  1301. char canon[256], *outcanon;
  1302. int nservs, naddrs, nais, canon_len, i, j, k;
  1303. int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0;
  1304. + int no_family = 0;
  1305. struct aibuf *out;
  1306. if (!host && !serv) return EAI_NONAME;
  1307. @@ -66,9 +67,11 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru
  1308. pthread_setcancelstate(
  1309. PTHREAD_CANCEL_DISABLE, &cs);
  1310. int r = connect(s, ta[i], tl[i]);
  1311. + int saved_errno = errno;
  1312. pthread_setcancelstate(cs, 0);
  1313. close(s);
  1314. if (!r) continue;
  1315. + errno = saved_errno;
  1316. }
  1317. switch (errno) {
  1318. case EADDRNOTAVAIL:
  1319. @@ -80,7 +83,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru
  1320. default:
  1321. return EAI_SYSTEM;
  1322. }
  1323. - if (family == tf[i]) return EAI_NONAME;
  1324. + if (family == tf[i]) no_family = 1;
  1325. family = tf[1-i];
  1326. }
  1327. }
  1328. @@ -91,6 +94,8 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru
  1329. naddrs = __lookup_name(addrs, canon, host, family, flags);
  1330. if (naddrs < 0) return naddrs;
  1331. + if (no_family) return EAI_NODATA;
  1332. +
  1333. nais = nservs * naddrs;
  1334. canon_len = strlen(canon);
  1335. out = calloc(1, nais * sizeof(*out) + canon_len + 1);
  1336. diff --git a/src/network/gethostbyaddr.c b/src/network/gethostbyaddr.c
  1337. index 598e2241..c3cacaac 100644
  1338. --- a/src/network/gethostbyaddr.c
  1339. +++ b/src/network/gethostbyaddr.c
  1340. @@ -20,5 +20,5 @@ struct hostent *gethostbyaddr(const void *a, socklen_t l, int af)
  1341. err = gethostbyaddr_r(a, l, af, h,
  1342. (void *)(h+1), size-sizeof *h, &res, &h_errno);
  1343. } while (err == ERANGE);
  1344. - return err ? 0 : h;
  1345. + return res;
  1346. }
  1347. diff --git a/src/network/gethostbyaddr_r.c b/src/network/gethostbyaddr_r.c
  1348. index 0f1e61aa..ceaf3935 100644
  1349. --- a/src/network/gethostbyaddr_r.c
  1350. +++ b/src/network/gethostbyaddr_r.c
  1351. @@ -54,9 +54,10 @@ int gethostbyaddr_r(const void *a, socklen_t l, int af,
  1352. case EAI_OVERFLOW:
  1353. return ERANGE;
  1354. default:
  1355. - case EAI_MEMORY:
  1356. - case EAI_SYSTEM:
  1357. case EAI_FAIL:
  1358. + *err = NO_RECOVERY;
  1359. + return EBADMSG;
  1360. + case EAI_SYSTEM:
  1361. *err = NO_RECOVERY;
  1362. return errno;
  1363. case 0:
  1364. diff --git a/src/network/gethostbyname2.c b/src/network/gethostbyname2.c
  1365. index dc9d6621..bd0da7f8 100644
  1366. --- a/src/network/gethostbyname2.c
  1367. +++ b/src/network/gethostbyname2.c
  1368. @@ -21,5 +21,5 @@ struct hostent *gethostbyname2(const char *name, int af)
  1369. err = gethostbyname2_r(name, af, h,
  1370. (void *)(h+1), size-sizeof *h, &res, &h_errno);
  1371. } while (err == ERANGE);
  1372. - return err ? 0 : h;
  1373. + return res;
  1374. }
  1375. diff --git a/src/network/gethostbyname2_r.c b/src/network/gethostbyname2_r.c
  1376. index fc894877..a5eb67fe 100644
  1377. --- a/src/network/gethostbyname2_r.c
  1378. +++ b/src/network/gethostbyname2_r.c
  1379. @@ -22,7 +22,10 @@ int gethostbyname2_r(const char *name, int af,
  1380. if (cnt<0) switch (cnt) {
  1381. case EAI_NONAME:
  1382. *err = HOST_NOT_FOUND;
  1383. - return ENOENT;
  1384. + return 0;
  1385. + case EAI_NODATA:
  1386. + *err = NO_DATA;
  1387. + return 0;
  1388. case EAI_AGAIN:
  1389. *err = TRY_AGAIN;
  1390. return EAGAIN;
  1391. @@ -30,7 +33,6 @@ int gethostbyname2_r(const char *name, int af,
  1392. case EAI_FAIL:
  1393. *err = NO_RECOVERY;
  1394. return EBADMSG;
  1395. - case EAI_MEMORY:
  1396. case EAI_SYSTEM:
  1397. *err = NO_RECOVERY;
  1398. return errno;
  1399. diff --git a/src/network/lookup_ipliteral.c b/src/network/lookup_ipliteral.c
  1400. index 2fddab73..1e766206 100644
  1401. --- a/src/network/lookup_ipliteral.c
  1402. +++ b/src/network/lookup_ipliteral.c
  1403. @@ -15,7 +15,7 @@ int __lookup_ipliteral(struct address buf[static 1], const char *name, int famil
  1404. struct in6_addr a6;
  1405. if (__inet_aton(name, &a4) > 0) {
  1406. if (family == AF_INET6) /* wrong family */
  1407. - return EAI_NONAME;
  1408. + return EAI_NODATA;
  1409. memcpy(&buf[0].addr, &a4, sizeof a4);
  1410. buf[0].family = AF_INET;
  1411. buf[0].scopeid = 0;
  1412. @@ -34,7 +34,7 @@ int __lookup_ipliteral(struct address buf[static 1], const char *name, int famil
  1413. if (inet_pton(AF_INET6, name, &a6) <= 0)
  1414. return 0;
  1415. if (family == AF_INET) /* wrong family */
  1416. - return EAI_NONAME;
  1417. + return EAI_NODATA;
  1418. memcpy(&buf[0].addr, &a6, sizeof a6);
  1419. buf[0].family = AF_INET6;
  1420. diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
  1421. index aa558c19..5f6867cb 100644
  1422. --- a/src/network/lookup_name.c
  1423. +++ b/src/network/lookup_name.c
  1424. @@ -79,7 +79,7 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
  1425. case 0:
  1426. continue;
  1427. default:
  1428. - badfam = EAI_NONAME;
  1429. + badfam = EAI_NODATA;
  1430. break;
  1431. }
  1432. @@ -102,45 +102,50 @@ struct dpc_ctx {
  1433. struct address *addrs;
  1434. char *canon;
  1435. int cnt;
  1436. + int rrtype;
  1437. };
  1438. #define RR_A 1
  1439. #define RR_CNAME 5
  1440. #define RR_AAAA 28
  1441. +#define ABUF_SIZE 768
  1442. +
  1443. static int dns_parse_callback(void *c, int rr, const void *data, int len, const void *packet)
  1444. {
  1445. char tmp[256];
  1446. + int family;
  1447. struct dpc_ctx *ctx = c;
  1448. - if (ctx->cnt >= MAXADDRS) return -1;
  1449. + if (rr == RR_CNAME) {
  1450. + if (__dn_expand(packet, (const unsigned char *)packet + ABUF_SIZE,
  1451. + data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
  1452. + strcpy(ctx->canon, tmp);
  1453. + return 0;
  1454. + }
  1455. + if (ctx->cnt >= MAXADDRS) return 0;
  1456. + if (rr != ctx->rrtype) return 0;
  1457. switch (rr) {
  1458. case RR_A:
  1459. if (len != 4) return -1;
  1460. - ctx->addrs[ctx->cnt].family = AF_INET;
  1461. - ctx->addrs[ctx->cnt].scopeid = 0;
  1462. - memcpy(ctx->addrs[ctx->cnt++].addr, data, 4);
  1463. + family = AF_INET;
  1464. break;
  1465. case RR_AAAA:
  1466. if (len != 16) return -1;
  1467. - ctx->addrs[ctx->cnt].family = AF_INET6;
  1468. - ctx->addrs[ctx->cnt].scopeid = 0;
  1469. - memcpy(ctx->addrs[ctx->cnt++].addr, data, 16);
  1470. - break;
  1471. - case RR_CNAME:
  1472. - if (__dn_expand(packet, (const unsigned char *)packet + 512,
  1473. - data, tmp, sizeof tmp) > 0 && is_valid_hostname(tmp))
  1474. - strcpy(ctx->canon, tmp);
  1475. + family = AF_INET6;
  1476. break;
  1477. }
  1478. + ctx->addrs[ctx->cnt].family = family;
  1479. + ctx->addrs[ctx->cnt].scopeid = 0;
  1480. + memcpy(ctx->addrs[ctx->cnt++].addr, data, len);
  1481. return 0;
  1482. }
  1483. static int name_from_dns(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family, const struct resolvconf *conf)
  1484. {
  1485. - unsigned char qbuf[2][280], abuf[2][512];
  1486. + unsigned char qbuf[2][280], abuf[2][ABUF_SIZE];
  1487. const unsigned char *qp[2] = { qbuf[0], qbuf[1] };
  1488. unsigned char *ap[2] = { abuf[0], abuf[1] };
  1489. - int qlens[2], alens[2];
  1490. + int qlens[2], alens[2], qtypes[2];
  1491. int i, nq = 0;
  1492. struct dpc_ctx ctx = { .addrs = buf, .canon = canon };
  1493. static const struct { int af; int rr; } afrr[2] = {
  1494. @@ -153,8 +158,12 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static
  1495. qlens[nq] = __res_mkquery(0, name, 1, afrr[i].rr,
  1496. 0, 0, 0, qbuf[nq], sizeof *qbuf);
  1497. if (qlens[nq] == -1)
  1498. - return EAI_NONAME;
  1499. + return 0;
  1500. + qtypes[nq] = afrr[i].rr;
  1501. qbuf[nq][3] = 0; /* don't need AD flag */
  1502. + /* Ensure query IDs are distinct. */
  1503. + if (nq && qbuf[nq][0] == qbuf[0][0])
  1504. + qbuf[nq][0]++;
  1505. nq++;
  1506. }
  1507. }
  1508. @@ -168,11 +177,13 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static
  1509. if ((abuf[i][3] & 15) != 0) return EAI_FAIL;
  1510. }
  1511. - for (i=0; i<nq; i++)
  1512. + for (i=nq-1; i>=0; i--) {
  1513. + ctx.rrtype = qtypes[i];
  1514. __dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx);
  1515. + }
  1516. if (ctx.cnt) return ctx.cnt;
  1517. - return EAI_NONAME;
  1518. + return EAI_NODATA;
  1519. }
  1520. static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family)
  1521. diff --git a/src/network/netlink.h b/src/network/netlink.h
  1522. index 38acb178..873fabe2 100644
  1523. --- a/src/network/netlink.h
  1524. +++ b/src/network/netlink.h
  1525. @@ -86,7 +86,7 @@ struct ifaddrmsg {
  1526. #define RTA_DATALEN(rta) ((rta)->rta_len-sizeof(struct rtattr))
  1527. #define RTA_DATAEND(rta) ((char*)(rta)+(rta)->rta_len)
  1528. #define RTA_NEXT(rta) (struct rtattr*)((char*)(rta)+NETLINK_ALIGN((rta)->rta_len))
  1529. -#define RTA_OK(nlh,end) ((char*)(end)-(char*)(rta) >= sizeof(struct rtattr))
  1530. +#define RTA_OK(rta,end) ((char*)(end)-(char*)(rta) >= sizeof(struct rtattr))
  1531. #define NLMSG_RTA(nlh,len) ((void*)((char*)(nlh)+sizeof(struct nlmsghdr)+NETLINK_ALIGN(len)))
  1532. #define NLMSG_RTAOK(rta,nlh) RTA_OK(rta,NLMSG_DATAEND(nlh))
  1533. diff --git a/src/network/res_mkquery.c b/src/network/res_mkquery.c
  1534. index 33f50cb9..614bf786 100644
  1535. --- a/src/network/res_mkquery.c
  1536. +++ b/src/network/res_mkquery.c
  1537. @@ -13,6 +13,7 @@ int __res_mkquery(int op, const char *dname, int class, int type,
  1538. int n;
  1539. if (l && dname[l-1]=='.') l--;
  1540. + if (l && dname[l-1]=='.') return -1;
  1541. n = 17+l+!!l;
  1542. if (l>253 || buflen<n || op>15u || class>255u || type>255u)
  1543. return -1;
  1544. diff --git a/src/network/res_msend.c b/src/network/res_msend.c
  1545. index 3e018009..11c6aa0e 100644
  1546. --- a/src/network/res_msend.c
  1547. +++ b/src/network/res_msend.c
  1548. @@ -1,5 +1,6 @@
  1549. #include <sys/socket.h>
  1550. #include <netinet/in.h>
  1551. +#include <netinet/tcp.h>
  1552. #include <netdb.h>
  1553. #include <arpa/inet.h>
  1554. #include <stdint.h>
  1555. @@ -16,7 +17,9 @@
  1556. static void cleanup(void *p)
  1557. {
  1558. - __syscall(SYS_close, (intptr_t)p);
  1559. + struct pollfd *pfd = p;
  1560. + for (int i=0; pfd[i].fd >= -1; i++)
  1561. + if (pfd[i].fd >= 0) __syscall(SYS_close, pfd[i].fd);
  1562. }
  1563. static unsigned long mtime()
  1564. @@ -27,6 +30,51 @@ static unsigned long mtime()
  1565. + ts.tv_nsec / 1000000;
  1566. }
  1567. +static int start_tcp(struct pollfd *pfd, int family, const void *sa, socklen_t sl, const unsigned char *q, int ql)
  1568. +{
  1569. + struct msghdr mh = {
  1570. + .msg_name = (void *)sa,
  1571. + .msg_namelen = sl,
  1572. + .msg_iovlen = 2,
  1573. + .msg_iov = (struct iovec [2]){
  1574. + { .iov_base = (uint8_t[]){ ql>>8, ql }, .iov_len = 2 },
  1575. + { .iov_base = (void *)q, .iov_len = ql } }
  1576. + };
  1577. + int r;
  1578. + int fd = socket(family, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
  1579. + pfd->fd = fd;
  1580. + pfd->events = POLLOUT;
  1581. + if (!setsockopt(fd, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
  1582. + &(int){1}, sizeof(int))) {
  1583. + r = sendmsg(fd, &mh, MSG_FASTOPEN|MSG_NOSIGNAL);
  1584. + if (r == ql+2) pfd->events = POLLIN;
  1585. + if (r >= 0) return r;
  1586. + if (errno == EINPROGRESS) return 0;
  1587. + }
  1588. + r = connect(fd, sa, sl);
  1589. + if (!r || errno == EINPROGRESS) return 0;
  1590. + close(fd);
  1591. + pfd->fd = -1;
  1592. + return -1;
  1593. +}
  1594. +
  1595. +static void step_mh(struct msghdr *mh, size_t n)
  1596. +{
  1597. + /* Adjust iovec in msghdr to skip first n bytes. */
  1598. + while (mh->msg_iovlen && n >= mh->msg_iov->iov_len) {
  1599. + n -= mh->msg_iov->iov_len;
  1600. + mh->msg_iov++;
  1601. + mh->msg_iovlen--;
  1602. + }
  1603. + if (!mh->msg_iovlen) return;
  1604. + mh->msg_iov->iov_base = (char *)mh->msg_iov->iov_base + n;
  1605. + mh->msg_iov->iov_len -= n;
  1606. +}
  1607. +
  1608. +/* Internal contract for __res_msend[_rc]: asize must be >=512, nqueries
  1609. + * must be sufficiently small to be safe as VLA size. In practice it's
  1610. + * either 1 or 2, anyway. */
  1611. +
  1612. int __res_msend_rc(int nqueries, const unsigned char *const *queries,
  1613. const int *qlens, unsigned char *const *answers, int *alens, int asize,
  1614. const struct resolvconf *conf)
  1615. @@ -44,7 +92,10 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
  1616. int next;
  1617. int i, j;
  1618. int cs;
  1619. - struct pollfd pfd;
  1620. + struct pollfd pfd[nqueries+2];
  1621. + int qpos[nqueries], apos[nqueries];
  1622. + unsigned char alen_buf[nqueries][2];
  1623. + int r;
  1624. unsigned long t0, t1, t2;
  1625. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
  1626. @@ -68,14 +119,20 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
  1627. }
  1628. /* Get local address and open/bind a socket */
  1629. - sa.sin.sin_family = family;
  1630. fd = socket(family, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
  1631. /* Handle case where system lacks IPv6 support */
  1632. if (fd < 0 && family == AF_INET6 && errno == EAFNOSUPPORT) {
  1633. + for (i=0; i<nns && conf->ns[nns].family == AF_INET6; i++);
  1634. + if (i==nns) {
  1635. + pthread_setcancelstate(cs, 0);
  1636. + return -1;
  1637. + }
  1638. fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
  1639. family = AF_INET;
  1640. + sl = sizeof sa.sin;
  1641. }
  1642. + sa.sin.sin_family = family;
  1643. if (fd < 0 || bind(fd, (void *)&sa, sl) < 0) {
  1644. if (fd >= 0) close(fd);
  1645. pthread_setcancelstate(cs, 0);
  1646. @@ -86,7 +143,12 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
  1647. * yield either no reply (indicated by zero length) or an answer
  1648. * packet which is up to the caller to interpret. */
  1649. - pthread_cleanup_push(cleanup, (void *)(intptr_t)fd);
  1650. + for (i=0; i<nqueries; i++) pfd[i].fd = -1;
  1651. + pfd[nqueries].fd = fd;
  1652. + pfd[nqueries].events = POLLIN;
  1653. + pfd[nqueries+1].fd = -2;
  1654. +
  1655. + pthread_cleanup_push(cleanup, pfd);
  1656. pthread_setcancelstate(cs, 0);
  1657. /* Convert any IPv4 addresses in a mixed environment to v4-mapped */
  1658. @@ -106,14 +168,17 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
  1659. memset(alens, 0, sizeof *alens * nqueries);
  1660. - pfd.fd = fd;
  1661. - pfd.events = POLLIN;
  1662. retry_interval = timeout / attempts;
  1663. next = 0;
  1664. t0 = t2 = mtime();
  1665. t1 = t2 - retry_interval;
  1666. for (; t2-t0 < timeout; t2=mtime()) {
  1667. + /* This is the loop exit condition: that all queries
  1668. + * have an accepted answer. */
  1669. + for (i=0; i<nqueries && alens[i]>0; i++);
  1670. + if (i==nqueries) break;
  1671. +
  1672. if (t2-t1 >= retry_interval) {
  1673. /* Query all configured namservers in parallel */
  1674. for (i=0; i<nqueries; i++)
  1675. @@ -127,10 +192,20 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
  1676. }
  1677. /* Wait for a response, or until time to retry */
  1678. - if (poll(&pfd, 1, t1+retry_interval-t2) <= 0) continue;
  1679. + if (poll(pfd, nqueries+1, t1+retry_interval-t2) <= 0) continue;
  1680. - while ((rlen = recvfrom(fd, answers[next], asize, 0,
  1681. - (void *)&sa, (socklen_t[1]){sl})) >= 0) {
  1682. + while (next < nqueries) {
  1683. + struct msghdr mh = {
  1684. + .msg_name = (void *)&sa,
  1685. + .msg_namelen = sl,
  1686. + .msg_iovlen = 1,
  1687. + .msg_iov = (struct iovec []){
  1688. + { .iov_base = (void *)answers[next],
  1689. + .iov_len = asize }
  1690. + }
  1691. + };
  1692. + rlen = recvmsg(fd, &mh, 0);
  1693. + if (rlen < 0) break;
  1694. /* Ignore non-identifiable packets */
  1695. if (rlen < 4) continue;
  1696. @@ -170,12 +245,72 @@ int __res_msend_rc(int nqueries, const unsigned char *const *queries,
  1697. else
  1698. memcpy(answers[i], answers[next], rlen);
  1699. - if (next == nqueries) goto out;
  1700. + /* Ignore further UDP if all slots full or TCP-mode */
  1701. + if (next == nqueries) pfd[nqueries].events = 0;
  1702. +
  1703. + /* If answer is truncated (TC bit), fallback to TCP */
  1704. + if ((answers[i][2] & 2) || (mh.msg_flags & MSG_TRUNC)) {
  1705. + alens[i] = -1;
  1706. + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0);
  1707. + r = start_tcp(pfd+i, family, ns+j, sl, queries[i], qlens[i]);
  1708. + pthread_setcancelstate(cs, 0);
  1709. + if (r >= 0) {
  1710. + qpos[i] = r;
  1711. + apos[i] = 0;
  1712. + }
  1713. + continue;
  1714. + }
  1715. + }
  1716. +
  1717. + for (i=0; i<nqueries; i++) if (pfd[i].revents & POLLOUT) {
  1718. + struct msghdr mh = {
  1719. + .msg_iovlen = 2,
  1720. + .msg_iov = (struct iovec [2]){
  1721. + { .iov_base = (uint8_t[]){ qlens[i]>>8, qlens[i] }, .iov_len = 2 },
  1722. + { .iov_base = (void *)queries[i], .iov_len = qlens[i] } }
  1723. + };
  1724. + step_mh(&mh, qpos[i]);
  1725. + r = sendmsg(pfd[i].fd, &mh, MSG_NOSIGNAL);
  1726. + if (r < 0) goto out;
  1727. + qpos[i] += r;
  1728. + if (qpos[i] == qlens[i]+2)
  1729. + pfd[i].events = POLLIN;
  1730. + }
  1731. +
  1732. + for (i=0; i<nqueries; i++) if (pfd[i].revents & POLLIN) {
  1733. + struct msghdr mh = {
  1734. + .msg_iovlen = 2,
  1735. + .msg_iov = (struct iovec [2]){
  1736. + { .iov_base = alen_buf[i], .iov_len = 2 },
  1737. + { .iov_base = answers[i], .iov_len = asize } }
  1738. + };
  1739. + step_mh(&mh, apos[i]);
  1740. + r = recvmsg(pfd[i].fd, &mh, 0);
  1741. + if (r < 0) goto out;
  1742. + apos[i] += r;
  1743. + if (apos[i] < 2) continue;
  1744. + int alen = alen_buf[i][0]*256 + alen_buf[i][1];
  1745. + if (alen < 13) goto out;
  1746. + if (apos[i] < alen+2 && apos[i] < asize+2)
  1747. + continue;
  1748. + int rcode = answers[i][3] & 15;
  1749. + if (rcode != 0 && rcode != 3)
  1750. + goto out;
  1751. +
  1752. + /* Storing the length here commits the accepted answer.
  1753. + * Immediately close TCP socket so as not to consume
  1754. + * resources we no longer need. */
  1755. + alens[i] = alen;
  1756. + __syscall(SYS_close, pfd[i].fd);
  1757. + pfd[i].fd = -1;
  1758. }
  1759. }
  1760. out:
  1761. pthread_cleanup_pop(1);
  1762. + /* Disregard any incomplete TCP results */
  1763. + for (i=0; i<nqueries; i++) if (alens[i]<0) alens[i] = 0;
  1764. +
  1765. return 0;
  1766. }
  1767. diff --git a/src/network/res_send.c b/src/network/res_send.c
  1768. index ee4abf1f..9593164d 100644
  1769. --- a/src/network/res_send.c
  1770. +++ b/src/network/res_send.c
  1771. @@ -1,8 +1,16 @@
  1772. #include <resolv.h>
  1773. +#include <string.h>
  1774. int __res_send(const unsigned char *msg, int msglen, unsigned char *answer, int anslen)
  1775. {
  1776. - int r = __res_msend(1, &msg, &msglen, &answer, &anslen, anslen);
  1777. + int r;
  1778. + if (anslen < 512) {
  1779. + unsigned char buf[512];
  1780. + r = __res_send(msg, msglen, buf, sizeof buf);
  1781. + if (r >= 0) memcpy(answer, buf, r < anslen ? r : anslen);
  1782. + return r;
  1783. + }
  1784. + r = __res_msend(1, &msg, &msglen, &answer, &anslen, anslen);
  1785. return r<0 || !anslen ? -1 : anslen;
  1786. }
  1787. diff --git a/src/process/_Fork.c b/src/process/_Fork.c
  1788. index da063868..fb0fdc2c 100644
  1789. --- a/src/process/_Fork.c
  1790. +++ b/src/process/_Fork.c
  1791. @@ -14,7 +14,6 @@ pid_t _Fork(void)
  1792. pid_t ret;
  1793. sigset_t set;
  1794. __block_all_sigs(&set);
  1795. - __aio_atfork(-1);
  1796. LOCK(__abort_lock);
  1797. #ifdef SYS_fork
  1798. ret = __syscall(SYS_fork);
  1799. @@ -32,7 +31,7 @@ pid_t _Fork(void)
  1800. if (libc.need_locks) libc.need_locks = -1;
  1801. }
  1802. UNLOCK(__abort_lock);
  1803. - __aio_atfork(!ret);
  1804. + if (!ret) __aio_atfork(1);
  1805. __restore_sigs(&set);
  1806. return __syscall_ret(ret);
  1807. }
  1808. diff --git a/src/process/aarch64/vfork.s b/src/process/aarch64/vfork.s
  1809. new file mode 100644
  1810. index 00000000..429bec8c
  1811. --- /dev/null
  1812. +++ b/src/process/aarch64/vfork.s
  1813. @@ -0,0 +1,9 @@
  1814. +.global vfork
  1815. +.type vfork,%function
  1816. +vfork:
  1817. + mov x8, 220 // SYS_clone
  1818. + mov x0, 0x4111 // SIGCHLD | CLONE_VM | CLONE_VFORK
  1819. + mov x1, 0
  1820. + svc 0
  1821. + .hidden __syscall_ret
  1822. + b __syscall_ret
  1823. diff --git a/src/process/fork.c b/src/process/fork.c
  1824. index 54bc2892..56f19313 100644
  1825. --- a/src/process/fork.c
  1826. +++ b/src/process/fork.c
  1827. @@ -9,7 +9,6 @@ static volatile int *const dummy_lockptr = 0;
  1828. weak_alias(dummy_lockptr, __at_quick_exit_lockptr);
  1829. weak_alias(dummy_lockptr, __atexit_lockptr);
  1830. -weak_alias(dummy_lockptr, __dlerror_lockptr);
  1831. weak_alias(dummy_lockptr, __gettext_lockptr);
  1832. weak_alias(dummy_lockptr, __locale_lockptr);
  1833. weak_alias(dummy_lockptr, __random_lockptr);
  1834. @@ -24,7 +23,6 @@ weak_alias(dummy_lockptr, __vmlock_lockptr);
  1835. static volatile int *const *const atfork_locks[] = {
  1836. &__at_quick_exit_lockptr,
  1837. &__atexit_lockptr,
  1838. - &__dlerror_lockptr,
  1839. &__gettext_lockptr,
  1840. &__locale_lockptr,
  1841. &__random_lockptr,
  1842. @@ -38,6 +36,8 @@ static volatile int *const *const atfork_locks[] = {
  1843. static void dummy(int x) { }
  1844. weak_alias(dummy, __fork_handler);
  1845. weak_alias(dummy, __malloc_atfork);
  1846. +weak_alias(dummy, __aio_atfork);
  1847. +weak_alias(dummy, __pthread_key_atfork);
  1848. weak_alias(dummy, __ldso_atfork);
  1849. static void dummy_0(void) { }
  1850. @@ -52,6 +52,8 @@ pid_t fork(void)
  1851. int need_locks = libc.need_locks > 0;
  1852. if (need_locks) {
  1853. __ldso_atfork(-1);
  1854. + __pthread_key_atfork(-1);
  1855. + __aio_atfork(-1);
  1856. __inhibit_ptc();
  1857. for (int i=0; i<sizeof atfork_locks/sizeof *atfork_locks; i++)
  1858. if (*atfork_locks[i]) LOCK(*atfork_locks[i]);
  1859. @@ -77,6 +79,8 @@ pid_t fork(void)
  1860. if (ret) UNLOCK(*atfork_locks[i]);
  1861. else **atfork_locks[i] = 0;
  1862. __release_ptc();
  1863. + if (ret) __aio_atfork(0);
  1864. + __pthread_key_atfork(!ret);
  1865. __ldso_atfork(!ret);
  1866. }
  1867. __restore_sigs(&set);
  1868. diff --git a/src/regex/glob.c b/src/regex/glob.c
  1869. index 9de080ed..a4906446 100644
  1870. --- a/src/regex/glob.c
  1871. +++ b/src/regex/glob.c
  1872. @@ -306,6 +306,3 @@ void globfree(glob_t *g)
  1873. g->gl_pathc = 0;
  1874. g->gl_pathv = NULL;
  1875. }
  1876. -
  1877. -weak_alias(glob, glob64);
  1878. -weak_alias(globfree, globfree64);
  1879. diff --git a/src/stat/__xstat.c b/src/stat/__xstat.c
  1880. index 630936a0..b4560df7 100644
  1881. --- a/src/stat/__xstat.c
  1882. +++ b/src/stat/__xstat.c
  1883. @@ -22,11 +22,6 @@ int __xstat(int ver, const char *path, struct stat *buf)
  1884. return stat(path, buf);
  1885. }
  1886. -weak_alias(__fxstat, __fxstat64);
  1887. -weak_alias(__fxstatat, __fxstatat64);
  1888. -weak_alias(__lxstat, __lxstat64);
  1889. -weak_alias(__xstat, __xstat64);
  1890. -
  1891. #endif
  1892. int __xmknod(int ver, const char *path, mode_t mode, dev_t *dev)
  1893. diff --git a/src/stat/fchmodat.c b/src/stat/fchmodat.c
  1894. index 4ee00b0a..bc581050 100644
  1895. --- a/src/stat/fchmodat.c
  1896. +++ b/src/stat/fchmodat.c
  1897. @@ -2,7 +2,6 @@
  1898. #include <fcntl.h>
  1899. #include <errno.h>
  1900. #include "syscall.h"
  1901. -#include "kstat.h"
  1902. int fchmodat(int fd, const char *path, mode_t mode, int flag)
  1903. {
  1904. @@ -11,12 +10,12 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag)
  1905. if (flag != AT_SYMLINK_NOFOLLOW)
  1906. return __syscall_ret(-EINVAL);
  1907. - struct kstat st;
  1908. + struct stat st;
  1909. int ret, fd2;
  1910. char proc[15+3*sizeof(int)];
  1911. - if ((ret = __syscall(SYS_fstatat, fd, path, &st, flag)))
  1912. - return __syscall_ret(ret);
  1913. + if (fstatat(fd, path, &st, flag))
  1914. + return -1;
  1915. if (S_ISLNK(st.st_mode))
  1916. return __syscall_ret(-EOPNOTSUPP);
  1917. @@ -27,12 +26,12 @@ int fchmodat(int fd, const char *path, mode_t mode, int flag)
  1918. }
  1919. __procfdname(proc, fd2);
  1920. - ret = __syscall(SYS_fstatat, AT_FDCWD, proc, &st, 0);
  1921. + ret = stat(proc, &st);
  1922. if (!ret) {
  1923. - if (S_ISLNK(st.st_mode)) ret = -EOPNOTSUPP;
  1924. - else ret = __syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
  1925. + if (S_ISLNK(st.st_mode)) ret = __syscall_ret(-EOPNOTSUPP);
  1926. + else ret = syscall(SYS_fchmodat, AT_FDCWD, proc, mode);
  1927. }
  1928. __syscall(SYS_close, fd2);
  1929. - return __syscall_ret(ret);
  1930. + return ret;
  1931. }
  1932. diff --git a/src/stat/fstat.c b/src/stat/fstat.c
  1933. index 9bbb46de..fd28b8ac 100644
  1934. --- a/src/stat/fstat.c
  1935. +++ b/src/stat/fstat.c
  1936. @@ -4,12 +4,10 @@
  1937. #include <fcntl.h>
  1938. #include "syscall.h"
  1939. -int fstat(int fd, struct stat *st)
  1940. +int __fstat(int fd, struct stat *st)
  1941. {
  1942. if (fd<0) return __syscall_ret(-EBADF);
  1943. - return fstatat(fd, "", st, AT_EMPTY_PATH);
  1944. + return __fstatat(fd, "", st, AT_EMPTY_PATH);
  1945. }
  1946. -#if !_REDIR_TIME64
  1947. -weak_alias(fstat, fstat64);
  1948. -#endif
  1949. +weak_alias(__fstat, fstat);
  1950. diff --git a/src/stat/fstatat.c b/src/stat/fstatat.c
  1951. index de165b5c..04506375 100644
  1952. --- a/src/stat/fstatat.c
  1953. +++ b/src/stat/fstatat.c
  1954. @@ -6,7 +6,6 @@
  1955. #include <stdint.h>
  1956. #include <sys/sysmacros.h>
  1957. #include "syscall.h"
  1958. -#include "kstat.h"
  1959. struct statx {
  1960. uint32_t stx_mask;
  1961. @@ -69,6 +68,10 @@ static int fstatat_statx(int fd, const char *restrict path, struct stat *restric
  1962. return 0;
  1963. }
  1964. +#ifdef SYS_fstatat
  1965. +
  1966. +#include "kstat.h"
  1967. +
  1968. static int fstatat_kstat(int fd, const char *restrict path, struct stat *restrict st, int flag)
  1969. {
  1970. int ret;
  1971. @@ -130,18 +133,21 @@ static int fstatat_kstat(int fd, const char *restrict path, struct stat *restric
  1972. return 0;
  1973. }
  1974. +#endif
  1975. -int fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag)
  1976. +int __fstatat(int fd, const char *restrict path, struct stat *restrict st, int flag)
  1977. {
  1978. int ret;
  1979. +#ifdef SYS_fstatat
  1980. if (sizeof((struct kstat){0}.st_atime_sec) < sizeof(time_t)) {
  1981. ret = fstatat_statx(fd, path, st, flag);
  1982. if (ret!=-ENOSYS) return __syscall_ret(ret);
  1983. }
  1984. ret = fstatat_kstat(fd, path, st, flag);
  1985. +#else
  1986. + ret = fstatat_statx(fd, path, st, flag);
  1987. +#endif
  1988. return __syscall_ret(ret);
  1989. }
  1990. -#if !_REDIR_TIME64
  1991. -weak_alias(fstatat, fstatat64);
  1992. -#endif
  1993. +weak_alias(__fstatat, fstatat);
  1994. diff --git a/src/stat/lstat.c b/src/stat/lstat.c
  1995. index 6fe004de..6822fcae 100644
  1996. --- a/src/stat/lstat.c
  1997. +++ b/src/stat/lstat.c
  1998. @@ -5,7 +5,3 @@ int lstat(const char *restrict path, struct stat *restrict buf)
  1999. {
  2000. return fstatat(AT_FDCWD, path, buf, AT_SYMLINK_NOFOLLOW);
  2001. }
  2002. -
  2003. -#if !_REDIR_TIME64
  2004. -weak_alias(lstat, lstat64);
  2005. -#endif
  2006. diff --git a/src/stat/stat.c b/src/stat/stat.c
  2007. index ea70efc4..23570e7a 100644
  2008. --- a/src/stat/stat.c
  2009. +++ b/src/stat/stat.c
  2010. @@ -5,7 +5,3 @@ int stat(const char *restrict path, struct stat *restrict buf)
  2011. {
  2012. return fstatat(AT_FDCWD, path, buf, 0);
  2013. }
  2014. -
  2015. -#if !_REDIR_TIME64
  2016. -weak_alias(stat, stat64);
  2017. -#endif
  2018. diff --git a/src/stat/statvfs.c b/src/stat/statvfs.c
  2019. index f65d1b54..bfbb5fee 100644
  2020. --- a/src/stat/statvfs.c
  2021. +++ b/src/stat/statvfs.c
  2022. @@ -56,8 +56,3 @@ int fstatvfs(int fd, struct statvfs *buf)
  2023. fixup(buf, &kbuf);
  2024. return 0;
  2025. }
  2026. -
  2027. -weak_alias(statvfs, statvfs64);
  2028. -weak_alias(statfs, statfs64);
  2029. -weak_alias(fstatvfs, fstatvfs64);
  2030. -weak_alias(fstatfs, fstatfs64);
  2031. diff --git a/src/stdio/fgetpos.c b/src/stdio/fgetpos.c
  2032. index 50813d2c..392f7323 100644
  2033. --- a/src/stdio/fgetpos.c
  2034. +++ b/src/stdio/fgetpos.c
  2035. @@ -7,5 +7,3 @@ int fgetpos(FILE *restrict f, fpos_t *restrict pos)
  2036. *(long long *)pos = off;
  2037. return 0;
  2038. }
  2039. -
  2040. -weak_alias(fgetpos, fgetpos64);
  2041. diff --git a/src/stdio/fgets.c b/src/stdio/fgets.c
  2042. index 6171f398..4a100b39 100644
  2043. --- a/src/stdio/fgets.c
  2044. +++ b/src/stdio/fgets.c
  2045. @@ -12,13 +12,14 @@ char *fgets(char *restrict s, int n, FILE *restrict f)
  2046. FLOCK(f);
  2047. - if (n--<=1) {
  2048. + if (n<=1) {
  2049. f->mode |= f->mode-1;
  2050. FUNLOCK(f);
  2051. - if (n) return 0;
  2052. + if (n<1) return 0;
  2053. *s = 0;
  2054. return s;
  2055. }
  2056. + n--;
  2057. while (n) {
  2058. if (f->rpos != f->rend) {
  2059. diff --git a/src/stdio/fopen.c b/src/stdio/fopen.c
  2060. index e1b91e12..80bc341e 100644
  2061. --- a/src/stdio/fopen.c
  2062. +++ b/src/stdio/fopen.c
  2063. @@ -29,5 +29,3 @@ FILE *fopen(const char *restrict filename, const char *restrict mode)
  2064. __syscall(SYS_close, fd);
  2065. return 0;
  2066. }
  2067. -
  2068. -weak_alias(fopen, fopen64);
  2069. diff --git a/src/stdio/freopen.c b/src/stdio/freopen.c
  2070. index 615d4b47..1641a4c5 100644
  2071. --- a/src/stdio/freopen.c
  2072. +++ b/src/stdio/freopen.c
  2073. @@ -40,6 +40,8 @@ FILE *freopen(const char *restrict filename, const char *restrict mode, FILE *re
  2074. fclose(f2);
  2075. }
  2076. + f->mode = 0;
  2077. + f->locale = 0;
  2078. FUNLOCK(f);
  2079. return f;
  2080. @@ -49,5 +51,3 @@ fail:
  2081. fclose(f);
  2082. return NULL;
  2083. }
  2084. -
  2085. -weak_alias(freopen, freopen64);
  2086. diff --git a/src/stdio/fseek.c b/src/stdio/fseek.c
  2087. index c07f7e95..c7425802 100644
  2088. --- a/src/stdio/fseek.c
  2089. +++ b/src/stdio/fseek.c
  2090. @@ -46,5 +46,3 @@ int fseek(FILE *f, long off, int whence)
  2091. }
  2092. weak_alias(__fseeko, fseeko);
  2093. -
  2094. -weak_alias(fseeko, fseeko64);
  2095. diff --git a/src/stdio/fsetpos.c b/src/stdio/fsetpos.c
  2096. index 77ab8d82..779cb3cc 100644
  2097. --- a/src/stdio/fsetpos.c
  2098. +++ b/src/stdio/fsetpos.c
  2099. @@ -4,5 +4,3 @@ int fsetpos(FILE *f, const fpos_t *pos)
  2100. {
  2101. return __fseeko(f, *(const long long *)pos, SEEK_SET);
  2102. }
  2103. -
  2104. -weak_alias(fsetpos, fsetpos64);
  2105. diff --git a/src/stdio/ftell.c b/src/stdio/ftell.c
  2106. index 1a2afbbc..1e1a08d8 100644
  2107. --- a/src/stdio/ftell.c
  2108. +++ b/src/stdio/ftell.c
  2109. @@ -37,5 +37,3 @@ long ftell(FILE *f)
  2110. }
  2111. weak_alias(__ftello, ftello);
  2112. -
  2113. -weak_alias(ftello, ftello64);
  2114. diff --git a/src/stdio/open_wmemstream.c b/src/stdio/open_wmemstream.c
  2115. index ed1b561d..b8ae4a79 100644
  2116. --- a/src/stdio/open_wmemstream.c
  2117. +++ b/src/stdio/open_wmemstream.c
  2118. @@ -40,8 +40,12 @@ fail:
  2119. static size_t wms_write(FILE *f, const unsigned char *buf, size_t len)
  2120. {
  2121. struct cookie *c = f->cookie;
  2122. - size_t len2;
  2123. + size_t len2 = f->wpos - f->wbase;
  2124. wchar_t *newbuf;
  2125. + if (len2) {
  2126. + f->wpos = f->wbase;
  2127. + if (wms_write(f, f->wbase, len2) < len2) return 0;
  2128. + }
  2129. if (len + c->pos >= c->space) {
  2130. len2 = 2*c->space+1 | c->pos+len+1;
  2131. if (len2 > SSIZE_MAX/4) return 0;
  2132. diff --git a/src/stdio/tempnam.c b/src/stdio/tempnam.c
  2133. index 565df6b6..0c65b1f0 100644
  2134. --- a/src/stdio/tempnam.c
  2135. +++ b/src/stdio/tempnam.c
  2136. @@ -6,7 +6,6 @@
  2137. #include <string.h>
  2138. #include <stdlib.h>
  2139. #include "syscall.h"
  2140. -#include "kstat.h"
  2141. #define MAXTRIES 100
  2142. @@ -37,11 +36,10 @@ char *tempnam(const char *dir, const char *pfx)
  2143. for (try=0; try<MAXTRIES; try++) {
  2144. __randname(s+l-6);
  2145. -#ifdef SYS_lstat
  2146. - r = __syscall(SYS_lstat, s, &(struct kstat){0});
  2147. +#ifdef SYS_readlink
  2148. + r = __syscall(SYS_readlink, s, (char[1]){0}, 1);
  2149. #else
  2150. - r = __syscall(SYS_fstatat, AT_FDCWD, s,
  2151. - &(struct kstat){0}, AT_SYMLINK_NOFOLLOW);
  2152. + r = __syscall(SYS_readlinkat, AT_FDCWD, s, (char[1]){0}, 1);
  2153. #endif
  2154. if (r == -ENOENT) return strdup(s);
  2155. }
  2156. diff --git a/src/stdio/tmpfile.c b/src/stdio/tmpfile.c
  2157. index ae493987..2fa8803f 100644
  2158. --- a/src/stdio/tmpfile.c
  2159. +++ b/src/stdio/tmpfile.c
  2160. @@ -27,5 +27,3 @@ FILE *tmpfile(void)
  2161. }
  2162. return 0;
  2163. }
  2164. -
  2165. -weak_alias(tmpfile, tmpfile64);
  2166. diff --git a/src/stdio/tmpnam.c b/src/stdio/tmpnam.c
  2167. index d667a836..71dc8bb1 100644
  2168. --- a/src/stdio/tmpnam.c
  2169. +++ b/src/stdio/tmpnam.c
  2170. @@ -5,7 +5,6 @@
  2171. #include <string.h>
  2172. #include <stdlib.h>
  2173. #include "syscall.h"
  2174. -#include "kstat.h"
  2175. #define MAXTRIES 100
  2176. @@ -17,11 +16,10 @@ char *tmpnam(char *buf)
  2177. int r;
  2178. for (try=0; try<MAXTRIES; try++) {
  2179. __randname(s+12);
  2180. -#ifdef SYS_lstat
  2181. - r = __syscall(SYS_lstat, s, &(struct kstat){0});
  2182. +#ifdef SYS_readlink
  2183. + r = __syscall(SYS_readlink, s, (char[1]){0}, 1);
  2184. #else
  2185. - r = __syscall(SYS_fstatat, AT_FDCWD, s,
  2186. - &(struct kstat){0}, AT_SYMLINK_NOFOLLOW);
  2187. + r = __syscall(SYS_readlinkat, AT_FDCWD, s, (char[1]){0}, 1);
  2188. #endif
  2189. if (r == -ENOENT) return strcpy(buf ? buf : internal, s);
  2190. }
  2191. diff --git a/src/stdlib/qsort_nr.c b/src/stdlib/qsort_nr.c
  2192. index efe7ccec..8ffe71d0 100644
  2193. --- a/src/stdlib/qsort_nr.c
  2194. +++ b/src/stdlib/qsort_nr.c
  2195. @@ -10,5 +10,5 @@ static int wrapper_cmp(const void *v1, const void *v2, void *cmp)
  2196. void qsort(void *base, size_t nel, size_t width, cmpfun cmp)
  2197. {
  2198. - __qsort_r(base, nel, width, wrapper_cmp, cmp);
  2199. + __qsort_r(base, nel, width, wrapper_cmp, (void *)cmp);
  2200. }
  2201. diff --git a/src/temp/__randname.c b/src/temp/__randname.c
  2202. index 2bce37a0..e9b970f1 100644
  2203. --- a/src/temp/__randname.c
  2204. +++ b/src/temp/__randname.c
  2205. @@ -1,5 +1,6 @@
  2206. #include <time.h>
  2207. #include <stdint.h>
  2208. +#include "pthread_impl.h"
  2209. /* This assumes that a check for the
  2210. template size has already been made */
  2211. @@ -10,7 +11,7 @@ char *__randname(char *template)
  2212. unsigned long r;
  2213. __clock_gettime(CLOCK_REALTIME, &ts);
  2214. - r = ts.tv_nsec*65537 ^ (uintptr_t)&ts / 16 + (uintptr_t)template;
  2215. + r = ts.tv_sec + ts.tv_nsec + __pthread_self()->tid * 65537UL;
  2216. for (i=0; i<6; i++, r>>=5)
  2217. template[i] = 'A'+(r&15)+(r&16)*2;
  2218. diff --git a/src/temp/mkostemp.c b/src/temp/mkostemp.c
  2219. index d8dcb805..e3dfdd91 100644
  2220. --- a/src/temp/mkostemp.c
  2221. +++ b/src/temp/mkostemp.c
  2222. @@ -5,5 +5,3 @@ int mkostemp(char *template, int flags)
  2223. {
  2224. return __mkostemps(template, 0, flags);
  2225. }
  2226. -
  2227. -weak_alias(mkostemp, mkostemp64);
  2228. diff --git a/src/temp/mkostemps.c b/src/temp/mkostemps.c
  2229. index ef24eeae..093d2380 100644
  2230. --- a/src/temp/mkostemps.c
  2231. +++ b/src/temp/mkostemps.c
  2232. @@ -26,4 +26,3 @@ int __mkostemps(char *template, int len, int flags)
  2233. }
  2234. weak_alias(__mkostemps, mkostemps);
  2235. -weak_alias(__mkostemps, mkostemps64);
  2236. diff --git a/src/temp/mkstemp.c b/src/temp/mkstemp.c
  2237. index 166b8afe..76c835bb 100644
  2238. --- a/src/temp/mkstemp.c
  2239. +++ b/src/temp/mkstemp.c
  2240. @@ -4,5 +4,3 @@ int mkstemp(char *template)
  2241. {
  2242. return __mkostemps(template, 0, 0);
  2243. }
  2244. -
  2245. -weak_alias(mkstemp, mkstemp64);
  2246. diff --git a/src/temp/mkstemps.c b/src/temp/mkstemps.c
  2247. index 6b7531b5..f8eabfec 100644
  2248. --- a/src/temp/mkstemps.c
  2249. +++ b/src/temp/mkstemps.c
  2250. @@ -5,5 +5,3 @@ int mkstemps(char *template, int len)
  2251. {
  2252. return __mkostemps(template, len, 0);
  2253. }
  2254. -
  2255. -weak_alias(mkstemps, mkstemps64);
  2256. diff --git a/src/thread/pthread_cancel.c b/src/thread/pthread_cancel.c
  2257. index 2f9d5e97..2d3a98ea 100644
  2258. --- a/src/thread/pthread_cancel.c
  2259. +++ b/src/thread/pthread_cancel.c
  2260. @@ -77,7 +77,7 @@ void __testcancel()
  2261. static void init_cancellation()
  2262. {
  2263. struct sigaction sa = {
  2264. - .sa_flags = SA_SIGINFO | SA_RESTART,
  2265. + .sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK,
  2266. .sa_sigaction = cancel_handler
  2267. };
  2268. memset(&sa.sa_mask, -1, _NSIG/8);
  2269. diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
  2270. index 6f187ee8..087f6206 100644
  2271. --- a/src/thread/pthread_create.c
  2272. +++ b/src/thread/pthread_create.c
  2273. @@ -107,6 +107,16 @@ _Noreturn void __pthread_exit(void *result)
  2274. /* At this point we are committed to thread termination. */
  2275. + /* After the kernel thread exits, its tid may be reused. Clear it
  2276. + * to prevent inadvertent use and inform functions that would use
  2277. + * it that it's no longer available. At this point the killlock
  2278. + * may be released, since functions that use it will consistently
  2279. + * see the thread as having exited. Release it now so that no
  2280. + * remaining locks (except thread list) are held if we end up
  2281. + * resetting need_locks below. */
  2282. + self->tid = 0;
  2283. + UNLOCK(self->killlock);
  2284. +
  2285. /* Process robust list in userspace to handle non-pshared mutexes
  2286. * and the detached thread case where the robust list head will
  2287. * be invalid when the kernel would process it. */
  2288. @@ -159,12 +169,6 @@ _Noreturn void __pthread_exit(void *result)
  2289. a_store(&self->detach_state, DT_EXITED);
  2290. __wake(&self->detach_state, 1, 1);
  2291. - /* After the kernel thread exits, its tid may be reused. Clear it
  2292. - * to prevent inadvertent use and inform functions that would use
  2293. - * it that it's no longer available. */
  2294. - self->tid = 0;
  2295. - UNLOCK(self->killlock);
  2296. -
  2297. for (;;) __syscall(SYS_exit, 0);
  2298. }
  2299. diff --git a/src/thread/pthread_key_create.c b/src/thread/pthread_key_create.c
  2300. index d1120941..39770c7a 100644
  2301. --- a/src/thread/pthread_key_create.c
  2302. +++ b/src/thread/pthread_key_create.c
  2303. @@ -1,4 +1,5 @@
  2304. #include "pthread_impl.h"
  2305. +#include "fork_impl.h"
  2306. volatile size_t __pthread_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX;
  2307. void *__pthread_tsd_main[PTHREAD_KEYS_MAX] = { 0 };
  2308. @@ -20,6 +21,13 @@ static void dummy_0(void)
  2309. weak_alias(dummy_0, __tl_lock);
  2310. weak_alias(dummy_0, __tl_unlock);
  2311. +void __pthread_key_atfork(int who)
  2312. +{
  2313. + if (who<0) __pthread_rwlock_rdlock(&key_lock);
  2314. + else if (!who) __pthread_rwlock_unlock(&key_lock);
  2315. + else key_lock = (pthread_rwlock_t)PTHREAD_RWLOCK_INITIALIZER;
  2316. +}
  2317. +
  2318. int __pthread_key_create(pthread_key_t *k, void (*dtor)(void *))
  2319. {
  2320. pthread_t self = __pthread_self();
  2321. diff --git a/src/thread/synccall.c b/src/thread/synccall.c
  2322. index d58c851f..a6b177c0 100644
  2323. --- a/src/thread/synccall.c
  2324. +++ b/src/thread/synccall.c
  2325. @@ -45,7 +45,7 @@ void __synccall(void (*func)(void *), void *ctx)
  2326. {
  2327. sigset_t oldmask;
  2328. int cs, i, r;
  2329. - struct sigaction sa = { .sa_flags = SA_RESTART, .sa_handler = handler };
  2330. + struct sigaction sa = { .sa_flags = SA_RESTART | SA_ONSTACK, .sa_handler = handler };
  2331. pthread_t self = __pthread_self(), td;
  2332. int count = 0;
  2333. diff --git a/src/time/__map_file.c b/src/time/__map_file.c
  2334. index d3cefa82..c2b29fe8 100644
  2335. --- a/src/time/__map_file.c
  2336. +++ b/src/time/__map_file.c
  2337. @@ -2,15 +2,14 @@
  2338. #include <fcntl.h>
  2339. #include <sys/stat.h>
  2340. #include "syscall.h"
  2341. -#include "kstat.h"
  2342. const char unsigned *__map_file(const char *pathname, size_t *size)
  2343. {
  2344. - struct kstat st;
  2345. + struct stat st;
  2346. const unsigned char *map = MAP_FAILED;
  2347. int fd = sys_open(pathname, O_RDONLY|O_CLOEXEC|O_NONBLOCK);
  2348. if (fd < 0) return 0;
  2349. - if (!syscall(SYS_fstat, fd, &st)) {
  2350. + if (!__fstat(fd, &st)) {
  2351. map = __mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
  2352. *size = st.st_size;
  2353. }
  2354. diff --git a/src/time/clock_getcpuclockid.c b/src/time/clock_getcpuclockid.c
  2355. index 8a0e2d4c..bce1e8ab 100644
  2356. --- a/src/time/clock_getcpuclockid.c
  2357. +++ b/src/time/clock_getcpuclockid.c
  2358. @@ -8,6 +8,7 @@ int clock_getcpuclockid(pid_t pid, clockid_t *clk)
  2359. struct timespec ts;
  2360. clockid_t id = (-pid-1)*8U + 2;
  2361. int ret = __syscall(SYS_clock_getres, id, &ts);
  2362. + if (ret == -EINVAL) ret = -ESRCH;
  2363. if (ret) return -ret;
  2364. *clk = id;
  2365. return 0;
  2366. diff --git a/src/time/clock_gettime.c b/src/time/clock_gettime.c
  2367. index 3e1d0975..4d2ec22f 100644
  2368. --- a/src/time/clock_gettime.c
  2369. +++ b/src/time/clock_gettime.c
  2370. @@ -42,6 +42,9 @@ static int cgt_init(clockid_t clk, struct timespec *ts)
  2371. p = cgt_time32_wrap;
  2372. }
  2373. }
  2374. +#ifdef VDSO_CGT_WORKAROUND
  2375. + if (!__vdsosym(VDSO_CGT32_VER, VDSO_CGT32_SYM)) p = 0;
  2376. +#endif
  2377. #endif
  2378. int (*f)(clockid_t, struct timespec *) =
  2379. (int (*)(clockid_t, struct timespec *))p;
  2380. @@ -80,10 +83,12 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
  2381. return __syscall_ret(r);
  2382. long ts32[2];
  2383. r = __syscall(SYS_clock_gettime, clk, ts32);
  2384. +#ifdef SYS_gettimeofday
  2385. if (r==-ENOSYS && clk==CLOCK_REALTIME) {
  2386. r = __syscall(SYS_gettimeofday, ts32, 0);
  2387. ts32[1] *= 1000;
  2388. }
  2389. +#endif
  2390. if (!r) {
  2391. ts->tv_sec = ts32[0];
  2392. ts->tv_nsec = ts32[1];
  2393. @@ -92,6 +97,7 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
  2394. return __syscall_ret(r);
  2395. #else
  2396. r = __syscall(SYS_clock_gettime, clk, ts);
  2397. +#ifdef SYS_gettimeofday
  2398. if (r == -ENOSYS) {
  2399. if (clk == CLOCK_REALTIME) {
  2400. __syscall(SYS_gettimeofday, ts, 0);
  2401. @@ -100,6 +106,7 @@ int __clock_gettime(clockid_t clk, struct timespec *ts)
  2402. }
  2403. r = -EINVAL;
  2404. }
  2405. +#endif
  2406. return __syscall_ret(r);
  2407. #endif
  2408. }
  2409. diff --git a/src/time/timer_create.c b/src/time/timer_create.c
  2410. index 4bef2390..cd32c945 100644
  2411. --- a/src/time/timer_create.c
  2412. +++ b/src/time/timer_create.c
  2413. @@ -43,6 +43,8 @@ static void *start(void *arg)
  2414. union sigval val = args->sev->sigev_value;
  2415. pthread_barrier_wait(&args->b);
  2416. + if (self->cancel)
  2417. + return 0;
  2418. for (;;) {
  2419. siginfo_t si;
  2420. while (sigwaitinfo(SIGTIMER_SET, &si) < 0);
  2421. @@ -113,8 +115,10 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
  2422. ksev.sigev_signo = SIGTIMER;
  2423. ksev.sigev_notify = SIGEV_THREAD_ID;
  2424. ksev.sigev_tid = td->tid;
  2425. - if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0)
  2426. + if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0) {
  2427. timerid = -1;
  2428. + td->cancel = 1;
  2429. + }
  2430. td->timer_id = timerid;
  2431. pthread_barrier_wait(&args.b);
  2432. if (timerid < 0) return -1;
  2433. diff --git a/src/unistd/ftruncate.c b/src/unistd/ftruncate.c
  2434. index b41be0fa..54ff34bc 100644
  2435. --- a/src/unistd/ftruncate.c
  2436. +++ b/src/unistd/ftruncate.c
  2437. @@ -5,5 +5,3 @@ int ftruncate(int fd, off_t length)
  2438. {
  2439. return syscall(SYS_ftruncate, fd, __SYSCALL_LL_O(length));
  2440. }
  2441. -
  2442. -weak_alias(ftruncate, ftruncate64);
  2443. diff --git a/src/unistd/lseek.c b/src/unistd/lseek.c
  2444. index b4984f3e..f5b66682 100644
  2445. --- a/src/unistd/lseek.c
  2446. +++ b/src/unistd/lseek.c
  2447. @@ -12,4 +12,3 @@ off_t __lseek(int fd, off_t offset, int whence)
  2448. }
  2449. weak_alias(__lseek, lseek);
  2450. -weak_alias(__lseek, lseek64);
  2451. diff --git a/src/unistd/mipsn32/lseek.c b/src/unistd/mipsn32/lseek.c
  2452. index 60e74a51..0f6cbcaa 100644
  2453. --- a/src/unistd/mipsn32/lseek.c
  2454. +++ b/src/unistd/mipsn32/lseek.c
  2455. @@ -17,4 +17,3 @@ off_t __lseek(int fd, off_t offset, int whence)
  2456. }
  2457. weak_alias(__lseek, lseek);
  2458. -weak_alias(__lseek, lseek64);
  2459. diff --git a/src/unistd/pread.c b/src/unistd/pread.c
  2460. index 5681b045..b03fb0ad 100644
  2461. --- a/src/unistd/pread.c
  2462. +++ b/src/unistd/pread.c
  2463. @@ -5,5 +5,3 @@ ssize_t pread(int fd, void *buf, size_t size, off_t ofs)
  2464. {
  2465. return syscall_cp(SYS_pread, fd, buf, size, __SYSCALL_LL_PRW(ofs));
  2466. }
  2467. -
  2468. -weak_alias(pread, pread64);
  2469. diff --git a/src/unistd/preadv.c b/src/unistd/preadv.c
  2470. index 8376d60f..890ab403 100644
  2471. --- a/src/unistd/preadv.c
  2472. +++ b/src/unistd/preadv.c
  2473. @@ -8,5 +8,3 @@ ssize_t preadv(int fd, const struct iovec *iov, int count, off_t ofs)
  2474. return syscall_cp(SYS_preadv, fd, iov, count,
  2475. (long)(ofs), (long)(ofs>>32));
  2476. }
  2477. -
  2478. -weak_alias(preadv, preadv64);
  2479. diff --git a/src/unistd/pwrite.c b/src/unistd/pwrite.c
  2480. index ca376576..869b69f0 100644
  2481. --- a/src/unistd/pwrite.c
  2482. +++ b/src/unistd/pwrite.c
  2483. @@ -5,5 +5,3 @@ ssize_t pwrite(int fd, const void *buf, size_t size, off_t ofs)
  2484. {
  2485. return syscall_cp(SYS_pwrite, fd, buf, size, __SYSCALL_LL_PRW(ofs));
  2486. }
  2487. -
  2488. -weak_alias(pwrite, pwrite64);
  2489. diff --git a/src/unistd/pwritev.c b/src/unistd/pwritev.c
  2490. index f5a612c4..becf9deb 100644
  2491. --- a/src/unistd/pwritev.c
  2492. +++ b/src/unistd/pwritev.c
  2493. @@ -8,5 +8,3 @@ ssize_t pwritev(int fd, const struct iovec *iov, int count, off_t ofs)
  2494. return syscall_cp(SYS_pwritev, fd, iov, count,
  2495. (long)(ofs), (long)(ofs>>32));
  2496. }
  2497. -
  2498. -weak_alias(pwritev, pwritev64);
  2499. diff --git a/src/unistd/truncate.c b/src/unistd/truncate.c
  2500. index 97296800..077351e1 100644
  2501. --- a/src/unistd/truncate.c
  2502. +++ b/src/unistd/truncate.c
  2503. @@ -5,5 +5,3 @@ int truncate(const char *path, off_t length)
  2504. {
  2505. return syscall(SYS_truncate, path, __SYSCALL_LL_O(length));
  2506. }
  2507. -
  2508. -weak_alias(truncate, truncate64);
  2509. diff --git a/src/unistd/x32/lseek.c b/src/unistd/x32/lseek.c
  2510. index 32636429..5f93292f 100644
  2511. --- a/src/unistd/x32/lseek.c
  2512. +++ b/src/unistd/x32/lseek.c
  2513. @@ -12,4 +12,3 @@ off_t __lseek(int fd, off_t offset, int whence)
  2514. }
  2515. weak_alias(__lseek, lseek);
  2516. -weak_alias(__lseek, lseek64);