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,49 @@
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
+ OUT: macho macho32 macho64
35
+ %define __SECT__ [section .text]
36
+ %macro __NASM_CDecl__ 1
37
+ %endmacro
38
+
39
+ ; This directive sets the MH_SUBSECTIONS_VIA_SYMBOLS header flag
40
+ %imacro subsections_via_symbols 0.nolist
41
+ %pragma __OUTPUT_FORMAT__ %?
42
+ %endmacro
43
+
44
+ %imacro no_dead_strip 1-*.nolist
45
+ %rep %0
46
+ %pragma __OUTPUT_FORMAT__ %? %1
47
+ %rotate 1
48
+ %endrep
49
+ %endmacro
@@ -0,0 +1,2725 @@
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
+ * outobj.c output routines for the Netwide Assembler to produce
36
+ * .OBJ 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
+ #include <limits.h>
46
+
47
+ #include "nasm.h"
48
+ #include "nasmlib.h"
49
+ #include "error.h"
50
+ #include "stdscan.h"
51
+ #include "eval.h"
52
+ #include "ver.h"
53
+
54
+ #include "outform.h"
55
+ #include "outlib.h"
56
+
57
+ #ifdef OF_OBJ
58
+
59
+ /*
60
+ * outobj.c is divided into two sections. The first section is low level
61
+ * routines for creating obj records; It has nearly zero NASM specific
62
+ * code. The second section is high level routines for processing calls and
63
+ * data structures from the rest of NASM into obj format.
64
+ *
65
+ * It should be easy (though not zero work) to lift the first section out for
66
+ * use as an obj file writer for some other assembler or compiler.
67
+ */
68
+
69
+ /*
70
+ * These routines are built around the ObjRecord data struture. An ObjRecord
71
+ * holds an object file record that may be under construction or complete.
72
+ *
73
+ * A major function of these routines is to support continuation of an obj
74
+ * record into the next record when the maximum record size is exceeded. The
75
+ * high level code does not need to worry about where the record breaks occur.
76
+ * It does need to do some minor extra steps to make the automatic continuation
77
+ * work. Those steps may be skipped for records where the high level knows no
78
+ * continuation could be required.
79
+ *
80
+ * 1) An ObjRecord is allocated and cleared by obj_new, or an existing ObjRecord
81
+ * is cleared by obj_clear.
82
+ *
83
+ * 2) The caller should fill in .type.
84
+ *
85
+ * 3) If the record is continuable and there is processing that must be done at
86
+ * the start of each record then the caller should fill in .ori with the
87
+ * address of the record initializer routine.
88
+ *
89
+ * 4) If the record is continuable and it should be saved (rather than emitted
90
+ * immediately) as each record is done, the caller should set .up to be a
91
+ * pointer to a location in which the caller keeps the master pointer to the
92
+ * ObjRecord. When the record is continued, the obj_bump routine will then
93
+ * allocate a new ObjRecord structure and update the master pointer.
94
+ *
95
+ * 5) If the .ori field was used then the caller should fill in the .parm with
96
+ * any data required by the initializer.
97
+ *
98
+ * 6) The caller uses the routines: obj_byte, obj_word, obj_rword, obj_dword,
99
+ * obj_x, obj_index, obj_value and obj_name to fill in the various kinds of
100
+ * data required for this record.
101
+ *
102
+ * 7) If the record is continuable, the caller should call obj_commit at each
103
+ * point where breaking the record is permitted.
104
+ *
105
+ * 8) To write out the record, the caller should call obj_emit2. If the
106
+ * caller has called obj_commit for all data written then he can get slightly
107
+ * faster code by calling obj_emit instead of obj_emit2.
108
+ *
109
+ * Most of these routines return an ObjRecord pointer. This will be the input
110
+ * pointer most of the time and will be the new location if the ObjRecord
111
+ * moved as a result of the call. The caller may ignore the return value in
112
+ * three cases: It is a "Never Reallocates" routine; or The caller knows
113
+ * continuation is not possible; or The caller uses the master pointer for the
114
+ * next operation.
115
+ */
116
+
117
+ #define RECORD_MAX (1024-3) /* maximal size of any record except type+reclen */
118
+ #define OBJ_PARMS 3 /* maximum .parm used by any .ori routine */
119
+
120
+ #define FIX_08_LOW 0x8000 /* location type for various fixup subrecords */
121
+ #define FIX_16_OFFSET 0x8400
122
+ #define FIX_16_SELECTOR 0x8800
123
+ #define FIX_32_POINTER 0x8C00
124
+ #define FIX_08_HIGH 0x9000
125
+ #define FIX_32_OFFSET 0xA400
126
+ #define FIX_48_POINTER 0xAC00
127
+
128
+ enum RecordID { /* record ID codes */
129
+
130
+ THEADR = 0x80, /* module header */
131
+ COMENT = 0x88, /* comment record */
132
+
133
+ LINNUM = 0x94, /* line number record */
134
+ LNAMES = 0x96, /* list of names */
135
+
136
+ SEGDEF = 0x98, /* segment definition */
137
+ GRPDEF = 0x9A, /* group definition */
138
+ EXTDEF = 0x8C, /* external definition */
139
+ PUBDEF = 0x90, /* public definition */
140
+ COMDEF = 0xB0, /* common definition */
141
+
142
+ LEDATA = 0xA0, /* logical enumerated data */
143
+ FIXUPP = 0x9C, /* fixups (relocations) */
144
+ FIXU32 = 0x9D, /* 32-bit fixups (relocations) */
145
+
146
+ MODEND = 0x8A, /* module end */
147
+ MODE32 = 0x8B /* module end for 32-bit objects */
148
+ };
149
+
150
+ enum ComentID { /* ID codes for comment records */
151
+ dTRANSL = 0x0000, /* translator comment */
152
+ dOMFEXT = 0xC0A0, /* "OMF extension" */
153
+ dEXTENDED = 0xC0A1, /* translator-specific extensions */
154
+ dLINKPASS = 0x40A2, /* link pass 2 marker */
155
+ dTYPEDEF = 0xC0E3, /* define a type */
156
+ dSYM = 0xC0E6, /* symbol debug record */
157
+ dFILNAME = 0xC0E8, /* file name record */
158
+ dDEPFILE = 0xC0E9, /* dependency file */
159
+ dCOMPDEF = 0xC0EA /* compiler type info */
160
+ };
161
+
162
+ typedef struct ObjRecord ObjRecord;
163
+ typedef void ORI(ObjRecord * orp);
164
+
165
+ struct ObjRecord {
166
+ ORI *ori; /* Initialization routine */
167
+ int used; /* Current data size */
168
+ int committed; /* Data size at last boundary */
169
+ int x_size; /* (see obj_x) */
170
+ unsigned int type; /* Record type */
171
+ ObjRecord *child; /* Associated record below this one */
172
+ ObjRecord **up; /* Master pointer to this ObjRecord */
173
+ ObjRecord *back; /* Previous part of this record */
174
+ uint32_t parm[OBJ_PARMS]; /* Parameters for ori routine */
175
+ uint8_t buf[RECORD_MAX + 3];
176
+ };
177
+
178
+ static void obj_fwrite(ObjRecord * orp);
179
+ static void ori_ledata(ObjRecord * orp);
180
+ static void ori_pubdef(ObjRecord * orp);
181
+ static void ori_null(ObjRecord * orp);
182
+ static ObjRecord *obj_commit(ObjRecord * orp);
183
+
184
+ static bool obj_uppercase; /* Flag: all names in uppercase */
185
+ static bool obj_use32; /* Flag: at least one segment is 32-bit */
186
+ static bool obj_nodepend; /* Flag: don't emit file dependencies */
187
+
188
+ /*
189
+ * Clear an ObjRecord structure. (Never reallocates).
190
+ * To simplify reuse of ObjRecord's, .type, .ori and .parm are not cleared.
191
+ */
192
+ static ObjRecord *obj_clear(ObjRecord * orp)
193
+ {
194
+ orp->used = 0;
195
+ orp->committed = 0;
196
+ orp->x_size = 0;
197
+ orp->child = NULL;
198
+ orp->up = NULL;
199
+ orp->back = NULL;
200
+ return (orp);
201
+ }
202
+
203
+ /*
204
+ * Emit an ObjRecord structure. (Never reallocates).
205
+ * The record is written out preceeded (recursively) by its previous part (if
206
+ * any) and followed (recursively) by its child (if any).
207
+ * The previous part and the child are freed. The main ObjRecord is cleared,
208
+ * not freed.
209
+ */
210
+ static ObjRecord *obj_emit(ObjRecord * orp)
211
+ {
212
+ if (orp->back) {
213
+ obj_emit(orp->back);
214
+ nasm_free(orp->back);
215
+ }
216
+
217
+ if (orp->committed)
218
+ obj_fwrite(orp);
219
+
220
+ if (orp->child) {
221
+ obj_emit(orp->child);
222
+ nasm_free(orp->child);
223
+ }
224
+
225
+ return (obj_clear(orp));
226
+ }
227
+
228
+ /*
229
+ * Commit and Emit a record. (Never reallocates).
230
+ */
231
+ static ObjRecord *obj_emit2(ObjRecord * orp)
232
+ {
233
+ obj_commit(orp);
234
+ return (obj_emit(orp));
235
+ }
236
+
237
+ /*
238
+ * Allocate and clear a new ObjRecord; Also sets .ori to ori_null
239
+ */
240
+ static ObjRecord *obj_new(void)
241
+ {
242
+ ObjRecord *orp;
243
+
244
+ orp = obj_clear(nasm_malloc(sizeof(ObjRecord)));
245
+ orp->ori = ori_null;
246
+ return (orp);
247
+ }
248
+
249
+ /*
250
+ * Advance to the next record because the existing one is full or its x_size
251
+ * is incompatible.
252
+ * Any uncommited data is moved into the next record.
253
+ */
254
+ static ObjRecord *obj_bump(ObjRecord * orp)
255
+ {
256
+ ObjRecord *nxt;
257
+ int used = orp->used;
258
+ int committed = orp->committed;
259
+
260
+ if (orp->up) {
261
+ *orp->up = nxt = obj_new();
262
+ nxt->ori = orp->ori;
263
+ nxt->type = orp->type;
264
+ nxt->up = orp->up;
265
+ nxt->back = orp;
266
+ memcpy(nxt->parm, orp->parm, sizeof(orp->parm));
267
+ } else
268
+ nxt = obj_emit(orp);
269
+
270
+ used -= committed;
271
+ if (used) {
272
+ nxt->committed = 1;
273
+ nxt->ori(nxt);
274
+ nxt->committed = nxt->used;
275
+ memcpy(nxt->buf + nxt->committed, orp->buf + committed, used);
276
+ nxt->used = nxt->committed + used;
277
+ }
278
+
279
+ return (nxt);
280
+ }
281
+
282
+ /*
283
+ * Advance to the next record if necessary to allow the next field to fit.
284
+ */
285
+ static ObjRecord *obj_check(ObjRecord * orp, int size)
286
+ {
287
+ if (orp->used + size > RECORD_MAX)
288
+ orp = obj_bump(orp);
289
+
290
+ if (!orp->committed) {
291
+ orp->committed = 1;
292
+ orp->ori(orp);
293
+ orp->committed = orp->used;
294
+ }
295
+
296
+ return (orp);
297
+ }
298
+
299
+ /*
300
+ * All data written so far is commited to the current record (won't be moved to
301
+ * the next record in case of continuation).
302
+ */
303
+ static ObjRecord *obj_commit(ObjRecord * orp)
304
+ {
305
+ orp->committed = orp->used;
306
+ return (orp);
307
+ }
308
+
309
+ /*
310
+ * Write a byte
311
+ */
312
+ static ObjRecord *obj_byte(ObjRecord * orp, uint8_t val)
313
+ {
314
+ orp = obj_check(orp, 1);
315
+ orp->buf[orp->used] = val;
316
+ orp->used++;
317
+ return (orp);
318
+ }
319
+
320
+ /*
321
+ * Write a word
322
+ */
323
+ static ObjRecord *obj_word(ObjRecord * orp, unsigned int val)
324
+ {
325
+ orp = obj_check(orp, 2);
326
+ orp->buf[orp->used] = val;
327
+ orp->buf[orp->used + 1] = val >> 8;
328
+ orp->used += 2;
329
+ return (orp);
330
+ }
331
+
332
+ /*
333
+ * Write a reversed word
334
+ */
335
+ static ObjRecord *obj_rword(ObjRecord * orp, unsigned int val)
336
+ {
337
+ orp = obj_check(orp, 2);
338
+ orp->buf[orp->used] = val >> 8;
339
+ orp->buf[orp->used + 1] = val;
340
+ orp->used += 2;
341
+ return (orp);
342
+ }
343
+
344
+ /*
345
+ * Write a dword
346
+ */
347
+ static ObjRecord *obj_dword(ObjRecord * orp, uint32_t val)
348
+ {
349
+ orp = obj_check(orp, 4);
350
+ orp->buf[orp->used] = val;
351
+ orp->buf[orp->used + 1] = val >> 8;
352
+ orp->buf[orp->used + 2] = val >> 16;
353
+ orp->buf[orp->used + 3] = val >> 24;
354
+ orp->used += 4;
355
+ return (orp);
356
+ }
357
+
358
+ /*
359
+ * All fields of "size x" in one obj record must be the same size (either 16
360
+ * bits or 32 bits). There is a one bit flag in each record which specifies
361
+ * which.
362
+ * This routine is used to force the current record to have the desired
363
+ * x_size. x_size is normally automatic (using obj_x), so that this
364
+ * routine should be used outside obj_x, only to provide compatibility with
365
+ * linkers that have bugs in their processing of the size bit.
366
+ */
367
+
368
+ static ObjRecord *obj_force(ObjRecord * orp, int x)
369
+ {
370
+ if (orp->x_size == (x ^ 48))
371
+ orp = obj_bump(orp);
372
+ orp->x_size = x;
373
+ return (orp);
374
+ }
375
+
376
+ /*
377
+ * This routine writes a field of size x. The caller does not need to worry at
378
+ * all about whether 16-bits or 32-bits are required.
379
+ */
380
+ static ObjRecord *obj_x(ObjRecord * orp, uint32_t val)
381
+ {
382
+ if (orp->type & 1)
383
+ orp->x_size = 32;
384
+ if (val > 0xFFFF)
385
+ orp = obj_force(orp, 32);
386
+ if (orp->x_size == 32) {
387
+ ObjRecord *nxt = obj_dword(orp, val);
388
+ nxt->x_size = 32; /* x_size is cleared when a record overflows */
389
+ return nxt;
390
+ }
391
+ orp->x_size = 16;
392
+ return (obj_word(orp, val));
393
+ }
394
+
395
+ /*
396
+ * Writes an index
397
+ */
398
+ static ObjRecord *obj_index(ObjRecord * orp, unsigned int val)
399
+ {
400
+ if (val < 128)
401
+ return (obj_byte(orp, val));
402
+ return (obj_word(orp, (val >> 8) | (val << 8) | 0x80));
403
+ }
404
+
405
+ /*
406
+ * Writes a variable length value
407
+ */
408
+ static ObjRecord *obj_value(ObjRecord * orp, uint32_t val)
409
+ {
410
+ if (val <= 128)
411
+ return (obj_byte(orp, val));
412
+ if (val <= 0xFFFF) {
413
+ orp = obj_byte(orp, 129);
414
+ return (obj_word(orp, val));
415
+ }
416
+ if (val <= 0xFFFFFF)
417
+ return (obj_dword(orp, (val << 8) + 132));
418
+ orp = obj_byte(orp, 136);
419
+ return (obj_dword(orp, val));
420
+ }
421
+
422
+ /*
423
+ * Writes a counted string
424
+ */
425
+ static ObjRecord *obj_name(ObjRecord * orp, const char *name)
426
+ {
427
+ int len = strlen(name);
428
+ uint8_t *ptr;
429
+
430
+ orp = obj_check(orp, len + 1);
431
+ ptr = orp->buf + orp->used;
432
+ *ptr++ = len;
433
+ orp->used += len + 1;
434
+ if (obj_uppercase)
435
+ while (--len >= 0) {
436
+ *ptr++ = toupper(*name);
437
+ name++;
438
+ } else
439
+ memcpy(ptr, name, len);
440
+ return (orp);
441
+ }
442
+
443
+ /*
444
+ * Initializer for an LEDATA record.
445
+ * parm[0] = offset
446
+ * parm[1] = segment index
447
+ * During the use of a LEDATA ObjRecord, parm[0] is constantly updated to
448
+ * represent the offset that would be required if the record were split at the
449
+ * last commit point.
450
+ * parm[2] is a copy of parm[0] as it was when the current record was initted.
451
+ */
452
+ static void ori_ledata(ObjRecord * orp)
453
+ {
454
+ obj_index(orp, orp->parm[1]);
455
+ orp->parm[2] = orp->parm[0];
456
+ obj_x(orp, orp->parm[0]);
457
+ }
458
+
459
+ /*
460
+ * Initializer for a PUBDEF record.
461
+ * parm[0] = group index
462
+ * parm[1] = segment index
463
+ * parm[2] = frame (only used when both indexes are zero)
464
+ */
465
+ static void ori_pubdef(ObjRecord * orp)
466
+ {
467
+ obj_index(orp, orp->parm[0]);
468
+ obj_index(orp, orp->parm[1]);
469
+ if (!(orp->parm[0] | orp->parm[1]))
470
+ obj_word(orp, orp->parm[2]);
471
+ }
472
+
473
+ /*
474
+ * Initializer for a LINNUM record.
475
+ * parm[0] = group index
476
+ * parm[1] = segment index
477
+ */
478
+ static void ori_linnum(ObjRecord * orp)
479
+ {
480
+ obj_index(orp, orp->parm[0]);
481
+ obj_index(orp, orp->parm[1]);
482
+ }
483
+
484
+ /*
485
+ * Initializer for a local vars record.
486
+ */
487
+ static void ori_local(ObjRecord * orp)
488
+ {
489
+ obj_rword(orp, dSYM);
490
+ }
491
+
492
+ /*
493
+ * Null initializer for records that continue without any header info
494
+ */
495
+ static void ori_null(ObjRecord * orp)
496
+ {
497
+ (void)orp; /* Do nothing */
498
+ }
499
+
500
+ /*
501
+ * This concludes the low level section of outobj.c
502
+ */
503
+
504
+ static char obj_infile[FILENAME_MAX];
505
+
506
+ static int32_t first_seg;
507
+ static bool any_segs;
508
+ static int passtwo;
509
+ static int arrindex;
510
+
511
+ #define GROUP_MAX 256 /* we won't _realistically_ have more
512
+ * than this many segs in a group */
513
+ #define EXT_BLKSIZ 256 /* block size for externals list */
514
+
515
+ struct Segment; /* need to know these structs exist */
516
+ struct Group;
517
+
518
+ struct LineNumber {
519
+ struct LineNumber *next;
520
+ struct Segment *segment;
521
+ int32_t offset;
522
+ int32_t lineno;
523
+ };
524
+
525
+ static struct FileName {
526
+ struct FileName *next;
527
+ char *name;
528
+ struct LineNumber *lnhead, **lntail;
529
+ int index;
530
+ } *fnhead, **fntail;
531
+
532
+ static struct Array {
533
+ struct Array *next;
534
+ unsigned size;
535
+ int basetype;
536
+ } *arrhead, **arrtail;
537
+
538
+ #define ARRAYBOT 31 /* magic number for first array index */
539
+
540
+ static struct Public {
541
+ struct Public *next;
542
+ char *name;
543
+ int32_t offset;
544
+ int32_t segment; /* only if it's far-absolute */
545
+ int type; /* only for local debug syms */
546
+ } *fpubhead, **fpubtail, *last_defined;
547
+
548
+ static struct External {
549
+ struct External *next;
550
+ char *name;
551
+ int32_t commonsize;
552
+ int32_t commonelem; /* element size if FAR, else zero */
553
+ int index; /* OBJ-file external index */
554
+ enum {
555
+ DEFWRT_NONE, /* no unusual default-WRT */
556
+ DEFWRT_STRING, /* a string we don't yet understand */
557
+ DEFWRT_SEGMENT, /* a segment */
558
+ DEFWRT_GROUP /* a group */
559
+ } defwrt_type;
560
+ union {
561
+ char *string;
562
+ struct Segment *seg;
563
+ struct Group *grp;
564
+ } defwrt_ptr;
565
+ struct External *next_dws; /* next with DEFWRT_STRING */
566
+ } *exthead, **exttail, *dws;
567
+
568
+ static int externals;
569
+
570
+ static struct ExtBack {
571
+ struct ExtBack *next;
572
+ struct External *exts[EXT_BLKSIZ];
573
+ } *ebhead, **ebtail;
574
+
575
+ static struct Segment {
576
+ struct Segment *next;
577
+ char *name;
578
+ int32_t index; /* the NASM segment id */
579
+ int32_t obj_index; /* the OBJ-file segment index */
580
+ struct Group *grp; /* the group it beint32_ts to */
581
+ uint32_t currentpos;
582
+ int32_t align; /* can be SEG_ABS + absolute addr */
583
+ struct Public *pubhead, **pubtail, *lochead, **loctail;
584
+ char *segclass, *overlay; /* `class' is a C++ keyword :-) */
585
+ ObjRecord *orp;
586
+ enum {
587
+ CMB_PRIVATE = 0,
588
+ CMB_PUBLIC = 2,
589
+ CMB_STACK = 5,
590
+ CMB_COMMON = 6
591
+ } combine;
592
+ bool use32; /* is this segment 32-bit? */
593
+ } *seghead, **segtail, *obj_seg_needs_update;
594
+
595
+ static struct Group {
596
+ struct Group *next;
597
+ char *name;
598
+ int32_t index; /* NASM segment id */
599
+ int32_t obj_index; /* OBJ-file group index */
600
+ int32_t nentries; /* number of elements... */
601
+ int32_t nindices; /* ...and number of index elts... */
602
+ union {
603
+ int32_t index;
604
+ char *name;
605
+ } segs[GROUP_MAX]; /* ...in this */
606
+ } *grphead, **grptail, *obj_grp_needs_update;
607
+
608
+ static struct ImpDef {
609
+ struct ImpDef *next;
610
+ char *extname;
611
+ char *libname;
612
+ unsigned int impindex;
613
+ char *impname;
614
+ } *imphead, **imptail;
615
+
616
+ static struct ExpDef {
617
+ struct ExpDef *next;
618
+ char *intname;
619
+ char *extname;
620
+ unsigned int ordinal;
621
+ int flags;
622
+ } *exphead, **exptail;
623
+
624
+ #define EXPDEF_FLAG_ORDINAL 0x80
625
+ #define EXPDEF_FLAG_RESIDENT 0x40
626
+ #define EXPDEF_FLAG_NODATA 0x20
627
+ #define EXPDEF_MASK_PARMCNT 0x1F
628
+
629
+ static int32_t obj_entry_seg, obj_entry_ofs;
630
+
631
+ const struct ofmt of_obj;
632
+ static const struct dfmt borland_debug_form;
633
+
634
+ /* The current segment */
635
+ static struct Segment *current_seg;
636
+
637
+ static int32_t obj_segment(char *, int, int *);
638
+ static void obj_write_file(void);
639
+ static enum directive_result obj_directive(enum directive, char *, int);
640
+
641
+ static void obj_init(void)
642
+ {
643
+ first_seg = seg_alloc();
644
+ any_segs = false;
645
+ fpubhead = NULL;
646
+ fpubtail = &fpubhead;
647
+ exthead = NULL;
648
+ exttail = &exthead;
649
+ imphead = NULL;
650
+ imptail = &imphead;
651
+ exphead = NULL;
652
+ exptail = &exphead;
653
+ dws = NULL;
654
+ externals = 0;
655
+ ebhead = NULL;
656
+ ebtail = &ebhead;
657
+ seghead = obj_seg_needs_update = NULL;
658
+ segtail = &seghead;
659
+ grphead = obj_grp_needs_update = NULL;
660
+ grptail = &grphead;
661
+ obj_entry_seg = NO_SEG;
662
+ obj_uppercase = false;
663
+ obj_use32 = false;
664
+ passtwo = 0;
665
+ current_seg = NULL;
666
+ }
667
+
668
+ static void obj_cleanup(void)
669
+ {
670
+ obj_write_file();
671
+ dfmt->cleanup();
672
+ while (seghead) {
673
+ struct Segment *segtmp = seghead;
674
+ seghead = seghead->next;
675
+ while (segtmp->pubhead) {
676
+ struct Public *pubtmp = segtmp->pubhead;
677
+ segtmp->pubhead = pubtmp->next;
678
+ nasm_free(pubtmp->name);
679
+ nasm_free(pubtmp);
680
+ }
681
+ nasm_free(segtmp->segclass);
682
+ nasm_free(segtmp->overlay);
683
+ nasm_free(segtmp);
684
+ }
685
+ while (fpubhead) {
686
+ struct Public *pubtmp = fpubhead;
687
+ fpubhead = fpubhead->next;
688
+ nasm_free(pubtmp->name);
689
+ nasm_free(pubtmp);
690
+ }
691
+ while (exthead) {
692
+ struct External *exttmp = exthead;
693
+ exthead = exthead->next;
694
+ nasm_free(exttmp);
695
+ }
696
+ while (imphead) {
697
+ struct ImpDef *imptmp = imphead;
698
+ imphead = imphead->next;
699
+ nasm_free(imptmp->extname);
700
+ nasm_free(imptmp->libname);
701
+ nasm_free(imptmp->impname); /* nasm_free won't mind if it's NULL */
702
+ nasm_free(imptmp);
703
+ }
704
+ while (exphead) {
705
+ struct ExpDef *exptmp = exphead;
706
+ exphead = exphead->next;
707
+ nasm_free(exptmp->extname);
708
+ nasm_free(exptmp->intname);
709
+ nasm_free(exptmp);
710
+ }
711
+ while (ebhead) {
712
+ struct ExtBack *ebtmp = ebhead;
713
+ ebhead = ebhead->next;
714
+ nasm_free(ebtmp);
715
+ }
716
+ while (grphead) {
717
+ struct Group *grptmp = grphead;
718
+ grphead = grphead->next;
719
+ nasm_free(grptmp);
720
+ }
721
+ }
722
+
723
+ static void obj_ext_set_defwrt(struct External *ext, char *id)
724
+ {
725
+ struct Segment *seg;
726
+ struct Group *grp;
727
+
728
+ for (seg = seghead; seg; seg = seg->next)
729
+ if (!strcmp(seg->name, id)) {
730
+ ext->defwrt_type = DEFWRT_SEGMENT;
731
+ ext->defwrt_ptr.seg = seg;
732
+ nasm_free(id);
733
+ return;
734
+ }
735
+
736
+ for (grp = grphead; grp; grp = grp->next)
737
+ if (!strcmp(grp->name, id)) {
738
+ ext->defwrt_type = DEFWRT_GROUP;
739
+ ext->defwrt_ptr.grp = grp;
740
+ nasm_free(id);
741
+ return;
742
+ }
743
+
744
+ ext->defwrt_type = DEFWRT_STRING;
745
+ ext->defwrt_ptr.string = id;
746
+ ext->next_dws = dws;
747
+ dws = ext;
748
+ }
749
+
750
+ static void obj_deflabel(char *name, int32_t segment,
751
+ int64_t offset, int is_global, char *special)
752
+ {
753
+ /*
754
+ * We have three cases:
755
+ *
756
+ * (i) `segment' is a segment-base. If so, set the name field
757
+ * for the segment or group structure it refers to, and then
758
+ * return.
759
+ *
760
+ * (ii) `segment' is one of our segments, or a SEG_ABS segment.
761
+ * Save the label position for later output of a PUBDEF record.
762
+ * (Or a MODPUB, if we work out how.)
763
+ *
764
+ * (iii) `segment' is not one of our segments. Save the label
765
+ * position for later output of an EXTDEF, and also store a
766
+ * back-reference so that we can map later references to this
767
+ * segment number to the external index.
768
+ */
769
+ struct External *ext;
770
+ struct ExtBack *eb;
771
+ struct Segment *seg;
772
+ int i;
773
+ bool used_special = false; /* have we used the special text? */
774
+
775
+ #if defined(DEBUG) && DEBUG>2
776
+ nasm_error(ERR_DEBUG,
777
+ " obj_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
778
+ name, segment, offset, is_global, special);
779
+ #endif
780
+
781
+ /*
782
+ * If it's a special-retry from pass two, discard it.
783
+ */
784
+ if (is_global == 3)
785
+ return;
786
+
787
+ /*
788
+ * First check for the double-period, signifying something
789
+ * unusual.
790
+ */
791
+ if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
792
+ if (!strcmp(name, "..start")) {
793
+ obj_entry_seg = segment;
794
+ obj_entry_ofs = offset;
795
+ return;
796
+ }
797
+ nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
798
+ }
799
+
800
+ /*
801
+ * Case (i):
802
+ */
803
+ if (obj_seg_needs_update) {
804
+ obj_seg_needs_update->name = name;
805
+ return;
806
+ } else if (obj_grp_needs_update) {
807
+ obj_grp_needs_update->name = name;
808
+ return;
809
+ }
810
+ if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
811
+ return;
812
+
813
+ if (segment >= SEG_ABS || segment == NO_SEG) {
814
+ /*
815
+ * SEG_ABS subcase of (ii).
816
+ */
817
+ if (is_global) {
818
+ struct Public *pub;
819
+
820
+ pub = *fpubtail = nasm_malloc(sizeof(*pub));
821
+ fpubtail = &pub->next;
822
+ pub->next = NULL;
823
+ pub->name = nasm_strdup(name);
824
+ pub->offset = offset;
825
+ pub->segment = (segment == NO_SEG ? 0 : segment & ~SEG_ABS);
826
+ }
827
+ if (special)
828
+ nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
829
+ " for this symbol type");
830
+ return;
831
+ }
832
+
833
+ /*
834
+ * If `any_segs' is still false, we might need to define a
835
+ * default segment, if they're trying to declare a label in
836
+ * `first_seg'.
837
+ */
838
+ if (!any_segs && segment == first_seg) {
839
+ int tempint; /* ignored */
840
+ if (segment != obj_segment("__NASMDEFSEG", 2, &tempint))
841
+ nasm_panic(0, "strange segment conditions in OBJ driver");
842
+ }
843
+
844
+ for (seg = seghead; seg && is_global; seg = seg->next)
845
+ if (seg->index == segment) {
846
+ struct Public *loc = nasm_malloc(sizeof(*loc));
847
+ /*
848
+ * Case (ii). Maybe MODPUB someday?
849
+ */
850
+ *seg->pubtail = loc;
851
+ seg->pubtail = &loc->next;
852
+ loc->next = NULL;
853
+ loc->name = nasm_strdup(name);
854
+ loc->offset = offset;
855
+
856
+ if (special)
857
+ nasm_error(ERR_NONFATAL,
858
+ "OBJ supports no special symbol features"
859
+ " for this symbol type");
860
+ return;
861
+ }
862
+
863
+ /*
864
+ * Case (iii).
865
+ */
866
+ if (is_global) {
867
+ ext = *exttail = nasm_malloc(sizeof(*ext));
868
+ ext->next = NULL;
869
+ exttail = &ext->next;
870
+ ext->name = name;
871
+ /* Place by default all externs into the current segment */
872
+ ext->defwrt_type = DEFWRT_NONE;
873
+
874
+ /* 28-Apr-2002 - John Coffman
875
+ The following code was introduced on 12-Aug-2000, and breaks fixups
876
+ on code passed thru the MSC 5.1 linker (3.66) and MSC 6.00A linker
877
+ (5.10). It was introduced after FIXUP32 was added, and may be needed
878
+ for 32-bit segments. The following will get 16-bit segments working
879
+ again, and maybe someone can correct the 'if' condition which is
880
+ actually needed.
881
+ */
882
+ #if 0
883
+ if (current_seg) {
884
+ #else
885
+ if (current_seg && current_seg->use32) {
886
+ if (current_seg->grp) {
887
+ ext->defwrt_type = DEFWRT_GROUP;
888
+ ext->defwrt_ptr.grp = current_seg->grp;
889
+ } else {
890
+ ext->defwrt_type = DEFWRT_SEGMENT;
891
+ ext->defwrt_ptr.seg = current_seg;
892
+ }
893
+ }
894
+ #endif
895
+
896
+ if (is_global == 2) {
897
+ ext->commonsize = offset;
898
+ ext->commonelem = 1; /* default FAR */
899
+ } else
900
+ ext->commonsize = 0;
901
+ } else
902
+ return;
903
+
904
+ /*
905
+ * Now process the special text, if any, to find default-WRT
906
+ * specifications and common-variable element-size and near/far
907
+ * specifications.
908
+ */
909
+ while (special && *special) {
910
+ used_special = true;
911
+
912
+ /*
913
+ * We might have a default-WRT specification.
914
+ */
915
+ if (!nasm_strnicmp(special, "wrt", 3)) {
916
+ char *p;
917
+ int len;
918
+ special += 3;
919
+ special += strspn(special, " \t");
920
+ p = nasm_strndup(special, len = strcspn(special, ":"));
921
+ obj_ext_set_defwrt(ext, p);
922
+ special += len;
923
+ if (*special && *special != ':')
924
+ nasm_error(ERR_NONFATAL, "`:' expected in special symbol"
925
+ " text for `%s'", ext->name);
926
+ else if (*special == ':')
927
+ special++;
928
+ }
929
+
930
+ /*
931
+ * The NEAR or FAR keywords specify nearness or
932
+ * farness. FAR gives default element size 1.
933
+ */
934
+ if (!nasm_strnicmp(special, "far", 3)) {
935
+ if (ext->commonsize)
936
+ ext->commonelem = 1;
937
+ else
938
+ nasm_error(ERR_NONFATAL,
939
+ "`%s': `far' keyword may only be applied"
940
+ " to common variables\n", ext->name);
941
+ special += 3;
942
+ special += strspn(special, " \t");
943
+ } else if (!nasm_strnicmp(special, "near", 4)) {
944
+ if (ext->commonsize)
945
+ ext->commonelem = 0;
946
+ else
947
+ nasm_error(ERR_NONFATAL,
948
+ "`%s': `far' keyword may only be applied"
949
+ " to common variables\n", ext->name);
950
+ special += 4;
951
+ special += strspn(special, " \t");
952
+ }
953
+
954
+ /*
955
+ * If it's a common, and anything else remains on the line
956
+ * before a further colon, evaluate it as an expression and
957
+ * use that as the element size. Forward references aren't
958
+ * allowed.
959
+ */
960
+ if (*special == ':')
961
+ special++;
962
+ else if (*special) {
963
+ if (ext->commonsize) {
964
+ expr *e;
965
+ struct tokenval tokval;
966
+
967
+ stdscan_reset();
968
+ stdscan_set(special);
969
+ tokval.t_type = TOKEN_INVALID;
970
+ e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
971
+ if (e) {
972
+ if (!is_simple(e))
973
+ nasm_error(ERR_NONFATAL, "cannot use relocatable"
974
+ " expression as common-variable element size");
975
+ else
976
+ ext->commonelem = reloc_value(e);
977
+ }
978
+ special = stdscan_get();
979
+ } else {
980
+ nasm_error(ERR_NONFATAL,
981
+ "`%s': element-size specifications only"
982
+ " apply to common variables", ext->name);
983
+ while (*special && *special != ':')
984
+ special++;
985
+ if (*special == ':')
986
+ special++;
987
+ }
988
+ }
989
+ }
990
+
991
+ i = segment / 2;
992
+ eb = ebhead;
993
+ if (!eb) {
994
+ eb = *ebtail = nasm_zalloc(sizeof(*eb));
995
+ eb->next = NULL;
996
+ ebtail = &eb->next;
997
+ }
998
+ while (i >= EXT_BLKSIZ) {
999
+ if (eb && eb->next)
1000
+ eb = eb->next;
1001
+ else {
1002
+ eb = *ebtail = nasm_zalloc(sizeof(*eb));
1003
+ eb->next = NULL;
1004
+ ebtail = &eb->next;
1005
+ }
1006
+ i -= EXT_BLKSIZ;
1007
+ }
1008
+ eb->exts[i] = ext;
1009
+ ext->index = ++externals;
1010
+
1011
+ if (special && !used_special)
1012
+ nasm_error(ERR_NONFATAL, "OBJ supports no special symbol features"
1013
+ " for this symbol type");
1014
+ }
1015
+
1016
+ /* forward declaration */
1017
+ static void obj_write_fixup(ObjRecord * orp, int bytes,
1018
+ int segrel, int32_t seg, int32_t wrt,
1019
+ struct Segment *segto);
1020
+
1021
+ static void obj_out(int32_t segto, const void *data,
1022
+ enum out_type type, uint64_t size,
1023
+ int32_t segment, int32_t wrt)
1024
+ {
1025
+ const uint8_t *ucdata;
1026
+ int32_t ldata;
1027
+ struct Segment *seg;
1028
+ ObjRecord *orp;
1029
+
1030
+ /*
1031
+ * handle absolute-assembly (structure definitions)
1032
+ */
1033
+ if (segto == NO_SEG) {
1034
+ if (type != OUT_RESERVE)
1035
+ nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1036
+ " space");
1037
+ return;
1038
+ }
1039
+
1040
+ /*
1041
+ * If `any_segs' is still false, we must define a default
1042
+ * segment.
1043
+ */
1044
+ if (!any_segs) {
1045
+ int tempint; /* ignored */
1046
+ if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
1047
+ nasm_panic(0, "strange segment conditions in OBJ driver");
1048
+ }
1049
+
1050
+ /*
1051
+ * Find the segment we are targetting.
1052
+ */
1053
+ for (seg = seghead; seg; seg = seg->next)
1054
+ if (seg->index == segto)
1055
+ break;
1056
+ if (!seg)
1057
+ nasm_panic(0, "code directed to nonexistent segment?");
1058
+
1059
+ orp = seg->orp;
1060
+ orp->parm[0] = seg->currentpos;
1061
+
1062
+ switch (type) {
1063
+ case OUT_RAWDATA:
1064
+ ucdata = data;
1065
+ while (size > 0) {
1066
+ unsigned int len;
1067
+ orp = obj_check(seg->orp, 1);
1068
+ len = RECORD_MAX - orp->used;
1069
+ if (len > size)
1070
+ len = size;
1071
+ memcpy(orp->buf + orp->used, ucdata, len);
1072
+ orp->committed = orp->used += len;
1073
+ orp->parm[0] = seg->currentpos += len;
1074
+ ucdata += len;
1075
+ size -= len;
1076
+ }
1077
+ break;
1078
+
1079
+ case OUT_ADDRESS:
1080
+ case OUT_REL1ADR:
1081
+ case OUT_REL2ADR:
1082
+ case OUT_REL4ADR:
1083
+ case OUT_REL8ADR:
1084
+ {
1085
+ int rsize;
1086
+
1087
+ if (type == OUT_ADDRESS)
1088
+ size = abs((int)size);
1089
+
1090
+ if (segment == NO_SEG && type != OUT_ADDRESS)
1091
+ nasm_error(ERR_NONFATAL, "relative call to absolute address not"
1092
+ " supported by OBJ format");
1093
+ if (segment >= SEG_ABS)
1094
+ nasm_error(ERR_NONFATAL, "far-absolute relocations not supported"
1095
+ " by OBJ format");
1096
+
1097
+ ldata = *(int64_t *)data;
1098
+ if (type != OUT_ADDRESS) {
1099
+ /*
1100
+ * For 16-bit and 32-bit x86 code, the size and realsize() always
1101
+ * matches as only jumps, calls and loops uses PC relative
1102
+ * addressing and the address isn't followed by any other opcode
1103
+ * bytes. In 64-bit mode there is RIP relative addressing which
1104
+ * means the fixup location can be followed by an immediate value,
1105
+ * meaning that size > realsize().
1106
+ *
1107
+ * When the CPU is calculating the effective address, it takes the
1108
+ * RIP at the end of the instruction and adds the fixed up relative
1109
+ * address value to it.
1110
+ *
1111
+ * The linker's point of reference is the end of the fixup location
1112
+ * (which is the end of the instruction for Jcc, CALL, LOOP[cc]).
1113
+ * It is calculating distance between the target symbol and the end
1114
+ * of the fixup location, and add this to the displacement value we
1115
+ * are calculating here and storing at the fixup location.
1116
+ *
1117
+ * To get the right effect, we need to _reduce_ the displacement
1118
+ * value by the number of bytes following the fixup.
1119
+ *
1120
+ * Example:
1121
+ * data at address 0x100; REL4ADR at 0x050, 4 byte immediate,
1122
+ * end of fixup at 0x054, end of instruction at 0x058.
1123
+ * => size = 8.
1124
+ * => realsize() -> 4
1125
+ * => CPU needs a value of: 0x100 - 0x058 = 0x0a8
1126
+ * => linker/loader will add: 0x100 - 0x054 = 0x0ac
1127
+ * => We must add an addend of -4.
1128
+ * => realsize() - size = -4.
1129
+ *
1130
+ * The code used to do size - realsize() at least since v0.90,
1131
+ * probably because it wasn't needed...
1132
+ */
1133
+ ldata -= size;
1134
+ size = realsize(type, size);
1135
+ ldata += size;
1136
+ }
1137
+
1138
+ switch (size) {
1139
+ default:
1140
+ nasm_error(ERR_NONFATAL, "OBJ format can only handle 16- or "
1141
+ "32-byte relocations");
1142
+ segment = NO_SEG; /* Don't actually generate a relocation */
1143
+ break;
1144
+ case 2:
1145
+ orp = obj_word(orp, ldata);
1146
+ break;
1147
+ case 4:
1148
+ orp = obj_dword(orp, ldata);
1149
+ break;
1150
+ }
1151
+
1152
+ rsize = size;
1153
+ if (segment < SEG_ABS && (segment != NO_SEG && segment % 2) &&
1154
+ size == 4) {
1155
+ /*
1156
+ * This is a 4-byte segment-base relocation such as
1157
+ * `MOV EAX,SEG foo'. OBJ format can't actually handle
1158
+ * these, but if the constant term has the 16 low bits
1159
+ * zero, we can just apply a 2-byte segment-base
1160
+ * relocation to the low word instead.
1161
+ */
1162
+ rsize = 2;
1163
+ if (ldata & 0xFFFF)
1164
+ nasm_error(ERR_NONFATAL, "OBJ format cannot handle complex"
1165
+ " dword-size segment base references");
1166
+ }
1167
+ if (segment != NO_SEG)
1168
+ obj_write_fixup(orp, rsize,
1169
+ (type == OUT_ADDRESS ? 0x4000 : 0),
1170
+ segment, wrt, seg);
1171
+ seg->currentpos += size;
1172
+ break;
1173
+ }
1174
+
1175
+ default:
1176
+ nasm_error(ERR_NONFATAL,
1177
+ "Relocation type not supported by output format");
1178
+ /* fall through */
1179
+
1180
+ case OUT_RESERVE:
1181
+ if (orp->committed)
1182
+ orp = obj_bump(orp);
1183
+ seg->currentpos += size;
1184
+ break;
1185
+ }
1186
+ obj_commit(orp);
1187
+ }
1188
+
1189
+ static void obj_write_fixup(ObjRecord * orp, int bytes,
1190
+ int segrel, int32_t seg, int32_t wrt,
1191
+ struct Segment *segto)
1192
+ {
1193
+ unsigned locat;
1194
+ int method;
1195
+ int base;
1196
+ int32_t tidx, fidx;
1197
+ struct Segment *s = NULL;
1198
+ struct Group *g = NULL;
1199
+ struct External *e = NULL;
1200
+ ObjRecord *forp;
1201
+
1202
+ if (bytes != 2 && bytes != 4) {
1203
+ nasm_error(ERR_NONFATAL, "`obj' output driver does not support"
1204
+ " %d-bit relocations", bytes << 3);
1205
+ return;
1206
+ }
1207
+
1208
+ forp = orp->child;
1209
+ if (forp == NULL) {
1210
+ orp->child = forp = obj_new();
1211
+ forp->up = &(orp->child);
1212
+ /* We should choose between FIXUPP and FIXU32 record type */
1213
+ /* If we're targeting a 32-bit segment, use a FIXU32 record */
1214
+ if (segto->use32)
1215
+ forp->type = FIXU32;
1216
+ else
1217
+ forp->type = FIXUPP;
1218
+ }
1219
+
1220
+ if (seg % 2) {
1221
+ base = true;
1222
+ locat = FIX_16_SELECTOR;
1223
+ seg--;
1224
+ if (bytes != 2)
1225
+ nasm_panic(0, "OBJ: 4-byte segment base fixup got"
1226
+ " through sanity check");
1227
+ } else {
1228
+ base = false;
1229
+ locat = (bytes == 2) ? FIX_16_OFFSET : FIX_32_OFFSET;
1230
+ if (!segrel)
1231
+ /*
1232
+ * There is a bug in tlink that makes it process self relative
1233
+ * fixups incorrectly if the x_size doesn't match the location
1234
+ * size.
1235
+ */
1236
+ forp = obj_force(forp, bytes << 3);
1237
+ }
1238
+
1239
+ forp = obj_rword(forp, locat | segrel | (orp->parm[0] - orp->parm[2]));
1240
+
1241
+ tidx = fidx = -1, method = 0; /* placate optimisers */
1242
+
1243
+ /*
1244
+ * See if we can find the segment ID in our segment list. If
1245
+ * so, we have a T4 (LSEG) target.
1246
+ */
1247
+ for (s = seghead; s; s = s->next)
1248
+ if (s->index == seg)
1249
+ break;
1250
+ if (s)
1251
+ method = 4, tidx = s->obj_index;
1252
+ else {
1253
+ for (g = grphead; g; g = g->next)
1254
+ if (g->index == seg)
1255
+ break;
1256
+ if (g)
1257
+ method = 5, tidx = g->obj_index;
1258
+ else {
1259
+ int32_t i = seg / 2;
1260
+ struct ExtBack *eb = ebhead;
1261
+ while (i >= EXT_BLKSIZ) {
1262
+ if (eb)
1263
+ eb = eb->next;
1264
+ else
1265
+ break;
1266
+ i -= EXT_BLKSIZ;
1267
+ }
1268
+ if (eb)
1269
+ method = 6, e = eb->exts[i], tidx = e->index;
1270
+ else
1271
+ nasm_panic(0,
1272
+ "unrecognised segment value in obj_write_fixup");
1273
+ }
1274
+ }
1275
+
1276
+ /*
1277
+ * If no WRT given, assume the natural default, which is method
1278
+ * F5 unless:
1279
+ *
1280
+ * - we are doing an OFFSET fixup for a grouped segment, in
1281
+ * which case we require F1 (group).
1282
+ *
1283
+ * - we are doing an OFFSET fixup for an external with a
1284
+ * default WRT, in which case we must honour the default WRT.
1285
+ */
1286
+ if (wrt == NO_SEG) {
1287
+ if (!base && s && s->grp)
1288
+ method |= 0x10, fidx = s->grp->obj_index;
1289
+ else if (!base && e && e->defwrt_type != DEFWRT_NONE) {
1290
+ if (e->defwrt_type == DEFWRT_SEGMENT)
1291
+ method |= 0x00, fidx = e->defwrt_ptr.seg->obj_index;
1292
+ else if (e->defwrt_type == DEFWRT_GROUP)
1293
+ method |= 0x10, fidx = e->defwrt_ptr.grp->obj_index;
1294
+ else {
1295
+ nasm_error(ERR_NONFATAL, "default WRT specification for"
1296
+ " external `%s' unresolved", e->name);
1297
+ method |= 0x50, fidx = -1; /* got to do _something_ */
1298
+ }
1299
+ } else
1300
+ method |= 0x50, fidx = -1;
1301
+ } else {
1302
+ /*
1303
+ * See if we can find the WRT-segment ID in our segment
1304
+ * list. If so, we have a F0 (LSEG) frame.
1305
+ */
1306
+ for (s = seghead; s; s = s->next)
1307
+ if (s->index == wrt - 1)
1308
+ break;
1309
+ if (s)
1310
+ method |= 0x00, fidx = s->obj_index;
1311
+ else {
1312
+ for (g = grphead; g; g = g->next)
1313
+ if (g->index == wrt - 1)
1314
+ break;
1315
+ if (g)
1316
+ method |= 0x10, fidx = g->obj_index;
1317
+ else {
1318
+ int32_t i = wrt / 2;
1319
+ struct ExtBack *eb = ebhead;
1320
+ while (i >= EXT_BLKSIZ) {
1321
+ if (eb)
1322
+ eb = eb->next;
1323
+ else
1324
+ break;
1325
+ i -= EXT_BLKSIZ;
1326
+ }
1327
+ if (eb)
1328
+ method |= 0x20, fidx = eb->exts[i]->index;
1329
+ else
1330
+ nasm_panic(0,
1331
+ "unrecognised WRT value in obj_write_fixup");
1332
+ }
1333
+ }
1334
+ }
1335
+
1336
+ forp = obj_byte(forp, method);
1337
+ if (fidx != -1)
1338
+ forp = obj_index(forp, fidx);
1339
+ forp = obj_index(forp, tidx);
1340
+ obj_commit(forp);
1341
+ }
1342
+
1343
+ static int32_t obj_segment(char *name, int pass, int *bits)
1344
+ {
1345
+ /*
1346
+ * We call the label manager here to define a name for the new
1347
+ * segment, and when our _own_ label-definition stub gets
1348
+ * called in return, it should register the new segment name
1349
+ * using the pointer it gets passed. That way we save memory,
1350
+ * by sponging off the label manager.
1351
+ */
1352
+ #if defined(DEBUG) && DEBUG>=3
1353
+ nasm_error(ERR_DEBUG, " obj_segment: < %s >, pass=%d, *bits=%d\n",
1354
+ name, pass, *bits);
1355
+ #endif
1356
+ if (!name) {
1357
+ *bits = 16;
1358
+ current_seg = NULL;
1359
+ return first_seg;
1360
+ } else {
1361
+ struct Segment *seg;
1362
+ struct Group *grp;
1363
+ struct External **extp;
1364
+ int obj_idx, i, attrs;
1365
+ bool rn_error;
1366
+ char *p;
1367
+
1368
+ /*
1369
+ * Look for segment attributes.
1370
+ */
1371
+ attrs = 0;
1372
+ while (*name == '.')
1373
+ name++; /* hack, but a documented one */
1374
+ p = name;
1375
+ while (*p && !nasm_isspace(*p))
1376
+ p++;
1377
+ if (*p) {
1378
+ *p++ = '\0';
1379
+ while (*p && nasm_isspace(*p))
1380
+ *p++ = '\0';
1381
+ }
1382
+ while (*p) {
1383
+ while (*p && !nasm_isspace(*p))
1384
+ p++;
1385
+ if (*p) {
1386
+ *p++ = '\0';
1387
+ while (*p && nasm_isspace(*p))
1388
+ *p++ = '\0';
1389
+ }
1390
+
1391
+ attrs++;
1392
+ }
1393
+
1394
+ obj_idx = 1;
1395
+ for (seg = seghead; seg; seg = seg->next) {
1396
+ obj_idx++;
1397
+ if (!strcmp(seg->name, name)) {
1398
+ if (attrs > 0 && pass == 1)
1399
+ nasm_error(ERR_WARNING, "segment attributes specified on"
1400
+ " redeclaration of segment: ignoring");
1401
+ if (seg->use32)
1402
+ *bits = 32;
1403
+ else
1404
+ *bits = 16;
1405
+ current_seg = seg;
1406
+ return seg->index;
1407
+ }
1408
+ }
1409
+
1410
+ *segtail = seg = nasm_malloc(sizeof(*seg));
1411
+ seg->next = NULL;
1412
+ segtail = &seg->next;
1413
+ seg->index = (any_segs ? seg_alloc() : first_seg);
1414
+ seg->obj_index = obj_idx;
1415
+ seg->grp = NULL;
1416
+ any_segs = true;
1417
+ seg->name = NULL;
1418
+ seg->currentpos = 0;
1419
+ seg->align = 1; /* default */
1420
+ seg->use32 = false; /* default */
1421
+ seg->combine = CMB_PUBLIC; /* default */
1422
+ seg->segclass = seg->overlay = NULL;
1423
+ seg->pubhead = NULL;
1424
+ seg->pubtail = &seg->pubhead;
1425
+ seg->lochead = NULL;
1426
+ seg->loctail = &seg->lochead;
1427
+ seg->orp = obj_new();
1428
+ seg->orp->up = &(seg->orp);
1429
+ seg->orp->ori = ori_ledata;
1430
+ seg->orp->type = LEDATA;
1431
+ seg->orp->parm[1] = obj_idx;
1432
+
1433
+ /*
1434
+ * Process the segment attributes.
1435
+ */
1436
+ p = name;
1437
+ while (attrs--) {
1438
+ p += strlen(p);
1439
+ while (!*p)
1440
+ p++;
1441
+
1442
+ /*
1443
+ * `p' contains a segment attribute.
1444
+ */
1445
+ if (!nasm_stricmp(p, "private"))
1446
+ seg->combine = CMB_PRIVATE;
1447
+ else if (!nasm_stricmp(p, "public"))
1448
+ seg->combine = CMB_PUBLIC;
1449
+ else if (!nasm_stricmp(p, "common"))
1450
+ seg->combine = CMB_COMMON;
1451
+ else if (!nasm_stricmp(p, "stack"))
1452
+ seg->combine = CMB_STACK;
1453
+ else if (!nasm_stricmp(p, "use16"))
1454
+ seg->use32 = false;
1455
+ else if (!nasm_stricmp(p, "use32"))
1456
+ seg->use32 = true;
1457
+ else if (!nasm_stricmp(p, "flat")) {
1458
+ /*
1459
+ * This segment is an OS/2 FLAT segment. That means
1460
+ * that its default group is group FLAT, even if
1461
+ * the group FLAT does not explicitly _contain_ the
1462
+ * segment.
1463
+ *
1464
+ * When we see this, we must create the group
1465
+ * `FLAT', containing no segments, if it does not
1466
+ * already exist; then we must set the default
1467
+ * group of this segment to be the FLAT group.
1468
+ */
1469
+ struct Group *grp;
1470
+ for (grp = grphead; grp; grp = grp->next)
1471
+ if (!strcmp(grp->name, "FLAT"))
1472
+ break;
1473
+ if (!grp) {
1474
+ obj_directive(D_GROUP, "FLAT", 1);
1475
+ for (grp = grphead; grp; grp = grp->next)
1476
+ if (!strcmp(grp->name, "FLAT"))
1477
+ break;
1478
+ if (!grp)
1479
+ nasm_panic(0, "failure to define FLAT?!");
1480
+ }
1481
+ seg->grp = grp;
1482
+ } else if (!nasm_strnicmp(p, "class=", 6))
1483
+ seg->segclass = nasm_strdup(p + 6);
1484
+ else if (!nasm_strnicmp(p, "overlay=", 8))
1485
+ seg->overlay = nasm_strdup(p + 8);
1486
+ else if (!nasm_strnicmp(p, "align=", 6)) {
1487
+ seg->align = readnum(p + 6, &rn_error);
1488
+ if (rn_error) {
1489
+ seg->align = 1;
1490
+ nasm_error(ERR_NONFATAL, "segment alignment should be"
1491
+ " numeric");
1492
+ }
1493
+ switch (seg->align) {
1494
+ case 1: /* BYTE */
1495
+ case 2: /* WORD */
1496
+ case 4: /* DWORD */
1497
+ case 16: /* PARA */
1498
+ case 256: /* PAGE */
1499
+ case 4096: /* PharLap extension */
1500
+ break;
1501
+ case 8:
1502
+ nasm_error(ERR_WARNING,
1503
+ "OBJ format does not support alignment"
1504
+ " of 8: rounding up to 16");
1505
+ seg->align = 16;
1506
+ break;
1507
+ case 32:
1508
+ case 64:
1509
+ case 128:
1510
+ nasm_error(ERR_WARNING,
1511
+ "OBJ format does not support alignment"
1512
+ " of %d: rounding up to 256", seg->align);
1513
+ seg->align = 256;
1514
+ break;
1515
+ case 512:
1516
+ case 1024:
1517
+ case 2048:
1518
+ nasm_error(ERR_WARNING,
1519
+ "OBJ format does not support alignment"
1520
+ " of %d: rounding up to 4096", seg->align);
1521
+ seg->align = 4096;
1522
+ break;
1523
+ default:
1524
+ nasm_error(ERR_NONFATAL, "invalid alignment value %d",
1525
+ seg->align);
1526
+ seg->align = 1;
1527
+ break;
1528
+ }
1529
+ } else if (!nasm_strnicmp(p, "absolute=", 9)) {
1530
+ seg->align = SEG_ABS + readnum(p + 9, &rn_error);
1531
+ if (rn_error)
1532
+ nasm_error(ERR_NONFATAL, "argument to `absolute' segment"
1533
+ " attribute should be numeric");
1534
+ }
1535
+ }
1536
+
1537
+ /* We need to know whenever we have at least one 32-bit segment */
1538
+ obj_use32 |= seg->use32;
1539
+
1540
+ obj_seg_needs_update = seg;
1541
+ if (seg->align >= SEG_ABS)
1542
+ define_label(name, NO_SEG, seg->align - SEG_ABS,
1543
+ NULL, false, false);
1544
+ else
1545
+ define_label(name, seg->index + 1, 0L,
1546
+ NULL, false, false);
1547
+ obj_seg_needs_update = NULL;
1548
+
1549
+ /*
1550
+ * See if this segment is defined in any groups.
1551
+ */
1552
+ for (grp = grphead; grp; grp = grp->next) {
1553
+ for (i = grp->nindices; i < grp->nentries; i++) {
1554
+ if (!strcmp(grp->segs[i].name, seg->name)) {
1555
+ nasm_free(grp->segs[i].name);
1556
+ grp->segs[i] = grp->segs[grp->nindices];
1557
+ grp->segs[grp->nindices++].index = seg->obj_index;
1558
+ if (seg->grp)
1559
+ nasm_error(ERR_WARNING,
1560
+ "segment `%s' is already part of"
1561
+ " a group: first one takes precedence",
1562
+ seg->name);
1563
+ else
1564
+ seg->grp = grp;
1565
+ }
1566
+ }
1567
+ }
1568
+
1569
+ /*
1570
+ * Walk through the list of externals with unresolved
1571
+ * default-WRT clauses, and resolve any that point at this
1572
+ * segment.
1573
+ */
1574
+ extp = &dws;
1575
+ while (*extp) {
1576
+ if ((*extp)->defwrt_type == DEFWRT_STRING &&
1577
+ !strcmp((*extp)->defwrt_ptr.string, seg->name)) {
1578
+ nasm_free((*extp)->defwrt_ptr.string);
1579
+ (*extp)->defwrt_type = DEFWRT_SEGMENT;
1580
+ (*extp)->defwrt_ptr.seg = seg;
1581
+ *extp = (*extp)->next_dws;
1582
+ } else
1583
+ extp = &(*extp)->next_dws;
1584
+ }
1585
+
1586
+ if (seg->use32)
1587
+ *bits = 32;
1588
+ else
1589
+ *bits = 16;
1590
+ current_seg = seg;
1591
+ return seg->index;
1592
+ }
1593
+ }
1594
+
1595
+ static enum directive_result
1596
+ obj_directive(enum directive directive, char *value, int pass)
1597
+ {
1598
+ switch (directive) {
1599
+ case D_GROUP:
1600
+ {
1601
+ char *p, *q, *v;
1602
+ if (pass == 1) {
1603
+ struct Group *grp;
1604
+ struct Segment *seg;
1605
+ struct External **extp;
1606
+ int obj_idx;
1607
+
1608
+ q = value;
1609
+ while (*q == '.')
1610
+ q++; /* hack, but a documented one */
1611
+ v = q;
1612
+ while (*q && !nasm_isspace(*q))
1613
+ q++;
1614
+ if (nasm_isspace(*q)) {
1615
+ *q++ = '\0';
1616
+ while (*q && nasm_isspace(*q))
1617
+ q++;
1618
+ }
1619
+ /*
1620
+ * Here we used to sanity-check the group directive to
1621
+ * ensure nobody tried to declare a group containing no
1622
+ * segments. However, OS/2 does this as standard
1623
+ * practice, so the sanity check has been removed.
1624
+ *
1625
+ * if (!*q) {
1626
+ * nasm_error(ERR_NONFATAL,"GROUP directive contains no segments");
1627
+ * return DIRR_ERROR;
1628
+ * }
1629
+ */
1630
+
1631
+ obj_idx = 1;
1632
+ for (grp = grphead; grp; grp = grp->next) {
1633
+ obj_idx++;
1634
+ if (!strcmp(grp->name, v)) {
1635
+ nasm_error(ERR_NONFATAL, "group `%s' defined twice", v);
1636
+ return DIRR_ERROR;
1637
+ }
1638
+ }
1639
+
1640
+ *grptail = grp = nasm_malloc(sizeof(*grp));
1641
+ grp->next = NULL;
1642
+ grptail = &grp->next;
1643
+ grp->index = seg_alloc();
1644
+ grp->obj_index = obj_idx;
1645
+ grp->nindices = grp->nentries = 0;
1646
+ grp->name = NULL;
1647
+
1648
+ obj_grp_needs_update = grp;
1649
+ define_label(v, grp->index + 1, 0L, NULL, false, false);
1650
+ obj_grp_needs_update = NULL;
1651
+
1652
+ while (*q) {
1653
+ p = q;
1654
+ while (*q && !nasm_isspace(*q))
1655
+ q++;
1656
+ if (nasm_isspace(*q)) {
1657
+ *q++ = '\0';
1658
+ while (*q && nasm_isspace(*q))
1659
+ q++;
1660
+ }
1661
+ /*
1662
+ * Now p contains a segment name. Find it.
1663
+ */
1664
+ for (seg = seghead; seg; seg = seg->next)
1665
+ if (!strcmp(seg->name, p))
1666
+ break;
1667
+ if (seg) {
1668
+ /*
1669
+ * We have a segment index. Shift a name entry
1670
+ * to the end of the array to make room.
1671
+ */
1672
+ grp->segs[grp->nentries++] = grp->segs[grp->nindices];
1673
+ grp->segs[grp->nindices++].index = seg->obj_index;
1674
+ if (seg->grp)
1675
+ nasm_error(ERR_WARNING,
1676
+ "segment `%s' is already part of"
1677
+ " a group: first one takes precedence",
1678
+ seg->name);
1679
+ else
1680
+ seg->grp = grp;
1681
+ } else {
1682
+ /*
1683
+ * We have an as-yet undefined segment.
1684
+ * Remember its name, for later.
1685
+ */
1686
+ grp->segs[grp->nentries++].name = nasm_strdup(p);
1687
+ }
1688
+ }
1689
+
1690
+ /*
1691
+ * Walk through the list of externals with unresolved
1692
+ * default-WRT clauses, and resolve any that point at
1693
+ * this group.
1694
+ */
1695
+ extp = &dws;
1696
+ while (*extp) {
1697
+ if ((*extp)->defwrt_type == DEFWRT_STRING &&
1698
+ !strcmp((*extp)->defwrt_ptr.string, grp->name)) {
1699
+ nasm_free((*extp)->defwrt_ptr.string);
1700
+ (*extp)->defwrt_type = DEFWRT_GROUP;
1701
+ (*extp)->defwrt_ptr.grp = grp;
1702
+ *extp = (*extp)->next_dws;
1703
+ } else
1704
+ extp = &(*extp)->next_dws;
1705
+ }
1706
+ }
1707
+ return DIRR_OK;
1708
+ }
1709
+ case D_UPPERCASE:
1710
+ obj_uppercase = true;
1711
+ return DIRR_OK;
1712
+
1713
+ case D_IMPORT:
1714
+ {
1715
+ char *q, *extname, *libname, *impname;
1716
+
1717
+ if (pass == 2)
1718
+ return 1; /* ignore in pass two */
1719
+ extname = q = value;
1720
+ while (*q && !nasm_isspace(*q))
1721
+ q++;
1722
+ if (nasm_isspace(*q)) {
1723
+ *q++ = '\0';
1724
+ while (*q && nasm_isspace(*q))
1725
+ q++;
1726
+ }
1727
+
1728
+ libname = q;
1729
+ while (*q && !nasm_isspace(*q))
1730
+ q++;
1731
+ if (nasm_isspace(*q)) {
1732
+ *q++ = '\0';
1733
+ while (*q && nasm_isspace(*q))
1734
+ q++;
1735
+ }
1736
+
1737
+ impname = q;
1738
+
1739
+ if (!*extname || !*libname)
1740
+ nasm_error(ERR_NONFATAL, "`import' directive requires symbol name"
1741
+ " and library name");
1742
+ else {
1743
+ struct ImpDef *imp;
1744
+ bool err = false;
1745
+
1746
+ imp = *imptail = nasm_malloc(sizeof(struct ImpDef));
1747
+ imptail = &imp->next;
1748
+ imp->next = NULL;
1749
+ imp->extname = nasm_strdup(extname);
1750
+ imp->libname = nasm_strdup(libname);
1751
+ imp->impindex = readnum(impname, &err);
1752
+ if (!*impname || err)
1753
+ imp->impname = nasm_strdup(impname);
1754
+ else
1755
+ imp->impname = NULL;
1756
+ }
1757
+
1758
+ return DIRR_OK;
1759
+ }
1760
+ case D_EXPORT:
1761
+ {
1762
+ char *q, *extname, *intname, *v;
1763
+ struct ExpDef *export;
1764
+ int flags = 0;
1765
+ unsigned int ordinal = 0;
1766
+
1767
+ if (pass == 2)
1768
+ return DIRR_OK; /* ignore in pass two */
1769
+ intname = q = value;
1770
+ while (*q && !nasm_isspace(*q))
1771
+ q++;
1772
+ if (nasm_isspace(*q)) {
1773
+ *q++ = '\0';
1774
+ while (*q && nasm_isspace(*q))
1775
+ q++;
1776
+ }
1777
+
1778
+ extname = q;
1779
+ while (*q && !nasm_isspace(*q))
1780
+ q++;
1781
+ if (nasm_isspace(*q)) {
1782
+ *q++ = '\0';
1783
+ while (*q && nasm_isspace(*q))
1784
+ q++;
1785
+ }
1786
+
1787
+ if (!*intname) {
1788
+ nasm_error(ERR_NONFATAL, "`export' directive requires export name");
1789
+ return DIRR_OK;
1790
+ }
1791
+ if (!*extname) {
1792
+ extname = intname;
1793
+ intname = "";
1794
+ }
1795
+ while (*q) {
1796
+ v = q;
1797
+ while (*q && !nasm_isspace(*q))
1798
+ q++;
1799
+ if (nasm_isspace(*q)) {
1800
+ *q++ = '\0';
1801
+ while (*q && nasm_isspace(*q))
1802
+ q++;
1803
+ }
1804
+ if (!nasm_stricmp(v, "resident"))
1805
+ flags |= EXPDEF_FLAG_RESIDENT;
1806
+ else if (!nasm_stricmp(v, "nodata"))
1807
+ flags |= EXPDEF_FLAG_NODATA;
1808
+ else if (!nasm_strnicmp(v, "parm=", 5)) {
1809
+ bool err = false;
1810
+ flags |= EXPDEF_MASK_PARMCNT & readnum(v + 5, &err);
1811
+ if (err) {
1812
+ nasm_error(ERR_NONFATAL,
1813
+ "value `%s' for `parm' is non-numeric", v + 5);
1814
+ return DIRR_ERROR;
1815
+ }
1816
+ } else {
1817
+ bool err = false;
1818
+ ordinal = readnum(v, &err);
1819
+ if (err) {
1820
+ nasm_error(ERR_NONFATAL,
1821
+ "unrecognised export qualifier `%s'", v);
1822
+ return DIRR_ERROR;
1823
+ }
1824
+ flags |= EXPDEF_FLAG_ORDINAL;
1825
+ }
1826
+ }
1827
+
1828
+ export = *exptail = nasm_malloc(sizeof(struct ExpDef));
1829
+ exptail = &export->next;
1830
+ export->next = NULL;
1831
+ export->extname = nasm_strdup(extname);
1832
+ export->intname = nasm_strdup(intname);
1833
+ export->ordinal = ordinal;
1834
+ export->flags = flags;
1835
+
1836
+ return DIRR_OK;
1837
+ }
1838
+ default:
1839
+ return DIRR_UNKNOWN;
1840
+ }
1841
+ }
1842
+
1843
+ static void obj_sectalign(int32_t seg, unsigned int value)
1844
+ {
1845
+ struct Segment *s;
1846
+
1847
+ list_for_each(s, seghead) {
1848
+ if (s->index == seg)
1849
+ break;
1850
+ }
1851
+
1852
+ /*
1853
+ * it should not be too big value
1854
+ * and applied on non-absolute sections
1855
+ */
1856
+ if (!s || !is_power2(value) ||
1857
+ value > 4096 || s->align >= SEG_ABS)
1858
+ return;
1859
+
1860
+ /*
1861
+ * FIXME: No code duplication please
1862
+ * consider making helper for this
1863
+ * mapping since section handler has
1864
+ * to do the same
1865
+ */
1866
+ switch (value) {
1867
+ case 8:
1868
+ value = 16;
1869
+ break;
1870
+ case 32:
1871
+ case 64:
1872
+ case 128:
1873
+ value = 256;
1874
+ break;
1875
+ case 512:
1876
+ case 1024:
1877
+ case 2048:
1878
+ value = 4096;
1879
+ break;
1880
+ }
1881
+
1882
+ if (s->align < (int)value)
1883
+ s->align = value;
1884
+ }
1885
+
1886
+ static int32_t obj_segbase(int32_t segment)
1887
+ {
1888
+ struct Segment *seg;
1889
+
1890
+ /*
1891
+ * Find the segment in our list.
1892
+ */
1893
+ for (seg = seghead; seg; seg = seg->next)
1894
+ if (seg->index == segment - 1)
1895
+ break;
1896
+
1897
+ if (!seg) {
1898
+ /*
1899
+ * Might be an external with a default WRT.
1900
+ */
1901
+ int32_t i = segment / 2;
1902
+ struct ExtBack *eb = ebhead;
1903
+ struct External *e;
1904
+
1905
+ while (i >= EXT_BLKSIZ) {
1906
+ if (eb)
1907
+ eb = eb->next;
1908
+ else
1909
+ break;
1910
+ i -= EXT_BLKSIZ;
1911
+ }
1912
+ if (eb) {
1913
+ e = eb->exts[i];
1914
+ if (!e) {
1915
+ nasm_assert(pass0 == 0);
1916
+ /* Not available - can happen during optimization */
1917
+ return NO_SEG;
1918
+ }
1919
+
1920
+ switch (e->defwrt_type) {
1921
+ case DEFWRT_NONE:
1922
+ return segment; /* fine */
1923
+ case DEFWRT_SEGMENT:
1924
+ return e->defwrt_ptr.seg->index + 1;
1925
+ case DEFWRT_GROUP:
1926
+ return e->defwrt_ptr.grp->index + 1;
1927
+ default:
1928
+ return NO_SEG; /* can't tell what it is */
1929
+ }
1930
+ }
1931
+
1932
+ return segment; /* not one of ours - leave it alone */
1933
+ }
1934
+
1935
+ if (seg->align >= SEG_ABS)
1936
+ return seg->align; /* absolute segment */
1937
+ if (seg->grp)
1938
+ return seg->grp->index + 1; /* grouped segment */
1939
+
1940
+ return segment; /* no special treatment */
1941
+ }
1942
+
1943
+ static void obj_filename(char *inname, char *outname)
1944
+ {
1945
+ strcpy(obj_infile, inname);
1946
+ standard_extension(inname, outname, ".obj");
1947
+ }
1948
+
1949
+ /* Get a file timestamp in MS-DOS format */
1950
+ static uint32_t obj_file_timestamp(const char *pathname)
1951
+ {
1952
+ time_t t;
1953
+ const struct tm *lt;
1954
+
1955
+ if (!nasm_file_time(&t, pathname))
1956
+ return 0;
1957
+
1958
+ lt = localtime(&t);
1959
+ if (!lt)
1960
+ return 0;
1961
+
1962
+ if (lt->tm_year < 80 || lt->tm_year > 207)
1963
+ return 0; /* Only years 1980-2107 representable */
1964
+
1965
+ return
1966
+ ((uint32_t)lt->tm_sec >> 1) +
1967
+ ((uint32_t)lt->tm_min << 5) +
1968
+ ((uint32_t)lt->tm_hour << 11) +
1969
+ ((uint32_t)lt->tm_mday << 16) +
1970
+ (((uint32_t)lt->tm_mon + 1) << 21) +
1971
+ (((uint32_t)lt->tm_year - 80) << 25);
1972
+ }
1973
+
1974
+ static void obj_write_file(void)
1975
+ {
1976
+ struct Segment *seg, *entry_seg_ptr = 0;
1977
+ struct FileName *fn;
1978
+ struct LineNumber *ln;
1979
+ struct Group *grp;
1980
+ struct Public *pub, *loc;
1981
+ struct External *ext;
1982
+ struct ImpDef *imp;
1983
+ struct ExpDef *export;
1984
+ int lname_idx;
1985
+ ObjRecord *orp;
1986
+ const StrList *depfile;
1987
+ const bool debuginfo = (dfmt == &borland_debug_form);
1988
+
1989
+ /*
1990
+ * Write the THEADR module header.
1991
+ */
1992
+ orp = obj_new();
1993
+ orp->type = THEADR;
1994
+ obj_name(orp, obj_infile);
1995
+ obj_emit2(orp);
1996
+
1997
+ /*
1998
+ * Write the NASM boast comment.
1999
+ */
2000
+ orp->type = COMENT;
2001
+ obj_rword(orp, dTRANSL);
2002
+ obj_name(orp, nasm_comment);
2003
+ obj_emit2(orp);
2004
+
2005
+ /*
2006
+ * Output file dependency information
2007
+ */
2008
+ if (!obj_nodepend) {
2009
+ list_for_each(depfile, depend_list) {
2010
+ uint32_t ts;
2011
+
2012
+ ts = obj_file_timestamp(depfile->str);
2013
+ if (ts) {
2014
+ orp->type = COMENT;
2015
+ obj_rword(orp, dDEPFILE);
2016
+ obj_dword(orp, ts);
2017
+ obj_name(orp, depfile->str);
2018
+ obj_emit2(orp);
2019
+ }
2020
+ }
2021
+ }
2022
+
2023
+ orp->type = COMENT;
2024
+ /*
2025
+ * Write the IMPDEF records, if any.
2026
+ */
2027
+ for (imp = imphead; imp; imp = imp->next) {
2028
+ obj_rword(orp, dOMFEXT);
2029
+ obj_byte(orp, 1); /* subfunction 1: IMPDEF */
2030
+ if (imp->impname)
2031
+ obj_byte(orp, 0); /* import by name */
2032
+ else
2033
+ obj_byte(orp, 1); /* import by ordinal */
2034
+ obj_name(orp, imp->extname);
2035
+ obj_name(orp, imp->libname);
2036
+ if (imp->impname)
2037
+ obj_name(orp, imp->impname);
2038
+ else
2039
+ obj_word(orp, imp->impindex);
2040
+ obj_emit2(orp);
2041
+ }
2042
+
2043
+ /*
2044
+ * Write the EXPDEF records, if any.
2045
+ */
2046
+ for (export = exphead; export; export = export->next) {
2047
+ obj_rword(orp, dOMFEXT);
2048
+ obj_byte(orp, 2); /* subfunction 2: EXPDEF */
2049
+ obj_byte(orp, export->flags);
2050
+ obj_name(orp, export->extname);
2051
+ obj_name(orp, export->intname);
2052
+ if (export->flags & EXPDEF_FLAG_ORDINAL)
2053
+ obj_word(orp, export->ordinal);
2054
+ obj_emit2(orp);
2055
+ }
2056
+
2057
+ /* we're using extended OMF if we put in debug info */
2058
+ if (debuginfo) {
2059
+ orp->type = COMENT;
2060
+ obj_rword(orp, dEXTENDED);
2061
+ obj_emit2(orp);
2062
+ }
2063
+
2064
+ /*
2065
+ * Write the first LNAMES record, containing LNAME one, which
2066
+ * is null. Also initialize the LNAME counter.
2067
+ */
2068
+ orp->type = LNAMES;
2069
+ obj_byte(orp, 0);
2070
+ lname_idx = 1;
2071
+ /*
2072
+ * Write some LNAMES for the segment names
2073
+ */
2074
+ for (seg = seghead; seg; seg = seg->next) {
2075
+ orp = obj_name(orp, seg->name);
2076
+ if (seg->segclass)
2077
+ orp = obj_name(orp, seg->segclass);
2078
+ if (seg->overlay)
2079
+ orp = obj_name(orp, seg->overlay);
2080
+ obj_commit(orp);
2081
+ }
2082
+ /*
2083
+ * Write some LNAMES for the group names
2084
+ */
2085
+ for (grp = grphead; grp; grp = grp->next) {
2086
+ orp = obj_name(orp, grp->name);
2087
+ obj_commit(orp);
2088
+ }
2089
+ obj_emit(orp);
2090
+
2091
+ /*
2092
+ * Write the SEGDEF records.
2093
+ */
2094
+ orp->type = SEGDEF;
2095
+ for (seg = seghead; seg; seg = seg->next) {
2096
+ int acbp;
2097
+ uint32_t seglen = seg->currentpos;
2098
+
2099
+ acbp = (seg->combine << 2); /* C field */
2100
+
2101
+ if (seg->use32)
2102
+ acbp |= 0x01; /* P bit is Use32 flag */
2103
+ else if (seglen == 0x10000L) {
2104
+ seglen = 0; /* This special case may be needed for old linkers */
2105
+ acbp |= 0x02; /* B bit */
2106
+ }
2107
+
2108
+ /* A field */
2109
+ if (seg->align >= SEG_ABS)
2110
+ /* acbp |= 0x00 */ ;
2111
+ else if (seg->align >= 4096) {
2112
+ if (seg->align > 4096)
2113
+ nasm_error(ERR_NONFATAL, "segment `%s' requires more alignment"
2114
+ " than OBJ format supports", seg->name);
2115
+ acbp |= 0xC0; /* PharLap extension */
2116
+ } else if (seg->align >= 256) {
2117
+ acbp |= 0x80;
2118
+ } else if (seg->align >= 16) {
2119
+ acbp |= 0x60;
2120
+ } else if (seg->align >= 4) {
2121
+ acbp |= 0xA0;
2122
+ } else if (seg->align >= 2) {
2123
+ acbp |= 0x40;
2124
+ } else
2125
+ acbp |= 0x20;
2126
+
2127
+ obj_byte(orp, acbp);
2128
+ if (seg->align & SEG_ABS) {
2129
+ obj_x(orp, seg->align - SEG_ABS); /* Frame */
2130
+ obj_byte(orp, 0); /* Offset */
2131
+ }
2132
+ obj_x(orp, seglen);
2133
+ obj_index(orp, ++lname_idx);
2134
+ obj_index(orp, seg->segclass ? ++lname_idx : 1);
2135
+ obj_index(orp, seg->overlay ? ++lname_idx : 1);
2136
+ obj_emit2(orp);
2137
+ }
2138
+
2139
+ /*
2140
+ * Write the GRPDEF records.
2141
+ */
2142
+ orp->type = GRPDEF;
2143
+ for (grp = grphead; grp; grp = grp->next) {
2144
+ int i;
2145
+
2146
+ if (grp->nindices != grp->nentries) {
2147
+ for (i = grp->nindices; i < grp->nentries; i++) {
2148
+ nasm_error(ERR_NONFATAL, "group `%s' contains undefined segment"
2149
+ " `%s'", grp->name, grp->segs[i].name);
2150
+ nasm_free(grp->segs[i].name);
2151
+ grp->segs[i].name = NULL;
2152
+ }
2153
+ }
2154
+ obj_index(orp, ++lname_idx);
2155
+ for (i = 0; i < grp->nindices; i++) {
2156
+ obj_byte(orp, 0xFF);
2157
+ obj_index(orp, grp->segs[i].index);
2158
+ }
2159
+ obj_emit2(orp);
2160
+ }
2161
+
2162
+ /*
2163
+ * Write the PUBDEF records: first the ones in the segments,
2164
+ * then the far-absolutes.
2165
+ */
2166
+ orp->type = PUBDEF;
2167
+ orp->ori = ori_pubdef;
2168
+ for (seg = seghead; seg; seg = seg->next) {
2169
+ orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2170
+ orp->parm[1] = seg->obj_index;
2171
+ for (pub = seg->pubhead; pub; pub = pub->next) {
2172
+ orp = obj_name(orp, pub->name);
2173
+ orp = obj_x(orp, pub->offset);
2174
+ orp = obj_byte(orp, 0); /* type index */
2175
+ obj_commit(orp);
2176
+ }
2177
+ obj_emit(orp);
2178
+ }
2179
+ orp->parm[0] = 0;
2180
+ orp->parm[1] = 0;
2181
+ for (pub = fpubhead; pub; pub = pub->next) { /* pub-crawl :-) */
2182
+ if (orp->parm[2] != (uint32_t)pub->segment) {
2183
+ obj_emit(orp);
2184
+ orp->parm[2] = pub->segment;
2185
+ }
2186
+ orp = obj_name(orp, pub->name);
2187
+ orp = obj_x(orp, pub->offset);
2188
+ orp = obj_byte(orp, 0); /* type index */
2189
+ obj_commit(orp);
2190
+ }
2191
+ obj_emit(orp);
2192
+
2193
+ /*
2194
+ * Write the EXTDEF and COMDEF records, in order.
2195
+ */
2196
+ orp->ori = ori_null;
2197
+ for (ext = exthead; ext; ext = ext->next) {
2198
+ if (ext->commonsize == 0) {
2199
+ if (orp->type != EXTDEF) {
2200
+ obj_emit(orp);
2201
+ orp->type = EXTDEF;
2202
+ }
2203
+ orp = obj_name(orp, ext->name);
2204
+ orp = obj_index(orp, 0);
2205
+ } else {
2206
+ if (orp->type != COMDEF) {
2207
+ obj_emit(orp);
2208
+ orp->type = COMDEF;
2209
+ }
2210
+ orp = obj_name(orp, ext->name);
2211
+ orp = obj_index(orp, 0);
2212
+ if (ext->commonelem) {
2213
+ orp = obj_byte(orp, 0x61); /* far communal */
2214
+ orp = obj_value(orp, (ext->commonsize / ext->commonelem));
2215
+ orp = obj_value(orp, ext->commonelem);
2216
+ } else {
2217
+ orp = obj_byte(orp, 0x62); /* near communal */
2218
+ orp = obj_value(orp, ext->commonsize);
2219
+ }
2220
+ }
2221
+ obj_commit(orp);
2222
+ }
2223
+ obj_emit(orp);
2224
+
2225
+ /*
2226
+ * Write a COMENT record stating that the linker's first pass
2227
+ * may stop processing at this point. Exception is if our
2228
+ * MODEND record specifies a start point, in which case,
2229
+ * according to some variants of the documentation, this COMENT
2230
+ * should be omitted. So we'll omit it just in case.
2231
+ * But, TASM puts it in all the time so if we are using
2232
+ * TASM debug stuff we are putting it in
2233
+ */
2234
+ if (debuginfo || obj_entry_seg == NO_SEG) {
2235
+ orp->type = COMENT;
2236
+ obj_rword(orp, dLINKPASS);
2237
+ obj_byte(orp, 1);
2238
+ obj_emit2(orp);
2239
+ }
2240
+
2241
+ /*
2242
+ * 1) put out the compiler type
2243
+ * 2) Put out the type info. The only type we are using is near label #19
2244
+ */
2245
+ if (debuginfo) {
2246
+ int i;
2247
+ struct Array *arrtmp = arrhead;
2248
+ orp->type = COMENT;
2249
+ obj_rword(orp, dCOMPDEF);
2250
+ obj_byte(orp, 4);
2251
+ obj_byte(orp, 0);
2252
+ obj_emit2(orp);
2253
+
2254
+ obj_rword(orp, dTYPEDEF);
2255
+ obj_word(orp, 0x18); /* type # for linking */
2256
+ obj_word(orp, 6); /* size of type */
2257
+ obj_byte(orp, 0x2a); /* absolute type for debugging */
2258
+ obj_emit2(orp);
2259
+ obj_rword(orp, dTYPEDEF);
2260
+ obj_word(orp, 0x19); /* type # for linking */
2261
+ obj_word(orp, 0); /* size of type */
2262
+ obj_byte(orp, 0x24); /* absolute type for debugging */
2263
+ obj_byte(orp, 0); /* near/far specifier */
2264
+ obj_emit2(orp);
2265
+ obj_rword(orp, dTYPEDEF);
2266
+ obj_word(orp, 0x1A); /* type # for linking */
2267
+ obj_word(orp, 0); /* size of type */
2268
+ obj_byte(orp, 0x24); /* absolute type for debugging */
2269
+ obj_byte(orp, 1); /* near/far specifier */
2270
+ obj_emit2(orp);
2271
+ obj_rword(orp, dTYPEDEF);
2272
+ obj_word(orp, 0x1b); /* type # for linking */
2273
+ obj_word(orp, 0); /* size of type */
2274
+ obj_byte(orp, 0x23); /* absolute type for debugging */
2275
+ obj_byte(orp, 0);
2276
+ obj_byte(orp, 0);
2277
+ obj_byte(orp, 0);
2278
+ obj_emit2(orp);
2279
+ obj_rword(orp, dTYPEDEF);
2280
+ obj_word(orp, 0x1c); /* type # for linking */
2281
+ obj_word(orp, 0); /* size of type */
2282
+ obj_byte(orp, 0x23); /* absolute type for debugging */
2283
+ obj_byte(orp, 0);
2284
+ obj_byte(orp, 4);
2285
+ obj_byte(orp, 0);
2286
+ obj_emit2(orp);
2287
+ obj_rword(orp, dTYPEDEF);
2288
+ obj_word(orp, 0x1d); /* type # for linking */
2289
+ obj_word(orp, 0); /* size of type */
2290
+ obj_byte(orp, 0x23); /* absolute type for debugging */
2291
+ obj_byte(orp, 0);
2292
+ obj_byte(orp, 1);
2293
+ obj_byte(orp, 0);
2294
+ obj_emit2(orp);
2295
+ obj_rword(orp, dTYPEDEF);
2296
+ obj_word(orp, 0x1e); /* type # for linking */
2297
+ obj_word(orp, 0); /* size of type */
2298
+ obj_byte(orp, 0x23); /* absolute type for debugging */
2299
+ obj_byte(orp, 0);
2300
+ obj_byte(orp, 5);
2301
+ obj_byte(orp, 0);
2302
+ obj_emit2(orp);
2303
+
2304
+ /* put out the array types */
2305
+ for (i = ARRAYBOT; i < arrindex; i++) {
2306
+ obj_rword(orp, dTYPEDEF);
2307
+ obj_word(orp, i); /* type # for linking */
2308
+ obj_word(orp, arrtmp->size); /* size of type */
2309
+ obj_byte(orp, 0x1A); /* absolute type for debugging (array) */
2310
+ obj_byte(orp, arrtmp->basetype); /* base type */
2311
+ obj_emit2(orp);
2312
+ arrtmp = arrtmp->next;
2313
+ }
2314
+ }
2315
+ /*
2316
+ * write out line number info with a LINNUM record
2317
+ * switch records when we switch segments, and output the
2318
+ * file in a pseudo-TASM fashion. The record switch is naive; that
2319
+ * is that one file may have many records for the same segment
2320
+ * if there are lots of segment switches
2321
+ */
2322
+ if (fnhead && debuginfo) {
2323
+ seg = fnhead->lnhead->segment;
2324
+
2325
+ for (fn = fnhead; fn; fn = fn->next) {
2326
+ /* write out current file name */
2327
+ orp->type = COMENT;
2328
+ orp->ori = ori_null;
2329
+ obj_rword(orp, dFILNAME);
2330
+ obj_byte(orp, 0);
2331
+ obj_name(orp, fn->name);
2332
+ obj_dword(orp, 0);
2333
+ obj_emit2(orp);
2334
+
2335
+ /* write out line numbers this file */
2336
+
2337
+ orp->type = LINNUM;
2338
+ orp->ori = ori_linnum;
2339
+ for (ln = fn->lnhead; ln; ln = ln->next) {
2340
+ if (seg != ln->segment) {
2341
+ /* if we get here have to flush the buffer and start
2342
+ * a new record for a new segment
2343
+ */
2344
+ seg = ln->segment;
2345
+ obj_emit(orp);
2346
+ }
2347
+ orp->parm[0] = seg->grp ? seg->grp->obj_index : 0;
2348
+ orp->parm[1] = seg->obj_index;
2349
+ orp = obj_word(orp, ln->lineno);
2350
+ orp = obj_x(orp, ln->offset);
2351
+ obj_commit(orp);
2352
+ }
2353
+ obj_emit(orp);
2354
+ }
2355
+ }
2356
+ /*
2357
+ * we are going to locate the entry point segment now
2358
+ * rather than wait until the MODEND record, because,
2359
+ * then we can output a special symbol to tell where the
2360
+ * entry point is.
2361
+ *
2362
+ */
2363
+ if (obj_entry_seg != NO_SEG) {
2364
+ for (seg = seghead; seg; seg = seg->next) {
2365
+ if (seg->index == obj_entry_seg) {
2366
+ entry_seg_ptr = seg;
2367
+ break;
2368
+ }
2369
+ }
2370
+ if (!seg)
2371
+ nasm_error(ERR_NONFATAL, "entry point is not in this module");
2372
+ }
2373
+
2374
+ /*
2375
+ * get ready to put out symbol records
2376
+ */
2377
+ orp->type = COMENT;
2378
+ orp->ori = ori_local;
2379
+
2380
+ /*
2381
+ * put out a symbol for the entry point
2382
+ * no dots in this symbol, because, borland does
2383
+ * not (officially) support dots in label names
2384
+ * and I don't know what various versions of TLINK will do
2385
+ */
2386
+ if (debuginfo && obj_entry_seg != NO_SEG) {
2387
+ orp = obj_name(orp, "start_of_program");
2388
+ orp = obj_word(orp, 0x19); /* type: near label */
2389
+ orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2390
+ orp = obj_index(orp, seg->obj_index);
2391
+ orp = obj_x(orp, obj_entry_ofs);
2392
+ obj_commit(orp);
2393
+ }
2394
+
2395
+ /*
2396
+ * put out the local labels
2397
+ */
2398
+ for (seg = seghead; seg && debuginfo; seg = seg->next) {
2399
+ /* labels this seg */
2400
+ for (loc = seg->lochead; loc; loc = loc->next) {
2401
+ orp = obj_name(orp, loc->name);
2402
+ orp = obj_word(orp, loc->type);
2403
+ orp = obj_index(orp, seg->grp ? seg->grp->obj_index : 0);
2404
+ orp = obj_index(orp, seg->obj_index);
2405
+ orp = obj_x(orp, loc->offset);
2406
+ obj_commit(orp);
2407
+ }
2408
+ }
2409
+ if (orp->used)
2410
+ obj_emit(orp);
2411
+
2412
+ /*
2413
+ * Write the LEDATA/FIXUPP pairs.
2414
+ */
2415
+ for (seg = seghead; seg; seg = seg->next) {
2416
+ obj_emit(seg->orp);
2417
+ nasm_free(seg->orp);
2418
+ }
2419
+
2420
+ /*
2421
+ * Write the MODEND module end marker.
2422
+ */
2423
+ orp->type = obj_use32 ? MODE32 : MODEND;
2424
+ orp->ori = ori_null;
2425
+ if (entry_seg_ptr) {
2426
+ orp->type = entry_seg_ptr->use32 ? MODE32 : MODEND;
2427
+ obj_byte(orp, 0xC1);
2428
+ seg = entry_seg_ptr;
2429
+ if (seg->grp) {
2430
+ obj_byte(orp, 0x10);
2431
+ obj_index(orp, seg->grp->obj_index);
2432
+ } else {
2433
+ /*
2434
+ * the below changed to prevent TLINK crashing.
2435
+ * Previous more efficient version read:
2436
+ *
2437
+ * obj_byte (orp, 0x50);
2438
+ */
2439
+ obj_byte(orp, 0x00);
2440
+ obj_index(orp, seg->obj_index);
2441
+ }
2442
+ obj_index(orp, seg->obj_index);
2443
+ obj_x(orp, obj_entry_ofs);
2444
+ } else
2445
+ obj_byte(orp, 0);
2446
+ obj_emit2(orp);
2447
+ nasm_free(orp);
2448
+ }
2449
+
2450
+ static void obj_fwrite(ObjRecord * orp)
2451
+ {
2452
+ unsigned int cksum, len;
2453
+ uint8_t *ptr;
2454
+
2455
+ cksum = orp->type;
2456
+ if (orp->x_size == 32)
2457
+ cksum |= 1;
2458
+ fputc(cksum, ofile);
2459
+ len = orp->committed + 1;
2460
+ cksum += (len & 0xFF) + ((len >> 8) & 0xFF);
2461
+ fwriteint16_t(len, ofile);
2462
+ nasm_write(orp->buf, len-1, ofile);
2463
+ for (ptr = orp->buf; --len; ptr++)
2464
+ cksum += *ptr;
2465
+ fputc((-cksum) & 0xFF, ofile);
2466
+ }
2467
+
2468
+ static enum directive_result
2469
+ obj_pragma(const struct pragma *pragma)
2470
+ {
2471
+ switch (pragma->opcode) {
2472
+ case D_NODEPEND:
2473
+ obj_nodepend = true;
2474
+ break;
2475
+
2476
+ default:
2477
+ break;
2478
+ }
2479
+
2480
+ return DIRR_OK;
2481
+ }
2482
+
2483
+ extern macros_t obj_stdmac[];
2484
+
2485
+ static void dbgbi_init(void)
2486
+ {
2487
+ fnhead = NULL;
2488
+ fntail = &fnhead;
2489
+ arrindex = ARRAYBOT;
2490
+ arrhead = NULL;
2491
+ arrtail = &arrhead;
2492
+ }
2493
+ static void dbgbi_cleanup(void)
2494
+ {
2495
+ struct Segment *segtmp;
2496
+ while (fnhead) {
2497
+ struct FileName *fntemp = fnhead;
2498
+ while (fnhead->lnhead) {
2499
+ struct LineNumber *lntemp = fnhead->lnhead;
2500
+ fnhead->lnhead = lntemp->next;
2501
+ nasm_free(lntemp);
2502
+ }
2503
+ fnhead = fnhead->next;
2504
+ nasm_free(fntemp->name);
2505
+ nasm_free(fntemp);
2506
+ }
2507
+ for (segtmp = seghead; segtmp; segtmp = segtmp->next) {
2508
+ while (segtmp->lochead) {
2509
+ struct Public *loctmp = segtmp->lochead;
2510
+ segtmp->lochead = loctmp->next;
2511
+ nasm_free(loctmp->name);
2512
+ nasm_free(loctmp);
2513
+ }
2514
+ }
2515
+ while (arrhead) {
2516
+ struct Array *arrtmp = arrhead;
2517
+ arrhead = arrhead->next;
2518
+ nasm_free(arrtmp);
2519
+ }
2520
+ }
2521
+
2522
+ static void dbgbi_linnum(const char *lnfname, int32_t lineno, int32_t segto)
2523
+ {
2524
+ struct FileName *fn;
2525
+ struct LineNumber *ln;
2526
+ struct Segment *seg;
2527
+
2528
+ if (segto == NO_SEG)
2529
+ return;
2530
+
2531
+ /*
2532
+ * If `any_segs' is still false, we must define a default
2533
+ * segment.
2534
+ */
2535
+ if (!any_segs) {
2536
+ int tempint; /* ignored */
2537
+ if (segto != obj_segment("__NASMDEFSEG", 2, &tempint))
2538
+ nasm_panic(0, "strange segment conditions in OBJ driver");
2539
+ }
2540
+
2541
+ /*
2542
+ * Find the segment we are targetting.
2543
+ */
2544
+ for (seg = seghead; seg; seg = seg->next)
2545
+ if (seg->index == segto)
2546
+ break;
2547
+ if (!seg)
2548
+ nasm_panic(0, "lineno directed to nonexistent segment?");
2549
+
2550
+ /* for (fn = fnhead; fn; fn = fnhead->next) */
2551
+ for (fn = fnhead; fn; fn = fn->next) /* fbk - Austin Lunnen - John Fine */
2552
+ if (!nasm_stricmp(lnfname, fn->name))
2553
+ break;
2554
+ if (!fn) {
2555
+ fn = nasm_malloc(sizeof(*fn));
2556
+ fn->name = nasm_malloc(strlen(lnfname) + 1);
2557
+ strcpy(fn->name, lnfname);
2558
+ fn->lnhead = NULL;
2559
+ fn->lntail = &fn->lnhead;
2560
+ fn->next = NULL;
2561
+ *fntail = fn;
2562
+ fntail = &fn->next;
2563
+ }
2564
+ ln = nasm_malloc(sizeof(*ln));
2565
+ ln->segment = seg;
2566
+ ln->offset = seg->currentpos;
2567
+ ln->lineno = lineno;
2568
+ ln->next = NULL;
2569
+ *fn->lntail = ln;
2570
+ fn->lntail = &ln->next;
2571
+
2572
+ }
2573
+ static void dbgbi_deflabel(char *name, int32_t segment,
2574
+ int64_t offset, int is_global, char *special)
2575
+ {
2576
+ struct Segment *seg;
2577
+
2578
+ (void)special;
2579
+
2580
+ /*
2581
+ * Note: ..[^@] special symbols are filtered in labels.c
2582
+ */
2583
+
2584
+ /*
2585
+ * If it's a special-retry from pass two, discard it.
2586
+ */
2587
+ if (is_global == 3)
2588
+ return;
2589
+
2590
+ /*
2591
+ * Case (i):
2592
+ */
2593
+ if (obj_seg_needs_update) {
2594
+ return;
2595
+ } else if (obj_grp_needs_update) {
2596
+ return;
2597
+ }
2598
+ if (segment < SEG_ABS && segment != NO_SEG && segment % 2)
2599
+ return;
2600
+
2601
+ if (segment >= SEG_ABS || segment == NO_SEG) {
2602
+ return;
2603
+ }
2604
+
2605
+ /*
2606
+ * If `any_segs' is still false, we might need to define a
2607
+ * default segment, if they're trying to declare a label in
2608
+ * `first_seg'. But the label should exist due to a prior
2609
+ * call to obj_deflabel so we can skip that.
2610
+ */
2611
+
2612
+ for (seg = seghead; seg; seg = seg->next)
2613
+ if (seg->index == segment) {
2614
+ struct Public *loc = nasm_malloc(sizeof(*loc));
2615
+ /*
2616
+ * Case (ii). Maybe MODPUB someday?
2617
+ */
2618
+ last_defined = *seg->loctail = loc;
2619
+ seg->loctail = &loc->next;
2620
+ loc->next = NULL;
2621
+ loc->name = nasm_strdup(name);
2622
+ loc->offset = offset;
2623
+ }
2624
+ }
2625
+ static void dbgbi_typevalue(int32_t type)
2626
+ {
2627
+ int vsize;
2628
+ int elem = TYM_ELEMENTS(type);
2629
+ type = TYM_TYPE(type);
2630
+
2631
+ if (!last_defined)
2632
+ return;
2633
+
2634
+ switch (type) {
2635
+ case TY_BYTE:
2636
+ last_defined->type = 8; /* uint8_t */
2637
+ vsize = 1;
2638
+ break;
2639
+ case TY_WORD:
2640
+ last_defined->type = 10; /* unsigned word */
2641
+ vsize = 2;
2642
+ break;
2643
+ case TY_DWORD:
2644
+ last_defined->type = 12; /* unsigned dword */
2645
+ vsize = 4;
2646
+ break;
2647
+ case TY_FLOAT:
2648
+ last_defined->type = 14; /* float */
2649
+ vsize = 4;
2650
+ break;
2651
+ case TY_QWORD:
2652
+ last_defined->type = 15; /* qword */
2653
+ vsize = 8;
2654
+ break;
2655
+ case TY_TBYTE:
2656
+ last_defined->type = 16; /* TBYTE */
2657
+ vsize = 10;
2658
+ break;
2659
+ default:
2660
+ last_defined->type = 0x19; /* label */
2661
+ vsize = 0;
2662
+ break;
2663
+ }
2664
+
2665
+ if (elem > 1) {
2666
+ struct Array *arrtmp = nasm_malloc(sizeof(*arrtmp));
2667
+ int vtype = last_defined->type;
2668
+ arrtmp->size = vsize * elem;
2669
+ arrtmp->basetype = vtype;
2670
+ arrtmp->next = NULL;
2671
+ last_defined->type = arrindex++;
2672
+ *arrtail = arrtmp;
2673
+ arrtail = &(arrtmp->next);
2674
+ }
2675
+ last_defined = NULL;
2676
+ }
2677
+ static void dbgbi_output(int output_type, void *param)
2678
+ {
2679
+ (void)output_type;
2680
+ (void)param;
2681
+ }
2682
+ static const struct dfmt borland_debug_form = {
2683
+ "Borland Debug Records",
2684
+ "borland",
2685
+ dbgbi_init,
2686
+ dbgbi_linnum,
2687
+ dbgbi_deflabel,
2688
+ null_debug_directive,
2689
+ dbgbi_typevalue,
2690
+ dbgbi_output,
2691
+ dbgbi_cleanup,
2692
+ NULL /* pragma list */
2693
+ };
2694
+
2695
+ static const struct dfmt * const borland_debug_arr[3] = {
2696
+ &borland_debug_form,
2697
+ &null_debug_form,
2698
+ NULL
2699
+ };
2700
+
2701
+ static const struct pragma_facility obj_pragma_list[] = {
2702
+ { NULL, obj_pragma }
2703
+ };
2704
+
2705
+ const struct ofmt of_obj = {
2706
+ "MS-DOS 16-bit/32-bit OMF object files",
2707
+ "obj",
2708
+ 0,
2709
+ 32,
2710
+ borland_debug_arr,
2711
+ &borland_debug_form,
2712
+ obj_stdmac,
2713
+ obj_init,
2714
+ nasm_do_legacy_output,
2715
+ obj_out,
2716
+ obj_deflabel,
2717
+ obj_segment,
2718
+ obj_sectalign,
2719
+ obj_segbase,
2720
+ obj_directive,
2721
+ obj_filename,
2722
+ obj_cleanup,
2723
+ obj_pragma_list
2724
+ };
2725
+ #endif /* OF_OBJ */