12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146 |
- commit 3975577922aedab7d60788dd320a2c8e4e94bc6e
- Author: Roman Yeryomin <roman@ubnt.com>
- Date: Thu Jul 2 12:29:00 2015 +0300
- socket.h: cleanup/reorder mips and powerpc bits/socket.h
-
- ....to be somewhat consistent and easily comparable with asm/socket.h
-
- Signed-off-by: Roman Yeryomin <roman@ubnt.com>
- commit 29ec7677a73a5227badbb1064205be09e707e466
- Author: Roman Yeryomin <roman@ubnt.com>
- Date: Thu Jul 2 12:28:41 2015 +0300
- socket.h: fix SO_* for mips
-
- Signed-off-by: Roman Yeryomin <roman@ubnt.com>
- commit 3fffa7a658aa925b8f95d36aef7531c1827dbf28
- Author: Felix Fietkau <nbd@openwrt.org>
- Date: Tue Jul 21 15:01:25 2015 +0200
- mips: fix mcontext_t register array field name
-
- glibc and uclibc use gregs instead of regs
-
- Signed-off-by: Felix Fietkau <nbd@openwrt.org>
- commit 0f9c2666aca95eb98eb0ef4f4d8d1473c8ce3fa0
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Thu Jul 9 18:36:02 2015 +0000
- handle loss of syslog socket connection
-
- when traditional syslogd implementations are restarted, the old server
- socket ceases to exist and a new unix socket with the same pathname is
- created. when this happens, the default destination address associated
- with the client socket via connect is no longer valid, and attempts to
- send produce errors. this happens despite the socket being datagram
- type, and is in contrast to the behavior that would be seen with an IP
- datagram (UDP) socket.
-
- in order to avoid a situation where the application is unable to send
- further syslog messages without calling closelog, this patch makes
- syslog attempt to reconnect the socket when send returns an error
- indicating a lost connection.
-
- additionally, initial failure to connect the socket no longer results
- in the socket being closed. this ensures that an application which
- calls openlog to reserve the socket file descriptor will not run into
- a situation where transient connection failure (e.g. due to syslogd
- restart) prevents fd reservation. however, applications which may be
- unable to connect the socket later (e.g. due to chroot, restricted
- permissions, seccomp, etc.) will still fail to log if the syslog
- socket cannot be connected at openlog time or if it has to be
- reconnected later.
- commit 11894f6d3a80be950a490dc7dfab349f057a545f
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Thu Jul 9 17:07:35 2015 +0000
- fix incorrect void return type for syncfs function
-
- being nonstandard, the closest thing to a specification for this
- function is its man page, which documents it as returning int. it can
- fail with EBADF if the file descriptor passed is invalid.
- commit e8cbe0bad4284906230a53af4c91ad2b9713d03b
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Wed Jul 8 02:46:45 2015 +0000
- fix negated return value of ns_skiprr, breakage in related functions
-
- due to a reversed pointer difference computation, ns_skiprr always
- returned a negative value, which functions using it would interpret as
- an error.
-
- patch by Yu Lu.
- commit fb58545f8d1c5fa32122244caeaf3625c12ddc01
- Author: Shiz <hi@shiz.me>
- Date: Sun Jun 28 23:08:21 2015 +0200
- add musl-clang, a wrapper for system clang installs
-
- musl-clang allows the user to compile musl-powered programs using their
- already existent clang install, without the need of a special cross compiler.
- it achieves this by wrapping around both the system clang install and the
- linker and passing them special flags to re-target musl at runtime.
- it does only affect invocations done through the special musl-clang wrapper
- script, so that the user setup remains fully intact otherwise.
-
- the clang wrapper consists of the compiler frontend wrapper script,
- musl-clang, and the linker wrapper script, ld.musl-clang.
- musl-clang makes sure clang invokes ld.musl-clang to link objects; neither
- script needs to be in PATH for the wrapper to work.
- commit f8db6f74b2c74a50c4dec7e30be5215f0e2c37a6
- Author: Shiz <hi@shiz.me>
- Date: Sun Jun 28 23:08:20 2015 +0200
- build: fix musl-targeting toolchain test
-
- the old test was broken in that it would never fail on a toolchains built
- without dynamic linking support, leading to the wrapper script possibly being
- installed on compilers that do not support it. in addition, the new test is
- portable across compilers: the old test only worked on GCC.
-
- the new test works by testing whether the toolchain libc defines __GLIBC__:
- most non-musl Linux libc's do define this for compatibility even when they
- are not glibc, so this is a safe bet to check for musl. in addition, the
- compiler runtime would need to have a somewhat glibc-compatible ABI in the
- first place, so any non-glibc compatible libc's compiler runtime might not
- work. it is safer to disable these cases by default and have the user enable
- the wrappers manually there using --enable-wrapper if they certain it works.
- commit b3cd7d13fe630ba1847326242525298e361018c1
- Author: Shiz <hi@shiz.me>
- Date: Sun Jun 28 23:08:19 2015 +0200
- build: overhaul wrapper script system for multiple wrapper support
-
- this overhauls part of the build system in order to support multiple
- toolchain wrapper scripts, as opposed to solely the musl-gcc wrapper as
- before. it thereby replaces --enable-gcc-wrapper with --enable-wrapper=...,
- which has the options 'auto' (the default, detect whether to use wrappers),
- 'all' (build and install all wrappers), 'no' (don't build any) and finally
- the options named after the individual compiler scripts (currently only
- 'gcc' is available) to build and install only that wrapper.
- the old --enable-gcc-wrapper is removed from --help, but still available.
-
- it also modifies the wrappers to use the C compiler specified to the build
- system as 'inner' compiler, when applicable. as wrapper detection works by
- probing this compiler, it may not work with any other.
- commit 2a780aa3050b86d888489361f04220bfb58890a1
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Mon Jul 6 22:13:11 2015 +0000
- treat empty TZ environment variable as GMT rather than default
-
- this improves compatibility with the behavior of other systems and
- with some applications which set an empty TZ var to disable use of
- local time by mktime, etc.
- commit 8f08a58c635bea5cdfae6bc0e323c80aa9ff82a7
- Author: Alexander Monakov <amonakov@ispras.ru>
- Date: Sun Jun 28 02:48:33 2015 +0300
- dynlink.c: pass gnu-hash table pointer to gnu_lookup
-
- The callers need to check the value of the pointer anyway, so make
- them pass the pointer to gnu_lookup instead of reloading it there.
-
- Reorder gnu_lookup arguments so that always-used ones are listed
- first. GCC can choose a calling convention with arguments in registers
- (e.g. up to 3 arguments in eax, ecx, edx on x86), but cannot reorder
- the arguments for static functions.
- commit 5b4286e12cd6baac343b10a41dc17ac578832089
- Author: Alexander Monakov <amonakov@ispras.ru>
- Date: Sun Jun 28 02:48:32 2015 +0300
- dynlink.c: slim down gnu_lookup
-
- Do not reference dso->syms and dso->strings until point of use.
- Check 'h1 == (h2|1)', the simplest condition, before the others.
- commit 84389c64562e2b2ba43225b5b7a9df7d974479b1
- Author: Alexander Monakov <amonakov@ispras.ru>
- Date: Sun Jun 28 02:48:31 2015 +0300
- dynlink.c: use bloom filter in gnu hash lookup
-
- Introduce gnu_lookup_filtered and use it to speed up symbol lookups in
- find_sym (do_dlsym is left as is, based on an expectation that
- frequently dlsym queries will use a dlopen handle rather than
- RTLD_NEXT or RTLD_DEFAULT, and will not need to look at more than one
- DSO).
- commit 66d45787c865a1807ae397a89a14699394ed4fa4
- Author: Alexander Monakov <amonakov@ispras.ru>
- Date: Sun Jun 28 02:48:30 2015 +0300
- dynlink.c: use a faster expression in gnu_hash
-
- With -Os, GCC uses a multiply rather than a shift and addition for 'h*33'.
- Use a more efficient expression explicitely.
- commit 6ba5517a460c6c438f64d69464fdfc3269a4c91a
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Thu Jun 25 22:22:00 2015 +0000
- fix local-dynamic model TLS on mips and powerpc
-
- the TLS ABI spec for mips, powerpc, and some other (presently
- unsupported) RISC archs has the return value of __tls_get_addr offset
- by +0x8000 and the result of DTPOFF relocations offset by -0x8000. I
- had previously assumed this part of the ABI was actually just an
- implementation detail, since the adjustments cancel out. however, when
- the local dynamic model is used for accessing TLS that's known to be
- in the same DSO, either of the following may happen:
-
- 1. the -0x8000 offset may already be applied to the argument structure
- passed to __tls_get_addr at ld time, without any opportunity for
- runtime relocations.
-
- 2. __tls_get_addr may be used with a zero offset argument to obtain a
- base address for the module's TLS, to which the caller then applies
- immediate offsets for individual objects accessed using the local
- dynamic model. since the immediate offsets have the -0x8000 adjustment
- applied to them, the base address they use needs to include the
- +0x8000 offset.
-
- it would be possible, but more complex, to store the pointers in the
- dtv[] array with the +0x8000 offset pre-applied, to avoid the runtime
- cost of adding 0x8000 on each call to __tls_get_addr. this change
- could be made later if measurements show that it would help.
- commit ce337daa00e42d4f2d9a4d9ae0ed51b20249d924
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 23 04:03:42 2015 +0000
- make dynamic linker work around MAP_FAILED mmap failure on nommu kernels
-
- previously, loading of additional libraries beyond libc/ldso did not
- work on nommu kernels, nor did loading programs via invocation of the
- dynamic linker as a command.
- commit a59341420fdedb288d9ff80e73609ae44e9cf258
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 23 00:12:25 2015 +0000
- reimplement strverscmp to fix corner cases
-
- this interface is non-standardized and is a GNU invention, and as
- such, our implementation should match the behavior of the GNU
- function. one peculiarity the old implementation got wrong was the
- handling of all-zero digit sequences: they are supposed to compare
- greater than digit sequences of which they are a proper prefix, as in
- 009 < 00.
-
- in addition, high bytes were treated with char signedness rather than
- as unsigned. this was wrong regardless of what the GNU function does
- since the resulting order relation varied by arch.
-
- the new strverscmp implementation makes explicit the cases where the
- order differs from what strcmp would produce, of which there are only
- two.
- commit 153e952e1a688859d7095345b17e6c1df74a295c
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Mon Jun 22 20:33:28 2015 +0000
- fix regression/typo that disabled __simple_malloc when calloc is used
-
- commit ba819787ee93ceae94efd274f7849e317c1bff58 introduced this
- regression. since the __malloc0 weak alias was not properly provided
- by __simple_malloc, use of calloc forced the full malloc to be linked.
- commit ba819787ee93ceae94efd274f7849e317c1bff58
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Mon Jun 22 18:50:09 2015 +0000
- fix calloc when __simple_malloc implementation is used
-
- previously, calloc's implementation encoded assumptions about the
- implementation of malloc, accessing a size_t word just prior to the
- allocated memory to determine if it was obtained by mmap to optimize
- out the zero-filling. when __simple_malloc is used (static linking a
- program with no realloc/free), it doesn't matter if the result of this
- check is wrong, since all allocations are zero-initialized anyway. but
- the access could be invalid if it crosses a page boundary or if the
- pointer is not sufficiently aligned, which can happen for very small
- allocations.
-
- this patch fixes the issue by moving the zero-fill logic into malloc.c
- with the full malloc, as a new function named __malloc0, which is
- provided by a weak alias to __simple_malloc (which always gives
- zero-filled memory) when the full malloc is not in use.
- commit 55d061f031085f24d138664c897791aebe9a2fab
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 20 03:01:07 2015 +0000
- provide __stack_chk_fail_local in libc.a
-
- this symbol is needed only on archs where the PLT call ABI is klunky,
- and only for position-independent code compiled with stack protector.
- thus references usually only appear in shared libraries or PIE
- executables, but they can also appear when linking statically if some
- of the object files being linked were built as PIC/PIE.
-
- normally libssp_nonshared.a from the compiler toolchain should provide
- __stack_chk_fail_local, but reportedly it appears prior to -lc in the
- link order, thus failing to satisfy references from libc itself (which
- arise only if libc.a was built as PIC/PIE with stack protector
- enabled).
- commit ce3688eca920aa77549323f84e21f33522397115
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 20 02:54:30 2015 +0000
- work around mips detached thread exit breakage due to kernel regression
-
- linux kernel commit 46e12c07b3b9603c60fc1d421ff18618241cb081 caused
- the mips syscall mechanism to fail with EFAULT when the userspace
- stack pointer is invalid, breaking __unmapself used for detached
- thread exit. the workaround is to set $sp to a known-valid, readable
- address, and the simplest one to obtain is the address of the current
- function, which is available (per o32 calling convention) in $25.
- commit 75eceb3ae824d54e865686c0c538551aeebf3372
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Wed Jun 17 17:21:46 2015 +0000
- ignore ENOSYS error from mprotect in pthread_create and dynamic linker
-
- this error simply indicated a system without memory protection (NOMMU)
- and should not cause failure in the caller.
- commit 10d0268ccfab9152250eeeed3952ce3fed44131a
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 16 15:25:02 2015 +0000
- switch to using trap number 31 for syscalls on sh
-
- nominally the low bits of the trap number on sh are the number of
- syscall arguments, but they have never been used by the kernel, and
- some code making syscalls does not even know the number of arguments
- and needs to pass an arbitrary high number anyway.
-
- sh3/sh4 traditionally used the trap range 16-31 for syscalls, but part
- of this range overlapped with hardware exceptions/interrupts on sh2
- hardware, so an incompatible range 32-47 was chosen for sh2.
-
- using trap number 31 everywhere, since it's in the existing sh3/sh4
- range and does not conflict with sh2 hardware, is a proposed
- unification of the kernel syscall convention that will allow binaries
- to be shared between sh2 and sh3/sh4. if this is not accepted into the
- kernel, we can refit the sh2 target with runtime selection mechanisms
- for the trap number, but doing so would be invasive and would entail
- non-trivial overhead.
- commit 3366a99b17847b58f2d8cc52cbb5d65deb824f8a
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 16 14:55:06 2015 +0000
- switch sh port's __unmapself to generic version when running on sh2/nommu
-
- due to the way the interrupt and syscall trap mechanism works,
- userspace on sh2 must never set the stack pointer to an invalid value.
- thus, the approach used on most archs, where __unmapself executes with
- no stack for the interval between SYS_munmap and SYS_exit, is not
- viable on sh2.
-
- in order not to pessimize sh3/sh4, the sh asm version of __unmapself
- is not removed. instead it's renamed and redirected through code that
- calls either the generic (safe) __unmapself or the sh3/sh4 asm,
- depending on compile-time and run-time conditions.
- commit f9d84554bae0fa17c9a1d724549c4408022228a5
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 16 14:28:30 2015 +0000
- add support for sh2 interrupt-masking-based atomics to sh port
-
- the sh2 target is being considered an ISA subset of sh3/sh4, in the
- sense that binaries built for sh2 are intended to be usable on later
- cpu models/kernels with mmu support. so rather than hard-coding
- sh2-specific atomics, the runtime atomic selection mechanisms that was
- already in place has been extended to add sh2 atomics.
-
- at this time, the sh2 atomics are not SMP-compatible; since the ISA
- lacks actual atomic operations, the new code instead masks interrupts
- for the duration of the atomic operation, producing an atomic result
- on single-core. this is only possible because the kernel/hardware does
- not impose protections against userspace doing so. additional changes
- will be needed to support future SMP systems.
-
- care has been taken to avoid producing significant additional code
- size in the case where it's known at compile-time that the target is
- not sh2 and does not need sh2-specific code.
- commit 1b0cdc8700d29ef018bf226d74b2b58b23bce91c
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 16 07:11:19 2015 +0000
- refactor stdio open file list handling, move it out of global libc struct
-
- functions which open in-memory FILE stream variants all shared a tail
- with __fdopen, adding the FILE structure to stdio's open file list.
- replacing this common tail with a function call reduces code size and
- duplication of logic. the list is also partially encapsulated now.
-
- function signatures were chosen to facilitate tail call optimization
- and reduce the need for additional accessor functions.
-
- with these changes, static linked programs that do not use stdio no
- longer have an open file list at all.
- commit f22a9edaf8a6f2ca1d314d18b3785558279a5c03
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 16 06:18:00 2015 +0000
- byte-based C locale, phase 3: make MB_CUR_MAX variable to activate code
-
- this patch activates the new byte-based C locale (high bytes treated
- as abstract code unit "characters" rather than decoded as multibyte
- characters) by making the value of MB_CUR_MAX depend on the active
- locale. for the C locale, the LC_CTYPE category pointer is null,
- yielding a value of 1. all other locales yield a value of 4.
- commit 16f18d036d9a7bf590ee6eb86785c0a9658220b6
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 16 05:35:31 2015 +0000
- byte-based C locale, phase 2: stdio and iconv (multibyte callers)
-
- this patch adjusts libc components which use the multibyte functions
- internally, and which depend on them operating in a particular
- encoding, to make the appropriate locale changes before calling them
- and restore the calling thread's locale afterwards. activating the
- byte-based C locale without these changes would cause regressions in
- stdio and iconv.
-
- in the case of iconv, the current implementation was simply using the
- multibyte functions as UTF-8 conversions. setting a multibyte UTF-8
- locale for the duration of the iconv operation allows the code to
- continue working.
-
- in the case of stdio, POSIX requires that FILE streams have an
- encoding rule bound at the time of setting wide orientation. as long
- as all locales, including the C locale, used the same encoding,
- treating high bytes as UTF-8, there was no need to store an encoding
- rule as part of the stream's state.
-
- a new locale field in the FILE structure points to the locale that
- should be made active during fgetwc/fputwc/ungetwc on the stream. it
- cannot point to the locale active at the time the stream becomes
- oriented, because this locale could be mutable (the global locale) or
- could be destroyed (locale_t objects produced by newlocale) before the
- stream is closed. instead, a pointer to the static C or C.UTF-8 locale
- object added in commit commit aeeac9ca5490d7d90fe061ab72da446c01ddf746
- is used. this is valid since categories other than LC_CTYPE will not
- affect these functions.
- commit 1507ebf837334e9e07cfab1ca1c2e88449069a80
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 16 04:44:17 2015 +0000
- byte-based C locale, phase 1: multibyte character handling functions
-
- this patch makes the functions which work directly on multibyte
- characters treat the high bytes as individual abstract code units
- rather than as multibyte sequences when MB_CUR_MAX is 1. since
- MB_CUR_MAX is presently defined as a constant 4, all of the new code
- added is dead code, and optimizing compilers' code generation should
- not be affected at all. a future commit will activate the new code.
-
- as abstract code units, bytes 0x80 to 0xff are represented by wchar_t
- values 0xdf80 to 0xdfff, at the end of the surrogates range. this
- ensures that they will never be misinterpreted as Unicode characters,
- and that all wctype functions return false for these "characters"
- without needing locale-specific logic. a high range outside of Unicode
- such as 0x7fffff80 to 0x7fffffff was also considered, but since C11's
- char16_t also needs to be able to represent conversions of these
- bytes, the surrogate range was the natural choice.
- commit 38e2f727237230300fea6aff68802db04625fd23
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 16 04:21:38 2015 +0000
- fix btowc corner case
-
- btowc is required to interpret its argument by conversion to unsigned
- char, unless the argument is equal to EOF. since the conversion to
- produces a non-character value anyway, we can just unconditionally
- convert, for now.
- commit ee59c296d56bf26f49f354d6eb32b4b6d4190188
- Author: Szabolcs Nagy <nsz@port70.net>
- Date: Wed Jun 3 10:32:14 2015 +0100
- arm: add vdso support
-
- vdso will be available on arm in linux v4.2, the user-space code
- for it is in kernel commit 8512287a8165592466cb9cb347ba94892e9c56a5
- commit e3bc22f1eff87b8f029a6ab31f1a269d69e4b053
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sun Jun 14 01:59:02 2015 +0000
- refactor malloc's expand_heap to share with __simple_malloc
-
- this extends the brk/stack collision protection added to full malloc
- in commit 276904c2f6bde3a31a24ebfa201482601d18b4f9 to also protect the
- __simple_malloc function used in static-linked programs that don't
- reference the free function.
-
- it also extends support for using mmap when brk fails, which full
- malloc got in commit 5446303328adf4b4e36d9fba21848e6feb55fab4, to
- __simple_malloc.
-
- since __simple_malloc may expand the heap by arbitrarily large
- increments, the stack collision detection is enhanced to detect
- interval overlap rather than just proximity of a single address to the
- stack. code size is increased a bit, but this is partly offset by the
- sharing of code between the two malloc implementations, which due to
- linking semantics, both get linked in a program that needs the full
- malloc with realloc/free support.
- commit 4ef9b828c1f39553a69e0635ac91f0fcadd6e8c6
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 13 20:53:02 2015 +0000
- remove cancellation points in stdio
-
- commit 58165923890865a6ac042fafce13f440ee986fd9 added these optional
- cancellation points on the basis that cancellable stdio could be
- useful, to unblock threads stuck on stdio operations that will never
- complete. however, the only way to ensure that cancellation can
- achieve this is to violate the rules for side effects when
- cancellation is acted upon, discarding knowledge of any partial data
- transfer already completed. our implementation exhibited this behavior
- and was thus non-conforming.
-
- in addition to improving correctness, removing these cancellation
- points moderately reduces code size, and should significantly improve
- performance on i386, where sysenter/syscall instructions can be used
- instead of "int $128" for non-cancellable syscalls.
- commit 536c6d5a4205e2a3f161f2983ce1e0ac3082187d
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 13 05:17:16 2015 +0000
- fix idiom for setting stdio stream orientation to wide
-
- the old idiom, f->mode |= f->mode+1, was adapted from the idiom for
- setting byte orientation, f->mode |= f->mode-1, but the adaptation was
- incorrect. unless the stream was alreasdy set byte-oriented, this code
- incremented f->mode each time it was executed, which would eventually
- lead to overflow. it could be fixed by changing it to f->mode |= 1,
- but upcoming changes will require slightly more work at the time of
- wide orientation, so it makes sense to just call fwide. as an
- optimization in the single-character functions, fwide is only called
- if the stream is not already wide-oriented.
- commit f8f565df467c13248104223f99abf7f37cef7584
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 13 04:42:38 2015 +0000
- add printing of null %s arguments as "(null)" in wide printf
-
- this is undefined, but supported in our implementation of the normal
- printf, so for consistency the wide variant should support it too.
- commit f9e25d813860d53cd1e9b6145cc63375d2fe2529
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 13 04:37:27 2015 +0000
- add %m support to wide printf
- commit ec634aad91f57479ef17525e33ed446c780a61f4
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Thu Jun 11 05:01:04 2015 +0000
- add sh asm for vfork
- commit c30cbcb0a646b1f13a22c645616dce624465b883
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Wed Jun 10 02:27:40 2015 +0000
- implement arch-generic version of __unmapself
-
- this can be used to put off writing an asm version of __unmapself for
- new archs, or as a permanent solution on archs where it's not
- practical or even possible to run momentarily with no stack.
-
- the concept here is simple: the caller takes a lock on a global shared
- stack and uses it to make the munmap and exit syscalls. the only trick
- is unlocking, which must be done after the thread exits, and this is
- achieved by using the set_tid_address syscall to have the kernel zero
- and futex-wake the lock word as part of the exit syscall.
- commit 276904c2f6bde3a31a24ebfa201482601d18b4f9
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 9 20:30:35 2015 +0000
- in malloc, refuse to use brk if it grows into stack
-
- the linux/nommu fdpic ELF loader sets up the brk range to overlap
- entirely with the main thread's stack (but growing from opposite
- ends), so that the resulting failure mode for malloc is not to return
- a null pointer but to start returning pointers to memory that overlaps
- with the caller's stack. needless to say this extremely dangerous and
- makes brk unusable.
-
- since it's non-trivial to detect execution environments that might be
- affected by this kernel bug, and since the severity of the bug makes
- any sort of detection that might yield false-negatives unsafe, we
- instead check the proximity of the brk to the stack pointer each time
- the brk is to be expanded. both the main thread's stack (where the
- real known risk lies) and the calling thread's stack are checked. an
- arbitrary gap distance of 8 MB is imposed, chosen to be larger than
- linux default main-thread stack reservation sizes and larger than any
- reasonable stack configuration on nommu.
-
- the effeciveness of this patch relies on an assumption that the amount
- by which the brk is being grown is smaller than the gap limit, which
- is always true for malloc's use of brk. reliance on this assumption is
- why the check is being done in malloc-specific code and not in __brk.
- commit bd1eaceaa3975bd2a2a34e211cff896affaecadf
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Tue Jun 9 20:09:27 2015 +0000
- fix spurious errors from pwd/grp functions when nscd backend is absent
-
- for several pwd/grp functions, the only way the caller can distinguish
- between a successful negative result ("no such user/group") and an
- internal error is by clearing errno before the call and checking errno
- afterwards. the nscd backend support code correctly simulated a
- not-found response on systems where such a backend is not running, but
- failed to restore errno.
-
- this commit also fixed an outdated/incorrect comment.
- commit 75ce4503950621b11fcc7f1fd1187dbcf3cde312
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sun Jun 7 20:55:23 2015 +0000
- fix regression in pre-v7 arm on kernels with kuser helper removed
-
- the arm atomics/TLS runtime selection code is called from
- __set_thread_area and depends on having libc.auxv and __hwcap
- available. commit 71f099cb7db821c51d8f39dfac622c61e54d794c moved the
- first call to __set_thread_area to the top of dynamic linking stage 3,
- before this data is made available, causing the runtime detection code
- to always see __hwcap as zero and thereby select the atomics/TLS
- implementations based on kuser helper.
-
- upcoming work on superh will use similar runtime detection.
-
- ideally this early-init code should be cleanly refactored and shared
- between the dynamic linker and static-linked startup.
- commit 32f3c4f70633488550c29a2444f819aafdf345ff
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sun Jun 7 03:09:16 2015 +0000
- add multiple inclusion guard to locale_impl.h
- commit 04b8360adbb6487f61aa0c00e53ec3a90a5a0d29
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sun Jun 7 02:59:49 2015 +0000
- remove redefinition of MB_CUR_MAX in locale_impl.h
-
- unless/until the byte-based C locale is implemented, defining
- MB_CUR_MAX to 1 in the C locale is wrong. no internal code currently
- uses the MB_CUR_MAX macro, but having it defined inconsistently is
- error-prone. applications get the value from stdlib.h and were
- unaffected.
- commit 16bf466532d7328e971012b0731ad493b017ad29
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 6 18:53:02 2015 +0000
- make static C and C.UTF-8 locales available outside of newlocale
- commit 312eea2ea4f4363fb01b73660c08bfcf43dd3bb4
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 6 18:20:30 2015 +0000
- remove another invalid skip of locking in ungetwc
- commit 3d7e32d28dc9962e9efc1c317c5b44b5b2df3008
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 6 18:16:22 2015 +0000
- add macro version of ctype.h isascii function
-
- presumably internal code (ungetwc and fputwc) was written assuming a
- macro implementation existed; otherwise use of isascii is just a
- pessimization.
- commit 7e816a6487932cbb3cb71d94b609e50e81f4e5bf
- Author: Rich Felker <dalias@aerifal.cx>
- Date: Sat Jun 6 18:11:17 2015 +0000
- remove invalid skip of locking in ungetwc
-
- aside from being invalid, the early check only optimized the error
- case, and likely pessimized the common case by separating the
- two branches on isascii(c) at opposite ends of the function.
- commit 63f4b9f18f3674124d8bcb119739fec85e6da005
- Author: Timo Teräs <timo.teras@iki.fi>
- Date: Fri Jun 5 10:39:42 2015 +0300
- fix uselocale((locale_t)0) not to modify locale
-
- commit 68630b55c0c7219fe9df70dc28ffbf9efc8021d8 made the new locale to
- be assigned unconditonally resulting in crashes later on.
- --- a/.gitignore
- +++ b/.gitignore
- @@ -7,5 +7,7 @@ arch/*/bits/alltypes.h
- config.mak
- include/bits
- tools/musl-gcc
- +tools/musl-clang
- +tools/ld.musl-clang
- lib/musl-gcc.specs
- src/internal/version.h
- --- a/Makefile
- +++ b/Makefile
- @@ -51,6 +51,9 @@ TOOL_LIBS = lib/musl-gcc.specs
- ALL_LIBS = $(CRT_LIBS) $(STATIC_LIBS) $(SHARED_LIBS) $(EMPTY_LIBS) $(TOOL_LIBS)
- ALL_TOOLS = tools/musl-gcc
-
- +WRAPCC_GCC = gcc
- +WRAPCC_CLANG = clang
- +
- LDSO_PATHNAME = $(syslibdir)/ld-musl-$(ARCH)$(SUBARCH).so.1
-
- -include config.mak
- @@ -155,7 +158,11 @@ lib/musl-gcc.specs: tools/musl-gcc.specs
- sh $< "$(includedir)" "$(libdir)" "$(LDSO_PATHNAME)" > $@
-
- tools/musl-gcc: config.mak
- - printf '#!/bin/sh\nexec "$${REALGCC:-gcc}" "$$@" -specs "%s/musl-gcc.specs"\n' "$(libdir)" > $@
- + printf '#!/bin/sh\nexec "$${REALGCC:-$(WRAPCC_GCC)}" "$$@" -specs "%s/musl-gcc.specs"\n' "$(libdir)" > $@
- + chmod +x $@
- +
- +tools/%-clang: tools/%-clang.in config.mak
- + sed -e 's!@CC@!$(WRAPCC_CLANG)!g' -e 's!@PREFIX@!$(prefix)!g' -e 's!@INCDIR@!$(includedir)!g' -e 's!@LIBDIR@!$(libdir)!g' -e 's!@LDSO@!$(LDSO_PATHNAME)!g' $< > $@
- chmod +x $@
-
- $(DESTDIR)$(bindir)/%: tools/%
- --- a/arch/arm/syscall_arch.h
- +++ b/arch/arm/syscall_arch.h
- @@ -72,3 +72,7 @@ static inline long __syscall6(long n, lo
- register long r5 __asm__("r5") = f;
- __asm_syscall("r"(r7), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5));
- }
- +
- +#define VDSO_USEFUL
- +#define VDSO_CGT_SYM "__vdso_clock_gettime"
- +#define VDSO_CGT_VER "LINUX_2.6"
- --- a/arch/mips/bits/signal.h
- +++ b/arch/mips/bits/signal.h
- @@ -28,7 +28,7 @@ struct sigcontext
- typedef struct
- {
- unsigned regmask, status;
- - unsigned long long pc, regs[32], fpregs[32];
- + unsigned long long pc, gregs[32], fpregs[32];
- unsigned ownedfp, fpc_csr, fpc_eir, used_math, dsp;
- unsigned long long mdhi, mdlo;
- unsigned long hi1, lo1, hi2, lo2, hi3, lo3;
- --- a/arch/mips/bits/socket.h
- +++ b/arch/mips/bits/socket.h
- @@ -22,26 +22,31 @@ struct cmsghdr
- #define SOL_SOCKET 65535
-
- #define SO_DEBUG 1
- -#define SO_REUSEADDR 4
- -#define SO_TYPE 0x1008
- -#define SO_ERROR 0x1007
- -#define SO_DONTROUTE 16
- -#define SO_BROADCAST 32
- +
- +#define SO_REUSEADDR 0x0004
- +#define SO_KEEPALIVE 0x0008
- +#define SO_DONTROUTE 0x0010
- +#define SO_BROADCAST 0x0020
- +#define SO_LINGER 0x0080
- +#define SO_OOBINLINE 0x0100
- +#define SO_REUSEPORT 0x0200
- #define SO_SNDBUF 0x1001
- #define SO_RCVBUF 0x1002
- -#define SO_KEEPALIVE 8
- -#define SO_OOBINLINE 256
- +#define SO_SNDLOWAT 0x1003
- +#define SO_RCVLOWAT 0x1004
- +#define SO_RCVTIMEO 0x1006
- +#define SO_SNDTIMEO 0x1005
- +#define SO_ERROR 0x1007
- +#define SO_TYPE 0x1008
- +#define SO_ACCEPTCONN 0x1009
- +#define SO_PROTOCOL 0x1028
- +#define SO_DOMAIN 0x1029
- +
- #define SO_NO_CHECK 11
- #define SO_PRIORITY 12
- -#define SO_LINGER 128
- #define SO_BSDCOMPAT 14
- -#define SO_REUSEPORT 512
- #define SO_PASSCRED 17
- #define SO_PEERCRED 18
- -#define SO_RCVLOWAT 0x1004
- -#define SO_SNDLOWAT 0x1003
- -#define SO_RCVTIMEO 0x1006
- -#define SO_SNDTIMEO 0x1005
- #define SO_SNDBUFFORCE 31
- #define SO_RCVBUFFORCE 33
-
- --- a/arch/mips/pthread_arch.h
- +++ b/arch/mips/pthread_arch.h
- @@ -13,4 +13,6 @@ static inline struct pthread *__pthread_
- #define TLS_ABOVE_TP
- #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
-
- +#define DTP_OFFSET 0x8000
- +
- #define CANCEL_REG_IP (3-(union {int __i; char __b;}){1}.__b)
- --- a/arch/powerpc/bits/socket.h
- +++ b/arch/powerpc/bits/socket.h
- @@ -24,8 +24,6 @@ struct cmsghdr
- #define SO_BROADCAST 6
- #define SO_SNDBUF 7
- #define SO_RCVBUF 8
- -#define SO_SNDBUFFORCE 32
- -#define SO_RCVBUFFORCE 33
- #define SO_KEEPALIVE 9
- #define SO_OOBINLINE 10
- #define SO_NO_CHECK 11
- @@ -39,4 +37,8 @@ struct cmsghdr
- #define SO_SNDTIMEO 19
- #define SO_PASSCRED 20
- #define SO_PEERCRED 21
- -
- +#define SO_ACCEPTCONN 30
- +#define SO_SNDBUFFORCE 32
- +#define SO_RCVBUFFORCE 33
- +#define SO_PROTOCOL 38
- +#define SO_DOMAIN 39
- --- a/arch/powerpc/pthread_arch.h
- +++ b/arch/powerpc/pthread_arch.h
- @@ -12,6 +12,8 @@ static inline struct pthread *__pthread_
- #define TLS_ABOVE_TP
- #define TP_ADJ(p) ((char *)(p) + sizeof(struct pthread) + 0x7000)
-
- +#define DTP_OFFSET 0x8000
- +
- // offset of the PC register in mcontext_t, divided by the system wordsize
- // the kernel calls the ip "nip", it's the first saved value after the 32
- // GPRs.
- --- /dev/null
- +++ b/arch/sh/src/__set_thread_area.c
- @@ -0,0 +1,34 @@
- +#include "pthread_impl.h"
- +#include "libc.h"
- +#include "sh_atomic.h"
- +#include <elf.h>
- +
- +/* Also perform sh-specific init */
- +
- +#define CPU_HAS_LLSC 0x0040
- +
- +__attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model, __sh_nommu;
- +
- +int __set_thread_area(void *p)
- +{
- + size_t *aux;
- + __asm__ __volatile__ ( "ldc %0, gbr" : : "r"(p) : "memory" );
- +#ifndef __SH4A__
- + if (__hwcap & CPU_HAS_LLSC) {
- + __sh_atomic_model = SH_A_LLSC;
- + return 0;
- + }
- +#if !defined(__SH3__) && !defined(__SH4__)
- + for (aux=libc.auxv; *aux; aux+=2) {
- + if (*aux != AT_PLATFORM) continue;
- + const char *s = (void *)aux[1];
- + if (s[0]!='s' || s[1]!='h' || s[2]!='2' || s[3]-'0'<10u) break;
- + __sh_atomic_model = SH_A_IMASK;
- + __sh_nommu = 1;
- + return 0;
- + }
- +#endif
- + /* __sh_atomic_model = SH_A_GUSA; */ /* 0, default */
- +#endif
- + return 0;
- +}
- --- /dev/null
- +++ b/arch/sh/src/__unmapself.c
- @@ -0,0 +1,19 @@
- +#include "pthread_impl.h"
- +
- +void __unmapself_sh_mmu(void *, size_t);
- +void __unmapself_sh_nommu(void *, size_t);
- +
- +#if !defined(__SH3__) && !defined(__SH4__)
- +#define __unmapself __unmapself_sh_nommu
- +#include "../../../src/thread/__unmapself.c"
- +#undef __unmapself
- +extern __attribute__((__visibility__("hidden"))) unsigned __sh_nommu;
- +#else
- +#define __sh_nommu 0
- +#endif
- +
- +void __unmapself(void *base, size_t size)
- +{
- + if (__sh_nommu) __unmapself_sh_nommu(base, size);
- + else __unmapself_sh_mmu(base, size);
- +}
- --- a/arch/sh/src/atomic.c
- +++ b/arch/sh/src/atomic.c
- @@ -1,8 +1,26 @@
- #ifndef __SH4A__
-
- +#include "sh_atomic.h"
- #include "atomic.h"
- #include "libc.h"
-
- +static inline unsigned mask()
- +{
- + unsigned sr;
- + __asm__ __volatile__ ( "\n"
- + " stc sr,r0 \n"
- + " mov r0,%0 \n"
- + " or #0xf0,r0 \n"
- + " ldc r0,sr \n"
- + : "=&r"(sr) : : "memory", "r0" );
- + return sr;
- +}
- +
- +static inline void unmask(unsigned sr)
- +{
- + __asm__ __volatile__ ( "ldc %0,sr" : : "r"(sr) : "memory" );
- +}
- +
- /* gusa is a hack in the kernel which lets you create a sequence of instructions
- * which will be restarted if the process is preempted in the middle of the
- * sequence. It will do for implementing atomics on non-smp systems. ABI is:
- @@ -25,11 +43,17 @@
- " mov.l " new ", @" mem "\n" \
- "1: mov r1, r15\n"
-
- -#define CPU_HAS_LLSC 0x0040
- -
- int __sh_cas(volatile int *p, int t, int s)
- {
- - if (__hwcap & CPU_HAS_LLSC) return __sh_cas_llsc(p, t, s);
- + if (__sh_atomic_model == SH_A_LLSC) return __sh_cas_llsc(p, t, s);
- +
- + if (__sh_atomic_model == SH_A_IMASK) {
- + unsigned sr = mask();
- + int old = *p;
- + if (old==t) *p = s;
- + unmask(sr);
- + return old;
- + }
-
- int old;
- __asm__ __volatile__(
- @@ -43,7 +67,15 @@ int __sh_cas(volatile int *p, int t, int
-
- int __sh_swap(volatile int *x, int v)
- {
- - if (__hwcap & CPU_HAS_LLSC) return __sh_swap_llsc(x, v);
- + if (__sh_atomic_model == SH_A_LLSC) return __sh_swap_llsc(x, v);
- +
- + if (__sh_atomic_model == SH_A_IMASK) {
- + unsigned sr = mask();
- + int old = *x;
- + *x = v;
- + unmask(sr);
- + return old;
- + }
-
- int old;
- __asm__ __volatile__(
- @@ -55,7 +87,15 @@ int __sh_swap(volatile int *x, int v)
-
- int __sh_fetch_add(volatile int *x, int v)
- {
- - if (__hwcap & CPU_HAS_LLSC) return __sh_fetch_add_llsc(x, v);
- + if (__sh_atomic_model == SH_A_LLSC) return __sh_fetch_add_llsc(x, v);
- +
- + if (__sh_atomic_model == SH_A_IMASK) {
- + unsigned sr = mask();
- + int old = *x;
- + *x = old + v;
- + unmask(sr);
- + return old;
- + }
-
- int old, dummy;
- __asm__ __volatile__(
- @@ -69,7 +109,7 @@ int __sh_fetch_add(volatile int *x, int
-
- void __sh_store(volatile int *p, int x)
- {
- - if (__hwcap & CPU_HAS_LLSC) return __sh_store_llsc(p, x);
- + if (__sh_atomic_model == SH_A_LLSC) return __sh_store_llsc(p, x);
- __asm__ __volatile__(
- " mov.l %1, @%0\n"
- : : "r"(p), "r"(x) : "memory");
- @@ -77,7 +117,15 @@ void __sh_store(volatile int *p, int x)
-
- void __sh_and(volatile int *x, int v)
- {
- - if (__hwcap & CPU_HAS_LLSC) return __sh_and_llsc(x, v);
- + if (__sh_atomic_model == SH_A_LLSC) return __sh_and_llsc(x, v);
- +
- + if (__sh_atomic_model == SH_A_IMASK) {
- + unsigned sr = mask();
- + int old = *x;
- + *x = old & v;
- + unmask(sr);
- + return;
- + }
-
- int dummy;
- __asm__ __volatile__(
- @@ -89,7 +137,15 @@ void __sh_and(volatile int *x, int v)
-
- void __sh_or(volatile int *x, int v)
- {
- - if (__hwcap & CPU_HAS_LLSC) return __sh_or_llsc(x, v);
- + if (__sh_atomic_model == SH_A_LLSC) return __sh_or_llsc(x, v);
- +
- + if (__sh_atomic_model == SH_A_IMASK) {
- + unsigned sr = mask();
- + int old = *x;
- + *x = old | v;
- + unmask(sr);
- + return;
- + }
-
- int dummy;
- __asm__ __volatile__(
- --- /dev/null
- +++ b/arch/sh/src/sh_atomic.h
- @@ -0,0 +1,15 @@
- +#ifndef _SH_ATOMIC_H
- +#define _SH_ATOMIC_H
- +
- +#define SH_A_GUSA 0
- +#define SH_A_LLSC 1
- +#define SH_A_CAS 2
- +#if !defined(__SH3__) && !defined(__SH4__)
- +#define SH_A_IMASK 3
- +#else
- +#define SH_A_IMASK -1LL /* unmatchable by unsigned int */
- +#endif
- +
- +extern __attribute__((__visibility__("hidden"))) unsigned __sh_atomic_model;
- +
- +#endif
- --- a/arch/sh/syscall_arch.h
- +++ b/arch/sh/syscall_arch.h
- @@ -8,7 +8,7 @@
- */
- #define __asm_syscall(trapno, ...) do { \
- __asm__ __volatile__ ( \
- - "trapa #" #trapno "\n" \
- + "trapa #31\n" \
- "or r0, r0\n" \
- "or r0, r0\n" \
- "or r0, r0\n" \
- --- a/configure
- +++ b/configure
- @@ -28,7 +28,7 @@ Optional features:
- --enable-debug build with debugging information [disabled]
- --enable-warnings build with recommended warnings flags [disabled]
- --enable-visibility use global visibility options to optimize PIC [auto]
- - --enable-gcc-wrapper build musl-gcc toolchain wrapper [auto]
- + --enable-wrapper=... build given musl toolchain wrapper [auto]
- --disable-shared inhibit building shared library [enabled]
- --disable-static inhibit building static library [enabled]
-
- @@ -123,6 +123,8 @@ bindir='$(exec_prefix)/bin'
- libdir='$(prefix)/lib'
- includedir='$(prefix)/include'
- syslibdir='/lib'
- +tools=
- +tool_libs=
- target=
- optimize=auto
- debug=no
- @@ -131,6 +133,8 @@ visibility=auto
- shared=auto
- static=yes
- wrapper=auto
- +gcc_wrapper=no
- +clang_wrapper=no
-
- for arg ; do
- case "$arg" in
- @@ -154,7 +158,12 @@ case "$arg" in
- --disable-warnings|--enable-warnings=no) warnings=no ;;
- --enable-visibility|--enable-visibility=yes) visibility=yes ;;
- --disable-visibility|--enable-visibility=no) visibility=no ;;
- ---enable-gcc-wrapper|--enable-gcc-wrapper=yes) wrapper=yes ;;
- +--enable-wrapper|--enable-wrapper=yes) wrapper=detect ;;
- +--enable-wrapper=all) wrapper=yes ; gcc_wrapper=yes ; clang_wrapper=yes ;;
- +--enable-wrapper=gcc) wrapper=yes ; gcc_wrapper=yes ;;
- +--enable-wrapper=clang) wrapper=yes ; clang_wrapper=yes ;;
- +--disable-wrapper|--enable-wrapper=no) wrapper=no ;;
- +--enable-gcc-wrapper|--enable-gcc-wrapper=yes) wrapper=yes ; gcc_wrapper=yes ;;
- --disable-gcc-wrapper|--enable-gcc-wrapper=no) wrapper=no ;;
- --enable-*|--disable-*|--with-*|--without-*|--*dir=*|--build=*) ;;
- --host=*|--target=*) target=${arg#*=} ;;
- @@ -215,36 +224,51 @@ tryldflag LDFLAGS_TRY -Werror=unknown-wa
- tryldflag LDFLAGS_TRY -Werror=unused-command-line-argument
-
- #
- -# Need to know if the compiler is gcc to decide whether to build the
- -# musl-gcc wrapper, and for critical bug detection in some gcc versions.
- +# Need to know if the compiler is gcc or clang to decide which toolchain
- +# wrappers to build.
- #
- -printf "checking whether compiler is gcc... "
- -if fnmatch '*gcc\ version*' "$(LC_ALL=C $CC -v 2>&1)" ; then
- -cc_is_gcc=yes
- +printf "checking for C compiler family... "
- +cc_ver="$(LC_ALL=C $CC -v 2>&1)"
- +cc_family=unknown
- +if fnmatch '*gcc\ version*' "$cc_ver" ; then
- +cc_family=gcc
- +elif fnmatch '*clang\ version*' "$cc_ver" ; then
- +cc_family=clang
- +fi
- +echo "$cc_family"
- +
- +#
- +# Figure out toolchain wrapper to build
- +#
- +if test "$wrapper" = auto -o "$wrapper" = detect ; then
- +echo "#include <stdlib.h>" > "$tmpc"
- +echo "#if ! __GLIBC__" >> "$tmpc"
- +echo "#error no" >> "$tmpc"
- +echo "#endif" >> "$tmpc"
- +printf "checking for toolchain wrapper to build... "
- +if test "$wrapper" = auto && ! $CC -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
- +echo "none"
- +elif test "$cc_family" = gcc ; then
- +gcc_wrapper=yes
- +echo "gcc"
- +elif test "$cc_family" = clang ; then
- +clang_wrapper=yes
- +echo "clang"
- else
- -cc_is_gcc=no
- +echo "none"
- +if test "$wrapper" = detect ; then
- +fail "$0: could not find an appropriate toolchain wrapper"
- fi
- -echo "$cc_is_gcc"
- -
- -#
- -# Only build musl-gcc wrapper if toolchain does not already target musl
- -#
- -if test "$wrapper" = auto ; then
- -printf "checking whether to build musl-gcc wrapper... "
- -if test "$cc_is_gcc" = yes ; then
- -wrapper=yes
- -while read line ; do
- -case "$line" in */ld-musl-*) wrapper=no ;; esac
- -done <<EOF
- -$($CC -dumpspecs)
- -EOF
- -else
- -wrapper=no
- fi
- -echo "$wrapper"
- fi
-
- -
- +if test "$gcc_wrapper" = yes ; then
- +tools="$tools tools/musl-gcc"
- +tool_libs="$tool_libs lib/musl-gcc.specs"
- +fi
- +if test "$clang_wrapper" = yes ; then
- +tools="$tools tools/musl-clang tools/ld.musl-clang"
- +fi
-
- #
- # Find the target architecture
- @@ -580,11 +604,13 @@ LDFLAGS = $LDFLAGS_AUTO $LDFLAGS
- CROSS_COMPILE = $CROSS_COMPILE
- LIBCC = $LIBCC
- OPTIMIZE_GLOBS = $OPTIMIZE_GLOBS
- +ALL_TOOLS = $tools
- +TOOL_LIBS = $tool_libs
- EOF
- test "x$static" = xno && echo "STATIC_LIBS ="
- test "x$shared" = xno && echo "SHARED_LIBS ="
- -test "x$wrapper" = xno && echo "ALL_TOOLS ="
- -test "x$wrapper" = xno && echo "TOOL_LIBS ="
- +test "x$cc_family" = xgcc && echo 'WRAPCC_GCC = $(CC)'
- +test "x$cc_family" = xclang && echo 'WRAPCC_CLANG = $(CC)'
- exec 1>&3 3>&-
-
- printf "done\n"
- --- a/include/ctype.h
- +++ b/include/ctype.h
- @@ -64,6 +64,7 @@ int isascii(int);
- int toascii(int);
- #define _tolower(a) ((a)|0x20)
- #define _toupper(a) ((a)&0x5f)
- +#define isascii(a) (0 ? isascii(a) : (unsigned)(a) < 128)
-
- #endif
-
- --- a/include/stdlib.h
- +++ b/include/stdlib.h
- @@ -76,7 +76,8 @@ size_t wcstombs (char *__restrict, const
- #define EXIT_FAILURE 1
- #define EXIT_SUCCESS 0
-
- -#define MB_CUR_MAX ((size_t)+4)
- +size_t __ctype_get_mb_cur_max(void);
- +#define MB_CUR_MAX (__ctype_get_mb_cur_max())
-
- #define RAND_MAX (0x7fffffff)
-
- --- a/include/sys/socket.h
- +++ b/include/sys/socket.h
- @@ -177,8 +177,11 @@ struct linger
- #define SO_SNDLOWAT 19
- #define SO_RCVTIMEO 20
- #define SO_SNDTIMEO 21
- +#define SO_ACCEPTCONN 30
- #define SO_SNDBUFFORCE 32
- #define SO_RCVBUFFORCE 33
- +#define SO_PROTOCOL 38
- +#define SO_DOMAIN 39
- #endif
-
- #define SO_SECURITY_AUTHENTICATION 22
- @@ -195,7 +198,6 @@ struct linger
- #define SO_TIMESTAMP 29
- #define SCM_TIMESTAMP SO_TIMESTAMP
-
- -#define SO_ACCEPTCONN 30
- #define SO_PEERSEC 31
- #define SO_PASSSEC 34
- #define SO_TIMESTAMPNS 35
- @@ -203,8 +205,6 @@ struct linger
- #define SO_MARK 36
- #define SO_TIMESTAMPING 37
- #define SCM_TIMESTAMPING SO_TIMESTAMPING
- -#define SO_PROTOCOL 38
- -#define SO_DOMAIN 39
- #define SO_RXQ_OVFL 40
- #define SO_WIFI_STATUS 41
- #define SCM_WIFI_STATUS SO_WIFI_STATUS
- --- a/include/unistd.h
- +++ b/include/unistd.h
- @@ -185,7 +185,7 @@ int setresgid(gid_t, gid_t, gid_t);
- int getresuid(uid_t *, uid_t *, uid_t *);
- int getresgid(gid_t *, gid_t *, gid_t *);
- char *get_current_dir_name(void);
- -void syncfs(int);
- +int syncfs(int);
- int euidaccess(const char *, int);
- int eaccess(const char *, int);
- #endif
- --- a/src/ctype/__ctype_get_mb_cur_max.c
- +++ b/src/ctype/__ctype_get_mb_cur_max.c
- @@ -1,6 +1,7 @@
- -#include <stddef.h>
- +#include <stdlib.h>
- +#include "locale_impl.h"
-
- size_t __ctype_get_mb_cur_max()
- {
- - return 4;
- + return MB_CUR_MAX;
- }
- --- a/src/ctype/isascii.c
- +++ b/src/ctype/isascii.c
- @@ -1,4 +1,5 @@
- #include <ctype.h>
- +#undef isascii
-
- int isascii(int c)
- {
- --- a/src/env/__stack_chk_fail.c
- +++ b/src/env/__stack_chk_fail.c
- @@ -25,4 +25,8 @@ void __stack_chk_fail_local(void)
- a_crash();
- }
-
- +#else
- +
- +weak_alias(__stack_chk_fail, __stack_chk_fail_local);
- +
- #endif
- --- a/src/internal/libc.h
- +++ b/src/internal/libc.h
- @@ -17,8 +17,6 @@ struct __libc {
- int secure;
- volatile int threads_minus_1;
- size_t *auxv;
- - FILE *ofl_head;
- - volatile int ofl_lock[2];
- size_t tls_size;
- size_t page_size;
- struct __locale_struct global_locale;
- --- a/src/internal/locale_impl.h
- +++ b/src/internal/locale_impl.h
- @@ -1,3 +1,6 @@
- +#ifndef _LOCALE_IMPL_H
- +#define _LOCALE_IMPL_H
- +
- #include <locale.h>
- #include <stdlib.h>
- #include "libc.h"
- @@ -12,6 +15,10 @@ struct __locale_map {
- const struct __locale_map *next;
- };
-
- +extern const struct __locale_map __c_dot_utf8;
- +extern const struct __locale_struct __c_locale;
- +extern const struct __locale_struct __c_dot_utf8_locale;
- +
- const struct __locale_map *__get_locale(int, const char *);
- const char *__mo_lookup(const void *, size_t, const char *);
- const char *__lctrans(const char *, const struct __locale_map *);
- @@ -20,9 +27,14 @@ const char *__lctrans_cur(const char *);
- #define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])
- #define LCTRANS_CUR(msg) __lctrans_cur(msg)
-
- +#define C_LOCALE ((locale_t)&__c_locale)
- +#define UTF8_LOCALE ((locale_t)&__c_dot_utf8_locale)
- +
- #define CURRENT_LOCALE (__pthread_self()->locale)
-
- #define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
-
- #undef MB_CUR_MAX
- #define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
- +
- +#endif
- --- a/src/internal/pthread_impl.h
- +++ b/src/internal/pthread_impl.h
- @@ -94,6 +94,10 @@ struct __timer {
- #define CANARY canary
- #endif
-
- +#ifndef DTP_OFFSET
- +#define DTP_OFFSET 0
- +#endif
- +
- #define SIGTIMER 32
- #define SIGCANCEL 33
- #define SIGSYNCCALL 34
- --- a/src/internal/sh/syscall.s
- +++ b/src/internal/sh/syscall.s
- @@ -13,7 +13,7 @@ __syscall:
- mov.l @r15, r7
- mov.l @(4,r15), r0
- mov.l @(8,r15), r1
- - trapa #22
- + trapa #31
- or r0, r0
- or r0, r0
- or r0, r0
- --- a/src/internal/stdio_impl.h
- +++ b/src/internal/stdio_impl.h
- @@ -47,6 +47,7 @@ struct _IO_FILE {
- unsigned char *shend;
- off_t shlim, shcnt;
- FILE *prev_locked, *next_locked;
- + struct __locale_struct *locale;
- };
-
- size_t __stdio_read(FILE *, unsigned char *, size_t);
- @@ -75,8 +76,9 @@ int __putc_unlocked(int, FILE *);
- FILE *__fdopen(int, const char *);
- int __fmodeflags(const char *);
-
- -#define OFLLOCK() LOCK(libc.ofl_lock)
- -#define OFLUNLOCK() UNLOCK(libc.ofl_lock)
- +FILE *__ofl_add(FILE *f);
- +FILE **__ofl_lock(void);
- +void __ofl_unlock(void);
-
- #define feof(f) ((f)->flags & F_EOF)
- #define ferror(f) ((f)->flags & F_ERR)
- --- a/src/ldso/dynlink.c
- +++ b/src/ldso/dynlink.c
- @@ -156,7 +156,7 @@ static uint32_t gnu_hash(const char *s0)
- const unsigned char *s = (void *)s0;
- uint_fast32_t h = 5381;
- for (; *s; s++)
- - h = h*33 + *s;
- + h += h*32 + *s;
- return h;
- }
-
- @@ -174,32 +174,39 @@ static Sym *sysv_lookup(const char *s, u
- return 0;
- }
-
- -static Sym *gnu_lookup(const char *s, uint32_t h1, struct dso *dso)
- +static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s)
- {
- - Sym *syms = dso->syms;
- - char *strings = dso->strings;
- - uint32_t *hashtab = dso->ghashtab;
- uint32_t nbuckets = hashtab[0];
- uint32_t *buckets = hashtab + 4 + hashtab[2]*(sizeof(size_t)/4);
- - uint32_t h2;
- - uint32_t *hashval;
- uint32_t i = buckets[h1 % nbuckets];
-
- if (!i) return 0;
-
- - hashval = buckets + nbuckets + (i - hashtab[1]);
- + uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]);
-
- for (h1 |= 1; ; i++) {
- - h2 = *hashval++;
- - if ((!dso->versym || dso->versym[i] >= 0)
- - && (h1 == (h2|1)) && !strcmp(s, strings + syms[i].st_name))
- - return syms+i;
- + uint32_t h2 = *hashval++;
- + if ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0)
- + && !strcmp(s, dso->strings + dso->syms[i].st_name))
- + return dso->syms+i;
- if (h2 & 1) break;
- }
-
- return 0;
- }
-
- +static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, const char *s, uint32_t fofs, size_t fmask)
- +{
- + const size_t *bloomwords = (const void *)(hashtab+4);
- + size_t f = bloomwords[fofs & (hashtab[2]-1)];
- + if (!(f & fmask)) return 0;
- +
- + f >>= (h1 >> hashtab[3]) % (8 * sizeof f);
- + if (!(f & 1)) return 0;
- +
- + return gnu_lookup(h1, hashtab, dso, s);
- +}
- +
- #define OK_TYPES (1<<STT_NOTYPE | 1<<STT_OBJECT | 1<<STT_FUNC | 1<<STT_COMMON | 1<<STT_TLS)
- #define OK_BINDS (1<<STB_GLOBAL | 1<<STB_WEAK | 1<<STB_GNU_UNIQUE)
-
- @@ -209,14 +216,20 @@ static Sym *gnu_lookup(const char *s, ui
-
- static struct symdef find_sym(struct dso *dso, const char *s, int need_def)
- {
- - uint32_t h = 0, gh = 0;
- + uint32_t h = 0, gh, gho, *ght;
- + size_t ghm = 0;
- struct symdef def = {0};
- for (; dso; dso=dso->next) {
- Sym *sym;
- if (!dso->global) continue;
- - if (dso->ghashtab) {
- - if (!gh) gh = gnu_hash(s);
- - sym = gnu_lookup(s, gh, dso);
- + if ((ght = dso->ghashtab)) {
- + if (!ghm) {
- + gh = gnu_hash(s);
- + int maskbits = 8 * sizeof ghm;
- + gho = gh / maskbits;
- + ghm = 1ul << gh % maskbits;
- + }
- + sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm);
- } else {
- if (!h) h = sysv_hash(s);
- sym = sysv_lookup(s, h, dso);
- @@ -337,7 +350,7 @@ static void do_relocs(struct dso *dso, s
- *reloc_addr = def.dso->tls_id;
- break;
- case REL_DTPOFF:
- - *reloc_addr = tls_val + addend;
- + *reloc_addr = tls_val + addend - DTP_OFFSET;
- break;
- #ifdef TLS_ABOVE_TP
- case REL_TPOFF:
- @@ -423,6 +436,28 @@ static void reclaim_gaps(struct dso *dso
- }
- }
-
- +static void *mmap_fixed(void *p, size_t n, int prot, int flags, int fd, off_t off)
- +{
- + char *q = mmap(p, n, prot, flags, fd, off);
- + if (q != MAP_FAILED || errno != EINVAL) return q;
- + /* Fallbacks for MAP_FIXED failure on NOMMU kernels. */
- + if (flags & MAP_ANONYMOUS) {
- + memset(p, 0, n);
- + return p;
- + }
- + ssize_t r;
- + if (lseek(fd, off, SEEK_SET) < 0) return MAP_FAILED;
- + for (q=p; n; q+=r, off+=r, n-=r) {
- + r = read(fd, q, n);
- + if (r < 0 && errno != EINTR) return MAP_FAILED;
- + if (!r) {
- + memset(q, 0, n);
- + break;
- + }
- + }
- + return p;
- +}
- +
- static void *map_library(int fd, struct dso *dso)
- {
- Ehdr buf[(896+sizeof(Ehdr))/sizeof(Ehdr)];
- @@ -524,19 +559,20 @@ static void *map_library(int fd, struct
- prot = (((ph->p_flags&PF_R) ? PROT_READ : 0) |
- ((ph->p_flags&PF_W) ? PROT_WRITE: 0) |
- ((ph->p_flags&PF_X) ? PROT_EXEC : 0));
- - if (mmap(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
- + if (mmap_fixed(base+this_min, this_max-this_min, prot, MAP_PRIVATE|MAP_FIXED, fd, off_start) == MAP_FAILED)
- goto error;
- if (ph->p_memsz > ph->p_filesz) {
- size_t brk = (size_t)base+ph->p_vaddr+ph->p_filesz;
- size_t pgbrk = brk+PAGE_SIZE-1 & -PAGE_SIZE;
- memset((void *)brk, 0, pgbrk-brk & PAGE_SIZE-1);
- - if (pgbrk-(size_t)base < this_max && mmap((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
- + if (pgbrk-(size_t)base < this_max && mmap_fixed((void *)pgbrk, (size_t)base+this_max-pgbrk, prot, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) == MAP_FAILED)
- goto error;
- }
- }
- for (i=0; ((size_t *)(base+dyn))[i]; i+=2)
- if (((size_t *)(base+dyn))[i]==DT_TEXTREL) {
- - if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC) < 0)
- + if (mprotect(map, map_len, PROT_READ|PROT_WRITE|PROT_EXEC)
- + && errno != ENOSYS)
- goto error;
- break;
- }
- @@ -927,7 +963,8 @@ static void reloc_all(struct dso *p)
- do_relocs(p, (void *)(p->base+dyn[DT_RELA]), dyn[DT_RELASZ], 3);
-
- if (head != &ldso && p->relro_start != p->relro_end &&
- - mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ) < 0) {
- + mprotect(p->base+p->relro_start, p->relro_end-p->relro_start, PROT_READ)
- + && errno != ENOSYS) {
- error("Error relocating %s: RELRO protection failed: %m",
- p->name);
- if (runtime) longjmp(*rtld_fail, 1);
- @@ -1078,7 +1115,7 @@ void *__tls_get_new(size_t *v)
- __block_all_sigs(&set);
- if (v[0]<=(size_t)self->dtv[0]) {
- __restore_sigs(&set);
- - return (char *)self->dtv[v[0]]+v[1];
- + return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
- }
-
- /* This is safe without any locks held because, if the caller
- @@ -1111,7 +1148,7 @@ void *__tls_get_new(size_t *v)
- if (p->tls_id == v[0]) break;
- }
- __restore_sigs(&set);
- - return mem + v[1];
- + return mem + v[1] + DTP_OFFSET;
- }
-
- static void update_tls_size()
- @@ -1192,6 +1229,17 @@ _Noreturn void __dls3(size_t *sp)
- char **argv_orig = argv;
- char **envp = argv+argc+1;
-
- + /* Find aux vector just past environ[] and use it to initialize
- + * global data that may be needed before we can make syscalls. */
- + __environ = envp;
- + for (i=argc+1; argv[i]; i++);
- + libc.auxv = auxv = (void *)(argv+i+1);
- + decode_vec(auxv, aux, AUX_CNT);
- + __hwcap = aux[AT_HWCAP];
- + libc.page_size = aux[AT_PAGESZ];
- + libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
- + || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]);
- +
- /* Setup early thread pointer in builtin_tls for ldso/libc itself to
- * use during dynamic linking. If possible it will also serve as the
- * thread pointer at runtime. */
- @@ -1200,25 +1248,11 @@ _Noreturn void __dls3(size_t *sp)
- a_crash();
- }
-
- - /* Find aux vector just past environ[] */
- - for (i=argc+1; argv[i]; i++)
- - if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16))
- - env_path = argv[i]+16;
- - else if (!memcmp(argv[i], "LD_PRELOAD=", 11))
- - env_preload = argv[i]+11;
- - auxv = (void *)(argv+i+1);
- -
- - decode_vec(auxv, aux, AUX_CNT);
- -
- /* Only trust user/env if kernel says we're not suid/sgid */
- - if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID]
- - || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]) {
- - env_path = 0;
- - env_preload = 0;
- - libc.secure = 1;
- + if (!libc.secure) {
- + env_path = getenv("LD_LIBRARY_PATH");
- + env_preload = getenv("LD_PRELOAD");
- }
- - libc.page_size = aux[AT_PAGESZ];
- - libc.auxv = auxv;
-
- /* If the main program was already loaded by the kernel,
- * AT_PHDR will point to some location other than the dynamic
- @@ -1523,7 +1557,7 @@ void *__tls_get_addr(size_t *);
- static void *do_dlsym(struct dso *p, const char *s, void *ra)
- {
- size_t i;
- - uint32_t h = 0, gh = 0;
- + uint32_t h = 0, gh = 0, *ght;
- Sym *sym;
- if (p == head || p == RTLD_DEFAULT || p == RTLD_NEXT) {
- if (p == RTLD_DEFAULT) {
- @@ -1541,9 +1575,9 @@ static void *do_dlsym(struct dso *p, con
- }
- if (invalid_dso_handle(p))
- return 0;
- - if (p->ghashtab) {
- + if ((ght = p->ghashtab)) {
- gh = gnu_hash(s);
- - sym = gnu_lookup(s, gh, p);
- + sym = gnu_lookup(gh, ght, p, s);
- } else {
- h = sysv_hash(s);
- sym = sysv_lookup(s, h, p);
- @@ -1553,9 +1587,9 @@ static void *do_dlsym(struct dso *p, con
- if (sym && sym->st_value && (1<<(sym->st_info&0xf) & OK_TYPES))
- return p->base + sym->st_value;
- if (p->deps) for (i=0; p->deps[i]; i++) {
- - if (p->deps[i]->ghashtab) {
- + if ((ght = p->deps[i]->ghashtab)) {
- if (!gh) gh = gnu_hash(s);
- - sym = gnu_lookup(s, gh, p->deps[i]);
- + sym = gnu_lookup(gh, ght, p->deps[i], s);
- } else {
- if (!h) h = sysv_hash(s);
- sym = sysv_lookup(s, h, p->deps[i]);
- --- a/src/linux/syncfs.c
- +++ b/src/linux/syncfs.c
- @@ -2,7 +2,7 @@
- #include <unistd.h>
- #include "syscall.h"
-
- -void syncfs(int fd)
- +int syncfs(int fd)
- {
- - __syscall(SYS_syncfs, fd);
- + return syscall(SYS_syncfs, fd);
- }
- --- /dev/null
- +++ b/src/locale/c_locale.c
- @@ -0,0 +1,15 @@
- +#include "locale_impl.h"
- +#include <stdint.h>
- +
- +static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
- +
- +const struct __locale_map __c_dot_utf8 = {
- + .map = empty_mo,
- + .map_size = sizeof empty_mo,
- + .name = "C.UTF-8"
- +};
- +
- +const struct __locale_struct __c_locale = { 0 };
- +const struct __locale_struct __c_dot_utf8_locale = {
- + .cat[LC_CTYPE] = &__c_dot_utf8
- +};
- --- a/src/locale/iconv.c
- +++ b/src/locale/iconv.c
- @@ -5,6 +5,7 @@
- #include <stdlib.h>
- #include <limits.h>
- #include <stdint.h>
- +#include "locale_impl.h"
-
- #define UTF_32BE 0300
- #define UTF_16LE 0301
- @@ -165,9 +166,12 @@ size_t iconv(iconv_t cd0, char **restric
- int err;
- unsigned char type = map[-1];
- unsigned char totype = tomap[-1];
- + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
-
- if (!in || !*in || !*inb) return 0;
-
- + *ploc = UTF8_LOCALE;
- +
- for (; *inb; *in+=l, *inb-=l) {
- c = *(unsigned char *)*in;
- l = 1;
- @@ -431,6 +435,7 @@ size_t iconv(iconv_t cd0, char **restric
- break;
- }
- }
- + *ploc = loc;
- return x;
- ilseq:
- err = EILSEQ;
- @@ -445,5 +450,6 @@ starved:
- x = -1;
- end:
- errno = err;
- + *ploc = loc;
- return x;
- }
- --- a/src/locale/langinfo.c
- +++ b/src/locale/langinfo.c
- @@ -33,7 +33,8 @@ char *__nl_langinfo_l(nl_item item, loca
- int idx = item & 65535;
- const char *str;
-
- - if (item == CODESET) return "UTF-8";
- + if (item == CODESET)
- + return MB_CUR_MAX==1 ? "UTF-8-CODE-UNITS" : "UTF-8";
-
- switch (cat) {
- case LC_NUMERIC:
- --- a/src/locale/locale_map.c
- +++ b/src/locale/locale_map.c
- @@ -24,14 +24,6 @@ static const char envvars[][12] = {
- "LC_MESSAGES",
- };
-
- -static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
- -
- -const struct __locale_map __c_dot_utf8 = {
- - .map = empty_mo,
- - .map_size = sizeof empty_mo,
- - .name = "C.UTF-8"
- -};
- -
- const struct __locale_map *__get_locale(int cat, const char *val)
- {
- static int lock[2];
- @@ -107,8 +99,8 @@ const struct __locale_map *__get_locale(
- * sake of being able to do message translations at the
- * application level. */
- if (!new && (new = malloc(sizeof *new))) {
- - new->map = empty_mo;
- - new->map_size = sizeof empty_mo;
- + new->map = __c_dot_utf8.map;
- + new->map_size = __c_dot_utf8.map_size;
- memcpy(new->name, val, n);
- new->name[n] = 0;
- new->next = loc_head;
- --- a/src/locale/newlocale.c
- +++ b/src/locale/newlocale.c
- @@ -3,16 +3,9 @@
- #include "locale_impl.h"
- #include "libc.h"
-
- -extern const struct __locale_map __c_dot_utf8;
- -
- -static const struct __locale_struct c_locale = { 0 };
- -static const struct __locale_struct c_dot_utf8_locale = {
- - .cat[LC_CTYPE] = &__c_dot_utf8
- -};
- -
- int __loc_is_allocated(locale_t loc)
- {
- - return loc && loc != &c_locale && loc != &c_dot_utf8_locale;
- + return loc && loc != C_LOCALE && loc != UTF8_LOCALE;
- }
-
- locale_t __newlocale(int mask, const char *name, locale_t loc)
- @@ -44,9 +37,9 @@ locale_t __newlocale(int mask, const cha
- }
-
- if (!j)
- - return (locale_t)&c_locale;
- - if (j==1 && tmp.cat[LC_CTYPE]==c_dot_utf8_locale.cat[LC_CTYPE])
- - return (locale_t)&c_dot_utf8_locale;
- + return C_LOCALE;
- + if (j==1 && tmp.cat[LC_CTYPE]==&__c_dot_utf8)
- + return UTF8_LOCALE;
-
- if ((loc = malloc(sizeof *loc))) *loc = tmp;
-
- --- a/src/locale/uselocale.c
- +++ b/src/locale/uselocale.c
- @@ -8,9 +8,7 @@ locale_t __uselocale(locale_t new)
- locale_t old = self->locale;
- locale_t global = &libc.global_locale;
-
- - if (new == LC_GLOBAL_LOCALE) new = global;
- -
- - self->locale = new;
- + if (new) self->locale = new == LC_GLOBAL_LOCALE ? global : new;
-
- return old == global ? LC_GLOBAL_LOCALE : old;
- }
- --- a/src/malloc/calloc.c
- +++ b/src/malloc/calloc.c
- @@ -1,22 +1,13 @@
- #include <stdlib.h>
- #include <errno.h>
-
- +void *__malloc0(size_t);
- +
- void *calloc(size_t m, size_t n)
- {
- - void *p;
- - size_t *z;
- if (n && m > (size_t)-1/n) {
- errno = ENOMEM;
- return 0;
- }
- - n *= m;
- - p = malloc(n);
- - if (!p) return 0;
- - /* Only do this for non-mmapped chunks */
- - if (((size_t *)p)[-1] & 7) {
- - /* Only write words that are not already zero */
- - m = (n + sizeof *z - 1)/sizeof *z;
- - for (z=p; m; m--, z++) if (*z) *z=0;
- - }
- - return p;
- + return __malloc0(n * m);
- }
- --- /dev/null
- +++ b/src/malloc/expand_heap.c
- @@ -0,0 +1,72 @@
- +#include <limits.h>
- +#include <stdint.h>
- +#include <errno.h>
- +#include <sys/mman.h>
- +#include "libc.h"
- +#include "syscall.h"
- +
- +/* This function returns true if the interval [old,new]
- + * intersects the 'len'-sized interval below &libc.auxv
- + * (interpreted as the main-thread stack) or below &b
- + * (the current stack). It is used to defend against
- + * buggy brk implementations that can cross the stack. */
- +
- +static int traverses_stack_p(uintptr_t old, uintptr_t new)
- +{
- + const uintptr_t len = 8<<20;
- + uintptr_t a, b;
- +
- + b = (uintptr_t)libc.auxv;
- + a = b > len ? b-len : 0;
- + if (new>a && old<b) return 1;
- +
- + b = (uintptr_t)&b;
- + a = b > len ? b-len : 0;
- + if (new>a && old<b) return 1;
- +
- + return 0;
- +}
- +
- +void *__mmap(void *, size_t, int, int, int, off_t);
- +
- +/* Expand the heap in-place if brk can be used, or otherwise via mmap,
- + * using an exponential lower bound on growth by mmap to make
- + * fragmentation asymptotically irrelevant. The size argument is both
- + * an input and an output, since the caller needs to know the size
- + * allocated, which will be larger than requested due to page alignment
- + * and mmap minimum size rules. The caller is responsible for locking
- + * to prevent concurrent calls. */
- +
- +void *__expand_heap(size_t *pn)
- +{
- + static uintptr_t brk;
- + static unsigned mmap_step;
- + size_t n = *pn;
- +
- + if (n > SIZE_MAX/2 - PAGE_SIZE) {
- + errno = ENOMEM;
- + return 0;
- + }
- + n += -n & PAGE_SIZE-1;
- +
- + if (!brk) {
- + brk = __syscall(SYS_brk, 0);
- + brk += -brk & PAGE_SIZE-1;
- + }
- +
- + if (n < SIZE_MAX-brk && !traverses_stack_p(brk, brk+n)
- + && __syscall(SYS_brk, brk+n)==brk+n) {
- + *pn = n;
- + brk += n;
- + return (void *)(brk-n);
- + }
- +
- + size_t min = (size_t)PAGE_SIZE << mmap_step/2;
- + if (n < min) n = min;
- + void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
- + MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- + if (area == MAP_FAILED) return 0;
- + *pn = n;
- + mmap_step++;
- + return area;
- +}
- --- a/src/malloc/lite_malloc.c
- +++ b/src/malloc/lite_malloc.c
- @@ -4,43 +4,47 @@
- #include <errno.h>
- #include "libc.h"
-
- -uintptr_t __brk(uintptr_t);
- -
- #define ALIGN 16
-
- +void *__expand_heap(size_t *);
- +
- void *__simple_malloc(size_t n)
- {
- - static uintptr_t cur, brk;
- - uintptr_t base, new;
- + static char *cur, *end;
- static volatile int lock[2];
- - size_t align=1;
- + size_t align=1, pad;
- + void *p;
-
- if (!n) n++;
- - if (n > SIZE_MAX/2) goto toobig;
- -
- while (align<n && align<ALIGN)
- align += align;
- - n = n + align - 1 & -align;
-
- LOCK(lock);
- - if (!cur) cur = brk = __brk(0)+16;
- - base = cur + align-1 & -align;
- - if (n > SIZE_MAX - PAGE_SIZE - base) goto fail;
- - if (base+n > brk) {
- - new = base+n + PAGE_SIZE-1 & -PAGE_SIZE;
- - if (__brk(new) != new) goto fail;
- - brk = new;
- - }
- - cur = base+n;
- - UNLOCK(lock);
-
- - return (void *)base;
- + pad = -(uintptr_t)cur & align-1;
- +
- + if (n <= SIZE_MAX/2 + ALIGN) n += pad;
- +
- + if (n > end-cur) {
- + size_t m = n;
- + char *new = __expand_heap(&m);
- + if (!new) {
- + UNLOCK(lock);
- + return 0;
- + }
- + if (new != end) {
- + cur = new;
- + n -= pad;
- + pad = 0;
- + }
- + end = new + m;
- + }
-
- -fail:
- + p = cur + pad;
- + cur += n;
- UNLOCK(lock);
- -toobig:
- - errno = ENOMEM;
- - return 0;
- + return p;
- }
-
- weak_alias(__simple_malloc, malloc);
- +weak_alias(__simple_malloc, __malloc0);
- --- a/src/malloc/malloc.c
- +++ b/src/malloc/malloc.c
- @@ -13,7 +13,6 @@
- #define inline inline __attribute__((always_inline))
- #endif
-
- -uintptr_t __brk(uintptr_t);
- void *__mmap(void *, size_t, int, int, int, off_t);
- int __munmap(void *, size_t);
- void *__mremap(void *, size_t, size_t, int, ...);
- @@ -31,13 +30,9 @@ struct bin {
- };
-
- static struct {
- - uintptr_t brk;
- - size_t *heap;
- volatile uint64_t binmap;
- struct bin bins[64];
- - volatile int brk_lock[2];
- volatile int free_lock[2];
- - unsigned mmap_step;
- } mal;
-
-
- @@ -152,69 +147,52 @@ void __dump_heap(int x)
- }
- #endif
-
- +void *__expand_heap(size_t *);
- +
- static struct chunk *expand_heap(size_t n)
- {
- - static int init;
- + static int heap_lock[2];
- + static void *end;
- + void *p;
- struct chunk *w;
- - uintptr_t new;
- -
- - lock(mal.brk_lock);
- -
- - if (!init) {
- - mal.brk = __brk(0);
- -#ifdef SHARED
- - mal.brk = mal.brk + PAGE_SIZE-1 & -PAGE_SIZE;
- -#endif
- - mal.brk = mal.brk + 2*SIZE_ALIGN-1 & -SIZE_ALIGN;
- - mal.heap = (void *)mal.brk;
- - init = 1;
- - }
- -
- - if (n > SIZE_MAX - mal.brk - 2*PAGE_SIZE) goto fail;
- - new = mal.brk + n + SIZE_ALIGN + PAGE_SIZE - 1 & -PAGE_SIZE;
- - n = new - mal.brk;
- -
- - if (__brk(new) != new) {
- - size_t min = (size_t)PAGE_SIZE << mal.mmap_step/2;
- - n += -n & PAGE_SIZE-1;
- - if (n < min) n = min;
- - void *area = __mmap(0, n, PROT_READ|PROT_WRITE,
- - MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
- - if (area == MAP_FAILED) goto fail;
-
- - mal.mmap_step++;
- - area = (char *)area + SIZE_ALIGN - OVERHEAD;
- - w = area;
- + /* The argument n already accounts for the caller's chunk
- + * overhead needs, but if the heap can't be extended in-place,
- + * we need room for an extra zero-sized sentinel chunk. */
- + n += SIZE_ALIGN;
- +
- + lock(heap_lock);
- +
- + p = __expand_heap(&n);
- + if (!p) {
- + unlock(heap_lock);
- + return 0;
- + }
- +
- + /* If not just expanding existing space, we need to make a
- + * new sentinel chunk below the allocated space. */
- + if (p != end) {
- + /* Valid/safe because of the prologue increment. */
- n -= SIZE_ALIGN;
- + p = (char *)p + SIZE_ALIGN;
- + w = MEM_TO_CHUNK(p);
- w->psize = 0 | C_INUSE;
- - w->csize = n | C_INUSE;
- - w = NEXT_CHUNK(w);
- - w->psize = n | C_INUSE;
- - w->csize = 0 | C_INUSE;
- -
- - unlock(mal.brk_lock);
- -
- - return area;
- }
-
- - w = MEM_TO_CHUNK(mal.heap);
- - w->psize = 0 | C_INUSE;
- -
- - w = MEM_TO_CHUNK(new);
- + /* Record new heap end and fill in footer. */
- + end = (char *)p + n;
- + w = MEM_TO_CHUNK(end);
- w->psize = n | C_INUSE;
- w->csize = 0 | C_INUSE;
-
- - w = MEM_TO_CHUNK(mal.brk);
- + /* Fill in header, which may be new or may be replacing a
- + * zero-size sentinel header at the old end-of-heap. */
- + w = MEM_TO_CHUNK(p);
- w->csize = n | C_INUSE;
- - mal.brk = new;
- -
- - unlock(mal.brk_lock);
- +
- + unlock(heap_lock);
-
- return w;
- -fail:
- - unlock(mal.brk_lock);
- - errno = ENOMEM;
- - return 0;
- }
-
- static int adjust_size(size_t *n)
- @@ -378,6 +356,17 @@ void *malloc(size_t n)
- return CHUNK_TO_MEM(c);
- }
-
- +void *__malloc0(size_t n)
- +{
- + void *p = malloc(n);
- + if (p && !IS_MMAPPED(MEM_TO_CHUNK(p))) {
- + size_t *z;
- + n = (n + sizeof *z - 1)/sizeof *z;
- + for (z=p; n; n--, z++) if (*z) *z=0;
- + }
- + return p;
- +}
- +
- void *realloc(void *p, size_t n)
- {
- struct chunk *self, *next;
- --- a/src/misc/syslog.c
- +++ b/src/misc/syslog.c
- @@ -48,12 +48,8 @@ void closelog(void)
-
- static void __openlog()
- {
- - int fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
- - if (fd < 0) return;
- - if (connect(fd, (void *)&log_addr, sizeof log_addr) < 0)
- - close(fd);
- - else
- - log_fd = fd;
- + log_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
- + if (log_fd >= 0) connect(log_fd, (void *)&log_addr, sizeof log_addr);
- }
-
- void openlog(const char *ident, int opt, int facility)
- @@ -78,6 +74,11 @@ void openlog(const char *ident, int opt,
- pthread_setcancelstate(cs, 0);
- }
-
- +static int is_lost_conn(int e)
- +{
- + return e==ECONNREFUSED || e==ECONNRESET || e==ENOTCONN || e==EPIPE;
- +}
- +
- static void _vsyslog(int priority, const char *message, va_list ap)
- {
- char timebuf[16];
- @@ -107,7 +108,10 @@ static void _vsyslog(int priority, const
- if (l2 >= sizeof buf - l) l = sizeof buf - 1;
- else l += l2;
- if (buf[l-1] != '\n') buf[l++] = '\n';
- - if (send(log_fd, buf, l, 0) < 0 && (log_opt & LOG_CONS)) {
- + if (send(log_fd, buf, l, 0) < 0 && (!is_lost_conn(errno)
- + || connect(log_fd, (void *)&log_addr, sizeof log_addr) < 0
- + || send(log_fd, buf, l, 0) < 0)
- + && (log_opt & LOG_CONS)) {
- fd = open("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
- if (fd >= 0) {
- dprintf(fd, "%.*s", l-hlen, buf+hlen);
- --- a/src/multibyte/btowc.c
- +++ b/src/multibyte/btowc.c
- @@ -1,7 +1,10 @@
- #include <stdio.h>
- #include <wchar.h>
- +#include <stdlib.h>
- +#include "internal.h"
-
- wint_t btowc(int c)
- {
- - return c<128U ? c : EOF;
- + int b = (unsigned char)c;
- + return b<128U ? b : (MB_CUR_MAX==1 && c!=EOF) ? CODEUNIT(c) : WEOF;
- }
- --- a/src/multibyte/internal.h
- +++ b/src/multibyte/internal.h
- @@ -23,3 +23,10 @@ extern const uint32_t bittab[];
-
- #define SA 0xc2u
- #define SB 0xf4u
- +
- +/* Arbitrary encoding for representing code units instead of characters. */
- +#define CODEUNIT(c) (0xdfff & (signed char)(c))
- +#define IS_CODEUNIT(c) ((unsigned)(c)-0xdf80 < 0x80)
- +
- +/* Get inline definition of MB_CUR_MAX. */
- +#include "locale_impl.h"
- --- a/src/multibyte/mbrtowc.c
- +++ b/src/multibyte/mbrtowc.c
- @@ -4,6 +4,7 @@
- * unnecessary.
- */
-
- +#include <stdlib.h>
- #include <wchar.h>
- #include <errno.h>
- #include "internal.h"
- @@ -27,6 +28,7 @@ size_t mbrtowc(wchar_t *restrict wc, con
- if (!n) return -2;
- if (!c) {
- if (*s < 0x80) return !!(*wc = *s);
- + if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
- if (*s-SA > SB-SA) goto ilseq;
- c = bittab[*s++-SA]; n--;
- }
- --- a/src/multibyte/mbsrtowcs.c
- +++ b/src/multibyte/mbsrtowcs.c
- @@ -7,6 +7,8 @@
- #include <stdint.h>
- #include <wchar.h>
- #include <errno.h>
- +#include <string.h>
- +#include <stdlib.h>
- #include "internal.h"
-
- size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st)
- @@ -24,6 +26,23 @@ size_t mbsrtowcs(wchar_t *restrict ws, c
- }
- }
-
- + if (MB_CUR_MAX==1) {
- + if (!ws) return strlen((const char *)s);
- + for (;;) {
- + if (!wn) {
- + *src = (const void *)s;
- + return wn0;
- + }
- + if (!*s) break;
- + c = *s++;
- + *ws++ = CODEUNIT(c);
- + wn--;
- + }
- + *ws = 0;
- + *src = 0;
- + return wn0-wn;
- + }
- +
- if (!ws) for (;;) {
- if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
- while (!(( *(uint32_t*)s | *(uint32_t*)s-0x01010101) & 0x80808080)) {
- --- a/src/multibyte/mbtowc.c
- +++ b/src/multibyte/mbtowc.c
- @@ -4,6 +4,7 @@
- * unnecessary.
- */
-
- +#include <stdlib.h>
- #include <wchar.h>
- #include <errno.h>
- #include "internal.h"
- @@ -19,6 +20,7 @@ int mbtowc(wchar_t *restrict wc, const c
- if (!wc) wc = &dummy;
-
- if (*s < 0x80) return !!(*wc = *s);
- + if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
- if (*s-SA > SB-SA) goto ilseq;
- c = bittab[*s++-SA];
-
- --- a/src/multibyte/wcrtomb.c
- +++ b/src/multibyte/wcrtomb.c
- @@ -4,8 +4,10 @@
- * unnecessary.
- */
-
- +#include <stdlib.h>
- #include <wchar.h>
- #include <errno.h>
- +#include "internal.h"
-
- size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st)
- {
- @@ -13,6 +15,13 @@ size_t wcrtomb(char *restrict s, wchar_t
- if ((unsigned)wc < 0x80) {
- *s = wc;
- return 1;
- + } else if (MB_CUR_MAX == 1) {
- + if (!IS_CODEUNIT(wc)) {
- + errno = EILSEQ;
- + return -1;
- + }
- + *s = wc;
- + return 1;
- } else if ((unsigned)wc < 0x800) {
- *s++ = 0xc0 | (wc>>6);
- *s = 0x80 | (wc&0x3f);
- --- a/src/multibyte/wctob.c
- +++ b/src/multibyte/wctob.c
- @@ -1,8 +1,10 @@
- -#include <stdio.h>
- #include <wchar.h>
- +#include <stdlib.h>
- +#include "internal.h"
-
- int wctob(wint_t c)
- {
- if (c < 128U) return c;
- + if (MB_CUR_MAX==1 && IS_CODEUNIT(c)) return (unsigned char)c;
- return EOF;
- }
- --- a/src/network/ns_parse.c
- +++ b/src/network/ns_parse.c
- @@ -95,7 +95,7 @@ int ns_skiprr(const unsigned char *ptr,
- p += r;
- }
- }
- - return ptr - p;
- + return p - ptr;
- bad:
- errno = EMSGSIZE;
- return -1;
- --- a/src/passwd/nscd_query.c
- +++ b/src/passwd/nscd_query.c
- @@ -32,6 +32,7 @@ FILE *__nscd_query(int32_t req, const ch
- },
- .msg_iovlen = 2
- };
- + int errno_save = errno;
-
- *swap = 0;
- retry:
- @@ -50,11 +51,14 @@ retry:
- return f;
-
- if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
- - /* If there isn't a running nscd we return -1 to indicate that
- - * that is precisely what happened
- - */
- - if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT)
- + /* If there isn't a running nscd we simulate a "not found"
- + * result and the caller is responsible for calling
- + * fclose on the (unconnected) socket. The value of
- + * errno must be left unchanged in this case. */
- + if (errno == EACCES || errno == ECONNREFUSED || errno == ENOENT) {
- + errno = errno_save;
- return f;
- + }
- goto error;
- }
-
- --- /dev/null
- +++ b/src/process/sh/vfork.s
- @@ -0,0 +1,23 @@
- +.global __vfork
- +.weak vfork
- +.type __vfork,@function
- +.type vfork,@function
- +__vfork:
- +vfork:
- + mov #95, r3
- + add r3, r3
- +
- + trapa #31
- + or r0, r0
- + or r0, r0
- + or r0, r0
- + or r0, r0
- + or r0, r0
- +
- + mov r0, r4
- + mov.l 1f, r0
- +2: braf r0
- + nop
- + .align 2
- + .hidden __syscall_ret
- +1: .long __syscall_ret@PLT-(2b+4-.)
- --- a/src/regex/fnmatch.c
- +++ b/src/regex/fnmatch.c
- @@ -18,6 +18,7 @@
- #include <stdlib.h>
- #include <wchar.h>
- #include <wctype.h>
- +#include "locale_impl.h"
-
- #define END 0
- #define UNMATCHABLE -2
- @@ -229,7 +230,7 @@ static int fnmatch_internal(const char *
- * On illegal sequences we may get it wrong, but in that case
- * we necessarily have a matching failure anyway. */
- for (s=endstr; s>str && tailcnt; tailcnt--) {
- - if (s[-1] < 128U) s--;
- + if (s[-1] < 128U || MB_CUR_MAX==1) s--;
- else while ((unsigned char)*--s-0x80U<0x40 && s>str);
- }
- if (tailcnt) return FNM_NOMATCH;
- --- a/src/signal/sh/restore.s
- +++ b/src/signal/sh/restore.s
- @@ -2,7 +2,7 @@
- .type __restore, @function
- __restore:
- mov #119, r3 !__NR_sigreturn
- - trapa #16
- + trapa #31
-
- or r0, r0
- or r0, r0
- @@ -15,7 +15,7 @@ __restore:
- __restore_rt:
- mov #100, r3 !__NR_rt_sigreturn
- add #73, r3
- - trapa #16
- + trapa #31
-
- or r0, r0
- or r0, r0
- --- a/src/stdio/__fdopen.c
- +++ b/src/stdio/__fdopen.c
- @@ -54,13 +54,7 @@ FILE *__fdopen(int fd, const char *mode)
- if (!libc.threaded) f->lock = -1;
-
- /* Add new FILE to open file list */
- - OFLLOCK();
- - f->next = libc.ofl_head;
- - if (libc.ofl_head) libc.ofl_head->prev = f;
- - libc.ofl_head = f;
- - OFLUNLOCK();
- -
- - return f;
- + return __ofl_add(f);
- }
-
- weak_alias(__fdopen, fdopen);
- --- a/src/stdio/__stdio_exit.c
- +++ b/src/stdio/__stdio_exit.c
- @@ -16,8 +16,7 @@ static void close_file(FILE *f)
- void __stdio_exit(void)
- {
- FILE *f;
- - OFLLOCK();
- - for (f=libc.ofl_head; f; f=f->next) close_file(f);
- + for (f=*__ofl_lock(); f; f=f->next) close_file(f);
- close_file(__stdin_used);
- close_file(__stdout_used);
- }
- --- a/src/stdio/__stdio_read.c
- +++ b/src/stdio/__stdio_read.c
- @@ -1,12 +1,5 @@
- #include "stdio_impl.h"
- #include <sys/uio.h>
- -#include <pthread.h>
- -
- -static void cleanup(void *p)
- -{
- - FILE *f = p;
- - if (!f->lockcount) __unlockfile(f);
- -}
-
- size_t __stdio_read(FILE *f, unsigned char *buf, size_t len)
- {
- @@ -16,9 +9,7 @@ size_t __stdio_read(FILE *f, unsigned ch
- };
- ssize_t cnt;
-
- - pthread_cleanup_push(cleanup, f);
- - cnt = syscall_cp(SYS_readv, f->fd, iov, 2);
- - pthread_cleanup_pop(0);
- + cnt = syscall(SYS_readv, f->fd, iov, 2);
- if (cnt <= 0) {
- f->flags |= F_EOF ^ ((F_ERR^F_EOF) & cnt);
- return cnt;
- --- a/src/stdio/__stdio_write.c
- +++ b/src/stdio/__stdio_write.c
- @@ -1,12 +1,5 @@
- #include "stdio_impl.h"
- #include <sys/uio.h>
- -#include <pthread.h>
- -
- -static void cleanup(void *p)
- -{
- - FILE *f = p;
- - if (!f->lockcount) __unlockfile(f);
- -}
-
- size_t __stdio_write(FILE *f, const unsigned char *buf, size_t len)
- {
- @@ -19,9 +12,7 @@ size_t __stdio_write(FILE *f, const unsi
- int iovcnt = 2;
- ssize_t cnt;
- for (;;) {
- - pthread_cleanup_push(cleanup, f);
- - cnt = syscall_cp(SYS_writev, f->fd, iov, iovcnt);
- - pthread_cleanup_pop(0);
- + cnt = syscall(SYS_writev, f->fd, iov, iovcnt);
- if (cnt == rem) {
- f->wend = f->buf + f->buf_size;
- f->wpos = f->wbase = f->buf;
- @@ -34,11 +25,8 @@ size_t __stdio_write(FILE *f, const unsi
- }
- rem -= cnt;
- if (cnt > iov[0].iov_len) {
- - f->wpos = f->wbase = f->buf;
- cnt -= iov[0].iov_len;
- iov++; iovcnt--;
- - } else if (iovcnt == 2) {
- - f->wbase += cnt;
- }
- iov[0].iov_base = (char *)iov[0].iov_base + cnt;
- iov[0].iov_len -= cnt;
- --- a/src/stdio/fclose.c
- +++ b/src/stdio/fclose.c
- @@ -14,11 +14,11 @@ int fclose(FILE *f)
- __unlist_locked_file(f);
-
- if (!(perm = f->flags & F_PERM)) {
- - OFLLOCK();
- + FILE **head = __ofl_lock();
- if (f->prev) f->prev->next = f->next;
- if (f->next) f->next->prev = f->prev;
- - if (libc.ofl_head == f) libc.ofl_head = f->next;
- - OFLUNLOCK();
- + if (*head == f) *head = f->next;
- + __ofl_unlock();
- }
-
- r = fflush(f);
- --- a/src/stdio/fflush.c
- +++ b/src/stdio/fflush.c
- @@ -35,13 +35,12 @@ int fflush(FILE *f)
-
- r = __stdout_used ? fflush(__stdout_used) : 0;
-
- - OFLLOCK();
- - for (f=libc.ofl_head; f; f=f->next) {
- + for (f=*__ofl_lock(); f; f=f->next) {
- FLOCK(f);
- if (f->wpos > f->wbase) r |= __fflush_unlocked(f);
- FUNLOCK(f);
- }
- - OFLUNLOCK();
- + __ofl_unlock();
-
- return r;
- }
- --- a/src/stdio/fgetwc.c
- +++ b/src/stdio/fgetwc.c
- @@ -1,8 +1,9 @@
- #include "stdio_impl.h"
- +#include "locale_impl.h"
- #include <wchar.h>
- #include <errno.h>
-
- -wint_t __fgetwc_unlocked(FILE *f)
- +static wint_t __fgetwc_unlocked_internal(FILE *f)
- {
- mbstate_t st = { 0 };
- wchar_t wc;
- @@ -10,8 +11,6 @@ wint_t __fgetwc_unlocked(FILE *f)
- unsigned char b;
- size_t l;
-
- - f->mode |= f->mode+1;
- -
- /* Convert character from buffer if possible */
- if (f->rpos < f->rend) {
- l = mbrtowc(&wc, (void *)f->rpos, f->rend - f->rpos, &st);
- @@ -39,6 +38,16 @@ wint_t __fgetwc_unlocked(FILE *f)
- return wc;
- }
-
- +wint_t __fgetwc_unlocked(FILE *f)
- +{
- + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
- + if (f->mode <= 0) fwide(f, 1);
- + *ploc = f->locale;
- + wchar_t wc = __fgetwc_unlocked_internal(f);
- + *ploc = loc;
- + return wc;
- +}
- +
- wint_t fgetwc(FILE *f)
- {
- wint_t c;
- --- a/src/stdio/fmemopen.c
- +++ b/src/stdio/fmemopen.c
- @@ -110,11 +110,5 @@ FILE *fmemopen(void *restrict buf, size_
-
- if (!libc.threaded) f->lock = -1;
-
- - OFLLOCK();
- - f->next = libc.ofl_head;
- - if (libc.ofl_head) libc.ofl_head->prev = f;
- - libc.ofl_head = f;
- - OFLUNLOCK();
- -
- - return f;
- + return __ofl_add(f);
- }
- --- a/src/stdio/fopen.c
- +++ b/src/stdio/fopen.c
- @@ -18,7 +18,7 @@ FILE *fopen(const char *restrict filenam
- /* Compute the flags to pass to open() */
- flags = __fmodeflags(mode);
-
- - fd = sys_open_cp(filename, flags, 0666);
- + fd = sys_open(filename, flags, 0666);
- if (fd < 0) return 0;
- if (flags & O_CLOEXEC)
- __syscall(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
- --- a/src/stdio/fputwc.c
- +++ b/src/stdio/fputwc.c
- @@ -1,4 +1,5 @@
- #include "stdio_impl.h"
- +#include "locale_impl.h"
- #include <wchar.h>
- #include <limits.h>
- #include <ctype.h>
- @@ -7,8 +8,10 @@ wint_t __fputwc_unlocked(wchar_t c, FILE
- {
- char mbc[MB_LEN_MAX];
- int l;
- + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
-
- - f->mode |= f->mode+1;
- + if (f->mode <= 0) fwide(f, 1);
- + *ploc = f->locale;
-
- if (isascii(c)) {
- c = putc_unlocked(c, f);
- @@ -20,6 +23,8 @@ wint_t __fputwc_unlocked(wchar_t c, FILE
- l = wctomb(mbc, c);
- if (l < 0 || __fwritex((void *)mbc, l, f) < l) c = WEOF;
- }
- + if (c==WEOF) f->flags |= F_ERR;
- + *ploc = loc;
- return c;
- }
-
- --- a/src/stdio/fputws.c
- +++ b/src/stdio/fputws.c
- @@ -1,23 +1,28 @@
- #include "stdio_impl.h"
- +#include "locale_impl.h"
- #include <wchar.h>
-
- int fputws(const wchar_t *restrict ws, FILE *restrict f)
- {
- unsigned char buf[BUFSIZ];
- size_t l=0;
- + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
-
- FLOCK(f);
-
- - f->mode |= f->mode+1;
- + fwide(f, 1);
- + *ploc = f->locale;
-
- while (ws && (l = wcsrtombs((void *)buf, (void*)&ws, sizeof buf, 0))+1 > 1)
- if (__fwritex(buf, l, f) < l) {
- FUNLOCK(f);
- + *ploc = loc;
- return -1;
- }
-
- FUNLOCK(f);
-
- + *ploc = loc;
- return l; /* 0 or -1 */
- }
-
- --- a/src/stdio/fwide.c
- +++ b/src/stdio/fwide.c
- @@ -1,13 +1,14 @@
- -#include <wchar.h>
- #include "stdio_impl.h"
- -
- -#define SH (8*sizeof(int)-1)
- -#define NORMALIZE(x) ((x)>>SH | -((-(x))>>SH))
- +#include "locale_impl.h"
-
- int fwide(FILE *f, int mode)
- {
- FLOCK(f);
- - if (!f->mode) f->mode = NORMALIZE(mode);
- + if (mode) {
- + if (!f->locale) f->locale = MB_CUR_MAX==1
- + ? C_LOCALE : UTF8_LOCALE;
- + if (!f->mode) f->mode = mode>0 ? 1 : -1;
- + }
- mode = f->mode;
- FUNLOCK(f);
- return mode;
- --- /dev/null
- +++ b/src/stdio/ofl.c
- @@ -0,0 +1,16 @@
- +#include "stdio_impl.h"
- +#include "libc.h"
- +
- +static FILE *ofl_head;
- +static volatile int ofl_lock[2];
- +
- +FILE **__ofl_lock()
- +{
- + LOCK(ofl_lock);
- + return &ofl_head;
- +}
- +
- +void __ofl_unlock()
- +{
- + UNLOCK(ofl_lock);
- +}
- --- /dev/null
- +++ b/src/stdio/ofl_add.c
- @@ -0,0 +1,11 @@
- +#include "stdio_impl.h"
- +
- +FILE *__ofl_add(FILE *f)
- +{
- + FILE **head = __ofl_lock();
- + f->next = *head;
- + if (*head) (*head)->prev = f;
- + *head = f;
- + __ofl_unlock();
- + return f;
- +}
- --- a/src/stdio/open_memstream.c
- +++ b/src/stdio/open_memstream.c
- @@ -79,11 +79,5 @@ FILE *open_memstream(char **bufp, size_t
-
- if (!libc.threaded) f->lock = -1;
-
- - OFLLOCK();
- - f->next = libc.ofl_head;
- - if (libc.ofl_head) libc.ofl_head->prev = f;
- - libc.ofl_head = f;
- - OFLUNLOCK();
- -
- - return f;
- + return __ofl_add(f);
- }
- --- a/src/stdio/open_wmemstream.c
- +++ b/src/stdio/open_wmemstream.c
- @@ -81,11 +81,5 @@ FILE *open_wmemstream(wchar_t **bufp, si
-
- if (!libc.threaded) f->lock = -1;
-
- - OFLLOCK();
- - f->next = libc.ofl_head;
- - if (libc.ofl_head) libc.ofl_head->prev = f;
- - libc.ofl_head = f;
- - OFLUNLOCK();
- -
- - return f;
- + return __ofl_add(f);
- }
- --- a/src/stdio/ungetwc.c
- +++ b/src/stdio/ungetwc.c
- @@ -1,4 +1,5 @@
- #include "stdio_impl.h"
- +#include "locale_impl.h"
- #include <wchar.h>
- #include <limits.h>
- #include <ctype.h>
- @@ -8,21 +9,19 @@ wint_t ungetwc(wint_t c, FILE *f)
- {
- unsigned char mbc[MB_LEN_MAX];
- int l=1;
- -
- - if (c == WEOF) return c;
- -
- - /* Try conversion early so we can fail without locking if invalid */
- - if (!isascii(c) && (l = wctomb((void *)mbc, c)) < 0)
- - return WEOF;
- + locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
-
- FLOCK(f);
-
- - f->mode |= f->mode+1;
- + if (f->mode <= 0) fwide(f, 1);
- + *ploc = f->locale;
-
- if (!f->rpos) __toread(f);
- - if (!f->rpos || f->rpos < f->buf - UNGET + l) {
- + if (!f->rpos || f->rpos < f->buf - UNGET + l || c == WEOF ||
- + (!isascii(c) && (l = wctomb((void *)mbc, c)) < 0)) {
- FUNLOCK(f);
- - return EOF;
- + *ploc = loc;
- + return WEOF;
- }
-
- if (isascii(c)) *--f->rpos = c;
- @@ -31,5 +30,6 @@ wint_t ungetwc(wint_t c, FILE *f)
- f->flags &= ~F_EOF;
-
- FUNLOCK(f);
- + *ploc = loc;
- return c;
- }
- --- a/src/stdio/vfwprintf.c
- +++ b/src/stdio/vfwprintf.c
- @@ -293,7 +293,10 @@ static int wprintf_core(FILE *f, const w
- if ((fl&LEFT_ADJ)) fprintf(f, "%.*s", w-p, "");
- l=w;
- continue;
- + case 'm':
- + arg.p = strerror(errno);
- case 's':
- + if (!arg.p) arg.p = "(null)";
- bs = arg.p;
- if (p<0) p = INT_MAX;
- for (i=l=0; l<p && (i=mbtowc(&wc, bs, MB_LEN_MAX))>0; bs+=i, l++);
- @@ -356,7 +359,7 @@ int vfwprintf(FILE *restrict f, const wc
- }
-
- FLOCK(f);
- - f->mode |= f->mode+1;
- + fwide(f, 1);
- olderr = f->flags & F_ERR;
- f->flags &= ~F_ERR;
- ret = wprintf_core(f, fmt, &ap2, nl_arg, nl_type);
- --- a/src/stdio/vfwscanf.c
- +++ b/src/stdio/vfwscanf.c
- @@ -104,7 +104,7 @@ int vfwscanf(FILE *restrict f, const wch
-
- FLOCK(f);
-
- - f->mode |= f->mode+1;
- + fwide(f, 1);
-
- for (p=fmt; *p; p++) {
-
- --- a/src/string/strverscmp.c
- +++ b/src/string/strverscmp.c
- @@ -2,40 +2,33 @@
- #include <ctype.h>
- #include <string.h>
-
- -int strverscmp(const char *l, const char *r)
- +int strverscmp(const char *l0, const char *r0)
- {
- - int haszero=1;
- - while (*l==*r) {
- - if (!*l) return 0;
- + const unsigned char *l = (const void *)l0;
- + const unsigned char *r = (const void *)r0;
- + size_t i, dp, j;
- + int z = 1;
-
- - if (*l=='0') {
- - if (haszero==1) {
- - haszero=0;
- - }
- - } else if (isdigit(*l)) {
- - if (haszero==1) {
- - haszero=2;
- - }
- - } else {
- - haszero=1;
- - }
- - l++; r++;
- + /* Find maximal matching prefix and track its maximal digit
- + * suffix and whether those digits are all zeros. */
- + for (dp=i=0; l[i]==r[i]; i++) {
- + int c = l[i];
- + if (!c) return 0;
- + if (!isdigit(c)) dp=i+1, z=1;
- + else if (c!='0') z=0;
- }
- - if (haszero==1 && (*l=='0' || *r=='0')) {
- - haszero=0;
- - }
- - if ((isdigit(*l) && isdigit(*r) ) && haszero) {
- - size_t lenl=0, lenr=0;
- - while (isdigit(l[lenl]) ) lenl++;
- - while (isdigit(r[lenr]) ) lenr++;
- - if (lenl==lenr) {
- - return (*l - *r);
- - } else if (lenl>lenr) {
- - return 1;
- - } else {
- - return -1;
- - }
- - } else {
- - return (*l - *r);
- +
- + if (l[dp]!='0' && r[dp]!='0') {
- + /* If we're not looking at a digit sequence that began
- + * with a zero, longest digit string is greater. */
- + for (j=i; isdigit(l[j]); j++)
- + if (!isdigit(r[j])) return 1;
- + if (isdigit(r[j])) return -1;
- + } else if (z && dp<i && (isdigit(l[i]) || isdigit(r[i]))) {
- + /* Otherwise, if common prefix of digit sequence is
- + * all zeros, digits order less than non-digits. */
- + return (unsigned char)(l[i]-'0') - (unsigned char)(r[i]-'0');
- }
- +
- + return l[i] - r[i];
- }
- --- a/src/thread/__tls_get_addr.c
- +++ b/src/thread/__tls_get_addr.c
- @@ -8,9 +8,9 @@ void *__tls_get_addr(size_t *v)
- __attribute__((__visibility__("hidden")))
- void *__tls_get_new(size_t *);
- if (v[0]<=(size_t)self->dtv[0])
- - return (char *)self->dtv[v[0]]+v[1];
- + return (char *)self->dtv[v[0]]+v[1]+DTP_OFFSET;
- return __tls_get_new(v);
- #else
- - return (char *)self->dtv[1]+v[1];
- + return (char *)self->dtv[1]+v[1]+DTP_OFFSET;
- #endif
- }
- --- /dev/null
- +++ b/src/thread/__unmapself.c
- @@ -0,0 +1,29 @@
- +#include "pthread_impl.h"
- +#include "atomic.h"
- +#include "syscall.h"
- +/* cheat and reuse CRTJMP macro from dynlink code */
- +#include "dynlink.h"
- +
- +static volatile int lock;
- +static void *unmap_base;
- +static size_t unmap_size;
- +static char shared_stack[256];
- +
- +static void do_unmap()
- +{
- + __syscall(SYS_munmap, unmap_base, unmap_size);
- + __syscall(SYS_exit);
- +}
- +
- +void __unmapself(void *base, size_t size)
- +{
- + int tid=__pthread_self()->tid;
- + char *stack = shared_stack + sizeof shared_stack;
- + stack -= (uintptr_t)stack % 16;
- + while (lock || a_cas(&lock, 0, tid))
- + a_spin();
- + __syscall(SYS_set_tid_address, &lock);
- + unmap_base = base;
- + unmap_size = size;
- + CRTJMP(do_unmap, stack);
- +}
- --- a/src/thread/mips/__unmapself.s
- +++ b/src/thread/mips/__unmapself.s
- @@ -2,6 +2,7 @@
- .global __unmapself
- .type __unmapself,@function
- __unmapself:
- + move $sp, $25
- li $2, 4091
- syscall
- li $4, 0
- --- a/src/thread/pthread_create.c
- +++ b/src/thread/pthread_create.c
- @@ -191,8 +191,9 @@ int __pthread_create(pthread_t *restrict
- if (!libc.can_do_threads) return ENOSYS;
- self = __pthread_self();
- if (!libc.threaded) {
- - for (FILE *f=libc.ofl_head; f; f=f->next)
- + for (FILE *f=*__ofl_lock(); f; f=f->next)
- init_file_lock(f);
- + __ofl_unlock();
- init_file_lock(__stdin_used);
- init_file_lock(__stdout_used);
- init_file_lock(__stderr_used);
- @@ -231,7 +232,8 @@ int __pthread_create(pthread_t *restrict
- if (guard) {
- map = __mmap(0, size, PROT_NONE, MAP_PRIVATE|MAP_ANON, -1, 0);
- if (map == MAP_FAILED) goto fail;
- - if (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE)) {
- + if (__mprotect(map+guard, size-guard, PROT_READ|PROT_WRITE)
- + && errno != ENOSYS) {
- __munmap(map, size);
- goto fail;
- }
- --- a/src/thread/sh/__set_thread_area.s
- +++ b/src/thread/sh/__set_thread_area.s
- @@ -1,6 +0,0 @@
- -.global __set_thread_area
- -.type __set_thread_area, @function
- -__set_thread_area:
- - ldc r4, gbr
- - rts
- - mov #0, r0
- --- a/src/thread/sh/__unmapself.s
- +++ b/src/thread/sh/__unmapself.s
- @@ -1,9 +1,9 @@
- .text
- -.global __unmapself
- -.type __unmapself, @function
- -__unmapself:
- +.global __unmapself_sh_mmu
- +.type __unmapself_sh_mmu, @function
- +__unmapself_sh_mmu:
- mov #91, r3 ! SYS_munmap
- - trapa #18
- + trapa #31
-
- or r0, r0
- or r0, r0
- @@ -13,7 +13,7 @@ __unmapself:
-
- mov #1, r3 ! SYS_exit
- mov #0, r4
- - trapa #17
- + trapa #31
-
- or r0, r0
- or r0, r0
- --- a/src/thread/sh/clone.s
- +++ b/src/thread/sh/clone.s
- @@ -17,7 +17,7 @@ __clone:
- mov.l @r15, r6 ! r6 = ptid
- mov.l @(8,r15), r7 ! r7 = ctid
- mov.l @(4,r15), r0 ! r0 = tls
- - trapa #21
- + trapa #31
-
- or r0, r0
- or r0, r0
- @@ -38,7 +38,7 @@ __clone:
-
- mov #1, r3 ! __NR_exit
- mov r0, r4
- - trapa #17
- + trapa #31
-
- or r0, r0
- or r0, r0
- --- a/src/thread/sh/syscall_cp.s
- +++ b/src/thread/sh/syscall_cp.s
- @@ -31,7 +31,7 @@ L1: .long __cancel@PLT-(1b-.)
- mov.l @(4,r15), r7
- mov.l @(8,r15), r0
- mov.l @(12,r15), r1
- - trapa #22
- + trapa #31
-
- __cp_end:
- ! work around hardware bug
- --- a/src/time/__tz.c
- +++ b/src/time/__tz.c
- @@ -125,7 +125,8 @@ static void do_tzset()
- "/usr/share/zoneinfo/\0/share/zoneinfo/\0/etc/zoneinfo/\0";
-
- s = getenv("TZ");
- - if (!s || !*s) s = "/etc/localtime";
- + if (!s) s = "/etc/localtime";
- + if (!*s) s = __gmt;
-
- if (old_tz && !strcmp(s, old_tz)) return;
-
- --- a/src/unistd/sh/pipe.s
- +++ b/src/unistd/sh/pipe.s
- @@ -2,7 +2,7 @@
- .type pipe, @function
- pipe:
- mov #42, r3
- - trapa #17
- + trapa #31
-
- ! work around hardware bug
- or r0, r0
- --- /dev/null
- +++ b/tools/ld.musl-clang.in
- @@ -0,0 +1,51 @@
- +#!/bin/sh
- +cc="@CC@"
- +libc_lib="@LIBDIR@"
- +ldso="@LDSO@"
- +cleared=
- +shared=
- +userlinkdir=
- +userlink=
- +
- +for x ; do
- + test "$cleared" || set -- ; cleared=1
- +
- + case "$x" in
- + -L-user-start)
- + userlinkdir=1
- + ;;
- + -L-user-end)
- + userlinkdir=
- + ;;
- + -L*)
- + test "$userlinkdir" && set -- "$@" "$x"
- + ;;
- + -l-user-start)
- + userlink=1
- + ;;
- + -l-user-end)
- + userlink=
- + ;;
- + crtbegin*.o|crtend*.o)
- + set -- "$@" $($cc -print-file-name=$x)
- + ;;
- + -lgcc|-lgcc_eh)
- + file=lib${x#-l}.a
- + set -- "$@" $($cc -print-file-name=$file)
- + ;;
- + -l*)
- + test "$userlink" && set -- "$@" "$x"
- + ;;
- + -shared)
- + shared=1
- + set -- "$@" -shared
- + ;;
- + -sysroot=*|--sysroot=*)
- + ;;
- + *)
- + set -- "$@" "$x"
- + ;;
- + esac
- +done
- +
- +exec $($cc -print-prog-name=ld) -nostdlib "$@" -lc -dynamic-linker "$ldso"
- --- /dev/null
- +++ b/tools/musl-clang.in
- @@ -0,0 +1,35 @@
- +#!/bin/sh
- +cc="@CC@"
- +libc="@PREFIX@"
- +libc_inc="@INCDIR@"
- +libc_lib="@LIBDIR@"
- +thisdir="`cd "$(dirname "$0")"; pwd`"
- +
- +# prevent clang from running the linker (and erroring) on no input.
- +sflags=
- +eflags=
- +for x ; do
- + case "$x" in
- + -l*) input=1 ;;
- + *) input= ;;
- + esac
- + if test "$input" ; then
- + sflags="-l-user-start"
- + eflags="-l-user-end"
- + break
- + fi
- +done
- +
- +exec $cc \
- + -B"$thisdir" \
- + -fuse-ld=musl-clang \
- + -static-libgcc \
- + -nostdinc \
- + --sysroot "$libc" \
- + -isystem "$libc_inc" \
- + -L-user-start \
- + $sflags \
- + "$@" \
- + $eflags \
- + -L"$libc_lib" \
- + -L-user-end
|