laag-nasm 2.13.03.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (455) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +57 -0
  3. data/LICENSE.txt +29 -0
  4. data/README.org +34 -0
  5. data/ext/laag/nasm/extconf.rb +16 -0
  6. data/laag-nasm.gemspec +20 -0
  7. data/lib/laag/nasm.rb +29 -0
  8. data/patches/Makefile.in.patch +13 -0
  9. data/vendor/repo.or.cz/nasm/.gitignore +102 -0
  10. data/vendor/repo.or.cz/nasm/AUTHORS +137 -0
  11. data/vendor/repo.or.cz/nasm/CHANGES +2 -0
  12. data/vendor/repo.or.cz/nasm/ChangeLog +2905 -0
  13. data/vendor/repo.or.cz/nasm/INSTALL +102 -0
  14. data/vendor/repo.or.cz/nasm/LICENSE +29 -0
  15. data/vendor/repo.or.cz/nasm/Makefile.in +855 -0
  16. data/vendor/repo.or.cz/nasm/Mkfiles/README +46 -0
  17. data/vendor/repo.or.cz/nasm/Mkfiles/msvc.mak +732 -0
  18. data/vendor/repo.or.cz/nasm/Mkfiles/openwcom.mak +706 -0
  19. data/vendor/repo.or.cz/nasm/README +23 -0
  20. data/vendor/repo.or.cz/nasm/SubmittingPatches +116 -0
  21. data/vendor/repo.or.cz/nasm/TODO +376 -0
  22. data/vendor/repo.or.cz/nasm/aclocal.m4 +139 -0
  23. data/vendor/repo.or.cz/nasm/asm/assemble.c +2957 -0
  24. data/vendor/repo.or.cz/nasm/asm/assemble.h +54 -0
  25. data/vendor/repo.or.cz/nasm/asm/directiv.c +566 -0
  26. data/vendor/repo.or.cz/nasm/asm/directiv.dat +92 -0
  27. data/vendor/repo.or.cz/nasm/asm/error.c +202 -0
  28. data/vendor/repo.or.cz/nasm/asm/eval.c +1014 -0
  29. data/vendor/repo.or.cz/nasm/asm/eval.h +49 -0
  30. data/vendor/repo.or.cz/nasm/asm/exprdump.c +79 -0
  31. data/vendor/repo.or.cz/nasm/asm/exprlib.c +200 -0
  32. data/vendor/repo.or.cz/nasm/asm/float.c +952 -0
  33. data/vendor/repo.or.cz/nasm/asm/float.h +54 -0
  34. data/vendor/repo.or.cz/nasm/asm/labels.c +540 -0
  35. data/vendor/repo.or.cz/nasm/asm/listing.c +346 -0
  36. data/vendor/repo.or.cz/nasm/asm/listing.h +113 -0
  37. data/vendor/repo.or.cz/nasm/asm/nasm.c +1855 -0
  38. data/vendor/repo.or.cz/nasm/asm/parser.c +1167 -0
  39. data/vendor/repo.or.cz/nasm/asm/parser.h +45 -0
  40. data/vendor/repo.or.cz/nasm/asm/phash.pl +109 -0
  41. data/vendor/repo.or.cz/nasm/asm/pptok.dat +96 -0
  42. data/vendor/repo.or.cz/nasm/asm/pptok.pl +271 -0
  43. data/vendor/repo.or.cz/nasm/asm/pragma.c +218 -0
  44. data/vendor/repo.or.cz/nasm/asm/preproc-nop.c +188 -0
  45. data/vendor/repo.or.cz/nasm/asm/preproc.c +5459 -0
  46. data/vendor/repo.or.cz/nasm/asm/preproc.h +55 -0
  47. data/vendor/repo.or.cz/nasm/asm/quote.c +479 -0
  48. data/vendor/repo.or.cz/nasm/asm/quote.h +44 -0
  49. data/vendor/repo.or.cz/nasm/asm/rdstrnum.c +68 -0
  50. data/vendor/repo.or.cz/nasm/asm/segalloc.c +51 -0
  51. data/vendor/repo.or.cz/nasm/asm/stdscan.c +345 -0
  52. data/vendor/repo.or.cz/nasm/asm/stdscan.h +49 -0
  53. data/vendor/repo.or.cz/nasm/asm/strfunc.c +359 -0
  54. data/vendor/repo.or.cz/nasm/asm/tokens.dat +135 -0
  55. data/vendor/repo.or.cz/nasm/asm/tokhash.pl +284 -0
  56. data/vendor/repo.or.cz/nasm/autogen.sh +9 -0
  57. data/vendor/repo.or.cz/nasm/common/common.c +122 -0
  58. data/vendor/repo.or.cz/nasm/config/msvc.h +192 -0
  59. data/vendor/repo.or.cz/nasm/config/unknown.h +51 -0
  60. data/vendor/repo.or.cz/nasm/config/watcom.h +74 -0
  61. data/vendor/repo.or.cz/nasm/configure.ac +253 -0
  62. data/vendor/repo.or.cz/nasm/contrib/MSVC6.txt +25 -0
  63. data/vendor/repo.or.cz/nasm/contrib/VSrules/nasm.README +16 -0
  64. data/vendor/repo.or.cz/nasm/contrib/VSrules/nasm.rules +79 -0
  65. data/vendor/repo.or.cz/nasm/disasm/disasm.c +1735 -0
  66. data/vendor/repo.or.cz/nasm/disasm/disasm.h +49 -0
  67. data/vendor/repo.or.cz/nasm/disasm/ndisasm.c +397 -0
  68. data/vendor/repo.or.cz/nasm/disasm/sync.c +132 -0
  69. data/vendor/repo.or.cz/nasm/disasm/sync.h +45 -0
  70. data/vendor/repo.or.cz/nasm/doc/Makefile.in +86 -0
  71. data/vendor/repo.or.cz/nasm/doc/README +20 -0
  72. data/vendor/repo.or.cz/nasm/doc/afmmetrics.ph +102 -0
  73. data/vendor/repo.or.cz/nasm/doc/changes.src +2588 -0
  74. data/vendor/repo.or.cz/nasm/doc/findfont.ph +180 -0
  75. data/vendor/repo.or.cz/nasm/doc/genps.pl +1294 -0
  76. data/vendor/repo.or.cz/nasm/doc/inslist.pl +108 -0
  77. data/vendor/repo.or.cz/nasm/doc/internal.doc +290 -0
  78. data/vendor/repo.or.cz/nasm/doc/local.css +1 -0
  79. data/vendor/repo.or.cz/nasm/doc/nasmdoc.css +150 -0
  80. data/vendor/repo.or.cz/nasm/doc/nasmdoc.src +8309 -0
  81. data/vendor/repo.or.cz/nasm/doc/nasmlogo.eps +212 -0
  82. data/vendor/repo.or.cz/nasm/doc/nasmlogw.png +0 -0
  83. data/vendor/repo.or.cz/nasm/doc/psfonts.ph +53 -0
  84. data/vendor/repo.or.cz/nasm/doc/pspdf.pl +98 -0
  85. data/vendor/repo.or.cz/nasm/doc/pswidth.ph +25 -0
  86. data/vendor/repo.or.cz/nasm/doc/rdsrc.pl +1111 -0
  87. data/vendor/repo.or.cz/nasm/doc/ttfmetrics.ph +63 -0
  88. data/vendor/repo.or.cz/nasm/headers/c +33 -0
  89. data/vendor/repo.or.cz/nasm/headers/doc +33 -0
  90. data/vendor/repo.or.cz/nasm/headers/mac +33 -0
  91. data/vendor/repo.or.cz/nasm/headers/perl +33 -0
  92. data/vendor/repo.or.cz/nasm/include/compiler.h +277 -0
  93. data/vendor/repo.or.cz/nasm/include/disp8.h +45 -0
  94. data/vendor/repo.or.cz/nasm/include/error.h +135 -0
  95. data/vendor/repo.or.cz/nasm/include/hashtbl.h +85 -0
  96. data/vendor/repo.or.cz/nasm/include/iflag.h +173 -0
  97. data/vendor/repo.or.cz/nasm/include/insns.h +76 -0
  98. data/vendor/repo.or.cz/nasm/include/labels.h +60 -0
  99. data/vendor/repo.or.cz/nasm/include/md5.h +21 -0
  100. data/vendor/repo.or.cz/nasm/include/nasm.h +1246 -0
  101. data/vendor/repo.or.cz/nasm/include/nasmint.h +219 -0
  102. data/vendor/repo.or.cz/nasm/include/nasmlib.h +524 -0
  103. data/vendor/repo.or.cz/nasm/include/opflags.h +271 -0
  104. data/vendor/repo.or.cz/nasm/include/perfhash.h +52 -0
  105. data/vendor/repo.or.cz/nasm/include/raa.h +46 -0
  106. data/vendor/repo.or.cz/nasm/include/rbtree.h +51 -0
  107. data/vendor/repo.or.cz/nasm/include/rdoff.h +169 -0
  108. data/vendor/repo.or.cz/nasm/include/saa.h +94 -0
  109. data/vendor/repo.or.cz/nasm/include/strlist.h +55 -0
  110. data/vendor/repo.or.cz/nasm/include/tables.h +70 -0
  111. data/vendor/repo.or.cz/nasm/include/ver.h +47 -0
  112. data/vendor/repo.or.cz/nasm/install-sh +250 -0
  113. data/vendor/repo.or.cz/nasm/macros/altreg.mac +107 -0
  114. data/vendor/repo.or.cz/nasm/macros/fp.mac +54 -0
  115. data/vendor/repo.or.cz/nasm/macros/ifunc.mac +48 -0
  116. data/vendor/repo.or.cz/nasm/macros/macros.pl +294 -0
  117. data/vendor/repo.or.cz/nasm/macros/smartalign.mac +189 -0
  118. data/vendor/repo.or.cz/nasm/macros/standard.mac +226 -0
  119. data/vendor/repo.or.cz/nasm/misc/Doxyfile +752 -0
  120. data/vendor/repo.or.cz/nasm/misc/Nindent +18 -0
  121. data/vendor/repo.or.cz/nasm/misc/README +2 -0
  122. data/vendor/repo.or.cz/nasm/misc/c16.mac +82 -0
  123. data/vendor/repo.or.cz/nasm/misc/c32.mac +52 -0
  124. data/vendor/repo.or.cz/nasm/misc/crcgen.c +44 -0
  125. data/vendor/repo.or.cz/nasm/misc/exebin.mac +57 -0
  126. data/vendor/repo.or.cz/nasm/misc/exebin2.mac +114 -0
  127. data/vendor/repo.or.cz/nasm/misc/fmtinsns.pl +40 -0
  128. data/vendor/repo.or.cz/nasm/misc/genfma.pl +63 -0
  129. data/vendor/repo.or.cz/nasm/misc/hints.txt +26 -0
  130. data/vendor/repo.or.cz/nasm/misc/magic +6 -0
  131. data/vendor/repo.or.cz/nasm/misc/myC32.mac +121 -0
  132. data/vendor/repo.or.cz/nasm/misc/nasm.sl +320 -0
  133. data/vendor/repo.or.cz/nasm/misc/nasmstab +296 -0
  134. data/vendor/repo.or.cz/nasm/misc/omfdump.c +517 -0
  135. data/vendor/repo.or.cz/nasm/misc/pmw.bat +9 -0
  136. data/vendor/repo.or.cz/nasm/misc/proc32.ash +441 -0
  137. data/vendor/repo.or.cz/nasm/misc/scitech.mac +1223 -0
  138. data/vendor/repo.or.cz/nasm/misc/xcrcgen.c +80 -0
  139. data/vendor/repo.or.cz/nasm/nasm.spec.in +83 -0
  140. data/vendor/repo.or.cz/nasm/nasm.spec.sed +3 -0
  141. data/vendor/repo.or.cz/nasm/nasm.txt +306 -0
  142. data/vendor/repo.or.cz/nasm/nasmlib/badenum.c +43 -0
  143. data/vendor/repo.or.cz/nasm/nasmlib/bsi.c +77 -0
  144. data/vendor/repo.or.cz/nasm/nasmlib/crc64.c +189 -0
  145. data/vendor/repo.or.cz/nasm/nasmlib/file.c +259 -0
  146. data/vendor/repo.or.cz/nasm/nasmlib/file.h +128 -0
  147. data/vendor/repo.or.cz/nasm/nasmlib/filename.c +69 -0
  148. data/vendor/repo.or.cz/nasm/nasmlib/hashtbl.c +232 -0
  149. data/vendor/repo.or.cz/nasm/nasmlib/ilog2.c +168 -0
  150. data/vendor/repo.or.cz/nasm/nasmlib/malloc.c +108 -0
  151. data/vendor/repo.or.cz/nasm/nasmlib/md5c.c +247 -0
  152. data/vendor/repo.or.cz/nasm/nasmlib/mmap.c +139 -0
  153. data/vendor/repo.or.cz/nasm/nasmlib/path.c +186 -0
  154. data/vendor/repo.or.cz/nasm/nasmlib/perfhash.c +55 -0
  155. data/vendor/repo.or.cz/nasm/nasmlib/perfhash.pl +362 -0
  156. data/vendor/repo.or.cz/nasm/nasmlib/raa.c +173 -0
  157. data/vendor/repo.or.cz/nasm/nasmlib/rbtree.c +119 -0
  158. data/vendor/repo.or.cz/nasm/nasmlib/readnum.c +172 -0
  159. data/vendor/repo.or.cz/nasm/nasmlib/realpath.c +135 -0
  160. data/vendor/repo.or.cz/nasm/nasmlib/saa.c +431 -0
  161. data/vendor/repo.or.cz/nasm/nasmlib/srcfile.c +128 -0
  162. data/vendor/repo.or.cz/nasm/nasmlib/string.c +242 -0
  163. data/vendor/repo.or.cz/nasm/nasmlib/strlist.c +100 -0
  164. data/vendor/repo.or.cz/nasm/nasmlib/ver.c +51 -0
  165. data/vendor/repo.or.cz/nasm/nasmlib/zerobuf.c +42 -0
  166. data/vendor/repo.or.cz/nasm/ndisasm.txt +94 -0
  167. data/vendor/repo.or.cz/nasm/nsis/NASMMultiUser.nsh +478 -0
  168. data/vendor/repo.or.cz/nasm/nsis/getpearch.pl +76 -0
  169. data/vendor/repo.or.cz/nasm/nsis/nasm-un.ico +0 -0
  170. data/vendor/repo.or.cz/nasm/nsis/nasm.ico +0 -0
  171. data/vendor/repo.or.cz/nasm/nsis/nasm.nsi +241 -0
  172. data/vendor/repo.or.cz/nasm/output/codeview.c +814 -0
  173. data/vendor/repo.or.cz/nasm/output/dwarf.h +566 -0
  174. data/vendor/repo.or.cz/nasm/output/elf.h +537 -0
  175. data/vendor/repo.or.cz/nasm/output/legacy.c +112 -0
  176. data/vendor/repo.or.cz/nasm/output/nulldbg.c +93 -0
  177. data/vendor/repo.or.cz/nasm/output/nullout.c +51 -0
  178. data/vendor/repo.or.cz/nasm/output/outaout.c +954 -0
  179. data/vendor/repo.or.cz/nasm/output/outaout.mac +37 -0
  180. data/vendor/repo.or.cz/nasm/output/outas86.c +650 -0
  181. data/vendor/repo.or.cz/nasm/output/outas86.mac +37 -0
  182. data/vendor/repo.or.cz/nasm/output/outbin.c +1713 -0
  183. data/vendor/repo.or.cz/nasm/output/outbin.mac +40 -0
  184. data/vendor/repo.or.cz/nasm/output/outcoff.c +1242 -0
  185. data/vendor/repo.or.cz/nasm/output/outcoff.mac +43 -0
  186. data/vendor/repo.or.cz/nasm/output/outdbg.c +425 -0
  187. data/vendor/repo.or.cz/nasm/output/outelf.c +3370 -0
  188. data/vendor/repo.or.cz/nasm/output/outelf.h +156 -0
  189. data/vendor/repo.or.cz/nasm/output/outelf.mac +41 -0
  190. data/vendor/repo.or.cz/nasm/output/outform.c +120 -0
  191. data/vendor/repo.or.cz/nasm/output/outform.h +379 -0
  192. data/vendor/repo.or.cz/nasm/output/outieee.c +1528 -0
  193. data/vendor/repo.or.cz/nasm/output/outlib.c +58 -0
  194. data/vendor/repo.or.cz/nasm/output/outlib.h +63 -0
  195. data/vendor/repo.or.cz/nasm/output/outmacho.c +2387 -0
  196. data/vendor/repo.or.cz/nasm/output/outmacho.mac +49 -0
  197. data/vendor/repo.or.cz/nasm/output/outobj.c +2725 -0
  198. data/vendor/repo.or.cz/nasm/output/outobj.mac +49 -0
  199. data/vendor/repo.or.cz/nasm/output/outrdf.mac +40 -0
  200. data/vendor/repo.or.cz/nasm/output/outrdf2.c +791 -0
  201. data/vendor/repo.or.cz/nasm/output/outrdf2.mac +43 -0
  202. data/vendor/repo.or.cz/nasm/output/pecoff.h +532 -0
  203. data/vendor/repo.or.cz/nasm/output/stabs.h +144 -0
  204. data/vendor/repo.or.cz/nasm/perllib/crc64.ph +158 -0
  205. data/vendor/repo.or.cz/nasm/perllib/gensv.pl +34 -0
  206. data/vendor/repo.or.cz/nasm/perllib/phash.ph +200 -0
  207. data/vendor/repo.or.cz/nasm/perllib/random_sv_vectors.ph +67 -0
  208. data/vendor/repo.or.cz/nasm/rdoff/README +185 -0
  209. data/vendor/repo.or.cz/nasm/rdoff/collectn.c +44 -0
  210. data/vendor/repo.or.cz/nasm/rdoff/collectn.h +22 -0
  211. data/vendor/repo.or.cz/nasm/rdoff/doc/Makefile +37 -0
  212. data/vendor/repo.or.cz/nasm/rdoff/doc/rdoff.texi +137 -0
  213. data/vendor/repo.or.cz/nasm/rdoff/doc/v1-v2.txt +62 -0
  214. data/vendor/repo.or.cz/nasm/rdoff/hash.c +122 -0
  215. data/vendor/repo.or.cz/nasm/rdoff/hash.h +17 -0
  216. data/vendor/repo.or.cz/nasm/rdoff/ldrdf.1 +41 -0
  217. data/vendor/repo.or.cz/nasm/rdoff/ldrdf.c +1395 -0
  218. data/vendor/repo.or.cz/nasm/rdoff/ldsegs.h +59 -0
  219. data/vendor/repo.or.cz/nasm/rdoff/rdf2bin.1 +65 -0
  220. data/vendor/repo.or.cz/nasm/rdoff/rdf2bin.c +431 -0
  221. data/vendor/repo.or.cz/nasm/rdoff/rdf2com.1 +1 -0
  222. data/vendor/repo.or.cz/nasm/rdoff/rdf2ihx.1 +1 -0
  223. data/vendor/repo.or.cz/nasm/rdoff/rdf2ith.1 +1 -0
  224. data/vendor/repo.or.cz/nasm/rdoff/rdf2srec.1 +1 -0
  225. data/vendor/repo.or.cz/nasm/rdoff/rdfdump.1 +24 -0
  226. data/vendor/repo.or.cz/nasm/rdoff/rdfdump.c +347 -0
  227. data/vendor/repo.or.cz/nasm/rdoff/rdflib.1 +39 -0
  228. data/vendor/repo.or.cz/nasm/rdoff/rdflib.c +434 -0
  229. data/vendor/repo.or.cz/nasm/rdoff/rdfload.c +213 -0
  230. data/vendor/repo.or.cz/nasm/rdoff/rdfload.h +29 -0
  231. data/vendor/repo.or.cz/nasm/rdoff/rdfutils.h +165 -0
  232. data/vendor/repo.or.cz/nasm/rdoff/rdlar.c +492 -0
  233. data/vendor/repo.or.cz/nasm/rdoff/rdlar.h +34 -0
  234. data/vendor/repo.or.cz/nasm/rdoff/rdlib.c +290 -0
  235. data/vendor/repo.or.cz/nasm/rdoff/rdlib.h +62 -0
  236. data/vendor/repo.or.cz/nasm/rdoff/rdoff.c +621 -0
  237. data/vendor/repo.or.cz/nasm/rdoff/rdx.1 +21 -0
  238. data/vendor/repo.or.cz/nasm/rdoff/rdx.c +90 -0
  239. data/vendor/repo.or.cz/nasm/rdoff/segtab.c +172 -0
  240. data/vendor/repo.or.cz/nasm/rdoff/segtab.h +45 -0
  241. data/vendor/repo.or.cz/nasm/rdoff/symtab.c +159 -0
  242. data/vendor/repo.or.cz/nasm/rdoff/symtab.h +55 -0
  243. data/vendor/repo.or.cz/nasm/rdoff/test/Makefile +10 -0
  244. data/vendor/repo.or.cz/nasm/rdoff/test/makelib.sh +14 -0
  245. data/vendor/repo.or.cz/nasm/rdoff/test/rdfseg.asm +20 -0
  246. data/vendor/repo.or.cz/nasm/rdoff/test/rdfseg2.asm +12 -0
  247. data/vendor/repo.or.cz/nasm/rdoff/test/rdftest1.asm +54 -0
  248. data/vendor/repo.or.cz/nasm/rdoff/test/rdftest2.asm +33 -0
  249. data/vendor/repo.or.cz/nasm/rdoff/test/rdtlib.asm +48 -0
  250. data/vendor/repo.or.cz/nasm/rdoff/test/rdtmain.asm +47 -0
  251. data/vendor/repo.or.cz/nasm/rdoff/test/testlib.asm +18 -0
  252. data/vendor/repo.or.cz/nasm/stdlib/snprintf.c +29 -0
  253. data/vendor/repo.or.cz/nasm/stdlib/strlcpy.c +51 -0
  254. data/vendor/repo.or.cz/nasm/stdlib/strnlen.c +46 -0
  255. data/vendor/repo.or.cz/nasm/stdlib/vsnprintf.c +51 -0
  256. data/vendor/repo.or.cz/nasm/test/Makefile +106 -0
  257. data/vendor/repo.or.cz/nasm/test/_file_.asm +5 -0
  258. data/vendor/repo.or.cz/nasm/test/_version.asm +2 -0
  259. data/vendor/repo.or.cz/nasm/test/a32offs.asm +9 -0
  260. data/vendor/repo.or.cz/nasm/test/absolute.asm +40 -0
  261. data/vendor/repo.or.cz/nasm/test/addr64x.asm +18 -0
  262. data/vendor/repo.or.cz/nasm/test/align13.asm +19 -0
  263. data/vendor/repo.or.cz/nasm/test/align13s.asm +20 -0
  264. data/vendor/repo.or.cz/nasm/test/alonesym-obj.asm +166 -0
  265. data/vendor/repo.or.cz/nasm/test/andbyte.asm +15 -0
  266. data/vendor/repo.or.cz/nasm/test/aoutso.asm +99 -0
  267. data/vendor/repo.or.cz/nasm/test/aouttest.asm +86 -0
  268. data/vendor/repo.or.cz/nasm/test/aouttest.c +36 -0
  269. data/vendor/repo.or.cz/nasm/test/avx.asm +46 -0
  270. data/vendor/repo.or.cz/nasm/test/avx005.asm +529 -0
  271. data/vendor/repo.or.cz/nasm/test/avx2.asm +1608 -0
  272. data/vendor/repo.or.cz/nasm/test/avx512cd.asm +106 -0
  273. data/vendor/repo.or.cz/nasm/test/avx512er.asm +144 -0
  274. data/vendor/repo.or.cz/nasm/test/avx512f.asm +7000 -0
  275. data/vendor/repo.or.cz/nasm/test/avx512pf.asm +88 -0
  276. data/vendor/repo.or.cz/nasm/test/bcd.asm +23 -0
  277. data/vendor/repo.or.cz/nasm/test/binexe.asm +35 -0
  278. data/vendor/repo.or.cz/nasm/test/bintest.asm +59 -0
  279. data/vendor/repo.or.cz/nasm/test/bisect.sh +22 -0
  280. data/vendor/repo.or.cz/nasm/test/br1879590.asm +25 -0
  281. data/vendor/repo.or.cz/nasm/test/br2003451.asm +17 -0
  282. data/vendor/repo.or.cz/nasm/test/br2030823.asm +7 -0
  283. data/vendor/repo.or.cz/nasm/test/br2148476.asm +221 -0
  284. data/vendor/repo.or.cz/nasm/test/br2222615.asm +19 -0
  285. data/vendor/repo.or.cz/nasm/test/br2496848.asm +42 -0
  286. data/vendor/repo.or.cz/nasm/test/br3005117.asm +26 -0
  287. data/vendor/repo.or.cz/nasm/test/br3026808.asm +20 -0
  288. data/vendor/repo.or.cz/nasm/test/br3028880.asm +8 -0
  289. data/vendor/repo.or.cz/nasm/test/br3041451.asm +59 -0
  290. data/vendor/repo.or.cz/nasm/test/br3058845.asm +14 -0
  291. data/vendor/repo.or.cz/nasm/test/br3066383.asm +70 -0
  292. data/vendor/repo.or.cz/nasm/test/br3074517.asm +12 -0
  293. data/vendor/repo.or.cz/nasm/test/br3092924.asm +25 -0
  294. data/vendor/repo.or.cz/nasm/test/br3104312.asm +11 -0
  295. data/vendor/repo.or.cz/nasm/test/br3109604.asm +9 -0
  296. data/vendor/repo.or.cz/nasm/test/br3174983.asm +9 -0
  297. data/vendor/repo.or.cz/nasm/test/br3187743.asm +7 -0
  298. data/vendor/repo.or.cz/nasm/test/br3189064.asm +7 -0
  299. data/vendor/repo.or.cz/nasm/test/br3200749.asm +9 -0
  300. data/vendor/repo.or.cz/nasm/test/br3385573.asm +11 -0
  301. data/vendor/repo.or.cz/nasm/test/br3392252.asm +43 -0
  302. data/vendor/repo.or.cz/nasm/test/br3392259.asm +8 -0
  303. data/vendor/repo.or.cz/nasm/test/br3392363.asm +4 -0
  304. data/vendor/repo.or.cz/nasm/test/br3392392.asm +16 -0
  305. data/vendor/repo.or.cz/nasm/test/br3392396.asm +5 -0
  306. data/vendor/repo.or.cz/nasm/test/br3392411.asm +22 -0
  307. data/vendor/repo.or.cz/nasm/test/br3392418.asm +3 -0
  308. data/vendor/repo.or.cz/nasm/test/br3392439.asm +25 -0
  309. data/vendor/repo.or.cz/nasm/test/br3392442.asm +6 -0
  310. data/vendor/repo.or.cz/nasm/test/br560575.asm +17 -0
  311. data/vendor/repo.or.cz/nasm/test/br560873.asm +27 -0
  312. data/vendor/repo.or.cz/nasm/test/br890790.asm +7 -0
  313. data/vendor/repo.or.cz/nasm/test/br890790_i.asm +1 -0
  314. data/vendor/repo.or.cz/nasm/test/br978756.asm +7 -0
  315. data/vendor/repo.or.cz/nasm/test/changed.asm +383 -0
  316. data/vendor/repo.or.cz/nasm/test/cofftest.asm +85 -0
  317. data/vendor/repo.or.cz/nasm/test/cofftest.c +35 -0
  318. data/vendor/repo.or.cz/nasm/test/crc32.asm +37 -0
  319. data/vendor/repo.or.cz/nasm/test/cv8struc.asm +14 -0
  320. data/vendor/repo.or.cz/nasm/test/dtbcd.asm +72 -0
  321. data/vendor/repo.or.cz/nasm/test/elf64so.asm +118 -0
  322. data/vendor/repo.or.cz/nasm/test/elfso.asm +100 -0
  323. data/vendor/repo.or.cz/nasm/test/elftest.asm +87 -0
  324. data/vendor/repo.or.cz/nasm/test/elftest.c +38 -0
  325. data/vendor/repo.or.cz/nasm/test/elftest64.c +43 -0
  326. data/vendor/repo.or.cz/nasm/test/elif.asm +39 -0
  327. data/vendor/repo.or.cz/nasm/test/expimp.asm +90 -0
  328. data/vendor/repo.or.cz/nasm/test/far64.asm +10 -0
  329. data/vendor/repo.or.cz/nasm/test/float.asm +186 -0
  330. data/vendor/repo.or.cz/nasm/test/float8.asm +135 -0
  331. data/vendor/repo.or.cz/nasm/test/floatb.asm +35 -0
  332. data/vendor/repo.or.cz/nasm/test/floatexp.asm +382 -0
  333. data/vendor/repo.or.cz/nasm/test/floatize.asm +19 -0
  334. data/vendor/repo.or.cz/nasm/test/floattest.asm +28 -0
  335. data/vendor/repo.or.cz/nasm/test/floatx.asm +525 -0
  336. data/vendor/repo.or.cz/nasm/test/fpu.asm +127 -0
  337. data/vendor/repo.or.cz/nasm/test/fwdopt.asm +133 -0
  338. data/vendor/repo.or.cz/nasm/test/fwdoptpp.asm +150 -0
  339. data/vendor/repo.or.cz/nasm/test/gas2nasm.py +104 -0
  340. data/vendor/repo.or.cz/nasm/test/gather.asm +11 -0
  341. data/vendor/repo.or.cz/nasm/test/gotoff64.asm +25 -0
  342. data/vendor/repo.or.cz/nasm/test/hexfp.asm +25 -0
  343. data/vendor/repo.or.cz/nasm/test/hle.asm +19 -0
  344. data/vendor/repo.or.cz/nasm/test/ifelse.asm +46 -0
  345. data/vendor/repo.or.cz/nasm/test/ifenv.asm +31 -0
  346. data/vendor/repo.or.cz/nasm/test/ifmacro.asm +413 -0
  347. data/vendor/repo.or.cz/nasm/test/iftoken.asm +317 -0
  348. data/vendor/repo.or.cz/nasm/test/iftoken.pl +32 -0
  349. data/vendor/repo.or.cz/nasm/test/ilog2.asm +271 -0
  350. data/vendor/repo.or.cz/nasm/test/imacro.asm +8 -0
  351. data/vendor/repo.or.cz/nasm/test/imm.asm +23 -0
  352. data/vendor/repo.or.cz/nasm/test/imm64.asm +61 -0
  353. data/vendor/repo.or.cz/nasm/test/immwarn.asm +91 -0
  354. data/vendor/repo.or.cz/nasm/test/imul.asm +117 -0
  355. data/vendor/repo.or.cz/nasm/test/inc1.asm +6 -0
  356. data/vendor/repo.or.cz/nasm/test/inc2.asm +8 -0
  357. data/vendor/repo.or.cz/nasm/test/incbin.asm +7 -0
  358. data/vendor/repo.or.cz/nasm/test/incbin.data +2 -0
  359. data/vendor/repo.or.cz/nasm/test/inctest.asm +15 -0
  360. data/vendor/repo.or.cz/nasm/test/insnlbl.asm +12 -0
  361. data/vendor/repo.or.cz/nasm/test/invlpga.asm +11 -0
  362. data/vendor/repo.or.cz/nasm/test/jmp64.asm +19 -0
  363. data/vendor/repo.or.cz/nasm/test/lar_lsl.asm +124 -0
  364. data/vendor/repo.or.cz/nasm/test/larlsl.asm +23 -0
  365. data/vendor/repo.or.cz/nasm/test/lnxhello.asm +54 -0
  366. data/vendor/repo.or.cz/nasm/test/local.asm +19 -0
  367. data/vendor/repo.or.cz/nasm/test/loopoffs.asm +12 -0
  368. data/vendor/repo.or.cz/nasm/test/lwp.asm +213 -0
  369. data/vendor/repo.or.cz/nasm/test/macro-defaults.asm +64 -0
  370. data/vendor/repo.or.cz/nasm/test/macroerr.asm +12 -0
  371. data/vendor/repo.or.cz/nasm/test/macroerr.inc +3 -0
  372. data/vendor/repo.or.cz/nasm/test/mmxsize.asm +38 -0
  373. data/vendor/repo.or.cz/nasm/test/movd.asm +12 -0
  374. data/vendor/repo.or.cz/nasm/test/movd64.asm +15 -0
  375. data/vendor/repo.or.cz/nasm/test/movimm.asm +28 -0
  376. data/vendor/repo.or.cz/nasm/test/movnti.asm +10 -0
  377. data/vendor/repo.or.cz/nasm/test/mpx-64.asm +120 -0
  378. data/vendor/repo.or.cz/nasm/test/mpx.asm +89 -0
  379. data/vendor/repo.or.cz/nasm/test/multisection.asm +96 -0
  380. data/vendor/repo.or.cz/nasm/test/nasmformat.asm +17 -0
  381. data/vendor/repo.or.cz/nasm/test/new +9 -0
  382. data/vendor/repo.or.cz/nasm/test/newrdwr.asm +24 -0
  383. data/vendor/repo.or.cz/nasm/test/nop.asm +17 -0
  384. data/vendor/repo.or.cz/nasm/test/nullfile.asm +4 -0
  385. data/vendor/repo.or.cz/nasm/test/objexe.asm +30 -0
  386. data/vendor/repo.or.cz/nasm/test/objlink.c +33 -0
  387. data/vendor/repo.or.cz/nasm/test/objtest.asm +85 -0
  388. data/vendor/repo.or.cz/nasm/test/optimization.asm +104 -0
  389. data/vendor/repo.or.cz/nasm/test/org.asm +18 -0
  390. data/vendor/repo.or.cz/nasm/test/paste.asm +12 -0
  391. data/vendor/repo.or.cz/nasm/test/pcrel.asm +52 -0
  392. data/vendor/repo.or.cz/nasm/test/perf/label.pl +18 -0
  393. data/vendor/repo.or.cz/nasm/test/perf/macro.pl +18 -0
  394. data/vendor/repo.or.cz/nasm/test/perf/token.pl +23 -0
  395. data/vendor/repo.or.cz/nasm/test/performtest.pl +192 -0
  396. data/vendor/repo.or.cz/nasm/test/pextrw.asm +3 -0
  397. data/vendor/repo.or.cz/nasm/test/pinsr16.asm +53 -0
  398. data/vendor/repo.or.cz/nasm/test/pinsr32.asm +53 -0
  399. data/vendor/repo.or.cz/nasm/test/pinsr64.asm +68 -0
  400. data/vendor/repo.or.cz/nasm/test/popcnt.asm +32 -0
  401. data/vendor/repo.or.cz/nasm/test/ppindirect.asm +42 -0
  402. data/vendor/repo.or.cz/nasm/test/pragma.asm +12 -0
  403. data/vendor/repo.or.cz/nasm/test/prefix66.asm +28 -0
  404. data/vendor/repo.or.cz/nasm/test/ptr.asm +4 -0
  405. data/vendor/repo.or.cz/nasm/test/pushseg.asm +17 -0
  406. data/vendor/repo.or.cz/nasm/test/r13.asm +15 -0
  407. data/vendor/repo.or.cz/nasm/test/radix.asm +54 -0
  408. data/vendor/repo.or.cz/nasm/test/rdpid.asm +21 -0
  409. data/vendor/repo.or.cz/nasm/test/reldef.asm +57 -0
  410. data/vendor/repo.or.cz/nasm/test/relocs.asm +20 -0
  411. data/vendor/repo.or.cz/nasm/test/riprel.asm +5357 -0
  412. data/vendor/repo.or.cz/nasm/test/riprel.pl +29 -0
  413. data/vendor/repo.or.cz/nasm/test/riprel2.asm +11 -0
  414. data/vendor/repo.or.cz/nasm/test/sha-64.asm +30 -0
  415. data/vendor/repo.or.cz/nasm/test/sha.asm +31 -0
  416. data/vendor/repo.or.cz/nasm/test/smartalign16.asm +36 -0
  417. data/vendor/repo.or.cz/nasm/test/smartalign32.asm +36 -0
  418. data/vendor/repo.or.cz/nasm/test/smartalign64.asm +36 -0
  419. data/vendor/repo.or.cz/nasm/test/splitea.asm +11 -0
  420. data/vendor/repo.or.cz/nasm/test/sreg.asm +65 -0
  421. data/vendor/repo.or.cz/nasm/test/strlen.asm +5 -0
  422. data/vendor/repo.or.cz/nasm/test/struc.asm +33 -0
  423. data/vendor/repo.or.cz/nasm/test/test67.asm +38 -0
  424. data/vendor/repo.or.cz/nasm/test/testdos.asm +13 -0
  425. data/vendor/repo.or.cz/nasm/test/testnos3.asm +973 -0
  426. data/vendor/repo.or.cz/nasm/test/time.asm +11 -0
  427. data/vendor/repo.or.cz/nasm/test/times.asm +21 -0
  428. data/vendor/repo.or.cz/nasm/test/timesneg.asm +3 -0
  429. data/vendor/repo.or.cz/nasm/test/tmap.nas +1447 -0
  430. data/vendor/repo.or.cz/nasm/test/uscore.asm +15 -0
  431. data/vendor/repo.or.cz/nasm/test/utf.asm +82 -0
  432. data/vendor/repo.or.cz/nasm/test/vaesenc.asm +22 -0
  433. data/vendor/repo.or.cz/nasm/test/vex.asm +9 -0
  434. data/vendor/repo.or.cz/nasm/test/vgather.asm +76 -0
  435. data/vendor/repo.or.cz/nasm/test/vmread.asm +26 -0
  436. data/vendor/repo.or.cz/nasm/test/weirdpaste.asm +29 -0
  437. data/vendor/repo.or.cz/nasm/test/xchg.asm +96 -0
  438. data/vendor/repo.or.cz/nasm/test/xcrypt.asm +24 -0
  439. data/vendor/repo.or.cz/nasm/test/xmm0.asm +12 -0
  440. data/vendor/repo.or.cz/nasm/test/zerobyte.asm +22 -0
  441. data/vendor/repo.or.cz/nasm/tools/cleanfile +176 -0
  442. data/vendor/repo.or.cz/nasm/tools/cleanpatch +258 -0
  443. data/vendor/repo.or.cz/nasm/tools/mkdep.pl +261 -0
  444. data/vendor/repo.or.cz/nasm/tools/release +105 -0
  445. data/vendor/repo.or.cz/nasm/tools/syncfiles.pl +137 -0
  446. data/vendor/repo.or.cz/nasm/tools/tag-release +58 -0
  447. data/vendor/repo.or.cz/nasm/version +1 -0
  448. data/vendor/repo.or.cz/nasm/version.pl +189 -0
  449. data/vendor/repo.or.cz/nasm/x86/disp8.c +131 -0
  450. data/vendor/repo.or.cz/nasm/x86/insns-iflags.ph +280 -0
  451. data/vendor/repo.or.cz/nasm/x86/insns.dat +5371 -0
  452. data/vendor/repo.or.cz/nasm/x86/insns.pl +1043 -0
  453. data/vendor/repo.or.cz/nasm/x86/regs.dat +138 -0
  454. data/vendor/repo.or.cz/nasm/x86/regs.pl +204 -0
  455. metadata +520 -0
@@ -0,0 +1,58 @@
1
+ /* ----------------------------------------------------------------------- *
2
+ *
3
+ * Copyright 1996-2009 The NASM Authors - All Rights Reserved
4
+ * See the file AUTHORS included with the NASM distribution for
5
+ * the specific copyright holders.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following
9
+ * conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above
14
+ * copyright notice, this list of conditions and the following
15
+ * disclaimer in the documentation and/or other materials provided
16
+ * with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ * ----------------------------------------------------------------------- */
33
+
34
+ /*
35
+ * libout.c
36
+ *
37
+ * Common routines for the output backends.
38
+ */
39
+
40
+ #include "compiler.h"
41
+ #include "nasm.h"
42
+ #include "outlib.h"
43
+
44
+ uint64_t realsize(enum out_type type, uint64_t size)
45
+ {
46
+ switch (type) {
47
+ case OUT_REL1ADR:
48
+ return 1;
49
+ case OUT_REL2ADR:
50
+ return 2;
51
+ case OUT_REL4ADR:
52
+ return 4;
53
+ case OUT_REL8ADR:
54
+ return 8;
55
+ default:
56
+ return size;
57
+ }
58
+ }
@@ -0,0 +1,63 @@
1
+ /* ----------------------------------------------------------------------- *
2
+ *
3
+ * Copyright 1996-2016 The NASM Authors - All Rights Reserved
4
+ * See the file AUTHORS included with the NASM distribution for
5
+ * the specific copyright holders.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following
9
+ * conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above
14
+ * copyright notice, this list of conditions and the following
15
+ * disclaimer in the documentation and/or other materials provided
16
+ * with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ * ----------------------------------------------------------------------- */
33
+
34
+ #ifndef NASM_OUTLIB_H
35
+ #define NASM_OUTLIB_H
36
+
37
+ #include "nasm.h"
38
+ #include "error.h"
39
+
40
+ uint64_t realsize(enum out_type type, uint64_t size);
41
+
42
+ /* Do-nothing versions of some output routines */
43
+ enum directive_result
44
+ null_directive(enum directive directive, char *value, int pass);
45
+ void null_sectalign(int32_t seg, unsigned int value);
46
+
47
+ /* Do-nothing versions of all the debug routines */
48
+ void null_debug_init(void);
49
+ void null_debug_linenum(const char *filename, int32_t linenumber,
50
+ int32_t segto);
51
+ void null_debug_deflabel(char *name, int32_t segment, int64_t offset,
52
+ int is_global, char *special);
53
+ void null_debug_directive(const char *directive, const char *params);
54
+ void null_debug_typevalue(int32_t type);
55
+ void null_debug_output(int type, void *param);
56
+ void null_debug_cleanup(void);
57
+ extern const struct dfmt * const null_debug_arr[2];
58
+
59
+ /* Wrapper for unported backends */
60
+ void nasm_do_legacy_output(const struct out_data *data);
61
+
62
+ #endif /* NASM_OUTLIB_H */
63
+
@@ -0,0 +1,2387 @@
1
+ /* ----------------------------------------------------------------------- *
2
+ *
3
+ * Copyright 1996-2017 The NASM Authors - All Rights Reserved
4
+ * See the file AUTHORS included with the NASM distribution for
5
+ * the specific copyright holders.
6
+ *
7
+ * Redistribution and use in source and binary forms, with or without
8
+ * modification, are permitted provided that the following
9
+ * conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above
14
+ * copyright notice, this list of conditions and the following
15
+ * disclaimer in the documentation and/or other materials provided
16
+ * with the distribution.
17
+ *
18
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
19
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
23
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ *
32
+ * ----------------------------------------------------------------------- */
33
+
34
+ /*
35
+ * outmacho.c output routines for the Netwide Assembler to produce
36
+ * NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X object files
37
+ */
38
+
39
+ #include "compiler.h"
40
+
41
+ #include <stdio.h>
42
+ #include <stdlib.h>
43
+ #include <string.h>
44
+ #include <ctype.h>
45
+
46
+ #include "nasm.h"
47
+ #include "nasmlib.h"
48
+ #include "labels.h"
49
+ #include "error.h"
50
+ #include "saa.h"
51
+ #include "raa.h"
52
+ #include "rbtree.h"
53
+ #include "outform.h"
54
+ #include "outlib.h"
55
+ #include "ver.h"
56
+ #include "dwarf.h"
57
+
58
+ #if defined(OF_MACHO) || defined(OF_MACHO64)
59
+
60
+ /* Mach-O in-file header structure sizes */
61
+ #define MACHO_HEADER_SIZE 28
62
+ #define MACHO_SEGCMD_SIZE 56
63
+ #define MACHO_SECTCMD_SIZE 68
64
+ #define MACHO_SYMCMD_SIZE 24
65
+ #define MACHO_NLIST_SIZE 12
66
+ #define MACHO_RELINFO_SIZE 8
67
+
68
+ #define MACHO_HEADER64_SIZE 32
69
+ #define MACHO_SEGCMD64_SIZE 72
70
+ #define MACHO_SECTCMD64_SIZE 80
71
+ #define MACHO_NLIST64_SIZE 16
72
+
73
+ /* Mach-O file header values */
74
+ #define MH_MAGIC 0xfeedface
75
+ #define MH_MAGIC_64 0xfeedfacf
76
+ #define CPU_TYPE_I386 7 /* x86 platform */
77
+ #define CPU_TYPE_X86_64 0x01000007 /* x86-64 platform */
78
+ #define CPU_SUBTYPE_I386_ALL 3 /* all-x86 compatible */
79
+ #define MH_OBJECT 0x1 /* object file */
80
+
81
+ /* Mach-O header flags */
82
+ #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000
83
+
84
+ /* Mach-O load commands */
85
+ #define LC_SEGMENT 0x1 /* 32-bit segment load cmd */
86
+ #define LC_SEGMENT_64 0x19 /* 64-bit segment load cmd */
87
+ #define LC_SYMTAB 0x2 /* symbol table load command */
88
+
89
+ /* Mach-O relocations numbers */
90
+
91
+ /* Generic relocs, used by i386 Mach-O */
92
+ #define GENERIC_RELOC_VANILLA 0 /* Generic relocation */
93
+ #define GENERIC_RELOC_TLV 5 /* Thread local */
94
+
95
+ #define X86_64_RELOC_UNSIGNED 0 /* Absolute address */
96
+ #define X86_64_RELOC_SIGNED 1 /* Signed 32-bit disp */
97
+ #define X86_64_RELOC_BRANCH 2 /* CALL/JMP with 32-bit disp */
98
+ #define X86_64_RELOC_GOT_LOAD 3 /* MOVQ of GOT entry */
99
+ #define X86_64_RELOC_GOT 4 /* Different GOT entry */
100
+ #define X86_64_RELOC_SUBTRACTOR 5 /* Subtracting two symbols */
101
+ #define X86_64_RELOC_SIGNED_1 6 /* SIGNED with -1 addend */
102
+ #define X86_64_RELOC_SIGNED_2 7 /* SIGNED with -2 addend */
103
+ #define X86_64_RELOC_SIGNED_4 8 /* SIGNED with -4 addend */
104
+ #define X86_64_RELOC_TLV 9 /* Thread local */
105
+
106
+ /* Mach-O VM permission constants */
107
+ #define VM_PROT_NONE (0x00)
108
+ #define VM_PROT_READ (0x01)
109
+ #define VM_PROT_WRITE (0x02)
110
+ #define VM_PROT_EXECUTE (0x04)
111
+
112
+ #define VM_PROT_DEFAULT (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
113
+ #define VM_PROT_ALL (VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE)
114
+
115
+ /* Our internal relocation types */
116
+ enum reltype {
117
+ RL_ABS, /* Absolute relocation */
118
+ RL_REL, /* Relative relocation */
119
+ RL_TLV, /* Thread local */
120
+ RL_BRANCH, /* Relative direct branch */
121
+ RL_SUB, /* X86_64_RELOC_SUBTRACT */
122
+ RL_GOT, /* X86_64_RELOC_GOT */
123
+ RL_GOTLOAD /* X86_64_RELOC_GOT_LOAD */
124
+ };
125
+ #define RL_MAX_32 RL_TLV
126
+ #define RL_MAX_64 RL_GOTLOAD
127
+
128
+ struct macho_fmt {
129
+ uint32_t ptrsize; /* Pointer size in bytes */
130
+ uint32_t mh_magic; /* Which magic number to use */
131
+ uint32_t cpu_type; /* Which CPU type */
132
+ uint32_t lc_segment; /* Which segment load command */
133
+ uint32_t header_size; /* Header size */
134
+ uint32_t segcmd_size; /* Segment command size */
135
+ uint32_t sectcmd_size; /* Section command size */
136
+ uint32_t nlist_size; /* Nlist (symbol) size */
137
+ enum reltype maxreltype; /* Maximum entry in enum reltype permitted */
138
+ uint32_t reloc_abs; /* Absolute relocation type */
139
+ uint32_t reloc_rel; /* Relative relocation type */
140
+ uint32_t reloc_tlv; /* Thread local relocation type */
141
+ bool forcesym; /* Always use "external" (symbol-relative) relocations */
142
+ };
143
+
144
+ static struct macho_fmt fmt;
145
+
146
+ static void fwriteptr(uint64_t data, FILE * fp)
147
+ {
148
+ fwriteaddr(data, fmt.ptrsize, fp);
149
+ }
150
+
151
+ struct section {
152
+ /* nasm internal data */
153
+ struct section *next;
154
+ struct SAA *data;
155
+ int32_t index;
156
+ int32_t fileindex;
157
+ struct reloc *relocs;
158
+ struct rbtree *syms[2]; /* All/global symbols symbols in section */
159
+ int align;
160
+ bool by_name; /* This section was specified by full MachO name */
161
+
162
+ /* data that goes into the file */
163
+ char sectname[16]; /* what this section is called */
164
+ char segname[16]; /* segment this section will be in */
165
+ uint64_t addr; /* in-memory address (subject to alignment) */
166
+ uint64_t size; /* in-memory and -file size */
167
+ uint64_t offset; /* in-file offset */
168
+ uint32_t pad; /* padding bytes before section */
169
+ uint32_t nreloc; /* relocation entry count */
170
+ uint32_t flags; /* type and attributes (masked) */
171
+ uint32_t extreloc; /* external relocations */
172
+ };
173
+
174
+ #define SECTION_TYPE 0x000000ff /* section type mask */
175
+
176
+ #define S_REGULAR (0x0) /* standard section */
177
+ #define S_ZEROFILL (0x1) /* zerofill, in-memory only */
178
+
179
+ #define SECTION_ATTRIBUTES_SYS 0x00ffff00 /* system setable attributes */
180
+ #define S_ATTR_SOME_INSTRUCTIONS 0x00000400 /* section contains some
181
+ machine instructions */
182
+ #define S_ATTR_EXT_RELOC 0x00000200 /* section has external relocation entries */
183
+ #define S_ATTR_LOC_RELOC 0x00000100 /* section has local relocation entries */
184
+ #define S_ATTR_DEBUG 0x02000000
185
+ #define S_ATTR_SELF_MODIFYING_CODE 0x04000000
186
+ #define S_ATTR_LIVE_SUPPORT 0x08000000
187
+ #define S_ATTR_NO_DEAD_STRIP 0x10000000 /* no dead stripping */
188
+ #define S_ATTR_STRIP_STATIC_SYMS 0x20000000
189
+ #define S_ATTR_NO_TOC 0x40000000
190
+ #define S_ATTR_PURE_INSTRUCTIONS 0x80000000 /* section uses pure machine instructions */
191
+ #define S_ATTR_DEBUG 0x02000000 /* debug section */
192
+
193
+ #define S_NASM_TYPE_MASK 0x800004ff /* we consider these bits "section type" */
194
+
195
+ /* fake section for absolute symbols, *not* part of the section linked list */
196
+ static struct section absolute_sect;
197
+
198
+ struct reloc {
199
+ /* nasm internal data */
200
+ struct reloc *next;
201
+
202
+ /* data that goes into the file */
203
+ int32_t addr; /* op's offset in section */
204
+ uint32_t snum:24, /* contains symbol index if
205
+ ** ext otherwise in-file
206
+ ** section number */
207
+ pcrel:1, /* relative relocation */
208
+ length:2, /* 0=byte, 1=word, 2=int32_t, 3=int64_t */
209
+ ext:1, /* external symbol referenced */
210
+ type:4; /* reloc type */
211
+ };
212
+
213
+ #define R_ABS 0 /* absolute relocation */
214
+ #define R_SCATTERED 0x80000000 /* reloc entry is scattered if
215
+ ** highest bit == 1 */
216
+
217
+ struct symbol {
218
+ /* nasm internal data */
219
+ struct rbtree symv[2]; /* All/global symbol rbtrees; "key" contains the
220
+ symbol offset. */
221
+ struct symbol *next; /* next symbol in the list */
222
+ char *name; /* name of this symbol */
223
+ int32_t initial_snum; /* symbol number used above in reloc */
224
+ int32_t snum; /* true snum for reloc */
225
+
226
+ /* data that goes into the file */
227
+ uint32_t strx; /* string table index */
228
+ uint8_t type; /* symbol type */
229
+ uint8_t sect; /* NO_SECT or section number */
230
+ uint16_t desc; /* for stab debugging, 0 for us */
231
+ };
232
+
233
+ /* symbol type bits */
234
+ #define N_EXT 0x01 /* global or external symbol */
235
+
236
+ #define N_UNDF 0x0 /* undefined symbol | n_sect == */
237
+ #define N_ABS 0x2 /* absolute symbol | NO_SECT */
238
+ #define N_SECT 0xe /* defined symbol, n_sect holds
239
+ ** section number */
240
+
241
+ #define N_TYPE 0x0e /* type bit mask */
242
+
243
+ #define DEFAULT_SECTION_ALIGNMENT 0 /* byte (i.e. no) alignment */
244
+
245
+ /* special section number values */
246
+ #define NO_SECT 0 /* no section, invalid */
247
+ #define MAX_SECT 255 /* maximum number of sections */
248
+
249
+ static struct section *sects, **sectstail, **sectstab;
250
+ static struct symbol *syms, **symstail;
251
+ static uint32_t nsyms;
252
+
253
+ /* These variables are set by macho_layout_symbols() to organize
254
+ the symbol table and string table in order the dynamic linker
255
+ expects. They are then used in macho_write() to put out the
256
+ symbols and strings in that order.
257
+
258
+ The order of the symbol table is:
259
+ local symbols
260
+ defined external symbols (sorted by name)
261
+ undefined external symbols (sorted by name)
262
+
263
+ The order of the string table is:
264
+ strings for external symbols
265
+ strings for local symbols
266
+ */
267
+ static uint32_t ilocalsym = 0;
268
+ static uint32_t iextdefsym = 0;
269
+ static uint32_t iundefsym = 0;
270
+ static uint32_t nlocalsym;
271
+ static uint32_t nextdefsym;
272
+ static uint32_t nundefsym;
273
+ static struct symbol **extdefsyms = NULL;
274
+ static struct symbol **undefsyms = NULL;
275
+
276
+ static struct RAA *extsyms;
277
+ static struct SAA *strs;
278
+ static uint32_t strslen;
279
+
280
+ /* Global file information. This should be cleaned up into either
281
+ a structure or as function arguments. */
282
+ static uint32_t head_ncmds = 0;
283
+ static uint32_t head_sizeofcmds = 0;
284
+ static uint32_t head_flags = 0;
285
+ static uint64_t seg_filesize = 0;
286
+ static uint64_t seg_vmsize = 0;
287
+ static uint32_t seg_nsects = 0;
288
+ static uint64_t rel_padcnt = 0;
289
+
290
+ /*
291
+ * Functions for handling fixed-length zero-padded string
292
+ * fields, that may or may not be null-terminated.
293
+ */
294
+
295
+ /* Copy a string into a zero-padded fixed-length field */
296
+ #define xstrncpy(xdst, xsrc) strncpy(xdst, xsrc, sizeof(xdst))
297
+
298
+ /* Compare a fixed-length field with a string */
299
+ #define xstrncmp(xdst, xsrc) strncmp(xdst, xsrc, sizeof(xdst))
300
+
301
+ #define alignint32_t(x) \
302
+ ALIGN(x, sizeof(int32_t)) /* align x to int32_t boundary */
303
+
304
+ #define alignint64_t(x) \
305
+ ALIGN(x, sizeof(int64_t)) /* align x to int64_t boundary */
306
+
307
+ #define alignptr(x) \
308
+ ALIGN(x, fmt.ptrsize) /* align x to output format width */
309
+
310
+ static struct section *get_section_by_name(const char *segname,
311
+ const char *sectname)
312
+ {
313
+ struct section *s;
314
+
315
+ for (s = sects; s != NULL; s = s->next)
316
+ if (!xstrncmp(s->segname, segname) && !xstrncmp(s->sectname, sectname))
317
+ break;
318
+
319
+ return s;
320
+ }
321
+
322
+ static struct section *get_section_by_index(const int32_t index)
323
+ {
324
+ struct section *s;
325
+
326
+ for (s = sects; s != NULL; s = s->next)
327
+ if (index == s->index)
328
+ break;
329
+
330
+ return s;
331
+ }
332
+
333
+ struct dir_list {
334
+ struct dir_list *next;
335
+ struct dir_list *last;
336
+ const char *dir_name;
337
+ uint32_t dir;
338
+ };
339
+
340
+ struct file_list {
341
+ struct file_list *next;
342
+ struct file_list *last;
343
+ const char *file_name;
344
+ uint32_t file;
345
+ struct dir_list *dir;
346
+ };
347
+
348
+ struct dw_sect_list {
349
+ struct SAA *psaa;
350
+ int32_t section;
351
+ uint32_t line;
352
+ uint64_t offset;
353
+ uint32_t file;
354
+ struct dw_sect_list *next;
355
+ struct dw_sect_list *last;
356
+ };
357
+
358
+ struct section_info {
359
+ uint64_t size;
360
+ int32_t secto;
361
+ };
362
+
363
+ #define DW_LN_BASE (-5)
364
+ #define DW_LN_RANGE 14
365
+ #define DW_OPCODE_BASE 13
366
+ #define DW_MAX_LN (DW_LN_BASE + DW_LN_RANGE)
367
+ #define DW_MAX_SP_OPCODE 256
368
+
369
+ static struct file_list *dw_head_file = 0, *dw_cur_file = 0, **dw_last_file_next = NULL;
370
+ static struct dir_list *dw_head_dir = 0, **dw_last_dir_next = NULL;
371
+ static struct dw_sect_list *dw_head_sect = 0, *dw_cur_sect = 0, *dw_last_sect = 0;
372
+ static uint32_t cur_line = 0, dw_num_files = 0, dw_num_dirs = 0, dw_num_sects = 0;
373
+ static bool dbg_immcall = false;
374
+ static const char *module_name = NULL;
375
+
376
+ /*
377
+ * Special section numbers which are used to define Mach-O special
378
+ * symbols, which can be used with WRT to provide PIC relocation
379
+ * types.
380
+ */
381
+ static int32_t macho_tlvp_sect;
382
+ static int32_t macho_gotpcrel_sect;
383
+
384
+ static void macho_init(void)
385
+ {
386
+ sects = NULL;
387
+ sectstail = &sects;
388
+
389
+ /* Fake section for absolute symbols */
390
+ absolute_sect.index = NO_SEG;
391
+
392
+ syms = NULL;
393
+ symstail = &syms;
394
+ nsyms = 0;
395
+ nlocalsym = 0;
396
+ nextdefsym = 0;
397
+ nundefsym = 0;
398
+
399
+ extsyms = raa_init();
400
+ strs = saa_init(1L);
401
+
402
+ /* string table starts with a zero byte so index 0 is an empty string */
403
+ saa_wbytes(strs, zero_buffer, 1);
404
+ strslen = 1;
405
+
406
+ /* add special symbol for TLVP */
407
+ macho_tlvp_sect = seg_alloc() + 1;
408
+ define_label("..tlvp", macho_tlvp_sect, 0L, NULL, false, false);
409
+
410
+ }
411
+
412
+ static void sect_write(struct section *sect,
413
+ const uint8_t *data, uint32_t len)
414
+ {
415
+ saa_wbytes(sect->data, data, len);
416
+ sect->size += len;
417
+ }
418
+
419
+ /*
420
+ * Find a suitable global symbol for a ..gotpcrel or ..tlvp reference
421
+ */
422
+ static struct symbol *macho_find_sym(struct section *s, uint64_t offset,
423
+ bool global, bool exact)
424
+ {
425
+ struct rbtree *srb;
426
+
427
+ srb = rb_search(s->syms[global], offset);
428
+
429
+ if (!srb || (exact && srb->key != offset)) {
430
+ nasm_error(ERR_NONFATAL, "unable to find a suitable%s%s symbol"
431
+ " for this reference",
432
+ global ? " global" : "",
433
+ s == &absolute_sect ? " absolute " : "");
434
+ return NULL;
435
+ }
436
+
437
+ return container_of(srb - global, struct symbol, symv);
438
+ }
439
+
440
+ static int64_t add_reloc(struct section *sect, int32_t section,
441
+ int64_t offset,
442
+ enum reltype reltype, int bytes)
443
+ {
444
+ struct reloc *r;
445
+ struct section *s;
446
+ int32_t fi;
447
+ int64_t adjust;
448
+
449
+ /* Double check this is a valid relocation type for this platform */
450
+ nasm_assert(reltype <= fmt.maxreltype);
451
+
452
+ /* the current end of the section will be the symbol's address for
453
+ ** now, might have to be fixed by macho_fixup_relocs() later on. make
454
+ ** sure we don't make the symbol scattered by setting the highest
455
+ ** bit by accident */
456
+ r = nasm_malloc(sizeof(struct reloc));
457
+ r->addr = sect->size & ~R_SCATTERED;
458
+ r->ext = 1;
459
+ adjust = bytes;
460
+
461
+ /* match byte count 1, 2, 4, 8 to length codes 0, 1, 2, 3 respectively */
462
+ r->length = ilog2_32(bytes);
463
+
464
+ /* set default relocation values */
465
+ r->type = fmt.reloc_abs;
466
+ r->pcrel = 0;
467
+ r->snum = R_ABS;
468
+
469
+ s = NULL;
470
+ if (section != NO_SEG)
471
+ s = get_section_by_index(section);
472
+ fi = s ? s->fileindex : NO_SECT;
473
+
474
+ /* absolute relocation */
475
+ switch (reltype) {
476
+ case RL_ABS:
477
+ if (section == NO_SEG) {
478
+ /* absolute (can this even happen?) */
479
+ r->ext = 0;
480
+ r->snum = NO_SECT;
481
+ } else if (fi == NO_SECT) {
482
+ /* external */
483
+ r->snum = raa_read(extsyms, section);
484
+ } else {
485
+ /* local */
486
+ r->ext = 0;
487
+ r->snum = fi;
488
+ adjust = -sect->size;
489
+ }
490
+ break;
491
+
492
+ case RL_REL:
493
+ case RL_BRANCH:
494
+ r->type = fmt.reloc_rel;
495
+ r->pcrel = 1;
496
+ if (section == NO_SEG) {
497
+ /* absolute - seems to produce garbage no matter what */
498
+ nasm_error(ERR_NONFATAL, "Mach-O does not support relative "
499
+ "references to absolute addresses");
500
+ goto bail;
501
+ #if 0
502
+ /* This "seems" to be how it ought to work... */
503
+
504
+ struct symbol *sym = macho_find_sym(&absolute_sect, offset,
505
+ false, false);
506
+ if (!sym)
507
+ goto bail;
508
+
509
+ sect->extreloc = 1;
510
+ r->snum = NO_SECT;
511
+ adjust = -sect->size;
512
+ #endif
513
+ } else if (fi == NO_SECT) {
514
+ /* external */
515
+ sect->extreloc = 1;
516
+ r->snum = raa_read(extsyms, section);
517
+ if (reltype == RL_BRANCH)
518
+ r->type = X86_64_RELOC_BRANCH;
519
+ else if (r->type == GENERIC_RELOC_VANILLA)
520
+ adjust = -sect->size;
521
+ } else {
522
+ /* local */
523
+ r->ext = 0;
524
+ r->snum = fi;
525
+ adjust = -sect->size;
526
+ }
527
+ break;
528
+
529
+ case RL_SUB:
530
+ r->pcrel = 0;
531
+ r->type = X86_64_RELOC_SUBTRACTOR;
532
+ break;
533
+
534
+ case RL_GOT:
535
+ r->type = X86_64_RELOC_GOT;
536
+ goto needsym;
537
+
538
+ case RL_GOTLOAD:
539
+ r->type = X86_64_RELOC_GOT_LOAD;
540
+ goto needsym;
541
+
542
+ case RL_TLV:
543
+ r->type = fmt.reloc_tlv;
544
+ goto needsym;
545
+
546
+ needsym:
547
+ r->pcrel = 1;
548
+ if (section == NO_SEG) {
549
+ nasm_error(ERR_NONFATAL, "Unsupported use of use of WRT");
550
+ } else if (fi == NO_SECT) {
551
+ /* external */
552
+ r->snum = raa_read(extsyms, section);
553
+ } else {
554
+ /* internal - does it really need to be global? */
555
+ struct symbol *sym = macho_find_sym(s, offset, true,
556
+ reltype != RL_TLV);
557
+ if (!sym)
558
+ goto bail;
559
+
560
+ r->snum = sym->initial_snum;
561
+ }
562
+ break;
563
+ }
564
+
565
+ /* For 64-bit Mach-O, force a symbol reference if at all possible */
566
+ if (!r->ext && r->snum != NO_SECT && fmt.forcesym) {
567
+ struct symbol *sym = macho_find_sym(s, offset, false, false);
568
+ if (sym) {
569
+ adjust = bytes - sym->symv[0].key;
570
+ r->snum = sym->initial_snum;
571
+ r->ext = 1;
572
+ }
573
+ }
574
+
575
+ /* NeXT as puts relocs in reversed order (address-wise) into the
576
+ ** files, so we do the same, doesn't seem to make much of a
577
+ ** difference either way */
578
+ r->next = sect->relocs;
579
+ sect->relocs = r;
580
+ if (r->ext)
581
+ sect->extreloc = 1;
582
+ ++sect->nreloc;
583
+
584
+ return adjust;
585
+
586
+ bail:
587
+ nasm_free(r);
588
+ return 0;
589
+ }
590
+
591
+ static void macho_output(int32_t secto, const void *data,
592
+ enum out_type type, uint64_t size,
593
+ int32_t section, int32_t wrt)
594
+ {
595
+ struct section *s;
596
+ int64_t addr, offset;
597
+ uint8_t mydata[16], *p;
598
+ bool is_bss;
599
+ enum reltype reltype;
600
+
601
+ if (secto == NO_SEG) {
602
+ if (type != OUT_RESERVE)
603
+ nasm_error(ERR_NONFATAL, "attempt to assemble code in "
604
+ "[ABSOLUTE] space");
605
+ return;
606
+ }
607
+
608
+ s = get_section_by_index(secto);
609
+
610
+ if (s == NULL) {
611
+ nasm_error(ERR_WARNING, "attempt to assemble code in"
612
+ " section %d: defaulting to `.text'", secto);
613
+ s = get_section_by_name("__TEXT", "__text");
614
+
615
+ /* should never happen */
616
+ if (s == NULL)
617
+ nasm_panic(0, "text section not found");
618
+ }
619
+
620
+ /* debug code generation only for sections tagged with
621
+ * instruction attribute */
622
+ if (s->flags & S_ATTR_SOME_INSTRUCTIONS)
623
+ {
624
+ struct section_info sinfo;
625
+ sinfo.size = s->size;
626
+ sinfo.secto = secto;
627
+ dfmt->debug_output(0, &sinfo);
628
+ }
629
+
630
+ is_bss = (s->flags & SECTION_TYPE) == S_ZEROFILL;
631
+
632
+ if (is_bss && type != OUT_RESERVE) {
633
+ nasm_error(ERR_WARNING, "attempt to initialize memory in "
634
+ "BSS section: ignored");
635
+ s->size += realsize(type, size);
636
+ return;
637
+ }
638
+
639
+ memset(mydata, 0, sizeof(mydata));
640
+
641
+ switch (type) {
642
+ case OUT_RESERVE:
643
+ if (!is_bss) {
644
+ nasm_error(ERR_WARNING, "uninitialized space declared in"
645
+ " %s,%s section: zeroing", s->segname, s->sectname);
646
+
647
+ sect_write(s, NULL, size);
648
+ } else
649
+ s->size += size;
650
+
651
+ break;
652
+
653
+ case OUT_RAWDATA:
654
+ if (section != NO_SEG)
655
+ nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
656
+
657
+ sect_write(s, data, size);
658
+ break;
659
+
660
+ case OUT_ADDRESS:
661
+ {
662
+ int asize = abs((int)size);
663
+
664
+ addr = *(int64_t *)data;
665
+ if (section != NO_SEG) {
666
+ if (section % 2) {
667
+ nasm_error(ERR_NONFATAL, "Mach-O format does not support"
668
+ " section base references");
669
+ } else if (wrt == NO_SEG) {
670
+ if (fmt.ptrsize == 8 && asize != 8) {
671
+ nasm_error(ERR_NONFATAL,
672
+ "Mach-O 64-bit format does not support"
673
+ " 32-bit absolute addresses");
674
+ } else {
675
+ add_reloc(s, section, addr, RL_ABS, asize);
676
+ }
677
+ } else {
678
+ nasm_error(ERR_NONFATAL, "Mach-O format does not support"
679
+ " this use of WRT");
680
+ }
681
+ }
682
+
683
+ p = mydata;
684
+ WRITEADDR(p, addr, asize);
685
+ sect_write(s, mydata, asize);
686
+ break;
687
+ }
688
+
689
+ case OUT_REL2ADR:
690
+ nasm_assert(section != secto);
691
+
692
+ p = mydata;
693
+ offset = *(int64_t *)data;
694
+ addr = offset - size;
695
+
696
+ if (section != NO_SEG && section % 2) {
697
+ nasm_error(ERR_NONFATAL, "Mach-O format does not support"
698
+ " section base references");
699
+ } else if (fmt.ptrsize == 8) {
700
+ nasm_error(ERR_NONFATAL, "Unsupported non-32-bit"
701
+ " Macho-O relocation [2]");
702
+ } else if (wrt != NO_SEG) {
703
+ nasm_error(ERR_NONFATAL, "Mach-O format does not support"
704
+ " this use of WRT");
705
+ wrt = NO_SEG; /* we can at least _try_ to continue */
706
+ } else {
707
+ addr += add_reloc(s, section, addr+size, RL_REL, 2);
708
+ }
709
+
710
+ WRITESHORT(p, addr);
711
+ sect_write(s, mydata, 2);
712
+ break;
713
+
714
+ case OUT_REL4ADR:
715
+ nasm_assert(section != secto);
716
+
717
+ p = mydata;
718
+ offset = *(int64_t *)data;
719
+ addr = offset - size;
720
+ reltype = RL_REL;
721
+
722
+ if (section != NO_SEG && section % 2) {
723
+ nasm_error(ERR_NONFATAL, "Mach-O format does not support"
724
+ " section base references");
725
+ } else if (wrt == NO_SEG) {
726
+ if (fmt.ptrsize == 8 &&
727
+ (s->flags & S_ATTR_SOME_INSTRUCTIONS)) {
728
+ uint8_t opcode[2];
729
+
730
+ opcode[0] = opcode[1] = 0;
731
+
732
+ /* HACK: Retrieve instruction opcode */
733
+ if (likely(s->data->datalen >= 2)) {
734
+ saa_fread(s->data, s->data->datalen-2, opcode, 2);
735
+ } else if (s->data->datalen == 1) {
736
+ saa_fread(s->data, 0, opcode+1, 1);
737
+ }
738
+
739
+ if ((opcode[0] != 0x0f && (opcode[1] & 0xfe) == 0xe8) ||
740
+ (opcode[0] == 0x0f && (opcode[1] & 0xf0) == 0x80)) {
741
+ /* Direct call, jmp, or jcc */
742
+ reltype = RL_BRANCH;
743
+ }
744
+ }
745
+ } else if (wrt == macho_gotpcrel_sect) {
746
+ reltype = RL_GOT;
747
+
748
+ if ((s->flags & S_ATTR_SOME_INSTRUCTIONS) &&
749
+ s->data->datalen >= 3) {
750
+ uint8_t gotload[3];
751
+
752
+ /* HACK: Retrieve instruction opcode */
753
+ saa_fread(s->data, s->data->datalen-3, gotload, 3);
754
+ if ((gotload[0] & 0xf8) == 0x48 &&
755
+ gotload[1] == 0x8b &&
756
+ (gotload[2] & 0307) == 0005) {
757
+ /* movq <reg>,[rel sym wrt ..gotpcrel] */
758
+ reltype = RL_GOTLOAD;
759
+ }
760
+ }
761
+ } else if (wrt == macho_tlvp_sect) {
762
+ reltype = RL_TLV;
763
+ } else {
764
+ nasm_error(ERR_NONFATAL, "Mach-O format does not support"
765
+ " this use of WRT");
766
+ /* continue with RL_REL */
767
+ }
768
+
769
+ addr += add_reloc(s, section, offset, reltype, 4);
770
+ WRITELONG(p, addr);
771
+ sect_write(s, mydata, 4);
772
+ break;
773
+
774
+ default:
775
+ nasm_error(ERR_NONFATAL, "Unrepresentable relocation in Mach-O");
776
+ break;
777
+ }
778
+ }
779
+
780
+ /* Translation table from traditional Unix section names to Mach-O */
781
+ static const struct sectmap {
782
+ const char *nasmsect;
783
+ const char *segname;
784
+ const char *sectname;
785
+ const uint32_t flags;
786
+ } sectmap[] = {
787
+ {".text", "__TEXT", "__text",
788
+ S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS},
789
+ {".data", "__DATA", "__data", S_REGULAR},
790
+ {".rodata", "__DATA", "__const", S_REGULAR},
791
+ {".bss", "__DATA", "__bss", S_ZEROFILL},
792
+ {".debug_abbrev", "__DWARF", "__debug_abbrev", S_ATTR_DEBUG},
793
+ {".debug_info", "__DWARF", "__debug_info", S_ATTR_DEBUG},
794
+ {".debug_line", "__DWARF", "__debug_line", S_ATTR_DEBUG},
795
+ {".debug_str", "__DWARF", "__debug_str", S_ATTR_DEBUG},
796
+ {NULL, NULL, NULL, 0}
797
+ };
798
+
799
+ #define NO_TYPE S_NASM_TYPE_MASK
800
+
801
+ /* Section type or attribute directives */
802
+ static const struct sect_attribs {
803
+ const char *name;
804
+ uint32_t flags;
805
+ } sect_attribs[] = {
806
+ { "data", S_REGULAR },
807
+ { "code", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS|S_ATTR_PURE_INSTRUCTIONS },
808
+ { "mixed", S_REGULAR|S_ATTR_SOME_INSTRUCTIONS },
809
+ { "bss", S_ZEROFILL },
810
+ { "zerofill", S_ZEROFILL },
811
+ { "no_dead_strip", NO_TYPE|S_ATTR_NO_DEAD_STRIP },
812
+ { "live_support", NO_TYPE|S_ATTR_LIVE_SUPPORT },
813
+ { "strip_static_syms", NO_TYPE|S_ATTR_STRIP_STATIC_SYMS },
814
+ { "debug", NO_TYPE|S_ATTR_DEBUG },
815
+ { NULL, 0 }
816
+ };
817
+
818
+ static int32_t macho_section(char *name, int pass, int *bits)
819
+ {
820
+ char *sectionAttributes;
821
+ const struct sectmap *sm;
822
+ struct section *s;
823
+ const char *section, *segment;
824
+ uint32_t flags;
825
+ const struct sect_attribs *sa;
826
+ char *currentAttribute;
827
+ char *comma;
828
+
829
+ bool new_seg;
830
+
831
+ (void)pass;
832
+
833
+ /* Default to the appropriate number of bits. */
834
+ if (!name) {
835
+ *bits = fmt.ptrsize << 3;
836
+ name = ".text";
837
+ sectionAttributes = NULL;
838
+ } else {
839
+ sectionAttributes = name;
840
+ name = nasm_strsep(&sectionAttributes, " \t");
841
+ }
842
+
843
+ section = segment = NULL;
844
+ flags = 0;
845
+
846
+ comma = strchr(name, ',');
847
+ if (comma) {
848
+ int len;
849
+
850
+ *comma = '\0';
851
+ segment = name;
852
+ section = comma+1;
853
+
854
+ len = strlen(segment);
855
+ if (len == 0) {
856
+ nasm_error(ERR_NONFATAL, "empty segment name\n");
857
+ } else if (len > 16) {
858
+ nasm_error(ERR_NONFATAL, "segment name %s too long\n", segment);
859
+ }
860
+
861
+ len = strlen(section);
862
+ if (len == 0) {
863
+ nasm_error(ERR_NONFATAL, "empty section name\n");
864
+ } else if (len > 16) {
865
+ nasm_error(ERR_NONFATAL, "section name %s too long\n", section);
866
+ }
867
+
868
+ if (!strcmp(section, "__text")) {
869
+ flags = S_REGULAR | S_ATTR_SOME_INSTRUCTIONS |
870
+ S_ATTR_PURE_INSTRUCTIONS;
871
+ } else if (!strcmp(section, "__bss")) {
872
+ flags = S_ZEROFILL;
873
+ } else {
874
+ flags = S_REGULAR;
875
+ }
876
+ } else {
877
+ for (sm = sectmap; sm->nasmsect != NULL; ++sm) {
878
+ /* make lookup into section name translation table */
879
+ if (!strcmp(name, sm->nasmsect)) {
880
+ segment = sm->segname;
881
+ section = sm->sectname;
882
+ flags = sm->flags;
883
+ goto found;
884
+ }
885
+ }
886
+ nasm_error(ERR_NONFATAL, "unknown section name\n");
887
+ return NO_SEG;
888
+ }
889
+
890
+ found:
891
+ /* try to find section with that name */
892
+ s = get_section_by_name(segment, section);
893
+
894
+ /* create it if it doesn't exist yet */
895
+ if (!s) {
896
+ new_seg = true;
897
+
898
+ s = *sectstail = nasm_zalloc(sizeof(struct section));
899
+ sectstail = &s->next;
900
+
901
+ s->data = saa_init(1L);
902
+ s->index = seg_alloc();
903
+ s->fileindex = ++seg_nsects;
904
+ s->align = -1;
905
+ s->pad = -1;
906
+ s->offset = -1;
907
+ s->by_name = false;
908
+
909
+ xstrncpy(s->segname, segment);
910
+ xstrncpy(s->sectname, section);
911
+ s->size = 0;
912
+ s->nreloc = 0;
913
+ s->flags = flags;
914
+ } else {
915
+ new_seg = false;
916
+ }
917
+
918
+ if (comma)
919
+ *comma = ','; /* Restore comma */
920
+
921
+ s->by_name = s->by_name || comma; /* Was specified by name */
922
+
923
+ flags = NO_TYPE;
924
+
925
+ while (sectionAttributes &&
926
+ (currentAttribute = nasm_strsep(&sectionAttributes, " \t"))) {
927
+ if (!*currentAttribute)
928
+ continue;
929
+
930
+ if (!nasm_strnicmp("align=", currentAttribute, 6)) {
931
+ char *end;
932
+ int newAlignment, value;
933
+
934
+ value = strtoul(currentAttribute + 6, (char**)&end, 0);
935
+ newAlignment = alignlog2_32(value);
936
+
937
+ if (0 != *end) {
938
+ nasm_error(ERR_NONFATAL,
939
+ "unknown or missing alignment value \"%s\" "
940
+ "specified for section \"%s\"",
941
+ currentAttribute + 6,
942
+ name);
943
+ } else if (0 > newAlignment) {
944
+ nasm_error(ERR_NONFATAL,
945
+ "alignment of %d (for section \"%s\") is not "
946
+ "a power of two",
947
+ value,
948
+ name);
949
+ }
950
+
951
+ if (s->align < newAlignment)
952
+ s->align = newAlignment;
953
+ } else {
954
+ for (sa = sect_attribs; sa->name; sa++) {
955
+ if (!nasm_stricmp(sa->name, currentAttribute)) {
956
+ if ((sa->flags & S_NASM_TYPE_MASK) != NO_TYPE) {
957
+ flags = (flags & ~S_NASM_TYPE_MASK)
958
+ | (sa->flags & S_NASM_TYPE_MASK);
959
+ }
960
+ flags |= sa->flags & ~S_NASM_TYPE_MASK;
961
+ break;
962
+ }
963
+ }
964
+
965
+ if (!sa->name) {
966
+ nasm_error(ERR_NONFATAL,
967
+ "unknown section attribute %s for section %s",
968
+ currentAttribute, name);
969
+ }
970
+ }
971
+ }
972
+
973
+ if ((flags & S_NASM_TYPE_MASK) != NO_TYPE) {
974
+ if (!new_seg && ((s->flags ^ flags) & S_NASM_TYPE_MASK)) {
975
+ nasm_error(ERR_NONFATAL,
976
+ "inconsistent section attributes for section %s\n",
977
+ name);
978
+ } else {
979
+ s->flags = (s->flags & ~S_NASM_TYPE_MASK) | flags;
980
+ }
981
+ } else {
982
+ s->flags |= flags & ~S_NASM_TYPE_MASK;
983
+ }
984
+
985
+ return s->index;
986
+ }
987
+
988
+ static void macho_symdef(char *name, int32_t section, int64_t offset,
989
+ int is_global, char *special)
990
+ {
991
+ struct symbol *sym;
992
+ struct section *s;
993
+
994
+ if (special) {
995
+ nasm_error(ERR_NONFATAL, "The Mach-O output format does "
996
+ "not support any special symbol types");
997
+ return;
998
+ }
999
+
1000
+ if (is_global == 3) {
1001
+ nasm_error(ERR_NONFATAL, "The Mach-O format does not "
1002
+ "(yet) support forward reference fixups.");
1003
+ return;
1004
+ }
1005
+
1006
+ if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
1007
+ /*
1008
+ * This is a NASM special symbol. We never allow it into
1009
+ * the Macho-O symbol table, even if it's a valid one. If it
1010
+ * _isn't_ a valid one, we should barf immediately.
1011
+ */
1012
+ if (strcmp(name, "..gotpcrel") && strcmp(name, "..tlvp"))
1013
+ nasm_error(ERR_NONFATAL, "unrecognized special symbol `%s'", name);
1014
+ return;
1015
+ }
1016
+
1017
+ sym = *symstail = nasm_zalloc(sizeof(struct symbol));
1018
+ sym->next = NULL;
1019
+ symstail = &sym->next;
1020
+
1021
+ sym->name = name;
1022
+ sym->strx = strslen;
1023
+ sym->type = 0;
1024
+ sym->desc = 0;
1025
+ sym->symv[0].key = offset;
1026
+ sym->symv[1].key = offset;
1027
+ sym->initial_snum = -1;
1028
+
1029
+ /* external and common symbols get N_EXT */
1030
+ if (is_global != 0) {
1031
+ sym->type |= N_EXT;
1032
+ }
1033
+
1034
+ if (section == NO_SEG) {
1035
+ /* symbols in no section get absolute */
1036
+ sym->type |= N_ABS;
1037
+ sym->sect = NO_SECT;
1038
+
1039
+ s = &absolute_sect;
1040
+ } else {
1041
+ s = get_section_by_index(section);
1042
+
1043
+ sym->type |= N_SECT;
1044
+
1045
+ /* get the in-file index of the section the symbol was defined in */
1046
+ sym->sect = s ? s->fileindex : NO_SECT;
1047
+
1048
+ /* track the initially allocated symbol number for use in future fix-ups */
1049
+ sym->initial_snum = nsyms;
1050
+
1051
+ if (!s) {
1052
+ /* remember symbol number of references to external
1053
+ ** symbols, this works because every external symbol gets
1054
+ ** its own section number allocated internally by nasm and
1055
+ ** can so be used as a key */
1056
+ extsyms = raa_write(extsyms, section, nsyms);
1057
+
1058
+ switch (is_global) {
1059
+ case 1:
1060
+ case 2:
1061
+ /* there isn't actually a difference between global
1062
+ ** and common symbols, both even have their size in
1063
+ ** sym->symv[0].key */
1064
+ sym->type = N_EXT;
1065
+ break;
1066
+
1067
+ default:
1068
+ /* give an error on unfound section if it's not an
1069
+ ** external or common symbol (assemble_file() does a
1070
+ ** seg_alloc() on every call for them) */
1071
+ nasm_panic(0, "in-file index for section %d not found, is_global = %d", section, is_global);
1072
+ break;
1073
+ }
1074
+ }
1075
+ }
1076
+
1077
+ if (s) {
1078
+ s->syms[0] = rb_insert(s->syms[0], &sym->symv[0]);
1079
+ if (is_global)
1080
+ s->syms[1] = rb_insert(s->syms[1], &sym->symv[1]);
1081
+ }
1082
+
1083
+ ++nsyms;
1084
+ }
1085
+
1086
+ static void macho_sectalign(int32_t seg, unsigned int value)
1087
+ {
1088
+ struct section *s;
1089
+ int align;
1090
+
1091
+ nasm_assert(!(seg & 1));
1092
+
1093
+ s = get_section_by_index(seg);
1094
+
1095
+ if (!s || !is_power2(value))
1096
+ return;
1097
+
1098
+ align = alignlog2_32(value);
1099
+ if (s->align < align)
1100
+ s->align = align;
1101
+ }
1102
+
1103
+ static int32_t macho_segbase(int32_t section)
1104
+ {
1105
+ return section;
1106
+ }
1107
+
1108
+ static void macho_filename(char *inname, char *outname)
1109
+ {
1110
+ standard_extension(inname, outname, ".o");
1111
+ module_name = inname;
1112
+ }
1113
+
1114
+ extern macros_t macho_stdmac[];
1115
+
1116
+ /* Comparison function for qsort symbol layout. */
1117
+ static int layout_compare (const struct symbol **s1,
1118
+ const struct symbol **s2)
1119
+ {
1120
+ return (strcmp ((*s1)->name, (*s2)->name));
1121
+ }
1122
+
1123
+ /* The native assembler does a few things in a similar function
1124
+
1125
+ * Remove temporary labels
1126
+ * Sort symbols according to local, external, undefined (by name)
1127
+ * Order the string table
1128
+
1129
+ We do not remove temporary labels right now.
1130
+
1131
+ numsyms is the total number of symbols we have. strtabsize is the
1132
+ number entries in the string table. */
1133
+
1134
+ static void macho_layout_symbols (uint32_t *numsyms,
1135
+ uint32_t *strtabsize)
1136
+ {
1137
+ struct symbol *sym, **symp;
1138
+ uint32_t i,j;
1139
+
1140
+ *numsyms = 0;
1141
+ *strtabsize = sizeof (char);
1142
+
1143
+ symp = &syms;
1144
+
1145
+ while ((sym = *symp)) {
1146
+ /* Undefined symbols are now external. */
1147
+ if (sym->type == N_UNDF)
1148
+ sym->type |= N_EXT;
1149
+
1150
+ if ((sym->type & N_EXT) == 0) {
1151
+ sym->snum = *numsyms;
1152
+ *numsyms = *numsyms + 1;
1153
+ nlocalsym++;
1154
+ }
1155
+ else {
1156
+ if ((sym->type & N_TYPE) != N_UNDF) {
1157
+ nextdefsym++;
1158
+ } else {
1159
+ nundefsym++;
1160
+ }
1161
+
1162
+ /* If we handle debug info we'll want
1163
+ to check for it here instead of just
1164
+ adding the symbol to the string table. */
1165
+ sym->strx = *strtabsize;
1166
+ saa_wbytes (strs, sym->name, (int32_t)(strlen(sym->name) + 1));
1167
+ *strtabsize += strlen(sym->name) + 1;
1168
+ }
1169
+ symp = &(sym->next);
1170
+ }
1171
+
1172
+ /* Next, sort the symbols. Most of this code is a direct translation from
1173
+ the Apple cctools symbol layout. We need to keep compatibility with that. */
1174
+ /* Set the indexes for symbol groups into the symbol table */
1175
+ ilocalsym = 0;
1176
+ iextdefsym = nlocalsym;
1177
+ iundefsym = nlocalsym + nextdefsym;
1178
+
1179
+ /* allocate arrays for sorting externals by name */
1180
+ extdefsyms = nasm_malloc(nextdefsym * sizeof(struct symbol *));
1181
+ undefsyms = nasm_malloc(nundefsym * sizeof(struct symbol *));
1182
+
1183
+ i = 0;
1184
+ j = 0;
1185
+
1186
+ symp = &syms;
1187
+
1188
+ while ((sym = *symp)) {
1189
+
1190
+ if((sym->type & N_EXT) == 0) {
1191
+ sym->strx = *strtabsize;
1192
+ saa_wbytes (strs, sym->name, (int32_t)(strlen (sym->name) + 1));
1193
+ *strtabsize += strlen(sym->name) + 1;
1194
+ }
1195
+ else {
1196
+ if ((sym->type & N_TYPE) != N_UNDF) {
1197
+ extdefsyms[i++] = sym;
1198
+ } else {
1199
+ undefsyms[j++] = sym;
1200
+ }
1201
+ }
1202
+ symp = &(sym->next);
1203
+ }
1204
+
1205
+ qsort(extdefsyms, nextdefsym, sizeof(struct symbol *),
1206
+ (int (*)(const void *, const void *))layout_compare);
1207
+ qsort(undefsyms, nundefsym, sizeof(struct symbol *),
1208
+ (int (*)(const void *, const void *))layout_compare);
1209
+
1210
+ for(i = 0; i < nextdefsym; i++) {
1211
+ extdefsyms[i]->snum = *numsyms;
1212
+ *numsyms += 1;
1213
+ }
1214
+ for(j = 0; j < nundefsym; j++) {
1215
+ undefsyms[j]->snum = *numsyms;
1216
+ *numsyms += 1;
1217
+ }
1218
+ }
1219
+
1220
+ /* Calculate some values we'll need for writing later. */
1221
+
1222
+ static void macho_calculate_sizes (void)
1223
+ {
1224
+ struct section *s;
1225
+ int fi;
1226
+
1227
+ /* count sections and calculate in-memory and in-file offsets */
1228
+ for (s = sects; s != NULL; s = s->next) {
1229
+ uint64_t newaddr;
1230
+
1231
+ /* recalculate segment address based on alignment and vm size */
1232
+ s->addr = seg_vmsize;
1233
+
1234
+ /* we need section alignment to calculate final section address */
1235
+ if (s->align == -1)
1236
+ s->align = DEFAULT_SECTION_ALIGNMENT;
1237
+
1238
+ newaddr = ALIGN(s->addr, UINT64_C(1) << s->align);
1239
+ s->addr = newaddr;
1240
+
1241
+ seg_vmsize = newaddr + s->size;
1242
+
1243
+ /* zerofill sections aren't actually written to the file */
1244
+ if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1245
+ /*
1246
+ * LLVM/Xcode as always aligns the section data to 4
1247
+ * bytes; there is a comment in the LLVM source code that
1248
+ * perhaps aligning to pointer size would be better.
1249
+ */
1250
+ s->pad = ALIGN(seg_filesize, 4) - seg_filesize;
1251
+ s->offset = seg_filesize + s->pad;
1252
+ seg_filesize += s->size + s->pad;
1253
+
1254
+ /* filesize and vmsize needs to be aligned */
1255
+ seg_vmsize += s->pad;
1256
+ }
1257
+ }
1258
+
1259
+ /* calculate size of all headers, load commands and sections to
1260
+ ** get a pointer to the start of all the raw data */
1261
+ if (seg_nsects > 0) {
1262
+ ++head_ncmds;
1263
+ head_sizeofcmds += fmt.segcmd_size + seg_nsects * fmt.sectcmd_size;
1264
+ }
1265
+
1266
+ if (nsyms > 0) {
1267
+ ++head_ncmds;
1268
+ head_sizeofcmds += MACHO_SYMCMD_SIZE;
1269
+ }
1270
+
1271
+ if (seg_nsects > MAX_SECT) {
1272
+ nasm_fatal(0, "MachO output is limited to %d sections\n",
1273
+ MAX_SECT);
1274
+ }
1275
+
1276
+ /* Create a table of sections by file index to avoid linear search */
1277
+ sectstab = nasm_malloc((seg_nsects + 1) * sizeof(*sectstab));
1278
+ sectstab[NO_SECT] = &absolute_sect;
1279
+ for (s = sects, fi = 1; s != NULL; s = s->next, fi++)
1280
+ sectstab[fi] = s;
1281
+ }
1282
+
1283
+ /* Write out the header information for the file. */
1284
+
1285
+ static void macho_write_header (void)
1286
+ {
1287
+ fwriteint32_t(fmt.mh_magic, ofile); /* magic */
1288
+ fwriteint32_t(fmt.cpu_type, ofile); /* CPU type */
1289
+ fwriteint32_t(CPU_SUBTYPE_I386_ALL, ofile); /* CPU subtype */
1290
+ fwriteint32_t(MH_OBJECT, ofile); /* Mach-O file type */
1291
+ fwriteint32_t(head_ncmds, ofile); /* number of load commands */
1292
+ fwriteint32_t(head_sizeofcmds, ofile); /* size of load commands */
1293
+ fwriteint32_t(head_flags, ofile); /* flags, if any */
1294
+ fwritezero(fmt.header_size - 7*4, ofile); /* reserved fields */
1295
+ }
1296
+
1297
+ /* Write out the segment load command at offset. */
1298
+
1299
+ static uint32_t macho_write_segment (uint64_t offset)
1300
+ {
1301
+ uint64_t rel_base = alignptr(offset + seg_filesize);
1302
+ uint32_t s_reloff = 0;
1303
+ struct section *s;
1304
+
1305
+ fwriteint32_t(fmt.lc_segment, ofile); /* cmd == LC_SEGMENT_64 */
1306
+
1307
+ /* size of load command including section load commands */
1308
+ fwriteint32_t(fmt.segcmd_size + seg_nsects * fmt.sectcmd_size,
1309
+ ofile);
1310
+
1311
+ /* in an MH_OBJECT file all sections are in one unnamed (name
1312
+ ** all zeros) segment */
1313
+ fwritezero(16, ofile);
1314
+ fwriteptr(0, ofile); /* in-memory offset */
1315
+ fwriteptr(seg_vmsize, ofile); /* in-memory size */
1316
+ fwriteptr(offset, ofile); /* in-file offset to data */
1317
+ fwriteptr(seg_filesize, ofile); /* in-file size */
1318
+ fwriteint32_t(VM_PROT_DEFAULT, ofile); /* maximum vm protection */
1319
+ fwriteint32_t(VM_PROT_DEFAULT, ofile); /* initial vm protection */
1320
+ fwriteint32_t(seg_nsects, ofile); /* number of sections */
1321
+ fwriteint32_t(0, ofile); /* no flags */
1322
+
1323
+ /* emit section headers */
1324
+ for (s = sects; s != NULL; s = s->next) {
1325
+ if (s->nreloc) {
1326
+ nasm_assert((s->flags & SECTION_TYPE) != S_ZEROFILL);
1327
+ s->flags |= S_ATTR_LOC_RELOC;
1328
+ if (s->extreloc)
1329
+ s->flags |= S_ATTR_EXT_RELOC;
1330
+ } else if (!xstrncmp(s->segname, "__DATA") &&
1331
+ !xstrncmp(s->sectname, "__const") &&
1332
+ !s->by_name &&
1333
+ !get_section_by_name("__TEXT", "__const")) {
1334
+ /*
1335
+ * The MachO equivalent to .rodata can be either
1336
+ * __DATA,__const or __TEXT,__const; the latter only if
1337
+ * there are no relocations. However, when mixed it is
1338
+ * better to specify the segments explicitly.
1339
+ */
1340
+ xstrncpy(s->segname, "__TEXT");
1341
+ }
1342
+
1343
+ nasm_write(s->sectname, sizeof(s->sectname), ofile);
1344
+ nasm_write(s->segname, sizeof(s->segname), ofile);
1345
+ fwriteptr(s->addr, ofile);
1346
+ fwriteptr(s->size, ofile);
1347
+
1348
+ /* dummy data for zerofill sections or proper values */
1349
+ if ((s->flags & SECTION_TYPE) != S_ZEROFILL) {
1350
+ nasm_assert(s->pad != (uint32_t)-1);
1351
+ offset += s->pad;
1352
+ fwriteint32_t(offset, ofile);
1353
+ offset += s->size;
1354
+ /* Write out section alignment, as a power of two.
1355
+ e.g. 32-bit word alignment would be 2 (2^2 = 4). */
1356
+ fwriteint32_t(s->align, ofile);
1357
+ /* To be compatible with cctools as we emit
1358
+ a zero reloff if we have no relocations. */
1359
+ fwriteint32_t(s->nreloc ? rel_base + s_reloff : 0, ofile);
1360
+ fwriteint32_t(s->nreloc, ofile);
1361
+
1362
+ s_reloff += s->nreloc * MACHO_RELINFO_SIZE;
1363
+ } else {
1364
+ fwriteint32_t(0, ofile);
1365
+ fwriteint32_t(s->align, ofile);
1366
+ fwriteint32_t(0, ofile);
1367
+ fwriteint32_t(0, ofile);
1368
+ }
1369
+
1370
+ fwriteint32_t(s->flags, ofile); /* flags */
1371
+ fwriteint32_t(0, ofile); /* reserved */
1372
+ fwriteptr(0, ofile); /* reserved */
1373
+ }
1374
+
1375
+ rel_padcnt = rel_base - offset;
1376
+ offset = rel_base + s_reloff;
1377
+
1378
+ return offset;
1379
+ }
1380
+
1381
+ /* For a given chain of relocs r, write out the entire relocation
1382
+ chain to the object file. */
1383
+
1384
+ static void macho_write_relocs (struct reloc *r)
1385
+ {
1386
+ while (r) {
1387
+ uint32_t word2;
1388
+
1389
+ fwriteint32_t(r->addr, ofile); /* reloc offset */
1390
+
1391
+ word2 = r->snum;
1392
+ word2 |= r->pcrel << 24;
1393
+ word2 |= r->length << 25;
1394
+ word2 |= r->ext << 27;
1395
+ word2 |= r->type << 28;
1396
+ fwriteint32_t(word2, ofile); /* reloc data */
1397
+ r = r->next;
1398
+ }
1399
+ }
1400
+
1401
+ /* Write out the section data. */
1402
+ static void macho_write_section (void)
1403
+ {
1404
+ struct section *s;
1405
+ struct reloc *r;
1406
+ uint8_t *p;
1407
+ int32_t len;
1408
+ int64_t l;
1409
+ union offset {
1410
+ uint64_t val;
1411
+ uint8_t buf[8];
1412
+ } blk;
1413
+
1414
+ for (s = sects; s != NULL; s = s->next) {
1415
+ if ((s->flags & SECTION_TYPE) == S_ZEROFILL)
1416
+ continue;
1417
+
1418
+ /* Like a.out Mach-O references things in the data or bss
1419
+ * sections by addresses which are actually relative to the
1420
+ * start of the _text_ section, in the _file_. See outaout.c
1421
+ * for more information. */
1422
+ saa_rewind(s->data);
1423
+ for (r = s->relocs; r != NULL; r = r->next) {
1424
+ len = (uint32_t)1 << r->length;
1425
+ if (len > 4) /* Can this ever be an issue?! */
1426
+ len = 8;
1427
+ blk.val = 0;
1428
+ saa_fread(s->data, r->addr, blk.buf, len);
1429
+
1430
+ /* get offset based on relocation type */
1431
+ #ifdef WORDS_LITTLEENDIAN
1432
+ l = blk.val;
1433
+ #else
1434
+ l = blk.buf[0];
1435
+ l += ((int64_t)blk.buf[1]) << 8;
1436
+ l += ((int64_t)blk.buf[2]) << 16;
1437
+ l += ((int64_t)blk.buf[3]) << 24;
1438
+ l += ((int64_t)blk.buf[4]) << 32;
1439
+ l += ((int64_t)blk.buf[5]) << 40;
1440
+ l += ((int64_t)blk.buf[6]) << 48;
1441
+ l += ((int64_t)blk.buf[7]) << 56;
1442
+ #endif
1443
+
1444
+ /* If the relocation is internal add to the current section
1445
+ offset. Otherwise the only value we need is the symbol
1446
+ offset which we already have. The linker takes care
1447
+ of the rest of the address. */
1448
+ if (!r->ext) {
1449
+ /* generate final address by section address and offset */
1450
+ nasm_assert(r->snum <= seg_nsects);
1451
+ l += sectstab[r->snum]->addr;
1452
+ if (r->pcrel)
1453
+ l -= s->addr;
1454
+ } else if (r->pcrel && r->type == GENERIC_RELOC_VANILLA) {
1455
+ l -= s->addr;
1456
+ }
1457
+
1458
+ /* write new offset back */
1459
+ p = blk.buf;
1460
+ WRITEDLONG(p, l);
1461
+ saa_fwrite(s->data, r->addr, blk.buf, len);
1462
+ }
1463
+
1464
+ /* dump the section data to file */
1465
+ fwritezero(s->pad, ofile);
1466
+ saa_fpwrite(s->data, ofile);
1467
+ }
1468
+
1469
+ /* pad last section up to reloc entries on pointer boundary */
1470
+ fwritezero(rel_padcnt, ofile);
1471
+
1472
+ /* emit relocation entries */
1473
+ for (s = sects; s != NULL; s = s->next)
1474
+ macho_write_relocs (s->relocs);
1475
+ }
1476
+
1477
+ /* Write out the symbol table. We should already have sorted this
1478
+ before now. */
1479
+ static void macho_write_symtab (void)
1480
+ {
1481
+ struct symbol *sym;
1482
+ uint64_t i;
1483
+
1484
+ /* we don't need to pad here since MACHO_RELINFO_SIZE == 8 */
1485
+
1486
+ for (sym = syms; sym != NULL; sym = sym->next) {
1487
+ if ((sym->type & N_EXT) == 0) {
1488
+ fwriteint32_t(sym->strx, ofile); /* string table entry number */
1489
+ nasm_write(&sym->type, 1, ofile); /* symbol type */
1490
+ nasm_write(&sym->sect, 1, ofile); /* section */
1491
+ fwriteint16_t(sym->desc, ofile); /* description */
1492
+
1493
+ /* Fix up the symbol value now that we know the final section
1494
+ sizes. */
1495
+ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1496
+ nasm_assert(sym->sect <= seg_nsects);
1497
+ sym->symv[0].key += sectstab[sym->sect]->addr;
1498
+ }
1499
+
1500
+ fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1501
+ }
1502
+ }
1503
+
1504
+ for (i = 0; i < nextdefsym; i++) {
1505
+ sym = extdefsyms[i];
1506
+ fwriteint32_t(sym->strx, ofile);
1507
+ nasm_write(&sym->type, 1, ofile); /* symbol type */
1508
+ nasm_write(&sym->sect, 1, ofile); /* section */
1509
+ fwriteint16_t(sym->desc, ofile); /* description */
1510
+
1511
+ /* Fix up the symbol value now that we know the final section
1512
+ sizes. */
1513
+ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1514
+ nasm_assert(sym->sect <= seg_nsects);
1515
+ sym->symv[0].key += sectstab[sym->sect]->addr;
1516
+ }
1517
+
1518
+ fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1519
+ }
1520
+
1521
+ for (i = 0; i < nundefsym; i++) {
1522
+ sym = undefsyms[i];
1523
+ fwriteint32_t(sym->strx, ofile);
1524
+ nasm_write(&sym->type, 1, ofile); /* symbol type */
1525
+ nasm_write(&sym->sect, 1, ofile); /* section */
1526
+ fwriteint16_t(sym->desc, ofile); /* description */
1527
+
1528
+ /* Fix up the symbol value now that we know the final section
1529
+ sizes. */
1530
+ if (((sym->type & N_TYPE) == N_SECT) && (sym->sect != NO_SECT)) {
1531
+ nasm_assert(sym->sect <= seg_nsects);
1532
+ sym->symv[0].key += sectstab[sym->sect]->addr;
1533
+ }
1534
+
1535
+ fwriteptr(sym->symv[0].key, ofile); /* value (i.e. offset) */
1536
+ }
1537
+
1538
+ }
1539
+
1540
+ /* Fixup the snum in the relocation entries, we should be
1541
+ doing this only for externally referenced symbols. */
1542
+ static void macho_fixup_relocs (struct reloc *r)
1543
+ {
1544
+ struct symbol *sym;
1545
+
1546
+ while (r != NULL) {
1547
+ if (r->ext) {
1548
+ for (sym = syms; sym != NULL; sym = sym->next) {
1549
+ if (sym->initial_snum == r->snum) {
1550
+ r->snum = sym->snum;
1551
+ break;
1552
+ }
1553
+ }
1554
+ }
1555
+ r = r->next;
1556
+ }
1557
+ }
1558
+
1559
+ /* Write out the object file. */
1560
+
1561
+ static void macho_write (void)
1562
+ {
1563
+ uint64_t offset = 0;
1564
+
1565
+ /* mach-o object file structure:
1566
+ **
1567
+ ** mach header
1568
+ ** uint32_t magic
1569
+ ** int cpu type
1570
+ ** int cpu subtype
1571
+ ** uint32_t mach file type
1572
+ ** uint32_t number of load commands
1573
+ ** uint32_t size of all load commands
1574
+ ** (includes section struct size of segment command)
1575
+ ** uint32_t flags
1576
+ **
1577
+ ** segment command
1578
+ ** uint32_t command type == LC_SEGMENT[_64]
1579
+ ** uint32_t size of load command
1580
+ ** (including section load commands)
1581
+ ** char[16] segment name
1582
+ ** pointer in-memory offset
1583
+ ** pointer in-memory size
1584
+ ** pointer in-file offset to data area
1585
+ ** pointer in-file size
1586
+ ** (in-memory size excluding zerofill sections)
1587
+ ** int maximum vm protection
1588
+ ** int initial vm protection
1589
+ ** uint32_t number of sections
1590
+ ** uint32_t flags
1591
+ **
1592
+ ** section commands
1593
+ ** char[16] section name
1594
+ ** char[16] segment name
1595
+ ** pointer in-memory offset
1596
+ ** pointer in-memory size
1597
+ ** uint32_t in-file offset
1598
+ ** uint32_t alignment
1599
+ ** (irrelevant in MH_OBJECT)
1600
+ ** uint32_t in-file offset of relocation entires
1601
+ ** uint32_t number of relocations
1602
+ ** uint32_t flags
1603
+ ** uint32_t reserved
1604
+ ** uint32_t reserved
1605
+ **
1606
+ ** symbol table command
1607
+ ** uint32_t command type == LC_SYMTAB
1608
+ ** uint32_t size of load command
1609
+ ** uint32_t symbol table offset
1610
+ ** uint32_t number of symbol table entries
1611
+ ** uint32_t string table offset
1612
+ ** uint32_t string table size
1613
+ **
1614
+ ** raw section data
1615
+ **
1616
+ ** padding to pointer boundary
1617
+ **
1618
+ ** relocation data (struct reloc)
1619
+ ** int32_t offset
1620
+ ** uint data (symbolnum, pcrel, length, extern, type)
1621
+ **
1622
+ ** symbol table data (struct nlist)
1623
+ ** int32_t string table entry number
1624
+ ** uint8_t type
1625
+ ** (extern, absolute, defined in section)
1626
+ ** uint8_t section
1627
+ ** (0 for global symbols, section number of definition (>= 1, <=
1628
+ ** 254) for local symbols, size of variable for common symbols
1629
+ ** [type == extern])
1630
+ ** int16_t description
1631
+ ** (for stab debugging format)
1632
+ ** pointer value (i.e. file offset) of symbol or stab offset
1633
+ **
1634
+ ** string table data
1635
+ ** list of null-terminated strings
1636
+ */
1637
+
1638
+ /* Emit the Mach-O header. */
1639
+ macho_write_header();
1640
+
1641
+ offset = fmt.header_size + head_sizeofcmds;
1642
+
1643
+ /* emit the segment load command */
1644
+ if (seg_nsects > 0)
1645
+ offset = macho_write_segment (offset);
1646
+ else
1647
+ nasm_error(ERR_WARNING, "no sections?");
1648
+
1649
+ if (nsyms > 0) {
1650
+ /* write out symbol command */
1651
+ fwriteint32_t(LC_SYMTAB, ofile); /* cmd == LC_SYMTAB */
1652
+ fwriteint32_t(MACHO_SYMCMD_SIZE, ofile); /* size of load command */
1653
+ fwriteint32_t(offset, ofile); /* symbol table offset */
1654
+ fwriteint32_t(nsyms, ofile); /* number of symbol
1655
+ ** table entries */
1656
+ offset += nsyms * fmt.nlist_size;
1657
+ fwriteint32_t(offset, ofile); /* string table offset */
1658
+ fwriteint32_t(strslen, ofile); /* string table size */
1659
+ }
1660
+
1661
+ /* emit section data */
1662
+ if (seg_nsects > 0)
1663
+ macho_write_section ();
1664
+
1665
+ /* emit symbol table if we have symbols */
1666
+ if (nsyms > 0)
1667
+ macho_write_symtab ();
1668
+
1669
+ /* we don't need to pad here, we are already aligned */
1670
+
1671
+ /* emit string table */
1672
+ saa_fpwrite(strs, ofile);
1673
+ }
1674
+ /* We do quite a bit here, starting with finalizing all of the data
1675
+ for the object file, writing, and then freeing all of the data from
1676
+ the file. */
1677
+
1678
+ static void macho_cleanup(void)
1679
+ {
1680
+ struct section *s;
1681
+ struct reloc *r;
1682
+ struct symbol *sym;
1683
+
1684
+ dfmt->cleanup();
1685
+
1686
+ /* Sort all symbols. */
1687
+ macho_layout_symbols (&nsyms, &strslen);
1688
+
1689
+ /* Fixup relocation entries */
1690
+ for (s = sects; s != NULL; s = s->next) {
1691
+ macho_fixup_relocs (s->relocs);
1692
+ }
1693
+
1694
+ /* First calculate and finalize needed values. */
1695
+ macho_calculate_sizes();
1696
+ macho_write();
1697
+
1698
+ /* free up everything */
1699
+ while (sects->next) {
1700
+ s = sects;
1701
+ sects = sects->next;
1702
+
1703
+ saa_free(s->data);
1704
+ while (s->relocs != NULL) {
1705
+ r = s->relocs;
1706
+ s->relocs = s->relocs->next;
1707
+ nasm_free(r);
1708
+ }
1709
+
1710
+ nasm_free(s);
1711
+ }
1712
+
1713
+ saa_free(strs);
1714
+ raa_free(extsyms);
1715
+
1716
+ while (syms) {
1717
+ sym = syms;
1718
+ syms = syms->next;
1719
+ nasm_free (sym);
1720
+ }
1721
+
1722
+ nasm_free(extdefsyms);
1723
+ nasm_free(undefsyms);
1724
+ nasm_free(sectstab);
1725
+ }
1726
+
1727
+ static bool macho_set_section_attribute_by_symbol(const char *label, uint32_t flags)
1728
+ {
1729
+ struct section *s;
1730
+ int32_t nasm_seg;
1731
+ int64_t offset;
1732
+
1733
+ if (!lookup_label(label, &nasm_seg, &offset)) {
1734
+ nasm_error(ERR_NONFATAL, "unknown symbol `%s' in no_dead_strip", label);
1735
+ return false;
1736
+ }
1737
+
1738
+ s = get_section_by_index(nasm_seg);
1739
+ if (!s) {
1740
+ nasm_error(ERR_NONFATAL, "symbol `%s' is external or absolute", label);
1741
+ return false;
1742
+ }
1743
+
1744
+ s->flags |= flags;
1745
+ return true;
1746
+ }
1747
+
1748
+ /*
1749
+ * Mark a symbol for no dead stripping
1750
+ */
1751
+ static enum directive_result macho_no_dead_strip(const char *labels)
1752
+ {
1753
+ char *s, *p, *ep;
1754
+ char ec;
1755
+ enum directive_result rv = DIRR_ERROR;
1756
+ bool real = passn > 1;
1757
+
1758
+ p = s = nasm_strdup(labels);
1759
+ while (*p) {
1760
+ ep = nasm_skip_identifier(p);
1761
+ if (!ep) {
1762
+ nasm_error(ERR_NONFATAL, "invalid symbol in NO_DEAD_STRIP");
1763
+ goto err;
1764
+ }
1765
+ ec = *ep;
1766
+ if (ec && ec != ',' && !nasm_isspace(ec)) {
1767
+ nasm_error(ERR_NONFATAL, "cannot parse contents after symbol");
1768
+ goto err;
1769
+ }
1770
+ *ep = '\0';
1771
+ if (real) {
1772
+ if (!macho_set_section_attribute_by_symbol(p, S_ATTR_NO_DEAD_STRIP))
1773
+ rv = DIRR_ERROR;
1774
+ }
1775
+ *ep = ec;
1776
+ p = nasm_skip_spaces(ep);
1777
+ if (*p == ',')
1778
+ p = nasm_skip_spaces(++p);
1779
+ }
1780
+
1781
+ rv = DIRR_OK;
1782
+
1783
+ err:
1784
+ nasm_free(s);
1785
+ return rv;
1786
+ }
1787
+
1788
+ /*
1789
+ * Mach-O pragmas
1790
+ */
1791
+ static enum directive_result
1792
+ macho_pragma(const struct pragma *pragma)
1793
+ {
1794
+ bool real = passn > 1;
1795
+
1796
+ switch (pragma->opcode) {
1797
+ case D_SUBSECTIONS_VIA_SYMBOLS:
1798
+ if (*pragma->tail)
1799
+ return DIRR_BADPARAM;
1800
+
1801
+ if (real)
1802
+ head_flags |= MH_SUBSECTIONS_VIA_SYMBOLS;
1803
+
1804
+ return DIRR_OK;
1805
+
1806
+ case D_NO_DEAD_STRIP:
1807
+ return macho_no_dead_strip(pragma->tail);
1808
+
1809
+ default:
1810
+ return DIRR_UNKNOWN; /* Not a Mach-O directive */
1811
+ }
1812
+ }
1813
+
1814
+ static const struct pragma_facility macho_pragma_list[] = {
1815
+ { "macho", macho_pragma },
1816
+ { NULL, macho_pragma } /* Implements macho32/macho64 namespaces */
1817
+ };
1818
+
1819
+ static void macho_dbg_generate(void)
1820
+ {
1821
+ uint8_t *p_buf = NULL, *p_buf_base = NULL;
1822
+ size_t saa_len = 0, high_addr = 0, total_len = 0;
1823
+ struct section *p_section = NULL;
1824
+ /* calculated at debug_str and referenced at debug_info */
1825
+ uint32_t producer_str_offset = 0, module_str_offset = 0, dir_str_offset = 0;
1826
+
1827
+ /* debug section defines */
1828
+ {
1829
+ int bits = 0;
1830
+ macho_section(".debug_abbrev", 0, &bits);
1831
+ macho_section(".debug_info", 0, &bits);
1832
+ macho_section(".debug_line", 0, &bits);
1833
+ macho_section(".debug_str", 0, &bits);
1834
+ }
1835
+
1836
+ /* dw section walk to find high_addr and total_len */
1837
+ {
1838
+ struct dw_sect_list *p_sect;
1839
+
1840
+ list_for_each(p_sect, dw_head_sect) {
1841
+ uint64_t offset = get_section_by_index(p_sect->section)->size;
1842
+ struct SAA *p_linep = p_sect->psaa;
1843
+
1844
+ saa_write8(p_linep, 2); /* std op 2 */
1845
+ saa_write8(p_linep, offset - p_sect->offset);
1846
+ saa_write8(p_linep, DW_LNS_extended_op);
1847
+ saa_write8(p_linep, 1); /* operand length */
1848
+ saa_write8(p_linep, DW_LNE_end_sequence);
1849
+
1850
+ total_len += p_linep->datalen;
1851
+ high_addr += offset;
1852
+ }
1853
+ }
1854
+
1855
+ /* debug line */
1856
+ {
1857
+ struct dw_sect_list *p_sect;
1858
+ size_t linep_off, buf_size;
1859
+ struct SAA *p_lines = saa_init(1L);
1860
+ struct dir_list *p_dir;
1861
+ struct file_list *p_file;
1862
+
1863
+ p_section = get_section_by_name("__DWARF", "__debug_line");
1864
+ nasm_assert(p_section != NULL);
1865
+
1866
+ saa_write8(p_lines, 1); /* minimum instruction length */
1867
+ saa_write8(p_lines, 1); /* initial value of "is_stmt" */
1868
+ saa_write8(p_lines, DW_LN_BASE); /* line base */
1869
+ saa_write8(p_lines, DW_LN_RANGE); /* line range */
1870
+ saa_write8(p_lines, DW_OPCODE_BASE); /* opcode base */
1871
+ saa_write8(p_lines, 0); /* std opcode 1 length */
1872
+ saa_write8(p_lines, 1); /* std opcode 2 length */
1873
+ saa_write8(p_lines, 1); /* std opcode 3 length */
1874
+ saa_write8(p_lines, 1); /* std opcode 4 length */
1875
+ saa_write8(p_lines, 1); /* std opcode 5 length */
1876
+ saa_write8(p_lines, 0); /* std opcode 6 length */
1877
+ saa_write8(p_lines, 0); /* std opcode 7 length */
1878
+ saa_write8(p_lines, 0); /* std opcode 8 length */
1879
+ saa_write8(p_lines, 1); /* std opcode 9 length */
1880
+ saa_write8(p_lines, 0); /* std opcode 10 length */
1881
+ saa_write8(p_lines, 0); /* std opcode 11 length */
1882
+ saa_write8(p_lines, 1); /* std opcode 12 length */
1883
+ list_for_each(p_dir, dw_head_dir) {
1884
+ saa_wcstring(p_lines, p_dir->dir_name);
1885
+ }
1886
+ saa_write8(p_lines, 0); /* end of table */
1887
+
1888
+ list_for_each(p_file, dw_head_file) {
1889
+ saa_wcstring(p_lines, p_file->file_name);
1890
+ saa_write8(p_lines, p_file->dir->dir); /* directory id */
1891
+ saa_write8(p_lines, 0); /* time */
1892
+ saa_write8(p_lines, 0); /* size */
1893
+ }
1894
+ saa_write8(p_lines, 0); /* end of table */
1895
+
1896
+ linep_off = p_lines->datalen;
1897
+ /* 10 bytes for initial & prolong length, and dwarf version info */
1898
+ buf_size = saa_len = linep_off + total_len + 10;
1899
+ p_buf_base = p_buf = nasm_malloc(buf_size);
1900
+
1901
+ WRITELONG(p_buf, saa_len - 4); /* initial length; size excluding itself */
1902
+ WRITESHORT(p_buf, 2); /* dwarf version */
1903
+ WRITELONG(p_buf, linep_off); /* prolong length */
1904
+
1905
+ saa_rnbytes(p_lines, p_buf, linep_off);
1906
+ p_buf += linep_off;
1907
+ saa_free(p_lines);
1908
+
1909
+ list_for_each(p_sect, dw_head_sect) {
1910
+ struct SAA *p_linep = p_sect->psaa;
1911
+
1912
+ saa_len = p_linep->datalen;
1913
+ saa_rnbytes(p_linep, p_buf, saa_len);
1914
+ p_buf += saa_len;
1915
+
1916
+ saa_free(p_linep);
1917
+ }
1918
+
1919
+ macho_output(p_section->index, p_buf_base, OUT_RAWDATA, buf_size, NO_SEG, 0);
1920
+
1921
+ nasm_free(p_buf_base);
1922
+ }
1923
+
1924
+ /* string section */
1925
+ {
1926
+ struct SAA *p_str = saa_init(1L);
1927
+ char *cur_path = nasm_realpath(module_name);
1928
+ char *cur_file = nasm_basename(cur_path);
1929
+ char *cur_dir = nasm_dirname(cur_path);
1930
+
1931
+ p_section = get_section_by_name("__DWARF", "__debug_str");
1932
+ nasm_assert(p_section != NULL);
1933
+
1934
+ producer_str_offset = 0;
1935
+ module_str_offset = dir_str_offset = saa_wcstring(p_str, nasm_signature);
1936
+ dir_str_offset += saa_wcstring(p_str, cur_file);
1937
+ saa_wcstring(p_str, cur_dir);
1938
+
1939
+ saa_len = p_str->datalen;
1940
+ p_buf = nasm_malloc(saa_len);
1941
+ saa_rnbytes(p_str, p_buf, saa_len);
1942
+ macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
1943
+
1944
+ nasm_free(cur_path);
1945
+ nasm_free(cur_file);
1946
+ nasm_free(cur_dir);
1947
+ saa_free(p_str);
1948
+ nasm_free(p_buf);
1949
+ }
1950
+
1951
+ /* debug info */
1952
+ {
1953
+ struct SAA *p_info = saa_init(1L);
1954
+
1955
+ p_section = get_section_by_name("__DWARF", "__debug_info");
1956
+ nasm_assert(p_section != NULL);
1957
+
1958
+ /* size will be overwritten once determined, so skip in p_info layout */
1959
+ saa_write16(p_info, 2); /* dwarf version */
1960
+ saa_write32(p_info, 0); /* offset info abbrev */
1961
+ saa_write8(p_info, (ofmt == &of_macho64) ? 8 : 4); /* pointer size */
1962
+
1963
+ saa_write8(p_info, 1); /* abbrev entry number */
1964
+
1965
+ saa_write32(p_info, producer_str_offset); /* offset from string table for DW_AT_producer */
1966
+ saa_write16(p_info, DW_LANG_Mips_Assembler); /* DW_AT_language */
1967
+ saa_write32(p_info, module_str_offset); /* offset from string table for DW_AT_name */
1968
+ saa_write32(p_info, dir_str_offset); /* offset from string table for DW_AT_comp_dir */
1969
+ saa_write32(p_info, 0); /* DW_AT_stmt_list */
1970
+
1971
+ if (ofmt == &of_macho64) {
1972
+ saa_write64(p_info, 0); /* DW_AT_low_pc */
1973
+ saa_write64(p_info, high_addr); /* DW_AT_high_pc */
1974
+ } else {
1975
+ saa_write32(p_info, 0); /* DW_AT_low_pc */
1976
+ saa_write32(p_info, high_addr); /* DW_AT_high_pc */
1977
+ }
1978
+
1979
+ saa_write8(p_info, 2); /* abbrev entry number */
1980
+
1981
+ if (ofmt == &of_macho64) {
1982
+ saa_write64(p_info, 0); /* DW_AT_low_pc */
1983
+ saa_write64(p_info, 0); /* DW_AT_frame_base */
1984
+ } else {
1985
+ saa_write32(p_info, 0); /* DW_AT_low_pc */
1986
+ saa_write32(p_info, 0); /* DW_AT_frame_base */
1987
+ }
1988
+ saa_write8(p_info, DW_END_default);
1989
+
1990
+ saa_len = p_info->datalen;
1991
+ p_buf_base = p_buf = nasm_malloc(saa_len + 4); /* 4B for size info */
1992
+
1993
+ WRITELONG(p_buf, saa_len);
1994
+ saa_rnbytes(p_info, p_buf, saa_len);
1995
+ macho_output(p_section->index, p_buf_base, OUT_RAWDATA, saa_len + 4, NO_SEG, 0);
1996
+
1997
+ saa_free(p_info);
1998
+ nasm_free(p_buf_base);
1999
+ }
2000
+
2001
+ /* abbrev section */
2002
+ {
2003
+ struct SAA *p_abbrev = saa_init(1L);
2004
+
2005
+ p_section = get_section_by_name("__DWARF", "__debug_abbrev");
2006
+ nasm_assert(p_section != NULL);
2007
+
2008
+ saa_write8(p_abbrev, 1); /* entry number */
2009
+
2010
+ saa_write8(p_abbrev, DW_TAG_compile_unit);
2011
+ saa_write8(p_abbrev, DW_CHILDREN_yes);
2012
+
2013
+ saa_write8(p_abbrev, DW_AT_producer);
2014
+ saa_write8(p_abbrev, DW_FORM_strp);
2015
+
2016
+ saa_write8(p_abbrev, DW_AT_language);
2017
+ saa_write8(p_abbrev, DW_FORM_data2);
2018
+
2019
+ saa_write8(p_abbrev, DW_AT_name);
2020
+ saa_write8(p_abbrev, DW_FORM_strp);
2021
+
2022
+ saa_write8(p_abbrev, DW_AT_comp_dir);
2023
+ saa_write8(p_abbrev, DW_FORM_strp);
2024
+
2025
+ saa_write8(p_abbrev, DW_AT_stmt_list);
2026
+ saa_write8(p_abbrev, DW_FORM_data4);
2027
+
2028
+ saa_write8(p_abbrev, DW_AT_low_pc);
2029
+ saa_write8(p_abbrev, DW_FORM_addr);
2030
+
2031
+ saa_write8(p_abbrev, DW_AT_high_pc);
2032
+ saa_write8(p_abbrev, DW_FORM_addr);
2033
+
2034
+ saa_write16(p_abbrev, DW_END_default);
2035
+
2036
+ saa_write8(p_abbrev, 2); /* entry number */
2037
+
2038
+ saa_write8(p_abbrev, DW_TAG_subprogram);
2039
+ saa_write8(p_abbrev, DW_CHILDREN_no);
2040
+
2041
+ saa_write8(p_abbrev, DW_AT_low_pc);
2042
+ saa_write8(p_abbrev, DW_FORM_addr);
2043
+
2044
+ saa_write8(p_abbrev, DW_AT_frame_base);
2045
+ saa_write8(p_abbrev, DW_FORM_addr);
2046
+
2047
+ saa_write16(p_abbrev, DW_END_default);
2048
+
2049
+ saa_write8(p_abbrev, 0); /* Terminal zero entry */
2050
+
2051
+ saa_len = p_abbrev->datalen;
2052
+
2053
+ p_buf = nasm_malloc(saa_len);
2054
+
2055
+ saa_rnbytes(p_abbrev, p_buf, saa_len);
2056
+ macho_output(p_section->index, p_buf, OUT_RAWDATA, saa_len, NO_SEG, 0);
2057
+
2058
+ saa_free(p_abbrev);
2059
+ nasm_free(p_buf);
2060
+ }
2061
+ }
2062
+
2063
+ static void new_file_list (const char *file_name, const char *dir_name)
2064
+ {
2065
+ struct dir_list *dir_list;
2066
+ bool need_new_dir_list = true;
2067
+
2068
+ nasm_new(dw_cur_file);
2069
+ dw_cur_file->file = ++dw_num_files;
2070
+ dw_cur_file->file_name = file_name;
2071
+ if(!dw_head_file) {
2072
+ dw_head_file = dw_cur_file;
2073
+ } else {
2074
+ *dw_last_file_next = dw_cur_file;
2075
+ }
2076
+ dw_last_file_next = &(dw_cur_file->next);
2077
+
2078
+ if(dw_head_dir) {
2079
+ list_for_each(dir_list, dw_head_dir) {
2080
+ if(!(strcmp(dir_name, dir_list->dir_name))) {
2081
+ dw_cur_file->dir = dir_list;
2082
+ need_new_dir_list = false;
2083
+ break;
2084
+ }
2085
+ }
2086
+ }
2087
+
2088
+ if(need_new_dir_list)
2089
+ {
2090
+ nasm_new(dir_list);
2091
+ dir_list->dir = dw_num_dirs++;
2092
+ dir_list->dir_name = dir_name;
2093
+ if(!dw_head_dir) {
2094
+ dw_head_dir = dir_list;
2095
+ } else {
2096
+ *dw_last_dir_next = dir_list;
2097
+ }
2098
+ dw_last_dir_next = &(dir_list->next);
2099
+ dw_cur_file->dir = dir_list;
2100
+ }
2101
+ }
2102
+
2103
+ static void macho_dbg_init(void)
2104
+ {
2105
+ }
2106
+
2107
+ static void macho_dbg_linenum(const char *file_name, int32_t line_num, int32_t segto)
2108
+ {
2109
+ bool need_new_list = true;
2110
+ const char *cur_file = nasm_basename(file_name);
2111
+ const char *cur_dir = nasm_dirname(file_name);
2112
+ (void)segto;
2113
+
2114
+ if(!dw_cur_file || strcmp(cur_file, dw_cur_file->file_name) ||
2115
+ strcmp(cur_dir, dw_cur_file->dir->dir_name)) {
2116
+ if(dw_head_file) {
2117
+ struct file_list *match;
2118
+
2119
+ list_for_each(match, dw_head_file) {
2120
+ if(!(strcmp(cur_file, match->file_name)) &&
2121
+ !(strcmp(cur_dir, match->dir->dir_name))) {
2122
+ dw_cur_file = match;
2123
+ dw_cur_file->dir = match->dir;
2124
+ need_new_list = false;
2125
+ break;
2126
+ }
2127
+ }
2128
+ }
2129
+
2130
+ if(need_new_list) {
2131
+ new_file_list(cur_file, cur_dir);
2132
+ }
2133
+ }
2134
+
2135
+ dbg_immcall = true;
2136
+ cur_line = line_num;
2137
+ }
2138
+
2139
+ static void macho_dbg_output(int type, void *param)
2140
+ {
2141
+ struct section_info *sinfo_param = (struct section_info *)param;
2142
+ int32_t secto = sinfo_param->secto;
2143
+ bool need_new_sect = false;
2144
+ struct SAA *p_linep = NULL;
2145
+ (void)type;
2146
+
2147
+ if(!(dw_cur_sect && (dw_cur_sect->section == secto))) {
2148
+ need_new_sect = true;
2149
+ if(dw_head_sect) {
2150
+ struct dw_sect_list *match = dw_head_sect;
2151
+ uint32_t idx = 0;
2152
+
2153
+ for(; idx < dw_num_sects; idx++) {
2154
+ if(match->section == secto) {
2155
+ dw_cur_sect = match;
2156
+ need_new_sect = false;
2157
+ break;
2158
+ }
2159
+ match = match->next;
2160
+ }
2161
+ }
2162
+ }
2163
+
2164
+ if(need_new_sect) {
2165
+ nasm_new(dw_cur_sect);
2166
+ dw_num_sects ++;
2167
+ p_linep = dw_cur_sect->psaa = saa_init(1L);
2168
+ dw_cur_sect->line = dw_cur_sect->file = 1;
2169
+ dw_cur_sect->offset = 0;
2170
+ dw_cur_sect->next = NULL;
2171
+ dw_cur_sect->section = secto;
2172
+
2173
+ saa_write8(p_linep, DW_LNS_extended_op);
2174
+ saa_write8(p_linep, (ofmt == &of_macho64) ? 9 : 5);
2175
+ saa_write8(p_linep, DW_LNE_set_address);
2176
+ if (ofmt == &of_macho64) {
2177
+ saa_write64(p_linep, 0);
2178
+ } else {
2179
+ saa_write32(p_linep, 0);
2180
+ }
2181
+
2182
+ if(!dw_head_sect) {
2183
+ dw_head_sect = dw_last_sect = dw_cur_sect;
2184
+ } else {
2185
+ dw_last_sect->next = dw_cur_sect;
2186
+ dw_last_sect = dw_cur_sect;
2187
+ }
2188
+ }
2189
+
2190
+ if(dbg_immcall == true) {
2191
+ int32_t line_delta = cur_line - dw_cur_sect->line;
2192
+ int32_t offset_delta = sinfo_param->size - dw_cur_sect->offset;
2193
+ uint32_t cur_file = dw_cur_file->file;
2194
+ p_linep = dw_cur_sect->psaa;
2195
+
2196
+ if(cur_file != dw_cur_sect->file) {
2197
+ saa_write8(p_linep, DW_LNS_set_file);
2198
+ saa_write8(p_linep, cur_file);
2199
+ dw_cur_sect->file = cur_file;
2200
+ }
2201
+
2202
+ if(line_delta) {
2203
+ int special_opcode = (line_delta - DW_LN_BASE) + (DW_LN_RANGE * offset_delta) +
2204
+ DW_OPCODE_BASE;
2205
+
2206
+ if((line_delta >= DW_LN_BASE) && (line_delta < DW_MAX_LN) &&
2207
+ (special_opcode < DW_MAX_SP_OPCODE)) {
2208
+ saa_write8(p_linep, special_opcode);
2209
+ } else {
2210
+ saa_write8(p_linep, DW_LNS_advance_line);
2211
+ saa_wleb128s(p_linep, line_delta);
2212
+ if(offset_delta) {
2213
+ saa_write8(p_linep, DW_LNS_advance_pc);
2214
+ saa_wleb128u(p_linep, offset_delta);
2215
+ }
2216
+ saa_write8(p_linep, DW_LNS_copy);
2217
+ }
2218
+
2219
+ dw_cur_sect->line = cur_line;
2220
+ dw_cur_sect->offset = sinfo_param->size;
2221
+ }
2222
+
2223
+ dbg_immcall = false;
2224
+ }
2225
+ }
2226
+
2227
+ static void macho_dbg_cleanup(void)
2228
+ {
2229
+ /* dwarf sectors generation */
2230
+ macho_dbg_generate();
2231
+
2232
+ {
2233
+ struct dw_sect_list *p_sect = dw_head_sect;
2234
+ struct file_list *p_file = dw_head_file;
2235
+ uint32_t idx = 0;
2236
+
2237
+ for(; idx < dw_num_sects; idx++) {
2238
+ struct dw_sect_list *next = p_sect->next;
2239
+ nasm_free(p_sect);
2240
+ p_sect = next;
2241
+ }
2242
+
2243
+ for(idx = 0; idx < dw_num_files; idx++) {
2244
+ struct file_list *next = p_file->next;
2245
+ nasm_free(p_file);
2246
+ p_file = next;
2247
+ }
2248
+ }
2249
+ }
2250
+
2251
+ #ifdef OF_MACHO32
2252
+ static const struct macho_fmt macho32_fmt = {
2253
+ 4,
2254
+ MH_MAGIC,
2255
+ CPU_TYPE_I386,
2256
+ LC_SEGMENT,
2257
+ MACHO_HEADER_SIZE,
2258
+ MACHO_SEGCMD_SIZE,
2259
+ MACHO_SECTCMD_SIZE,
2260
+ MACHO_NLIST_SIZE,
2261
+ RL_MAX_32,
2262
+ GENERIC_RELOC_VANILLA,
2263
+ GENERIC_RELOC_VANILLA,
2264
+ GENERIC_RELOC_TLV,
2265
+ false /* Allow segment-relative relocations */
2266
+ };
2267
+
2268
+ static void macho32_init(void)
2269
+ {
2270
+ fmt = macho32_fmt;
2271
+ macho_init();
2272
+
2273
+ macho_gotpcrel_sect = NO_SEG;
2274
+ }
2275
+
2276
+ static const struct dfmt macho32_df_dwarf = {
2277
+ "MachO32 (i386) dwarf debug format for Darwin/MacOS",
2278
+ "dwarf",
2279
+ macho_dbg_init,
2280
+ macho_dbg_linenum,
2281
+ null_debug_deflabel,
2282
+ null_debug_directive,
2283
+ null_debug_typevalue,
2284
+ macho_dbg_output,
2285
+ macho_dbg_cleanup,
2286
+ NULL /*pragma list*/
2287
+ };
2288
+
2289
+ static const struct dfmt * const macho32_df_arr[2] =
2290
+ { &macho32_df_dwarf, NULL };
2291
+
2292
+ const struct ofmt of_macho32 = {
2293
+ "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files",
2294
+ "macho32",
2295
+ 0,
2296
+ 32,
2297
+ macho32_df_arr,
2298
+ &macho32_df_dwarf,
2299
+ macho_stdmac,
2300
+ macho32_init,
2301
+ nasm_do_legacy_output,
2302
+ macho_output,
2303
+ macho_symdef,
2304
+ macho_section,
2305
+ macho_sectalign,
2306
+ macho_segbase,
2307
+ null_directive,
2308
+ macho_filename,
2309
+ macho_cleanup,
2310
+ macho_pragma_list
2311
+ };
2312
+ #endif
2313
+
2314
+ #ifdef OF_MACHO64
2315
+ static const struct macho_fmt macho64_fmt = {
2316
+ 8,
2317
+ MH_MAGIC_64,
2318
+ CPU_TYPE_X86_64,
2319
+ LC_SEGMENT_64,
2320
+ MACHO_HEADER64_SIZE,
2321
+ MACHO_SEGCMD64_SIZE,
2322
+ MACHO_SECTCMD64_SIZE,
2323
+ MACHO_NLIST64_SIZE,
2324
+ RL_MAX_64,
2325
+ X86_64_RELOC_UNSIGNED,
2326
+ X86_64_RELOC_SIGNED,
2327
+ X86_64_RELOC_TLV,
2328
+ true /* Force symbol-relative relocations */
2329
+ };
2330
+
2331
+ static void macho64_init(void)
2332
+ {
2333
+ fmt = macho64_fmt;
2334
+ macho_init();
2335
+
2336
+ /* add special symbol for ..gotpcrel */
2337
+ macho_gotpcrel_sect = seg_alloc() + 1;
2338
+ define_label("..gotpcrel", macho_gotpcrel_sect, 0L, NULL, false, false);
2339
+ }
2340
+
2341
+ static const struct dfmt macho64_df_dwarf = {
2342
+ "MachO64 (x86-64) dwarf debug format for Darwin/MacOS",
2343
+ "dwarf",
2344
+ macho_dbg_init,
2345
+ macho_dbg_linenum,
2346
+ null_debug_deflabel,
2347
+ null_debug_directive,
2348
+ null_debug_typevalue,
2349
+ macho_dbg_output,
2350
+ macho_dbg_cleanup,
2351
+ NULL /*pragma list*/
2352
+ };
2353
+
2354
+ static const struct dfmt * const macho64_df_arr[2] =
2355
+ { &macho64_df_dwarf, NULL };
2356
+
2357
+ const struct ofmt of_macho64 = {
2358
+ "NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files",
2359
+ "macho64",
2360
+ 0,
2361
+ 64,
2362
+ macho64_df_arr,
2363
+ &macho64_df_dwarf,
2364
+ macho_stdmac,
2365
+ macho64_init,
2366
+ nasm_do_legacy_output,
2367
+ macho_output,
2368
+ macho_symdef,
2369
+ macho_section,
2370
+ macho_sectalign,
2371
+ macho_segbase,
2372
+ null_directive,
2373
+ macho_filename,
2374
+ macho_cleanup,
2375
+ macho_pragma_list,
2376
+ };
2377
+ #endif
2378
+
2379
+ #endif
2380
+
2381
+ /*
2382
+ * Local Variables:
2383
+ * mode:c
2384
+ * c-basic-offset:4
2385
+ * End:
2386
+ *
2387
+ * end of file */