001-git-2015-06-04.patch 62 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015
  1. commit b6a6cd703ffefa6352249fb01f4da28d85d17306
  2. Author: Rich Felker <dalias@aerifal.cx>
  3. Date: Thu Jun 4 11:45:17 2015 -0400
  4. fix dynamic linker regression processing R_*_NONE type relocations
  5. commit f3ddd173806fd5c60b3f034528ca24542aecc5b9 inadvertently removed
  6. the early check for "none" type relocations, causing the address
  7. dso->base+0 to be dereferenced to obtain an addend. shared libraries,
  8. (including libc.so) and PIE executables were unaffected, since their
  9. base addresses are the actual address of their mappings and are
  10. readable. non-PIE main executables, however, have a base address of 0
  11. because their load addresses are absolute and not offset at load time.
  12. in practice none-type relocations do not arise with toolchains that
  13. are in use except on mips, and on mips it's moderately rare for a
  14. non-PIE executable to have a relocation table, since the mips-specific
  15. got processing serves in its place for most purposes.
  16. commit 585ba14df4799d50ec9682ce75825d2eafec2a6a
  17. Author: Rich Felker <dalias@aerifal.cx>
  18. Date: Wed Jun 3 02:00:44 2015 -0400
  19. add additional Makefile dependency rules for rcrt1.o PIE start file
  20. commit 2b4fcfdacf93c3dfd6ac15e31790a9e154374679
  21. Author: Rich Felker <dalias@aerifal.cx>
  22. Date: Thu May 28 23:08:12 2015 -0400
  23. fix failure of ungetc and ungetwc to work on files in eof status
  24. these functions were written to handle clearing eof status, but failed
  25. to account for the __toread function's handling of eof. with this
  26. patch applied, __toread still returns EOF when the file is in eof
  27. status, so that read operations will fail, but it also sets up valid
  28. buffer pointers for read mode, which are set to the end of the buffer
  29. rather than the beginning in order to make the whole buffer available
  30. to ungetc/ungetwc.
  31. minor changes to __uflow were needed since it's now possible to have
  32. non-zero buffer pointers while in eof status. as made, these changes
  33. remove a 'fast path' bypassing the function call to __toread, which
  34. could be reintroduced with slightly different logic, but since
  35. ordinary files have a syscall in f->read, optimizing the code path
  36. does not seem worthwhile.
  37. the __stdio_read function is also updated not to zero the read buffer
  38. pointers on eof/error. while not necessary for correctness, this
  39. change avoids the overhead of calling __toread in ungetc after
  40. reaching eof, and it also reduces code size and increases consistency
  41. with the fmemopen read operation which does not zero the pointers.
  42. commit b6e7c664677ab7c77f183b8c41105f2be519800c
  43. Author: Rich Felker <dalias@aerifal.cx>
  44. Date: Thu May 28 15:37:23 2015 -0400
  45. add missing legacy LFS64 macros in sys/resource.h
  46. based on patch by Felix Janda, with RLIM64_SAVED_CUR and
  47. RLIM64_SAVED_MAX added for completeness.
  48. commit fc431d3f76bb9bde34a89e4a3e4d0c27de959855
  49. Author: Shiz <hi@shiz.me>
  50. Date: Thu May 28 05:52:22 2015 +0200
  51. configure: work around compilers that merely warn for unknown options
  52. some compilers (such as clang) accept unknown options without error,
  53. but then print warnings on each invocation, cluttering the build
  54. output and burying meaningful warnings. this patch makes configure's
  55. tryflag and tryldflag functions use additional options to turn the
  56. unknown-option warnings into errors, if available, but only at check
  57. time. these options are not output in config.mak to avoid the risk of
  58. spurious build breakage; if they work, they will have already done
  59. their job at configure time.
  60. commit aeeac9ca5490d7d90fe061ab72da446c01ddf746
  61. Author: Rich Felker <dalias@aerifal.cx>
  62. Date: Wed May 27 15:54:47 2015 -0400
  63. implement fail-safe static locales for newlocale
  64. this frees applications which need to make temporary use of the C
  65. locale (via uselocale) from the possibility that newlocale might fail.
  66. the C.UTF-8 locale is also provided as a static locale. presently they
  67. behave the same, but this may change in the future.
  68. commit 11858d31aa020df3e7e7dedf49f9870ce12f31cc
  69. Author: Rich Felker <dalias@aerifal.cx>
  70. Date: Wed May 27 03:32:46 2015 -0400
  71. rename internal locale file handling locale maps
  72. since the __setlocalecat function was removed, the filename
  73. __setlocalecat.c no longer made sense.
  74. commit 61a3364d246e72b903da8b76c2e27a225a51351e
  75. Author: Rich Felker <dalias@aerifal.cx>
  76. Date: Wed May 27 03:22:52 2015 -0400
  77. overhaul locale internals to treat categories roughly uniformly
  78. previously, LC_MESSAGES was treated specially as the only category
  79. which could be set to a locale name without a definition file, in
  80. order to facilitate gettext message translations when no libc locale
  81. was available. LC_NUMERIC was completely un-settable, and LC_CTYPE
  82. stored a flag intended to be used for a possible future byte-based C
  83. locale, instead of storing a __locale_map pointer like the other
  84. categories use.
  85. this patch changes all categories to be represented by pointers to
  86. __locale_map structures, and allows locale names without definition
  87. files to be treated as valid locales with trivial definition when used
  88. in any category. outwardly visible functional changes should be minor,
  89. limited mainly to the strings read back from setlocale and the way
  90. gettext handles translations in categories other than LC_MESSAGES.
  91. various internal refactoring has also been performed, and improvements
  92. in const correctness have been made.
  93. commit 63c188ec42e76ff768e81f6b65b11c68fc43351e
  94. Author: Rich Felker <dalias@aerifal.cx>
  95. Date: Wed May 27 00:22:43 2015 -0400
  96. replace atomics with locks in locale-setting code
  97. this is part of a general program of removing direct use of atomics
  98. where they are not necessary to meet correctness or performance needs,
  99. but in this case it's also an optimization. only the global locale
  100. needs synchronization; allocated locales referenced with locale_t
  101. handles are immutable during their lifetimes, and using atomics to
  102. initialize them increases their cost of setup.
  103. commit dc031ee0b1ba11baa00cd7f0769e461a5f396c71
  104. Author: Rich Felker <dalias@aerifal.cx>
  105. Date: Tue May 26 03:37:41 2015 -0400
  106. add rcrt1 start file for fully static-linked PIE
  107. static-linked PIE files need startup code to relocate themselves, much
  108. like the dynamic linker does. rcrt1.c reuses the code in dlstart.c,
  109. stage 1 of the dynamic linker, which in turn reuses crt_arch.h, to
  110. achieve static PIE with no new code. only relative relocations are
  111. supported.
  112. existing toolchains that don't yet support static PIE directly can be
  113. repurposed by passing "-shared -Wl,-Bstatic -Wl,-Bsymbolic" instead of
  114. "-static -pie" and substituting rcrt1.o in place of crt1.o.
  115. all libraries being linked must be built as PIC/PIE; TEXTRELs are not
  116. supported at this time.
  117. commit ed0c8249825161036356a3616e8c5247c15d0927
  118. Author: Rich Felker <dalias@aerifal.cx>
  119. Date: Tue May 26 02:31:04 2015 -0400
  120. fix incorrect application of visibility to Scrt1.o
  121. commit de2b67f8d41e08caa56bf6540277f6561edb647f attempted to avoid
  122. having vis.h affect crt files, but the Makefile variable used,
  123. CRT_LIBS, refers to the final output copies in the lib directory, not
  124. the copies in the crt build directory, and thus the -DCRT was not
  125. applied.
  126. while unlikely to be noticed, this regression probably broke
  127. production of PIE executables whose main functions are not in the
  128. executable but rather a shared library.
  129. commit 9bbddf730f7837cf87f4c789fbb41a312e295d6c
  130. Author: Rich Felker <dalias@aerifal.cx>
  131. Date: Mon May 25 23:33:59 2015 -0400
  132. reprocess all libc/ldso symbolic relocations in dynamic linking stage 3
  133. commit f3ddd173806fd5c60b3f034528ca24542aecc5b9 introduced early
  134. relocations and subsequent reprocessing as part of the dynamic linker
  135. bootstrap overhaul, to allow use of arbitrary libc functions before
  136. the main application and libraries are loaded, but only reprocessed
  137. GOT/PLT relocation types.
  138. commit c093e2e8201524db0d638920e76bcb6b1d925f3a added reprocessing of
  139. non-GOT/PLT relocations to fix an actual regression that was observed
  140. on powerpc, but only for RELA format tables with out-of-line addends.
  141. REL table (inline addends at the relocation address) reprocessing is
  142. trickier because the first relocation pass clobbers the addends.
  143. this patch extends symbolic relocation reprocessing for libc/ldso to
  144. support all relocation types, whether REL or RELA format tables are
  145. used. it is believed not to alter behavior on any existing archs for
  146. the current dynamic linker and libc code. the motivations for this
  147. change are consistency and future-proofing. it ensures that behavior
  148. does not differ depending on whether REL or RELA tables are used,
  149. which could lead to undetected arch-specific bugs. it also ensures
  150. that, if in the future code depending on additional relocation types
  151. is added to libc.so, either at the source level or as part of the
  152. compiler runtime that gets pulled in (for example, soft-float with TLS
  153. for fenv), the new code will work properly.
  154. the implementation concept is simple: stage 2 of the dynamic linker
  155. counts the number of symbolic relocations in the libc/ldso REL table
  156. and allocates a VLA to save their addends into; stage 3 then uses the
  157. saved addends in place of the inline ones which were clobbered. for
  158. stack safety, a hard limit (currently 4k) is imposed on the number of
  159. such addends; this should be a couple orders of magnitude larger than
  160. the actual need. this number is not a runtime variable that could
  161. break fail-safety; it is constant for a given libc.so build.
  162. commit 768b82c6de24e480267c4c251c440edfc71800e3
  163. Author: Rich Felker <dalias@aerifal.cx>
  164. Date: Mon May 25 19:15:17 2015 -0400
  165. move call to dynamic linker stage-3 into stage-2 function
  166. this move eliminates a duplicate "by-hand" symbol lookup loop from the
  167. stage-1 code and replaces it with a call to find_sym, which can be
  168. used once we're in stage 2. it reduces the size of the stage 1 code,
  169. which is helpful because stage 1 will become the crt start file for
  170. static-PIE executables, and it will allow stage 3 to access stage 2's
  171. automatic storage, which will be important in an upcoming commit.
  172. commit 967bcbf67c3ffac587de4d79abc1e5e072d83e3e
  173. Author: Rich Felker <dalias@aerifal.cx>
  174. Date: Mon May 25 16:02:49 2015 -0400
  175. mark mips crt code as code
  176. otherwise disassemblers treat it as data.
  177. commit 7b75c4877ddf22f219f944c61d939df1dee4f6d3
  178. Author: Rich Felker <dalias@aerifal.cx>
  179. Date: Mon May 25 15:56:36 2015 -0400
  180. mark mips cancellable syscall code as code
  181. otherwise disassemblers treat it as data.
  182. commit 0e0e49421f08cfd670975ecd3604f7f9015e1833
  183. Author: Rich Felker <dalias@aerifal.cx>
  184. Date: Mon May 25 00:32:37 2015 -0400
  185. simplify/shrink relocation processing in dynamic linker stage 1
  186. the outer-loop approach made sense when we were also processing
  187. DT_JMPREL, which might be in REL or RELA form, to avoid major code
  188. duplication. commit 09db855b35709aa627d7055c57a98e1e471920ab removed
  189. processing of DT_JMPREL, and in the remaining two tables, the format
  190. (REL or RELA) is known by the name of the table. simply writing two
  191. versions of the loop results in smaller and simpler code.
  192. commit 09db855b35709aa627d7055c57a98e1e471920ab
  193. Author: Rich Felker <dalias@aerifal.cx>
  194. Date: Mon May 25 00:25:56 2015 -0400
  195. remove processing of DT_JMPREL from dynamic linker stage 1 bootstrap
  196. the DT_JMPREL relocation table necessarily consists entirely of
  197. JMP_SLOT (REL_PLT in internal nomenclature) relocations, which are
  198. symbolic; they cannot be resolved in stage 1, so there is no point in
  199. processing them.
  200. commit 9f26ebded188ed78c3571a4ca1477dd6351bc647
  201. Author: Rich Felker <dalias@aerifal.cx>
  202. Date: Sun May 24 23:03:47 2015 -0400
  203. fix stack alignment code in mips crt_arch.h
  204. the instruction used to align the stack, "and $sp, $sp, -8", does not
  205. actually exist; it's expanded to 2 instructions using the 'at'
  206. (assembler temporary) register, and thus cannot be used in a branch
  207. delay slot. since alignment mod 16 commutes with subtracting 8, simply
  208. swapping these two operations fixes the problem.
  209. crt1.o was not affected because it's still being generated from a
  210. dedicated asm source file. dlstart.lo was not affected because the
  211. stack pointer it receives is already aligned by the kernel. but
  212. Scrt1.o was affected in cases where the dynamic linker gave it a
  213. misaligned stack pointer.
  214. commit 63caf1d207d143fe405bbe0cda9aac8deca1171a
  215. Author: Rich Felker <dalias@aerifal.cx>
  216. Date: Fri May 22 01:50:05 2015 -0400
  217. add .text section directive to all crt_arch.h files missing it
  218. i386 and x86_64 versions already had the .text directive; other archs
  219. did not. normally, top-level (file scope) __asm__ starts in the .text
  220. section anyway, but problems were reported with some versions of
  221. clang, and it seems preferable to set it explicitly anyway, at least
  222. for the sake of consistency between archs.
  223. commit 3b0e83264d156f9e496ab32badd89e4447b807aa
  224. Author: Rich Felker <dalias@aerifal.cx>
  225. Date: Thu May 21 17:06:28 2015 -0400
  226. remove outdated and misleading comment in iconv.c
  227. the comment claimed that EUC/GBK/Big5 are not implemented, which has
  228. been incorrect since commit 19b4a0a20efc6b9df98b6a43536ecdd628ba4643.
  229. commit 39b8ce66f2ed9c17427ec3a48be9bda29b93b9d7
  230. Author: Rich Felker <dalias@aerifal.cx>
  231. Date: Thu May 21 17:01:23 2015 -0400
  232. in iconv_open, accept "CHAR" and "" as aliases for "UTF-8"
  233. while not a requirement, it's common convention in other iconv
  234. implementations to accept "CHAR" as an alias for nl_langinfo(CODESET),
  235. meaning the encoding used for char[] strings in the current locale,
  236. and also "" as an alternate form. supporting this is not costly and
  237. improves compatibility.
  238. commit c648cefb27984db60474ec1747cbfde83c2856d0
  239. Author: Rich Felker <dalias@aerifal.cx>
  240. Date: Wed May 20 00:17:35 2015 -0400
  241. fix inconsistency in a_and and a_or argument types on x86[_64]
  242. conceptually, and on other archs, these functions take a pointer to
  243. int, but in the i386, x86_64, and x32 versions of atomic.h, they took
  244. a pointer to void instead.
  245. commit 390f93ef69153bf2087fcf3baa1776ad9a6765ab
  246. Author: Bobby Bingham <koorogi@koorogi.info>
  247. Date: Sun May 17 13:46:38 2015 -0500
  248. inline llsc atomics when building for sh4a
  249. If we're building for sh4a, the compiler is already free to use
  250. instructions only available on sh4a, so we can do the same and inline the
  251. llsc atomics. If we're building for an older processor, we still do the
  252. same runtime atomics selection as before.
  253. commit c093e2e8201524db0d638920e76bcb6b1d925f3a
  254. Author: Rich Felker <dalias@aerifal.cx>
  255. Date: Mon May 18 16:51:54 2015 -0400
  256. reprocess libc/ldso RELA relocations in stage 3 of dynamic linking
  257. this fixes a regression on powerpc that was introduced in commit
  258. f3ddd173806fd5c60b3f034528ca24542aecc5b9. global data accesses on
  259. powerpc seem to be using a translation-unit-local GOT filled via
  260. R_PPC_ADDR32 relocations rather than R_PPC_GLOB_DAT. being a non-GOT
  261. relocation type, these were not reprocessed after adding the main
  262. application and its libraries to the chain, causing libc code not to
  263. see copy relocations in the main program, and therefore to use the
  264. pre-copy-relocation addresses for global data objects (like environ).
  265. the motivation for the dynamic linker only reprocessing GOT/PLT
  266. relocation types in stage 3 is that these types always have a zero
  267. addend, making them safe to process again even if the storage for the
  268. addend has been clobbered. other relocation types which can be used
  269. for address constants in initialized data objects may have non-zero
  270. addends which will be clobbered during the first pass of relocation
  271. processing if they're stored inline (REL form) rather than out-of-line
  272. (RELA form).
  273. powerpc generally uses only RELA, so this patch is sufficient to fix
  274. the regression in practice, but is not fully general, and would not
  275. suffice if an alternate toolchain generated REL for powerpc.
  276. commit 43e9f652bf4b2195b04fc14c93db591b30a7b790
  277. Author: Rich Felker <dalias@aerifal.cx>
  278. Date: Mon May 18 12:11:25 2015 -0400
  279. fix null pointer dereference in dcngettext under specific conditions
  280. if setlocale has not been called, the current locale's messages_name
  281. may be a null pointer. the code path where it's assumed to be non-null
  282. was only reachable if bindtextdomain had already been called, which is
  283. normally not done in programs which do not call setlocale, so the
  284. omitted check went unnoticed.
  285. patch from Void Linux, with description rewritten.
  286. commit 68630b55c0c7219fe9df70dc28ffbf9efc8021d8
  287. Author: Rich Felker <dalias@aerifal.cx>
  288. Date: Sat May 16 01:53:54 2015 -0400
  289. eliminate costly tricks to avoid TLS access for current locale state
  290. the code being removed used atomics to track whether any threads might
  291. be using a locale other than the current global locale, and whether
  292. any threads might have abstract 8-bit (non-UTF-8) LC_CTYPE active, a
  293. feature which was never committed (still pending). the motivations
  294. were to support early execution prior to setup of the thread pointer,
  295. to partially support systems (ancient kernels) where thread pointer
  296. setup is not possible, and to avoid high performance cost on archs
  297. where accessing the thread pointer may be very slow.
  298. since commit 19a1fe670acb3ab9ead0fe31859ca7d4fe40dd54, the thread
  299. pointer is always available, so these hacks are no longer needed.
  300. removing them greatly simplifies the affected code.
  301. commit 707d7c30f3379441de9b320536ddfd354f4c2143
  302. Author: Rich Felker <dalias@aerifal.cx>
  303. Date: Sat May 16 01:15:40 2015 -0400
  304. in i386 __set_thread_area, don't assume %gs register is initially zero
  305. commit f630df09b1fd954eda16e2f779da0b5ecc9d80d3 added logic to handle
  306. the case where __set_thread_area is called more than once by reusing
  307. the GDT slot already in the %gs register, and only setting up a new
  308. GDT slot when %gs is zero. this created a hidden assumption that %gs
  309. is zero when a new process image starts, which is true in practice on
  310. Linux, but does not seem to be documented ABI, and fails to hold under
  311. qemu app-level emulation.
  312. while it would in theory be possible to zero %gs in the entry point
  313. code, this code is shared between static and dynamic binaries, and
  314. dynamic binaries must not clobber the value of %gs already setup by
  315. the dynamic linker.
  316. the alternative solution implemented in this commit simply uses global
  317. data to store the GDT index that's selected. __set_thread_area should
  318. only be called in the initial thread anyway (subsequent threads get
  319. their thread pointer setup by __clone), but even if it were called by
  320. another thread, it would simply read and write back the same GDT index
  321. that was already assigned to the initial thread, and thus (in the x86
  322. memory model) there is no data race.
  323. commit c0f10cf06725bd0de37f3ced7954a653bf9f1049
  324. Author: Rich Felker <dalias@aerifal.cx>
  325. Date: Thu May 14 18:51:27 2015 -0400
  326. make arm reloc.h CRTJMP macro compatible with thumb
  327. compilers targeting armv7 may be configured to produce thumb2 code
  328. instead of arm code by default, and in the future we may wish to
  329. support targets where only the thumb instruction set is available.
  330. the instructions this patch omits in thumb mode are needed only for
  331. non-thumb versions of armv4 or earlier, which are not supported by any
  332. current compilers/toolchains and thus rather pointless to have. at
  333. some point these compatibility return sequences may be removed from
  334. all asm source files, and in that case it would make sense to remove
  335. them here too and remove the ifdef.
  336. commit 83340c7a580e91b22f58321b7cf6d976af61084c
  337. Author: Rich Felker <dalias@aerifal.cx>
  338. Date: Thu May 14 18:26:16 2015 -0400
  339. make arm crt_arch.h compatible with thumb code generation
  340. compilers targeting armv7 may be configured to produce thumb2 code
  341. instead of arm code by default, and in the future we may wish to
  342. support targets where only the thumb instruction set is available.
  343. the changes made here avoid operating directly on the sp register,
  344. which is not possible in thumb code, and address an issue with the way
  345. the address of _DYNAMIC is computed.
  346. previously, the relative address of _DYNAMIC was stored with an
  347. additional offset of -8 versus the pc-relative add instruction, since
  348. on arm the pc register evaluates to ".+8". in thumb code, it instead
  349. evaluates to ".+4". both are two (normal-size) instructions beyond "."
  350. in the current execution mode, so the numbered label 2 used in the
  351. relative address expression is simply moved two instructions ahead to
  352. be compatible with both instruction sets.
  353. --- a/Makefile
  354. +++ b/Makefile
  355. @@ -44,7 +44,7 @@ ALL_INCLUDES = $(sort $(wildcard include
  356. EMPTY_LIB_NAMES = m rt pthread crypt util xnet resolv dl
  357. EMPTY_LIBS = $(EMPTY_LIB_NAMES:%=lib/lib%.a)
  358. -CRT_LIBS = lib/crt1.o lib/Scrt1.o lib/crti.o lib/crtn.o
  359. +CRT_LIBS = lib/crt1.o lib/Scrt1.o lib/rcrt1.o lib/crti.o lib/crtn.o
  360. STATIC_LIBS = lib/libc.a
  361. SHARED_LIBS = lib/libc.so
  362. TOOL_LIBS = lib/musl-gcc.specs
  363. @@ -85,11 +85,13 @@ src/internal/version.h: $(wildcard VERSI
  364. src/internal/version.lo: src/internal/version.h
  365. -src/ldso/dlstart.lo src/ldso/dynlink.lo: src/internal/dynlink.h arch/$(ARCH)/reloc.h
  366. +crt/rcrt1.o src/ldso/dlstart.lo src/ldso/dynlink.lo: src/internal/dynlink.h arch/$(ARCH)/reloc.h
  367. -crt/crt1.o crt/Scrt1.o src/ldso/dlstart.lo: $(wildcard arch/$(ARCH)/crt_arch.h)
  368. +crt/crt1.o crt/Scrt1.o crt/rcrt1.o src/ldso/dlstart.lo: $(wildcard arch/$(ARCH)/crt_arch.h)
  369. -crt/Scrt1.o: CFLAGS += -fPIC
  370. +crt/rcrt1.o: src/ldso/dlstart.c
  371. +
  372. +crt/Scrt1.o crt/rcrt1.o: CFLAGS += -fPIC
  373. OPTIMIZE_SRCS = $(wildcard $(OPTIMIZE_GLOBS:%=src/%))
  374. $(OPTIMIZE_SRCS:%.c=%.o) $(OPTIMIZE_SRCS:%.c=%.lo): CFLAGS += -O3
  375. @@ -104,7 +106,7 @@ NOSSP_SRCS = $(wildcard crt/*.c) \
  376. src/ldso/dlstart.c src/ldso/dynlink.c
  377. $(NOSSP_SRCS:%.c=%.o) $(NOSSP_SRCS:%.c=%.lo): CFLAGS += $(CFLAGS_NOSSP)
  378. -$(CRT_LIBS): CFLAGS += -DCRT
  379. +$(CRT_LIBS:lib/%=crt/%): CFLAGS += -DCRT
  380. # This incantation ensures that changes to any subarch asm files will
  381. # force the corresponding object file to be rebuilt, even if the implicit
  382. --- a/arch/aarch64/crt_arch.h
  383. +++ b/arch/aarch64/crt_arch.h
  384. @@ -1,4 +1,5 @@
  385. __asm__(
  386. +".text \n"
  387. ".global " START "\n"
  388. ".type " START ",%function\n"
  389. START ":\n"
  390. --- a/arch/arm/crt_arch.h
  391. +++ b/arch/arm/crt_arch.h
  392. @@ -1,15 +1,18 @@
  393. __asm__(
  394. +".text \n"
  395. ".global " START " \n"
  396. ".type " START ",%function \n"
  397. START ": \n"
  398. " mov fp, #0 \n"
  399. " mov lr, #0 \n"
  400. -" mov a1, sp \n"
  401. " ldr a2, 1f \n"
  402. -"2: add a2, pc, a2 \n"
  403. -" and sp, sp, #-16 \n"
  404. +" add a2, pc, a2 \n"
  405. +" mov a1, sp \n"
  406. +"2: and ip, a1, #-16 \n"
  407. +" mov sp, ip \n"
  408. " bl " START "_c \n"
  409. ".weak _DYNAMIC \n"
  410. ".hidden _DYNAMIC \n"
  411. -"1: .word _DYNAMIC-2b-8 \n"
  412. +".align 2 \n"
  413. +"1: .word _DYNAMIC-2b \n"
  414. );
  415. --- a/arch/arm/reloc.h
  416. +++ b/arch/arm/reloc.h
  417. @@ -28,5 +28,10 @@
  418. #define REL_TPOFF R_ARM_TLS_TPOFF32
  419. //#define REL_TLSDESC R_ARM_TLS_DESC
  420. +#ifdef __thumb__
  421. +#define CRTJMP(pc,sp) __asm__ __volatile__( \
  422. + "mov sp,%1 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
  423. +#else
  424. #define CRTJMP(pc,sp) __asm__ __volatile__( \
  425. "mov sp,%1 ; tst %0,#1 ; moveq pc,%0 ; bx %0" : : "r"(pc), "r"(sp) : "memory" )
  426. +#endif
  427. --- a/arch/i386/atomic.h
  428. +++ b/arch/i386/atomic.h
  429. @@ -50,16 +50,16 @@ static inline int a_cas(volatile int *p,
  430. return t;
  431. }
  432. -static inline void a_or(volatile void *p, int v)
  433. +static inline void a_or(volatile int *p, int v)
  434. {
  435. __asm__( "lock ; orl %1, %0"
  436. - : "=m"(*(int *)p) : "r"(v) : "memory" );
  437. + : "=m"(*p) : "r"(v) : "memory" );
  438. }
  439. -static inline void a_and(volatile void *p, int v)
  440. +static inline void a_and(volatile int *p, int v)
  441. {
  442. __asm__( "lock ; andl %1, %0"
  443. - : "=m"(*(int *)p) : "r"(v) : "memory" );
  444. + : "=m"(*p) : "r"(v) : "memory" );
  445. }
  446. static inline int a_swap(volatile int *x, int v)
  447. --- a/arch/microblaze/crt_arch.h
  448. +++ b/arch/microblaze/crt_arch.h
  449. @@ -1,4 +1,5 @@
  450. __asm__(
  451. +".text \n"
  452. ".global " START " \n"
  453. ".align 2 \n"
  454. START ": \n"
  455. --- a/arch/mips/crt_arch.h
  456. +++ b/arch/mips/crt_arch.h
  457. @@ -1,6 +1,7 @@
  458. __asm__(
  459. ".set push\n"
  460. ".set noreorder\n"
  461. +".text \n"
  462. ".global _" START "\n"
  463. ".global " START "\n"
  464. ".type _" START ", @function\n"
  465. @@ -21,8 +22,8 @@ __asm__(
  466. " addu $5, $5, $gp \n"
  467. " lw $25, 4($ra) \n"
  468. " addu $25, $25, $gp \n"
  469. -" subu $sp, $sp, 16 \n"
  470. +" and $sp, $sp, -8 \n"
  471. " jalr $25 \n"
  472. -" and $sp, $sp, -8 \n"
  473. +" subu $sp, $sp, 16 \n"
  474. ".set pop \n"
  475. );
  476. --- a/arch/or1k/crt_arch.h
  477. +++ b/arch/or1k/crt_arch.h
  478. @@ -1,4 +1,5 @@
  479. __asm__(
  480. +".text \n"
  481. ".global " START " \n"
  482. ".align 4 \n"
  483. START ": \n"
  484. --- a/arch/powerpc/crt_arch.h
  485. +++ b/arch/powerpc/crt_arch.h
  486. @@ -1,4 +1,5 @@
  487. __asm__(
  488. +".text \n"
  489. ".global " START " \n"
  490. ".type " START ", %function \n"
  491. START ": \n"
  492. --- a/arch/sh/atomic.h
  493. +++ b/arch/sh/atomic.h
  494. @@ -22,6 +22,88 @@ static inline int a_ctz_64(uint64_t x)
  495. return a_ctz_l(y);
  496. }
  497. +#define LLSC_CLOBBERS "r0", "t", "memory"
  498. +#define LLSC_START(mem) "synco\n" \
  499. + "0: movli.l @" mem ", r0\n"
  500. +#define LLSC_END(mem) \
  501. + "1: movco.l r0, @" mem "\n" \
  502. + " bf 0b\n" \
  503. + " synco\n"
  504. +
  505. +static inline int __sh_cas_llsc(volatile int *p, int t, int s)
  506. +{
  507. + int old;
  508. + __asm__ __volatile__(
  509. + LLSC_START("%1")
  510. + " mov r0, %0\n"
  511. + " cmp/eq %0, %2\n"
  512. + " bf 1f\n"
  513. + " mov %3, r0\n"
  514. + LLSC_END("%1")
  515. + : "=&r"(old) : "r"(p), "r"(t), "r"(s) : LLSC_CLOBBERS);
  516. + return old;
  517. +}
  518. +
  519. +static inline int __sh_swap_llsc(volatile int *x, int v)
  520. +{
  521. + int old;
  522. + __asm__ __volatile__(
  523. + LLSC_START("%1")
  524. + " mov r0, %0\n"
  525. + " mov %2, r0\n"
  526. + LLSC_END("%1")
  527. + : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
  528. + return old;
  529. +}
  530. +
  531. +static inline int __sh_fetch_add_llsc(volatile int *x, int v)
  532. +{
  533. + int old;
  534. + __asm__ __volatile__(
  535. + LLSC_START("%1")
  536. + " mov r0, %0\n"
  537. + " add %2, r0\n"
  538. + LLSC_END("%1")
  539. + : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
  540. + return old;
  541. +}
  542. +
  543. +static inline void __sh_store_llsc(volatile int *p, int x)
  544. +{
  545. + __asm__ __volatile__(
  546. + " synco\n"
  547. + " mov.l %1, @%0\n"
  548. + " synco\n"
  549. + : : "r"(p), "r"(x) : "memory");
  550. +}
  551. +
  552. +static inline void __sh_and_llsc(volatile int *x, int v)
  553. +{
  554. + __asm__ __volatile__(
  555. + LLSC_START("%0")
  556. + " and %1, r0\n"
  557. + LLSC_END("%0")
  558. + : : "r"(x), "r"(v) : LLSC_CLOBBERS);
  559. +}
  560. +
  561. +static inline void __sh_or_llsc(volatile int *x, int v)
  562. +{
  563. + __asm__ __volatile__(
  564. + LLSC_START("%0")
  565. + " or %1, r0\n"
  566. + LLSC_END("%0")
  567. + : : "r"(x), "r"(v) : LLSC_CLOBBERS);
  568. +}
  569. +
  570. +#ifdef __SH4A__
  571. +#define a_cas(p,t,s) __sh_cas_llsc(p,t,s)
  572. +#define a_swap(x,v) __sh_swap_llsc(x,v)
  573. +#define a_fetch_add(x,v) __sh_fetch_add_llsc(x, v)
  574. +#define a_store(x,v) __sh_store_llsc(x, v)
  575. +#define a_and(x,v) __sh_and_llsc(x, v)
  576. +#define a_or(x,v) __sh_or_llsc(x, v)
  577. +#else
  578. +
  579. int __sh_cas(volatile int *, int, int);
  580. int __sh_swap(volatile int *, int);
  581. int __sh_fetch_add(volatile int *, int);
  582. @@ -35,6 +117,7 @@ void __sh_or(volatile int *, int);
  583. #define a_store(x,v) __sh_store(x, v)
  584. #define a_and(x,v) __sh_and(x, v)
  585. #define a_or(x,v) __sh_or(x, v)
  586. +#endif
  587. static inline void *a_cas_p(volatile void *p, void *t, void *s)
  588. {
  589. --- a/arch/sh/crt_arch.h
  590. +++ b/arch/sh/crt_arch.h
  591. @@ -1,4 +1,5 @@
  592. __asm__(
  593. +".text \n"
  594. ".global " START " \n"
  595. START ": \n"
  596. " mova 1f, r0 \n"
  597. --- a/arch/sh/src/atomic.c
  598. +++ b/arch/sh/src/atomic.c
  599. @@ -1,12 +1,7 @@
  600. -#include "libc.h"
  601. +#ifndef __SH4A__
  602. -#define LLSC_CLOBBERS "r0", "t", "memory"
  603. -#define LLSC_START(mem) "synco\n" \
  604. - "0: movli.l @" mem ", r0\n"
  605. -#define LLSC_END(mem) \
  606. - "1: movco.l r0, @" mem "\n" \
  607. - " bf 0b\n" \
  608. - " synco\n"
  609. +#include "atomic.h"
  610. +#include "libc.h"
  611. /* gusa is a hack in the kernel which lets you create a sequence of instructions
  612. * which will be restarted if the process is preempted in the middle of the
  613. @@ -34,114 +29,74 @@
  614. int __sh_cas(volatile int *p, int t, int s)
  615. {
  616. + if (__hwcap & CPU_HAS_LLSC) return __sh_cas_llsc(p, t, s);
  617. +
  618. int old;
  619. - if (__hwcap & CPU_HAS_LLSC) {
  620. - __asm__ __volatile__(
  621. - LLSC_START("%1")
  622. - " mov r0, %0\n"
  623. - " cmp/eq %0, %2\n"
  624. - " bf 1f\n"
  625. - " mov %3, r0\n"
  626. - LLSC_END("%1")
  627. - : "=&r"(old) : "r"(p), "r"(t), "r"(s) : LLSC_CLOBBERS);
  628. - } else {
  629. - __asm__ __volatile__(
  630. - GUSA_START_EVEN("%1", "%0")
  631. - " cmp/eq %0, %2\n"
  632. - " bf 1f\n"
  633. - GUSA_END("%1", "%3")
  634. - : "=&r"(old) : "r"(p), "r"(t), "r"(s) : GUSA_CLOBBERS, "t");
  635. - }
  636. + __asm__ __volatile__(
  637. + GUSA_START_EVEN("%1", "%0")
  638. + " cmp/eq %0, %2\n"
  639. + " bf 1f\n"
  640. + GUSA_END("%1", "%3")
  641. + : "=&r"(old) : "r"(p), "r"(t), "r"(s) : GUSA_CLOBBERS, "t");
  642. return old;
  643. }
  644. int __sh_swap(volatile int *x, int v)
  645. {
  646. + if (__hwcap & CPU_HAS_LLSC) return __sh_swap_llsc(x, v);
  647. +
  648. int old;
  649. - if (__hwcap & CPU_HAS_LLSC) {
  650. - __asm__ __volatile__(
  651. - LLSC_START("%1")
  652. - " mov r0, %0\n"
  653. - " mov %2, r0\n"
  654. - LLSC_END("%1")
  655. - : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
  656. - } else {
  657. - __asm__ __volatile__(
  658. - GUSA_START_EVEN("%1", "%0")
  659. - GUSA_END("%1", "%2")
  660. - : "=&r"(old) : "r"(x), "r"(v) : GUSA_CLOBBERS);
  661. - }
  662. + __asm__ __volatile__(
  663. + GUSA_START_EVEN("%1", "%0")
  664. + GUSA_END("%1", "%2")
  665. + : "=&r"(old) : "r"(x), "r"(v) : GUSA_CLOBBERS);
  666. return old;
  667. }
  668. int __sh_fetch_add(volatile int *x, int v)
  669. {
  670. + if (__hwcap & CPU_HAS_LLSC) return __sh_fetch_add_llsc(x, v);
  671. +
  672. int old, dummy;
  673. - if (__hwcap & CPU_HAS_LLSC) {
  674. - __asm__ __volatile__(
  675. - LLSC_START("%1")
  676. - " mov r0, %0\n"
  677. - " add %2, r0\n"
  678. - LLSC_END("%1")
  679. - : "=&r"(old) : "r"(x), "r"(v) : LLSC_CLOBBERS);
  680. - } else {
  681. - __asm__ __volatile__(
  682. - GUSA_START_EVEN("%2", "%0")
  683. - " mov %0, %1\n"
  684. - " add %3, %1\n"
  685. - GUSA_END("%2", "%1")
  686. - : "=&r"(old), "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
  687. - }
  688. + __asm__ __volatile__(
  689. + GUSA_START_EVEN("%2", "%0")
  690. + " mov %0, %1\n"
  691. + " add %3, %1\n"
  692. + GUSA_END("%2", "%1")
  693. + : "=&r"(old), "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
  694. return old;
  695. }
  696. void __sh_store(volatile int *p, int x)
  697. {
  698. - if (__hwcap & CPU_HAS_LLSC) {
  699. - __asm__ __volatile__(
  700. - " synco\n"
  701. - " mov.l %1, @%0\n"
  702. - " synco\n"
  703. - : : "r"(p), "r"(x) : "memory");
  704. - } else {
  705. - __asm__ __volatile__(
  706. - " mov.l %1, @%0\n"
  707. - : : "r"(p), "r"(x) : "memory");
  708. - }
  709. + if (__hwcap & CPU_HAS_LLSC) return __sh_store_llsc(p, x);
  710. + __asm__ __volatile__(
  711. + " mov.l %1, @%0\n"
  712. + : : "r"(p), "r"(x) : "memory");
  713. }
  714. void __sh_and(volatile int *x, int v)
  715. {
  716. + if (__hwcap & CPU_HAS_LLSC) return __sh_and_llsc(x, v);
  717. +
  718. int dummy;
  719. - if (__hwcap & CPU_HAS_LLSC) {
  720. - __asm__ __volatile__(
  721. - LLSC_START("%0")
  722. - " and %1, r0\n"
  723. - LLSC_END("%0")
  724. - : : "r"(x), "r"(v) : LLSC_CLOBBERS);
  725. - } else {
  726. - __asm__ __volatile__(
  727. - GUSA_START_ODD("%1", "%0")
  728. - " and %2, %0\n"
  729. - GUSA_END("%1", "%0")
  730. - : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
  731. - }
  732. + __asm__ __volatile__(
  733. + GUSA_START_ODD("%1", "%0")
  734. + " and %2, %0\n"
  735. + GUSA_END("%1", "%0")
  736. + : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
  737. }
  738. void __sh_or(volatile int *x, int v)
  739. {
  740. + if (__hwcap & CPU_HAS_LLSC) return __sh_or_llsc(x, v);
  741. +
  742. int dummy;
  743. - if (__hwcap & CPU_HAS_LLSC) {
  744. - __asm__ __volatile__(
  745. - LLSC_START("%0")
  746. - " or %1, r0\n"
  747. - LLSC_END("%0")
  748. - : : "r"(x), "r"(v) : LLSC_CLOBBERS);
  749. - } else {
  750. - __asm__ __volatile__(
  751. - GUSA_START_ODD("%1", "%0")
  752. - " or %2, %0\n"
  753. - GUSA_END("%1", "%0")
  754. - : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
  755. - }
  756. + __asm__ __volatile__(
  757. + GUSA_START_ODD("%1", "%0")
  758. + " or %2, %0\n"
  759. + GUSA_END("%1", "%0")
  760. + : "=&r"(dummy) : "r"(x), "r"(v) : GUSA_CLOBBERS);
  761. }
  762. +
  763. +#endif
  764. --- a/arch/x32/atomic.h
  765. +++ b/arch/x32/atomic.h
  766. @@ -47,16 +47,16 @@ static inline int a_cas(volatile int *p,
  767. return t;
  768. }
  769. -static inline void a_or(volatile void *p, int v)
  770. +static inline void a_or(volatile int *p, int v)
  771. {
  772. __asm__( "lock ; or %1, %0"
  773. - : "=m"(*(int *)p) : "r"(v) : "memory" );
  774. + : "=m"(*p) : "r"(v) : "memory" );
  775. }
  776. -static inline void a_and(volatile void *p, int v)
  777. +static inline void a_and(volatile int *p, int v)
  778. {
  779. __asm__( "lock ; and %1, %0"
  780. - : "=m"(*(int *)p) : "r"(v) : "memory" );
  781. + : "=m"(*p) : "r"(v) : "memory" );
  782. }
  783. static inline int a_swap(volatile int *x, int v)
  784. --- a/arch/x86_64/atomic.h
  785. +++ b/arch/x86_64/atomic.h
  786. @@ -47,16 +47,16 @@ static inline int a_cas(volatile int *p,
  787. return t;
  788. }
  789. -static inline void a_or(volatile void *p, int v)
  790. +static inline void a_or(volatile int *p, int v)
  791. {
  792. __asm__( "lock ; or %1, %0"
  793. - : "=m"(*(int *)p) : "r"(v) : "memory" );
  794. + : "=m"(*p) : "r"(v) : "memory" );
  795. }
  796. -static inline void a_and(volatile void *p, int v)
  797. +static inline void a_and(volatile int *p, int v)
  798. {
  799. __asm__( "lock ; and %1, %0"
  800. - : "=m"(*(int *)p) : "r"(v) : "memory" );
  801. + : "=m"(*p) : "r"(v) : "memory" );
  802. }
  803. static inline int a_swap(volatile int *x, int v)
  804. --- a/configure
  805. +++ b/configure
  806. @@ -80,7 +80,7 @@ fi
  807. tryflag () {
  808. printf "checking whether compiler accepts %s... " "$2"
  809. echo "typedef int x;" > "$tmpc"
  810. -if $CC $2 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
  811. +if $CC $CFLAGS_TRY $2 -c -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
  812. printf "yes\n"
  813. eval "$1=\"\${$1} \$2\""
  814. eval "$1=\${$1# }"
  815. @@ -94,7 +94,7 @@ fi
  816. tryldflag () {
  817. printf "checking whether linker accepts %s... " "$2"
  818. echo "typedef int x;" > "$tmpc"
  819. -if $CC -nostdlib -shared "$2" -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
  820. +if $CC $LDFLAGS_TRY -nostdlib -shared "$2" -o /dev/null "$tmpc" >/dev/null 2>&1 ; then
  821. printf "yes\n"
  822. eval "$1=\"\${$1} \$2\""
  823. eval "$1=\${$1# }"
  824. @@ -113,7 +113,9 @@ CFLAGS_C99FSE=
  825. CFLAGS_AUTO=
  826. CFLAGS_MEMOPS=
  827. CFLAGS_NOSSP=
  828. +CFLAGS_TRY=
  829. LDFLAGS_AUTO=
  830. +LDFLAGS_TRY=
  831. OPTIMIZE_GLOBS=
  832. prefix=/usr/local/musl
  833. exec_prefix='$(prefix)'
  834. @@ -205,6 +207,14 @@ exit 1
  835. fi
  836. #
  837. +# Figure out options to force errors on unknown flags.
  838. +#
  839. +tryflag CFLAGS_TRY -Werror=unknown-warning-option
  840. +tryflag CFLAGS_TRY -Werror=unused-command-line-argument
  841. +tryldflag LDFLAGS_TRY -Werror=unknown-warning-option
  842. +tryldflag LDFLAGS_TRY -Werror=unused-command-line-argument
  843. +
  844. +#
  845. # Need to know if the compiler is gcc to decide whether to build the
  846. # musl-gcc wrapper, and for critical bug detection in some gcc versions.
  847. #
  848. --- a/crt/mips/crt1.s
  849. +++ b/crt/mips/crt1.s
  850. @@ -4,6 +4,8 @@
  851. .weak _fini
  852. .global __start
  853. .global _start
  854. +.type __start,@function
  855. +.type _start,@function
  856. __start:
  857. _start:
  858. subu $fp, $fp, $fp # Zero the frame pointer.
  859. --- a/crt/mips/crti.s
  860. +++ b/crt/mips/crti.s
  861. @@ -2,6 +2,7 @@
  862. .section .init
  863. .global _init
  864. +.type _init,@function
  865. .align 2
  866. _init:
  867. subu $sp,$sp,32
  868. @@ -10,6 +11,7 @@ _init:
  869. .section .fini
  870. .global _fini
  871. +.type _fini,@function
  872. .align 2
  873. _fini:
  874. subu $sp,$sp,32
  875. --- /dev/null
  876. +++ b/crt/rcrt1.c
  877. @@ -0,0 +1,15 @@
  878. +#define SHARED
  879. +#define START "_start"
  880. +#define _dlstart_c _start_c
  881. +#include "../src/ldso/dlstart.c"
  882. +
  883. +int main();
  884. +void _init() __attribute__((weak));
  885. +void _fini() __attribute__((weak));
  886. +_Noreturn int __libc_start_main(int (*)(), int, char **,
  887. + void (*)(), void(*)(), void(*)());
  888. +
  889. +_Noreturn void __dls2(unsigned char *base, size_t *sp)
  890. +{
  891. + __libc_start_main(main, *sp, (void *)(sp+1), _init, _fini, 0);
  892. +}
  893. --- a/include/sys/resource.h
  894. +++ b/include/sys/resource.h
  895. @@ -96,6 +96,9 @@ int prlimit(pid_t, int, const struct rli
  896. #define RLIM_NLIMITS RLIMIT_NLIMITS
  897. #if defined(_LARGEFILE64_SOURCE) || defined(_GNU_SOURCE)
  898. +#define RLIM64_INFINITY RLIM_INFINITY
  899. +#define RLIM64_SAVED_CUR RLIM_SAVED_CUR
  900. +#define RLIM64_SAVED_MAX RLIM_SAVED_MAX
  901. #define getrlimit64 getrlimit
  902. #define setrlimit64 setrlimit
  903. #define rlimit64 rlimit
  904. --- a/src/internal/dynlink.h
  905. +++ b/src/internal/dynlink.h
  906. @@ -51,7 +51,7 @@ enum {
  907. #define AUX_CNT 32
  908. #define DYN_CNT 32
  909. -typedef void (*stage2_func)(unsigned char *);
  910. +typedef void (*stage2_func)(unsigned char *, size_t *);
  911. typedef _Noreturn void (*stage3_func)(size_t *);
  912. #endif
  913. --- a/src/internal/libc.h
  914. +++ b/src/internal/libc.h
  915. @@ -8,9 +8,7 @@
  916. struct __locale_map;
  917. struct __locale_struct {
  918. - volatile int ctype_utf8;
  919. - char *messages_name;
  920. - struct __locale_map *volatile cat[4];
  921. + const struct __locale_map *volatile cat[6];
  922. };
  923. struct __libc {
  924. @@ -23,8 +21,6 @@ struct __libc {
  925. volatile int ofl_lock[2];
  926. size_t tls_size;
  927. size_t page_size;
  928. - volatile int uselocale_cnt;
  929. - volatile int bytelocale_cnt_minus_1;
  930. struct __locale_struct global_locale;
  931. };
  932. --- a/src/internal/locale_impl.h
  933. +++ b/src/internal/locale_impl.h
  934. @@ -9,22 +9,20 @@ struct __locale_map {
  935. const void *map;
  936. size_t map_size;
  937. char name[LOCALE_NAME_MAX+1];
  938. - struct __locale_map *next;
  939. + const struct __locale_map *next;
  940. };
  941. -int __setlocalecat(locale_t, int, const char *);
  942. +const struct __locale_map *__get_locale(int, const char *);
  943. const char *__mo_lookup(const void *, size_t, const char *);
  944. const char *__lctrans(const char *, const struct __locale_map *);
  945. const char *__lctrans_cur(const char *);
  946. -#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)-2])
  947. +#define LCTRANS(msg, lc, loc) __lctrans(msg, (loc)->cat[(lc)])
  948. #define LCTRANS_CUR(msg) __lctrans_cur(msg)
  949. -#define CURRENT_LOCALE \
  950. - (libc.uselocale_cnt ? __pthread_self()->locale : &libc.global_locale)
  951. +#define CURRENT_LOCALE (__pthread_self()->locale)
  952. -#define CURRENT_UTF8 \
  953. - (libc.bytelocale_cnt_minus_1<0 || __pthread_self()->locale->ctype_utf8)
  954. +#define CURRENT_UTF8 (!!__pthread_self()->locale->cat[LC_CTYPE])
  955. #undef MB_CUR_MAX
  956. #define MB_CUR_MAX (CURRENT_UTF8 ? 4 : 1)
  957. --- a/src/ldso/dlstart.c
  958. +++ b/src/ldso/dlstart.c
  959. @@ -56,31 +56,22 @@ void _dlstart_c(size_t *sp, size_t *dynv
  960. for (i=0; i<local_cnt; i++) got[i] += (size_t)base;
  961. }
  962. - /* The use of the reloc_info structure and nested loops is a trick
  963. - * to work around the fact that we can't necessarily make function
  964. - * calls yet. Each struct in the array serves like the arguments
  965. - * to a function call. */
  966. - struct {
  967. - void *rel;
  968. - size_t size;
  969. - size_t stride;
  970. - } reloc_info[] = {
  971. - { base+dyn[DT_JMPREL], dyn[DT_PLTRELSZ], 2+(dyn[DT_PLTREL]==DT_RELA) },
  972. - { base+dyn[DT_REL], dyn[DT_RELSZ], 2 },
  973. - { base+dyn[DT_RELA], dyn[DT_RELASZ], 3 },
  974. - { 0, 0, 0 }
  975. - };
  976. -
  977. - for (i=0; reloc_info[i].stride; i++) {
  978. - size_t *rel = reloc_info[i].rel;
  979. - size_t rel_size = reloc_info[i].size;
  980. - size_t stride = reloc_info[i].stride;
  981. - for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
  982. - if (!IS_RELATIVE(rel[1])) continue;
  983. - size_t *rel_addr = (void *)(base + rel[0]);
  984. - size_t addend = stride==3 ? rel[2] : *rel_addr;
  985. - *rel_addr = (size_t)base + addend;
  986. - }
  987. + size_t *rel, rel_size;
  988. +
  989. + rel = (void *)(base+dyn[DT_REL]);
  990. + rel_size = dyn[DT_RELSZ];
  991. + for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t)) {
  992. + if (!IS_RELATIVE(rel[1])) continue;
  993. + size_t *rel_addr = (void *)(base + rel[0]);
  994. + *rel_addr += (size_t)base;
  995. + }
  996. +
  997. + rel = (void *)(base+dyn[DT_RELA]);
  998. + rel_size = dyn[DT_RELASZ];
  999. + for (; rel_size; rel+=3, rel_size-=3*sizeof(size_t)) {
  1000. + if (!IS_RELATIVE(rel[1])) continue;
  1001. + size_t *rel_addr = (void *)(base + rel[0]);
  1002. + *rel_addr = (size_t)base + rel[2];
  1003. }
  1004. const char *strings = (void *)(base + dyn[DT_STRTAB]);
  1005. @@ -93,16 +84,7 @@ void _dlstart_c(size_t *sp, size_t *dynv
  1006. && s[3]=='l' && s[4]=='s' && s[5]=='2' && !s[6])
  1007. break;
  1008. }
  1009. - ((stage2_func)(base + syms[i].st_value))(base);
  1010. -
  1011. - /* Call dynamic linker stage-3, __dls3 */
  1012. - for (i=0; ;i++) {
  1013. - const char *s = strings + syms[i].st_name;
  1014. - if (s[0]=='_' && s[1]=='_' && s[2]=='d'
  1015. - && s[3]=='l' && s[4]=='s' && s[5]=='3' && !s[6])
  1016. - break;
  1017. - }
  1018. - ((stage3_func)(base + syms[i].st_value))(sp);
  1019. + ((stage2_func)(base + syms[i].st_value))(base, sp);
  1020. }
  1021. #endif
  1022. --- a/src/ldso/dynlink.c
  1023. +++ b/src/ldso/dynlink.c
  1024. @@ -74,7 +74,6 @@ struct dso {
  1025. volatile int new_dtv_idx, new_tls_idx;
  1026. struct td_index *td_index;
  1027. struct dso *fini_next;
  1028. - int rel_early_relative, rel_update_got;
  1029. char *shortname;
  1030. char buf[];
  1031. };
  1032. @@ -96,6 +95,9 @@ static struct builtin_tls {
  1033. } builtin_tls[1];
  1034. #define MIN_TLS_ALIGN offsetof(struct builtin_tls, pt)
  1035. +#define ADDEND_LIMIT 4096
  1036. +static size_t *saved_addends, *apply_addends_to;
  1037. +
  1038. static struct dso ldso;
  1039. static struct dso *head, *tail, *fini_head;
  1040. static char *env_path, *sys_path;
  1041. @@ -256,10 +258,19 @@ static void do_relocs(struct dso *dso, s
  1042. size_t sym_val;
  1043. size_t tls_val;
  1044. size_t addend;
  1045. + int skip_relative = 0, reuse_addends = 0, save_slot = 0;
  1046. +
  1047. + if (dso == &ldso) {
  1048. + /* Only ldso's REL table needs addend saving/reuse. */
  1049. + if (rel == apply_addends_to)
  1050. + reuse_addends = 1;
  1051. + skip_relative = 1;
  1052. + }
  1053. for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) {
  1054. - if (dso->rel_early_relative && IS_RELATIVE(rel[1])) continue;
  1055. + if (skip_relative && IS_RELATIVE(rel[1])) continue;
  1056. type = R_TYPE(rel[1]);
  1057. + if (type == REL_NONE) continue;
  1058. sym_index = R_SYM(rel[1]);
  1059. reloc_addr = (void *)(base + rel[0]);
  1060. if (sym_index) {
  1061. @@ -280,12 +291,20 @@ static void do_relocs(struct dso *dso, s
  1062. def.dso = dso;
  1063. }
  1064. - int gotplt = (type == REL_GOT || type == REL_PLT);
  1065. - if (dso->rel_update_got && !gotplt) continue;
  1066. -
  1067. - addend = stride>2 ? rel[2]
  1068. - : gotplt || type==REL_COPY ? 0
  1069. - : *reloc_addr;
  1070. + if (stride > 2) {
  1071. + addend = rel[2];
  1072. + } else if (type==REL_GOT || type==REL_PLT|| type==REL_COPY) {
  1073. + addend = 0;
  1074. + } else if (reuse_addends) {
  1075. + /* Save original addend in stage 2 where the dso
  1076. + * chain consists of just ldso; otherwise read back
  1077. + * saved addend since the inline one was clobbered. */
  1078. + if (head==&ldso)
  1079. + saved_addends[save_slot] = *reloc_addr;
  1080. + addend = saved_addends[save_slot++];
  1081. + } else {
  1082. + addend = *reloc_addr;
  1083. + }
  1084. sym_val = def.sym ? (size_t)def.dso->base+def.sym->st_value : 0;
  1085. tls_val = def.sym ? def.sym->st_value : 0;
  1086. @@ -879,7 +898,7 @@ static void do_mips_relocs(struct dso *p
  1087. size_t i, j, rel[2];
  1088. unsigned char *base = p->base;
  1089. i=0; search_vec(p->dynv, &i, DT_MIPS_LOCAL_GOTNO);
  1090. - if (p->rel_early_relative) {
  1091. + if (p==&ldso) {
  1092. got += i;
  1093. } else {
  1094. while (i--) *got++ += (size_t)base;
  1095. @@ -1116,7 +1135,7 @@ static void update_tls_size()
  1096. * linker itself, but some of the relocations performed may need to be
  1097. * replaced later due to copy relocations in the main program. */
  1098. -void __dls2(unsigned char *base)
  1099. +void __dls2(unsigned char *base, size_t *sp)
  1100. {
  1101. Ehdr *ehdr = (void *)base;
  1102. ldso.base = base;
  1103. @@ -1125,15 +1144,35 @@ void __dls2(unsigned char *base)
  1104. ldso.phnum = ehdr->e_phnum;
  1105. ldso.phdr = (void *)(base + ehdr->e_phoff);
  1106. ldso.phentsize = ehdr->e_phentsize;
  1107. - ldso.rel_early_relative = 1;
  1108. kernel_mapped_dso(&ldso);
  1109. decode_dyn(&ldso);
  1110. + /* Prepare storage for to save clobbered REL addends so they
  1111. + * can be reused in stage 3. There should be very few. If
  1112. + * something goes wrong and there are a huge number, abort
  1113. + * instead of risking stack overflow. */
  1114. + size_t dyn[DYN_CNT];
  1115. + decode_vec(ldso.dynv, dyn, DYN_CNT);
  1116. + size_t *rel = (void *)(base+dyn[DT_REL]);
  1117. + size_t rel_size = dyn[DT_RELSZ];
  1118. + size_t symbolic_rel_cnt = 0;
  1119. + apply_addends_to = rel;
  1120. + for (; rel_size; rel+=2, rel_size-=2*sizeof(size_t))
  1121. + if (!IS_RELATIVE(rel[1])) symbolic_rel_cnt++;
  1122. + if (symbolic_rel_cnt >= ADDEND_LIMIT) a_crash();
  1123. + size_t addends[symbolic_rel_cnt+1];
  1124. + saved_addends = addends;
  1125. +
  1126. head = &ldso;
  1127. reloc_all(&ldso);
  1128. ldso.relocated = 0;
  1129. - ldso.rel_update_got = 1;
  1130. +
  1131. + /* Call dynamic linker stage-3, __dls3, looking it up
  1132. + * symbolically as a barrier against moving the address
  1133. + * load across the above relocation processing. */
  1134. + struct symdef dls3_def = find_sym(&ldso, "__dls3", 0);
  1135. + ((stage3_func)(ldso.base+dls3_def.sym->st_value))(sp);
  1136. }
  1137. /* Stage 3 of the dynamic linker is called with the dynamic linker/libc
  1138. --- a/src/locale/__lctrans.c
  1139. +++ b/src/locale/__lctrans.c
  1140. @@ -16,5 +16,5 @@ const char *__lctrans(const char *msg, c
  1141. const char *__lctrans_cur(const char *msg)
  1142. {
  1143. - return __lctrans_impl(msg, CURRENT_LOCALE->cat[LC_MESSAGES-2]);
  1144. + return __lctrans_impl(msg, CURRENT_LOCALE->cat[LC_MESSAGES]);
  1145. }
  1146. --- a/src/locale/__setlocalecat.c
  1147. +++ /dev/null
  1148. @@ -1,111 +0,0 @@
  1149. -#include <locale.h>
  1150. -#include <string.h>
  1151. -#include "locale_impl.h"
  1152. -#include "libc.h"
  1153. -#include "atomic.h"
  1154. -
  1155. -const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
  1156. -{
  1157. - const char *trans = 0;
  1158. - if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg);
  1159. - return trans ? trans : msg;
  1160. -}
  1161. -
  1162. -const unsigned char *__map_file(const char *, size_t *);
  1163. -int __munmap(void *, size_t);
  1164. -char *__strchrnul(const char *, int);
  1165. -
  1166. -static struct __locale_map *findlocale(const char *name, size_t n)
  1167. -{
  1168. - static void *volatile loc_head;
  1169. - struct __locale_map *p, *new, *old_head;
  1170. - const char *path = 0, *z;
  1171. - char buf[256];
  1172. - size_t l;
  1173. - const void *map;
  1174. - size_t map_size;
  1175. -
  1176. - for (p=loc_head; p; p=p->next)
  1177. - if (!strcmp(name, p->name)) return p;
  1178. -
  1179. - if (!libc.secure) path = getenv("MUSL_LOCPATH");
  1180. - /* FIXME: add a default path? */
  1181. - if (!path) return 0;
  1182. -
  1183. - for (; *path; path=z+!!*z) {
  1184. - z = __strchrnul(path, ':');
  1185. - l = z - path - !!*z;
  1186. - if (l >= sizeof buf - n - 2) continue;
  1187. - memcpy(buf, path, l);
  1188. - buf[l] = '/';
  1189. - memcpy(buf+l+1, name, n);
  1190. - buf[l+1+n] = 0;
  1191. - map = __map_file(buf, &map_size);
  1192. - if (map) {
  1193. - new = malloc(sizeof *new);
  1194. - if (!new) {
  1195. - __munmap((void *)map, map_size);
  1196. - return 0;
  1197. - }
  1198. - new->map = map;
  1199. - new->map_size = map_size;
  1200. - memcpy(new->name, name, n);
  1201. - new->name[n] = 0;
  1202. - do {
  1203. - old_head = loc_head;
  1204. - new->next = old_head;
  1205. - } while (a_cas_p(&loc_head, old_head, new) != old_head);
  1206. - return new;
  1207. - }
  1208. - }
  1209. - return 0;
  1210. -}
  1211. -
  1212. -static const char envvars[][12] = {
  1213. - "LC_CTYPE",
  1214. - "LC_NUMERIC",
  1215. - "LC_TIME",
  1216. - "LC_COLLATE",
  1217. - "LC_MONETARY",
  1218. - "LC_MESSAGES",
  1219. -};
  1220. -
  1221. -int __setlocalecat(locale_t loc, int cat, const char *val)
  1222. -{
  1223. - if (!*val) {
  1224. - (val = getenv("LC_ALL")) && *val ||
  1225. - (val = getenv(envvars[cat])) && *val ||
  1226. - (val = getenv("LANG")) && *val ||
  1227. - (val = "C.UTF-8");
  1228. - }
  1229. -
  1230. - size_t n;
  1231. - for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);
  1232. - if (val[0]=='.' || val[n]) val = "C.UTF-8";
  1233. - int builtin = (val[0]=='C' && !val[1])
  1234. - || !strcmp(val, "C.UTF-8")
  1235. - || !strcmp(val, "POSIX");
  1236. - struct __locale_map *data, *old;
  1237. -
  1238. - switch (cat) {
  1239. - case LC_CTYPE:
  1240. - a_store(&loc->ctype_utf8, !builtin || val[1]=='.');
  1241. - break;
  1242. - case LC_MESSAGES:
  1243. - if (builtin) {
  1244. - loc->messages_name[0] = 0;
  1245. - } else {
  1246. - memcpy(loc->messages_name, val, n);
  1247. - loc->messages_name[n] = 0;
  1248. - }
  1249. - /* fall through */
  1250. - default:
  1251. - data = builtin ? 0 : findlocale(val, n);
  1252. - if (data == loc->cat[cat-2]) break;
  1253. - do old = loc->cat[cat-2];
  1254. - while (a_cas_p(&loc->cat[cat-2], old, data) != old);
  1255. - case LC_NUMERIC:
  1256. - break;
  1257. - }
  1258. - return 0;
  1259. -}
  1260. --- a/src/locale/dcngettext.c
  1261. +++ b/src/locale/dcngettext.c
  1262. @@ -84,13 +84,15 @@ char *bindtextdomain(const char *domainn
  1263. }
  1264. static const char catnames[][12] = {
  1265. + "LC_CTYPE",
  1266. + "LC_NUMERIC",
  1267. "LC_TIME",
  1268. "LC_COLLATE",
  1269. "LC_MONETARY",
  1270. "LC_MESSAGES",
  1271. };
  1272. -static const char catlens[] = { 7, 10, 11, 11 };
  1273. +static const char catlens[] = { 8, 10, 7, 10, 11, 11 };
  1274. struct msgcat {
  1275. struct msgcat *next;
  1276. @@ -117,10 +119,12 @@ char *dcngettext(const char *domainname,
  1277. static struct msgcat *volatile cats;
  1278. struct msgcat *p;
  1279. struct __locale_struct *loc = CURRENT_LOCALE;
  1280. - struct __locale_map *lm;
  1281. + const struct __locale_map *lm;
  1282. const char *dirname, *locname, *catname;
  1283. size_t dirlen, loclen, catlen, domlen;
  1284. + if ((unsigned)category >= LC_ALL) goto notrans;
  1285. +
  1286. if (!domainname) domainname = __gettextdomain();
  1287. domlen = strlen(domainname);
  1288. @@ -129,25 +133,15 @@ char *dcngettext(const char *domainname,
  1289. dirname = gettextdir(domainname, &dirlen);
  1290. if (!dirname) goto notrans;
  1291. - switch (category) {
  1292. - case LC_MESSAGES:
  1293. - locname = loc->messages_name;
  1294. - if (!*locname) goto notrans;
  1295. - break;
  1296. - case LC_TIME:
  1297. - case LC_MONETARY:
  1298. - case LC_COLLATE:
  1299. - lm = loc->cat[category-2];
  1300. - if (!lm) goto notrans;
  1301. - locname = lm->name;
  1302. - break;
  1303. - default:
  1304. + lm = loc->cat[category];
  1305. + if (!lm) {
  1306. notrans:
  1307. return (char *) ((n == 1) ? msgid1 : msgid2);
  1308. }
  1309. + locname = lm->name;
  1310. - catname = catnames[category-2];
  1311. - catlen = catlens[category-2];
  1312. + catname = catnames[category];
  1313. + catlen = catlens[category];
  1314. loclen = strlen(locname);
  1315. size_t namelen = dirlen+1 + loclen+1 + catlen+1 + domlen+3;
  1316. --- a/src/locale/duplocale.c
  1317. +++ b/src/locale/duplocale.c
  1318. @@ -5,17 +5,10 @@
  1319. locale_t __duplocale(locale_t old)
  1320. {
  1321. - locale_t new = calloc(1, sizeof *new + LOCALE_NAME_MAX + 1);
  1322. + locale_t new = malloc(sizeof *new);
  1323. if (!new) return 0;
  1324. - new->messages_name = (void *)(new+1);
  1325. -
  1326. if (old == LC_GLOBAL_LOCALE) old = &libc.global_locale;
  1327. - new->ctype_utf8 = old->ctype_utf8;
  1328. - if (old->messages_name)
  1329. - strcpy(new->messages_name, old->messages_name);
  1330. -
  1331. - for (size_t i=0; i<sizeof new->cat/sizeof new->cat[0]; i++)
  1332. - new->cat[i] = old->cat[i];
  1333. + *new = *old;
  1334. return new;
  1335. }
  1336. --- a/src/locale/freelocale.c
  1337. +++ b/src/locale/freelocale.c
  1338. @@ -2,9 +2,11 @@
  1339. #include "locale_impl.h"
  1340. #include "libc.h"
  1341. +int __loc_is_allocated(locale_t);
  1342. +
  1343. void freelocale(locale_t l)
  1344. {
  1345. - free(l);
  1346. + if (__loc_is_allocated(l)) free(l);
  1347. }
  1348. weak_alias(freelocale, __freelocale);
  1349. --- a/src/locale/iconv.c
  1350. +++ b/src/locale/iconv.c
  1351. @@ -23,19 +23,13 @@
  1352. #define BIG5 0340
  1353. #define EUC_KR 0350
  1354. -/* FIXME: these are not implemented yet
  1355. - * EUC: A1-FE A1-FE
  1356. - * GBK: 81-FE 40-7E,80-FE
  1357. - * Big5: A1-FE 40-7E,A1-FE
  1358. - */
  1359. -
  1360. /* Definitions of charmaps. Each charmap consists of:
  1361. * 1. Empty-string-terminated list of null-terminated aliases.
  1362. * 2. Special type code or number of elided entries.
  1363. * 3. Character table (size determined by field 2). */
  1364. static const unsigned char charmaps[] =
  1365. -"utf8\0\0\310"
  1366. +"utf8\0char\0\0\310"
  1367. "wchart\0\0\306"
  1368. "ucs2\0ucs2be\0\0\304"
  1369. "ucs2le\0\0\305"
  1370. @@ -90,6 +84,7 @@ static int fuzzycmp(const unsigned char
  1371. static size_t find_charmap(const void *name)
  1372. {
  1373. const unsigned char *s;
  1374. + if (!*(char *)name) name=charmaps; /* "utf8" */
  1375. for (s=charmaps; *s; ) {
  1376. if (!fuzzycmp(name, s)) {
  1377. for (; *s; s+=strlen((void *)s)+1);
  1378. --- /dev/null
  1379. +++ b/src/locale/locale_map.c
  1380. @@ -0,0 +1,124 @@
  1381. +#include <locale.h>
  1382. +#include <string.h>
  1383. +#include "locale_impl.h"
  1384. +#include "libc.h"
  1385. +#include "atomic.h"
  1386. +
  1387. +const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
  1388. +{
  1389. + const char *trans = 0;
  1390. + if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg);
  1391. + return trans ? trans : msg;
  1392. +}
  1393. +
  1394. +const unsigned char *__map_file(const char *, size_t *);
  1395. +int __munmap(void *, size_t);
  1396. +char *__strchrnul(const char *, int);
  1397. +
  1398. +static const char envvars[][12] = {
  1399. + "LC_CTYPE",
  1400. + "LC_NUMERIC",
  1401. + "LC_TIME",
  1402. + "LC_COLLATE",
  1403. + "LC_MONETARY",
  1404. + "LC_MESSAGES",
  1405. +};
  1406. +
  1407. +static const uint32_t empty_mo[] = { 0x950412de, 0, -1, -1, -1 };
  1408. +
  1409. +const struct __locale_map __c_dot_utf8 = {
  1410. + .map = empty_mo,
  1411. + .map_size = sizeof empty_mo,
  1412. + .name = "C.UTF-8"
  1413. +};
  1414. +
  1415. +const struct __locale_map *__get_locale(int cat, const char *val)
  1416. +{
  1417. + static int lock[2];
  1418. + static void *volatile loc_head;
  1419. + const struct __locale_map *p;
  1420. + struct __locale_map *new = 0;
  1421. + const char *path = 0, *z;
  1422. + char buf[256];
  1423. + size_t l, n;
  1424. +
  1425. + if (!*val) {
  1426. + (val = getenv("LC_ALL")) && *val ||
  1427. + (val = getenv(envvars[cat])) && *val ||
  1428. + (val = getenv("LANG")) && *val ||
  1429. + (val = "C.UTF-8");
  1430. + }
  1431. +
  1432. + /* Limit name length and forbid leading dot or any slashes. */
  1433. + for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);
  1434. + if (val[0]=='.' || val[n]) val = "C.UTF-8";
  1435. + int builtin = (val[0]=='C' && !val[1])
  1436. + || !strcmp(val, "C.UTF-8")
  1437. + || !strcmp(val, "POSIX");
  1438. +
  1439. + if (builtin) {
  1440. + if (cat == LC_CTYPE && val[1]=='.')
  1441. + return (void *)&__c_dot_utf8;
  1442. + return 0;
  1443. + }
  1444. +
  1445. + for (p=loc_head; p; p=p->next)
  1446. + if (!strcmp(val, p->name)) return p;
  1447. +
  1448. + LOCK(lock);
  1449. +
  1450. + for (p=loc_head; p; p=p->next)
  1451. + if (!strcmp(val, p->name)) {
  1452. + UNLOCK(lock);
  1453. + return p;
  1454. + }
  1455. +
  1456. + if (!libc.secure) path = getenv("MUSL_LOCPATH");
  1457. + /* FIXME: add a default path? */
  1458. +
  1459. + if (path) for (; *path; path=z+!!*z) {
  1460. + z = __strchrnul(path, ':');
  1461. + l = z - path - !!*z;
  1462. + if (l >= sizeof buf - n - 2) continue;
  1463. + memcpy(buf, path, l);
  1464. + buf[l] = '/';
  1465. + memcpy(buf+l+1, val, n);
  1466. + buf[l+1+n] = 0;
  1467. + size_t map_size;
  1468. + const void *map = __map_file(buf, &map_size);
  1469. + if (map) {
  1470. + new = malloc(sizeof *new);
  1471. + if (!new) {
  1472. + __munmap((void *)map, map_size);
  1473. + break;
  1474. + }
  1475. + new->map = map;
  1476. + new->map_size = map_size;
  1477. + memcpy(new->name, val, n);
  1478. + new->name[n] = 0;
  1479. + new->next = loc_head;
  1480. + loc_head = new;
  1481. + break;
  1482. + }
  1483. + }
  1484. +
  1485. + /* If no locale definition was found, make a locale map
  1486. + * object anyway to store the name, which is kept for the
  1487. + * sake of being able to do message translations at the
  1488. + * application level. */
  1489. + if (!new && (new = malloc(sizeof *new))) {
  1490. + new->map = empty_mo;
  1491. + new->map_size = sizeof empty_mo;
  1492. + memcpy(new->name, val, n);
  1493. + new->name[n] = 0;
  1494. + new->next = loc_head;
  1495. + loc_head = new;
  1496. + }
  1497. +
  1498. + /* For LC_CTYPE, never return a null pointer unless the
  1499. + * requested name was "C" or "POSIX". */
  1500. + if (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8;
  1501. +
  1502. + UNLOCK(lock);
  1503. + return new;
  1504. +}
  1505. --- a/src/locale/newlocale.c
  1506. +++ b/src/locale/newlocale.c
  1507. @@ -3,22 +3,52 @@
  1508. #include "locale_impl.h"
  1509. #include "libc.h"
  1510. +extern const struct __locale_map __c_dot_utf8;
  1511. +
  1512. +static const struct __locale_struct c_locale = { 0 };
  1513. +static const struct __locale_struct c_dot_utf8_locale = {
  1514. + .cat[LC_CTYPE] = &__c_dot_utf8
  1515. +};
  1516. +
  1517. +int __loc_is_allocated(locale_t loc)
  1518. +{
  1519. + return loc && loc != &c_locale && loc != &c_dot_utf8_locale;
  1520. +}
  1521. +
  1522. locale_t __newlocale(int mask, const char *name, locale_t loc)
  1523. {
  1524. - int i;
  1525. + int i, j;
  1526. + struct __locale_struct tmp;
  1527. + const struct __locale_map *lm;
  1528. - if (!loc) {
  1529. - loc = calloc(1, sizeof *loc + LOCALE_NAME_MAX + 1);
  1530. - if (!loc) return 0;
  1531. - loc->messages_name = (void *)(loc+1);
  1532. + /* For locales with allocated storage, modify in-place. */
  1533. + if (__loc_is_allocated(loc)) {
  1534. for (i=0; i<LC_ALL; i++)
  1535. - if (!(mask & (1<<i)))
  1536. - __setlocalecat(loc, i, "");
  1537. + if (mask & (1<<i))
  1538. + loc->cat[i] = __get_locale(i, name);
  1539. + return loc;
  1540. + }
  1541. +
  1542. + /* Otherwise, build a temporary locale object, which will only
  1543. + * be instantiated in allocated storage if it does not match
  1544. + * one of the built-in static locales. This makes the common
  1545. + * usage case for newlocale, getting a C locale with predictable
  1546. + * behavior, very fast, and more importantly, fail-safe. */
  1547. + for (j=i=0; i<LC_ALL; i++) {
  1548. + if (loc && !(mask & (1<<i)))
  1549. + lm = loc->cat[i];
  1550. + else
  1551. + lm = __get_locale(i, mask & (1<<i) ? name : "");
  1552. + if (lm) j++;
  1553. + tmp.cat[i] = lm;
  1554. }
  1555. - for (i=0; i<LC_ALL; i++)
  1556. - if (mask & (1<<i))
  1557. - __setlocalecat(loc, i, name);
  1558. + if (!j)
  1559. + return (locale_t)&c_locale;
  1560. + if (j==1 && tmp.cat[LC_CTYPE]==c_dot_utf8_locale.cat[LC_CTYPE])
  1561. + return (locale_t)&c_dot_utf8_locale;
  1562. +
  1563. + if ((loc = malloc(sizeof *loc))) *loc = tmp;
  1564. return loc;
  1565. }
  1566. --- a/src/locale/setlocale.c
  1567. +++ b/src/locale/setlocale.c
  1568. @@ -5,73 +5,66 @@
  1569. #include "libc.h"
  1570. #include "atomic.h"
  1571. -static char buf[2+4*(LOCALE_NAME_MAX+1)];
  1572. +static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
  1573. -char *setlocale(int cat, const char *name)
  1574. +static char *setlocale_one_unlocked(int cat, const char *name)
  1575. {
  1576. - struct __locale_map *lm;
  1577. - int i, j;
  1578. + const struct __locale_map *lm;
  1579. - if (!libc.global_locale.messages_name) {
  1580. - libc.global_locale.messages_name =
  1581. - buf + 2 + 3*(LOCALE_NAME_MAX+1);
  1582. - }
  1583. + if (name) libc.global_locale.cat[cat] = lm = __get_locale(cat, name);
  1584. + else lm = libc.global_locale.cat[cat];
  1585. +
  1586. + return lm ? (char *)lm->name : "C";
  1587. +}
  1588. +
  1589. +char *__strchrnul(const char *, int);
  1590. +
  1591. +char *setlocale(int cat, const char *name)
  1592. +{
  1593. + static volatile int lock[2];
  1594. if ((unsigned)cat > LC_ALL) return 0;
  1595. + LOCK(lock);
  1596. +
  1597. /* For LC_ALL, setlocale is required to return a string which
  1598. * encodes the current setting for all categories. The format of
  1599. * this string is unspecified, and only the following code, which
  1600. * performs both the serialization and deserialization, depends
  1601. * on the format, so it can easily be changed if needed. */
  1602. if (cat == LC_ALL) {
  1603. + int i;
  1604. if (name) {
  1605. - char part[LOCALE_NAME_MAX+1];
  1606. - if (name[0] && name[1]==';'
  1607. - && strlen(name) > 2 + 3*(LOCALE_NAME_MAX+1)) {
  1608. - part[0] = name[0];
  1609. - part[1] = 0;
  1610. - setlocale(LC_CTYPE, part);
  1611. - part[LOCALE_NAME_MAX] = 0;
  1612. - for (i=LC_TIME; i<LC_MESSAGES; i++) {
  1613. - memcpy(part, name + 2 + (i-2)*(LOCALE_NAME_MAX+1), LOCALE_NAME_MAX);
  1614. - for (j=LOCALE_NAME_MAX-1; j && part[j]==';'; j--)
  1615. - part[j] = 0;
  1616. - setlocale(i, part);
  1617. + char part[LOCALE_NAME_MAX+1] = "C.UTF-8";
  1618. + const char *p = name;
  1619. + for (i=0; i<LC_ALL; i++) {
  1620. + const char *z = __strchrnul(p, ';');
  1621. + if (z-p <= LOCALE_NAME_MAX) {
  1622. + memcpy(part, p, z-p);
  1623. + part[z-p] = 0;
  1624. + if (*z) p = z+1;
  1625. }
  1626. - setlocale(LC_MESSAGES, name + 2 + 3*(LOCALE_NAME_MAX+1));
  1627. - } else {
  1628. - for (i=0; i<LC_ALL; i++)
  1629. - setlocale(i, name);
  1630. + setlocale_one_unlocked(i, part);
  1631. }
  1632. }
  1633. - memset(buf, ';', 2 + 3*(LOCALE_NAME_MAX+1));
  1634. - buf[0] = libc.global_locale.ctype_utf8 ? 'U' : 'C';
  1635. - for (i=LC_TIME; i<LC_MESSAGES; i++) {
  1636. - lm = libc.global_locale.cat[i-2];
  1637. - if (lm) memcpy(buf + 2 + (i-2)*(LOCALE_NAME_MAX+1),
  1638. - lm->name, strlen(lm->name));
  1639. + char *s = buf;
  1640. + for (i=0; i<LC_ALL; i++) {
  1641. + const struct __locale_map *lm =
  1642. + libc.global_locale.cat[i];
  1643. + const char *part = lm ? lm->name : "C";
  1644. + size_t l = strlen(part);
  1645. + memcpy(s, part, l);
  1646. + s[l] = ';';
  1647. + s += l+1;
  1648. }
  1649. + *--s = 0;
  1650. + UNLOCK(lock);
  1651. return buf;
  1652. }
  1653. - if (name) {
  1654. - int adj = libc.global_locale.ctype_utf8;
  1655. - __setlocalecat(&libc.global_locale, cat, name);
  1656. - adj -= libc.global_locale.ctype_utf8;
  1657. - if (adj) a_fetch_add(&libc.bytelocale_cnt_minus_1, adj);
  1658. - }
  1659. + char *ret = setlocale_one_unlocked(cat, name);
  1660. - switch (cat) {
  1661. - case LC_CTYPE:
  1662. - return libc.global_locale.ctype_utf8 ? "C.UTF-8" : "C";
  1663. - case LC_NUMERIC:
  1664. - return "C";
  1665. - case LC_MESSAGES:
  1666. - return libc.global_locale.messages_name[0]
  1667. - ? libc.global_locale.messages_name : "C";
  1668. - default:
  1669. - lm = libc.global_locale.cat[cat-2];
  1670. - return lm ? lm->name : "C";
  1671. - }
  1672. + UNLOCK(lock);
  1673. +
  1674. + return ret;
  1675. }
  1676. --- a/src/locale/uselocale.c
  1677. +++ b/src/locale/uselocale.c
  1678. @@ -10,15 +10,7 @@ locale_t __uselocale(locale_t new)
  1679. if (new == LC_GLOBAL_LOCALE) new = global;
  1680. - if (new && new != old) {
  1681. - int adj = 0;
  1682. - if (new == global) a_dec(&libc.uselocale_cnt);
  1683. - else if (!new->ctype_utf8) adj++;
  1684. - if (old == global) a_inc(&libc.uselocale_cnt);
  1685. - else if (!old->ctype_utf8) adj--;
  1686. - a_fetch_add(&libc.bytelocale_cnt_minus_1, adj);
  1687. - self->locale = new;
  1688. - }
  1689. + self->locale = new;
  1690. return old == global ? LC_GLOBAL_LOCALE : old;
  1691. }
  1692. --- a/src/stdio/__stdio_read.c
  1693. +++ b/src/stdio/__stdio_read.c
  1694. @@ -21,7 +21,6 @@ size_t __stdio_read(FILE *f, unsigned ch
  1695. pthread_cleanup_pop(0);
  1696. if (cnt <= 0) {
  1697. f->flags |= F_EOF ^ ((F_ERR^F_EOF) & cnt);
  1698. - f->rpos = f->rend = 0;
  1699. return cnt;
  1700. }
  1701. if (cnt <= iov[0].iov_len) return cnt;
  1702. --- a/src/stdio/__toread.c
  1703. +++ b/src/stdio/__toread.c
  1704. @@ -5,12 +5,12 @@ int __toread(FILE *f)
  1705. f->mode |= f->mode-1;
  1706. if (f->wpos > f->buf) f->write(f, 0, 0);
  1707. f->wpos = f->wbase = f->wend = 0;
  1708. - if (f->flags & (F_EOF|F_NORD)) {
  1709. - if (f->flags & F_NORD) f->flags |= F_ERR;
  1710. + if (f->flags & F_NORD) {
  1711. + f->flags |= F_ERR;
  1712. return EOF;
  1713. }
  1714. - f->rpos = f->rend = f->buf;
  1715. - return 0;
  1716. + f->rpos = f->rend = f->buf + f->buf_size;
  1717. + return (f->flags & F_EOF) ? EOF : 0;
  1718. }
  1719. void __stdio_exit_needed(void);
  1720. --- a/src/stdio/__uflow.c
  1721. +++ b/src/stdio/__uflow.c
  1722. @@ -1,11 +1,11 @@
  1723. #include "stdio_impl.h"
  1724. -/* This function will never be called if there is already data
  1725. - * buffered for reading. Thus we can get by with very few branches. */
  1726. +/* This function assumes it will never be called if there is already
  1727. + * data buffered for reading. */
  1728. int __uflow(FILE *f)
  1729. {
  1730. unsigned char c;
  1731. - if ((f->rend || !__toread(f)) && f->read(f, &c, 1)==1) return c;
  1732. + if (!__toread(f) && f->read(f, &c, 1)==1) return c;
  1733. return EOF;
  1734. }
  1735. --- a/src/stdio/ungetc.c
  1736. +++ b/src/stdio/ungetc.c
  1737. @@ -6,7 +6,8 @@ int ungetc(int c, FILE *f)
  1738. FLOCK(f);
  1739. - if ((!f->rend && __toread(f)) || f->rpos <= f->buf - UNGET) {
  1740. + if (!f->rpos) __toread(f);
  1741. + if (!f->rpos || f->rpos <= f->buf - UNGET) {
  1742. FUNLOCK(f);
  1743. return EOF;
  1744. }
  1745. --- a/src/stdio/ungetwc.c
  1746. +++ b/src/stdio/ungetwc.c
  1747. @@ -19,7 +19,8 @@ wint_t ungetwc(wint_t c, FILE *f)
  1748. f->mode |= f->mode+1;
  1749. - if ((!f->rend && __toread(f)) || f->rpos < f->buf - UNGET + l) {
  1750. + if (!f->rpos) __toread(f);
  1751. + if (!f->rpos || f->rpos < f->buf - UNGET + l) {
  1752. FUNLOCK(f);
  1753. return EOF;
  1754. }
  1755. --- a/src/thread/i386/__set_thread_area.s
  1756. +++ b/src/thread/i386/__set_thread_area.s
  1757. @@ -6,10 +6,10 @@ __set_thread_area:
  1758. push $0x51
  1759. push $0xfffff
  1760. push 16(%esp)
  1761. - xor %edx,%edx
  1762. - mov %gs,%dx
  1763. - sub $3,%edx
  1764. - sar $3,%edx
  1765. + call 1f
  1766. +1: addl $4f-1b,(%esp)
  1767. + pop %ecx
  1768. + mov (%ecx),%edx
  1769. push %edx
  1770. mov %esp,%ebx
  1771. xor %eax,%eax
  1772. @@ -18,6 +18,7 @@ __set_thread_area:
  1773. testl %eax,%eax
  1774. jnz 2f
  1775. movl (%esp),%edx
  1776. + movl %edx,(%ecx)
  1777. leal 3(,%edx,8),%edx
  1778. 3: movw %dx,%gs
  1779. 1:
  1780. @@ -38,3 +39,7 @@ __set_thread_area:
  1781. mov $7,%dl
  1782. inc %al
  1783. jmp 3b
  1784. +
  1785. +.data
  1786. + .align 4
  1787. +4: .long -1
  1788. --- a/src/thread/mips/syscall_cp.s
  1789. +++ b/src/thread/mips/syscall_cp.s
  1790. @@ -2,10 +2,13 @@
  1791. .global __cp_begin
  1792. .hidden __cp_begin
  1793. +.type __cp_begin,@function
  1794. .global __cp_end
  1795. .hidden __cp_end
  1796. +.type __cp_end,@function
  1797. .global __cp_cancel
  1798. .hidden __cp_cancel
  1799. +.type __cp_cancel,@function
  1800. .hidden __cancel
  1801. .global __syscall_cp_asm
  1802. .hidden __syscall_cp_asm
  1803. --- a/src/thread/pthread_create.c
  1804. +++ b/src/thread/pthread_create.c
  1805. @@ -67,12 +67,6 @@ _Noreturn void __pthread_exit(void *resu
  1806. exit(0);
  1807. }
  1808. - if (self->locale != &libc.global_locale) {
  1809. - a_dec(&libc.uselocale_cnt);
  1810. - if (self->locale->ctype_utf8)
  1811. - a_dec(&libc.bytelocale_cnt_minus_1);
  1812. - }
  1813. -
  1814. /* Process robust list in userspace to handle non-pshared mutexes
  1815. * and the detached thread case where the robust list head will
  1816. * be invalid when the kernel would process it. */