branch-updates.diff 142 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098
  1. diff --git a/INSTALL b/INSTALL
  2. index 22477b6b..c583691d 100644
  3. --- a/INSTALL
  4. +++ b/INSTALL
  5. @@ -86,7 +86,7 @@ and ABI combinations:
  6. * SuperH (SH)
  7. * Standard ELF ABI or FDPIC ABI (shared-text without MMU)
  8. - * Little-endian by default; big-engian variant also supported
  9. + * Little-endian by default; big-endian variant also supported
  10. * Full FPU ABI or soft-float ABI is supported, but the
  11. single-precision-only FPU ABI is not
  12. diff --git a/arch/aarch64/bits/hwcap.h b/arch/aarch64/bits/hwcap.h
  13. index a7484028..7ab73f99 100644
  14. --- a/arch/aarch64/bits/hwcap.h
  15. +++ b/arch/aarch64/bits/hwcap.h
  16. @@ -38,3 +38,13 @@
  17. #define HWCAP2_SVEBITPERM (1 << 4)
  18. #define HWCAP2_SVESHA3 (1 << 5)
  19. #define HWCAP2_SVESM4 (1 << 6)
  20. +#define HWCAP2_FLAGM2 (1 << 7)
  21. +#define HWCAP2_FRINT (1 << 8)
  22. +#define HWCAP2_SVEI8MM (1 << 9)
  23. +#define HWCAP2_SVEF32MM (1 << 10)
  24. +#define HWCAP2_SVEF64MM (1 << 11)
  25. +#define HWCAP2_SVEBF16 (1 << 12)
  26. +#define HWCAP2_I8MM (1 << 13)
  27. +#define HWCAP2_BF16 (1 << 14)
  28. +#define HWCAP2_DGH (1 << 15)
  29. +#define HWCAP2_RNG (1 << 16)
  30. diff --git a/arch/aarch64/bits/signal.h b/arch/aarch64/bits/signal.h
  31. index b71261f5..5098c734 100644
  32. --- a/arch/aarch64/bits/signal.h
  33. +++ b/arch/aarch64/bits/signal.h
  34. @@ -11,7 +11,7 @@ typedef unsigned long greg_t;
  35. typedef unsigned long gregset_t[34];
  36. typedef struct {
  37. - long double vregs[32];
  38. + __uint128_t vregs[32];
  39. unsigned int fpsr;
  40. unsigned int fpcr;
  41. } fpregset_t;
  42. @@ -34,7 +34,7 @@ struct fpsimd_context {
  43. struct _aarch64_ctx head;
  44. unsigned int fpsr;
  45. unsigned int fpcr;
  46. - long double vregs[32];
  47. + __uint128_t vregs[32];
  48. };
  49. struct esr_context {
  50. struct _aarch64_ctx head;
  51. diff --git a/arch/aarch64/bits/syscall.h.in b/arch/aarch64/bits/syscall.h.in
  52. index 93648afd..f9457c18 100644
  53. --- a/arch/aarch64/bits/syscall.h.in
  54. +++ b/arch/aarch64/bits/syscall.h.in
  55. @@ -289,4 +289,8 @@
  56. #define __NR_fspick 433
  57. #define __NR_pidfd_open 434
  58. #define __NR_clone3 435
  59. +#define __NR_close_range 436
  60. +#define __NR_openat2 437
  61. +#define __NR_pidfd_getfd 438
  62. +#define __NR_faccessat2 439
  63. diff --git a/arch/aarch64/bits/user.h b/arch/aarch64/bits/user.h
  64. index d12cdf7f..8a1002aa 100644
  65. --- a/arch/aarch64/bits/user.h
  66. +++ b/arch/aarch64/bits/user.h
  67. @@ -6,7 +6,7 @@ struct user_regs_struct {
  68. };
  69. struct user_fpsimd_struct {
  70. - long double vregs[32];
  71. + __uint128_t vregs[32];
  72. unsigned int fpsr;
  73. unsigned int fpcr;
  74. };
  75. diff --git a/arch/aarch64/pthread_arch.h b/arch/aarch64/pthread_arch.h
  76. index e64b126d..3909616c 100644
  77. --- a/arch/aarch64/pthread_arch.h
  78. +++ b/arch/aarch64/pthread_arch.h
  79. @@ -1,12 +1,11 @@
  80. -static inline struct pthread *__pthread_self()
  81. +static inline uintptr_t __get_tp()
  82. {
  83. - char *self;
  84. - __asm__ ("mrs %0,tpidr_el0" : "=r"(self));
  85. - return (void*)(self - sizeof(struct pthread));
  86. + uintptr_t tp;
  87. + __asm__ ("mrs %0,tpidr_el0" : "=r"(tp));
  88. + return tp;
  89. }
  90. #define TLS_ABOVE_TP
  91. #define GAP_ABOVE_TP 16
  92. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
  93. #define MC_PC pc
  94. diff --git a/arch/arm/bits/syscall.h.in b/arch/arm/bits/syscall.h.in
  95. index 11d67763..7e2fc266 100644
  96. --- a/arch/arm/bits/syscall.h.in
  97. +++ b/arch/arm/bits/syscall.h.in
  98. @@ -389,6 +389,10 @@
  99. #define __NR_fspick 433
  100. #define __NR_pidfd_open 434
  101. #define __NR_clone3 435
  102. +#define __NR_close_range 436
  103. +#define __NR_openat2 437
  104. +#define __NR_pidfd_getfd 438
  105. +#define __NR_faccessat2 439
  106. #define __ARM_NR_breakpoint 0x0f0001
  107. #define __ARM_NR_cacheflush 0x0f0002
  108. diff --git a/arch/arm/pthread_arch.h b/arch/arm/pthread_arch.h
  109. index e689ea21..157e2eae 100644
  110. --- a/arch/arm/pthread_arch.h
  111. +++ b/arch/arm/pthread_arch.h
  112. @@ -1,11 +1,11 @@
  113. #if ((__ARM_ARCH_6K__ || __ARM_ARCH_6KZ__ || __ARM_ARCH_6ZK__) && !__thumb__) \
  114. || __ARM_ARCH_7A__ || __ARM_ARCH_7R__ || __ARM_ARCH >= 7
  115. -static inline pthread_t __pthread_self()
  116. +static inline uintptr_t __get_tp()
  117. {
  118. - char *p;
  119. - __asm__ ( "mrc p15,0,%0,c13,c0,3" : "=r"(p) );
  120. - return (void *)(p-sizeof(struct pthread));
  121. + uintptr_t tp;
  122. + __asm__ ( "mrc p15,0,%0,c13,c0,3" : "=r"(tp) );
  123. + return tp;
  124. }
  125. #else
  126. @@ -16,18 +16,17 @@ static inline pthread_t __pthread_self()
  127. #define BLX "blx"
  128. #endif
  129. -static inline pthread_t __pthread_self()
  130. +static inline uintptr_t __get_tp()
  131. {
  132. extern hidden uintptr_t __a_gettp_ptr;
  133. - register uintptr_t p __asm__("r0");
  134. - __asm__ ( BLX " %1" : "=r"(p) : "r"(__a_gettp_ptr) : "cc", "lr" );
  135. - return (void *)(p-sizeof(struct pthread));
  136. + register uintptr_t tp __asm__("r0");
  137. + __asm__ ( BLX " %1" : "=r"(tp) : "r"(__a_gettp_ptr) : "cc", "lr" );
  138. + return tp;
  139. }
  140. #endif
  141. #define TLS_ABOVE_TP
  142. #define GAP_ABOVE_TP 8
  143. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
  144. #define MC_PC arm_pc
  145. diff --git a/arch/generic/bits/fcntl.h b/arch/generic/bits/fcntl.h
  146. index ae233cc0..730a98cf 100644
  147. --- a/arch/generic/bits/fcntl.h
  148. +++ b/arch/generic/bits/fcntl.h
  149. @@ -30,9 +30,15 @@
  150. #define F_SETSIG 10
  151. #define F_GETSIG 11
  152. +#if __LONG_MAX == 0x7fffffffL
  153. #define F_GETLK 12
  154. #define F_SETLK 13
  155. #define F_SETLKW 14
  156. +#else
  157. +#define F_GETLK 5
  158. +#define F_SETLK 6
  159. +#define F_SETLKW 7
  160. +#endif
  161. #define F_SETOWN_EX 15
  162. #define F_GETOWN_EX 16
  163. diff --git a/arch/i386/bits/syscall.h.in b/arch/i386/bits/syscall.h.in
  164. index 1ae4e48a..abdb210d 100644
  165. --- a/arch/i386/bits/syscall.h.in
  166. +++ b/arch/i386/bits/syscall.h.in
  167. @@ -426,4 +426,8 @@
  168. #define __NR_fspick 433
  169. #define __NR_pidfd_open 434
  170. #define __NR_clone3 435
  171. +#define __NR_close_range 436
  172. +#define __NR_openat2 437
  173. +#define __NR_pidfd_getfd 438
  174. +#define __NR_faccessat2 439
  175. diff --git a/arch/i386/pthread_arch.h b/arch/i386/pthread_arch.h
  176. index 6f600b9e..a639c382 100644
  177. --- a/arch/i386/pthread_arch.h
  178. +++ b/arch/i386/pthread_arch.h
  179. @@ -1,10 +1,8 @@
  180. -static inline struct pthread *__pthread_self()
  181. +static inline uintptr_t __get_tp()
  182. {
  183. - struct pthread *self;
  184. - __asm__ ("movl %%gs:0,%0" : "=r" (self) );
  185. - return self;
  186. + uintptr_t tp;
  187. + __asm__ ("movl %%gs:0,%0" : "=r" (tp) );
  188. + return tp;
  189. }
  190. -#define TP_ADJ(p) (p)
  191. -
  192. #define MC_PC gregs[REG_EIP]
  193. diff --git a/arch/i386/syscall_arch.h b/arch/i386/syscall_arch.h
  194. index 69642e57..f92b7aa9 100644
  195. --- a/arch/i386/syscall_arch.h
  196. +++ b/arch/i386/syscall_arch.h
  197. @@ -87,5 +87,3 @@ static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a
  198. #define VDSO_CGT32_VER "LINUX_2.6"
  199. #define VDSO_CGT_SYM "__vdso_clock_gettime64"
  200. #define VDSO_CGT_VER "LINUX_2.6"
  201. -
  202. -#define SYSCALL_USE_SOCKETCALL
  203. diff --git a/arch/m68k/bits/syscall.h.in b/arch/m68k/bits/syscall.h.in
  204. index ddfa72e4..e10969a2 100644
  205. --- a/arch/m68k/bits/syscall.h.in
  206. +++ b/arch/m68k/bits/syscall.h.in
  207. @@ -405,3 +405,8 @@
  208. #define __NR_fsmount 432
  209. #define __NR_fspick 433
  210. #define __NR_pidfd_open 434
  211. +#define __NR_clone3 435
  212. +#define __NR_close_range 436
  213. +#define __NR_openat2 437
  214. +#define __NR_pidfd_getfd 438
  215. +#define __NR_faccessat2 439
  216. diff --git a/arch/m68k/pthread_arch.h b/arch/m68k/pthread_arch.h
  217. index 02d5b8a0..5bea4e1a 100644
  218. --- a/arch/m68k/pthread_arch.h
  219. +++ b/arch/m68k/pthread_arch.h
  220. @@ -1,13 +1,12 @@
  221. -static inline struct pthread *__pthread_self()
  222. +static inline uintptr_t __get_tp()
  223. {
  224. - uintptr_t tp = __syscall(SYS_get_thread_area);
  225. - return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
  226. + return __syscall(SYS_get_thread_area);
  227. }
  228. #define TLS_ABOVE_TP
  229. #define GAP_ABOVE_TP 0
  230. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
  231. +#define TP_OFFSET 0x7000
  232. #define DTP_OFFSET 0x8000
  233. #define MC_PC gregs[R_PC]
  234. diff --git a/arch/m68k/syscall_arch.h b/arch/m68k/syscall_arch.h
  235. index af79c306..6a9d0ae8 100644
  236. --- a/arch/m68k/syscall_arch.h
  237. +++ b/arch/m68k/syscall_arch.h
  238. @@ -87,5 +87,4 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
  239. return d0;
  240. }
  241. -#define SYSCALL_USE_SOCKETCALL
  242. #define SYSCALL_IPC_BROKEN_MODE
  243. diff --git a/arch/microblaze/bits/syscall.h.in b/arch/microblaze/bits/syscall.h.in
  244. index 963386a8..9d469047 100644
  245. --- a/arch/microblaze/bits/syscall.h.in
  246. +++ b/arch/microblaze/bits/syscall.h.in
  247. @@ -427,4 +427,8 @@
  248. #define __NR_fspick 433
  249. #define __NR_pidfd_open 434
  250. #define __NR_clone3 435
  251. +#define __NR_close_range 436
  252. +#define __NR_openat2 437
  253. +#define __NR_pidfd_getfd 438
  254. +#define __NR_faccessat2 439
  255. diff --git a/arch/microblaze/pthread_arch.h b/arch/microblaze/pthread_arch.h
  256. index f6ba8de9..ff26624e 100644
  257. --- a/arch/microblaze/pthread_arch.h
  258. +++ b/arch/microblaze/pthread_arch.h
  259. @@ -1,10 +1,8 @@
  260. -static inline struct pthread *__pthread_self()
  261. +static inline uintptr_t __get_tp()
  262. {
  263. - struct pthread *self;
  264. - __asm__ ("ori %0, r21, 0" : "=r" (self) );
  265. - return self;
  266. + uintptr_t tp;
  267. + __asm__ ("ori %0, r21, 0" : "=r" (tp) );
  268. + return tp;
  269. }
  270. -#define TP_ADJ(p) (p)
  271. -
  272. #define MC_PC regs.pc
  273. diff --git a/arch/microblaze/syscall_arch.h b/arch/microblaze/syscall_arch.h
  274. index 169013f8..61d8248e 100644
  275. --- a/arch/microblaze/syscall_arch.h
  276. +++ b/arch/microblaze/syscall_arch.h
  277. @@ -95,3 +95,5 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
  278. }
  279. #define SYSCALL_IPC_BROKEN_MODE
  280. +
  281. +#undef SYS_socketcall
  282. diff --git a/arch/mips/bits/syscall.h.in b/arch/mips/bits/syscall.h.in
  283. index 86251bf3..2bb03f06 100644
  284. --- a/arch/mips/bits/syscall.h.in
  285. +++ b/arch/mips/bits/syscall.h.in
  286. @@ -408,4 +408,8 @@
  287. #define __NR_fspick 4433
  288. #define __NR_pidfd_open 4434
  289. #define __NR_clone3 4435
  290. +#define __NR_close_range 4436
  291. +#define __NR_openat2 4437
  292. +#define __NR_pidfd_getfd 4438
  293. +#define __NR_faccessat2 4439
  294. diff --git a/arch/mips/pthread_arch.h b/arch/mips/pthread_arch.h
  295. index 1e7839ea..c45347ab 100644
  296. --- a/arch/mips/pthread_arch.h
  297. +++ b/arch/mips/pthread_arch.h
  298. @@ -1,19 +1,19 @@
  299. -static inline struct pthread *__pthread_self()
  300. +static inline uintptr_t __get_tp()
  301. {
  302. #if __mips_isa_rev < 2
  303. - register char *tp __asm__("$3");
  304. + register uintptr_t tp __asm__("$3");
  305. __asm__ (".word 0x7c03e83b" : "=r" (tp) );
  306. #else
  307. - char *tp;
  308. + uintptr_t tp;
  309. __asm__ ("rdhwr %0, $29" : "=r" (tp) );
  310. #endif
  311. - return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
  312. + return tp;
  313. }
  314. #define TLS_ABOVE_TP
  315. #define GAP_ABOVE_TP 0
  316. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
  317. +#define TP_OFFSET 0x7000
  318. #define DTP_OFFSET 0x8000
  319. #define MC_PC pc
  320. diff --git a/arch/mips/syscall_arch.h b/arch/mips/syscall_arch.h
  321. index 380a94b3..5b7c38de 100644
  322. --- a/arch/mips/syscall_arch.h
  323. +++ b/arch/mips/syscall_arch.h
  324. @@ -149,3 +149,5 @@ static inline long __syscall7(long n, long a, long b, long c, long d, long e, lo
  325. #define SO_SNDTIMEO_OLD 0x1005
  326. #define SO_RCVTIMEO_OLD 0x1006
  327. +
  328. +#undef SYS_socketcall
  329. diff --git a/arch/mips64/bits/fcntl.h b/arch/mips64/bits/fcntl.h
  330. index 3bcec15e..5da1eef8 100644
  331. --- a/arch/mips64/bits/fcntl.h
  332. +++ b/arch/mips64/bits/fcntl.h
  333. @@ -13,7 +13,7 @@
  334. #define O_ASYNC 010000
  335. #define O_DIRECT 0100000
  336. -#define O_LARGEFILE 0
  337. +#define O_LARGEFILE 020000
  338. #define O_NOATIME 01000000
  339. #define O_PATH 010000000
  340. #define O_TMPFILE 020200000
  341. diff --git a/arch/mips64/bits/syscall.h.in b/arch/mips64/bits/syscall.h.in
  342. index 9b406e9a..045e8238 100644
  343. --- a/arch/mips64/bits/syscall.h.in
  344. +++ b/arch/mips64/bits/syscall.h.in
  345. @@ -338,4 +338,8 @@
  346. #define __NR_fspick 5433
  347. #define __NR_pidfd_open 5434
  348. #define __NR_clone3 5435
  349. +#define __NR_close_range 5436
  350. +#define __NR_openat2 5437
  351. +#define __NR_pidfd_getfd 5438
  352. +#define __NR_faccessat2 5439
  353. diff --git a/arch/mips64/pthread_arch.h b/arch/mips64/pthread_arch.h
  354. index 1e7839ea..c45347ab 100644
  355. --- a/arch/mips64/pthread_arch.h
  356. +++ b/arch/mips64/pthread_arch.h
  357. @@ -1,19 +1,19 @@
  358. -static inline struct pthread *__pthread_self()
  359. +static inline uintptr_t __get_tp()
  360. {
  361. #if __mips_isa_rev < 2
  362. - register char *tp __asm__("$3");
  363. + register uintptr_t tp __asm__("$3");
  364. __asm__ (".word 0x7c03e83b" : "=r" (tp) );
  365. #else
  366. - char *tp;
  367. + uintptr_t tp;
  368. __asm__ ("rdhwr %0, $29" : "=r" (tp) );
  369. #endif
  370. - return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
  371. + return tp;
  372. }
  373. #define TLS_ABOVE_TP
  374. #define GAP_ABOVE_TP 0
  375. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
  376. +#define TP_OFFSET 0x7000
  377. #define DTP_OFFSET 0x8000
  378. #define MC_PC pc
  379. diff --git a/arch/mipsn32/bits/syscall.h.in b/arch/mipsn32/bits/syscall.h.in
  380. index 2ad48d10..5b322558 100644
  381. --- a/arch/mipsn32/bits/syscall.h.in
  382. +++ b/arch/mipsn32/bits/syscall.h.in
  383. @@ -362,4 +362,8 @@
  384. #define __NR_fspick 6433
  385. #define __NR_pidfd_open 6434
  386. #define __NR_clone3 6435
  387. +#define __NR_close_range 6436
  388. +#define __NR_openat2 6437
  389. +#define __NR_pidfd_getfd 6438
  390. +#define __NR_faccessat2 6439
  391. diff --git a/arch/mipsn32/pthread_arch.h b/arch/mipsn32/pthread_arch.h
  392. index 1e7839ea..c45347ab 100644
  393. --- a/arch/mipsn32/pthread_arch.h
  394. +++ b/arch/mipsn32/pthread_arch.h
  395. @@ -1,19 +1,19 @@
  396. -static inline struct pthread *__pthread_self()
  397. +static inline uintptr_t __get_tp()
  398. {
  399. #if __mips_isa_rev < 2
  400. - register char *tp __asm__("$3");
  401. + register uintptr_t tp __asm__("$3");
  402. __asm__ (".word 0x7c03e83b" : "=r" (tp) );
  403. #else
  404. - char *tp;
  405. + uintptr_t tp;
  406. __asm__ ("rdhwr %0, $29" : "=r" (tp) );
  407. #endif
  408. - return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
  409. + return tp;
  410. }
  411. #define TLS_ABOVE_TP
  412. #define GAP_ABOVE_TP 0
  413. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
  414. +#define TP_OFFSET 0x7000
  415. #define DTP_OFFSET 0x8000
  416. #define MC_PC pc
  417. diff --git a/arch/or1k/bits/syscall.h.in b/arch/or1k/bits/syscall.h.in
  418. index e9c925e4..b3603891 100644
  419. --- a/arch/or1k/bits/syscall.h.in
  420. +++ b/arch/or1k/bits/syscall.h.in
  421. @@ -311,4 +311,8 @@
  422. #define __NR_fspick 433
  423. #define __NR_pidfd_open 434
  424. #define __NR_clone3 435
  425. +#define __NR_close_range 436
  426. +#define __NR_openat2 437
  427. +#define __NR_pidfd_getfd 438
  428. +#define __NR_faccessat2 439
  429. diff --git a/arch/or1k/pthread_arch.h b/arch/or1k/pthread_arch.h
  430. index 1b806f89..f75ea7e4 100644
  431. --- a/arch/or1k/pthread_arch.h
  432. +++ b/arch/or1k/pthread_arch.h
  433. @@ -1,18 +1,16 @@
  434. -/* or1k use variant I, but with the twist that tp points to the end of TCB */
  435. -static inline struct pthread *__pthread_self()
  436. +static inline uintptr_t __get_tp()
  437. {
  438. #ifdef __clang__
  439. - char *tp;
  440. + uintptr_t tp;
  441. __asm__ ("l.ori %0, r10, 0" : "=r" (tp) );
  442. #else
  443. - register char *tp __asm__("r10");
  444. + register uintptr_t tp __asm__("r10");
  445. __asm__ ("" : "=r" (tp) );
  446. #endif
  447. - return (struct pthread *) (tp - sizeof(struct pthread));
  448. + return tp;
  449. }
  450. #define TLS_ABOVE_TP
  451. #define GAP_ABOVE_TP 0
  452. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
  453. #define MC_PC regs.pc
  454. diff --git a/arch/powerpc/bits/syscall.h.in b/arch/powerpc/bits/syscall.h.in
  455. index 8d4f79b5..5c6fae3e 100644
  456. --- a/arch/powerpc/bits/syscall.h.in
  457. +++ b/arch/powerpc/bits/syscall.h.in
  458. @@ -415,4 +415,8 @@
  459. #define __NR_fspick 433
  460. #define __NR_pidfd_open 434
  461. #define __NR_clone3 435
  462. +#define __NR_close_range 436
  463. +#define __NR_openat2 437
  464. +#define __NR_pidfd_getfd 438
  465. +#define __NR_faccessat2 439
  466. diff --git a/arch/powerpc/pthread_arch.h b/arch/powerpc/pthread_arch.h
  467. index ae0f28d6..42e88b07 100644
  468. --- a/arch/powerpc/pthread_arch.h
  469. +++ b/arch/powerpc/pthread_arch.h
  470. @@ -1,18 +1,16 @@
  471. -static inline struct pthread *__pthread_self()
  472. +static inline uintptr_t __get_tp()
  473. {
  474. - register char *tp __asm__("r2");
  475. + register uintptr_t tp __asm__("r2");
  476. __asm__ ("" : "=r" (tp) );
  477. - return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
  478. + return tp;
  479. }
  480. #define TLS_ABOVE_TP
  481. #define GAP_ABOVE_TP 0
  482. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
  483. +#define TP_OFFSET 0x7000
  484. #define DTP_OFFSET 0x8000
  485. // the kernel calls the ip "nip", it's the first saved value after the 32
  486. // GPRs.
  487. #define MC_PC gregs[32]
  488. -
  489. -#define CANARY canary_at_end
  490. diff --git a/arch/powerpc64/bits/syscall.h.in b/arch/powerpc64/bits/syscall.h.in
  491. index b935864c..edf73d3d 100644
  492. --- a/arch/powerpc64/bits/syscall.h.in
  493. +++ b/arch/powerpc64/bits/syscall.h.in
  494. @@ -387,4 +387,8 @@
  495. #define __NR_fspick 433
  496. #define __NR_pidfd_open 434
  497. #define __NR_clone3 435
  498. +#define __NR_close_range 436
  499. +#define __NR_openat2 437
  500. +#define __NR_pidfd_getfd 438
  501. +#define __NR_faccessat2 439
  502. diff --git a/arch/powerpc64/pthread_arch.h b/arch/powerpc64/pthread_arch.h
  503. index 79c3ecd8..1b7b9079 100644
  504. --- a/arch/powerpc64/pthread_arch.h
  505. +++ b/arch/powerpc64/pthread_arch.h
  506. @@ -1,18 +1,16 @@
  507. -static inline struct pthread *__pthread_self()
  508. +static inline uintptr_t __get_tp()
  509. {
  510. - register char *tp __asm__("r13");
  511. + register uintptr_t tp __asm__("r13");
  512. __asm__ ("" : "=r" (tp) );
  513. - return (pthread_t)(tp - 0x7000 - sizeof(struct pthread));
  514. + return tp;
  515. }
  516. #define TLS_ABOVE_TP
  517. #define GAP_ABOVE_TP 0
  518. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
  519. +#define TP_OFFSET 0x7000
  520. #define DTP_OFFSET 0x8000
  521. // the kernel calls the ip "nip", it's the first saved value after the 32
  522. // GPRs.
  523. #define MC_PC gp_regs[32]
  524. -
  525. -#define CANARY canary_at_end
  526. diff --git a/arch/riscv64/bits/fcntl.h b/arch/riscv64/bits/fcntl.h
  527. deleted file mode 100644
  528. index ecb4d18f..00000000
  529. --- a/arch/riscv64/bits/fcntl.h
  530. +++ /dev/null
  531. @@ -1,38 +0,0 @@
  532. -#define O_CREAT 0100
  533. -#define O_EXCL 0200
  534. -#define O_NOCTTY 0400
  535. -#define O_TRUNC 01000
  536. -#define O_APPEND 02000
  537. -#define O_NONBLOCK 04000
  538. -#define O_DSYNC 010000
  539. -#define O_SYNC 04010000
  540. -#define O_RSYNC 04010000
  541. -#define O_DIRECTORY 0200000
  542. -#define O_NOFOLLOW 0400000
  543. -#define O_CLOEXEC 02000000
  544. -
  545. -#define O_ASYNC 020000
  546. -#define O_DIRECT 040000
  547. -#define O_LARGEFILE 0100000
  548. -#define O_NOATIME 01000000
  549. -#define O_PATH 010000000
  550. -#define O_TMPFILE 020200000
  551. -#define O_NDELAY O_NONBLOCK
  552. -
  553. -#define F_DUPFD 0
  554. -#define F_GETFD 1
  555. -#define F_SETFD 2
  556. -#define F_GETFL 3
  557. -#define F_SETFL 4
  558. -#define F_GETLK 5
  559. -#define F_SETLK 6
  560. -#define F_SETLKW 7
  561. -#define F_SETOWN 8
  562. -#define F_GETOWN 9
  563. -#define F_SETSIG 10
  564. -#define F_GETSIG 11
  565. -
  566. -#define F_SETOWN_EX 15
  567. -#define F_GETOWN_EX 16
  568. -
  569. -#define F_GETOWNER_UIDS 17
  570. diff --git a/arch/riscv64/bits/signal.h b/arch/riscv64/bits/signal.h
  571. index b006334f..287367db 100644
  572. --- a/arch/riscv64/bits/signal.h
  573. +++ b/arch/riscv64/bits/signal.h
  574. @@ -60,10 +60,10 @@ struct sigaltstack {
  575. size_t ss_size;
  576. };
  577. -typedef struct ucontext_t
  578. +typedef struct __ucontext
  579. {
  580. unsigned long uc_flags;
  581. - struct ucontext_t *uc_link;
  582. + struct __ucontext *uc_link;
  583. stack_t uc_stack;
  584. sigset_t uc_sigmask;
  585. mcontext_t uc_mcontext;
  586. diff --git a/arch/riscv64/bits/syscall.h.in b/arch/riscv64/bits/syscall.h.in
  587. index 0043eeba..5def016b 100644
  588. --- a/arch/riscv64/bits/syscall.h.in
  589. +++ b/arch/riscv64/bits/syscall.h.in
  590. @@ -289,6 +289,10 @@
  591. #define __NR_fspick 433
  592. #define __NR_pidfd_open 434
  593. #define __NR_clone3 435
  594. +#define __NR_close_range 436
  595. +#define __NR_openat2 437
  596. +#define __NR_pidfd_getfd 438
  597. +#define __NR_faccessat2 439
  598. #define __NR_sysriscv __NR_arch_specific_syscall
  599. #define __NR_riscv_flush_icache (__NR_sysriscv + 15)
  600. diff --git a/arch/riscv64/pthread_arch.h b/arch/riscv64/pthread_arch.h
  601. index db414b17..a20d7fba 100644
  602. --- a/arch/riscv64/pthread_arch.h
  603. +++ b/arch/riscv64/pthread_arch.h
  604. @@ -1,13 +1,12 @@
  605. -static inline struct pthread *__pthread_self()
  606. +static inline uintptr_t __get_tp()
  607. {
  608. - char *tp;
  609. + uintptr_t tp;
  610. __asm__ __volatile__("mv %0, tp" : "=r"(tp));
  611. - return (void *)(tp - sizeof(struct pthread));
  612. + return tp;
  613. }
  614. #define TLS_ABOVE_TP
  615. #define GAP_ABOVE_TP 0
  616. -#define TP_ADJ(p) ((char *)p + sizeof(struct pthread))
  617. #define DTP_OFFSET 0x800
  618. diff --git a/arch/s390x/bits/alltypes.h.in b/arch/s390x/bits/alltypes.h.in
  619. index 15d18c8f..6c0eb7f4 100644
  620. --- a/arch/s390x/bits/alltypes.h.in
  621. +++ b/arch/s390x/bits/alltypes.h.in
  622. @@ -9,7 +9,11 @@
  623. TYPEDEF int wchar_t;
  624. #endif
  625. +#if defined(__FLT_EVAL_METHOD__) && __FLT_EVAL_METHOD__ == 1
  626. TYPEDEF double float_t;
  627. +#else
  628. +TYPEDEF float float_t;
  629. +#endif
  630. TYPEDEF double double_t;
  631. TYPEDEF struct { long long __ll; long double __ld; } max_align_t;
  632. diff --git a/arch/s390x/bits/float.h b/arch/s390x/bits/float.h
  633. index 90b73bee..e188cb61 100644
  634. --- a/arch/s390x/bits/float.h
  635. +++ b/arch/s390x/bits/float.h
  636. @@ -1,4 +1,8 @@
  637. -#define FLT_EVAL_METHOD 1
  638. +#ifdef __FLT_EVAL_METHOD__
  639. +#define FLT_EVAL_METHOD __FLT_EVAL_METHOD__
  640. +#else
  641. +#define FLT_EVAL_METHOD 0
  642. +#endif
  643. #define LDBL_TRUE_MIN 6.47517511943802511092443895822764655e-4966L
  644. #define LDBL_MIN 3.36210314311209350626267781732175260e-4932L
  645. diff --git a/arch/s390x/bits/syscall.h.in b/arch/s390x/bits/syscall.h.in
  646. index e89f3782..fb2e60e3 100644
  647. --- a/arch/s390x/bits/syscall.h.in
  648. +++ b/arch/s390x/bits/syscall.h.in
  649. @@ -352,4 +352,8 @@
  650. #define __NR_fspick 433
  651. #define __NR_pidfd_open 434
  652. #define __NR_clone3 435
  653. +#define __NR_close_range 436
  654. +#define __NR_openat2 437
  655. +#define __NR_pidfd_getfd 438
  656. +#define __NR_faccessat2 439
  657. diff --git a/arch/s390x/pthread_arch.h b/arch/s390x/pthread_arch.h
  658. index e2251f1f..e54fec3f 100644
  659. --- a/arch/s390x/pthread_arch.h
  660. +++ b/arch/s390x/pthread_arch.h
  661. @@ -1,14 +1,12 @@
  662. -static inline struct pthread *__pthread_self()
  663. +static inline uintptr_t __get_tp()
  664. {
  665. - struct pthread *self;
  666. + uintptr_t tp;
  667. __asm__ (
  668. "ear %0, %%a0\n"
  669. "sllg %0, %0, 32\n"
  670. "ear %0, %%a1\n"
  671. - : "=r"(self));
  672. - return self;
  673. + : "=r"(tp));
  674. + return tp;
  675. }
  676. -#define TP_ADJ(p) (p)
  677. -
  678. #define MC_PC psw.addr
  679. diff --git a/arch/s390x/syscall_arch.h b/arch/s390x/syscall_arch.h
  680. index afb99852..83cc9a27 100644
  681. --- a/arch/s390x/syscall_arch.h
  682. +++ b/arch/s390x/syscall_arch.h
  683. @@ -72,5 +72,3 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo
  684. register long r7 __asm__("r7") = f;
  685. __asm_syscall("+r"(r2), "r"(r1), "r"(r3), "r"(r4), "r"(r5), "r"(r6), "r"(r7));
  686. }
  687. -
  688. -#define SYSCALL_USE_SOCKETCALL
  689. diff --git a/arch/sh/bits/signal.h b/arch/sh/bits/signal.h
  690. index 160311fa..d0b14828 100644
  691. --- a/arch/sh/bits/signal.h
  692. +++ b/arch/sh/bits/signal.h
  693. @@ -9,7 +9,16 @@
  694. #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
  695. typedef int greg_t, gregset_t[16];
  696. typedef int freg_t, fpregset_t[16];
  697. -typedef struct sigcontext {
  698. +typedef struct {
  699. + unsigned long oldmask;
  700. + unsigned long gregs[16];
  701. + unsigned long pc, pr, sr;
  702. + unsigned long gbr, mach, macl;
  703. + unsigned long fpregs[16];
  704. + unsigned long xfpregs[16];
  705. + unsigned int fpscr, fpul, ownedfp;
  706. +} mcontext_t;
  707. +struct sigcontext {
  708. unsigned long oldmask;
  709. unsigned long sc_regs[16];
  710. unsigned long sc_pc, sc_pr, sc_sr;
  711. @@ -17,7 +26,7 @@ typedef struct sigcontext {
  712. unsigned long sc_fpregs[16];
  713. unsigned long sc_xfpregs[16];
  714. unsigned int sc_fpscr, sc_fpul, sc_ownedfp;
  715. -} mcontext_t;
  716. +};
  717. #else
  718. typedef struct {
  719. unsigned long __regs[58];
  720. diff --git a/arch/sh/bits/syscall.h.in b/arch/sh/bits/syscall.h.in
  721. index 0102ddaf..158afc09 100644
  722. --- a/arch/sh/bits/syscall.h.in
  723. +++ b/arch/sh/bits/syscall.h.in
  724. @@ -398,4 +398,9 @@
  725. #define __NR_fsmount 432
  726. #define __NR_fspick 433
  727. #define __NR_pidfd_open 434
  728. +#define __NR_clone3 435
  729. +#define __NR_close_range 436
  730. +#define __NR_openat2 437
  731. +#define __NR_pidfd_getfd 438
  732. +#define __NR_faccessat2 439
  733. diff --git a/arch/sh/pthread_arch.h b/arch/sh/pthread_arch.h
  734. index 3ee9c1a9..199c2d55 100644
  735. --- a/arch/sh/pthread_arch.h
  736. +++ b/arch/sh/pthread_arch.h
  737. @@ -1,17 +1,16 @@
  738. -static inline struct pthread *__pthread_self()
  739. +static inline uintptr_t __get_tp()
  740. {
  741. - char *self;
  742. - __asm__ ("stc gbr,%0" : "=r" (self) );
  743. - return (struct pthread *) (self - sizeof(struct pthread));
  744. + uintptr_t tp;
  745. + __asm__ ("stc gbr,%0" : "=r" (tp) );
  746. + return tp;
  747. }
  748. #define TLS_ABOVE_TP
  749. #define GAP_ABOVE_TP 8
  750. -#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread))
  751. -#define MC_PC sc_pc
  752. +#define MC_PC pc
  753. #ifdef __FDPIC__
  754. -#define MC_GOT sc_regs[12]
  755. +#define MC_GOT gregs[12]
  756. #define CANCEL_GOT (*(uintptr_t *)((char *)__syscall_cp_asm+sizeof(uintptr_t)))
  757. #endif
  758. diff --git a/arch/x32/bits/fcntl.h b/arch/x32/bits/fcntl.h
  759. index 1b88ad39..08627f81 100644
  760. --- a/arch/x32/bits/fcntl.h
  761. +++ b/arch/x32/bits/fcntl.h
  762. @@ -13,7 +13,7 @@
  763. #define O_ASYNC 020000
  764. #define O_DIRECT 040000
  765. -#define O_LARGEFILE 0
  766. +#define O_LARGEFILE 0100000
  767. #define O_NOATIME 01000000
  768. #define O_PATH 010000000
  769. #define O_TMPFILE 020200000
  770. diff --git a/arch/x32/bits/syscall.h.in b/arch/x32/bits/syscall.h.in
  771. index f47bdee5..cfd9856f 100644
  772. --- a/arch/x32/bits/syscall.h.in
  773. +++ b/arch/x32/bits/syscall.h.in
  774. @@ -298,6 +298,10 @@
  775. #define __NR_fspick (0x40000000 + 433)
  776. #define __NR_pidfd_open (0x40000000 + 434)
  777. #define __NR_clone3 (0x40000000 + 435)
  778. +#define __NR_close_range (0x40000000 + 436)
  779. +#define __NR_openat2 (0x40000000 + 437)
  780. +#define __NR_pidfd_getfd (0x40000000 + 438)
  781. +#define __NR_faccessat2 (0x40000000 + 439)
  782. #define __NR_rt_sigaction (0x40000000 + 512)
  783. diff --git a/arch/x32/pthread_arch.h b/arch/x32/pthread_arch.h
  784. index f640a1a1..c1e7716d 100644
  785. --- a/arch/x32/pthread_arch.h
  786. +++ b/arch/x32/pthread_arch.h
  787. @@ -1,14 +1,12 @@
  788. -static inline struct pthread *__pthread_self()
  789. +static inline uintptr_t __get_tp()
  790. {
  791. - struct pthread *self;
  792. - __asm__ ("mov %%fs:0,%0" : "=r" (self) );
  793. - return self;
  794. + uintptr_t tp;
  795. + __asm__ ("mov %%fs:0,%0" : "=r" (tp) );
  796. + return tp;
  797. }
  798. -#define TP_ADJ(p) (p)
  799. -
  800. #define MC_PC gregs[REG_RIP]
  801. -#define CANARY canary2
  802. +#define CANARY_PAD
  803. #define tls_mod_off_t unsigned long long
  804. diff --git a/arch/x86_64/bits/fcntl.h b/arch/x86_64/bits/fcntl.h
  805. deleted file mode 100644
  806. index 1b88ad39..00000000
  807. --- a/arch/x86_64/bits/fcntl.h
  808. +++ /dev/null
  809. @@ -1,40 +0,0 @@
  810. -#define O_CREAT 0100
  811. -#define O_EXCL 0200
  812. -#define O_NOCTTY 0400
  813. -#define O_TRUNC 01000
  814. -#define O_APPEND 02000
  815. -#define O_NONBLOCK 04000
  816. -#define O_DSYNC 010000
  817. -#define O_SYNC 04010000
  818. -#define O_RSYNC 04010000
  819. -#define O_DIRECTORY 0200000
  820. -#define O_NOFOLLOW 0400000
  821. -#define O_CLOEXEC 02000000
  822. -
  823. -#define O_ASYNC 020000
  824. -#define O_DIRECT 040000
  825. -#define O_LARGEFILE 0
  826. -#define O_NOATIME 01000000
  827. -#define O_PATH 010000000
  828. -#define O_TMPFILE 020200000
  829. -#define O_NDELAY O_NONBLOCK
  830. -
  831. -#define F_DUPFD 0
  832. -#define F_GETFD 1
  833. -#define F_SETFD 2
  834. -#define F_GETFL 3
  835. -#define F_SETFL 4
  836. -
  837. -#define F_SETOWN 8
  838. -#define F_GETOWN 9
  839. -#define F_SETSIG 10
  840. -#define F_GETSIG 11
  841. -
  842. -#define F_GETLK 5
  843. -#define F_SETLK 6
  844. -#define F_SETLKW 7
  845. -
  846. -#define F_SETOWN_EX 15
  847. -#define F_GETOWN_EX 16
  848. -
  849. -#define F_GETOWNER_UIDS 17
  850. diff --git a/arch/x86_64/bits/syscall.h.in b/arch/x86_64/bits/syscall.h.in
  851. index 6a646ad3..a6117951 100644
  852. --- a/arch/x86_64/bits/syscall.h.in
  853. +++ b/arch/x86_64/bits/syscall.h.in
  854. @@ -345,4 +345,8 @@
  855. #define __NR_fspick 433
  856. #define __NR_pidfd_open 434
  857. #define __NR_clone3 435
  858. +#define __NR_close_range 436
  859. +#define __NR_openat2 437
  860. +#define __NR_pidfd_getfd 438
  861. +#define __NR_faccessat2 439
  862. diff --git a/arch/x86_64/pthread_arch.h b/arch/x86_64/pthread_arch.h
  863. index 65e880c6..c8c63f2e 100644
  864. --- a/arch/x86_64/pthread_arch.h
  865. +++ b/arch/x86_64/pthread_arch.h
  866. @@ -1,10 +1,8 @@
  867. -static inline struct pthread *__pthread_self()
  868. +static inline uintptr_t __get_tp()
  869. {
  870. - struct pthread *self;
  871. - __asm__ ("mov %%fs:0,%0" : "=r" (self) );
  872. - return self;
  873. + uintptr_t tp;
  874. + __asm__ ("mov %%fs:0,%0" : "=r" (tp) );
  875. + return tp;
  876. }
  877. -#define TP_ADJ(p) (p)
  878. -
  879. #define MC_PC gregs[REG_RIP]
  880. diff --git a/configure b/configure
  881. index 18fda9af..a5231a0e 100755
  882. --- a/configure
  883. +++ b/configure
  884. @@ -30,7 +30,7 @@ System types:
  885. Optional features:
  886. --enable-optimize=... optimize listed components for speed over size [auto]
  887. --enable-debug build with debugging information [disabled]
  888. - --enable-warnings build with recommended warnings flags [disabled]
  889. + --disable-warnings build with recommended warnings flags [enabled]
  890. --enable-wrapper=... build given musl toolchain wrapper [auto]
  891. --disable-shared inhibit building shared library [enabled]
  892. --disable-static inhibit building static library [enabled]
  893. @@ -136,7 +136,7 @@ build=
  894. target=
  895. optimize=auto
  896. debug=no
  897. -warnings=no
  898. +warnings=yes
  899. shared=auto
  900. static=yes
  901. wrapper=auto
  902. @@ -204,7 +204,7 @@ fi
  903. abs_builddir="$(pwd)" || fail "$0: cannot determine working directory"
  904. abs_srcdir="$(cd $srcdir && pwd)" || fail "$0: invalid source directory $srcdir"
  905. test "$abs_srcdir" = "$abs_builddir" && srcdir=.
  906. -test "$srcdir" != "." -a -f Makefile -a ! -h Makefile && fail "$0: Makefile already exists in the working directory"
  907. +test "$srcdir" != "." && test -f Makefile && test ! -h Makefile && fail "$0: Makefile already exists in the working directory"
  908. #
  909. # Get a temp filename we can use
  910. @@ -279,7 +279,7 @@ echo "$cc_family"
  911. #
  912. # Figure out toolchain wrapper to build
  913. #
  914. -if test "$wrapper" = auto -o "$wrapper" = detect ; then
  915. +if test "$wrapper" = auto || test "$wrapper" = detect ; then
  916. echo "#include <stdlib.h>" > "$tmpc"
  917. echo "#if ! __GLIBC__" >> "$tmpc"
  918. echo "#error no" >> "$tmpc"
  919. @@ -468,7 +468,7 @@ tryflag CFLAGS_AUTO -pipe
  920. # pointer is no longer needed for debugging.
  921. #
  922. if fnmatch '-g*|*\ -g*' "$CFLAGS_AUTO $CFLAGS" ; then :
  923. -else
  924. +else
  925. tryflag CFLAGS_AUTO -fomit-frame-pointer
  926. fi
  927. @@ -508,10 +508,13 @@ fi
  928. #
  929. # GCC defines -w as overriding any -W options, regardless of order, but
  930. # clang has a bunch of annoying warnings enabled by default and needs -w
  931. -# to start from a clean slate. So use -w if building with clang.
  932. +# to start from a clean slate. So use -w if building with clang. Also
  933. +# turn off a common on-by-default cast warning regardless of compiler.
  934. #
  935. test "$cc_family" = clang && tryflag CFLAGS_AUTO -w
  936. +tryflag CFLAGS_AUTO -Wno-pointer-to-int-cast
  937. +
  938. #
  939. # Even with -std=c99, gcc accepts some constructs which are constraint
  940. # violations. We want to treat these as errors regardless of whether
  941. @@ -522,6 +525,10 @@ tryflag CFLAGS_AUTO -Werror=implicit-function-declaration
  942. tryflag CFLAGS_AUTO -Werror=implicit-int
  943. tryflag CFLAGS_AUTO -Werror=pointer-sign
  944. tryflag CFLAGS_AUTO -Werror=pointer-arith
  945. +tryflag CFLAGS_AUTO -Werror=int-conversion
  946. +tryflag CFLAGS_AUTO -Werror=incompatible-pointer-types
  947. +tryflag CFLAGS_AUTO -Werror=discarded-qualifiers
  948. +tryflag CFLAGS_AUTO -Werror=discarded-array-qualifiers
  949. #
  950. # GCC ignores unused arguements by default, but Clang needs this extra
  951. @@ -531,14 +538,17 @@ tryflag CFLAGS_AUTO -Werror=pointer-arith
  952. test "$cc_family" = clang && tryflag CFLAGS_AUTO -Qunused-arguments
  953. if test "x$warnings" = xyes ; then
  954. -tryflag CFLAGS_AUTO -Wall
  955. -tryflag CFLAGS_AUTO -Wno-parentheses
  956. -tryflag CFLAGS_AUTO -Wno-uninitialized
  957. -tryflag CFLAGS_AUTO -Wno-missing-braces
  958. -tryflag CFLAGS_AUTO -Wno-unused-value
  959. -tryflag CFLAGS_AUTO -Wno-unused-but-set-variable
  960. -tryflag CFLAGS_AUTO -Wno-unknown-pragmas
  961. -tryflag CFLAGS_AUTO -Wno-pointer-to-int-cast
  962. +tryflag CFLAGS_AUTO -Waddress
  963. +tryflag CFLAGS_AUTO -Warray-bounds
  964. +tryflag CFLAGS_AUTO -Wchar-subscripts
  965. +tryflag CFLAGS_AUTO -Wduplicate-decl-specifier
  966. +tryflag CFLAGS_AUTO -Winit-self
  967. +tryflag CFLAGS_AUTO -Wreturn-type
  968. +tryflag CFLAGS_AUTO -Wsequence-point
  969. +tryflag CFLAGS_AUTO -Wstrict-aliasing
  970. +tryflag CFLAGS_AUTO -Wunused-function
  971. +tryflag CFLAGS_AUTO -Wunused-label
  972. +tryflag CFLAGS_AUTO -Wunused-variable
  973. fi
  974. # Determine if the compiler produces position-independent code (PIC)
  975. diff --git a/include/alltypes.h.in b/include/alltypes.h.in
  976. index d9ff462e..d47aeea9 100644
  977. --- a/include/alltypes.h.in
  978. +++ b/include/alltypes.h.in
  979. @@ -77,6 +77,8 @@ TYPEDEF struct __sigset_t { unsigned long __bits[128/sizeof(long)]; } sigset_t;
  980. STRUCT iovec { void *iov_base; size_t iov_len; };
  981. +STRUCT winsize { unsigned short ws_row, ws_col, ws_xpixel, ws_ypixel; };
  982. +
  983. TYPEDEF unsigned socklen_t;
  984. TYPEDEF unsigned short sa_family_t;
  985. diff --git a/include/elf.h b/include/elf.h
  986. index 549f92c1..b5e7befb 100644
  987. --- a/include/elf.h
  988. +++ b/include/elf.h
  989. @@ -603,6 +603,7 @@ typedef struct {
  990. #define PT_GNU_EH_FRAME 0x6474e550
  991. #define PT_GNU_STACK 0x6474e551
  992. #define PT_GNU_RELRO 0x6474e552
  993. +#define PT_GNU_PROPERTY 0x6474e553
  994. #define PT_LOSUNW 0x6ffffffa
  995. #define PT_SUNWBSS 0x6ffffffa
  996. #define PT_SUNWSTACK 0x6ffffffb
  997. @@ -1085,6 +1086,7 @@ typedef struct {
  998. #define NT_GNU_BUILD_ID 3
  999. #define NT_GNU_GOLD_VERSION 4
  1000. +#define NT_GNU_PROPERTY_TYPE_0 5
  1001. diff --git a/include/netinet/if_ether.h b/include/netinet/if_ether.h
  1002. index a08485e7..55a2ff1b 100644
  1003. --- a/include/netinet/if_ether.h
  1004. +++ b/include/netinet/if_ether.h
  1005. @@ -59,6 +59,7 @@
  1006. #define ETH_P_PREAUTH 0x88C7
  1007. #define ETH_P_TIPC 0x88CA
  1008. #define ETH_P_LLDP 0x88CC
  1009. +#define ETH_P_MRP 0x88E3
  1010. #define ETH_P_MACSEC 0x88E5
  1011. #define ETH_P_8021AH 0x88E7
  1012. #define ETH_P_MVRP 0x88F5
  1013. diff --git a/include/netinet/in.h b/include/netinet/in.h
  1014. index 103d2e04..f9594339 100644
  1015. --- a/include/netinet/in.h
  1016. +++ b/include/netinet/in.h
  1017. @@ -101,8 +101,10 @@ uint16_t ntohs(uint16_t);
  1018. #define IPPROTO_MH 135
  1019. #define IPPROTO_UDPLITE 136
  1020. #define IPPROTO_MPLS 137
  1021. +#define IPPROTO_ETHERNET 143
  1022. #define IPPROTO_RAW 255
  1023. -#define IPPROTO_MAX 256
  1024. +#define IPPROTO_MPTCP 262
  1025. +#define IPPROTO_MAX 263
  1026. #define IN6_IS_ADDR_UNSPECIFIED(a) \
  1027. (((uint32_t *) (a))[0] == 0 && ((uint32_t *) (a))[1] == 0 && \
  1028. @@ -200,6 +202,7 @@ uint16_t ntohs(uint16_t);
  1029. #define IP_CHECKSUM 23
  1030. #define IP_BIND_ADDRESS_NO_PORT 24
  1031. #define IP_RECVFRAGSIZE 25
  1032. +#define IP_RECVERR_RFC4884 26
  1033. #define IP_MULTICAST_IF 32
  1034. #define IP_MULTICAST_TTL 33
  1035. #define IP_MULTICAST_LOOP 34
  1036. diff --git a/include/netinet/tcp.h b/include/netinet/tcp.h
  1037. index 44a007aa..b7b997f5 100644
  1038. --- a/include/netinet/tcp.h
  1039. +++ b/include/netinet/tcp.h
  1040. @@ -78,6 +78,8 @@ enum {
  1041. TCP_NLA_DSACK_DUPS,
  1042. TCP_NLA_REORD_SEEN,
  1043. TCP_NLA_SRTT,
  1044. + TCP_NLA_TIMEOUT_REHASH,
  1045. + TCP_NLA_BYTES_NOTSENT,
  1046. };
  1047. #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
  1048. @@ -181,6 +183,13 @@ struct tcphdr {
  1049. #define TCP_CA_Recovery 3
  1050. #define TCP_CA_Loss 4
  1051. +enum tcp_fastopen_client_fail {
  1052. + TFO_STATUS_UNSPEC,
  1053. + TFO_COOKIE_UNAVAILABLE,
  1054. + TFO_DATA_NOT_ACKED,
  1055. + TFO_SYN_RETRANSMITTED,
  1056. +};
  1057. +
  1058. struct tcp_info {
  1059. uint8_t tcpi_state;
  1060. uint8_t tcpi_ca_state;
  1061. @@ -189,7 +198,7 @@ struct tcp_info {
  1062. uint8_t tcpi_backoff;
  1063. uint8_t tcpi_options;
  1064. uint8_t tcpi_snd_wscale : 4, tcpi_rcv_wscale : 4;
  1065. - uint8_t tcpi_delivery_rate_app_limited : 1;
  1066. + uint8_t tcpi_delivery_rate_app_limited : 1, tcpi_fastopen_client_fail : 2;
  1067. uint32_t tcpi_rto;
  1068. uint32_t tcpi_ato;
  1069. uint32_t tcpi_snd_mss;
  1070. @@ -240,14 +249,15 @@ struct tcp_info {
  1071. #define TCP_MD5SIG_MAXKEYLEN 80
  1072. -#define TCP_MD5SIG_FLAG_PREFIX 1
  1073. +#define TCP_MD5SIG_FLAG_PREFIX 0x1
  1074. +#define TCP_MD5SIG_FLAG_IFINDEX 0x2
  1075. struct tcp_md5sig {
  1076. struct sockaddr_storage tcpm_addr;
  1077. uint8_t tcpm_flags;
  1078. uint8_t tcpm_prefixlen;
  1079. uint16_t tcpm_keylen;
  1080. - uint32_t __tcpm_pad;
  1081. + int tcpm_ifindex;
  1082. uint8_t tcpm_key[TCP_MD5SIG_MAXKEYLEN];
  1083. };
  1084. @@ -275,6 +285,8 @@ struct tcp_zerocopy_receive {
  1085. uint64_t address;
  1086. uint32_t length;
  1087. uint32_t recv_skip_hint;
  1088. + uint32_t inq;
  1089. + int32_t err;
  1090. };
  1091. #endif
  1092. diff --git a/include/netinet/udp.h b/include/netinet/udp.h
  1093. index ffd89079..40c3f203 100644
  1094. --- a/include/netinet/udp.h
  1095. +++ b/include/netinet/udp.h
  1096. @@ -35,6 +35,7 @@ struct udphdr {
  1097. #define UDP_ENCAP_GTP0 4
  1098. #define UDP_ENCAP_GTP1U 5
  1099. #define UDP_ENCAP_RXRPC 6
  1100. +#define TCP_ENCAP_ESPINTCP 7
  1101. #define SOL_UDP 17
  1102. diff --git a/include/sched.h b/include/sched.h
  1103. index 822f464e..fda4b484 100644
  1104. --- a/include/sched.h
  1105. +++ b/include/sched.h
  1106. @@ -49,6 +49,7 @@ int sched_yield(void);
  1107. #ifdef _GNU_SOURCE
  1108. #define CSIGNAL 0x000000ff
  1109. +#define CLONE_NEWTIME 0x00000080
  1110. #define CLONE_VM 0x00000100
  1111. #define CLONE_FS 0x00000200
  1112. #define CLONE_FILES 0x00000400
  1113. diff --git a/include/signal.h b/include/signal.h
  1114. index fbdf667b..9ed929e4 100644
  1115. --- a/include/signal.h
  1116. +++ b/include/signal.h
  1117. @@ -180,14 +180,24 @@ struct sigevent {
  1118. union sigval sigev_value;
  1119. int sigev_signo;
  1120. int sigev_notify;
  1121. - void (*sigev_notify_function)(union sigval);
  1122. - pthread_attr_t *sigev_notify_attributes;
  1123. - char __pad[56-3*sizeof(long)];
  1124. + union {
  1125. + char __pad[64 - 2*sizeof(int) - sizeof(union sigval)];
  1126. + pid_t sigev_notify_thread_id;
  1127. + struct {
  1128. + void (*sigev_notify_function)(union sigval);
  1129. + pthread_attr_t *sigev_notify_attributes;
  1130. + } __sev_thread;
  1131. + } __sev_fields;
  1132. };
  1133. +#define sigev_notify_thread_id __sev_fields.sigev_notify_thread_id
  1134. +#define sigev_notify_function __sev_fields.__sev_thread.sigev_notify_function
  1135. +#define sigev_notify_attributes __sev_fields.__sev_thread.sigev_notify_attributes
  1136. +
  1137. #define SIGEV_SIGNAL 0
  1138. #define SIGEV_NONE 1
  1139. #define SIGEV_THREAD 2
  1140. +#define SIGEV_THREAD_ID 4
  1141. int __libc_current_sigrtmin(void);
  1142. int __libc_current_sigrtmax(void);
  1143. diff --git a/include/stdlib.h b/include/stdlib.h
  1144. index 194c2033..b54a051f 100644
  1145. --- a/include/stdlib.h
  1146. +++ b/include/stdlib.h
  1147. @@ -145,6 +145,7 @@ int getloadavg(double *, int);
  1148. int clearenv(void);
  1149. #define WCOREDUMP(s) ((s) & 0x80)
  1150. #define WIFCONTINUED(s) ((s) == 0xffff)
  1151. +void *reallocarray (void *, size_t, size_t);
  1152. #endif
  1153. #ifdef _GNU_SOURCE
  1154. diff --git a/include/sys/fanotify.h b/include/sys/fanotify.h
  1155. index b637c8f5..10e5f15e 100644
  1156. --- a/include/sys/fanotify.h
  1157. +++ b/include/sys/fanotify.h
  1158. @@ -55,8 +55,9 @@ struct fanotify_response {
  1159. #define FAN_OPEN_PERM 0x10000
  1160. #define FAN_ACCESS_PERM 0x20000
  1161. #define FAN_OPEN_EXEC_PERM 0x40000
  1162. -#define FAN_ONDIR 0x40000000
  1163. +#define FAN_DIR_MODIFY 0x00080000
  1164. #define FAN_EVENT_ON_CHILD 0x08000000
  1165. +#define FAN_ONDIR 0x40000000
  1166. #define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE)
  1167. #define FAN_MOVE (FAN_MOVED_FROM | FAN_MOVED_TO)
  1168. #define FAN_CLOEXEC 0x01
  1169. @@ -70,6 +71,9 @@ struct fanotify_response {
  1170. #define FAN_ENABLE_AUDIT 0x40
  1171. #define FAN_REPORT_TID 0x100
  1172. #define FAN_REPORT_FID 0x200
  1173. +#define FAN_REPORT_DIR_FID 0x00000400
  1174. +#define FAN_REPORT_NAME 0x00000800
  1175. +#define FAN_REPORT_DFID_NAME (FAN_REPORT_DIR_FID | FAN_REPORT_NAME)
  1176. #define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE | FAN_UNLIMITED_MARKS)
  1177. #define FAN_MARK_ADD 0x01
  1178. #define FAN_MARK_REMOVE 0x02
  1179. @@ -88,6 +92,8 @@ struct fanotify_response {
  1180. #define FAN_ALL_OUTGOING_EVENTS (FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_Q_OVERFLOW)
  1181. #define FANOTIFY_METADATA_VERSION 3
  1182. #define FAN_EVENT_INFO_TYPE_FID 1
  1183. +#define FAN_EVENT_INFO_TYPE_DFID_NAME 2
  1184. +#define FAN_EVENT_INFO_TYPE_DFID 3
  1185. #define FAN_ALLOW 0x01
  1186. #define FAN_DENY 0x02
  1187. #define FAN_AUDIT 0x10
  1188. diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h
  1189. index c2ce3b48..a9a2346e 100644
  1190. --- a/include/sys/ioctl.h
  1191. +++ b/include/sys/ioctl.h
  1192. @@ -4,6 +4,8 @@
  1193. extern "C" {
  1194. #endif
  1195. +#define __NEED_struct_winsize
  1196. +
  1197. #include <bits/alltypes.h>
  1198. #include <bits/ioctl.h>
  1199. @@ -47,13 +49,6 @@ extern "C" {
  1200. #define TIOCSER_TEMT 1
  1201. -struct winsize {
  1202. - unsigned short ws_row;
  1203. - unsigned short ws_col;
  1204. - unsigned short ws_xpixel;
  1205. - unsigned short ws_ypixel;
  1206. -};
  1207. -
  1208. #define SIOCADDRT 0x890B
  1209. #define SIOCDELRT 0x890C
  1210. #define SIOCRTMSG 0x890D
  1211. diff --git a/include/sys/mman.h b/include/sys/mman.h
  1212. index 3bade727..4d603e91 100644
  1213. --- a/include/sys/mman.h
  1214. +++ b/include/sys/mman.h
  1215. @@ -101,6 +101,7 @@ extern "C" {
  1216. #ifdef _GNU_SOURCE
  1217. #define MREMAP_MAYMOVE 1
  1218. #define MREMAP_FIXED 2
  1219. +#define MREMAP_DONTUNMAP 4
  1220. #define MLOCK_ONFAULT 0x01
  1221. diff --git a/include/sys/personality.h b/include/sys/personality.h
  1222. index 31d43dfe..411dc475 100644
  1223. --- a/include/sys/personality.h
  1224. +++ b/include/sys/personality.h
  1225. @@ -5,7 +5,9 @@
  1226. extern "C" {
  1227. #endif
  1228. +#define UNAME26 0x0020000
  1229. #define ADDR_NO_RANDOMIZE 0x0040000
  1230. +#define FDPIC_FUNCPTRS 0x0080000
  1231. #define MMAP_PAGE_ZERO 0x0100000
  1232. #define ADDR_COMPAT_LAYOUT 0x0200000
  1233. #define READ_IMPLIES_EXEC 0x0400000
  1234. @@ -17,6 +19,7 @@ extern "C" {
  1235. #define PER_LINUX 0
  1236. #define PER_LINUX_32BIT ADDR_LIMIT_32BIT
  1237. +#define PER_LINUX_FDPIC FDPIC_FUNCPTRS
  1238. #define PER_SVR4 (1 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO)
  1239. #define PER_SVR3 (2 | STICKY_TIMEOUTS | SHORT_INODE)
  1240. #define PER_SCOSVR3 (3 | STICKY_TIMEOUTS | WHOLE_SECONDS | SHORT_INODE)
  1241. diff --git a/include/sys/prctl.h b/include/sys/prctl.h
  1242. index d9c846e9..4b9fcc05 100644
  1243. --- a/include/sys/prctl.h
  1244. +++ b/include/sys/prctl.h
  1245. @@ -158,6 +158,9 @@ struct prctl_mm_map {
  1246. #define PR_GET_TAGGED_ADDR_CTRL 56
  1247. #define PR_TAGGED_ADDR_ENABLE (1UL << 0)
  1248. +#define PR_SET_IO_FLUSHER 57
  1249. +#define PR_GET_IO_FLUSHER 58
  1250. +
  1251. int prctl (int, ...);
  1252. #ifdef __cplusplus
  1253. diff --git a/include/sys/random.h b/include/sys/random.h
  1254. index 4ee7bf2c..59e40ab8 100644
  1255. --- a/include/sys/random.h
  1256. +++ b/include/sys/random.h
  1257. @@ -10,6 +10,7 @@ extern "C" {
  1258. #define GRND_NONBLOCK 0x0001
  1259. #define GRND_RANDOM 0x0002
  1260. +#define GRND_INSECURE 0x0004
  1261. ssize_t getrandom(void *, size_t, unsigned);
  1262. diff --git a/include/termios.h b/include/termios.h
  1263. index d73c780d..cbb53301 100644
  1264. --- a/include/termios.h
  1265. +++ b/include/termios.h
  1266. @@ -8,6 +8,7 @@ extern "C" {
  1267. #include <features.h>
  1268. #define __NEED_pid_t
  1269. +#define __NEED_struct_winsize
  1270. #include <bits/alltypes.h>
  1271. @@ -27,6 +28,9 @@ int cfsetispeed (struct termios *, speed_t);
  1272. int tcgetattr (int, struct termios *);
  1273. int tcsetattr (int, int, const struct termios *);
  1274. +int tcgetwinsize (int, struct winsize *);
  1275. +int tcsetwinsize (int, const struct winsize *);
  1276. +
  1277. int tcsendbreak (int, int);
  1278. int tcdrain (int);
  1279. int tcflush (int, int);
  1280. diff --git a/include/unistd.h b/include/unistd.h
  1281. index 7bcbff94..13064026 100644
  1282. --- a/include/unistd.h
  1283. +++ b/include/unistd.h
  1284. @@ -82,6 +82,7 @@ unsigned sleep(unsigned);
  1285. int pause(void);
  1286. pid_t fork(void);
  1287. +pid_t _Fork(void);
  1288. int execve(const char *, char *const [], char *const []);
  1289. int execv(const char *, char *const []);
  1290. int execle(const char *, const char *, ...);
  1291. @@ -190,6 +191,7 @@ int syncfs(int);
  1292. int euidaccess(const char *, int);
  1293. int eaccess(const char *, int);
  1294. ssize_t copy_file_range(int, off_t *, int, off_t *, size_t, unsigned);
  1295. +pid_t gettid(void);
  1296. #endif
  1297. #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  1298. diff --git a/ldso/dynlink.c b/ldso/dynlink.c
  1299. index d3d4ddd2..6b868c84 100644
  1300. --- a/ldso/dynlink.c
  1301. +++ b/ldso/dynlink.c
  1302. @@ -1,6 +1,5 @@
  1303. #define _GNU_SOURCE
  1304. #define SYSCALL_NO_TLS 1
  1305. -#include <stdio.h>
  1306. #include <stdlib.h>
  1307. #include <stdarg.h>
  1308. #include <stddef.h>
  1309. @@ -21,9 +20,15 @@
  1310. #include <semaphore.h>
  1311. #include <sys/membarrier.h>
  1312. #include "pthread_impl.h"
  1313. +#include "fork_impl.h"
  1314. #include "libc.h"
  1315. #include "dynlink.h"
  1316. +#define malloc __libc_malloc
  1317. +#define calloc __libc_calloc
  1318. +#define realloc __libc_realloc
  1319. +#define free __libc_free
  1320. +
  1321. static void error(const char *, ...);
  1322. #define MAXP2(a,b) (-(-(a)&-(b)))
  1323. @@ -78,7 +83,7 @@ struct dso {
  1324. struct dso **deps, *needed_by;
  1325. size_t ndeps_direct;
  1326. size_t next_dep;
  1327. - int ctor_visitor;
  1328. + pthread_t ctor_visitor;
  1329. char *rpath_orig, *rpath;
  1330. struct tls_module tls;
  1331. size_t tls_id;
  1332. @@ -556,6 +561,20 @@ static void reclaim_gaps(struct dso *dso)
  1333. }
  1334. }
  1335. +static ssize_t read_loop(int fd, void *p, size_t n)
  1336. +{
  1337. + for (size_t i=0; i<n; ) {
  1338. + ssize_t l = read(fd, (char *)p+i, n-i);
  1339. + if (l<0) {
  1340. + if (errno==EINTR) continue;
  1341. + else return -1;
  1342. + }
  1343. + if (l==0) return i;
  1344. + i += l;
  1345. + }
  1346. + return n;
  1347. +}
  1348. +
  1349. static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
  1350. {
  1351. static int no_map_fixed;
  1352. @@ -1060,13 +1079,17 @@ static struct dso *load_library(const char *name, struct dso *needed_by)
  1353. snprintf(etc_ldso_path, sizeof etc_ldso_path,
  1354. "%.*s/etc/ld-musl-" LDSO_ARCH ".path",
  1355. (int)prefix_len, prefix);
  1356. - FILE *f = fopen(etc_ldso_path, "rbe");
  1357. - if (f) {
  1358. - if (getdelim(&sys_path, (size_t[1]){0}, 0, f) <= 0) {
  1359. + fd = open(etc_ldso_path, O_RDONLY|O_CLOEXEC);
  1360. + if (fd>=0) {
  1361. + size_t n = 0;
  1362. + if (!fstat(fd, &st)) n = st.st_size;
  1363. + if ((sys_path = malloc(n+1)))
  1364. + sys_path[n] = 0;
  1365. + if (!sys_path || read_loop(fd, sys_path, n)<0) {
  1366. free(sys_path);
  1367. sys_path = "";
  1368. }
  1369. - fclose(f);
  1370. + close(fd);
  1371. } else if (errno != ENOENT) {
  1372. sys_path = "";
  1373. }
  1374. @@ -1378,7 +1401,7 @@ void __libc_exit_fini()
  1375. {
  1376. struct dso *p;
  1377. size_t dyn[DYN_CNT];
  1378. - int self = __pthread_self()->tid;
  1379. + pthread_t self = __pthread_self();
  1380. /* Take both locks before setting shutting_down, so that
  1381. * either lock is sufficient to read its value. The lock
  1382. @@ -1404,6 +1427,17 @@ void __libc_exit_fini()
  1383. }
  1384. }
  1385. +void __ldso_atfork(int who)
  1386. +{
  1387. + if (who<0) {
  1388. + pthread_rwlock_wrlock(&lock);
  1389. + pthread_mutex_lock(&init_fini_lock);
  1390. + } else {
  1391. + pthread_mutex_unlock(&init_fini_lock);
  1392. + pthread_rwlock_unlock(&lock);
  1393. + }
  1394. +}
  1395. +
  1396. static struct dso **queue_ctors(struct dso *dso)
  1397. {
  1398. size_t cnt, qpos, spos, i;
  1399. @@ -1462,6 +1496,13 @@ static struct dso **queue_ctors(struct dso *dso)
  1400. }
  1401. queue[qpos] = 0;
  1402. for (i=0; i<qpos; i++) queue[i]->mark = 0;
  1403. + for (i=0; i<qpos; i++)
  1404. + if (queue[i]->ctor_visitor && queue[i]->ctor_visitor->tid < 0) {
  1405. + error("State of %s is inconsistent due to multithreaded fork\n",
  1406. + queue[i]->name);
  1407. + free(queue);
  1408. + if (runtime) longjmp(*rtld_fail, 1);
  1409. + }
  1410. return queue;
  1411. }
  1412. @@ -1470,7 +1511,7 @@ static void do_init_fini(struct dso **queue)
  1413. {
  1414. struct dso *p;
  1415. size_t dyn[DYN_CNT], i;
  1416. - int self = __pthread_self()->tid;
  1417. + pthread_t self = __pthread_self();
  1418. pthread_mutex_lock(&init_fini_lock);
  1419. for (i=0; (p=queue[i]); i++) {
  1420. @@ -1579,7 +1620,7 @@ static void install_new_tls(void)
  1421. /* Install new dtv for each thread. */
  1422. for (j=0, td=self; !j || td!=self; j++, td=td->next) {
  1423. - td->dtv = td->dtv_copy = newdtv[j];
  1424. + td->dtv = newdtv[j];
  1425. }
  1426. __tl_unlock();
  1427. @@ -1947,7 +1988,7 @@ void __dls3(size_t *sp, size_t *auxv)
  1428. debug.bp = dl_debug_state;
  1429. debug.head = head;
  1430. debug.base = ldso.base;
  1431. - debug.state = 0;
  1432. + debug.state = RT_CONSISTENT;
  1433. _dl_debug_state();
  1434. if (replace_argv0) argv[0] = replace_argv0;
  1435. @@ -1996,6 +2037,9 @@ void *dlopen(const char *file, int mode)
  1436. pthread_rwlock_wrlock(&lock);
  1437. __inhibit_ptc();
  1438. + debug.state = RT_ADD;
  1439. + _dl_debug_state();
  1440. +
  1441. p = 0;
  1442. if (shutting_down) {
  1443. error("Cannot dlopen while program is exiting.");
  1444. @@ -2055,8 +2099,9 @@ void *dlopen(const char *file, int mode)
  1445. load_deps(p);
  1446. extend_bfs_deps(p);
  1447. pthread_mutex_lock(&init_fini_lock);
  1448. - if (!p->constructed) ctor_queue = queue_ctors(p);
  1449. + int constructed = p->constructed;
  1450. pthread_mutex_unlock(&init_fini_lock);
  1451. + if (!constructed) ctor_queue = queue_ctors(p);
  1452. if (!p->relocated && (mode & RTLD_LAZY)) {
  1453. prepare_lazy(p);
  1454. for (i=0; p->deps[i]; i++)
  1455. @@ -2088,9 +2133,10 @@ void *dlopen(const char *file, int mode)
  1456. update_tls_size();
  1457. if (tls_cnt != orig_tls_cnt)
  1458. install_new_tls();
  1459. - _dl_debug_state();
  1460. orig_tail = tail;
  1461. end:
  1462. + debug.state = RT_CONSISTENT;
  1463. + _dl_debug_state();
  1464. __release_ptc();
  1465. if (p) gencnt++;
  1466. pthread_rwlock_unlock(&lock);
  1467. diff --git a/src/aio/aio.c b/src/aio/aio.c
  1468. index 6d34fa86..a1a3e791 100644
  1469. --- a/src/aio/aio.c
  1470. +++ b/src/aio/aio.c
  1471. @@ -9,6 +9,12 @@
  1472. #include "syscall.h"
  1473. #include "atomic.h"
  1474. #include "pthread_impl.h"
  1475. +#include "aio_impl.h"
  1476. +
  1477. +#define malloc __libc_malloc
  1478. +#define calloc __libc_calloc
  1479. +#define realloc __libc_realloc
  1480. +#define free __libc_free
  1481. /* The following is a threads-based implementation of AIO with minimal
  1482. * dependence on implementation details. Most synchronization is
  1483. @@ -70,6 +76,10 @@ static struct aio_queue *****map;
  1484. static volatile int aio_fd_cnt;
  1485. volatile int __aio_fut;
  1486. +static size_t io_thread_stack_size;
  1487. +
  1488. +#define MAX(a,b) ((a)>(b) ? (a) : (b))
  1489. +
  1490. static struct aio_queue *__aio_get_queue(int fd, int need)
  1491. {
  1492. if (fd < 0) {
  1493. @@ -84,6 +94,10 @@ static struct aio_queue *__aio_get_queue(int fd, int need)
  1494. pthread_rwlock_unlock(&maplock);
  1495. if (fcntl(fd, F_GETFD) < 0) return 0;
  1496. pthread_rwlock_wrlock(&maplock);
  1497. + if (!io_thread_stack_size) {
  1498. + unsigned long val = __getauxval(AT_MINSIGSTKSZ);
  1499. + io_thread_stack_size = MAX(MINSIGSTKSZ+2048, val+512);
  1500. + }
  1501. if (!map) map = calloc(sizeof *map, (-1U/2+1)>>24);
  1502. if (!map) goto out;
  1503. if (!map[a]) map[a] = calloc(sizeof **map, 256);
  1504. @@ -259,15 +273,6 @@ static void *io_thread_func(void *ctx)
  1505. return 0;
  1506. }
  1507. -static size_t io_thread_stack_size = MINSIGSTKSZ+2048;
  1508. -static pthread_once_t init_stack_size_once;
  1509. -
  1510. -static void init_stack_size()
  1511. -{
  1512. - unsigned long val = __getauxval(AT_MINSIGSTKSZ);
  1513. - if (val > MINSIGSTKSZ) io_thread_stack_size = val + 512;
  1514. -}
  1515. -
  1516. static int submit(struct aiocb *cb, int op)
  1517. {
  1518. int ret = 0;
  1519. @@ -293,7 +298,6 @@ static int submit(struct aiocb *cb, int op)
  1520. else
  1521. pthread_attr_init(&a);
  1522. } else {
  1523. - pthread_once(&init_stack_size_once, init_stack_size);
  1524. pthread_attr_init(&a);
  1525. pthread_attr_setstacksize(&a, io_thread_stack_size);
  1526. pthread_attr_setguardsize(&a, 0);
  1527. @@ -392,6 +396,20 @@ int __aio_close(int fd)
  1528. return fd;
  1529. }
  1530. +void __aio_atfork(int who)
  1531. +{
  1532. + if (who<0) {
  1533. + pthread_rwlock_rdlock(&maplock);
  1534. + return;
  1535. + }
  1536. + if (who>0 && map) for (int a=0; a<(-1U/2+1)>>24; a++)
  1537. + if (map[a]) for (int b=0; b<256; b++)
  1538. + if (map[a][b]) for (int c=0; c<256; c++)
  1539. + if (map[a][b][c]) for (int d=0; d<256; d++)
  1540. + map[a][b][c][d] = 0;
  1541. + pthread_rwlock_unlock(&maplock);
  1542. +}
  1543. +
  1544. weak_alias(aio_cancel, aio_cancel64);
  1545. weak_alias(aio_error, aio_error64);
  1546. weak_alias(aio_fsync, aio_fsync64);
  1547. diff --git a/src/aio/aio_suspend.c b/src/aio/aio_suspend.c
  1548. index 34b66f87..1c1060e3 100644
  1549. --- a/src/aio/aio_suspend.c
  1550. +++ b/src/aio/aio_suspend.c
  1551. @@ -3,6 +3,7 @@
  1552. #include <time.h>
  1553. #include "atomic.h"
  1554. #include "pthread_impl.h"
  1555. +#include "aio_impl.h"
  1556. int aio_suspend(const struct aiocb *const cbs[], int cnt, const struct timespec *ts)
  1557. {
  1558. diff --git a/src/crypt/crypt_blowfish.c b/src/crypt/crypt_blowfish.c
  1559. index d3f79851..d722607b 100644
  1560. --- a/src/crypt/crypt_blowfish.c
  1561. +++ b/src/crypt/crypt_blowfish.c
  1562. @@ -15,7 +15,7 @@
  1563. * No copyright is claimed, and the software is hereby placed in the public
  1564. * domain. In case this attempt to disclaim copyright and place the software
  1565. * in the public domain is deemed null and void, then the software is
  1566. - * Copyright (c) 1998-2012 Solar Designer and it is hereby released to the
  1567. + * Copyright (c) 1998-2014 Solar Designer and it is hereby released to the
  1568. * general public under the following terms:
  1569. *
  1570. * Redistribution and use in source and binary forms, with or without
  1571. @@ -31,12 +31,12 @@
  1572. * you place this code and any modifications you make under a license
  1573. * of your choice.
  1574. *
  1575. - * This implementation is mostly compatible with OpenBSD's bcrypt.c (prefix
  1576. - * "$2a$") by Niels Provos <provos at citi.umich.edu>, and uses some of his
  1577. - * ideas. The password hashing algorithm was designed by David Mazieres
  1578. - * <dm at lcs.mit.edu>. For more information on the level of compatibility,
  1579. - * please refer to the comments in BF_set_key() below and to the included
  1580. - * crypt(3) man page.
  1581. + * This implementation is fully compatible with OpenBSD's bcrypt.c for prefix
  1582. + * "$2b$", originally by Niels Provos <provos at citi.umich.edu>, and it uses
  1583. + * some of his ideas. The password hashing algorithm was designed by David
  1584. + * Mazieres <dm at lcs.mit.edu>. For information on the level of
  1585. + * compatibility for bcrypt hash prefixes other than "$2b$", please refer to
  1586. + * the comments in BF_set_key() below and to the included crypt(3) man page.
  1587. *
  1588. * There's a paper on the algorithm that explains its design decisions:
  1589. *
  1590. @@ -533,6 +533,7 @@ static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
  1591. * Valid combinations of settings are:
  1592. *
  1593. * Prefix "$2a$": bug = 0, safety = 0x10000
  1594. + * Prefix "$2b$": bug = 0, safety = 0
  1595. * Prefix "$2x$": bug = 1, safety = 0
  1596. * Prefix "$2y$": bug = 0, safety = 0
  1597. */
  1598. @@ -596,12 +597,14 @@ static void BF_set_key(const char *key, BF_key expanded, BF_key initial,
  1599. initial[0] ^= sign;
  1600. }
  1601. +static const unsigned char flags_by_subtype[26] = {
  1602. + 2, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1603. + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0
  1604. +};
  1605. +
  1606. static char *BF_crypt(const char *key, const char *setting,
  1607. char *output, BF_word min)
  1608. {
  1609. - static const unsigned char flags_by_subtype[26] =
  1610. - {2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  1611. - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 0};
  1612. struct {
  1613. BF_ctx ctx;
  1614. BF_key expanded_key;
  1615. @@ -746,9 +749,11 @@ char *__crypt_blowfish(const char *key, const char *setting, char *output)
  1616. {
  1617. const char *test_key = "8b \xd0\xc1\xd2\xcf\xcc\xd8";
  1618. const char *test_setting = "$2a$00$abcdefghijklmnopqrstuu";
  1619. - static const char test_hash[2][34] =
  1620. - {"VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* $2x$ */
  1621. - "i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55"}; /* $2a$, $2y$ */
  1622. + static const char test_hashes[2][34] = {
  1623. + "i1D709vfamulimlGcq0qq3UvuUasvEa\0\x55", /* 'a', 'b', 'y' */
  1624. + "VUrPmXD6q/nVSSp7pNDhCR9071IfIRe\0\x55", /* 'x' */
  1625. + };
  1626. + const char *test_hash = test_hashes[0];
  1627. char *retval;
  1628. const char *p;
  1629. int ok;
  1630. @@ -768,8 +773,11 @@ char *__crypt_blowfish(const char *key, const char *setting, char *output)
  1631. * detected by the self-test.
  1632. */
  1633. memcpy(buf.s, test_setting, sizeof(buf.s));
  1634. - if (retval)
  1635. + if (retval) {
  1636. + unsigned int flags = flags_by_subtype[setting[2] - 'a'];
  1637. + test_hash = test_hashes[flags & 1];
  1638. buf.s[2] = setting[2];
  1639. + }
  1640. memset(buf.o, 0x55, sizeof(buf.o));
  1641. buf.o[sizeof(buf.o) - 1] = 0;
  1642. p = BF_crypt(test_key, buf.s, buf.o, 1);
  1643. @@ -777,7 +785,7 @@ char *__crypt_blowfish(const char *key, const char *setting, char *output)
  1644. ok = (p == buf.o &&
  1645. !memcmp(p, buf.s, 7 + 22) &&
  1646. !memcmp(p + (7 + 22),
  1647. - test_hash[buf.s[2] & 1],
  1648. + test_hash,
  1649. 31 + 1 + 1 + 1));
  1650. {
  1651. diff --git a/src/env/__init_tls.c b/src/env/__init_tls.c
  1652. index 772baba3..a93141ed 100644
  1653. --- a/src/env/__init_tls.c
  1654. +++ b/src/env/__init_tls.c
  1655. @@ -67,7 +67,7 @@ void *__copy_tls(unsigned char *mem)
  1656. }
  1657. #endif
  1658. dtv[0] = libc.tls_cnt;
  1659. - td->dtv = td->dtv_copy = dtv;
  1660. + td->dtv = dtv;
  1661. return td;
  1662. }
  1663. diff --git a/src/env/__stack_chk_fail.c b/src/env/__stack_chk_fail.c
  1664. index e32596d1..bf5a280a 100644
  1665. --- a/src/env/__stack_chk_fail.c
  1666. +++ b/src/env/__stack_chk_fail.c
  1667. @@ -9,7 +9,7 @@ void __init_ssp(void *entropy)
  1668. if (entropy) memcpy(&__stack_chk_guard, entropy, sizeof(uintptr_t));
  1669. else __stack_chk_guard = (uintptr_t)&__stack_chk_guard * 1103515245;
  1670. - __pthread_self()->CANARY = __stack_chk_guard;
  1671. + __pthread_self()->canary = __stack_chk_guard;
  1672. }
  1673. void __stack_chk_fail(void)
  1674. diff --git a/src/exit/abort.c b/src/exit/abort.c
  1675. index e1980f10..f21f458e 100644
  1676. --- a/src/exit/abort.c
  1677. +++ b/src/exit/abort.c
  1678. @@ -6,8 +6,6 @@
  1679. #include "lock.h"
  1680. #include "ksigaction.h"
  1681. -hidden volatile int __abort_lock[1];
  1682. -
  1683. _Noreturn void abort(void)
  1684. {
  1685. raise(SIGABRT);
  1686. diff --git a/src/exit/abort_lock.c b/src/exit/abort_lock.c
  1687. new file mode 100644
  1688. index 00000000..3af72c7b
  1689. --- /dev/null
  1690. +++ b/src/exit/abort_lock.c
  1691. @@ -0,0 +1,3 @@
  1692. +#include "pthread_impl.h"
  1693. +
  1694. +volatile int __abort_lock[1];
  1695. diff --git a/src/exit/assert.c b/src/exit/assert.c
  1696. index 49b0dc3e..94edd827 100644
  1697. --- a/src/exit/assert.c
  1698. +++ b/src/exit/assert.c
  1699. @@ -4,6 +4,5 @@
  1700. _Noreturn void __assert_fail(const char *expr, const char *file, int line, const char *func)
  1701. {
  1702. fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line);
  1703. - fflush(NULL);
  1704. abort();
  1705. }
  1706. diff --git a/src/exit/at_quick_exit.c b/src/exit/at_quick_exit.c
  1707. index d3ce6522..e4b5d78d 100644
  1708. --- a/src/exit/at_quick_exit.c
  1709. +++ b/src/exit/at_quick_exit.c
  1710. @@ -1,12 +1,14 @@
  1711. #include <stdlib.h>
  1712. #include "libc.h"
  1713. #include "lock.h"
  1714. +#include "fork_impl.h"
  1715. #define COUNT 32
  1716. static void (*funcs[COUNT])(void);
  1717. static int count;
  1718. static volatile int lock[1];
  1719. +volatile int *const __at_quick_exit_lockptr = lock;
  1720. void __funcs_on_quick_exit()
  1721. {
  1722. diff --git a/src/exit/atexit.c b/src/exit/atexit.c
  1723. index 160d277a..854e9fdd 100644
  1724. --- a/src/exit/atexit.c
  1725. +++ b/src/exit/atexit.c
  1726. @@ -2,6 +2,12 @@
  1727. #include <stdint.h>
  1728. #include "libc.h"
  1729. #include "lock.h"
  1730. +#include "fork_impl.h"
  1731. +
  1732. +#define malloc __libc_malloc
  1733. +#define calloc __libc_calloc
  1734. +#define realloc undef
  1735. +#define free undef
  1736. /* Ensure that at least 32 atexit handlers can be registered without malloc */
  1737. #define COUNT 32
  1738. @@ -15,6 +21,7 @@ static struct fl
  1739. static int slot;
  1740. static volatile int lock[1];
  1741. +volatile int *const __atexit_lockptr = lock;
  1742. void __funcs_on_exit()
  1743. {
  1744. diff --git a/src/include/stdlib.h b/src/include/stdlib.h
  1745. index d38a5417..e9da2015 100644
  1746. --- a/src/include/stdlib.h
  1747. +++ b/src/include/stdlib.h
  1748. @@ -9,4 +9,10 @@ hidden int __mkostemps(char *, int, int);
  1749. hidden int __ptsname_r(int, char *, size_t);
  1750. hidden char *__randname(char *);
  1751. +hidden void *__libc_malloc(size_t);
  1752. +hidden void *__libc_malloc_impl(size_t);
  1753. +hidden void *__libc_calloc(size_t, size_t);
  1754. +hidden void *__libc_realloc(void *, size_t);
  1755. +hidden void __libc_free(void *);
  1756. +
  1757. #endif
  1758. diff --git a/src/include/unistd.h b/src/include/unistd.h
  1759. index 1b4605c7..7b52a924 100644
  1760. --- a/src/include/unistd.h
  1761. +++ b/src/include/unistd.h
  1762. @@ -8,7 +8,6 @@ extern char **__environ;
  1763. hidden int __dup3(int, int, int);
  1764. hidden int __mkostemps(char *, int, int);
  1765. hidden int __execvpe(const char *, char *const *, char *const *);
  1766. -hidden int __aio_close(int);
  1767. hidden off_t __lseek(int, off_t, int);
  1768. #endif
  1769. diff --git a/src/internal/aio_impl.h b/src/internal/aio_impl.h
  1770. new file mode 100644
  1771. index 00000000..a8657665
  1772. --- /dev/null
  1773. +++ b/src/internal/aio_impl.h
  1774. @@ -0,0 +1,9 @@
  1775. +#ifndef AIO_IMPL_H
  1776. +#define AIO_IMPL_H
  1777. +
  1778. +extern hidden volatile int __aio_fut;
  1779. +
  1780. +extern hidden int __aio_close(int);
  1781. +extern hidden void __aio_atfork(int);
  1782. +
  1783. +#endif
  1784. diff --git a/src/internal/fork_impl.h b/src/internal/fork_impl.h
  1785. new file mode 100644
  1786. index 00000000..5892c13b
  1787. --- /dev/null
  1788. +++ b/src/internal/fork_impl.h
  1789. @@ -0,0 +1,19 @@
  1790. +#include <features.h>
  1791. +
  1792. +extern hidden volatile int *const __at_quick_exit_lockptr;
  1793. +extern hidden volatile int *const __atexit_lockptr;
  1794. +extern hidden volatile int *const __dlerror_lockptr;
  1795. +extern hidden volatile int *const __gettext_lockptr;
  1796. +extern hidden volatile int *const __locale_lockptr;
  1797. +extern hidden volatile int *const __random_lockptr;
  1798. +extern hidden volatile int *const __sem_open_lockptr;
  1799. +extern hidden volatile int *const __stdio_ofl_lockptr;
  1800. +extern hidden volatile int *const __syslog_lockptr;
  1801. +extern hidden volatile int *const __timezone_lockptr;
  1802. +
  1803. +extern hidden volatile int *const __bump_lockptr;
  1804. +
  1805. +extern hidden volatile int *const __vmlock_lockptr;
  1806. +
  1807. +hidden void __malloc_atfork(int);
  1808. +hidden void __ldso_atfork(int);
  1809. diff --git a/src/internal/libm.h b/src/internal/libm.h
  1810. index 7533f6ba..72ad17d8 100644
  1811. --- a/src/internal/libm.h
  1812. +++ b/src/internal/libm.h
  1813. @@ -267,5 +267,8 @@ hidden double __math_uflow(uint32_t);
  1814. hidden double __math_oflow(uint32_t);
  1815. hidden double __math_divzero(uint32_t);
  1816. hidden double __math_invalid(double);
  1817. +#if LDBL_MANT_DIG != DBL_MANT_DIG
  1818. +hidden long double __math_invalidl(long double);
  1819. +#endif
  1820. #endif
  1821. diff --git a/src/internal/locale_impl.h b/src/internal/locale_impl.h
  1822. index 741a71c4..4431a92e 100644
  1823. --- a/src/internal/locale_impl.h
  1824. +++ b/src/internal/locale_impl.h
  1825. @@ -15,6 +15,8 @@ struct __locale_map {
  1826. const struct __locale_map *next;
  1827. };
  1828. +extern hidden volatile int __locale_lock[1];
  1829. +
  1830. extern hidden const struct __locale_map __c_dot_utf8;
  1831. extern hidden const struct __locale_struct __c_locale;
  1832. extern hidden const struct __locale_struct __c_dot_utf8_locale;
  1833. diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
  1834. index 5742dfc5..de2b9d8b 100644
  1835. --- a/src/internal/pthread_impl.h
  1836. +++ b/src/internal/pthread_impl.h
  1837. @@ -11,16 +11,25 @@
  1838. #include "atomic.h"
  1839. #include "futex.h"
  1840. +#include "pthread_arch.h"
  1841. +
  1842. #define pthread __pthread
  1843. struct pthread {
  1844. /* Part 1 -- these fields may be external or
  1845. * internal (accessed via asm) ABI. Do not change. */
  1846. struct pthread *self;
  1847. +#ifndef TLS_ABOVE_TP
  1848. uintptr_t *dtv;
  1849. +#endif
  1850. struct pthread *prev, *next; /* non-ABI */
  1851. uintptr_t sysinfo;
  1852. - uintptr_t canary, canary2;
  1853. +#ifndef TLS_ABOVE_TP
  1854. +#ifdef CANARY_PAD
  1855. + uintptr_t canary_pad;
  1856. +#endif
  1857. + uintptr_t canary;
  1858. +#endif
  1859. /* Part 2 -- implementation details, non-ABI. */
  1860. int tid;
  1861. @@ -43,6 +52,7 @@ struct pthread {
  1862. long off;
  1863. volatile void *volatile pending;
  1864. } robust_list;
  1865. + int h_errno_val;
  1866. volatile int timer_id;
  1867. locale_t locale;
  1868. volatile int killlock[1];
  1869. @@ -51,21 +61,19 @@ struct pthread {
  1870. /* Part 3 -- the positions of these fields relative to
  1871. * the end of the structure is external and internal ABI. */
  1872. - uintptr_t canary_at_end;
  1873. - uintptr_t *dtv_copy;
  1874. +#ifdef TLS_ABOVE_TP
  1875. + uintptr_t canary;
  1876. + uintptr_t *dtv;
  1877. +#endif
  1878. };
  1879. enum {
  1880. - DT_EXITING = 0,
  1881. + DT_EXITED = 0,
  1882. + DT_EXITING,
  1883. DT_JOINABLE,
  1884. DT_DETACHED,
  1885. };
  1886. -struct __timer {
  1887. - int timerid;
  1888. - pthread_t thread;
  1889. -};
  1890. -
  1891. #define __SU (sizeof(size_t)/sizeof(int))
  1892. #define _a_stacksize __u.__s[0]
  1893. @@ -98,16 +106,22 @@ struct __timer {
  1894. #define _b_waiters2 __u.__vi[4]
  1895. #define _b_inst __u.__p[3]
  1896. -#include "pthread_arch.h"
  1897. -
  1898. -#ifndef CANARY
  1899. -#define CANARY canary
  1900. +#ifndef TP_OFFSET
  1901. +#define TP_OFFSET 0
  1902. #endif
  1903. #ifndef DTP_OFFSET
  1904. #define DTP_OFFSET 0
  1905. #endif
  1906. +#ifdef TLS_ABOVE_TP
  1907. +#define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + TP_OFFSET)
  1908. +#define __pthread_self() ((pthread_t)(__get_tp() - sizeof(struct __pthread) - TP_OFFSET))
  1909. +#else
  1910. +#define TP_ADJ(p) (p)
  1911. +#define __pthread_self() ((pthread_t)__get_tp())
  1912. +#endif
  1913. +
  1914. #ifndef tls_mod_off_t
  1915. #define tls_mod_off_t size_t
  1916. #endif
  1917. @@ -141,7 +155,6 @@ hidden int __pthread_key_delete_impl(pthread_key_t);
  1918. extern hidden volatile size_t __pthread_tsd_size;
  1919. extern hidden void *__pthread_tsd_main[];
  1920. -extern hidden volatile int __aio_fut;
  1921. extern hidden volatile int __eintr_valid_flag;
  1922. hidden int __clone(int (*)(void *), void *, int, void *, ...);
  1923. @@ -176,6 +189,8 @@ hidden void __tl_sync(pthread_t);
  1924. extern hidden volatile int __thread_list_lock;
  1925. +extern hidden volatile int __abort_lock[1];
  1926. +
  1927. extern hidden unsigned __default_stacksize;
  1928. extern hidden unsigned __default_guardsize;
  1929. diff --git a/src/internal/syscall.h b/src/internal/syscall.h
  1930. index 975a0031..d5f294d4 100644
  1931. --- a/src/internal/syscall.h
  1932. +++ b/src/internal/syscall.h
  1933. @@ -2,6 +2,7 @@
  1934. #define _INTERNAL_SYSCALL_H
  1935. #include <features.h>
  1936. +#include <errno.h>
  1937. #include <sys/syscall.h>
  1938. #include "syscall_arch.h"
  1939. @@ -57,15 +58,22 @@ hidden long __syscall_ret(unsigned long),
  1940. #define __syscall_cp(...) __SYSCALL_DISP(__syscall_cp,__VA_ARGS__)
  1941. #define syscall_cp(...) __syscall_ret(__syscall_cp(__VA_ARGS__))
  1942. -#ifndef SYSCALL_USE_SOCKETCALL
  1943. -#define __socketcall(nm,a,b,c,d,e,f) __syscall(SYS_##nm, a, b, c, d, e, f)
  1944. -#define __socketcall_cp(nm,a,b,c,d,e,f) __syscall_cp(SYS_##nm, a, b, c, d, e, f)
  1945. -#else
  1946. -#define __socketcall(nm,a,b,c,d,e,f) __syscall(SYS_socketcall, __SC_##nm, \
  1947. - ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
  1948. -#define __socketcall_cp(nm,a,b,c,d,e,f) __syscall_cp(SYS_socketcall, __SC_##nm, \
  1949. - ((long [6]){ (long)a, (long)b, (long)c, (long)d, (long)e, (long)f }))
  1950. -#endif
  1951. +static inline long __alt_socketcall(int sys, int sock, int cp, long a, long b, long c, long d, long e, long f)
  1952. +{
  1953. + long r;
  1954. + if (cp) r = __syscall_cp(sys, a, b, c, d, e, f);
  1955. + else r = __syscall(sys, a, b, c, d, e, f);
  1956. + if (r != -ENOSYS) return r;
  1957. +#ifdef SYS_socketcall
  1958. + if (cp) r = __syscall_cp(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f}));
  1959. + else r = __syscall(SYS_socketcall, sock, ((long[6]){a, b, c, d, e, f}));
  1960. +#endif
  1961. + return r;
  1962. +}
  1963. +#define __socketcall(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 0, \
  1964. + (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))
  1965. +#define __socketcall_cp(nm, a, b, c, d, e, f) __alt_socketcall(SYS_##nm, __SC_##nm, 1, \
  1966. + (long)(a), (long)(b), (long)(c), (long)(d), (long)(e), (long)(f))
  1967. /* fixup legacy 16-bit junk */
  1968. @@ -338,6 +346,12 @@ hidden long __syscall_ret(unsigned long),
  1969. #define __SC_recvmmsg 19
  1970. #define __SC_sendmmsg 20
  1971. +/* This is valid only because all socket syscalls are made via
  1972. + * socketcall, which always fills unused argument slots with zeros. */
  1973. +#ifndef SYS_accept
  1974. +#define SYS_accept SYS_accept4
  1975. +#endif
  1976. +
  1977. #ifndef SO_RCVTIMEO_OLD
  1978. #define SO_RCVTIMEO_OLD 20
  1979. #endif
  1980. diff --git a/src/ldso/dlerror.c b/src/ldso/dlerror.c
  1981. index 3fcc7779..afe59253 100644
  1982. --- a/src/ldso/dlerror.c
  1983. +++ b/src/ldso/dlerror.c
  1984. @@ -4,6 +4,12 @@
  1985. #include "pthread_impl.h"
  1986. #include "dynlink.h"
  1987. #include "lock.h"
  1988. +#include "fork_impl.h"
  1989. +
  1990. +#define malloc __libc_malloc
  1991. +#define calloc __libc_calloc
  1992. +#define realloc __libc_realloc
  1993. +#define free __libc_free
  1994. char *dlerror()
  1995. {
  1996. @@ -19,6 +25,7 @@ char *dlerror()
  1997. static volatile int freebuf_queue_lock[1];
  1998. static void **freebuf_queue;
  1999. +volatile int *const __dlerror_lockptr = freebuf_queue_lock;
  2000. void __dl_thread_cleanup(void)
  2001. {
  2002. @@ -35,13 +42,16 @@ void __dl_thread_cleanup(void)
  2003. hidden void __dl_vseterr(const char *fmt, va_list ap)
  2004. {
  2005. LOCK(freebuf_queue_lock);
  2006. - while (freebuf_queue) {
  2007. - void **p = freebuf_queue;
  2008. - freebuf_queue = *p;
  2009. - free(p);
  2010. - }
  2011. + void **q = freebuf_queue;
  2012. + freebuf_queue = 0;
  2013. UNLOCK(freebuf_queue_lock);
  2014. + while (q) {
  2015. + void **p = *q;
  2016. + free(q);
  2017. + q = p;
  2018. + }
  2019. +
  2020. va_list ap2;
  2021. va_copy(ap2, ap);
  2022. pthread_t self = __pthread_self();
  2023. diff --git a/src/legacy/lutimes.c b/src/legacy/lutimes.c
  2024. index 2e5502d1..dd465923 100644
  2025. --- a/src/legacy/lutimes.c
  2026. +++ b/src/legacy/lutimes.c
  2027. @@ -6,9 +6,11 @@
  2028. int lutimes(const char *filename, const struct timeval tv[2])
  2029. {
  2030. struct timespec times[2];
  2031. - times[0].tv_sec = tv[0].tv_sec;
  2032. - times[0].tv_nsec = tv[0].tv_usec * 1000;
  2033. - times[1].tv_sec = tv[1].tv_sec;
  2034. - times[1].tv_nsec = tv[1].tv_usec * 1000;
  2035. - return utimensat(AT_FDCWD, filename, times, AT_SYMLINK_NOFOLLOW);
  2036. + if (tv) {
  2037. + times[0].tv_sec = tv[0].tv_sec;
  2038. + times[0].tv_nsec = tv[0].tv_usec * 1000;
  2039. + times[1].tv_sec = tv[1].tv_sec;
  2040. + times[1].tv_nsec = tv[1].tv_usec * 1000;
  2041. + }
  2042. + return utimensat(AT_FDCWD, filename, tv ? times : 0, AT_SYMLINK_NOFOLLOW);
  2043. }
  2044. diff --git a/src/linux/gettid.c b/src/linux/gettid.c
  2045. new file mode 100644
  2046. index 00000000..70767137
  2047. --- /dev/null
  2048. +++ b/src/linux/gettid.c
  2049. @@ -0,0 +1,8 @@
  2050. +#define _GNU_SOURCE
  2051. +#include <unistd.h>
  2052. +#include "pthread_impl.h"
  2053. +
  2054. +pid_t gettid(void)
  2055. +{
  2056. + return __pthread_self()->tid;
  2057. +}
  2058. diff --git a/src/linux/membarrier.c b/src/linux/membarrier.c
  2059. index 9ebe906e..343f7360 100644
  2060. --- a/src/linux/membarrier.c
  2061. +++ b/src/linux/membarrier.c
  2062. @@ -9,13 +9,8 @@ static void dummy_0(void)
  2063. {
  2064. }
  2065. -static void dummy_1(pthread_t t)
  2066. -{
  2067. -}
  2068. -
  2069. weak_alias(dummy_0, __tl_lock);
  2070. weak_alias(dummy_0, __tl_unlock);
  2071. -weak_alias(dummy_1, __tl_sync);
  2072. static sem_t barrier_sem;
  2073. diff --git a/src/linux/setgroups.c b/src/linux/setgroups.c
  2074. index 1248fdbf..47142f14 100644
  2075. --- a/src/linux/setgroups.c
  2076. +++ b/src/linux/setgroups.c
  2077. @@ -1,8 +1,36 @@
  2078. #define _GNU_SOURCE
  2079. #include <unistd.h>
  2080. +#include <signal.h>
  2081. #include "syscall.h"
  2082. +#include "libc.h"
  2083. +
  2084. +struct ctx {
  2085. + size_t count;
  2086. + const gid_t *list;
  2087. + int ret;
  2088. +};
  2089. +
  2090. +static void do_setgroups(void *p)
  2091. +{
  2092. + struct ctx *c = p;
  2093. + if (c->ret<0) return;
  2094. + int ret = __syscall(SYS_setgroups, c->count, c->list);
  2095. + if (ret && !c->ret) {
  2096. + /* If one thread fails to set groups after another has already
  2097. + * succeeded, forcibly killing the process is the only safe
  2098. + * thing to do. State is inconsistent and dangerous. Use
  2099. + * SIGKILL because it is uncatchable. */
  2100. + __block_all_sigs(0);
  2101. + __syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL);
  2102. + }
  2103. + c->ret = ret;
  2104. +}
  2105. int setgroups(size_t count, const gid_t list[])
  2106. {
  2107. - return syscall(SYS_setgroups, count, list);
  2108. + /* ret is initially nonzero so that failure of the first thread does not
  2109. + * trigger the safety kill above. */
  2110. + struct ctx c = { .count = count, .list = list, .ret = 1 };
  2111. + __synccall(do_setgroups, &c);
  2112. + return __syscall_ret(c.ret);
  2113. }
  2114. diff --git a/src/locale/dcngettext.c b/src/locale/dcngettext.c
  2115. index 4c304393..d1e6c6d1 100644
  2116. --- a/src/locale/dcngettext.c
  2117. +++ b/src/locale/dcngettext.c
  2118. @@ -10,6 +10,12 @@
  2119. #include "atomic.h"
  2120. #include "pleval.h"
  2121. #include "lock.h"
  2122. +#include "fork_impl.h"
  2123. +
  2124. +#define malloc __libc_malloc
  2125. +#define calloc __libc_calloc
  2126. +#define realloc undef
  2127. +#define free undef
  2128. struct binding {
  2129. struct binding *next;
  2130. @@ -34,9 +40,11 @@ static char *gettextdir(const char *domainname, size_t *dirlen)
  2131. return 0;
  2132. }
  2133. +static volatile int lock[1];
  2134. +volatile int *const __gettext_lockptr = lock;
  2135. +
  2136. char *bindtextdomain(const char *domainname, const char *dirname)
  2137. {
  2138. - static volatile int lock[1];
  2139. struct binding *p, *q;
  2140. if (!domainname) return 0;
  2141. diff --git a/src/locale/freelocale.c b/src/locale/freelocale.c
  2142. index 802b8bfe..385d1206 100644
  2143. --- a/src/locale/freelocale.c
  2144. +++ b/src/locale/freelocale.c
  2145. @@ -1,6 +1,11 @@
  2146. #include <stdlib.h>
  2147. #include "locale_impl.h"
  2148. +#define malloc undef
  2149. +#define calloc undef
  2150. +#define realloc undef
  2151. +#define free __libc_free
  2152. +
  2153. void freelocale(locale_t l)
  2154. {
  2155. if (__loc_is_allocated(l)) free(l);
  2156. diff --git a/src/locale/locale_map.c b/src/locale/locale_map.c
  2157. index 2321bac0..da61f7fc 100644
  2158. --- a/src/locale/locale_map.c
  2159. +++ b/src/locale/locale_map.c
  2160. @@ -1,9 +1,16 @@
  2161. #include <locale.h>
  2162. #include <string.h>
  2163. #include <sys/mman.h>
  2164. +#include <stdlib.h>
  2165. #include "locale_impl.h"
  2166. #include "libc.h"
  2167. #include "lock.h"
  2168. +#include "fork_impl.h"
  2169. +
  2170. +#define malloc __libc_malloc
  2171. +#define calloc undef
  2172. +#define realloc undef
  2173. +#define free undef
  2174. const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
  2175. {
  2176. @@ -21,9 +28,11 @@ static const char envvars[][12] = {
  2177. "LC_MESSAGES",
  2178. };
  2179. +volatile int __locale_lock[1];
  2180. +volatile int *const __locale_lockptr = __locale_lock;
  2181. +
  2182. const struct __locale_map *__get_locale(int cat, const char *val)
  2183. {
  2184. - static volatile int lock[1];
  2185. static void *volatile loc_head;
  2186. const struct __locale_map *p;
  2187. struct __locale_map *new = 0;
  2188. @@ -54,20 +63,12 @@ const struct __locale_map *__get_locale(int cat, const char *val)
  2189. for (p=loc_head; p; p=p->next)
  2190. if (!strcmp(val, p->name)) return p;
  2191. - LOCK(lock);
  2192. -
  2193. - for (p=loc_head; p; p=p->next)
  2194. - if (!strcmp(val, p->name)) {
  2195. - UNLOCK(lock);
  2196. - return p;
  2197. - }
  2198. -
  2199. if (!libc.secure) path = getenv("MUSL_LOCPATH");
  2200. /* FIXME: add a default path? */
  2201. if (path) for (; *path; path=z+!!*z) {
  2202. z = __strchrnul(path, ':');
  2203. - l = z - path - !!*z;
  2204. + l = z - path;
  2205. if (l >= sizeof buf - n - 2) continue;
  2206. memcpy(buf, path, l);
  2207. buf[l] = '/';
  2208. @@ -108,6 +109,5 @@ const struct __locale_map *__get_locale(int cat, const char *val)
  2209. * requested name was "C" or "POSIX". */
  2210. if (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8;
  2211. - UNLOCK(lock);
  2212. return new;
  2213. }
  2214. diff --git a/src/locale/newlocale.c b/src/locale/newlocale.c
  2215. index d20a8489..9ac3cd38 100644
  2216. --- a/src/locale/newlocale.c
  2217. +++ b/src/locale/newlocale.c
  2218. @@ -2,16 +2,15 @@
  2219. #include <string.h>
  2220. #include <pthread.h>
  2221. #include "locale_impl.h"
  2222. +#include "lock.h"
  2223. -static pthread_once_t default_locale_once;
  2224. -static struct __locale_struct default_locale, default_ctype_locale;
  2225. +#define malloc __libc_malloc
  2226. +#define calloc undef
  2227. +#define realloc undef
  2228. +#define free undef
  2229. -static void default_locale_init(void)
  2230. -{
  2231. - for (int i=0; i<LC_ALL; i++)
  2232. - default_locale.cat[i] = __get_locale(i, "");
  2233. - default_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];
  2234. -}
  2235. +static int default_locale_init_done;
  2236. +static struct __locale_struct default_locale, default_ctype_locale;
  2237. int __loc_is_allocated(locale_t loc)
  2238. {
  2239. @@ -19,7 +18,7 @@ int __loc_is_allocated(locale_t loc)
  2240. && loc != &default_locale && loc != &default_ctype_locale;
  2241. }
  2242. -locale_t __newlocale(int mask, const char *name, locale_t loc)
  2243. +static locale_t do_newlocale(int mask, const char *name, locale_t loc)
  2244. {
  2245. struct __locale_struct tmp;
  2246. @@ -44,7 +43,12 @@ locale_t __newlocale(int mask, const char *name, locale_t loc)
  2247. /* And provide builtins for the initial default locale, and a
  2248. * variant of the C locale honoring the default locale's encoding. */
  2249. - pthread_once(&default_locale_once, default_locale_init);
  2250. + if (!default_locale_init_done) {
  2251. + for (int i=0; i<LC_ALL; i++)
  2252. + default_locale.cat[i] = __get_locale(i, "");
  2253. + default_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];
  2254. + default_locale_init_done = 1;
  2255. + }
  2256. if (!memcmp(&tmp, &default_locale, sizeof tmp)) return &default_locale;
  2257. if (!memcmp(&tmp, &default_ctype_locale, sizeof tmp))
  2258. return &default_ctype_locale;
  2259. @@ -55,4 +59,12 @@ locale_t __newlocale(int mask, const char *name, locale_t loc)
  2260. return loc;
  2261. }
  2262. +locale_t __newlocale(int mask, const char *name, locale_t loc)
  2263. +{
  2264. + LOCK(__locale_lock);
  2265. + loc = do_newlocale(mask, name, loc);
  2266. + UNLOCK(__locale_lock);
  2267. + return loc;
  2268. +}
  2269. +
  2270. weak_alias(__newlocale, newlocale);
  2271. diff --git a/src/locale/setlocale.c b/src/locale/setlocale.c
  2272. index 2bc7b500..360c4437 100644
  2273. --- a/src/locale/setlocale.c
  2274. +++ b/src/locale/setlocale.c
  2275. @@ -9,12 +9,11 @@ static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
  2276. char *setlocale(int cat, const char *name)
  2277. {
  2278. - static volatile int lock[1];
  2279. const struct __locale_map *lm;
  2280. if ((unsigned)cat > LC_ALL) return 0;
  2281. - LOCK(lock);
  2282. + LOCK(__locale_lock);
  2283. /* For LC_ALL, setlocale is required to return a string which
  2284. * encodes the current setting for all categories. The format of
  2285. @@ -36,7 +35,7 @@ char *setlocale(int cat, const char *name)
  2286. }
  2287. lm = __get_locale(i, part);
  2288. if (lm == LOC_MAP_FAILED) {
  2289. - UNLOCK(lock);
  2290. + UNLOCK(__locale_lock);
  2291. return 0;
  2292. }
  2293. tmp_locale.cat[i] = lm;
  2294. @@ -57,14 +56,14 @@ char *setlocale(int cat, const char *name)
  2295. s += l+1;
  2296. }
  2297. *--s = 0;
  2298. - UNLOCK(lock);
  2299. + UNLOCK(__locale_lock);
  2300. return same==LC_ALL ? (char *)part : buf;
  2301. }
  2302. if (name) {
  2303. lm = __get_locale(cat, name);
  2304. if (lm == LOC_MAP_FAILED) {
  2305. - UNLOCK(lock);
  2306. + UNLOCK(__locale_lock);
  2307. return 0;
  2308. }
  2309. libc.global_locale.cat[cat] = lm;
  2310. @@ -73,7 +72,7 @@ char *setlocale(int cat, const char *name)
  2311. }
  2312. char *ret = lm ? (char *)lm->name : "C";
  2313. - UNLOCK(lock);
  2314. + UNLOCK(__locale_lock);
  2315. return ret;
  2316. }
  2317. diff --git a/src/malloc/free.c b/src/malloc/free.c
  2318. new file mode 100644
  2319. index 00000000..f17a952c
  2320. --- /dev/null
  2321. +++ b/src/malloc/free.c
  2322. @@ -0,0 +1,6 @@
  2323. +#include <stdlib.h>
  2324. +
  2325. +void free(void *p)
  2326. +{
  2327. + return __libc_free(p);
  2328. +}
  2329. diff --git a/src/malloc/libc_calloc.c b/src/malloc/libc_calloc.c
  2330. new file mode 100644
  2331. index 00000000..d25eabea
  2332. --- /dev/null
  2333. +++ b/src/malloc/libc_calloc.c
  2334. @@ -0,0 +1,4 @@
  2335. +#define calloc __libc_calloc
  2336. +#define malloc __libc_malloc
  2337. +
  2338. +#include "calloc.c"
  2339. diff --git a/src/malloc/lite_malloc.c b/src/malloc/lite_malloc.c
  2340. index f8931ba5..43a988fb 100644
  2341. --- a/src/malloc/lite_malloc.c
  2342. +++ b/src/malloc/lite_malloc.c
  2343. @@ -6,6 +6,7 @@
  2344. #include "libc.h"
  2345. #include "lock.h"
  2346. #include "syscall.h"
  2347. +#include "fork_impl.h"
  2348. #define ALIGN 16
  2349. @@ -31,10 +32,12 @@ static int traverses_stack_p(uintptr_t old, uintptr_t new)
  2350. return 0;
  2351. }
  2352. +static volatile int lock[1];
  2353. +volatile int *const __bump_lockptr = lock;
  2354. +
  2355. static void *__simple_malloc(size_t n)
  2356. {
  2357. static uintptr_t brk, cur, end;
  2358. - static volatile int lock[1];
  2359. static unsigned mmap_step;
  2360. size_t align=1;
  2361. void *p;
  2362. @@ -100,4 +103,16 @@ static void *__simple_malloc(size_t n)
  2363. return p;
  2364. }
  2365. -weak_alias(__simple_malloc, malloc);
  2366. +weak_alias(__simple_malloc, __libc_malloc_impl);
  2367. +
  2368. +void *__libc_malloc(size_t n)
  2369. +{
  2370. + return __libc_malloc_impl(n);
  2371. +}
  2372. +
  2373. +static void *default_malloc(size_t n)
  2374. +{
  2375. + return __libc_malloc_impl(n);
  2376. +}
  2377. +
  2378. +weak_alias(default_malloc, malloc);
  2379. diff --git a/src/malloc/mallocng/glue.h b/src/malloc/mallocng/glue.h
  2380. index 16acd1ea..151c48b8 100644
  2381. --- a/src/malloc/mallocng/glue.h
  2382. +++ b/src/malloc/mallocng/glue.h
  2383. @@ -20,6 +20,10 @@
  2384. #define is_allzero __malloc_allzerop
  2385. #define dump_heap __dump_heap
  2386. +#define malloc __libc_malloc_impl
  2387. +#define realloc __libc_realloc
  2388. +#define free __libc_free
  2389. +
  2390. #if USE_REAL_ASSERT
  2391. #include <assert.h>
  2392. #else
  2393. @@ -56,7 +60,8 @@ __attribute__((__visibility__("hidden")))
  2394. extern int __malloc_lock[1];
  2395. #define LOCK_OBJ_DEF \
  2396. -int __malloc_lock[1];
  2397. +int __malloc_lock[1]; \
  2398. +void __malloc_atfork(int who) { malloc_atfork(who); }
  2399. static inline void rdlock()
  2400. {
  2401. @@ -73,5 +78,16 @@ static inline void unlock()
  2402. static inline void upgradelock()
  2403. {
  2404. }
  2405. +static inline void resetlock()
  2406. +{
  2407. + __malloc_lock[0] = 0;
  2408. +}
  2409. +
  2410. +static inline void malloc_atfork(int who)
  2411. +{
  2412. + if (who<0) rdlock();
  2413. + else if (who>0) resetlock();
  2414. + else unlock();
  2415. +}
  2416. #endif
  2417. diff --git a/src/malloc/mallocng/malloc_usable_size.c b/src/malloc/mallocng/malloc_usable_size.c
  2418. index a440a4ea..ce6a960c 100644
  2419. --- a/src/malloc/mallocng/malloc_usable_size.c
  2420. +++ b/src/malloc/mallocng/malloc_usable_size.c
  2421. @@ -3,6 +3,7 @@
  2422. size_t malloc_usable_size(void *p)
  2423. {
  2424. + if (!p) return 0;
  2425. struct meta *g = get_meta(p);
  2426. int idx = get_slot_index(p);
  2427. size_t stride = get_stride(g);
  2428. diff --git a/src/malloc/oldmalloc/malloc.c b/src/malloc/oldmalloc/malloc.c
  2429. index c0997ad8..53f5f959 100644
  2430. --- a/src/malloc/oldmalloc/malloc.c
  2431. +++ b/src/malloc/oldmalloc/malloc.c
  2432. @@ -9,6 +9,11 @@
  2433. #include "atomic.h"
  2434. #include "pthread_impl.h"
  2435. #include "malloc_impl.h"
  2436. +#include "fork_impl.h"
  2437. +
  2438. +#define malloc __libc_malloc
  2439. +#define realloc __libc_realloc
  2440. +#define free __libc_free
  2441. #if defined(__GNUC__) && defined(__PIC__)
  2442. #define inline inline __attribute__((always_inline))
  2443. @@ -527,3 +532,21 @@ void __malloc_donate(char *start, char *end)
  2444. c->csize = n->psize = C_INUSE | (end-start);
  2445. __bin_chunk(c);
  2446. }
  2447. +
  2448. +void __malloc_atfork(int who)
  2449. +{
  2450. + if (who<0) {
  2451. + lock(mal.split_merge_lock);
  2452. + for (int i=0; i<64; i++)
  2453. + lock(mal.bins[i].lock);
  2454. + } else if (!who) {
  2455. + for (int i=0; i<64; i++)
  2456. + unlock(mal.bins[i].lock);
  2457. + unlock(mal.split_merge_lock);
  2458. + } else {
  2459. + for (int i=0; i<64; i++)
  2460. + mal.bins[i].lock[0] = mal.bins[i].lock[1] = 0;
  2461. + mal.split_merge_lock[1] = 0;
  2462. + mal.split_merge_lock[0] = 0;
  2463. + }
  2464. +}
  2465. diff --git a/src/malloc/realloc.c b/src/malloc/realloc.c
  2466. new file mode 100644
  2467. index 00000000..fb0e8b7c
  2468. --- /dev/null
  2469. +++ b/src/malloc/realloc.c
  2470. @@ -0,0 +1,6 @@
  2471. +#include <stdlib.h>
  2472. +
  2473. +void *realloc(void *p, size_t n)
  2474. +{
  2475. + return __libc_realloc(p, n);
  2476. +}
  2477. diff --git a/src/malloc/reallocarray.c b/src/malloc/reallocarray.c
  2478. new file mode 100644
  2479. index 00000000..4a6ebe46
  2480. --- /dev/null
  2481. +++ b/src/malloc/reallocarray.c
  2482. @@ -0,0 +1,13 @@
  2483. +#define _BSD_SOURCE
  2484. +#include <errno.h>
  2485. +#include <stdlib.h>
  2486. +
  2487. +void *reallocarray(void *ptr, size_t m, size_t n)
  2488. +{
  2489. + if (n && m > -1 / n) {
  2490. + errno = ENOMEM;
  2491. + return 0;
  2492. + }
  2493. +
  2494. + return realloc(ptr, m * n);
  2495. +}
  2496. diff --git a/src/math/__math_invalidl.c b/src/math/__math_invalidl.c
  2497. new file mode 100644
  2498. index 00000000..1fca99de
  2499. --- /dev/null
  2500. +++ b/src/math/__math_invalidl.c
  2501. @@ -0,0 +1,9 @@
  2502. +#include <float.h>
  2503. +#include "libm.h"
  2504. +
  2505. +#if LDBL_MANT_DIG != DBL_MANT_DIG
  2506. +long double __math_invalidl(long double x)
  2507. +{
  2508. + return (x - x) / (x - x);
  2509. +}
  2510. +#endif
  2511. diff --git a/src/math/arm/fabs.c b/src/math/arm/fabs.c
  2512. index f890520a..6e1d367d 100644
  2513. --- a/src/math/arm/fabs.c
  2514. +++ b/src/math/arm/fabs.c
  2515. @@ -1,6 +1,6 @@
  2516. #include <math.h>
  2517. -#if __ARM_PCS_VFP
  2518. +#if __ARM_PCS_VFP && __ARM_FP&8
  2519. double fabs(double x)
  2520. {
  2521. diff --git a/src/math/arm/sqrt.c b/src/math/arm/sqrt.c
  2522. index 874af960..567e2e91 100644
  2523. --- a/src/math/arm/sqrt.c
  2524. +++ b/src/math/arm/sqrt.c
  2525. @@ -1,6 +1,6 @@
  2526. #include <math.h>
  2527. -#if __ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)
  2528. +#if (__ARM_PCS_VFP || (__VFP_FP__ && !__SOFTFP__)) && (__ARM_FP&8)
  2529. double sqrt(double x)
  2530. {
  2531. diff --git a/src/math/sqrt.c b/src/math/sqrt.c
  2532. index f1f6d76c..5ba26559 100644
  2533. --- a/src/math/sqrt.c
  2534. +++ b/src/math/sqrt.c
  2535. @@ -1,184 +1,158 @@
  2536. -/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrt.c */
  2537. -/*
  2538. - * ====================================================
  2539. - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  2540. - *
  2541. - * Developed at SunSoft, a Sun Microsystems, Inc. business.
  2542. - * Permission to use, copy, modify, and distribute this
  2543. - * software is freely granted, provided that this notice
  2544. - * is preserved.
  2545. - * ====================================================
  2546. - */
  2547. -/* sqrt(x)
  2548. - * Return correctly rounded sqrt.
  2549. - * ------------------------------------------
  2550. - * | Use the hardware sqrt if you have one |
  2551. - * ------------------------------------------
  2552. - * Method:
  2553. - * Bit by bit method using integer arithmetic. (Slow, but portable)
  2554. - * 1. Normalization
  2555. - * Scale x to y in [1,4) with even powers of 2:
  2556. - * find an integer k such that 1 <= (y=x*2^(2k)) < 4, then
  2557. - * sqrt(x) = 2^k * sqrt(y)
  2558. - * 2. Bit by bit computation
  2559. - * Let q = sqrt(y) truncated to i bit after binary point (q = 1),
  2560. - * i 0
  2561. - * i+1 2
  2562. - * s = 2*q , and y = 2 * ( y - q ). (1)
  2563. - * i i i i
  2564. - *
  2565. - * To compute q from q , one checks whether
  2566. - * i+1 i
  2567. - *
  2568. - * -(i+1) 2
  2569. - * (q + 2 ) <= y. (2)
  2570. - * i
  2571. - * -(i+1)
  2572. - * If (2) is false, then q = q ; otherwise q = q + 2 .
  2573. - * i+1 i i+1 i
  2574. - *
  2575. - * With some algebric manipulation, it is not difficult to see
  2576. - * that (2) is equivalent to
  2577. - * -(i+1)
  2578. - * s + 2 <= y (3)
  2579. - * i i
  2580. - *
  2581. - * The advantage of (3) is that s and y can be computed by
  2582. - * i i
  2583. - * the following recurrence formula:
  2584. - * if (3) is false
  2585. - *
  2586. - * s = s , y = y ; (4)
  2587. - * i+1 i i+1 i
  2588. - *
  2589. - * otherwise,
  2590. - * -i -(i+1)
  2591. - * s = s + 2 , y = y - s - 2 (5)
  2592. - * i+1 i i+1 i i
  2593. - *
  2594. - * One may easily use induction to prove (4) and (5).
  2595. - * Note. Since the left hand side of (3) contain only i+2 bits,
  2596. - * it does not necessary to do a full (53-bit) comparison
  2597. - * in (3).
  2598. - * 3. Final rounding
  2599. - * After generating the 53 bits result, we compute one more bit.
  2600. - * Together with the remainder, we can decide whether the
  2601. - * result is exact, bigger than 1/2ulp, or less than 1/2ulp
  2602. - * (it will never equal to 1/2ulp).
  2603. - * The rounding mode can be detected by checking whether
  2604. - * huge + tiny is equal to huge, and whether huge - tiny is
  2605. - * equal to huge for some floating point number "huge" and "tiny".
  2606. - *
  2607. - * Special cases:
  2608. - * sqrt(+-0) = +-0 ... exact
  2609. - * sqrt(inf) = inf
  2610. - * sqrt(-ve) = NaN ... with invalid signal
  2611. - * sqrt(NaN) = NaN ... with invalid signal for signaling NaN
  2612. - */
  2613. -
  2614. +#include <stdint.h>
  2615. +#include <math.h>
  2616. #include "libm.h"
  2617. +#include "sqrt_data.h"
  2618. -static const double tiny = 1.0e-300;
  2619. +#define FENV_SUPPORT 1
  2620. -double sqrt(double x)
  2621. +/* returns a*b*2^-32 - e, with error 0 <= e < 1. */
  2622. +static inline uint32_t mul32(uint32_t a, uint32_t b)
  2623. {
  2624. - double z;
  2625. - int32_t sign = (int)0x80000000;
  2626. - int32_t ix0,s0,q,m,t,i;
  2627. - uint32_t r,t1,s1,ix1,q1;
  2628. + return (uint64_t)a*b >> 32;
  2629. +}
  2630. - EXTRACT_WORDS(ix0, ix1, x);
  2631. +/* returns a*b*2^-64 - e, with error 0 <= e < 3. */
  2632. +static inline uint64_t mul64(uint64_t a, uint64_t b)
  2633. +{
  2634. + uint64_t ahi = a>>32;
  2635. + uint64_t alo = a&0xffffffff;
  2636. + uint64_t bhi = b>>32;
  2637. + uint64_t blo = b&0xffffffff;
  2638. + return ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32);
  2639. +}
  2640. - /* take care of Inf and NaN */
  2641. - if ((ix0&0x7ff00000) == 0x7ff00000) {
  2642. - return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
  2643. - }
  2644. - /* take care of zero */
  2645. - if (ix0 <= 0) {
  2646. - if (((ix0&~sign)|ix1) == 0)
  2647. - return x; /* sqrt(+-0) = +-0 */
  2648. - if (ix0 < 0)
  2649. - return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
  2650. - }
  2651. - /* normalize x */
  2652. - m = ix0>>20;
  2653. - if (m == 0) { /* subnormal x */
  2654. - while (ix0 == 0) {
  2655. - m -= 21;
  2656. - ix0 |= (ix1>>11);
  2657. - ix1 <<= 21;
  2658. - }
  2659. - for (i=0; (ix0&0x00100000) == 0; i++)
  2660. - ix0<<=1;
  2661. - m -= i - 1;
  2662. - ix0 |= ix1>>(32-i);
  2663. - ix1 <<= i;
  2664. - }
  2665. - m -= 1023; /* unbias exponent */
  2666. - ix0 = (ix0&0x000fffff)|0x00100000;
  2667. - if (m & 1) { /* odd m, double x to make it even */
  2668. - ix0 += ix0 + ((ix1&sign)>>31);
  2669. - ix1 += ix1;
  2670. - }
  2671. - m >>= 1; /* m = [m/2] */
  2672. -
  2673. - /* generate sqrt(x) bit by bit */
  2674. - ix0 += ix0 + ((ix1&sign)>>31);
  2675. - ix1 += ix1;
  2676. - q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
  2677. - r = 0x00200000; /* r = moving bit from right to left */
  2678. -
  2679. - while (r != 0) {
  2680. - t = s0 + r;
  2681. - if (t <= ix0) {
  2682. - s0 = t + r;
  2683. - ix0 -= t;
  2684. - q += r;
  2685. - }
  2686. - ix0 += ix0 + ((ix1&sign)>>31);
  2687. - ix1 += ix1;
  2688. - r >>= 1;
  2689. - }
  2690. +double sqrt(double x)
  2691. +{
  2692. + uint64_t ix, top, m;
  2693. - r = sign;
  2694. - while (r != 0) {
  2695. - t1 = s1 + r;
  2696. - t = s0;
  2697. - if (t < ix0 || (t == ix0 && t1 <= ix1)) {
  2698. - s1 = t1 + r;
  2699. - if ((t1&sign) == sign && (s1&sign) == 0)
  2700. - s0++;
  2701. - ix0 -= t;
  2702. - if (ix1 < t1)
  2703. - ix0--;
  2704. - ix1 -= t1;
  2705. - q1 += r;
  2706. - }
  2707. - ix0 += ix0 + ((ix1&sign)>>31);
  2708. - ix1 += ix1;
  2709. - r >>= 1;
  2710. + /* special case handling. */
  2711. + ix = asuint64(x);
  2712. + top = ix >> 52;
  2713. + if (predict_false(top - 0x001 >= 0x7ff - 0x001)) {
  2714. + /* x < 0x1p-1022 or inf or nan. */
  2715. + if (ix * 2 == 0)
  2716. + return x;
  2717. + if (ix == 0x7ff0000000000000)
  2718. + return x;
  2719. + if (ix > 0x7ff0000000000000)
  2720. + return __math_invalid(x);
  2721. + /* x is subnormal, normalize it. */
  2722. + ix = asuint64(x * 0x1p52);
  2723. + top = ix >> 52;
  2724. + top -= 52;
  2725. }
  2726. - /* use floating add to find out rounding direction */
  2727. - if ((ix0|ix1) != 0) {
  2728. - z = 1.0 - tiny; /* raise inexact flag */
  2729. - if (z >= 1.0) {
  2730. - z = 1.0 + tiny;
  2731. - if (q1 == (uint32_t)0xffffffff) {
  2732. - q1 = 0;
  2733. - q++;
  2734. - } else if (z > 1.0) {
  2735. - if (q1 == (uint32_t)0xfffffffe)
  2736. - q++;
  2737. - q1 += 2;
  2738. - } else
  2739. - q1 += q1 & 1;
  2740. - }
  2741. + /* argument reduction:
  2742. + x = 4^e m; with integer e, and m in [1, 4)
  2743. + m: fixed point representation [2.62]
  2744. + 2^e is the exponent part of the result. */
  2745. + int even = top & 1;
  2746. + m = (ix << 11) | 0x8000000000000000;
  2747. + if (even) m >>= 1;
  2748. + top = (top + 0x3ff) >> 1;
  2749. +
  2750. + /* approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4)
  2751. +
  2752. + initial estimate:
  2753. + 7bit table lookup (1bit exponent and 6bit significand).
  2754. +
  2755. + iterative approximation:
  2756. + using 2 goldschmidt iterations with 32bit int arithmetics
  2757. + and a final iteration with 64bit int arithmetics.
  2758. +
  2759. + details:
  2760. +
  2761. + the relative error (e = r0 sqrt(m)-1) of a linear estimate
  2762. + (r0 = a m + b) is |e| < 0.085955 ~ 0x1.6p-4 at best,
  2763. + a table lookup is faster and needs one less iteration
  2764. + 6 bit lookup table (128b) gives |e| < 0x1.f9p-8
  2765. + 7 bit lookup table (256b) gives |e| < 0x1.fdp-9
  2766. + for single and double prec 6bit is enough but for quad
  2767. + prec 7bit is needed (or modified iterations). to avoid
  2768. + one more iteration >=13bit table would be needed (16k).
  2769. +
  2770. + a newton-raphson iteration for r is
  2771. + w = r*r
  2772. + u = 3 - m*w
  2773. + r = r*u/2
  2774. + can use a goldschmidt iteration for s at the end or
  2775. + s = m*r
  2776. +
  2777. + first goldschmidt iteration is
  2778. + s = m*r
  2779. + u = 3 - s*r
  2780. + r = r*u/2
  2781. + s = s*u/2
  2782. + next goldschmidt iteration is
  2783. + u = 3 - s*r
  2784. + r = r*u/2
  2785. + s = s*u/2
  2786. + and at the end r is not computed only s.
  2787. +
  2788. + they use the same amount of operations and converge at the
  2789. + same quadratic rate, i.e. if
  2790. + r1 sqrt(m) - 1 = e, then
  2791. + r2 sqrt(m) - 1 = -3/2 e^2 - 1/2 e^3
  2792. + the advantage of goldschmidt is that the mul for s and r
  2793. + are independent (computed in parallel), however it is not
  2794. + "self synchronizing": it only uses the input m in the
  2795. + first iteration so rounding errors accumulate. at the end
  2796. + or when switching to larger precision arithmetics rounding
  2797. + errors dominate so the first iteration should be used.
  2798. +
  2799. + the fixed point representations are
  2800. + m: 2.30 r: 0.32, s: 2.30, d: 2.30, u: 2.30, three: 2.30
  2801. + and after switching to 64 bit
  2802. + m: 2.62 r: 0.64, s: 2.62, d: 2.62, u: 2.62, three: 2.62 */
  2803. +
  2804. + static const uint64_t three = 0xc0000000;
  2805. + uint64_t r, s, d, u, i;
  2806. +
  2807. + i = (ix >> 46) % 128;
  2808. + r = (uint32_t)__rsqrt_tab[i] << 16;
  2809. + /* |r sqrt(m) - 1| < 0x1.fdp-9 */
  2810. + s = mul32(m>>32, r);
  2811. + /* |s/sqrt(m) - 1| < 0x1.fdp-9 */
  2812. + d = mul32(s, r);
  2813. + u = three - d;
  2814. + r = mul32(r, u) << 1;
  2815. + /* |r sqrt(m) - 1| < 0x1.7bp-16 */
  2816. + s = mul32(s, u) << 1;
  2817. + /* |s/sqrt(m) - 1| < 0x1.7bp-16 */
  2818. + d = mul32(s, r);
  2819. + u = three - d;
  2820. + r = mul32(r, u) << 1;
  2821. + /* |r sqrt(m) - 1| < 0x1.3704p-29 (measured worst-case) */
  2822. + r = r << 32;
  2823. + s = mul64(m, r);
  2824. + d = mul64(s, r);
  2825. + u = (three<<32) - d;
  2826. + s = mul64(s, u); /* repr: 3.61 */
  2827. + /* -0x1p-57 < s - sqrt(m) < 0x1.8001p-61 */
  2828. + s = (s - 2) >> 9; /* repr: 12.52 */
  2829. + /* -0x1.09p-52 < s - sqrt(m) < -0x1.fffcp-63 */
  2830. +
  2831. + /* s < sqrt(m) < s + 0x1.09p-52,
  2832. + compute nearest rounded result:
  2833. + the nearest result to 52 bits is either s or s+0x1p-52,
  2834. + we can decide by comparing (2^52 s + 0.5)^2 to 2^104 m. */
  2835. + uint64_t d0, d1, d2;
  2836. + double y, t;
  2837. + d0 = (m << 42) - s*s;
  2838. + d1 = s - d0;
  2839. + d2 = d1 + s + 1;
  2840. + s += d1 >> 63;
  2841. + s &= 0x000fffffffffffff;
  2842. + s |= top << 52;
  2843. + y = asdouble(s);
  2844. + if (FENV_SUPPORT) {
  2845. + /* handle rounding modes and inexact exception:
  2846. + only (s+1)^2 == 2^42 m case is exact otherwise
  2847. + add a tiny value to cause the fenv effects. */
  2848. + uint64_t tiny = predict_false(d2==0) ? 0 : 0x0010000000000000;
  2849. + tiny |= (d1^d2) & 0x8000000000000000;
  2850. + t = asdouble(tiny);
  2851. + y = eval_as_double(y + t);
  2852. }
  2853. - ix0 = (q>>1) + 0x3fe00000;
  2854. - ix1 = q1>>1;
  2855. - if (q&1)
  2856. - ix1 |= sign;
  2857. - INSERT_WORDS(z, ix0 + ((uint32_t)m << 20), ix1);
  2858. - return z;
  2859. + return y;
  2860. }
  2861. diff --git a/src/math/sqrt_data.c b/src/math/sqrt_data.c
  2862. new file mode 100644
  2863. index 00000000..61bc22f4
  2864. --- /dev/null
  2865. +++ b/src/math/sqrt_data.c
  2866. @@ -0,0 +1,19 @@
  2867. +#include "sqrt_data.h"
  2868. +const uint16_t __rsqrt_tab[128] = {
  2869. +0xb451,0xb2f0,0xb196,0xb044,0xaef9,0xadb6,0xac79,0xab43,
  2870. +0xaa14,0xa8eb,0xa7c8,0xa6aa,0xa592,0xa480,0xa373,0xa26b,
  2871. +0xa168,0xa06a,0x9f70,0x9e7b,0x9d8a,0x9c9d,0x9bb5,0x9ad1,
  2872. +0x99f0,0x9913,0x983a,0x9765,0x9693,0x95c4,0x94f8,0x9430,
  2873. +0x936b,0x92a9,0x91ea,0x912e,0x9075,0x8fbe,0x8f0a,0x8e59,
  2874. +0x8daa,0x8cfe,0x8c54,0x8bac,0x8b07,0x8a64,0x89c4,0x8925,
  2875. +0x8889,0x87ee,0x8756,0x86c0,0x862b,0x8599,0x8508,0x8479,
  2876. +0x83ec,0x8361,0x82d8,0x8250,0x81c9,0x8145,0x80c2,0x8040,
  2877. +0xff02,0xfd0e,0xfb25,0xf947,0xf773,0xf5aa,0xf3ea,0xf234,
  2878. +0xf087,0xeee3,0xed47,0xebb3,0xea27,0xe8a3,0xe727,0xe5b2,
  2879. +0xe443,0xe2dc,0xe17a,0xe020,0xdecb,0xdd7d,0xdc34,0xdaf1,
  2880. +0xd9b3,0xd87b,0xd748,0xd61a,0xd4f1,0xd3cd,0xd2ad,0xd192,
  2881. +0xd07b,0xcf69,0xce5b,0xcd51,0xcc4a,0xcb48,0xca4a,0xc94f,
  2882. +0xc858,0xc764,0xc674,0xc587,0xc49d,0xc3b7,0xc2d4,0xc1f4,
  2883. +0xc116,0xc03c,0xbf65,0xbe90,0xbdbe,0xbcef,0xbc23,0xbb59,
  2884. +0xba91,0xb9cc,0xb90a,0xb84a,0xb78c,0xb6d0,0xb617,0xb560,
  2885. +};
  2886. diff --git a/src/math/sqrt_data.h b/src/math/sqrt_data.h
  2887. new file mode 100644
  2888. index 00000000..260c7f9c
  2889. --- /dev/null
  2890. +++ b/src/math/sqrt_data.h
  2891. @@ -0,0 +1,13 @@
  2892. +#ifndef _SQRT_DATA_H
  2893. +#define _SQRT_DATA_H
  2894. +
  2895. +#include <features.h>
  2896. +#include <stdint.h>
  2897. +
  2898. +/* if x in [1,2): i = (int)(64*x);
  2899. + if x in [2,4): i = (int)(32*x-64);
  2900. + __rsqrt_tab[i]*2^-16 is estimating 1/sqrt(x) with small relative error:
  2901. + |__rsqrt_tab[i]*0x1p-16*sqrt(x) - 1| < -0x1.fdp-9 < 2^-8 */
  2902. +extern hidden const uint16_t __rsqrt_tab[128];
  2903. +
  2904. +#endif
  2905. diff --git a/src/math/sqrtf.c b/src/math/sqrtf.c
  2906. index d6ace38a..740d81cb 100644
  2907. --- a/src/math/sqrtf.c
  2908. +++ b/src/math/sqrtf.c
  2909. @@ -1,83 +1,83 @@
  2910. -/* origin: FreeBSD /usr/src/lib/msun/src/e_sqrtf.c */
  2911. -/*
  2912. - * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
  2913. - */
  2914. -/*
  2915. - * ====================================================
  2916. - * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  2917. - *
  2918. - * Developed at SunPro, a Sun Microsystems, Inc. business.
  2919. - * Permission to use, copy, modify, and distribute this
  2920. - * software is freely granted, provided that this notice
  2921. - * is preserved.
  2922. - * ====================================================
  2923. - */
  2924. -
  2925. +#include <stdint.h>
  2926. +#include <math.h>
  2927. #include "libm.h"
  2928. +#include "sqrt_data.h"
  2929. -static const float tiny = 1.0e-30;
  2930. +#define FENV_SUPPORT 1
  2931. -float sqrtf(float x)
  2932. +static inline uint32_t mul32(uint32_t a, uint32_t b)
  2933. {
  2934. - float z;
  2935. - int32_t sign = (int)0x80000000;
  2936. - int32_t ix,s,q,m,t,i;
  2937. - uint32_t r;
  2938. + return (uint64_t)a*b >> 32;
  2939. +}
  2940. - GET_FLOAT_WORD(ix, x);
  2941. +/* see sqrt.c for more detailed comments. */
  2942. - /* take care of Inf and NaN */
  2943. - if ((ix&0x7f800000) == 0x7f800000)
  2944. - return x*x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf, sqrt(-inf)=sNaN */
  2945. +float sqrtf(float x)
  2946. +{
  2947. + uint32_t ix, m, m1, m0, even, ey;
  2948. - /* take care of zero */
  2949. - if (ix <= 0) {
  2950. - if ((ix&~sign) == 0)
  2951. - return x; /* sqrt(+-0) = +-0 */
  2952. - if (ix < 0)
  2953. - return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
  2954. - }
  2955. - /* normalize x */
  2956. - m = ix>>23;
  2957. - if (m == 0) { /* subnormal x */
  2958. - for (i = 0; (ix&0x00800000) == 0; i++)
  2959. - ix<<=1;
  2960. - m -= i - 1;
  2961. + ix = asuint(x);
  2962. + if (predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) {
  2963. + /* x < 0x1p-126 or inf or nan. */
  2964. + if (ix * 2 == 0)
  2965. + return x;
  2966. + if (ix == 0x7f800000)
  2967. + return x;
  2968. + if (ix > 0x7f800000)
  2969. + return __math_invalidf(x);
  2970. + /* x is subnormal, normalize it. */
  2971. + ix = asuint(x * 0x1p23f);
  2972. + ix -= 23 << 23;
  2973. }
  2974. - m -= 127; /* unbias exponent */
  2975. - ix = (ix&0x007fffff)|0x00800000;
  2976. - if (m&1) /* odd m, double x to make it even */
  2977. - ix += ix;
  2978. - m >>= 1; /* m = [m/2] */
  2979. - /* generate sqrt(x) bit by bit */
  2980. - ix += ix;
  2981. - q = s = 0; /* q = sqrt(x) */
  2982. - r = 0x01000000; /* r = moving bit from right to left */
  2983. + /* x = 4^e m; with int e and m in [1, 4). */
  2984. + even = ix & 0x00800000;
  2985. + m1 = (ix << 8) | 0x80000000;
  2986. + m0 = (ix << 7) & 0x7fffffff;
  2987. + m = even ? m0 : m1;
  2988. - while (r != 0) {
  2989. - t = s + r;
  2990. - if (t <= ix) {
  2991. - s = t+r;
  2992. - ix -= t;
  2993. - q += r;
  2994. - }
  2995. - ix += ix;
  2996. - r >>= 1;
  2997. - }
  2998. + /* 2^e is the exponent part of the return value. */
  2999. + ey = ix >> 1;
  3000. + ey += 0x3f800000 >> 1;
  3001. + ey &= 0x7f800000;
  3002. +
  3003. + /* compute r ~ 1/sqrt(m), s ~ sqrt(m) with 2 goldschmidt iterations. */
  3004. + static const uint32_t three = 0xc0000000;
  3005. + uint32_t r, s, d, u, i;
  3006. + i = (ix >> 17) % 128;
  3007. + r = (uint32_t)__rsqrt_tab[i] << 16;
  3008. + /* |r*sqrt(m) - 1| < 0x1p-8 */
  3009. + s = mul32(m, r);
  3010. + /* |s/sqrt(m) - 1| < 0x1p-8 */
  3011. + d = mul32(s, r);
  3012. + u = three - d;
  3013. + r = mul32(r, u) << 1;
  3014. + /* |r*sqrt(m) - 1| < 0x1.7bp-16 */
  3015. + s = mul32(s, u) << 1;
  3016. + /* |s/sqrt(m) - 1| < 0x1.7bp-16 */
  3017. + d = mul32(s, r);
  3018. + u = three - d;
  3019. + s = mul32(s, u);
  3020. + /* -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 */
  3021. + s = (s - 1)>>6;
  3022. + /* s < sqrt(m) < s + 0x1.08p-23 */
  3023. - /* use floating add to find out rounding direction */
  3024. - if (ix != 0) {
  3025. - z = 1.0f - tiny; /* raise inexact flag */
  3026. - if (z >= 1.0f) {
  3027. - z = 1.0f + tiny;
  3028. - if (z > 1.0f)
  3029. - q += 2;
  3030. - else
  3031. - q += q & 1;
  3032. - }
  3033. + /* compute nearest rounded result. */
  3034. + uint32_t d0, d1, d2;
  3035. + float y, t;
  3036. + d0 = (m << 16) - s*s;
  3037. + d1 = s - d0;
  3038. + d2 = d1 + s + 1;
  3039. + s += d1 >> 31;
  3040. + s &= 0x007fffff;
  3041. + s |= ey;
  3042. + y = asfloat(s);
  3043. + if (FENV_SUPPORT) {
  3044. + /* handle rounding and inexact exception. */
  3045. + uint32_t tiny = predict_false(d2==0) ? 0 : 0x01000000;
  3046. + tiny |= (d1^d2) & 0x80000000;
  3047. + t = asfloat(tiny);
  3048. + y = eval_as_float(y + t);
  3049. }
  3050. - ix = (q>>1) + 0x3f000000;
  3051. - SET_FLOAT_WORD(z, ix + ((uint32_t)m << 23));
  3052. - return z;
  3053. + return y;
  3054. }
  3055. diff --git a/src/math/sqrtl.c b/src/math/sqrtl.c
  3056. index 83a8f80c..1b9f19c7 100644
  3057. --- a/src/math/sqrtl.c
  3058. +++ b/src/math/sqrtl.c
  3059. @@ -1,7 +1,259 @@
  3060. +#include <stdint.h>
  3061. #include <math.h>
  3062. +#include <float.h>
  3063. +#include "libm.h"
  3064. +#if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
  3065. long double sqrtl(long double x)
  3066. {
  3067. - /* FIXME: implement in C, this is for LDBL_MANT_DIG == 64 only */
  3068. return sqrt(x);
  3069. }
  3070. +#elif (LDBL_MANT_DIG == 113 || LDBL_MANT_DIG == 64) && LDBL_MAX_EXP == 16384
  3071. +#include "sqrt_data.h"
  3072. +
  3073. +#define FENV_SUPPORT 1
  3074. +
  3075. +typedef struct {
  3076. + uint64_t hi;
  3077. + uint64_t lo;
  3078. +} u128;
  3079. +
  3080. +/* top: 16 bit sign+exponent, x: significand. */
  3081. +static inline long double mkldbl(uint64_t top, u128 x)
  3082. +{
  3083. + union ldshape u;
  3084. +#if LDBL_MANT_DIG == 113
  3085. + u.i2.hi = x.hi;
  3086. + u.i2.lo = x.lo;
  3087. + u.i2.hi &= 0x0000ffffffffffff;
  3088. + u.i2.hi |= top << 48;
  3089. +#elif LDBL_MANT_DIG == 64
  3090. + u.i.se = top;
  3091. + u.i.m = x.lo;
  3092. + /* force the top bit on non-zero (and non-subnormal) results. */
  3093. + if (top & 0x7fff)
  3094. + u.i.m |= 0x8000000000000000;
  3095. +#endif
  3096. + return u.f;
  3097. +}
  3098. +
  3099. +/* return: top 16 bit is sign+exp and following bits are the significand. */
  3100. +static inline u128 asu128(long double x)
  3101. +{
  3102. + union ldshape u = {.f=x};
  3103. + u128 r;
  3104. +#if LDBL_MANT_DIG == 113
  3105. + r.hi = u.i2.hi;
  3106. + r.lo = u.i2.lo;
  3107. +#elif LDBL_MANT_DIG == 64
  3108. + r.lo = u.i.m<<49;
  3109. + /* ignore the top bit: pseudo numbers are not handled. */
  3110. + r.hi = u.i.m>>15;
  3111. + r.hi &= 0x0000ffffffffffff;
  3112. + r.hi |= (uint64_t)u.i.se << 48;
  3113. +#endif
  3114. + return r;
  3115. +}
  3116. +
  3117. +/* returns a*b*2^-32 - e, with error 0 <= e < 1. */
  3118. +static inline uint32_t mul32(uint32_t a, uint32_t b)
  3119. +{
  3120. + return (uint64_t)a*b >> 32;
  3121. +}
  3122. +
  3123. +/* returns a*b*2^-64 - e, with error 0 <= e < 3. */
  3124. +static inline uint64_t mul64(uint64_t a, uint64_t b)
  3125. +{
  3126. + uint64_t ahi = a>>32;
  3127. + uint64_t alo = a&0xffffffff;
  3128. + uint64_t bhi = b>>32;
  3129. + uint64_t blo = b&0xffffffff;
  3130. + return ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32);
  3131. +}
  3132. +
  3133. +static inline u128 add64(u128 a, uint64_t b)
  3134. +{
  3135. + u128 r;
  3136. + r.lo = a.lo + b;
  3137. + r.hi = a.hi;
  3138. + if (r.lo < a.lo)
  3139. + r.hi++;
  3140. + return r;
  3141. +}
  3142. +
  3143. +static inline u128 add128(u128 a, u128 b)
  3144. +{
  3145. + u128 r;
  3146. + r.lo = a.lo + b.lo;
  3147. + r.hi = a.hi + b.hi;
  3148. + if (r.lo < a.lo)
  3149. + r.hi++;
  3150. + return r;
  3151. +}
  3152. +
  3153. +static inline u128 sub64(u128 a, uint64_t b)
  3154. +{
  3155. + u128 r;
  3156. + r.lo = a.lo - b;
  3157. + r.hi = a.hi;
  3158. + if (a.lo < b)
  3159. + r.hi--;
  3160. + return r;
  3161. +}
  3162. +
  3163. +static inline u128 sub128(u128 a, u128 b)
  3164. +{
  3165. + u128 r;
  3166. + r.lo = a.lo - b.lo;
  3167. + r.hi = a.hi - b.hi;
  3168. + if (a.lo < b.lo)
  3169. + r.hi--;
  3170. + return r;
  3171. +}
  3172. +
  3173. +/* a<<n, 0 <= n <= 127 */
  3174. +static inline u128 lsh(u128 a, int n)
  3175. +{
  3176. + if (n == 0)
  3177. + return a;
  3178. + if (n >= 64) {
  3179. + a.hi = a.lo<<(n-64);
  3180. + a.lo = 0;
  3181. + } else {
  3182. + a.hi = (a.hi<<n) | (a.lo>>(64-n));
  3183. + a.lo = a.lo<<n;
  3184. + }
  3185. + return a;
  3186. +}
  3187. +
  3188. +/* a>>n, 0 <= n <= 127 */
  3189. +static inline u128 rsh(u128 a, int n)
  3190. +{
  3191. + if (n == 0)
  3192. + return a;
  3193. + if (n >= 64) {
  3194. + a.lo = a.hi>>(n-64);
  3195. + a.hi = 0;
  3196. + } else {
  3197. + a.lo = (a.lo>>n) | (a.hi<<(64-n));
  3198. + a.hi = a.hi>>n;
  3199. + }
  3200. + return a;
  3201. +}
  3202. +
  3203. +/* returns a*b exactly. */
  3204. +static inline u128 mul64_128(uint64_t a, uint64_t b)
  3205. +{
  3206. + u128 r;
  3207. + uint64_t ahi = a>>32;
  3208. + uint64_t alo = a&0xffffffff;
  3209. + uint64_t bhi = b>>32;
  3210. + uint64_t blo = b&0xffffffff;
  3211. + uint64_t lo1 = ((ahi*blo)&0xffffffff) + ((alo*bhi)&0xffffffff) + (alo*blo>>32);
  3212. + uint64_t lo2 = (alo*blo)&0xffffffff;
  3213. + r.hi = ahi*bhi + (ahi*blo>>32) + (alo*bhi>>32) + (lo1>>32);
  3214. + r.lo = (lo1<<32) + lo2;
  3215. + return r;
  3216. +}
  3217. +
  3218. +/* returns a*b*2^-128 - e, with error 0 <= e < 7. */
  3219. +static inline u128 mul128(u128 a, u128 b)
  3220. +{
  3221. + u128 hi = mul64_128(a.hi, b.hi);
  3222. + uint64_t m1 = mul64(a.hi, b.lo);
  3223. + uint64_t m2 = mul64(a.lo, b.hi);
  3224. + return add64(add64(hi, m1), m2);
  3225. +}
  3226. +
  3227. +/* returns a*b % 2^128. */
  3228. +static inline u128 mul128_tail(u128 a, u128 b)
  3229. +{
  3230. + u128 lo = mul64_128(a.lo, b.lo);
  3231. + lo.hi += a.hi*b.lo + a.lo*b.hi;
  3232. + return lo;
  3233. +}
  3234. +
  3235. +
  3236. +/* see sqrt.c for detailed comments. */
  3237. +
  3238. +long double sqrtl(long double x)
  3239. +{
  3240. + u128 ix, ml;
  3241. + uint64_t top;
  3242. +
  3243. + ix = asu128(x);
  3244. + top = ix.hi >> 48;
  3245. + if (predict_false(top - 0x0001 >= 0x7fff - 0x0001)) {
  3246. + /* x < 0x1p-16382 or inf or nan. */
  3247. + if (2*ix.hi == 0 && ix.lo == 0)
  3248. + return x;
  3249. + if (ix.hi == 0x7fff000000000000 && ix.lo == 0)
  3250. + return x;
  3251. + if (top >= 0x7fff)
  3252. + return __math_invalidl(x);
  3253. + /* x is subnormal, normalize it. */
  3254. + ix = asu128(x * 0x1p112);
  3255. + top = ix.hi >> 48;
  3256. + top -= 112;
  3257. + }
  3258. +
  3259. + /* x = 4^e m; with int e and m in [1, 4) */
  3260. + int even = top & 1;
  3261. + ml = lsh(ix, 15);
  3262. + ml.hi |= 0x8000000000000000;
  3263. + if (even) ml = rsh(ml, 1);
  3264. + top = (top + 0x3fff) >> 1;
  3265. +
  3266. + /* r ~ 1/sqrt(m) */
  3267. + static const uint64_t three = 0xc0000000;
  3268. + uint64_t r, s, d, u, i;
  3269. + i = (ix.hi >> 42) % 128;
  3270. + r = (uint32_t)__rsqrt_tab[i] << 16;
  3271. + /* |r sqrt(m) - 1| < 0x1p-8 */
  3272. + s = mul32(ml.hi>>32, r);
  3273. + d = mul32(s, r);
  3274. + u = three - d;
  3275. + r = mul32(u, r) << 1;
  3276. + /* |r sqrt(m) - 1| < 0x1.7bp-16, switch to 64bit */
  3277. + r = r<<32;
  3278. + s = mul64(ml.hi, r);
  3279. + d = mul64(s, r);
  3280. + u = (three<<32) - d;
  3281. + r = mul64(u, r) << 1;
  3282. + /* |r sqrt(m) - 1| < 0x1.a5p-31 */
  3283. + s = mul64(u, s) << 1;
  3284. + d = mul64(s, r);
  3285. + u = (three<<32) - d;
  3286. + r = mul64(u, r) << 1;
  3287. + /* |r sqrt(m) - 1| < 0x1.c001p-59, switch to 128bit */
  3288. +
  3289. + static const u128 threel = {.hi=three<<32, .lo=0};
  3290. + u128 rl, sl, dl, ul;
  3291. + rl.hi = r;
  3292. + rl.lo = 0;
  3293. + sl = mul128(ml, rl);
  3294. + dl = mul128(sl, rl);
  3295. + ul = sub128(threel, dl);
  3296. + sl = mul128(ul, sl); /* repr: 3.125 */
  3297. + /* -0x1p-116 < s - sqrt(m) < 0x3.8001p-125 */
  3298. + sl = rsh(sub64(sl, 4), 125-(LDBL_MANT_DIG-1));
  3299. + /* s < sqrt(m) < s + 1 ULP + tiny */
  3300. +
  3301. + long double y;
  3302. + u128 d2, d1, d0;
  3303. + d0 = sub128(lsh(ml, 2*(LDBL_MANT_DIG-1)-126), mul128_tail(sl,sl));
  3304. + d1 = sub128(sl, d0);
  3305. + d2 = add128(add64(sl, 1), d1);
  3306. + sl = add64(sl, d1.hi >> 63);
  3307. + y = mkldbl(top, sl);
  3308. + if (FENV_SUPPORT) {
  3309. + /* handle rounding modes and inexact exception. */
  3310. + top = predict_false((d2.hi|d2.lo)==0) ? 0 : 1;
  3311. + top |= ((d1.hi^d2.hi)&0x8000000000000000) >> 48;
  3312. + y += mkldbl(top, (u128){0});
  3313. + }
  3314. + return y;
  3315. +}
  3316. +#else
  3317. +#error unsupported long double format
  3318. +#endif
  3319. diff --git a/src/misc/ioctl.c b/src/misc/ioctl.c
  3320. index 89477511..49282811 100644
  3321. --- a/src/misc/ioctl.c
  3322. +++ b/src/misc/ioctl.c
  3323. @@ -4,6 +4,7 @@
  3324. #include <time.h>
  3325. #include <sys/time.h>
  3326. #include <stddef.h>
  3327. +#include <stdint.h>
  3328. #include <string.h>
  3329. #include "syscall.h"
  3330. @@ -28,6 +29,12 @@ struct ioctl_compat_map {
  3331. * number producing macros; only size of result is meaningful. */
  3332. #define new_misaligned(n) struct { int i; time_t t; char c[(n)-4]; }
  3333. +struct v4l2_event {
  3334. + uint32_t a;
  3335. + uint64_t b[8];
  3336. + uint32_t c[2], ts[2], d[9];
  3337. +};
  3338. +
  3339. static const struct ioctl_compat_map compat_map[] = {
  3340. { SIOCGSTAMP, SIOCGSTAMP_OLD, 8, R, 0, OFFS(0, 4) },
  3341. { SIOCGSTAMPNS, SIOCGSTAMPNS_OLD, 8, R, 0, OFFS(0, 4) },
  3342. @@ -49,13 +56,14 @@ static const struct ioctl_compat_map compat_map[] = {
  3343. { 0, 0, 8, WR, 1, OFFS(0,4) }, /* snd_pcm_mmap_control */
  3344. /* VIDIOC_QUERYBUF, VIDIOC_QBUF, VIDIOC_DQBUF, VIDIOC_PREPARE_BUF */
  3345. - { _IOWR('V', 9, new_misaligned(72)), _IOWR('V', 9, char[72]), 72, WR, 0, OFFS(20) },
  3346. - { _IOWR('V', 15, new_misaligned(72)), _IOWR('V', 15, char[72]), 72, WR, 0, OFFS(20) },
  3347. - { _IOWR('V', 17, new_misaligned(72)), _IOWR('V', 17, char[72]), 72, WR, 0, OFFS(20) },
  3348. - { _IOWR('V', 93, new_misaligned(72)), _IOWR('V', 93, char[72]), 72, WR, 0, OFFS(20) },
  3349. + { _IOWR('V', 9, new_misaligned(68)), _IOWR('V', 9, char[68]), 68, WR, 1, OFFS(20, 24) },
  3350. + { _IOWR('V', 15, new_misaligned(68)), _IOWR('V', 15, char[68]), 68, WR, 1, OFFS(20, 24) },
  3351. + { _IOWR('V', 17, new_misaligned(68)), _IOWR('V', 17, char[68]), 68, WR, 1, OFFS(20, 24) },
  3352. + { _IOWR('V', 93, new_misaligned(68)), _IOWR('V', 93, char[68]), 68, WR, 1, OFFS(20, 24) },
  3353. /* VIDIOC_DQEVENT */
  3354. - { _IOR('V', 89, new_misaligned(96)), _IOR('V', 89, char[96]), 96, R, 0, OFFS(76,80) },
  3355. + { _IOR('V', 89, new_misaligned(120)), _IOR('V', 89, struct v4l2_event), sizeof(struct v4l2_event),
  3356. + R, 0, OFFS(offsetof(struct v4l2_event, ts[0]), offsetof(struct v4l2_event, ts[1])) },
  3357. /* VIDIOC_OMAP3ISP_STAT_REQ */
  3358. { _IOWR('V', 192+6, char[32]), _IOWR('V', 192+6, char[24]), 22, WR, 0, OFFS(0,4) },
  3359. diff --git a/src/misc/realpath.c b/src/misc/realpath.c
  3360. index d2708e59..db8b74dc 100644
  3361. --- a/src/misc/realpath.c
  3362. +++ b/src/misc/realpath.c
  3363. @@ -1,43 +1,156 @@
  3364. #include <stdlib.h>
  3365. #include <limits.h>
  3366. -#include <sys/stat.h>
  3367. -#include <fcntl.h>
  3368. #include <errno.h>
  3369. #include <unistd.h>
  3370. #include <string.h>
  3371. -#include "syscall.h"
  3372. +
  3373. +static size_t slash_len(const char *s)
  3374. +{
  3375. + const char *s0 = s;
  3376. + while (*s == '/') s++;
  3377. + return s-s0;
  3378. +}
  3379. char *realpath(const char *restrict filename, char *restrict resolved)
  3380. {
  3381. - int fd;
  3382. - ssize_t r;
  3383. - struct stat st1, st2;
  3384. - char buf[15+3*sizeof(int)];
  3385. - char tmp[PATH_MAX];
  3386. + char stack[PATH_MAX+1];
  3387. + char output[PATH_MAX];
  3388. + size_t p, q, l, l0, cnt=0, nup=0;
  3389. + int check_dir=0;
  3390. if (!filename) {
  3391. errno = EINVAL;
  3392. return 0;
  3393. }
  3394. + l = strnlen(filename, sizeof stack);
  3395. + if (!l) {
  3396. + errno = ENOENT;
  3397. + return 0;
  3398. + }
  3399. + if (l >= PATH_MAX) goto toolong;
  3400. + p = sizeof stack - l - 1;
  3401. + q = 0;
  3402. + memcpy(stack+p, filename, l+1);
  3403. +
  3404. + /* Main loop. Each iteration pops the next part from stack of
  3405. + * remaining path components and consumes any slashes that follow.
  3406. + * If not a link, it's moved to output; if a link, contents are
  3407. + * pushed to the stack. */
  3408. +restart:
  3409. + for (; ; p+=slash_len(stack+p)) {
  3410. + /* If stack starts with /, the whole component is / or //
  3411. + * and the output state must be reset. */
  3412. + if (stack[p] == '/') {
  3413. + check_dir=0;
  3414. + nup=0;
  3415. + q=0;
  3416. + output[q++] = '/';
  3417. + p++;
  3418. + /* Initial // is special. */
  3419. + if (stack[p] == '/' && stack[p+1] != '/')
  3420. + output[q++] = '/';
  3421. + continue;
  3422. + }
  3423. +
  3424. + char *z = __strchrnul(stack+p, '/');
  3425. + l0 = l = z-(stack+p);
  3426. - fd = sys_open(filename, O_PATH|O_NONBLOCK|O_CLOEXEC);
  3427. - if (fd < 0) return 0;
  3428. - __procfdname(buf, fd);
  3429. + if (!l && !check_dir) break;
  3430. - r = readlink(buf, tmp, sizeof tmp - 1);
  3431. - if (r < 0) goto err;
  3432. - tmp[r] = 0;
  3433. + /* Skip any . component but preserve check_dir status. */
  3434. + if (l==1 && stack[p]=='.') {
  3435. + p += l;
  3436. + continue;
  3437. + }
  3438. - fstat(fd, &st1);
  3439. - r = stat(tmp, &st2);
  3440. - if (r<0 || st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino) {
  3441. - if (!r) errno = ELOOP;
  3442. - goto err;
  3443. + /* Copy next component onto output at least temporarily, to
  3444. + * call readlink, but wait to advance output position until
  3445. + * determining it's not a link. */
  3446. + if (q && output[q-1] != '/') {
  3447. + if (!p) goto toolong;
  3448. + stack[--p] = '/';
  3449. + l++;
  3450. + }
  3451. + if (q+l >= PATH_MAX) goto toolong;
  3452. + memcpy(output+q, stack+p, l);
  3453. + output[q+l] = 0;
  3454. + p += l;
  3455. +
  3456. + int up = 0;
  3457. + if (l0==2 && stack[p-2]=='.' && stack[p-1]=='.') {
  3458. + up = 1;
  3459. + /* Any non-.. path components we could cancel start
  3460. + * after nup repetitions of the 3-byte string "../";
  3461. + * if there are none, accumulate .. components to
  3462. + * later apply to cwd, if needed. */
  3463. + if (q <= 3*nup) {
  3464. + nup++;
  3465. + q += l;
  3466. + continue;
  3467. + }
  3468. + /* When previous components are already known to be
  3469. + * directories, processing .. can skip readlink. */
  3470. + if (!check_dir) goto skip_readlink;
  3471. + }
  3472. + ssize_t k = readlink(output, stack, p);
  3473. + if (k==p) goto toolong;
  3474. + if (!k) {
  3475. + errno = ENOENT;
  3476. + return 0;
  3477. + }
  3478. + if (k<0) {
  3479. + if (errno != EINVAL) return 0;
  3480. +skip_readlink:
  3481. + check_dir = 0;
  3482. + if (up) {
  3483. + while(q && output[q-1]!='/') q--;
  3484. + if (q>1 && (q>2 || output[0]!='/')) q--;
  3485. + continue;
  3486. + }
  3487. + if (l0) q += l;
  3488. + check_dir = stack[p];
  3489. + continue;
  3490. + }
  3491. + if (++cnt == SYMLOOP_MAX) {
  3492. + errno = ELOOP;
  3493. + return 0;
  3494. + }
  3495. +
  3496. + /* If link contents end in /, strip any slashes already on
  3497. + * stack to avoid /->// or //->/// or spurious toolong. */
  3498. + if (stack[k-1]=='/') while (stack[p]=='/') p++;
  3499. + p -= k;
  3500. + memmove(stack+p, stack, k);
  3501. +
  3502. + /* Skip the stack advancement in case we have a new
  3503. + * absolute base path. */
  3504. + goto restart;
  3505. }
  3506. - __syscall(SYS_close, fd);
  3507. - return resolved ? strcpy(resolved, tmp) : strdup(tmp);
  3508. -err:
  3509. - __syscall(SYS_close, fd);
  3510. + output[q] = 0;
  3511. +
  3512. + if (output[0] != '/') {
  3513. + if (!getcwd(stack, sizeof stack)) return 0;
  3514. + l = strlen(stack);
  3515. + /* Cancel any initial .. components. */
  3516. + p = 0;
  3517. + while (nup--) {
  3518. + while(l>1 && stack[l-1]!='/') l--;
  3519. + if (l>1) l--;
  3520. + p += 2;
  3521. + if (p<q) p++;
  3522. + }
  3523. + if (q-p && stack[l-1]!='/') stack[l++] = '/';
  3524. + if (l + (q-p) + 1 >= PATH_MAX) goto toolong;
  3525. + memmove(output + l, output + p, q - p + 1);
  3526. + memcpy(output, stack, l);
  3527. + q = l + q-p;
  3528. + }
  3529. +
  3530. + if (resolved) return memcpy(resolved, output, q+1);
  3531. + else return strdup(output);
  3532. +
  3533. +toolong:
  3534. + errno = ENAMETOOLONG;
  3535. return 0;
  3536. }
  3537. diff --git a/src/misc/setrlimit.c b/src/misc/setrlimit.c
  3538. index 7a66ab29..8340aee0 100644
  3539. --- a/src/misc/setrlimit.c
  3540. +++ b/src/misc/setrlimit.c
  3541. @@ -6,25 +6,8 @@
  3542. #define MIN(a, b) ((a)<(b) ? (a) : (b))
  3543. #define FIX(x) do{ if ((x)>=SYSCALL_RLIM_INFINITY) (x)=RLIM_INFINITY; }while(0)
  3544. -static int __setrlimit(int resource, const struct rlimit *rlim)
  3545. -{
  3546. - unsigned long k_rlim[2];
  3547. - struct rlimit tmp;
  3548. - if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
  3549. - tmp = *rlim;
  3550. - FIX(tmp.rlim_cur);
  3551. - FIX(tmp.rlim_max);
  3552. - rlim = &tmp;
  3553. - }
  3554. - int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
  3555. - if (ret != -ENOSYS) return ret;
  3556. - k_rlim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY));
  3557. - k_rlim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY));
  3558. - return __syscall(SYS_setrlimit, resource, k_rlim);
  3559. -}
  3560. -
  3561. struct ctx {
  3562. - const struct rlimit *rlim;
  3563. + unsigned long lim[2];
  3564. int res;
  3565. int err;
  3566. };
  3567. @@ -33,12 +16,26 @@ static void do_setrlimit(void *p)
  3568. {
  3569. struct ctx *c = p;
  3570. if (c->err>0) return;
  3571. - c->err = -__setrlimit(c->res, c->rlim);
  3572. + c->err = -__syscall(SYS_setrlimit, c->res, c->lim);
  3573. }
  3574. int setrlimit(int resource, const struct rlimit *rlim)
  3575. {
  3576. - struct ctx c = { .res = resource, .rlim = rlim, .err = -1 };
  3577. + struct rlimit tmp;
  3578. + if (SYSCALL_RLIM_INFINITY != RLIM_INFINITY) {
  3579. + tmp = *rlim;
  3580. + FIX(tmp.rlim_cur);
  3581. + FIX(tmp.rlim_max);
  3582. + rlim = &tmp;
  3583. + }
  3584. + int ret = __syscall(SYS_prlimit64, 0, resource, rlim, 0);
  3585. + if (ret != -ENOSYS) return __syscall_ret(ret);
  3586. +
  3587. + struct ctx c = {
  3588. + .lim[0] = MIN(rlim->rlim_cur, MIN(-1UL, SYSCALL_RLIM_INFINITY)),
  3589. + .lim[1] = MIN(rlim->rlim_max, MIN(-1UL, SYSCALL_RLIM_INFINITY)),
  3590. + .res = resource, .err = -1
  3591. + };
  3592. __synccall(do_setrlimit, &c);
  3593. if (c.err) {
  3594. if (c.err>0) errno = c.err;
  3595. diff --git a/src/misc/syslog.c b/src/misc/syslog.c
  3596. index 13d4b0a6..7dc0c1be 100644
  3597. --- a/src/misc/syslog.c
  3598. +++ b/src/misc/syslog.c
  3599. @@ -10,6 +10,7 @@
  3600. #include <errno.h>
  3601. #include <fcntl.h>
  3602. #include "lock.h"
  3603. +#include "fork_impl.h"
  3604. static volatile int lock[1];
  3605. static char log_ident[32];
  3606. @@ -17,6 +18,7 @@ static int log_opt;
  3607. static int log_facility = LOG_USER;
  3608. static int log_mask = 0xff;
  3609. static int log_fd = -1;
  3610. +volatile int *const __syslog_lockptr = lock;
  3611. int setlogmask(int maskpri)
  3612. {
  3613. diff --git a/src/multibyte/wcsnrtombs.c b/src/multibyte/wcsnrtombs.c
  3614. index 676932b5..95e25e70 100644
  3615. --- a/src/multibyte/wcsnrtombs.c
  3616. +++ b/src/multibyte/wcsnrtombs.c
  3617. @@ -1,41 +1,33 @@
  3618. #include <wchar.h>
  3619. +#include <limits.h>
  3620. +#include <string.h>
  3621. size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
  3622. {
  3623. - size_t l, cnt=0, n2;
  3624. - char *s, buf[256];
  3625. const wchar_t *ws = *wcs;
  3626. - const wchar_t *tmp_ws;
  3627. -
  3628. - if (!dst) s = buf, n = sizeof buf;
  3629. - else s = dst;
  3630. -
  3631. - while ( ws && n && ( (n2=wn)>=n || n2>32 ) ) {
  3632. - if (n2>=n) n2=n;
  3633. - tmp_ws = ws;
  3634. - l = wcsrtombs(s, &ws, n2, 0);
  3635. - if (!(l+1)) {
  3636. - cnt = l;
  3637. - n = 0;
  3638. + size_t cnt = 0;
  3639. + if (!dst) n=0;
  3640. + while (ws && wn) {
  3641. + char tmp[MB_LEN_MAX];
  3642. + size_t l = wcrtomb(n<MB_LEN_MAX ? tmp : dst, *ws, 0);
  3643. + if (l==-1) {
  3644. + cnt = -1;
  3645. break;
  3646. }
  3647. - if (s != buf) {
  3648. - s += l;
  3649. + if (dst) {
  3650. + if (n<MB_LEN_MAX) {
  3651. + if (l>n) break;
  3652. + memcpy(dst, tmp, l);
  3653. + }
  3654. + dst += l;
  3655. n -= l;
  3656. }
  3657. - wn = ws ? wn - (ws - tmp_ws) : 0;
  3658. - cnt += l;
  3659. - }
  3660. - if (ws) while (n && wn) {
  3661. - l = wcrtomb(s, *ws, 0);
  3662. - if ((l+1)<=1) {
  3663. - if (!l) ws = 0;
  3664. - else cnt = l;
  3665. + if (!*ws) {
  3666. + ws = 0;
  3667. break;
  3668. }
  3669. - ws++; wn--;
  3670. - /* safe - this loop runs fewer than sizeof(buf) times */
  3671. - s+=l; n-=l;
  3672. + ws++;
  3673. + wn--;
  3674. cnt += l;
  3675. }
  3676. if (dst) *wcs = ws;
  3677. diff --git a/src/network/h_errno.c b/src/network/h_errno.c
  3678. index 4f700cea..638f7718 100644
  3679. --- a/src/network/h_errno.c
  3680. +++ b/src/network/h_errno.c
  3681. @@ -1,9 +1,11 @@
  3682. #include <netdb.h>
  3683. +#include "pthread_impl.h"
  3684. #undef h_errno
  3685. int h_errno;
  3686. int *__h_errno_location(void)
  3687. {
  3688. - return &h_errno;
  3689. + if (!__pthread_self()->stack) return &h_errno;
  3690. + return &__pthread_self()->h_errno_val;
  3691. }
  3692. diff --git a/src/network/herror.c b/src/network/herror.c
  3693. index 65f25ff3..87f8cff4 100644
  3694. --- a/src/network/herror.c
  3695. +++ b/src/network/herror.c
  3696. @@ -4,5 +4,5 @@
  3697. void herror(const char *msg)
  3698. {
  3699. - fprintf(stderr, "%s%s%s", msg?msg:"", msg?": ":"", hstrerror(h_errno));
  3700. + fprintf(stderr, "%s%s%s\n", msg?msg:"", msg?": ":"", hstrerror(h_errno));
  3701. }
  3702. diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c
  3703. index aae0d95a..aa558c19 100644
  3704. --- a/src/network/lookup_name.c
  3705. +++ b/src/network/lookup_name.c
  3706. @@ -50,7 +50,7 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
  3707. {
  3708. char line[512];
  3709. size_t l = strlen(name);
  3710. - int cnt = 0, badfam = 0;
  3711. + int cnt = 0, badfam = 0, have_canon = 0;
  3712. unsigned char _buf[1032];
  3713. FILE _f, *f = __fopen_rb_ca("/etc/hosts", &_f, _buf, sizeof _buf);
  3714. if (!f) switch (errno) {
  3715. @@ -80,14 +80,19 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati
  3716. continue;
  3717. default:
  3718. badfam = EAI_NONAME;
  3719. - continue;
  3720. + break;
  3721. }
  3722. + if (have_canon) continue;
  3723. +
  3724. /* Extract first name as canonical name */
  3725. for (; *p && isspace(*p); p++);
  3726. for (z=p; *z && !isspace(*z); z++);
  3727. *z = 0;
  3728. - if (is_valid_hostname(p)) memcpy(canon, p, z-p+1);
  3729. + if (is_valid_hostname(p)) {
  3730. + have_canon = 1;
  3731. + memcpy(canon, p, z-p+1);
  3732. + }
  3733. }
  3734. __fclose_ca(f);
  3735. return cnt ? cnt : badfam;
  3736. diff --git a/src/network/res_query.c b/src/network/res_query.c
  3737. index 2f4da2e2..506dc231 100644
  3738. --- a/src/network/res_query.c
  3739. +++ b/src/network/res_query.c
  3740. @@ -1,3 +1,4 @@
  3741. +#define _BSD_SOURCE
  3742. #include <resolv.h>
  3743. #include <netdb.h>
  3744. @@ -6,7 +7,20 @@ int res_query(const char *name, int class, int type, unsigned char *dest, int le
  3745. unsigned char q[280];
  3746. int ql = __res_mkquery(0, name, class, type, 0, 0, 0, q, sizeof q);
  3747. if (ql < 0) return ql;
  3748. - return __res_send(q, ql, dest, len);
  3749. + int r = __res_send(q, ql, dest, len);
  3750. + if (r<12) {
  3751. + h_errno = TRY_AGAIN;
  3752. + return -1;
  3753. + }
  3754. + if ((dest[3] & 15) == 3) {
  3755. + h_errno = HOST_NOT_FOUND;
  3756. + return -1;
  3757. + }
  3758. + if ((dest[3] & 15) == 0 && !dest[6] && !dest[7]) {
  3759. + h_errno = NO_DATA;
  3760. + return -1;
  3761. + }
  3762. + return r;
  3763. }
  3764. weak_alias(res_query, res_search);
  3765. diff --git a/src/passwd/getgrouplist.c b/src/passwd/getgrouplist.c
  3766. index 43e51824..301824ce 100644
  3767. --- a/src/passwd/getgrouplist.c
  3768. +++ b/src/passwd/getgrouplist.c
  3769. @@ -31,7 +31,8 @@ int getgrouplist(const char *user, gid_t gid, gid_t *groups, int *ngroups)
  3770. if (resp[INITGRFOUND]) {
  3771. nscdbuf = calloc(resp[INITGRNGRPS], sizeof(uint32_t));
  3772. if (!nscdbuf) goto cleanup;
  3773. - if (!fread(nscdbuf, sizeof(*nscdbuf)*resp[INITGRNGRPS], 1, f)) {
  3774. + size_t nbytes = sizeof(*nscdbuf)*resp[INITGRNGRPS];
  3775. + if (nbytes && !fread(nscdbuf, nbytes, 1, f)) {
  3776. if (!ferror(f)) errno = EIO;
  3777. goto cleanup;
  3778. }
  3779. diff --git a/src/prng/random.c b/src/prng/random.c
  3780. index 633a17f6..d3780fa7 100644
  3781. --- a/src/prng/random.c
  3782. +++ b/src/prng/random.c
  3783. @@ -1,6 +1,7 @@
  3784. #include <stdlib.h>
  3785. #include <stdint.h>
  3786. #include "lock.h"
  3787. +#include "fork_impl.h"
  3788. /*
  3789. this code uses the same lagged fibonacci generator as the
  3790. @@ -23,6 +24,7 @@ static int i = 3;
  3791. static int j = 0;
  3792. static uint32_t *x = init+1;
  3793. static volatile int lock[1];
  3794. +volatile int *const __random_lockptr = lock;
  3795. static uint32_t lcg31(uint32_t x) {
  3796. return (1103515245*x + 12345) & 0x7fffffff;
  3797. diff --git a/src/process/_Fork.c b/src/process/_Fork.c
  3798. new file mode 100644
  3799. index 00000000..da063868
  3800. --- /dev/null
  3801. +++ b/src/process/_Fork.c
  3802. @@ -0,0 +1,38 @@
  3803. +#include <unistd.h>
  3804. +#include <signal.h>
  3805. +#include "syscall.h"
  3806. +#include "libc.h"
  3807. +#include "lock.h"
  3808. +#include "pthread_impl.h"
  3809. +#include "aio_impl.h"
  3810. +
  3811. +static void dummy(int x) { }
  3812. +weak_alias(dummy, __aio_atfork);
  3813. +
  3814. +pid_t _Fork(void)
  3815. +{
  3816. + pid_t ret;
  3817. + sigset_t set;
  3818. + __block_all_sigs(&set);
  3819. + __aio_atfork(-1);
  3820. + LOCK(__abort_lock);
  3821. +#ifdef SYS_fork
  3822. + ret = __syscall(SYS_fork);
  3823. +#else
  3824. + ret = __syscall(SYS_clone, SIGCHLD, 0);
  3825. +#endif
  3826. + if (!ret) {
  3827. + pthread_t self = __pthread_self();
  3828. + self->tid = __syscall(SYS_gettid);
  3829. + self->robust_list.off = 0;
  3830. + self->robust_list.pending = 0;
  3831. + self->next = self->prev = self;
  3832. + __thread_list_lock = 0;
  3833. + libc.threads_minus_1 = 0;
  3834. + if (libc.need_locks) libc.need_locks = -1;
  3835. + }
  3836. + UNLOCK(__abort_lock);
  3837. + __aio_atfork(!ret);
  3838. + __restore_sigs(&set);
  3839. + return __syscall_ret(ret);
  3840. +}
  3841. diff --git a/src/process/fork.c b/src/process/fork.c
  3842. index 7e984ff8..54bc2892 100644
  3843. --- a/src/process/fork.c
  3844. +++ b/src/process/fork.c
  3845. @@ -1,38 +1,86 @@
  3846. #include <unistd.h>
  3847. -#include <string.h>
  3848. -#include <signal.h>
  3849. -#include "syscall.h"
  3850. +#include <errno.h>
  3851. #include "libc.h"
  3852. +#include "lock.h"
  3853. #include "pthread_impl.h"
  3854. +#include "fork_impl.h"
  3855. -static void dummy(int x)
  3856. -{
  3857. -}
  3858. +static volatile int *const dummy_lockptr = 0;
  3859. +
  3860. +weak_alias(dummy_lockptr, __at_quick_exit_lockptr);
  3861. +weak_alias(dummy_lockptr, __atexit_lockptr);
  3862. +weak_alias(dummy_lockptr, __dlerror_lockptr);
  3863. +weak_alias(dummy_lockptr, __gettext_lockptr);
  3864. +weak_alias(dummy_lockptr, __locale_lockptr);
  3865. +weak_alias(dummy_lockptr, __random_lockptr);
  3866. +weak_alias(dummy_lockptr, __sem_open_lockptr);
  3867. +weak_alias(dummy_lockptr, __stdio_ofl_lockptr);
  3868. +weak_alias(dummy_lockptr, __syslog_lockptr);
  3869. +weak_alias(dummy_lockptr, __timezone_lockptr);
  3870. +weak_alias(dummy_lockptr, __bump_lockptr);
  3871. +
  3872. +weak_alias(dummy_lockptr, __vmlock_lockptr);
  3873. +static volatile int *const *const atfork_locks[] = {
  3874. + &__at_quick_exit_lockptr,
  3875. + &__atexit_lockptr,
  3876. + &__dlerror_lockptr,
  3877. + &__gettext_lockptr,
  3878. + &__locale_lockptr,
  3879. + &__random_lockptr,
  3880. + &__sem_open_lockptr,
  3881. + &__stdio_ofl_lockptr,
  3882. + &__syslog_lockptr,
  3883. + &__timezone_lockptr,
  3884. + &__bump_lockptr,
  3885. +};
  3886. +
  3887. +static void dummy(int x) { }
  3888. weak_alias(dummy, __fork_handler);
  3889. +weak_alias(dummy, __malloc_atfork);
  3890. +weak_alias(dummy, __ldso_atfork);
  3891. +
  3892. +static void dummy_0(void) { }
  3893. +weak_alias(dummy_0, __tl_lock);
  3894. +weak_alias(dummy_0, __tl_unlock);
  3895. pid_t fork(void)
  3896. {
  3897. - pid_t ret;
  3898. sigset_t set;
  3899. __fork_handler(-1);
  3900. - __block_all_sigs(&set);
  3901. -#ifdef SYS_fork
  3902. - ret = __syscall(SYS_fork);
  3903. -#else
  3904. - ret = __syscall(SYS_clone, SIGCHLD, 0);
  3905. -#endif
  3906. - if (!ret) {
  3907. - pthread_t self = __pthread_self();
  3908. - self->tid = __syscall(SYS_gettid);
  3909. - self->robust_list.off = 0;
  3910. - self->robust_list.pending = 0;
  3911. - self->next = self->prev = self;
  3912. - __thread_list_lock = 0;
  3913. - libc.threads_minus_1 = 0;
  3914. - if (libc.need_locks) libc.need_locks = -1;
  3915. + __block_app_sigs(&set);
  3916. + int need_locks = libc.need_locks > 0;
  3917. + if (need_locks) {
  3918. + __ldso_atfork(-1);
  3919. + __inhibit_ptc();
  3920. + for (int i=0; i<sizeof atfork_locks/sizeof *atfork_locks; i++)
  3921. + if (*atfork_locks[i]) LOCK(*atfork_locks[i]);
  3922. + __malloc_atfork(-1);
  3923. + __tl_lock();
  3924. + }
  3925. + pthread_t self=__pthread_self(), next=self->next;
  3926. + pid_t ret = _Fork();
  3927. + int errno_save = errno;
  3928. + if (need_locks) {
  3929. + if (!ret) {
  3930. + for (pthread_t td=next; td!=self; td=td->next)
  3931. + td->tid = -1;
  3932. + if (__vmlock_lockptr) {
  3933. + __vmlock_lockptr[0] = 0;
  3934. + __vmlock_lockptr[1] = 0;
  3935. + }
  3936. + }
  3937. + __tl_unlock();
  3938. + __malloc_atfork(!ret);
  3939. + for (int i=0; i<sizeof atfork_locks/sizeof *atfork_locks; i++)
  3940. + if (*atfork_locks[i])
  3941. + if (ret) UNLOCK(*atfork_locks[i]);
  3942. + else **atfork_locks[i] = 0;
  3943. + __release_ptc();
  3944. + __ldso_atfork(!ret);
  3945. }
  3946. __restore_sigs(&set);
  3947. __fork_handler(!ret);
  3948. - return __syscall_ret(ret);
  3949. + if (ret<0) errno = errno_save;
  3950. + return ret;
  3951. }
  3952. diff --git a/src/process/posix_spawn.c b/src/process/posix_spawn.c
  3953. index 29652197..728551b3 100644
  3954. --- a/src/process/posix_spawn.c
  3955. +++ b/src/process/posix_spawn.c
  3956. @@ -6,6 +6,7 @@
  3957. #include <fcntl.h>
  3958. #include <sys/wait.h>
  3959. #include "syscall.h"
  3960. +#include "lock.h"
  3961. #include "pthread_impl.h"
  3962. #include "fdop.h"
  3963. @@ -170,9 +171,6 @@ int posix_spawn(pid_t *restrict res, const char *restrict path,
  3964. int ec=0, cs;
  3965. struct args args;
  3966. - if (pipe2(args.p, O_CLOEXEC))
  3967. - return errno;
  3968. -
  3969. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
  3970. args.path = path;
  3971. @@ -182,9 +180,20 @@ int posix_spawn(pid_t *restrict res, const char *restrict path,
  3972. args.envp = envp;
  3973. pthread_sigmask(SIG_BLOCK, SIGALL_SET, &args.oldmask);
  3974. + /* The lock guards both against seeing a SIGABRT disposition change
  3975. + * by abort and against leaking the pipe fd to fork-without-exec. */
  3976. + LOCK(__abort_lock);
  3977. +
  3978. + if (pipe2(args.p, O_CLOEXEC)) {
  3979. + UNLOCK(__abort_lock);
  3980. + ec = errno;
  3981. + goto fail;
  3982. + }
  3983. +
  3984. pid = __clone(child, stack+sizeof stack,
  3985. CLONE_VM|CLONE_VFORK|SIGCHLD, &args);
  3986. close(args.p[1]);
  3987. + UNLOCK(__abort_lock);
  3988. if (pid > 0) {
  3989. if (read(args.p[0], &ec, sizeof ec) != sizeof ec) ec = 0;
  3990. @@ -197,6 +206,7 @@ int posix_spawn(pid_t *restrict res, const char *restrict path,
  3991. if (!ec && res) *res = pid;
  3992. +fail:
  3993. pthread_sigmask(SIG_SETMASK, &args.oldmask, 0);
  3994. pthread_setcancelstate(cs, 0);
  3995. diff --git a/src/setjmp/aarch64/longjmp.s b/src/setjmp/aarch64/longjmp.s
  3996. index 7c4655fa..0af9c50e 100644
  3997. --- a/src/setjmp/aarch64/longjmp.s
  3998. +++ b/src/setjmp/aarch64/longjmp.s
  3999. @@ -18,7 +18,6 @@ longjmp:
  4000. ldp d12, d13, [x0,#144]
  4001. ldp d14, d15, [x0,#160]
  4002. - mov x0, x1
  4003. - cbnz x1, 1f
  4004. - mov x0, #1
  4005. -1: br x30
  4006. + cmp w1, 0
  4007. + csinc w0, w1, wzr, ne
  4008. + br x30
  4009. diff --git a/src/setjmp/i386/longjmp.s b/src/setjmp/i386/longjmp.s
  4010. index 772d28dd..8188f06b 100644
  4011. --- a/src/setjmp/i386/longjmp.s
  4012. +++ b/src/setjmp/i386/longjmp.s
  4013. @@ -6,15 +6,11 @@ _longjmp:
  4014. longjmp:
  4015. mov 4(%esp),%edx
  4016. mov 8(%esp),%eax
  4017. - test %eax,%eax
  4018. - jnz 1f
  4019. - inc %eax
  4020. -1:
  4021. + cmp $1,%eax
  4022. + adc $0, %al
  4023. mov (%edx),%ebx
  4024. mov 4(%edx),%esi
  4025. mov 8(%edx),%edi
  4026. mov 12(%edx),%ebp
  4027. - mov 16(%edx),%ecx
  4028. - mov %ecx,%esp
  4029. - mov 20(%edx),%ecx
  4030. - jmp *%ecx
  4031. + mov 16(%edx),%esp
  4032. + jmp *20(%edx)
  4033. diff --git a/src/setjmp/x32/longjmp.s b/src/setjmp/x32/longjmp.s
  4034. index e175a4b9..1b2661c3 100644
  4035. --- a/src/setjmp/x32/longjmp.s
  4036. +++ b/src/setjmp/x32/longjmp.s
  4037. @@ -5,18 +5,14 @@
  4038. .type longjmp,@function
  4039. _longjmp:
  4040. longjmp:
  4041. - mov %rsi,%rax /* val will be longjmp return */
  4042. - test %rax,%rax
  4043. - jnz 1f
  4044. - inc %rax /* if val==0, val=1 per longjmp semantics */
  4045. -1:
  4046. + xor %eax,%eax
  4047. + cmp $1,%esi /* CF = val ? 0 : 1 */
  4048. + adc %esi,%eax /* eax = val + !val */
  4049. mov (%rdi),%rbx /* rdi is the jmp_buf, restore regs from it */
  4050. mov 8(%rdi),%rbp
  4051. mov 16(%rdi),%r12
  4052. mov 24(%rdi),%r13
  4053. mov 32(%rdi),%r14
  4054. mov 40(%rdi),%r15
  4055. - mov 48(%rdi),%rdx /* this ends up being the stack pointer */
  4056. - mov %rdx,%rsp
  4057. - mov 56(%rdi),%rdx /* this is the instruction pointer */
  4058. - jmp *%rdx /* goto saved address without altering rsp */
  4059. + mov 48(%rdi),%rsp
  4060. + jmp *56(%rdi) /* goto saved address without altering rsp */
  4061. diff --git a/src/setjmp/x32/setjmp.s b/src/setjmp/x32/setjmp.s
  4062. index 98f58b8d..d95e4853 100644
  4063. --- a/src/setjmp/x32/setjmp.s
  4064. +++ b/src/setjmp/x32/setjmp.s
  4065. @@ -18,5 +18,5 @@ setjmp:
  4066. mov %rdx,48(%rdi)
  4067. mov (%rsp),%rdx /* save return addr ptr for new rip */
  4068. mov %rdx,56(%rdi)
  4069. - xor %rax,%rax /* always return 0 */
  4070. + xor %eax,%eax /* always return 0 */
  4071. ret
  4072. diff --git a/src/setjmp/x86_64/longjmp.s b/src/setjmp/x86_64/longjmp.s
  4073. index e175a4b9..1b2661c3 100644
  4074. --- a/src/setjmp/x86_64/longjmp.s
  4075. +++ b/src/setjmp/x86_64/longjmp.s
  4076. @@ -5,18 +5,14 @@
  4077. .type longjmp,@function
  4078. _longjmp:
  4079. longjmp:
  4080. - mov %rsi,%rax /* val will be longjmp return */
  4081. - test %rax,%rax
  4082. - jnz 1f
  4083. - inc %rax /* if val==0, val=1 per longjmp semantics */
  4084. -1:
  4085. + xor %eax,%eax
  4086. + cmp $1,%esi /* CF = val ? 0 : 1 */
  4087. + adc %esi,%eax /* eax = val + !val */
  4088. mov (%rdi),%rbx /* rdi is the jmp_buf, restore regs from it */
  4089. mov 8(%rdi),%rbp
  4090. mov 16(%rdi),%r12
  4091. mov 24(%rdi),%r13
  4092. mov 32(%rdi),%r14
  4093. mov 40(%rdi),%r15
  4094. - mov 48(%rdi),%rdx /* this ends up being the stack pointer */
  4095. - mov %rdx,%rsp
  4096. - mov 56(%rdi),%rdx /* this is the instruction pointer */
  4097. - jmp *%rdx /* goto saved address without altering rsp */
  4098. + mov 48(%rdi),%rsp
  4099. + jmp *56(%rdi) /* goto saved address without altering rsp */
  4100. diff --git a/src/setjmp/x86_64/setjmp.s b/src/setjmp/x86_64/setjmp.s
  4101. index 98f58b8d..d95e4853 100644
  4102. --- a/src/setjmp/x86_64/setjmp.s
  4103. +++ b/src/setjmp/x86_64/setjmp.s
  4104. @@ -18,5 +18,5 @@ setjmp:
  4105. mov %rdx,48(%rdi)
  4106. mov (%rsp),%rdx /* save return addr ptr for new rip */
  4107. mov %rdx,56(%rdi)
  4108. - xor %rax,%rax /* always return 0 */
  4109. + xor %eax,%eax /* always return 0 */
  4110. ret
  4111. diff --git a/src/signal/sigaction.c b/src/signal/sigaction.c
  4112. index c109bea0..2203471b 100644
  4113. --- a/src/signal/sigaction.c
  4114. +++ b/src/signal/sigaction.c
  4115. @@ -7,12 +7,6 @@
  4116. #include "lock.h"
  4117. #include "ksigaction.h"
  4118. -static volatile int dummy_lock[1] = { 0 };
  4119. -
  4120. -extern hidden volatile int __abort_lock[1];
  4121. -
  4122. -weak_alias(dummy_lock, __abort_lock);
  4123. -
  4124. static int unmask_done;
  4125. static unsigned long handler_set[_NSIG/(8*sizeof(long))];
  4126. @@ -26,7 +20,6 @@ volatile int __eintr_valid_flag;
  4127. int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
  4128. {
  4129. struct k_sigaction ksa, ksa_old;
  4130. - unsigned long set[_NSIG/(8*sizeof(long))];
  4131. if (sa) {
  4132. if ((uintptr_t)sa->sa_handler > 1UL) {
  4133. a_or_l(handler_set+(sig-1)/(8*sizeof(long)),
  4134. @@ -50,24 +43,12 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
  4135. a_store(&__eintr_valid_flag, 1);
  4136. }
  4137. }
  4138. - /* Changing the disposition of SIGABRT to anything but
  4139. - * SIG_DFL requires a lock, so that it cannot be changed
  4140. - * while abort is terminating the process after simply
  4141. - * calling raise(SIGABRT) failed to do so. */
  4142. - if (sa->sa_handler != SIG_DFL && sig == SIGABRT) {
  4143. - __block_all_sigs(&set);
  4144. - LOCK(__abort_lock);
  4145. - }
  4146. ksa.handler = sa->sa_handler;
  4147. ksa.flags = sa->sa_flags | SA_RESTORER;
  4148. ksa.restorer = (sa->sa_flags & SA_SIGINFO) ? __restore_rt : __restore;
  4149. memcpy(&ksa.mask, &sa->sa_mask, _NSIG/8);
  4150. }
  4151. int r = __syscall(SYS_rt_sigaction, sig, sa?&ksa:0, old?&ksa_old:0, _NSIG/8);
  4152. - if (sig == SIGABRT && sa && sa->sa_handler != SIG_DFL) {
  4153. - UNLOCK(__abort_lock);
  4154. - __restore_sigs(&set);
  4155. - }
  4156. if (old && !r) {
  4157. old->sa_handler = ksa_old.handler;
  4158. old->sa_flags = ksa_old.flags;
  4159. @@ -78,11 +59,26 @@ int __libc_sigaction(int sig, const struct sigaction *restrict sa, struct sigact
  4160. int __sigaction(int sig, const struct sigaction *restrict sa, struct sigaction *restrict old)
  4161. {
  4162. + unsigned long set[_NSIG/(8*sizeof(long))];
  4163. +
  4164. if (sig-32U < 3 || sig-1U >= _NSIG-1) {
  4165. errno = EINVAL;
  4166. return -1;
  4167. }
  4168. - return __libc_sigaction(sig, sa, old);
  4169. +
  4170. + /* Doing anything with the disposition of SIGABRT requires a lock,
  4171. + * so that it cannot be changed while abort is terminating the
  4172. + * process and so any change made by abort can't be observed. */
  4173. + if (sig == SIGABRT) {
  4174. + __block_all_sigs(&set);
  4175. + LOCK(__abort_lock);
  4176. + }
  4177. + int r = __libc_sigaction(sig, sa, old);
  4178. + if (sig == SIGABRT) {
  4179. + UNLOCK(__abort_lock);
  4180. + __restore_sigs(&set);
  4181. + }
  4182. + return r;
  4183. }
  4184. weak_alias(__sigaction, sigaction);
  4185. diff --git a/src/stdio/__stdio_close.c b/src/stdio/__stdio_close.c
  4186. index 79452bdb..30291328 100644
  4187. --- a/src/stdio/__stdio_close.c
  4188. +++ b/src/stdio/__stdio_close.c
  4189. @@ -1,4 +1,5 @@
  4190. #include "stdio_impl.h"
  4191. +#include "aio_impl.h"
  4192. static int dummy(int fd)
  4193. {
  4194. diff --git a/src/stdio/ofl.c b/src/stdio/ofl.c
  4195. index f2d3215a..aad3d171 100644
  4196. --- a/src/stdio/ofl.c
  4197. +++ b/src/stdio/ofl.c
  4198. @@ -1,8 +1,10 @@
  4199. #include "stdio_impl.h"
  4200. #include "lock.h"
  4201. +#include "fork_impl.h"
  4202. static FILE *ofl_head;
  4203. static volatile int ofl_lock[1];
  4204. +volatile int *const __stdio_ofl_lockptr = ofl_lock;
  4205. FILE **__ofl_lock()
  4206. {
  4207. diff --git a/src/string/strstr.c b/src/string/strstr.c
  4208. index 43a0207a..96657bc2 100644
  4209. --- a/src/string/strstr.c
  4210. +++ b/src/string/strstr.c
  4211. @@ -96,7 +96,7 @@ static char *twoway_strstr(const unsigned char *h, const unsigned char *n)
  4212. for (;;) {
  4213. /* Update incremental end-of-haystack pointer */
  4214. if (z-h < l) {
  4215. - /* Fast estimate for MIN(l,63) */
  4216. + /* Fast estimate for MAX(l,63) */
  4217. size_t grow = l | 63;
  4218. const unsigned char *z2 = memchr(z, 0, grow);
  4219. if (z2) {
  4220. diff --git a/src/termios/tcgetwinsize.c b/src/termios/tcgetwinsize.c
  4221. new file mode 100644
  4222. index 00000000..9b3a65a4
  4223. --- /dev/null
  4224. +++ b/src/termios/tcgetwinsize.c
  4225. @@ -0,0 +1,8 @@
  4226. +#include <termios.h>
  4227. +#include <sys/ioctl.h>
  4228. +#include "syscall.h"
  4229. +
  4230. +int tcgetwinsize(int fd, struct winsize *wsz)
  4231. +{
  4232. + return syscall(SYS_ioctl, fd, TIOCGWINSZ, wsz);
  4233. +}
  4234. diff --git a/src/termios/tcsetwinsize.c b/src/termios/tcsetwinsize.c
  4235. new file mode 100644
  4236. index 00000000..e01d0e25
  4237. --- /dev/null
  4238. +++ b/src/termios/tcsetwinsize.c
  4239. @@ -0,0 +1,8 @@
  4240. +#include <termios.h>
  4241. +#include <sys/ioctl.h>
  4242. +#include "syscall.h"
  4243. +
  4244. +int tcsetwinsize(int fd, const struct winsize *wsz)
  4245. +{
  4246. + return syscall(SYS_ioctl, fd, TIOCSWINSZ, wsz);
  4247. +}
  4248. diff --git a/src/thread/i386/__set_thread_area.s b/src/thread/i386/__set_thread_area.s
  4249. index c2c21dd5..aa6852be 100644
  4250. --- a/src/thread/i386/__set_thread_area.s
  4251. +++ b/src/thread/i386/__set_thread_area.s
  4252. @@ -28,6 +28,7 @@ __set_thread_area:
  4253. ret
  4254. 2:
  4255. mov %ebx,%ecx
  4256. + xor %eax,%eax
  4257. xor %ebx,%ebx
  4258. xor %edx,%edx
  4259. mov %ebx,(%esp)
  4260. diff --git a/src/thread/pthread_attr_get.c b/src/thread/pthread_attr_get.c
  4261. index 4aa5afdb..f12ff442 100644
  4262. --- a/src/thread/pthread_attr_get.c
  4263. +++ b/src/thread/pthread_attr_get.c
  4264. @@ -70,7 +70,7 @@ int pthread_condattr_getpshared(const pthread_condattr_t *restrict a, int *restr
  4265. int pthread_mutexattr_getprotocol(const pthread_mutexattr_t *restrict a, int *restrict protocol)
  4266. {
  4267. - *protocol = PTHREAD_PRIO_NONE;
  4268. + *protocol = a->__attr / 8U % 2;
  4269. return 0;
  4270. }
  4271. int pthread_mutexattr_getpshared(const pthread_mutexattr_t *restrict a, int *restrict pshared)
  4272. diff --git a/src/thread/pthread_cond_timedwait.c b/src/thread/pthread_cond_timedwait.c
  4273. index d1501240..6b761455 100644
  4274. --- a/src/thread/pthread_cond_timedwait.c
  4275. +++ b/src/thread/pthread_cond_timedwait.c
  4276. @@ -146,14 +146,18 @@ relock:
  4277. if (oldstate == WAITING) goto done;
  4278. - if (!node.next) a_inc(&m->_m_waiters);
  4279. + if (!node.next && !(m->_m_type & 8))
  4280. + a_inc(&m->_m_waiters);
  4281. /* Unlock the barrier that's holding back the next waiter, and
  4282. * either wake it or requeue it to the mutex. */
  4283. - if (node.prev)
  4284. - unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & 128);
  4285. - else
  4286. - a_dec(&m->_m_waiters);
  4287. + if (node.prev) {
  4288. + int val = m->_m_lock;
  4289. + if (val>0) a_cas(&m->_m_lock, val, val|0x80000000);
  4290. + unlock_requeue(&node.prev->barrier, &m->_m_lock, m->_m_type & (8|128));
  4291. + } else if (!(m->_m_type & 8)) {
  4292. + a_dec(&m->_m_waiters);
  4293. + }
  4294. /* Since a signal was consumed, cancellation is not permitted. */
  4295. if (e == ECANCELED) e = 0;
  4296. diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
  4297. index 10f1b7d8..6f187ee8 100644
  4298. --- a/src/thread/pthread_create.c
  4299. +++ b/src/thread/pthread_create.c
  4300. @@ -69,12 +69,25 @@ _Noreturn void __pthread_exit(void *result)
  4301. __pthread_tsd_run_dtors();
  4302. + __block_app_sigs(&set);
  4303. +
  4304. + /* This atomic potentially competes with a concurrent pthread_detach
  4305. + * call; the loser is responsible for freeing thread resources. */
  4306. + int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING);
  4307. +
  4308. + if (state==DT_DETACHED && self->map_base) {
  4309. + /* Since __unmapself bypasses the normal munmap code path,
  4310. + * explicitly wait for vmlock holders first. This must be
  4311. + * done before any locks are taken, to avoid lock ordering
  4312. + * issues that could lead to deadlock. */
  4313. + __vm_wait();
  4314. + }
  4315. +
  4316. /* Access to target the exiting thread with syscalls that use
  4317. * its kernel tid is controlled by killlock. For detached threads,
  4318. * any use past this point would have undefined behavior, but for
  4319. * joinable threads it's a valid usage that must be handled.
  4320. * Signals must be blocked since pthread_kill must be AS-safe. */
  4321. - __block_app_sigs(&set);
  4322. LOCK(self->killlock);
  4323. /* The thread list lock must be AS-safe, and thus depends on
  4324. @@ -87,6 +100,7 @@ _Noreturn void __pthread_exit(void *result)
  4325. if (self->next == self) {
  4326. __tl_unlock();
  4327. UNLOCK(self->killlock);
  4328. + self->detach_state = state;
  4329. __restore_sigs(&set);
  4330. exit(0);
  4331. }
  4332. @@ -125,10 +139,6 @@ _Noreturn void __pthread_exit(void *result)
  4333. self->prev->next = self->next;
  4334. self->prev = self->next = self;
  4335. - /* This atomic potentially competes with a concurrent pthread_detach
  4336. - * call; the loser is responsible for freeing thread resources. */
  4337. - int state = a_cas(&self->detach_state, DT_JOINABLE, DT_EXITING);
  4338. -
  4339. if (state==DT_DETACHED && self->map_base) {
  4340. /* Detached threads must block even implementation-internal
  4341. * signals, since they will not have a stack in their last
  4342. @@ -140,16 +150,13 @@ _Noreturn void __pthread_exit(void *result)
  4343. if (self->robust_list.off)
  4344. __syscall(SYS_set_robust_list, 0, 3*sizeof(long));
  4345. - /* Since __unmapself bypasses the normal munmap code path,
  4346. - * explicitly wait for vmlock holders first. */
  4347. - __vm_wait();
  4348. -
  4349. /* The following call unmaps the thread's stack mapping
  4350. * and then exits without touching the stack. */
  4351. __unmapself(self->map_base, self->map_size);
  4352. }
  4353. /* Wake any joiner. */
  4354. + a_store(&self->detach_state, DT_EXITED);
  4355. __wake(&self->detach_state, 1, 1);
  4356. /* After the kernel thread exits, its tid may be reused. Clear it
  4357. @@ -314,7 +321,7 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
  4358. new->detach_state = DT_JOINABLE;
  4359. }
  4360. new->robust_list.head = &new->robust_list.head;
  4361. - new->CANARY = self->CANARY;
  4362. + new->canary = self->canary;
  4363. new->sysinfo = self->sysinfo;
  4364. /* Setup argument structure for the new thread on its stack.
  4365. diff --git a/src/thread/pthread_mutex_destroy.c b/src/thread/pthread_mutex_destroy.c
  4366. index 6d49e689..8d1bf77b 100644
  4367. --- a/src/thread/pthread_mutex_destroy.c
  4368. +++ b/src/thread/pthread_mutex_destroy.c
  4369. @@ -1,6 +1,10 @@
  4370. -#include <pthread.h>
  4371. +#include "pthread_impl.h"
  4372. int pthread_mutex_destroy(pthread_mutex_t *mutex)
  4373. {
  4374. + /* If the mutex being destroyed is process-shared and has nontrivial
  4375. + * type (tracking ownership), it might be in the pending slot of a
  4376. + * robust_list; wait for quiescence. */
  4377. + if (mutex->_m_type > 128) __vm_wait();
  4378. return 0;
  4379. }
  4380. diff --git a/src/thread/pthread_mutexattr_setprotocol.c b/src/thread/pthread_mutexattr_setprotocol.c
  4381. index 511cc32d..8b80c1ce 100644
  4382. --- a/src/thread/pthread_mutexattr_setprotocol.c
  4383. +++ b/src/thread/pthread_mutexattr_setprotocol.c
  4384. @@ -1,24 +1,23 @@
  4385. #include "pthread_impl.h"
  4386. #include "syscall.h"
  4387. -static pthread_once_t check_pi_once;
  4388. -static int check_pi_result;
  4389. -
  4390. -static void check_pi()
  4391. -{
  4392. - volatile int lk = 0;
  4393. - check_pi_result = -__syscall(SYS_futex, &lk, FUTEX_LOCK_PI, 0, 0);
  4394. -}
  4395. +static volatile int check_pi_result = -1;
  4396. int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int protocol)
  4397. {
  4398. + int r;
  4399. switch (protocol) {
  4400. case PTHREAD_PRIO_NONE:
  4401. a->__attr &= ~8;
  4402. return 0;
  4403. case PTHREAD_PRIO_INHERIT:
  4404. - pthread_once(&check_pi_once, check_pi);
  4405. - if (check_pi_result) return check_pi_result;
  4406. + r = check_pi_result;
  4407. + if (r < 0) {
  4408. + volatile int lk = 0;
  4409. + r = -__syscall(SYS_futex, &lk, FUTEX_LOCK_PI, 0, 0);
  4410. + a_store(&check_pi_result, r);
  4411. + }
  4412. + if (r) return r;
  4413. a->__attr |= 8;
  4414. return 0;
  4415. case PTHREAD_PRIO_PROTECT:
  4416. diff --git a/src/thread/pthread_mutexattr_setrobust.c b/src/thread/pthread_mutexattr_setrobust.c
  4417. index 04db92a6..30a9ac3b 100644
  4418. --- a/src/thread/pthread_mutexattr_setrobust.c
  4419. +++ b/src/thread/pthread_mutexattr_setrobust.c
  4420. @@ -1,22 +1,20 @@
  4421. #include "pthread_impl.h"
  4422. #include "syscall.h"
  4423. -static pthread_once_t check_robust_once;
  4424. -static int check_robust_result;
  4425. -
  4426. -static void check_robust()
  4427. -{
  4428. - void *p;
  4429. - size_t l;
  4430. - check_robust_result = -__syscall(SYS_get_robust_list, 0, &p, &l);
  4431. -}
  4432. +static volatile int check_robust_result = -1;
  4433. int pthread_mutexattr_setrobust(pthread_mutexattr_t *a, int robust)
  4434. {
  4435. if (robust > 1U) return EINVAL;
  4436. if (robust) {
  4437. - pthread_once(&check_robust_once, check_robust);
  4438. - if (check_robust_result) return check_robust_result;
  4439. + int r = check_robust_result;
  4440. + if (r < 0) {
  4441. + void *p;
  4442. + size_t l;
  4443. + r = -__syscall(SYS_get_robust_list, 0, &p, &l);
  4444. + a_store(&check_robust_result, r);
  4445. + }
  4446. + if (r) return r;
  4447. a->__attr |= 4;
  4448. return 0;
  4449. }
  4450. diff --git a/src/thread/s390x/clone.s b/src/thread/s390x/clone.s
  4451. index 577748ea..2125f20b 100644
  4452. --- a/src/thread/s390x/clone.s
  4453. +++ b/src/thread/s390x/clone.s
  4454. @@ -17,6 +17,9 @@ __clone:
  4455. # if (!tid) syscall(SYS_exit, a(d));
  4456. # return tid;
  4457. + # preserve call-saved register used as syscall arg
  4458. + stg %r6, 48(%r15)
  4459. +
  4460. # create initial stack frame for new thread
  4461. nill %r3, 0xfff8
  4462. aghi %r3, -160
  4463. @@ -35,6 +38,9 @@ __clone:
  4464. lg %r6, 160(%r15)
  4465. svc 120
  4466. + # restore call-saved register
  4467. + lg %r6, 48(%r15)
  4468. +
  4469. # if error or if we're the parent, return
  4470. ltgr %r2, %r2
  4471. bnzr %r14
  4472. diff --git a/src/thread/s390x/syscall_cp.s b/src/thread/s390x/syscall_cp.s
  4473. index c1da40de..d094cbf5 100644
  4474. --- a/src/thread/s390x/syscall_cp.s
  4475. +++ b/src/thread/s390x/syscall_cp.s
  4476. @@ -14,6 +14,7 @@ __cp_begin:
  4477. icm %r2, 15, 0(%r2)
  4478. jne __cp_cancel
  4479. + stg %r6, 48(%r15)
  4480. stg %r7, 56(%r15)
  4481. lgr %r1, %r3
  4482. lgr %r2, %r4
  4483. @@ -26,6 +27,7 @@ __cp_begin:
  4484. __cp_end:
  4485. lg %r7, 56(%r15)
  4486. + lg %r6, 48(%r15)
  4487. br %r14
  4488. __cp_cancel:
  4489. diff --git a/src/thread/sem_open.c b/src/thread/sem_open.c
  4490. index de8555c5..0ad29de9 100644
  4491. --- a/src/thread/sem_open.c
  4492. +++ b/src/thread/sem_open.c
  4493. @@ -12,6 +12,12 @@
  4494. #include <stdlib.h>
  4495. #include <pthread.h>
  4496. #include "lock.h"
  4497. +#include "fork_impl.h"
  4498. +
  4499. +#define malloc __libc_malloc
  4500. +#define calloc __libc_calloc
  4501. +#define realloc undef
  4502. +#define free undef
  4503. static struct {
  4504. ino_t ino;
  4505. @@ -19,6 +25,7 @@ static struct {
  4506. int refcnt;
  4507. } *semtab;
  4508. static volatile int lock[1];
  4509. +volatile int *const __sem_open_lockptr = lock;
  4510. #define FLAGS (O_RDWR|O_NOFOLLOW|O_CLOEXEC|O_NONBLOCK)
  4511. @@ -163,10 +170,12 @@ int sem_close(sem_t *sem)
  4512. int i;
  4513. LOCK(lock);
  4514. for (i=0; i<SEM_NSEMS_MAX && semtab[i].sem != sem; i++);
  4515. - if (!--semtab[i].refcnt) {
  4516. - semtab[i].sem = 0;
  4517. - semtab[i].ino = 0;
  4518. + if (--semtab[i].refcnt) {
  4519. + UNLOCK(lock);
  4520. + return 0;
  4521. }
  4522. + semtab[i].sem = 0;
  4523. + semtab[i].ino = 0;
  4524. UNLOCK(lock);
  4525. munmap(sem, sizeof *sem);
  4526. return 0;
  4527. diff --git a/src/thread/synccall.c b/src/thread/synccall.c
  4528. index 648a6ad4..d58c851f 100644
  4529. --- a/src/thread/synccall.c
  4530. +++ b/src/thread/synccall.c
  4531. @@ -63,7 +63,8 @@ void __synccall(void (*func)(void *), void *ctx)
  4532. sem_init(&target_sem, 0, 0);
  4533. sem_init(&caller_sem, 0, 0);
  4534. - if (!libc.threads_minus_1) goto single_threaded;
  4535. + if (!libc.threads_minus_1 || __syscall(SYS_gettid) != self->tid)
  4536. + goto single_threaded;
  4537. callback = func;
  4538. context = ctx;
  4539. diff --git a/src/thread/vmlock.c b/src/thread/vmlock.c
  4540. index 75f3cb76..fa0a8e3c 100644
  4541. --- a/src/thread/vmlock.c
  4542. +++ b/src/thread/vmlock.c
  4543. @@ -1,6 +1,8 @@
  4544. #include "pthread_impl.h"
  4545. +#include "fork_impl.h"
  4546. static volatile int vmlock[2];
  4547. +volatile int *const __vmlock_lockptr = vmlock;
  4548. void __vm_wait()
  4549. {
  4550. diff --git a/src/time/__tz.c b/src/time/__tz.c
  4551. index 49a7371e..09a6317e 100644
  4552. --- a/src/time/__tz.c
  4553. +++ b/src/time/__tz.c
  4554. @@ -6,6 +6,12 @@
  4555. #include <sys/mman.h>
  4556. #include "libc.h"
  4557. #include "lock.h"
  4558. +#include "fork_impl.h"
  4559. +
  4560. +#define malloc __libc_malloc
  4561. +#define calloc undef
  4562. +#define realloc undef
  4563. +#define free undef
  4564. long __timezone = 0;
  4565. int __daylight = 0;
  4566. @@ -30,6 +36,7 @@ static char *old_tz = old_tz_buf;
  4567. static size_t old_tz_size = sizeof old_tz_buf;
  4568. static volatile int lock[1];
  4569. +volatile int *const __timezone_lockptr = lock;
  4570. static int getint(const char **p)
  4571. {
  4572. @@ -178,7 +185,7 @@ static void do_tzset()
  4573. zi = map;
  4574. if (map) {
  4575. int scale = 2;
  4576. - if (sizeof(time_t) > 4 && map[4]=='2') {
  4577. + if (map[4]!='1') {
  4578. size_t skip = zi_dotprod(zi+20, VEC(1,1,8,5,6,1), 6);
  4579. trans = zi+skip+44+44;
  4580. scale++;
  4581. diff --git a/src/time/timer_create.c b/src/time/timer_create.c
  4582. index 455d49fc..4bef2390 100644
  4583. --- a/src/time/timer_create.c
  4584. +++ b/src/time/timer_create.c
  4585. @@ -2,6 +2,7 @@
  4586. #include <setjmp.h>
  4587. #include <limits.h>
  4588. #include "pthread_impl.h"
  4589. +#include "atomic.h"
  4590. struct ksigevent {
  4591. union sigval sigev_value;
  4592. @@ -32,19 +33,6 @@ static void cleanup_fromsig(void *p)
  4593. longjmp(p, 1);
  4594. }
  4595. -static void timer_handler(int sig, siginfo_t *si, void *ctx)
  4596. -{
  4597. -}
  4598. -
  4599. -static void install_handler()
  4600. -{
  4601. - struct sigaction sa = {
  4602. - .sa_sigaction = timer_handler,
  4603. - .sa_flags = SA_SIGINFO | SA_RESTART
  4604. - };
  4605. - __libc_sigaction(SIGTIMER, &sa, 0);
  4606. -}
  4607. -
  4608. static void *start(void *arg)
  4609. {
  4610. pthread_t self = __pthread_self();
  4611. @@ -71,7 +59,7 @@ static void *start(void *arg)
  4612. int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict res)
  4613. {
  4614. - static pthread_once_t once = PTHREAD_ONCE_INIT;
  4615. + volatile static int init = 0;
  4616. pthread_t td;
  4617. pthread_attr_t attr;
  4618. int r;
  4619. @@ -83,11 +71,15 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
  4620. switch (evp ? evp->sigev_notify : SIGEV_SIGNAL) {
  4621. case SIGEV_NONE:
  4622. case SIGEV_SIGNAL:
  4623. + case SIGEV_THREAD_ID:
  4624. if (evp) {
  4625. ksev.sigev_value = evp->sigev_value;
  4626. ksev.sigev_signo = evp->sigev_signo;
  4627. ksev.sigev_notify = evp->sigev_notify;
  4628. - ksev.sigev_tid = 0;
  4629. + if (evp->sigev_notify == SIGEV_THREAD_ID)
  4630. + ksev.sigev_tid = evp->sigev_notify_thread_id;
  4631. + else
  4632. + ksev.sigev_tid = 0;
  4633. ksevp = &ksev;
  4634. }
  4635. if (syscall(SYS_timer_create, clk, ksevp, &timerid) < 0)
  4636. @@ -95,7 +87,11 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
  4637. *res = (void *)(intptr_t)timerid;
  4638. break;
  4639. case SIGEV_THREAD:
  4640. - pthread_once(&once, install_handler);
  4641. + if (!init) {
  4642. + struct sigaction sa = { .sa_handler = SIG_DFL };
  4643. + __libc_sigaction(SIGTIMER, &sa, 0);
  4644. + a_store(&init, 1);
  4645. + }
  4646. if (evp->sigev_notify_attributes)
  4647. attr = *evp->sigev_notify_attributes;
  4648. else
  4649. @@ -115,7 +111,7 @@ int timer_create(clockid_t clk, struct sigevent *restrict evp, timer_t *restrict
  4650. ksev.sigev_value.sival_ptr = 0;
  4651. ksev.sigev_signo = SIGTIMER;
  4652. - ksev.sigev_notify = 4; /* SIGEV_THREAD_ID */
  4653. + ksev.sigev_notify = SIGEV_THREAD_ID;
  4654. ksev.sigev_tid = td->tid;
  4655. if (syscall(SYS_timer_create, clk, &ksev, &timerid) < 0)
  4656. timerid = -1;
  4657. diff --git a/src/unistd/close.c b/src/unistd/close.c
  4658. index 5b38e019..a2105f50 100644
  4659. --- a/src/unistd/close.c
  4660. +++ b/src/unistd/close.c
  4661. @@ -1,5 +1,6 @@
  4662. #include <unistd.h>
  4663. #include <errno.h>
  4664. +#include "aio_impl.h"
  4665. #include "syscall.h"
  4666. static int dummy(int fd)
  4667. diff --git a/src/unistd/faccessat.c b/src/unistd/faccessat.c
  4668. index 76bbd4c7..557503eb 100644
  4669. --- a/src/unistd/faccessat.c
  4670. +++ b/src/unistd/faccessat.c
  4671. @@ -25,12 +25,17 @@ static int checker(void *p)
  4672. int faccessat(int fd, const char *filename, int amode, int flag)
  4673. {
  4674. - if (!flag || (flag==AT_EACCESS && getuid()==geteuid() && getgid()==getegid()))
  4675. - return syscall(SYS_faccessat, fd, filename, amode, flag);
  4676. + if (flag) {
  4677. + int ret = __syscall(SYS_faccessat2, fd, filename, amode, flag);
  4678. + if (ret != -ENOSYS) return __syscall_ret(ret);
  4679. + }
  4680. - if (flag != AT_EACCESS)
  4681. + if (flag & ~AT_EACCESS)
  4682. return __syscall_ret(-EINVAL);
  4683. + if (!flag || (getuid()==geteuid() && getgid()==getegid()))
  4684. + return syscall(SYS_faccessat, fd, filename, amode);
  4685. +
  4686. char stack[1024];
  4687. sigset_t set;
  4688. pid_t pid;
  4689. diff --git a/src/unistd/readlink.c b/src/unistd/readlink.c
  4690. index a152d524..32f4537f 100644
  4691. --- a/src/unistd/readlink.c
  4692. +++ b/src/unistd/readlink.c
  4693. @@ -4,9 +4,16 @@
  4694. ssize_t readlink(const char *restrict path, char *restrict buf, size_t bufsize)
  4695. {
  4696. + char dummy[1];
  4697. + if (!bufsize) {
  4698. + buf = dummy;
  4699. + bufsize = 1;
  4700. + }
  4701. #ifdef SYS_readlink
  4702. - return syscall(SYS_readlink, path, buf, bufsize);
  4703. + int r = __syscall(SYS_readlink, path, buf, bufsize);
  4704. #else
  4705. - return syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
  4706. + int r = __syscall(SYS_readlinkat, AT_FDCWD, path, buf, bufsize);
  4707. #endif
  4708. + if (buf == dummy && r > 0) r = 0;
  4709. + return __syscall_ret(r);
  4710. }
  4711. diff --git a/src/unistd/readlinkat.c b/src/unistd/readlinkat.c
  4712. index 9af45cd5..f79d3d14 100644
  4713. --- a/src/unistd/readlinkat.c
  4714. +++ b/src/unistd/readlinkat.c
  4715. @@ -3,5 +3,12 @@
  4716. ssize_t readlinkat(int fd, const char *restrict path, char *restrict buf, size_t bufsize)
  4717. {
  4718. - return syscall(SYS_readlinkat, fd, path, buf, bufsize);
  4719. + char dummy[1];
  4720. + if (!bufsize) {
  4721. + buf = dummy;
  4722. + bufsize = 1;
  4723. + }
  4724. + int r = __syscall(SYS_readlinkat, fd, path, buf, bufsize);
  4725. + if (buf == dummy && r > 0) r = 0;
  4726. + return __syscall_ret(r);
  4727. }
  4728. diff --git a/src/unistd/setxid.c b/src/unistd/setxid.c
  4729. index 0239f8af..487c1a16 100644
  4730. --- a/src/unistd/setxid.c
  4731. +++ b/src/unistd/setxid.c
  4732. @@ -1,20 +1,19 @@
  4733. #include <unistd.h>
  4734. -#include <errno.h>
  4735. +#include <signal.h>
  4736. #include "syscall.h"
  4737. #include "libc.h"
  4738. -#include "pthread_impl.h"
  4739. struct ctx {
  4740. int id, eid, sid;
  4741. - int nr, err;
  4742. + int nr, ret;
  4743. };
  4744. static void do_setxid(void *p)
  4745. {
  4746. struct ctx *c = p;
  4747. - if (c->err>0) return;
  4748. - int ret = -__syscall(c->nr, c->id, c->eid, c->sid);
  4749. - if (ret && !c->err) {
  4750. + if (c->ret<0) return;
  4751. + int ret = __syscall(c->nr, c->id, c->eid, c->sid);
  4752. + if (ret && !c->ret) {
  4753. /* If one thread fails to set ids after another has already
  4754. * succeeded, forcibly killing the process is the only safe
  4755. * thing to do. State is inconsistent and dangerous. Use
  4756. @@ -22,18 +21,14 @@ static void do_setxid(void *p)
  4757. __block_all_sigs(0);
  4758. __syscall(SYS_kill, __syscall(SYS_getpid), SIGKILL);
  4759. }
  4760. - c->err = ret;
  4761. + c->ret = ret;
  4762. }
  4763. int __setxid(int nr, int id, int eid, int sid)
  4764. {
  4765. - /* err is initially nonzero so that failure of the first thread does not
  4766. + /* ret is initially nonzero so that failure of the first thread does not
  4767. * trigger the safety kill above. */
  4768. - struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .err = -1 };
  4769. + struct ctx c = { .nr = nr, .id = id, .eid = eid, .sid = sid, .ret = 1 };
  4770. __synccall(do_setxid, &c);
  4771. - if (c.err) {
  4772. - if (c.err>0) errno = c.err;
  4773. - return -1;
  4774. - }
  4775. - return 0;
  4776. + return __syscall_ret(c.ret);
  4777. }