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,3370 @@
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
+ * Common code for outelf32 and outelf64
36
+ */
37
+
38
+ #include "compiler.h"
39
+
40
+ #include <stdio.h>
41
+ #include <stdlib.h>
42
+
43
+ #include "nasm.h"
44
+ #include "nasmlib.h"
45
+ #include "error.h"
46
+ #include "saa.h"
47
+ #include "raa.h"
48
+ #include "stdscan.h"
49
+ #include "eval.h"
50
+ #include "outform.h"
51
+ #include "outlib.h"
52
+ #include "rbtree.h"
53
+ #include "ver.h"
54
+
55
+ #include "dwarf.h"
56
+ #include "stabs.h"
57
+ #include "outelf.h"
58
+ #include "elf.h"
59
+
60
+ #if defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32)
61
+
62
+ #define SECT_DELTA 32
63
+ static struct elf_section **sects;
64
+ static int nsects, sectlen;
65
+
66
+ #define SHSTR_DELTA 256
67
+ static char *shstrtab;
68
+ static int shstrtablen, shstrtabsize;
69
+
70
+ static struct SAA *syms;
71
+ static uint32_t nlocals, nglobs, ndebugs; /* Symbol counts */
72
+
73
+ static int32_t def_seg;
74
+
75
+ static struct RAA *bsym;
76
+
77
+ static struct SAA *strs;
78
+ static uint32_t strslen;
79
+
80
+ static struct elf_symbol *fwds;
81
+
82
+ static char elf_module[FILENAME_MAX];
83
+
84
+ extern const struct ofmt of_elf32;
85
+ extern const struct ofmt of_elf64;
86
+ extern const struct ofmt of_elfx32;
87
+
88
+ static struct ELF_SECTDATA {
89
+ void *data;
90
+ int64_t len;
91
+ bool is_saa;
92
+ } *elf_sects;
93
+
94
+ static int elf_nsect, nsections;
95
+ static int64_t elf_foffs;
96
+
97
+ static void elf_write(void);
98
+ static void elf_sect_write(struct elf_section *, const void *, size_t);
99
+ static void elf_sect_writeaddr(struct elf_section *, int64_t, size_t);
100
+ static void elf_section_header(int, int, uint64_t, void *, bool, uint64_t, int, int,
101
+ int, int);
102
+ static void elf_write_sections(void);
103
+ static struct SAA *elf_build_symtab(int32_t *, int32_t *);
104
+ static struct SAA *elf_build_reltab(uint64_t *, struct elf_reloc *);
105
+ static void add_sectname(const char *, const char *);
106
+
107
+ struct erel {
108
+ int offset;
109
+ int info;
110
+ };
111
+
112
+ struct symlininfo {
113
+ int offset;
114
+ int section; /* index into sects[] */
115
+ int segto; /* internal section number */
116
+ char *name; /* shallow-copied pointer of section name */
117
+ };
118
+
119
+ struct linelist {
120
+ struct linelist *next;
121
+ struct linelist *last;
122
+ struct symlininfo info;
123
+ char *filename;
124
+ int line;
125
+ };
126
+
127
+ struct sectlist {
128
+ struct SAA *psaa;
129
+ int section;
130
+ int line;
131
+ int offset;
132
+ int file;
133
+ struct sectlist *next;
134
+ struct sectlist *last;
135
+ };
136
+
137
+ /* common debug variables */
138
+ static int currentline = 1;
139
+ static int debug_immcall = 0;
140
+
141
+ /* stabs debug variables */
142
+ static struct linelist *stabslines = 0;
143
+ static int numlinestabs = 0;
144
+ static char *stabs_filename = 0;
145
+ static uint8_t *stabbuf = 0, *stabstrbuf = 0, *stabrelbuf = 0;
146
+ static int stablen, stabstrlen, stabrellen;
147
+
148
+ /* dwarf debug variables */
149
+ static struct linelist *dwarf_flist = 0, *dwarf_clist = 0, *dwarf_elist = 0;
150
+ static struct sectlist *dwarf_fsect = 0, *dwarf_csect = 0, *dwarf_esect = 0;
151
+ static int dwarf_numfiles = 0, dwarf_nsections;
152
+ static uint8_t *arangesbuf = 0, *arangesrelbuf = 0, *pubnamesbuf = 0, *infobuf = 0, *inforelbuf = 0,
153
+ *abbrevbuf = 0, *linebuf = 0, *linerelbuf = 0, *framebuf = 0, *locbuf = 0;
154
+ static int8_t line_base = -5, line_range = 14, opcode_base = 13;
155
+ static int arangeslen, arangesrellen, pubnameslen, infolen, inforellen,
156
+ abbrevlen, linelen, linerellen, framelen, loclen;
157
+ static int64_t dwarf_infosym, dwarf_abbrevsym, dwarf_linesym;
158
+
159
+ static struct elf_symbol *lastsym;
160
+
161
+ /* common debugging routines */
162
+ static void debug_typevalue(int32_t);
163
+
164
+ /* stabs debugging routines */
165
+ static void stabs_linenum(const char *filename, int32_t linenumber, int32_t);
166
+ static void stabs_output(int, void *);
167
+ static void stabs_generate(void);
168
+ static void stabs_cleanup(void);
169
+
170
+ /* dwarf debugging routines */
171
+ static void dwarf_init(void);
172
+ static void dwarf_linenum(const char *filename, int32_t linenumber, int32_t);
173
+ static void dwarf_output(int, void *);
174
+ static void dwarf_generate(void);
175
+ static void dwarf_cleanup(void);
176
+ static void dwarf_findfile(const char *);
177
+ static void dwarf_findsect(const int);
178
+
179
+ static bool is_elf64(void);
180
+ static bool is_elf32(void);
181
+ static bool is_elfx32(void);
182
+
183
+ static bool dfmt_is_stabs(void);
184
+ static bool dfmt_is_dwarf(void);
185
+
186
+ /*
187
+ * Special NASM section numbers which are used to define ELF special
188
+ * symbols.
189
+ */
190
+ static int32_t elf_gotpc_sect, elf_gotoff_sect;
191
+ static int32_t elf_got_sect, elf_plt_sect;
192
+ static int32_t elf_sym_sect, elf_gottpoff_sect, elf_tlsie_sect;
193
+
194
+ uint8_t elf_osabi = 0; /* Default OSABI = 0 (System V or Linux) */
195
+ uint8_t elf_abiver = 0; /* Current ABI version */
196
+
197
+ const struct elf_known_section elf_known_sections[] = {
198
+ { ".text", SHT_PROGBITS, SHF_ALLOC|SHF_EXECINSTR, 16 },
199
+ { ".rodata", SHT_PROGBITS, SHF_ALLOC, 4 },
200
+ { ".lrodata", SHT_PROGBITS, SHF_ALLOC, 4 },
201
+ { ".data", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4 },
202
+ { ".ldata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE, 4 },
203
+ { ".bss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4 },
204
+ { ".lbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE, 4 },
205
+ { ".tdata", SHT_PROGBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4 },
206
+ { ".tbss", SHT_NOBITS, SHF_ALLOC|SHF_WRITE|SHF_TLS, 4 },
207
+ { ".comment", SHT_PROGBITS, 0, 1 },
208
+ { NULL, SHT_PROGBITS, SHF_ALLOC, 1 } /* default */
209
+ };
210
+
211
+ /* parse section attributes */
212
+ void elf_section_attrib(char *name, char *attr, int pass,
213
+ uint32_t *flags_and, uint32_t *flags_or,
214
+ uint64_t *align, int *type)
215
+ {
216
+ char *opt, *val, *next;
217
+
218
+ opt = nasm_skip_spaces(attr);
219
+ if (!opt || !*opt)
220
+ return;
221
+
222
+ while ((opt = nasm_opt_val(opt, &val, &next))) {
223
+ if (!nasm_stricmp(opt, "align")) {
224
+ if (!val) {
225
+ nasm_error(ERR_NONFATAL,
226
+ "section align without value specified");
227
+ } else {
228
+ *align = atoi(val);
229
+ if (*align == 0) {
230
+ *align = SHA_ANY;
231
+ } else if (!is_power2(*align)) {
232
+ nasm_error(ERR_NONFATAL,
233
+ "section alignment %"PRId64" is not a power of two",
234
+ *align);
235
+ *align = SHA_ANY;
236
+ }
237
+ }
238
+ } else if (!nasm_stricmp(opt, "alloc")) {
239
+ *flags_and |= SHF_ALLOC;
240
+ *flags_or |= SHF_ALLOC;
241
+ } else if (!nasm_stricmp(opt, "noalloc")) {
242
+ *flags_and |= SHF_ALLOC;
243
+ *flags_or &= ~SHF_ALLOC;
244
+ } else if (!nasm_stricmp(opt, "exec")) {
245
+ *flags_and |= SHF_EXECINSTR;
246
+ *flags_or |= SHF_EXECINSTR;
247
+ } else if (!nasm_stricmp(opt, "noexec")) {
248
+ *flags_and |= SHF_EXECINSTR;
249
+ *flags_or &= ~SHF_EXECINSTR;
250
+ } else if (!nasm_stricmp(opt, "write")) {
251
+ *flags_and |= SHF_WRITE;
252
+ *flags_or |= SHF_WRITE;
253
+ } else if (!nasm_stricmp(opt, "tls")) {
254
+ *flags_and |= SHF_TLS;
255
+ *flags_or |= SHF_TLS;
256
+ } else if (!nasm_stricmp(opt, "nowrite")) {
257
+ *flags_and |= SHF_WRITE;
258
+ *flags_or &= ~SHF_WRITE;
259
+ } else if (!nasm_stricmp(opt, "progbits")) {
260
+ *type = SHT_PROGBITS;
261
+ } else if (!nasm_stricmp(opt, "nobits")) {
262
+ *type = SHT_NOBITS;
263
+ } else if (pass == 1) {
264
+ nasm_error(ERR_WARNING,
265
+ "Unknown section attribute '%s' ignored on"
266
+ " declaration of section `%s'", opt, name);
267
+ }
268
+ opt = next;
269
+ }
270
+ }
271
+
272
+ static enum directive_result
273
+ elf_directive(enum directive directive, char *value, int pass)
274
+ {
275
+ int64_t n;
276
+ bool err;
277
+ char *p;
278
+
279
+ switch (directive) {
280
+ case D_OSABI:
281
+ if (pass == 2)
282
+ return DIRR_OK; /* ignore in pass 2 */
283
+
284
+ n = readnum(value, &err);
285
+ if (err) {
286
+ nasm_error(ERR_NONFATAL, "`osabi' directive requires a parameter");
287
+ return DIRR_ERROR;
288
+ }
289
+
290
+ if (n < 0 || n > 255) {
291
+ nasm_error(ERR_NONFATAL, "valid osabi numbers are 0 to 255");
292
+ return DIRR_ERROR;
293
+ }
294
+
295
+ elf_osabi = n;
296
+ elf_abiver = 0;
297
+
298
+ p = strchr(value,',');
299
+ if (!p)
300
+ return DIRR_OK;
301
+
302
+ n = readnum(p + 1, &err);
303
+ if (err || n < 0 || n > 255) {
304
+ nasm_error(ERR_NONFATAL, "invalid ABI version number (valid: 0 to 255)");
305
+ return DIRR_ERROR;
306
+ }
307
+
308
+ elf_abiver = n;
309
+ return DIRR_OK;
310
+
311
+ default:
312
+ return DIRR_UNKNOWN;
313
+ }
314
+ }
315
+
316
+ static void elf_init(void)
317
+ {
318
+ sects = NULL;
319
+ nsects = sectlen = 0;
320
+ syms = saa_init((int32_t)sizeof(struct elf_symbol));
321
+ nlocals = nglobs = ndebugs = 0;
322
+ bsym = raa_init();
323
+ strs = saa_init(1L);
324
+ saa_wbytes(strs, "\0", 1L);
325
+ saa_wbytes(strs, elf_module, strlen(elf_module)+1);
326
+ strslen = 2 + strlen(elf_module);
327
+ shstrtab = NULL;
328
+ shstrtablen = shstrtabsize = 0;;
329
+ add_sectname("", "");
330
+
331
+ fwds = NULL;
332
+
333
+ /*
334
+ * FIXME: tlsie is Elf32 only and
335
+ * gottpoff is Elfx32|64 only.
336
+ */
337
+
338
+ elf_gotpc_sect = seg_alloc();
339
+ define_label("..gotpc", elf_gotpc_sect + 1, 0L, NULL, false, false);
340
+ elf_gotoff_sect = seg_alloc();
341
+ define_label("..gotoff", elf_gotoff_sect + 1, 0L, NULL, false, false);
342
+ elf_got_sect = seg_alloc();
343
+ define_label("..got", elf_got_sect + 1, 0L, NULL, false, false);
344
+ elf_plt_sect = seg_alloc();
345
+ define_label("..plt", elf_plt_sect + 1, 0L, NULL, false, false);
346
+ elf_sym_sect = seg_alloc();
347
+ define_label("..sym", elf_sym_sect + 1, 0L, NULL, false, false);
348
+ elf_gottpoff_sect = seg_alloc();
349
+ define_label("..gottpoff", elf_gottpoff_sect + 1, 0L, NULL, false, false);
350
+ elf_tlsie_sect = seg_alloc();
351
+ define_label("..tlsie", elf_tlsie_sect + 1, 0L, NULL, false, false);
352
+
353
+ def_seg = seg_alloc();
354
+ }
355
+
356
+ static void elf_cleanup(void)
357
+ {
358
+ struct elf_reloc *r;
359
+ int i;
360
+
361
+ elf_write();
362
+ for (i = 0; i < nsects; i++) {
363
+ if (sects[i]->type != SHT_NOBITS)
364
+ saa_free(sects[i]->data);
365
+ if (sects[i]->head)
366
+ saa_free(sects[i]->rel);
367
+ while (sects[i]->head) {
368
+ r = sects[i]->head;
369
+ sects[i]->head = sects[i]->head->next;
370
+ nasm_free(r);
371
+ }
372
+ }
373
+ nasm_free(sects);
374
+ saa_free(syms);
375
+ raa_free(bsym);
376
+ saa_free(strs);
377
+ dfmt->cleanup();
378
+ }
379
+
380
+ /* add entry to the elf .shstrtab section */
381
+ static void add_sectname(const char *firsthalf, const char *secondhalf)
382
+ {
383
+ int len = strlen(firsthalf) + strlen(secondhalf);
384
+ while (shstrtablen + len + 1 > shstrtabsize)
385
+ shstrtab = nasm_realloc(shstrtab, (shstrtabsize += SHSTR_DELTA));
386
+ strcpy(shstrtab + shstrtablen, firsthalf);
387
+ strcat(shstrtab + shstrtablen, secondhalf);
388
+ shstrtablen += len + 1;
389
+ }
390
+
391
+ static int elf_make_section(char *name, int type, int flags, int align)
392
+ {
393
+ struct elf_section *s;
394
+
395
+ s = nasm_zalloc(sizeof(*s));
396
+
397
+ if (type != SHT_NOBITS)
398
+ s->data = saa_init(1L);
399
+ s->tail = &s->head;
400
+ if (!strcmp(name, ".text"))
401
+ s->index = def_seg;
402
+ else
403
+ s->index = seg_alloc();
404
+ add_sectname("", name);
405
+
406
+ s->name = nasm_strdup(name);
407
+ s->type = type;
408
+ s->flags = flags;
409
+ s->align = align;
410
+
411
+ if (nsects >= sectlen)
412
+ sects = nasm_realloc(sects, (sectlen += SECT_DELTA) * sizeof(*sects));
413
+ sects[nsects++] = s;
414
+
415
+ return nsects - 1;
416
+ }
417
+
418
+ static int32_t elf_section_names(char *name, int pass, int *bits)
419
+ {
420
+ char *p;
421
+ uint32_t flags, flags_and, flags_or;
422
+ uint64_t align;
423
+ int type, i;
424
+
425
+ if (!name) {
426
+ *bits = ofmt->maxbits;
427
+ return def_seg;
428
+ }
429
+
430
+ p = nasm_skip_word(name);
431
+ if (*p)
432
+ *p++ = '\0';
433
+ flags_and = flags_or = type = align = 0;
434
+
435
+ elf_section_attrib(name, p, pass, &flags_and,
436
+ &flags_or, &align, &type);
437
+
438
+ if (!strcmp(name, ".shstrtab") ||
439
+ !strcmp(name, ".symtab") ||
440
+ !strcmp(name, ".strtab")) {
441
+ nasm_error(ERR_NONFATAL, "attempt to redefine reserved section"
442
+ "name `%s'", name);
443
+ return NO_SEG;
444
+ }
445
+
446
+ for (i = 0; i < nsects; i++)
447
+ if (!strcmp(name, sects[i]->name))
448
+ break;
449
+ if (i == nsects) {
450
+ const struct elf_known_section *ks = elf_known_sections;
451
+
452
+ while (ks->name) {
453
+ if (!strcmp(name, ks->name))
454
+ break;
455
+ ks++;
456
+ }
457
+
458
+ type = type ? type : ks->type;
459
+ align = align ? align : ks->align;
460
+ flags = (ks->flags & ~flags_and) | flags_or;
461
+
462
+ i = elf_make_section(name, type, flags, align);
463
+ } else if (pass == 1) {
464
+ if ((type && sects[i]->type != type)
465
+ || (align && sects[i]->align != align)
466
+ || (flags_and && ((sects[i]->flags & flags_and) != flags_or)))
467
+ nasm_error(ERR_WARNING, "incompatible section attributes ignored on"
468
+ " redeclaration of section `%s'", name);
469
+ }
470
+
471
+ return sects[i]->index;
472
+ }
473
+
474
+ static void elf_deflabel(char *name, int32_t segment, int64_t offset,
475
+ int is_global, char *special)
476
+ {
477
+ int pos = strslen;
478
+ struct elf_symbol *sym;
479
+ bool special_used = false;
480
+
481
+ #if defined(DEBUG) && DEBUG>2
482
+ nasm_error(ERR_DEBUG,
483
+ " elf_deflabel: %s, seg=%"PRIx32", off=%"PRIx64", is_global=%d, %s\n",
484
+ name, segment, offset, is_global, special);
485
+ #endif
486
+ if (name[0] == '.' && name[1] == '.' && name[2] != '@') {
487
+ /*
488
+ * This is a NASM special symbol. We never allow it into
489
+ * the ELF symbol table, even if it's a valid one. If it
490
+ * _isn't_ a valid one, we should barf immediately.
491
+ *
492
+ * FIXME: tlsie is Elf32 only, and gottpoff is Elfx32|64 only.
493
+ */
494
+ if (strcmp(name, "..gotpc") && strcmp(name, "..gotoff") &&
495
+ strcmp(name, "..got") && strcmp(name, "..plt") &&
496
+ strcmp(name, "..sym") && strcmp(name, "..gottpoff") &&
497
+ strcmp(name, "..tlsie"))
498
+ nasm_error(ERR_NONFATAL, "unrecognised special symbol `%s'", name);
499
+ return;
500
+ }
501
+
502
+ if (is_global == 3) {
503
+ struct elf_symbol **s;
504
+ /*
505
+ * Fix up a forward-reference symbol size from the first
506
+ * pass.
507
+ */
508
+ for (s = &fwds; *s; s = &(*s)->nextfwd)
509
+ if (!strcmp((*s)->name, name)) {
510
+ struct tokenval tokval;
511
+ expr *e;
512
+ char *p = nasm_skip_spaces(nasm_skip_word(special));
513
+
514
+ stdscan_reset();
515
+ stdscan_set(p);
516
+ tokval.t_type = TOKEN_INVALID;
517
+ e = evaluate(stdscan, NULL, &tokval, NULL, 1, NULL);
518
+ if (e) {
519
+ if (!is_simple(e))
520
+ nasm_error(ERR_NONFATAL, "cannot use relocatable"
521
+ " expression as symbol size");
522
+ else
523
+ (*s)->size = reloc_value(e);
524
+ }
525
+
526
+ /*
527
+ * Remove it from the list of unresolved sizes.
528
+ */
529
+ nasm_free((*s)->name);
530
+ *s = (*s)->nextfwd;
531
+ return;
532
+ }
533
+ return; /* it wasn't an important one */
534
+ }
535
+
536
+ saa_wbytes(strs, name, (int32_t)(1 + strlen(name)));
537
+ strslen += 1 + strlen(name);
538
+
539
+ lastsym = sym = saa_wstruct(syms);
540
+
541
+ memset(&sym->symv, 0, sizeof(struct rbtree));
542
+
543
+ sym->strpos = pos;
544
+ sym->type = is_global ? SYM_GLOBAL : SYM_LOCAL;
545
+ sym->other = STV_DEFAULT;
546
+ sym->size = 0;
547
+ if (segment == NO_SEG)
548
+ sym->section = SHN_ABS;
549
+ else {
550
+ int i;
551
+ sym->section = SHN_UNDEF;
552
+ if (segment == def_seg) {
553
+ /* we have to be sure at least text section is there */
554
+ int tempint;
555
+ if (segment != elf_section_names(".text", 2, &tempint))
556
+ nasm_panic(0, "strange segment conditions in ELF driver");
557
+ }
558
+ for (i = 0; i < nsects; i++) {
559
+ if (segment == sects[i]->index) {
560
+ sym->section = i + 1;
561
+ break;
562
+ }
563
+ }
564
+ }
565
+
566
+ if (is_global == 2) {
567
+ sym->size = offset;
568
+ sym->symv.key = 0;
569
+ sym->section = SHN_COMMON;
570
+ /*
571
+ * We have a common variable. Check the special text to see
572
+ * if it's a valid number and power of two; if so, store it
573
+ * as the alignment for the common variable.
574
+ */
575
+ if (special) {
576
+ bool err;
577
+ sym->symv.key = readnum(special, &err);
578
+ if (err)
579
+ nasm_error(ERR_NONFATAL, "alignment constraint `%s' is not a"
580
+ " valid number", special);
581
+ else if ((sym->symv.key | (sym->symv.key - 1)) != 2 * sym->symv.key - 1)
582
+ nasm_error(ERR_NONFATAL, "alignment constraint `%s' is not a"
583
+ " power of two", special);
584
+ }
585
+ special_used = true;
586
+ } else
587
+ sym->symv.key = (sym->section == SHN_UNDEF ? 0 : offset);
588
+
589
+ if (sym->type == SYM_GLOBAL) {
590
+ /*
591
+ * If sym->section == SHN_ABS, then the first line of the
592
+ * else section would cause a core dump, because its a reference
593
+ * beyond the end of the section array.
594
+ * This behaviour is exhibited by this code:
595
+ * GLOBAL crash_nasm
596
+ * crash_nasm equ 0
597
+ * To avoid such a crash, such requests are silently discarded.
598
+ * This may not be the best solution.
599
+ */
600
+ if (sym->section == SHN_UNDEF || sym->section == SHN_COMMON) {
601
+ bsym = raa_write(bsym, segment, nglobs);
602
+ } else if (sym->section != SHN_ABS) {
603
+ /*
604
+ * This is a global symbol; so we must add it to the rbtree
605
+ * of global symbols in its section.
606
+ *
607
+ * In addition, we check the special text for symbol
608
+ * type and size information.
609
+ */
610
+ sects[sym->section-1]->gsyms =
611
+ rb_insert(sects[sym->section-1]->gsyms, &sym->symv);
612
+
613
+ if (special) {
614
+ int n = strcspn(special, " \t");
615
+
616
+ if (!nasm_strnicmp(special, "function", n))
617
+ sym->type |= STT_FUNC;
618
+ else if (!nasm_strnicmp(special, "data", n) ||
619
+ !nasm_strnicmp(special, "object", n))
620
+ sym->type |= STT_OBJECT;
621
+ else if (!nasm_strnicmp(special, "notype", n))
622
+ sym->type |= STT_NOTYPE;
623
+ else
624
+ nasm_error(ERR_NONFATAL, "unrecognised symbol type `%.*s'",
625
+ n, special);
626
+ special += n;
627
+
628
+ special = nasm_skip_spaces(special);
629
+ if (*special) {
630
+ n = strcspn(special, " \t");
631
+ if (!nasm_strnicmp(special, "default", n))
632
+ sym->other = STV_DEFAULT;
633
+ else if (!nasm_strnicmp(special, "internal", n))
634
+ sym->other = STV_INTERNAL;
635
+ else if (!nasm_strnicmp(special, "hidden", n))
636
+ sym->other = STV_HIDDEN;
637
+ else if (!nasm_strnicmp(special, "protected", n))
638
+ sym->other = STV_PROTECTED;
639
+ else
640
+ n = 0;
641
+ special += n;
642
+ }
643
+
644
+ if (*special) {
645
+ struct tokenval tokval;
646
+ expr *e;
647
+ int fwd = 0;
648
+ char *saveme = stdscan_get();
649
+
650
+ while (special[n] && nasm_isspace(special[n]))
651
+ n++;
652
+ /*
653
+ * We have a size expression; attempt to
654
+ * evaluate it.
655
+ */
656
+ stdscan_reset();
657
+ stdscan_set(special + n);
658
+ tokval.t_type = TOKEN_INVALID;
659
+ e = evaluate(stdscan, NULL, &tokval, &fwd, 0, NULL);
660
+ if (fwd) {
661
+ sym->nextfwd = fwds;
662
+ fwds = sym;
663
+ sym->name = nasm_strdup(name);
664
+ } else if (e) {
665
+ if (!is_simple(e))
666
+ nasm_error(ERR_NONFATAL, "cannot use relocatable"
667
+ " expression as symbol size");
668
+ else
669
+ sym->size = reloc_value(e);
670
+ }
671
+ stdscan_set(saveme);
672
+ }
673
+ special_used = true;
674
+ }
675
+ /*
676
+ * If TLS segment, mark symbol accordingly.
677
+ */
678
+ if (sects[sym->section - 1]->flags & SHF_TLS) {
679
+ sym->type &= 0xf0;
680
+ sym->type |= STT_TLS;
681
+ }
682
+ }
683
+ sym->globnum = nglobs;
684
+ nglobs++;
685
+ } else
686
+ nlocals++;
687
+
688
+ if (special && !special_used)
689
+ nasm_error(ERR_NONFATAL, "no special symbol features supported here");
690
+ }
691
+
692
+ static void elf_add_reloc(struct elf_section *sect, int32_t segment,
693
+ int64_t offset, int type)
694
+ {
695
+ struct elf_reloc *r;
696
+
697
+ r = *sect->tail = nasm_zalloc(sizeof(struct elf_reloc));
698
+ sect->tail = &r->next;
699
+
700
+ r->address = sect->len;
701
+ r->offset = offset;
702
+
703
+ if (segment != NO_SEG) {
704
+ int i;
705
+ for (i = 0; i < nsects; i++)
706
+ if (segment == sects[i]->index)
707
+ r->symbol = i + 2;
708
+ if (!r->symbol)
709
+ r->symbol = GLOBAL_TEMP_BASE + raa_read(bsym, segment);
710
+ }
711
+ r->type = type;
712
+
713
+ sect->nrelocs++;
714
+ }
715
+
716
+ /*
717
+ * This routine deals with ..got and ..sym relocations: the more
718
+ * complicated kinds. In shared-library writing, some relocations
719
+ * with respect to global symbols must refer to the precise symbol
720
+ * rather than referring to an offset from the base of the section
721
+ * _containing_ the symbol. Such relocations call to this routine,
722
+ * which searches the symbol list for the symbol in question.
723
+ *
724
+ * R_386_GOT32 | R_X86_64_GOT32 references require the _exact_ symbol address to be
725
+ * used; R_386_32 | R_X86_64_32 references can be at an offset from the symbol.
726
+ * The boolean argument `exact' tells us this.
727
+ *
728
+ * Return value is the adjusted value of `addr', having become an
729
+ * offset from the symbol rather than the section. Should always be
730
+ * zero when returning from an exact call.
731
+ *
732
+ * Limitation: if you define two symbols at the same place,
733
+ * confusion will occur.
734
+ *
735
+ * Inefficiency: we search, currently, using a linked list which
736
+ * isn't even necessarily sorted.
737
+ */
738
+ static int64_t elf_add_gsym_reloc(struct elf_section *sect,
739
+ int32_t segment, uint64_t offset,
740
+ int64_t pcrel, int type, bool exact)
741
+ {
742
+ struct elf_reloc *r;
743
+ struct elf_section *s;
744
+ struct elf_symbol *sym;
745
+ struct rbtree *srb;
746
+ int i;
747
+
748
+ /*
749
+ * First look up the segment/offset pair and find a global
750
+ * symbol corresponding to it. If it's not one of our segments,
751
+ * then it must be an external symbol, in which case we're fine
752
+ * doing a normal elf_add_reloc after first sanity-checking
753
+ * that the offset from the symbol is zero.
754
+ */
755
+ s = NULL;
756
+ for (i = 0; i < nsects; i++)
757
+ if (segment == sects[i]->index) {
758
+ s = sects[i];
759
+ break;
760
+ }
761
+
762
+ if (!s) {
763
+ if (exact && offset)
764
+ nasm_error(ERR_NONFATAL, "invalid access to an external symbol");
765
+ else
766
+ elf_add_reloc(sect, segment, offset - pcrel, type);
767
+ return 0;
768
+ }
769
+
770
+ srb = rb_search(s->gsyms, offset);
771
+ if (!srb || (exact && srb->key != offset)) {
772
+ nasm_error(ERR_NONFATAL, "unable to find a suitable global symbol"
773
+ " for this reference");
774
+ return 0;
775
+ }
776
+ sym = container_of(srb, struct elf_symbol, symv);
777
+
778
+ r = *sect->tail = nasm_malloc(sizeof(struct elf_reloc));
779
+ sect->tail = &r->next;
780
+
781
+ r->next = NULL;
782
+ r->address = sect->len;
783
+ r->offset = offset - pcrel - sym->symv.key;
784
+ r->symbol = GLOBAL_TEMP_BASE + sym->globnum;
785
+ r->type = type;
786
+
787
+ sect->nrelocs++;
788
+ return r->offset;
789
+ }
790
+
791
+ static void elf32_out(int32_t segto, const void *data,
792
+ enum out_type type, uint64_t size,
793
+ int32_t segment, int32_t wrt)
794
+ {
795
+ struct elf_section *s;
796
+ int64_t addr;
797
+ int reltype, bytes;
798
+ int i;
799
+ static struct symlininfo sinfo;
800
+
801
+ /*
802
+ * handle absolute-assembly (structure definitions)
803
+ */
804
+ if (segto == NO_SEG) {
805
+ if (type != OUT_RESERVE)
806
+ nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
807
+ " space");
808
+ return;
809
+ }
810
+
811
+ s = NULL;
812
+ for (i = 0; i < nsects; i++)
813
+ if (segto == sects[i]->index) {
814
+ s = sects[i];
815
+ break;
816
+ }
817
+ if (!s) {
818
+ int tempint; /* ignored */
819
+ if (segto != elf_section_names(".text", 2, &tempint))
820
+ nasm_panic(0, "strange segment conditions in ELF driver");
821
+ else {
822
+ s = sects[nsects - 1];
823
+ i = nsects - 1;
824
+ }
825
+ }
826
+
827
+ /* again some stabs debugging stuff */
828
+ sinfo.offset = s->len;
829
+ sinfo.section = i;
830
+ sinfo.segto = segto;
831
+ sinfo.name = s->name;
832
+ dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
833
+ /* end of debugging stuff */
834
+
835
+ if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
836
+ nasm_error(ERR_WARNING, "attempt to initialize memory in"
837
+ " BSS section `%s': ignored", s->name);
838
+ s->len += realsize(type, size);
839
+ return;
840
+ }
841
+
842
+ switch (type) {
843
+ case OUT_RESERVE:
844
+ if (s->type == SHT_PROGBITS) {
845
+ nasm_error(ERR_WARNING, "uninitialized space declared in"
846
+ " non-BSS section `%s': zeroing", s->name);
847
+ elf_sect_write(s, NULL, size);
848
+ } else
849
+ s->len += size;
850
+ break;
851
+
852
+ case OUT_RAWDATA:
853
+ if (segment != NO_SEG)
854
+ nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
855
+ elf_sect_write(s, data, size);
856
+ break;
857
+
858
+ case OUT_ADDRESS:
859
+ {
860
+ bool gnu16 = false;
861
+ int asize = abs((int)size);
862
+
863
+ addr = *(int64_t *)data;
864
+ if (segment != NO_SEG) {
865
+ if (segment % 2) {
866
+ nasm_error(ERR_NONFATAL, "ELF format does not support"
867
+ " segment base references");
868
+ } else {
869
+ if (wrt == NO_SEG) {
870
+ /*
871
+ * The if() is a hack to deal with compilers which
872
+ * don't handle switch() statements with 64-bit
873
+ * expressions.
874
+ */
875
+ switch (asize) {
876
+ case 1:
877
+ gnu16 = true;
878
+ elf_add_reloc(s, segment, 0, R_386_8);
879
+ break;
880
+ case 2:
881
+ gnu16 = true;
882
+ elf_add_reloc(s, segment, 0, R_386_16);
883
+ break;
884
+ case 4:
885
+ elf_add_reloc(s, segment, 0, R_386_32);
886
+ break;
887
+ default: /* Error issued further down */
888
+ break;
889
+ }
890
+ } else if (wrt == elf_gotpc_sect + 1) {
891
+ /*
892
+ * The user will supply GOT relative to $$. ELF
893
+ * will let us have GOT relative to $. So we
894
+ * need to fix up the data item by $-$$.
895
+ */
896
+ addr += s->len;
897
+ elf_add_reloc(s, segment, 0, R_386_GOTPC);
898
+ } else if (wrt == elf_gotoff_sect + 1) {
899
+ elf_add_reloc(s, segment, 0, R_386_GOTOFF);
900
+ } else if (wrt == elf_tlsie_sect + 1) {
901
+ addr = elf_add_gsym_reloc(s, segment, addr, 0,
902
+ R_386_TLS_IE, true);
903
+ } else if (wrt == elf_got_sect + 1) {
904
+ addr = elf_add_gsym_reloc(s, segment, addr, 0,
905
+ R_386_GOT32, true);
906
+ } else if (wrt == elf_sym_sect + 1) {
907
+ switch (asize) {
908
+ case 1:
909
+ gnu16 = true;
910
+ addr = elf_add_gsym_reloc(s, segment, addr, 0,
911
+ R_386_8, false);
912
+ break;
913
+ case 2:
914
+ gnu16 = true;
915
+ addr = elf_add_gsym_reloc(s, segment, addr, 0,
916
+ R_386_16, false);
917
+ break;
918
+ case 4:
919
+ addr = elf_add_gsym_reloc(s, segment, addr, 0,
920
+ R_386_32, false);
921
+ break;
922
+ default:
923
+ break;
924
+ }
925
+ } else if (wrt == elf_plt_sect + 1) {
926
+ nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
927
+ "relative PLT references");
928
+ } else {
929
+ nasm_error(ERR_NONFATAL, "ELF format does not support this"
930
+ " use of WRT");
931
+ wrt = NO_SEG; /* we can at least _try_ to continue */
932
+ }
933
+ }
934
+ }
935
+
936
+ if (gnu16) {
937
+ nasm_error(ERR_WARNING | ERR_WARN_GNUELF,
938
+ "8- or 16-bit relocations in ELF32 is a GNU extension");
939
+ } else if (asize != 4 && segment != NO_SEG) {
940
+ nasm_error(ERR_NONFATAL, "Unsupported non-32-bit ELF relocation");
941
+ }
942
+ elf_sect_writeaddr(s, addr, asize);
943
+ break;
944
+ }
945
+
946
+ case OUT_REL1ADR:
947
+ reltype = R_386_PC8;
948
+ bytes = 1;
949
+ goto rel12adr;
950
+ case OUT_REL2ADR:
951
+ reltype = R_386_PC16;
952
+ bytes = 2;
953
+ goto rel12adr;
954
+
955
+ rel12adr:
956
+ addr = *(int64_t *)data - size;
957
+ nasm_assert(segment != segto);
958
+ if (segment != NO_SEG && segment % 2) {
959
+ nasm_error(ERR_NONFATAL, "ELF format does not support"
960
+ " segment base references");
961
+ } else {
962
+ if (wrt == NO_SEG) {
963
+ nasm_error(ERR_WARNING | ERR_WARN_GNUELF,
964
+ "8- or 16-bit relocations in ELF is a GNU extension");
965
+ elf_add_reloc(s, segment, 0, reltype);
966
+ } else {
967
+ nasm_error(ERR_NONFATAL,
968
+ "Unsupported non-32-bit ELF relocation");
969
+ }
970
+ }
971
+ elf_sect_writeaddr(s, addr, bytes);
972
+ break;
973
+
974
+ case OUT_REL4ADR:
975
+ addr = *(int64_t *)data - size;
976
+ if (segment == segto)
977
+ nasm_panic(0, "intra-segment OUT_REL4ADR");
978
+ if (segment != NO_SEG && segment % 2) {
979
+ nasm_error(ERR_NONFATAL, "ELF format does not support"
980
+ " segment base references");
981
+ } else {
982
+ if (wrt == NO_SEG) {
983
+ elf_add_reloc(s, segment, 0, R_386_PC32);
984
+ } else if (wrt == elf_plt_sect + 1) {
985
+ elf_add_reloc(s, segment, 0, R_386_PLT32);
986
+ } else if (wrt == elf_gotpc_sect + 1 ||
987
+ wrt == elf_gotoff_sect + 1 ||
988
+ wrt == elf_got_sect + 1) {
989
+ nasm_error(ERR_NONFATAL, "ELF format cannot produce PC-"
990
+ "relative GOT references");
991
+ } else {
992
+ nasm_error(ERR_NONFATAL, "ELF format does not support this"
993
+ " use of WRT");
994
+ wrt = NO_SEG; /* we can at least _try_ to continue */
995
+ }
996
+ }
997
+ elf_sect_writeaddr(s, addr, 4);
998
+ break;
999
+
1000
+ case OUT_REL8ADR:
1001
+ nasm_error(ERR_NONFATAL, "32-bit ELF format does not support 64-bit relocations");
1002
+ addr = 0;
1003
+ elf_sect_writeaddr(s, addr, 8);
1004
+ break;
1005
+
1006
+ default:
1007
+ panic();
1008
+ }
1009
+ }
1010
+ static void elf64_out(int32_t segto, const void *data,
1011
+ enum out_type type, uint64_t size,
1012
+ int32_t segment, int32_t wrt)
1013
+ {
1014
+ struct elf_section *s;
1015
+ int64_t addr;
1016
+ int reltype, bytes;
1017
+ int i;
1018
+ static struct symlininfo sinfo;
1019
+
1020
+ /*
1021
+ * handle absolute-assembly (structure definitions)
1022
+ */
1023
+ if (segto == NO_SEG) {
1024
+ if (type != OUT_RESERVE)
1025
+ nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1026
+ " space");
1027
+ return;
1028
+ }
1029
+
1030
+ s = NULL;
1031
+ for (i = 0; i < nsects; i++)
1032
+ if (segto == sects[i]->index) {
1033
+ s = sects[i];
1034
+ break;
1035
+ }
1036
+ if (!s) {
1037
+ int tempint; /* ignored */
1038
+ if (segto != elf_section_names(".text", 2, &tempint))
1039
+ nasm_panic(0, "strange segment conditions in ELF driver");
1040
+ else {
1041
+ s = sects[nsects - 1];
1042
+ i = nsects - 1;
1043
+ }
1044
+ }
1045
+
1046
+ /* again some stabs debugging stuff */
1047
+ sinfo.offset = s->len;
1048
+ sinfo.section = i;
1049
+ sinfo.segto = segto;
1050
+ sinfo.name = s->name;
1051
+ dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1052
+ /* end of debugging stuff */
1053
+
1054
+ if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1055
+ nasm_error(ERR_WARNING, "attempt to initialize memory in"
1056
+ " BSS section `%s': ignored", s->name);
1057
+ s->len += realsize(type, size);
1058
+ return;
1059
+ }
1060
+
1061
+ switch (type) {
1062
+ case OUT_RESERVE:
1063
+ if (s->type == SHT_PROGBITS) {
1064
+ nasm_error(ERR_WARNING, "uninitialized space declared in"
1065
+ " non-BSS section `%s': zeroing", s->name);
1066
+ elf_sect_write(s, NULL, size);
1067
+ } else
1068
+ s->len += size;
1069
+ break;
1070
+
1071
+ case OUT_RAWDATA:
1072
+ if (segment != NO_SEG)
1073
+ nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
1074
+ elf_sect_write(s, data, size);
1075
+ break;
1076
+
1077
+ case OUT_ADDRESS:
1078
+ {
1079
+ int isize = (int)size;
1080
+ int asize = abs((int)size);
1081
+
1082
+ addr = *(int64_t *)data;
1083
+ if (segment == NO_SEG) {
1084
+ /* Do nothing */
1085
+ } else if (segment % 2) {
1086
+ nasm_error(ERR_NONFATAL, "ELF format does not support"
1087
+ " segment base references");
1088
+ } else {
1089
+ if (wrt == NO_SEG) {
1090
+ switch (isize) {
1091
+ case 1:
1092
+ case -1:
1093
+ elf_add_reloc(s, segment, addr, R_X86_64_8);
1094
+ break;
1095
+ case 2:
1096
+ case -2:
1097
+ elf_add_reloc(s, segment, addr, R_X86_64_16);
1098
+ break;
1099
+ case 4:
1100
+ elf_add_reloc(s, segment, addr, R_X86_64_32);
1101
+ break;
1102
+ case -4:
1103
+ elf_add_reloc(s, segment, addr, R_X86_64_32S);
1104
+ break;
1105
+ case 8:
1106
+ case -8:
1107
+ elf_add_reloc(s, segment, addr, R_X86_64_64);
1108
+ break;
1109
+ default:
1110
+ nasm_panic(0, "internal error elf64-hpa-871");
1111
+ break;
1112
+ }
1113
+ addr = 0;
1114
+ } else if (wrt == elf_gotpc_sect + 1) {
1115
+ /*
1116
+ * The user will supply GOT relative to $$. ELF
1117
+ * will let us have GOT relative to $. So we
1118
+ * need to fix up the data item by $-$$.
1119
+ */
1120
+ addr += s->len;
1121
+ elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
1122
+ addr = 0;
1123
+ } else if (wrt == elf_gotoff_sect + 1) {
1124
+ if (asize != 8) {
1125
+ nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff "
1126
+ "references to be qword");
1127
+ } else {
1128
+ elf_add_reloc(s, segment, addr, R_X86_64_GOTOFF64);
1129
+ addr = 0;
1130
+ }
1131
+ } else if (wrt == elf_got_sect + 1) {
1132
+ switch (asize) {
1133
+ case 4:
1134
+ elf_add_gsym_reloc(s, segment, addr, 0,
1135
+ R_X86_64_GOT32, true);
1136
+ addr = 0;
1137
+ break;
1138
+ case 8:
1139
+ elf_add_gsym_reloc(s, segment, addr, 0,
1140
+ R_X86_64_GOT64, true);
1141
+ addr = 0;
1142
+ break;
1143
+ default:
1144
+ nasm_error(ERR_NONFATAL, "invalid ..got reference");
1145
+ break;
1146
+ }
1147
+ } else if (wrt == elf_sym_sect + 1) {
1148
+ switch (isize) {
1149
+ case 1:
1150
+ case -1:
1151
+ elf_add_gsym_reloc(s, segment, addr, 0,
1152
+ R_X86_64_8, false);
1153
+ addr = 0;
1154
+ break;
1155
+ case 2:
1156
+ case -2:
1157
+ elf_add_gsym_reloc(s, segment, addr, 0,
1158
+ R_X86_64_16, false);
1159
+ addr = 0;
1160
+ break;
1161
+ case 4:
1162
+ elf_add_gsym_reloc(s, segment, addr, 0,
1163
+ R_X86_64_32, false);
1164
+ addr = 0;
1165
+ break;
1166
+ case -4:
1167
+ elf_add_gsym_reloc(s, segment, addr, 0,
1168
+ R_X86_64_32S, false);
1169
+ addr = 0;
1170
+ break;
1171
+ case 8:
1172
+ case -8:
1173
+ elf_add_gsym_reloc(s, segment, addr, 0,
1174
+ R_X86_64_64, false);
1175
+ addr = 0;
1176
+ break;
1177
+ default:
1178
+ nasm_panic(0, "internal error elf64-hpa-903");
1179
+ break;
1180
+ }
1181
+ } else if (wrt == elf_plt_sect + 1) {
1182
+ nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
1183
+ "relative PLT references");
1184
+ } else {
1185
+ nasm_error(ERR_NONFATAL, "ELF format does not support this"
1186
+ " use of WRT");
1187
+ }
1188
+ }
1189
+ elf_sect_writeaddr(s, addr, asize);
1190
+ break;
1191
+ }
1192
+
1193
+ case OUT_REL1ADR:
1194
+ reltype = R_X86_64_PC8;
1195
+ bytes = 1;
1196
+ goto rel12adr;
1197
+
1198
+ case OUT_REL2ADR:
1199
+ reltype = R_X86_64_PC16;
1200
+ bytes = 2;
1201
+ goto rel12adr;
1202
+
1203
+ rel12adr:
1204
+ addr = *(int64_t *)data - size;
1205
+ if (segment == segto)
1206
+ nasm_panic(0, "intra-segment OUT_REL1ADR");
1207
+ if (segment == NO_SEG) {
1208
+ /* Do nothing */
1209
+ } else if (segment % 2) {
1210
+ nasm_error(ERR_NONFATAL, "ELF format does not support"
1211
+ " segment base references");
1212
+ } else {
1213
+ if (wrt == NO_SEG) {
1214
+ elf_add_reloc(s, segment, addr, reltype);
1215
+ addr = 0;
1216
+ } else {
1217
+ nasm_error(ERR_NONFATAL,
1218
+ "Unsupported non-32-bit ELF relocation");
1219
+ }
1220
+ }
1221
+ elf_sect_writeaddr(s, addr, bytes);
1222
+ break;
1223
+
1224
+ case OUT_REL4ADR:
1225
+ addr = *(int64_t *)data - size;
1226
+ if (segment == segto)
1227
+ nasm_panic(0, "intra-segment OUT_REL4ADR");
1228
+ if (segment == NO_SEG) {
1229
+ /* Do nothing */
1230
+ } else if (segment % 2) {
1231
+ nasm_error(ERR_NONFATAL, "ELF64 format does not support"
1232
+ " segment base references");
1233
+ } else {
1234
+ if (wrt == NO_SEG) {
1235
+ elf_add_reloc(s, segment, addr, R_X86_64_PC32);
1236
+ addr = 0;
1237
+ } else if (wrt == elf_plt_sect + 1) {
1238
+ elf_add_gsym_reloc(s, segment, addr+size, size,
1239
+ R_X86_64_PLT32, true);
1240
+ addr = 0;
1241
+ } else if (wrt == elf_gotpc_sect + 1 ||
1242
+ wrt == elf_got_sect + 1) {
1243
+ elf_add_gsym_reloc(s, segment, addr+size, size,
1244
+ R_X86_64_GOTPCREL, true);
1245
+ addr = 0;
1246
+ } else if (wrt == elf_gotoff_sect + 1 ||
1247
+ wrt == elf_got_sect + 1) {
1248
+ nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
1249
+ "qword absolute");
1250
+ } else if (wrt == elf_gottpoff_sect + 1) {
1251
+ elf_add_gsym_reloc(s, segment, addr+size, size,
1252
+ R_X86_64_GOTTPOFF, true);
1253
+ addr = 0;
1254
+ } else {
1255
+ nasm_error(ERR_NONFATAL, "ELF64 format does not support this"
1256
+ " use of WRT");
1257
+ }
1258
+ }
1259
+ elf_sect_writeaddr(s, addr, 4);
1260
+ break;
1261
+
1262
+ case OUT_REL8ADR:
1263
+ addr = *(int64_t *)data - size;
1264
+ if (segment == segto)
1265
+ nasm_panic(0, "intra-segment OUT_REL8ADR");
1266
+ if (segment == NO_SEG) {
1267
+ /* Do nothing */
1268
+ } else if (segment % 2) {
1269
+ nasm_error(ERR_NONFATAL, "ELF64 format does not support"
1270
+ " segment base references");
1271
+ } else {
1272
+ if (wrt == NO_SEG) {
1273
+ elf_add_reloc(s, segment, addr, R_X86_64_PC64);
1274
+ addr = 0;
1275
+ } else if (wrt == elf_gotpc_sect + 1 ||
1276
+ wrt == elf_got_sect + 1) {
1277
+ elf_add_gsym_reloc(s, segment, addr+size, size,
1278
+ R_X86_64_GOTPCREL64, true);
1279
+ addr = 0;
1280
+ } else if (wrt == elf_gotoff_sect + 1 ||
1281
+ wrt == elf_got_sect + 1) {
1282
+ nasm_error(ERR_NONFATAL, "ELF64 requires ..gotoff references to be "
1283
+ "absolute");
1284
+ } else if (wrt == elf_gottpoff_sect + 1) {
1285
+ nasm_error(ERR_NONFATAL, "ELF64 requires ..gottpoff references to be "
1286
+ "dword");
1287
+ } else {
1288
+ nasm_error(ERR_NONFATAL, "ELF64 format does not support this"
1289
+ " use of WRT");
1290
+ }
1291
+ }
1292
+ elf_sect_writeaddr(s, addr, 8);
1293
+ break;
1294
+
1295
+ default:
1296
+ panic();
1297
+ }
1298
+ }
1299
+
1300
+ static void elfx32_out(int32_t segto, const void *data,
1301
+ enum out_type type, uint64_t size,
1302
+ int32_t segment, int32_t wrt)
1303
+ {
1304
+ struct elf_section *s;
1305
+ int64_t addr;
1306
+ int reltype, bytes;
1307
+ int i;
1308
+ static struct symlininfo sinfo;
1309
+
1310
+ /*
1311
+ * handle absolute-assembly (structure definitions)
1312
+ */
1313
+ if (segto == NO_SEG) {
1314
+ if (type != OUT_RESERVE)
1315
+ nasm_error(ERR_NONFATAL, "attempt to assemble code in [ABSOLUTE]"
1316
+ " space");
1317
+ return;
1318
+ }
1319
+
1320
+ s = NULL;
1321
+ for (i = 0; i < nsects; i++)
1322
+ if (segto == sects[i]->index) {
1323
+ s = sects[i];
1324
+ break;
1325
+ }
1326
+ if (!s) {
1327
+ int tempint; /* ignored */
1328
+ if (segto != elf_section_names(".text", 2, &tempint))
1329
+ nasm_panic(0, "strange segment conditions in ELF driver");
1330
+ else {
1331
+ s = sects[nsects - 1];
1332
+ i = nsects - 1;
1333
+ }
1334
+ }
1335
+
1336
+ /* again some stabs debugging stuff */
1337
+ sinfo.offset = s->len;
1338
+ sinfo.section = i;
1339
+ sinfo.segto = segto;
1340
+ sinfo.name = s->name;
1341
+ dfmt->debug_output(TY_DEBUGSYMLIN, &sinfo);
1342
+ /* end of debugging stuff */
1343
+
1344
+ if (s->type == SHT_NOBITS && type != OUT_RESERVE) {
1345
+ nasm_error(ERR_WARNING, "attempt to initialize memory in"
1346
+ " BSS section `%s': ignored", s->name);
1347
+ s->len += realsize(type, size);
1348
+ return;
1349
+ }
1350
+
1351
+ switch (type) {
1352
+ case OUT_RESERVE:
1353
+ if (s->type == SHT_PROGBITS) {
1354
+ nasm_error(ERR_WARNING, "uninitialized space declared in"
1355
+ " non-BSS section `%s': zeroing", s->name);
1356
+ elf_sect_write(s, NULL, size);
1357
+ } else
1358
+ s->len += size;
1359
+ break;
1360
+
1361
+ case OUT_RAWDATA:
1362
+ if (segment != NO_SEG)
1363
+ nasm_panic(0, "OUT_RAWDATA with other than NO_SEG");
1364
+ elf_sect_write(s, data, size);
1365
+ break;
1366
+
1367
+ case OUT_ADDRESS:
1368
+ {
1369
+ int isize = (int)size;
1370
+ int asize = abs((int)size);
1371
+
1372
+ addr = *(int64_t *)data;
1373
+ if (segment == NO_SEG) {
1374
+ /* Do nothing */
1375
+ } else if (segment % 2) {
1376
+ nasm_error(ERR_NONFATAL, "ELF format does not support"
1377
+ " segment base references");
1378
+ } else {
1379
+ if (wrt == NO_SEG) {
1380
+ switch (isize) {
1381
+ case 1:
1382
+ case -1:
1383
+ elf_add_reloc(s, segment, addr, R_X86_64_8);
1384
+ break;
1385
+ case 2:
1386
+ case -2:
1387
+ elf_add_reloc(s, segment, addr, R_X86_64_16);
1388
+ break;
1389
+ case 4:
1390
+ elf_add_reloc(s, segment, addr, R_X86_64_32);
1391
+ break;
1392
+ case -4:
1393
+ elf_add_reloc(s, segment, addr, R_X86_64_32S);
1394
+ break;
1395
+ case 8:
1396
+ case -8:
1397
+ elf_add_reloc(s, segment, addr, R_X86_64_64);
1398
+ break;
1399
+ default:
1400
+ nasm_panic(0, "internal error elfx32-hpa-871");
1401
+ break;
1402
+ }
1403
+ addr = 0;
1404
+ } else if (wrt == elf_gotpc_sect + 1) {
1405
+ /*
1406
+ * The user will supply GOT relative to $$. ELF
1407
+ * will let us have GOT relative to $. So we
1408
+ * need to fix up the data item by $-$$.
1409
+ */
1410
+ addr += s->len;
1411
+ elf_add_reloc(s, segment, addr, R_X86_64_GOTPC32);
1412
+ addr = 0;
1413
+ } else if (wrt == elf_gotoff_sect + 1) {
1414
+ nasm_error(ERR_NONFATAL, "ELFX32 doesn't support "
1415
+ "R_X86_64_GOTOFF64");
1416
+ } else if (wrt == elf_got_sect + 1) {
1417
+ switch (asize) {
1418
+ case 4:
1419
+ elf_add_gsym_reloc(s, segment, addr, 0,
1420
+ R_X86_64_GOT32, true);
1421
+ addr = 0;
1422
+ break;
1423
+ default:
1424
+ nasm_error(ERR_NONFATAL, "invalid ..got reference");
1425
+ break;
1426
+ }
1427
+ } else if (wrt == elf_sym_sect + 1) {
1428
+ switch (isize) {
1429
+ case 1:
1430
+ case -1:
1431
+ elf_add_gsym_reloc(s, segment, addr, 0,
1432
+ R_X86_64_8, false);
1433
+ addr = 0;
1434
+ break;
1435
+ case 2:
1436
+ case -2:
1437
+ elf_add_gsym_reloc(s, segment, addr, 0,
1438
+ R_X86_64_16, false);
1439
+ addr = 0;
1440
+ break;
1441
+ case 4:
1442
+ elf_add_gsym_reloc(s, segment, addr, 0,
1443
+ R_X86_64_32, false);
1444
+ addr = 0;
1445
+ break;
1446
+ case -4:
1447
+ elf_add_gsym_reloc(s, segment, addr, 0,
1448
+ R_X86_64_32S, false);
1449
+ addr = 0;
1450
+ break;
1451
+ case 8:
1452
+ case -8:
1453
+ elf_add_gsym_reloc(s, segment, addr, 0,
1454
+ R_X86_64_64, false);
1455
+ addr = 0;
1456
+ break;
1457
+ default:
1458
+ nasm_panic(0, "internal error elfx32-hpa-903");
1459
+ break;
1460
+ }
1461
+ } else if (wrt == elf_plt_sect + 1) {
1462
+ nasm_error(ERR_NONFATAL, "ELF format cannot produce non-PC-"
1463
+ "relative PLT references");
1464
+ } else {
1465
+ nasm_error(ERR_NONFATAL, "ELF format does not support this"
1466
+ " use of WRT");
1467
+ }
1468
+ }
1469
+ elf_sect_writeaddr(s, addr, asize);
1470
+ break;
1471
+ }
1472
+
1473
+ case OUT_REL1ADR:
1474
+ reltype = R_X86_64_PC8;
1475
+ bytes = 1;
1476
+ goto rel12adr;
1477
+
1478
+ case OUT_REL2ADR:
1479
+ reltype = R_X86_64_PC16;
1480
+ bytes = 2;
1481
+ goto rel12adr;
1482
+
1483
+ rel12adr:
1484
+ addr = *(int64_t *)data - size;
1485
+ if (segment == segto)
1486
+ nasm_panic(0, "intra-segment OUT_REL1ADR");
1487
+ if (segment == NO_SEG) {
1488
+ /* Do nothing */
1489
+ } else if (segment % 2) {
1490
+ nasm_error(ERR_NONFATAL, "ELF format does not support"
1491
+ " segment base references");
1492
+ } else {
1493
+ if (wrt == NO_SEG) {
1494
+ elf_add_reloc(s, segment, addr, reltype);
1495
+ addr = 0;
1496
+ } else {
1497
+ nasm_error(ERR_NONFATAL,
1498
+ "Unsupported non-32-bit ELF relocation");
1499
+ }
1500
+ }
1501
+ elf_sect_writeaddr(s, addr, bytes);
1502
+ break;
1503
+
1504
+ case OUT_REL4ADR:
1505
+ addr = *(int64_t *)data - size;
1506
+ if (segment == segto)
1507
+ nasm_panic(0, "intra-segment OUT_REL4ADR");
1508
+ if (segment == NO_SEG) {
1509
+ /* Do nothing */
1510
+ } else if (segment % 2) {
1511
+ nasm_error(ERR_NONFATAL, "ELFX32 format does not support"
1512
+ " segment base references");
1513
+ } else {
1514
+ if (wrt == NO_SEG) {
1515
+ elf_add_reloc(s, segment, addr, R_X86_64_PC32);
1516
+ addr = 0;
1517
+ } else if (wrt == elf_plt_sect + 1) {
1518
+ elf_add_gsym_reloc(s, segment, addr+size, size,
1519
+ R_X86_64_PLT32, true);
1520
+ addr = 0;
1521
+ } else if (wrt == elf_gotpc_sect + 1 ||
1522
+ wrt == elf_got_sect + 1) {
1523
+ elf_add_gsym_reloc(s, segment, addr+size, size,
1524
+ R_X86_64_GOTPCREL, true);
1525
+ addr = 0;
1526
+ } else if (wrt == elf_gotoff_sect + 1 ||
1527
+ wrt == elf_got_sect + 1) {
1528
+ nasm_error(ERR_NONFATAL, "invalid ..gotoff reference");
1529
+ } else if (wrt == elf_gottpoff_sect + 1) {
1530
+ elf_add_gsym_reloc(s, segment, addr+size, size,
1531
+ R_X86_64_GOTTPOFF, true);
1532
+ addr = 0;
1533
+ } else {
1534
+ nasm_error(ERR_NONFATAL, "ELFX32 format does not support this"
1535
+ " use of WRT");
1536
+ }
1537
+ }
1538
+ elf_sect_writeaddr(s, addr, 4);
1539
+ break;
1540
+
1541
+ case OUT_REL8ADR:
1542
+ nasm_error(ERR_NONFATAL, "32-bit ELF format does not support 64-bit relocations");
1543
+ addr = 0;
1544
+ elf_sect_writeaddr(s, addr, 8);
1545
+ break;
1546
+
1547
+ default:
1548
+ panic();
1549
+ }
1550
+ }
1551
+
1552
+ static void elf_write(void)
1553
+ {
1554
+ int align;
1555
+ char *p;
1556
+ int i;
1557
+
1558
+ struct SAA *symtab;
1559
+ int32_t symtablen, symtablocal;
1560
+
1561
+ /*
1562
+ * Work out how many sections we will have. We have SHN_UNDEF,
1563
+ * then the flexible user sections, then the fixed sections
1564
+ * `.shstrtab', `.symtab' and `.strtab', then optionally
1565
+ * relocation sections for the user sections.
1566
+ */
1567
+ nsections = sec_numspecial + 1;
1568
+ if (dfmt_is_stabs())
1569
+ nsections += 3;
1570
+ else if (dfmt_is_dwarf())
1571
+ nsections += 10;
1572
+
1573
+ add_sectname("", ".shstrtab");
1574
+ add_sectname("", ".symtab");
1575
+ add_sectname("", ".strtab");
1576
+ for (i = 0; i < nsects; i++) {
1577
+ nsections++; /* for the section itself */
1578
+ if (sects[i]->head) {
1579
+ nsections++; /* for its relocations */
1580
+ add_sectname(is_elf32() ? ".rel" : ".rela", sects[i]->name);
1581
+ }
1582
+ }
1583
+
1584
+ if (dfmt_is_stabs()) {
1585
+ /* in case the debug information is wanted, just add these three sections... */
1586
+ add_sectname("", ".stab");
1587
+ add_sectname("", ".stabstr");
1588
+ add_sectname(is_elf32() ? ".rel" : ".rela", ".stab");
1589
+ } else if (dfmt_is_dwarf()) {
1590
+ /* the dwarf debug standard specifies the following ten sections,
1591
+ not all of which are currently implemented,
1592
+ although all of them are defined. */
1593
+ #define debug_aranges (int64_t) (nsections-10)
1594
+ #define debug_info (int64_t) (nsections-7)
1595
+ #define debug_abbrev (int64_t) (nsections-5)
1596
+ #define debug_line (int64_t) (nsections-4)
1597
+ add_sectname("", ".debug_aranges");
1598
+ add_sectname(".rela", ".debug_aranges");
1599
+ add_sectname("", ".debug_pubnames");
1600
+ add_sectname("", ".debug_info");
1601
+ add_sectname(".rela", ".debug_info");
1602
+ add_sectname("", ".debug_abbrev");
1603
+ add_sectname("", ".debug_line");
1604
+ add_sectname(".rela", ".debug_line");
1605
+ add_sectname("", ".debug_frame");
1606
+ add_sectname("", ".debug_loc");
1607
+ }
1608
+
1609
+ /*
1610
+ * Output the ELF header.
1611
+ */
1612
+ if (is_elf32() || is_elfx32()) {
1613
+ nasm_write("\177ELF\1\1\1", 7, ofile);
1614
+ fputc(elf_osabi, ofile);
1615
+ fputc(elf_abiver, ofile);
1616
+ fwritezero(7, ofile);
1617
+ fwriteint16_t(ET_REL, ofile); /* relocatable file */
1618
+ fwriteint16_t(is_elf32() ? EM_386 : EM_X86_64, ofile); /* processor ID */
1619
+ fwriteint32_t(1L, ofile); /* EV_CURRENT file format version */
1620
+ fwriteint32_t(0L, ofile); /* no entry point */
1621
+ fwriteint32_t(0L, ofile); /* no program header table */
1622
+ fwriteint32_t(0x40L, ofile); /* section headers straight after ELF header plus alignment */
1623
+ fwriteint32_t(0L, ofile); /* no special flags */
1624
+ fwriteint16_t(0x34, ofile); /* size of ELF header */
1625
+ fwriteint16_t(0, ofile); /* no program header table, again */
1626
+ fwriteint16_t(0, ofile); /* still no program header table */
1627
+ fwriteint16_t(sizeof(Elf32_Shdr), ofile); /* size of section header */
1628
+ fwriteint16_t(nsections, ofile); /* number of sections */
1629
+ fwriteint16_t(sec_shstrtab, ofile); /* string table section index for section header table */
1630
+
1631
+ fwriteint32_t(0L, ofile); /* align to 0x40 bytes */
1632
+ fwriteint32_t(0L, ofile);
1633
+ fwriteint32_t(0L, ofile);
1634
+ } else {
1635
+ nasm_assert(is_elf64());
1636
+ nasm_write("\177ELF\2\1\1", 7, ofile);
1637
+ fputc(elf_osabi, ofile);
1638
+ fputc(elf_abiver, ofile);
1639
+ fwritezero(7, ofile);
1640
+ fwriteint16_t(ET_REL, ofile); /* relocatable file */
1641
+ fwriteint16_t(EM_X86_64, ofile); /* processor ID */
1642
+ fwriteint32_t(1L, ofile); /* EV_CURRENT file format version */
1643
+ fwriteint64_t(0L, ofile); /* no entry point */
1644
+ fwriteint64_t(0L, ofile); /* no program header table */
1645
+ fwriteint64_t(0x40L, ofile); /* section headers straight after ELF header plus alignment */
1646
+ fwriteint32_t(0L, ofile); /* no special flags */
1647
+ fwriteint16_t(0x40, ofile); /* size of ELF header */
1648
+ fwriteint16_t(0, ofile); /* no program header table, again */
1649
+ fwriteint16_t(0, ofile); /* still no program header table */
1650
+ fwriteint16_t(sizeof(Elf64_Shdr), ofile); /* size of section header */
1651
+ fwriteint16_t(nsections, ofile); /* number of sections */
1652
+ fwriteint16_t(sec_shstrtab, ofile); /* string table section index for section header table */
1653
+ }
1654
+
1655
+ /*
1656
+ * Build the symbol table and relocation tables.
1657
+ */
1658
+ symtab = elf_build_symtab(&symtablen, &symtablocal);
1659
+ for (i = 0; i < nsects; i++)
1660
+ if (sects[i]->head)
1661
+ sects[i]->rel = elf_build_reltab(&sects[i]->rellen,
1662
+ sects[i]->head);
1663
+
1664
+ /*
1665
+ * Now output the section header table.
1666
+ */
1667
+
1668
+ elf_foffs = 0x40 + (is_elf64() ? sizeof(Elf64_Shdr): sizeof(Elf32_Shdr)) * nsections;
1669
+ align = ALIGN(elf_foffs, SEC_FILEALIGN) - elf_foffs;
1670
+ elf_foffs += align;
1671
+ elf_nsect = 0;
1672
+ elf_sects = nasm_malloc(sizeof(*elf_sects) * nsections);
1673
+
1674
+ /* SHN_UNDEF */
1675
+ elf_section_header(0, SHT_NULL, 0, NULL, false, 0, SHN_UNDEF, 0, 0, 0);
1676
+ p = shstrtab + 1;
1677
+
1678
+ /* The normal sections */
1679
+ for (i = 0; i < nsects; i++) {
1680
+ elf_section_header(p - shstrtab, sects[i]->type, sects[i]->flags,
1681
+ (sects[i]->type == SHT_PROGBITS ?
1682
+ sects[i]->data : NULL), true,
1683
+ sects[i]->len, 0, 0, sects[i]->align, 0);
1684
+ p += strlen(p) + 1;
1685
+ }
1686
+
1687
+ /* .shstrtab */
1688
+ elf_section_header(p - shstrtab, SHT_STRTAB, 0, shstrtab, false,
1689
+ shstrtablen, 0, 0, 1, 0);
1690
+ p += strlen(p) + 1;
1691
+
1692
+ /* .symtab */
1693
+ if (is_elf64())
1694
+ elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
1695
+ symtablen, sec_strtab, symtablocal, 8, 24);
1696
+ else
1697
+ elf_section_header(p - shstrtab, SHT_SYMTAB, 0, symtab, true,
1698
+ symtablen, sec_strtab, symtablocal, 4, 16);
1699
+ p += strlen(p) + 1;
1700
+
1701
+ /* .strtab */
1702
+ elf_section_header(p - shstrtab, SHT_STRTAB, 0, strs, true,
1703
+ strslen, 0, 0, 1, 0);
1704
+ p += strlen(p) + 1;
1705
+
1706
+ /* The relocation sections */
1707
+ if (is_elf32()) {
1708
+ for (i = 0; i < nsects; i++) {
1709
+ if (sects[i]->head) {
1710
+ elf_section_header(p - shstrtab, SHT_REL, 0, sects[i]->rel, true,
1711
+ sects[i]->rellen, sec_symtab, i + 1, 4, 8);
1712
+ p += strlen(p) + 1;
1713
+ }
1714
+ }
1715
+ } else if (is_elfx32()) {
1716
+ for (i = 0; i < nsects; i++) {
1717
+ if (sects[i]->head) {
1718
+ elf_section_header(p - shstrtab, SHT_RELA, 0, sects[i]->rel, true,
1719
+ sects[i]->rellen, sec_symtab, i + 1, 4, 12);
1720
+ p += strlen(p) + 1;
1721
+ }
1722
+ }
1723
+ } else {
1724
+ nasm_assert(is_elf64());
1725
+ for (i = 0; i < nsects; i++) {
1726
+ if (sects[i]->head) {
1727
+ elf_section_header(p - shstrtab, SHT_RELA, 0, sects[i]->rel, true,
1728
+ sects[i]->rellen, sec_symtab, i + 1, 8, 24);
1729
+ p += strlen(p) + 1;
1730
+ }
1731
+ }
1732
+ }
1733
+
1734
+ if (dfmt_is_stabs()) {
1735
+ /* for debugging information, create the last three sections
1736
+ which are the .stab , .stabstr and .rel.stab sections respectively */
1737
+
1738
+ /* this function call creates the stab sections in memory */
1739
+ stabs_generate();
1740
+
1741
+ if (stabbuf && stabstrbuf && stabrelbuf) {
1742
+ elf_section_header(p - shstrtab, SHT_PROGBITS, 0, stabbuf, false,
1743
+ stablen, sec_stabstr, 0, 4, 12);
1744
+ p += strlen(p) + 1;
1745
+
1746
+ elf_section_header(p - shstrtab, SHT_STRTAB, 0, stabstrbuf, false,
1747
+ stabstrlen, 0, 0, 4, 0);
1748
+ p += strlen(p) + 1;
1749
+
1750
+ /* link -> symtable info -> section to refer to */
1751
+ if (is_elf32()) {
1752
+ elf_section_header(p - shstrtab, SHT_REL, 0, stabrelbuf, false,
1753
+ stabrellen, sec_symtab, sec_stab, 4, 8);
1754
+ } else {
1755
+ elf_section_header(p - shstrtab, SHT_RELA, 0, stabrelbuf, false,
1756
+ stabrellen, sec_symtab, sec_stab, 4, is_elf64() ? 24 : 12);
1757
+ }
1758
+ p += strlen(p) + 1;
1759
+ }
1760
+ } else if (dfmt_is_dwarf()) {
1761
+ /* for dwarf debugging information, create the ten dwarf sections */
1762
+
1763
+ /* this function call creates the dwarf sections in memory */
1764
+ if (dwarf_fsect)
1765
+ dwarf_generate();
1766
+
1767
+ elf_section_header(p - shstrtab, SHT_PROGBITS, 0, arangesbuf, false,
1768
+ arangeslen, 0, 0, 1, 0);
1769
+ p += strlen(p) + 1;
1770
+
1771
+ elf_section_header(p - shstrtab, SHT_RELA, 0, arangesrelbuf, false,
1772
+ arangesrellen, sec_symtab,
1773
+ is_elf64() ? debug_aranges : sec_debug_aranges,
1774
+ 1, is_elf64() ? 24 : 12);
1775
+ p += strlen(p) + 1;
1776
+
1777
+ elf_section_header(p - shstrtab, SHT_PROGBITS, 0, pubnamesbuf,
1778
+ false, pubnameslen, 0, 0, 1, 0);
1779
+ p += strlen(p) + 1;
1780
+
1781
+ elf_section_header(p - shstrtab, SHT_PROGBITS, 0, infobuf, false,
1782
+ infolen, 0, 0, 1, 0);
1783
+ p += strlen(p) + 1;
1784
+
1785
+ elf_section_header(p - shstrtab, SHT_RELA, 0, inforelbuf, false,
1786
+ inforellen, sec_symtab,
1787
+ is_elf64() ? debug_info : sec_debug_info,
1788
+ 1, is_elf64() ? 24 : 12);
1789
+ p += strlen(p) + 1;
1790
+
1791
+ elf_section_header(p - shstrtab, SHT_PROGBITS, 0, abbrevbuf, false,
1792
+ abbrevlen, 0, 0, 1, 0);
1793
+ p += strlen(p) + 1;
1794
+
1795
+ elf_section_header(p - shstrtab, SHT_PROGBITS, 0, linebuf, false,
1796
+ linelen, 0, 0, 1, 0);
1797
+ p += strlen(p) + 1;
1798
+
1799
+ elf_section_header(p - shstrtab, SHT_RELA, 0, linerelbuf, false,
1800
+ linerellen, sec_symtab,
1801
+ is_elf64() ? debug_line : sec_debug_line,
1802
+ 1, is_elf64() ? 24 : 12);
1803
+ p += strlen(p) + 1;
1804
+
1805
+ elf_section_header(p - shstrtab, SHT_PROGBITS, 0, framebuf, false,
1806
+ framelen, 0, 0, 8, 0);
1807
+ p += strlen(p) + 1;
1808
+
1809
+ elf_section_header(p - shstrtab, SHT_PROGBITS, 0, locbuf, false,
1810
+ loclen, 0, 0, 1, 0);
1811
+ p += strlen(p) + 1;
1812
+ }
1813
+ fwritezero(align, ofile);
1814
+
1815
+ /*
1816
+ * Now output the sections.
1817
+ */
1818
+ elf_write_sections();
1819
+
1820
+ nasm_free(elf_sects);
1821
+ saa_free(symtab);
1822
+ }
1823
+
1824
+ static struct SAA *elf_build_symtab(int32_t *len, int32_t *local)
1825
+ {
1826
+ struct SAA *s = saa_init(1L);
1827
+ struct elf_symbol *sym;
1828
+ uint8_t entry[24], *p;
1829
+ int i;
1830
+
1831
+ *len = *local = 0;
1832
+
1833
+ /*
1834
+ * First, an all-zeros entry, required by the ELF spec.
1835
+ */
1836
+ saa_wbytes(s, NULL, is_elf64() ? 24L : 16L); /* null symbol table entry */
1837
+ *len += is_elf64() ? 24L : 16L;
1838
+ (*local)++;
1839
+
1840
+ /*
1841
+ * Next, an entry for the file name.
1842
+ */
1843
+ p = entry;
1844
+ if (is_elf64()) {
1845
+ WRITELONG(p, 1); /* we know it's 1st entry in strtab */
1846
+ WRITESHORT(p, STT_FILE); /* type FILE */
1847
+ WRITESHORT(p, SHN_ABS);
1848
+ WRITEDLONG(p, (uint64_t) 0); /* no value */
1849
+ WRITEDLONG(p, (uint64_t) 0); /* no size either */
1850
+ saa_wbytes(s, entry, 24L);
1851
+ *len += 24;
1852
+ (*local)++;
1853
+ } else {
1854
+ WRITELONG(p, 1); /* we know it's 1st entry in strtab */
1855
+ WRITELONG(p, 0); /* no value */
1856
+ WRITELONG(p, 0); /* no size either */
1857
+ WRITESHORT(p, STT_FILE); /* type FILE */
1858
+ WRITESHORT(p, SHN_ABS);
1859
+ saa_wbytes(s, entry, 16L);
1860
+ *len += 16;
1861
+ (*local)++;
1862
+ }
1863
+
1864
+ /*
1865
+ * Now some standard symbols defining the segments, for relocation
1866
+ * purposes.
1867
+ */
1868
+ if (is_elf64()) {
1869
+ for (i = 1; i <= nsects; i++) {
1870
+ p = entry;
1871
+ WRITELONG(p, 0); /* no symbol name */
1872
+ WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1873
+ WRITESHORT(p, i); /* section id */
1874
+ WRITEDLONG(p, (uint64_t) 0); /* offset zero */
1875
+ WRITEDLONG(p, (uint64_t) 0); /* size zero */
1876
+ saa_wbytes(s, entry, 24L);
1877
+ *len += 24;
1878
+ (*local)++;
1879
+ }
1880
+ } else {
1881
+ for (i = 1; i <= nsects; i++) {
1882
+ p = entry;
1883
+ WRITELONG(p, 0); /* no symbol name */
1884
+ WRITELONG(p, 0); /* offset zero */
1885
+ WRITELONG(p, 0); /* size zero */
1886
+ WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1887
+ WRITESHORT(p, i); /* section id */
1888
+ saa_wbytes(s, entry, 16L);
1889
+ *len += 16;
1890
+ (*local)++;
1891
+ }
1892
+ }
1893
+
1894
+ /*
1895
+ * Now the other local symbols.
1896
+ */
1897
+ saa_rewind(syms);
1898
+ if (is_elf64()) {
1899
+ while ((sym = saa_rstruct(syms))) {
1900
+ if (sym->type & SYM_GLOBAL)
1901
+ continue;
1902
+ p = entry;
1903
+ WRITELONG(p, sym->strpos); /* index into symbol string table */
1904
+ WRITECHAR(p, sym->type); /* type and binding */
1905
+ WRITECHAR(p, sym->other); /* visibility */
1906
+ WRITESHORT(p, sym->section); /* index into section header table */
1907
+ WRITEDLONG(p, (int64_t)sym->symv.key); /* value of symbol */
1908
+ WRITEDLONG(p, (int64_t)sym->size); /* size of symbol */
1909
+ saa_wbytes(s, entry, 24L);
1910
+ *len += 24;
1911
+ (*local)++;
1912
+ }
1913
+ /*
1914
+ * dwarf needs symbols for debug sections
1915
+ * which are relocation targets.
1916
+ */
1917
+ if (dfmt_is_dwarf()) {
1918
+ dwarf_infosym = *local;
1919
+ p = entry;
1920
+ WRITELONG(p, 0); /* no symbol name */
1921
+ WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1922
+ WRITESHORT(p, debug_info); /* section id */
1923
+ WRITEDLONG(p, (uint64_t) 0); /* offset zero */
1924
+ WRITEDLONG(p, (uint64_t) 0); /* size zero */
1925
+ saa_wbytes(s, entry, 24L);
1926
+ *len += 24;
1927
+ (*local)++;
1928
+ dwarf_abbrevsym = *local;
1929
+ p = entry;
1930
+ WRITELONG(p, 0); /* no symbol name */
1931
+ WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1932
+ WRITESHORT(p, debug_abbrev); /* section id */
1933
+ WRITEDLONG(p, (uint64_t) 0); /* offset zero */
1934
+ WRITEDLONG(p, (uint64_t) 0); /* size zero */
1935
+ saa_wbytes(s, entry, 24L);
1936
+ *len += 24;
1937
+ (*local)++;
1938
+ dwarf_linesym = *local;
1939
+ p = entry;
1940
+ WRITELONG(p, 0); /* no symbol name */
1941
+ WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1942
+ WRITESHORT(p, debug_line); /* section id */
1943
+ WRITEDLONG(p, (uint64_t) 0); /* offset zero */
1944
+ WRITEDLONG(p, (uint64_t) 0); /* size zero */
1945
+ saa_wbytes(s, entry, 24L);
1946
+ *len += 24;
1947
+ (*local)++;
1948
+ }
1949
+ } else {
1950
+ while ((sym = saa_rstruct(syms))) {
1951
+ if (sym->type & SYM_GLOBAL)
1952
+ continue;
1953
+ p = entry;
1954
+ WRITELONG(p, sym->strpos);
1955
+ WRITELONG(p, sym->symv.key);
1956
+ WRITELONG(p, sym->size);
1957
+ WRITECHAR(p, sym->type); /* type and binding */
1958
+ WRITECHAR(p, sym->other); /* visibility */
1959
+ WRITESHORT(p, sym->section);
1960
+ saa_wbytes(s, entry, 16L);
1961
+ *len += 16;
1962
+ (*local)++;
1963
+ }
1964
+ /*
1965
+ * dwarf needs symbols for debug sections
1966
+ * which are relocation targets.
1967
+ */
1968
+ if (dfmt_is_dwarf()) {
1969
+ dwarf_infosym = *local;
1970
+ p = entry;
1971
+ WRITELONG(p, 0); /* no symbol name */
1972
+ WRITELONG(p, (uint32_t) 0); /* offset zero */
1973
+ WRITELONG(p, (uint32_t) 0); /* size zero */
1974
+ WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1975
+ WRITESHORT(p, sec_debug_info); /* section id */
1976
+ saa_wbytes(s, entry, 16L);
1977
+ *len += 16;
1978
+ (*local)++;
1979
+ dwarf_abbrevsym = *local;
1980
+ p = entry;
1981
+ WRITELONG(p, 0); /* no symbol name */
1982
+ WRITELONG(p, (uint32_t) 0); /* offset zero */
1983
+ WRITELONG(p, (uint32_t) 0); /* size zero */
1984
+ WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1985
+ WRITESHORT(p, sec_debug_abbrev); /* section id */
1986
+ saa_wbytes(s, entry, 16L);
1987
+ *len += 16;
1988
+ (*local)++;
1989
+ dwarf_linesym = *local;
1990
+ p = entry;
1991
+ WRITELONG(p, 0); /* no symbol name */
1992
+ WRITELONG(p, (uint32_t) 0); /* offset zero */
1993
+ WRITELONG(p, (uint32_t) 0); /* size zero */
1994
+ WRITESHORT(p, STT_SECTION); /* type, binding, and visibility */
1995
+ WRITESHORT(p, sec_debug_line); /* section id */
1996
+ saa_wbytes(s, entry, 16L);
1997
+ *len += 16;
1998
+ (*local)++;
1999
+ }
2000
+ }
2001
+
2002
+ /*
2003
+ * Now the global symbols.
2004
+ */
2005
+ saa_rewind(syms);
2006
+ if (is_elf64()) {
2007
+ while ((sym = saa_rstruct(syms))) {
2008
+ if (!(sym->type & SYM_GLOBAL))
2009
+ continue;
2010
+ p = entry;
2011
+ WRITELONG(p, sym->strpos);
2012
+ WRITECHAR(p, sym->type); /* type and binding */
2013
+ WRITECHAR(p, sym->other); /* visibility */
2014
+ WRITESHORT(p, sym->section);
2015
+ WRITEDLONG(p, (int64_t)sym->symv.key);
2016
+ WRITEDLONG(p, (int64_t)sym->size);
2017
+ saa_wbytes(s, entry, 24L);
2018
+ *len += 24;
2019
+ }
2020
+ } else {
2021
+ while ((sym = saa_rstruct(syms))) {
2022
+ if (!(sym->type & SYM_GLOBAL))
2023
+ continue;
2024
+ p = entry;
2025
+ WRITELONG(p, sym->strpos);
2026
+ WRITELONG(p, sym->symv.key);
2027
+ WRITELONG(p, sym->size);
2028
+ WRITECHAR(p, sym->type); /* type and binding */
2029
+ WRITECHAR(p, sym->other); /* visibility */
2030
+ WRITESHORT(p, sym->section);
2031
+ saa_wbytes(s, entry, 16L);
2032
+ *len += 16;
2033
+ }
2034
+ }
2035
+
2036
+ return s;
2037
+ }
2038
+
2039
+ static struct SAA *elf_build_reltab(uint64_t *len, struct elf_reloc *r)
2040
+ {
2041
+ struct SAA *s;
2042
+ uint8_t *p, entry[24];
2043
+ int32_t global_offset;
2044
+
2045
+ if (!r)
2046
+ return NULL;
2047
+
2048
+ s = saa_init(1L);
2049
+ *len = 0;
2050
+
2051
+ /*
2052
+ * How to onvert from a global placeholder to a real symbol index;
2053
+ * the +2 refers to the two special entries, the null entry and
2054
+ * the filename entry.
2055
+ */
2056
+ global_offset = -GLOBAL_TEMP_BASE + nsects + nlocals + ndebugs + 2;
2057
+
2058
+ if (is_elf32()) {
2059
+ while (r) {
2060
+ int32_t sym = r->symbol;
2061
+
2062
+ if (sym >= GLOBAL_TEMP_BASE)
2063
+ sym += global_offset;
2064
+
2065
+ p = entry;
2066
+ WRITELONG(p, r->address);
2067
+ WRITELONG(p, (sym << 8) + r->type);
2068
+ saa_wbytes(s, entry, 8L);
2069
+ *len += 8;
2070
+
2071
+ r = r->next;
2072
+ }
2073
+ } else if (is_elfx32()) {
2074
+ while (r) {
2075
+ int32_t sym = r->symbol;
2076
+
2077
+ if (sym >= GLOBAL_TEMP_BASE)
2078
+ sym += global_offset;
2079
+
2080
+ p = entry;
2081
+ WRITELONG(p, r->address);
2082
+ WRITELONG(p, (sym << 8) + r->type);
2083
+ WRITELONG(p, r->offset);
2084
+ saa_wbytes(s, entry, 12L);
2085
+ *len += 12;
2086
+
2087
+ r = r->next;
2088
+ }
2089
+ } else {
2090
+ nasm_assert(is_elf64());
2091
+ while (r) {
2092
+ int32_t sym = r->symbol;
2093
+
2094
+ if (sym >= GLOBAL_TEMP_BASE)
2095
+ sym += global_offset;
2096
+
2097
+ p = entry;
2098
+ WRITEDLONG(p, r->address);
2099
+ WRITELONG(p, r->type);
2100
+ WRITELONG(p, sym);
2101
+ WRITEDLONG(p, r->offset);
2102
+ saa_wbytes(s, entry, 24L);
2103
+ *len += 24;
2104
+
2105
+ r = r->next;
2106
+ }
2107
+ }
2108
+
2109
+ return s;
2110
+ }
2111
+
2112
+ static void elf_section_header(int name, int type, uint64_t flags,
2113
+ void *data, bool is_saa, uint64_t datalen,
2114
+ int link, int info, int align, int eltsize)
2115
+ {
2116
+ elf_sects[elf_nsect].data = data;
2117
+ elf_sects[elf_nsect].len = datalen;
2118
+ elf_sects[elf_nsect].is_saa = is_saa;
2119
+ elf_nsect++;
2120
+
2121
+ if (is_elf32() || is_elfx32()) {
2122
+ fwriteint32_t((int32_t)name, ofile);
2123
+ fwriteint32_t((int32_t)type, ofile);
2124
+ fwriteint32_t((int32_t)flags, ofile);
2125
+ fwriteint32_t(0L, ofile); /* no address, ever, in object files */
2126
+ fwriteint32_t(type == 0 ? 0L : elf_foffs, ofile);
2127
+ fwriteint32_t(datalen, ofile);
2128
+ if (data)
2129
+ elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
2130
+ fwriteint32_t((int32_t)link, ofile);
2131
+ fwriteint32_t((int32_t)info, ofile);
2132
+ fwriteint32_t((int32_t)align, ofile);
2133
+ fwriteint32_t((int32_t)eltsize, ofile);
2134
+ } else {
2135
+ nasm_assert(is_elf64());
2136
+ fwriteint32_t((int32_t)name, ofile);
2137
+ fwriteint32_t((int32_t)type, ofile);
2138
+ fwriteint64_t((int64_t)flags, ofile);
2139
+ fwriteint64_t(0L, ofile); /* no address, ever, in object files */
2140
+ fwriteint64_t(type == 0 ? 0L : elf_foffs, ofile);
2141
+ fwriteint64_t(datalen, ofile);
2142
+ if (data)
2143
+ elf_foffs += ALIGN(datalen, SEC_FILEALIGN);
2144
+ fwriteint32_t((int32_t)link, ofile);
2145
+ fwriteint32_t((int32_t)info, ofile);
2146
+ fwriteint64_t((int64_t)align, ofile);
2147
+ fwriteint64_t((int64_t)eltsize, ofile);
2148
+ }
2149
+ }
2150
+
2151
+ static void elf_write_sections(void)
2152
+ {
2153
+ int i;
2154
+ for (i = 0; i < elf_nsect; i++)
2155
+ if (elf_sects[i].data) {
2156
+ int32_t len = elf_sects[i].len;
2157
+ int32_t reallen = ALIGN(len, SEC_FILEALIGN);
2158
+ int32_t align = reallen - len;
2159
+ if (elf_sects[i].is_saa)
2160
+ saa_fpwrite(elf_sects[i].data, ofile);
2161
+ else
2162
+ nasm_write(elf_sects[i].data, len, ofile);
2163
+ fwritezero(align, ofile);
2164
+ }
2165
+ }
2166
+
2167
+ static void elf_sect_write(struct elf_section *sect, const void *data, size_t len)
2168
+ {
2169
+ saa_wbytes(sect->data, data, len);
2170
+ sect->len += len;
2171
+ }
2172
+
2173
+ static void elf_sect_writeaddr(struct elf_section *sect, int64_t data, size_t len)
2174
+ {
2175
+ saa_writeaddr(sect->data, data, len);
2176
+ sect->len += len;
2177
+ }
2178
+
2179
+ static void elf_sectalign(int32_t seg, unsigned int value)
2180
+ {
2181
+ struct elf_section *s = NULL;
2182
+ int i;
2183
+
2184
+ for (i = 0; i < nsects; i++) {
2185
+ if (sects[i]->index == seg) {
2186
+ s = sects[i];
2187
+ break;
2188
+ }
2189
+ }
2190
+ if (!s || !is_power2(value))
2191
+ return;
2192
+
2193
+ if (value > s->align)
2194
+ s->align = value;
2195
+ }
2196
+
2197
+ static int32_t elf_segbase(int32_t segment)
2198
+ {
2199
+ return segment;
2200
+ }
2201
+
2202
+ static void elf_filename(char *inname, char *outname)
2203
+ {
2204
+ strcpy(elf_module, inname);
2205
+ standard_extension(inname, outname, ".o");
2206
+ }
2207
+
2208
+ extern macros_t elf_stdmac[];
2209
+
2210
+ /* Claim "elf" as a pragma namespace, for the future */
2211
+ static const struct pragma_facility elf_pragma_list[] =
2212
+ {
2213
+ { "elf", NULL },
2214
+ { NULL, NULL } /* Implements the canonical output name */
2215
+ };
2216
+
2217
+
2218
+ static const struct dfmt elf32_df_dwarf = {
2219
+ "ELF32 (i386) dwarf debug format for Linux/Unix",
2220
+ "dwarf",
2221
+ dwarf_init,
2222
+ dwarf_linenum,
2223
+ null_debug_deflabel,
2224
+ null_debug_directive,
2225
+ debug_typevalue,
2226
+ dwarf_output,
2227
+ dwarf_cleanup,
2228
+ NULL /* pragma list */
2229
+ };
2230
+
2231
+ static const struct dfmt elf32_df_stabs = {
2232
+ "ELF32 (i386) stabs debug format for Linux/Unix",
2233
+ "stabs",
2234
+ null_debug_init,
2235
+ stabs_linenum,
2236
+ null_debug_deflabel,
2237
+ null_debug_directive,
2238
+ debug_typevalue,
2239
+ stabs_output,
2240
+ stabs_cleanup,
2241
+ NULL /* pragma list */
2242
+ };
2243
+
2244
+ static const struct dfmt * const elf32_debugs_arr[3] =
2245
+ { &elf32_df_dwarf, &elf32_df_stabs, NULL };
2246
+
2247
+ const struct ofmt of_elf32 = {
2248
+ "ELF32 (i386) object files (e.g. Linux)",
2249
+ "elf32",
2250
+ 0,
2251
+ 32,
2252
+ elf32_debugs_arr,
2253
+ &elf32_df_stabs,
2254
+ elf_stdmac,
2255
+ elf_init,
2256
+ nasm_do_legacy_output,
2257
+ elf32_out,
2258
+ elf_deflabel,
2259
+ elf_section_names,
2260
+ elf_sectalign,
2261
+ elf_segbase,
2262
+ elf_directive,
2263
+ elf_filename,
2264
+ elf_cleanup,
2265
+ elf_pragma_list,
2266
+ };
2267
+
2268
+ static const struct dfmt elf64_df_dwarf = {
2269
+ "ELF64 (x86-64) dwarf debug format for Linux/Unix",
2270
+ "dwarf",
2271
+ dwarf_init,
2272
+ dwarf_linenum,
2273
+ null_debug_deflabel,
2274
+ null_debug_directive,
2275
+ debug_typevalue,
2276
+ dwarf_output,
2277
+ dwarf_cleanup,
2278
+ NULL /* pragma list */
2279
+ };
2280
+
2281
+ static const struct dfmt elf64_df_stabs = {
2282
+ "ELF64 (x86-64) stabs debug format for Linux/Unix",
2283
+ "stabs",
2284
+ null_debug_init,
2285
+ stabs_linenum,
2286
+ null_debug_deflabel,
2287
+ null_debug_directive,
2288
+ debug_typevalue,
2289
+ stabs_output,
2290
+ stabs_cleanup,
2291
+ NULL /* pragma list */
2292
+ };
2293
+
2294
+ static const struct dfmt * const elf64_debugs_arr[3] =
2295
+ { &elf64_df_dwarf, &elf64_df_stabs, NULL };
2296
+
2297
+ const struct ofmt of_elf64 = {
2298
+ "ELF64 (x86_64) object files (e.g. Linux)",
2299
+ "elf64",
2300
+ 0,
2301
+ 64,
2302
+ elf64_debugs_arr,
2303
+ &elf64_df_stabs,
2304
+ elf_stdmac,
2305
+ elf_init,
2306
+ nasm_do_legacy_output,
2307
+ elf64_out,
2308
+ elf_deflabel,
2309
+ elf_section_names,
2310
+ elf_sectalign,
2311
+ elf_segbase,
2312
+ elf_directive,
2313
+ elf_filename,
2314
+ elf_cleanup,
2315
+ elf_pragma_list,
2316
+ };
2317
+
2318
+ static const struct dfmt elfx32_df_dwarf = {
2319
+ "ELFX32 (x86-64) dwarf debug format for Linux/Unix",
2320
+ "dwarf",
2321
+ dwarf_init,
2322
+ dwarf_linenum,
2323
+ null_debug_deflabel,
2324
+ null_debug_directive,
2325
+ debug_typevalue,
2326
+ dwarf_output,
2327
+ dwarf_cleanup,
2328
+ NULL /* pragma list */
2329
+ };
2330
+
2331
+ static const struct dfmt elfx32_df_stabs = {
2332
+ "ELFX32 (x86-64) stabs debug format for Linux/Unix",
2333
+ "stabs",
2334
+ null_debug_init,
2335
+ stabs_linenum,
2336
+ null_debug_deflabel,
2337
+ null_debug_directive,
2338
+ debug_typevalue,
2339
+ stabs_output,
2340
+ stabs_cleanup,
2341
+ elf_pragma_list,
2342
+ };
2343
+
2344
+ static const struct dfmt * const elfx32_debugs_arr[3] =
2345
+ { &elfx32_df_dwarf, &elfx32_df_stabs, NULL };
2346
+
2347
+ const struct ofmt of_elfx32 = {
2348
+ "ELFX32 (x86_64) object files (e.g. Linux)",
2349
+ "elfx32",
2350
+ 0,
2351
+ 64,
2352
+ elfx32_debugs_arr,
2353
+ &elfx32_df_stabs,
2354
+ elf_stdmac,
2355
+ elf_init,
2356
+ nasm_do_legacy_output,
2357
+ elfx32_out,
2358
+ elf_deflabel,
2359
+ elf_section_names,
2360
+ elf_sectalign,
2361
+ elf_segbase,
2362
+ elf_directive,
2363
+ elf_filename,
2364
+ elf_cleanup,
2365
+ NULL /* pragma list */
2366
+ };
2367
+
2368
+ static bool is_elf64(void)
2369
+ {
2370
+ return ofmt == &of_elf64;
2371
+ }
2372
+
2373
+ static bool is_elf32(void)
2374
+ {
2375
+ return ofmt == &of_elf32;
2376
+ }
2377
+
2378
+ static bool is_elfx32(void)
2379
+ {
2380
+ return ofmt == &of_elfx32;
2381
+ }
2382
+
2383
+ static bool dfmt_is_stabs(void)
2384
+ {
2385
+ return dfmt == &elf32_df_stabs ||
2386
+ dfmt == &elfx32_df_stabs ||
2387
+ dfmt == &elf64_df_stabs;
2388
+ }
2389
+
2390
+ static bool dfmt_is_dwarf(void)
2391
+ {
2392
+ return dfmt == &elf32_df_dwarf ||
2393
+ dfmt == &elfx32_df_dwarf ||
2394
+ dfmt == &elf64_df_dwarf;
2395
+ }
2396
+
2397
+ /* common debugging routines */
2398
+ static void debug_typevalue(int32_t type)
2399
+ {
2400
+ int32_t stype, ssize;
2401
+ switch (TYM_TYPE(type)) {
2402
+ case TY_LABEL:
2403
+ ssize = 0;
2404
+ stype = STT_NOTYPE;
2405
+ break;
2406
+ case TY_BYTE:
2407
+ ssize = 1;
2408
+ stype = STT_OBJECT;
2409
+ break;
2410
+ case TY_WORD:
2411
+ ssize = 2;
2412
+ stype = STT_OBJECT;
2413
+ break;
2414
+ case TY_DWORD:
2415
+ ssize = 4;
2416
+ stype = STT_OBJECT;
2417
+ break;
2418
+ case TY_FLOAT:
2419
+ ssize = 4;
2420
+ stype = STT_OBJECT;
2421
+ break;
2422
+ case TY_QWORD:
2423
+ ssize = 8;
2424
+ stype = STT_OBJECT;
2425
+ break;
2426
+ case TY_TBYTE:
2427
+ ssize = 10;
2428
+ stype = STT_OBJECT;
2429
+ break;
2430
+ case TY_OWORD:
2431
+ ssize = 16;
2432
+ stype = STT_OBJECT;
2433
+ break;
2434
+ case TY_YWORD:
2435
+ ssize = 32;
2436
+ stype = STT_OBJECT;
2437
+ break;
2438
+ case TY_ZWORD:
2439
+ ssize = 64;
2440
+ stype = STT_OBJECT;
2441
+ break;
2442
+ case TY_COMMON:
2443
+ ssize = 0;
2444
+ stype = STT_COMMON;
2445
+ break;
2446
+ case TY_SEG:
2447
+ ssize = 0;
2448
+ stype = STT_SECTION;
2449
+ break;
2450
+ case TY_EXTERN:
2451
+ ssize = 0;
2452
+ stype = STT_NOTYPE;
2453
+ break;
2454
+ case TY_EQU:
2455
+ ssize = 0;
2456
+ stype = STT_NOTYPE;
2457
+ break;
2458
+ default:
2459
+ ssize = 0;
2460
+ stype = STT_NOTYPE;
2461
+ break;
2462
+ }
2463
+ if (stype == STT_OBJECT && lastsym && !lastsym->type) {
2464
+ lastsym->size = ssize;
2465
+ lastsym->type = stype;
2466
+ }
2467
+ }
2468
+
2469
+ /* stabs debugging routines */
2470
+
2471
+ static void stabs_linenum(const char *filename, int32_t linenumber, int32_t segto)
2472
+ {
2473
+ (void)segto;
2474
+ if (!stabs_filename) {
2475
+ stabs_filename = nasm_malloc(strlen(filename) + 1);
2476
+ strcpy(stabs_filename, filename);
2477
+ } else {
2478
+ if (strcmp(stabs_filename, filename)) {
2479
+ /* yep, a memory leak...this program is one-shot anyway, so who cares...
2480
+ in fact, this leak comes in quite handy to maintain a list of files
2481
+ encountered so far in the symbol lines... */
2482
+
2483
+ /* why not nasm_free(stabs_filename); we're done with the old one */
2484
+
2485
+ stabs_filename = nasm_malloc(strlen(filename) + 1);
2486
+ strcpy(stabs_filename, filename);
2487
+ }
2488
+ }
2489
+ debug_immcall = 1;
2490
+ currentline = linenumber;
2491
+ }
2492
+
2493
+ static void stabs_output(int type, void *param)
2494
+ {
2495
+ struct symlininfo *s;
2496
+ struct linelist *el;
2497
+ if (type == TY_DEBUGSYMLIN) {
2498
+ if (debug_immcall) {
2499
+ s = (struct symlininfo *)param;
2500
+ if (!(sects[s->section]->flags & SHF_EXECINSTR))
2501
+ return; /* line info is only collected for executable sections */
2502
+ numlinestabs++;
2503
+ el = nasm_malloc(sizeof(struct linelist));
2504
+ el->info.offset = s->offset;
2505
+ el->info.section = s->section;
2506
+ el->info.name = s->name;
2507
+ el->line = currentline;
2508
+ el->filename = stabs_filename;
2509
+ el->next = 0;
2510
+ if (stabslines) {
2511
+ stabslines->last->next = el;
2512
+ stabslines->last = el;
2513
+ } else {
2514
+ stabslines = el;
2515
+ stabslines->last = el;
2516
+ }
2517
+ }
2518
+ }
2519
+ debug_immcall = 0;
2520
+ }
2521
+
2522
+ /* for creating the .stab , .stabstr and .rel.stab sections in memory */
2523
+
2524
+ static void stabs_generate(void)
2525
+ {
2526
+ int i, numfiles, strsize, numstabs = 0, currfile, mainfileindex;
2527
+ uint8_t *sbuf, *ssbuf, *rbuf, *sptr, *rptr;
2528
+ char **allfiles;
2529
+ int *fileidx;
2530
+
2531
+ struct linelist *ptr;
2532
+
2533
+ ptr = stabslines;
2534
+
2535
+ allfiles = nasm_zalloc(numlinestabs * sizeof(char *));
2536
+ numfiles = 0;
2537
+ while (ptr) {
2538
+ if (numfiles == 0) {
2539
+ allfiles[0] = ptr->filename;
2540
+ numfiles++;
2541
+ } else {
2542
+ for (i = 0; i < numfiles; i++) {
2543
+ if (!strcmp(allfiles[i], ptr->filename))
2544
+ break;
2545
+ }
2546
+ if (i >= numfiles) {
2547
+ allfiles[i] = ptr->filename;
2548
+ numfiles++;
2549
+ }
2550
+ }
2551
+ ptr = ptr->next;
2552
+ }
2553
+ strsize = 1;
2554
+ fileidx = nasm_malloc(numfiles * sizeof(int));
2555
+ for (i = 0; i < numfiles; i++) {
2556
+ fileidx[i] = strsize;
2557
+ strsize += strlen(allfiles[i]) + 1;
2558
+ }
2559
+ mainfileindex = 0;
2560
+ for (i = 0; i < numfiles; i++) {
2561
+ if (!strcmp(allfiles[i], elf_module)) {
2562
+ mainfileindex = i;
2563
+ break;
2564
+ }
2565
+ }
2566
+
2567
+ /*
2568
+ * worst case size of the stab buffer would be:
2569
+ * the sourcefiles changes each line, which would mean 1 SOL, 1 SYMLIN per line
2570
+ * plus one "ending" entry
2571
+ */
2572
+ sbuf = nasm_malloc((numlinestabs * 2 + 4) *
2573
+ sizeof(struct stabentry));
2574
+ ssbuf = nasm_malloc(strsize);
2575
+ rbuf = nasm_malloc(numlinestabs * (is_elf64() ? 16 : 8) * (2 + 3));
2576
+ rptr = rbuf;
2577
+
2578
+ for (i = 0; i < numfiles; i++)
2579
+ strcpy((char *)ssbuf + fileidx[i], allfiles[i]);
2580
+ ssbuf[0] = 0;
2581
+
2582
+ stabstrlen = strsize; /* set global variable for length of stab strings */
2583
+
2584
+ sptr = sbuf;
2585
+ ptr = stabslines;
2586
+ numstabs = 0;
2587
+
2588
+ if (ptr) {
2589
+ /*
2590
+ * this is the first stab, its strx points to the filename of the
2591
+ * the source-file, the n_desc field should be set to the number
2592
+ * of remaining stabs
2593
+ */
2594
+ WRITE_STAB(sptr, fileidx[0], 0, 0, 0, stabstrlen);
2595
+
2596
+ /* this is the stab for the main source file */
2597
+ WRITE_STAB(sptr, fileidx[mainfileindex], N_SO, 0, 0, 0);
2598
+
2599
+ /* relocation table entry */
2600
+
2601
+ /*
2602
+ * Since the symbol table has two entries before
2603
+ * the section symbols, the index in the info.section
2604
+ * member must be adjusted by adding 2
2605
+ */
2606
+
2607
+ if (is_elf32()) {
2608
+ WRITELONG(rptr, (sptr - sbuf) - 4);
2609
+ WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2610
+ } else if (is_elfx32()) {
2611
+ WRITELONG(rptr, (sptr - sbuf) - 4);
2612
+ WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2613
+ WRITELONG(rptr, 0);
2614
+ } else {
2615
+ nasm_assert(is_elf64());
2616
+ WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2617
+ WRITELONG(rptr, R_X86_64_32);
2618
+ WRITELONG(rptr, ptr->info.section + 2);
2619
+ WRITEDLONG(rptr, 0);
2620
+ }
2621
+ numstabs++;
2622
+ currfile = mainfileindex;
2623
+ }
2624
+
2625
+ if (is_elf32()) {
2626
+ while (ptr) {
2627
+ if (strcmp(allfiles[currfile], ptr->filename)) {
2628
+ /* oops file has changed... */
2629
+ for (i = 0; i < numfiles; i++)
2630
+ if (!strcmp(allfiles[i], ptr->filename))
2631
+ break;
2632
+ currfile = i;
2633
+ WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2634
+ ptr->info.offset);
2635
+ numstabs++;
2636
+
2637
+ /* relocation table entry */
2638
+ WRITELONG(rptr, (sptr - sbuf) - 4);
2639
+ WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2640
+ }
2641
+
2642
+ WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2643
+ numstabs++;
2644
+
2645
+ /* relocation table entry */
2646
+ WRITELONG(rptr, (sptr - sbuf) - 4);
2647
+ WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_386_32);
2648
+
2649
+ ptr = ptr->next;
2650
+ }
2651
+ } else if (is_elfx32()) {
2652
+ while (ptr) {
2653
+ if (strcmp(allfiles[currfile], ptr->filename)) {
2654
+ /* oops file has changed... */
2655
+ for (i = 0; i < numfiles; i++)
2656
+ if (!strcmp(allfiles[i], ptr->filename))
2657
+ break;
2658
+ currfile = i;
2659
+ WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2660
+ ptr->info.offset);
2661
+ numstabs++;
2662
+
2663
+ /* relocation table entry */
2664
+ WRITELONG(rptr, (sptr - sbuf) - 4);
2665
+ WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2666
+ WRITELONG(rptr, ptr->info.offset);
2667
+ }
2668
+
2669
+ WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2670
+ numstabs++;
2671
+
2672
+ /* relocation table entry */
2673
+ WRITELONG(rptr, (sptr - sbuf) - 4);
2674
+ WRITELONG(rptr, ((ptr->info.section + 2) << 8) | R_X86_64_32);
2675
+ WRITELONG(rptr, ptr->info.offset);
2676
+
2677
+ ptr = ptr->next;
2678
+ }
2679
+ } else {
2680
+ nasm_assert(is_elf64());
2681
+ while (ptr) {
2682
+ if (strcmp(allfiles[currfile], ptr->filename)) {
2683
+ /* oops file has changed... */
2684
+ for (i = 0; i < numfiles; i++)
2685
+ if (!strcmp(allfiles[i], ptr->filename))
2686
+ break;
2687
+ currfile = i;
2688
+ WRITE_STAB(sptr, fileidx[currfile], N_SOL, 0, 0,
2689
+ ptr->info.offset);
2690
+ numstabs++;
2691
+
2692
+ /* relocation table entry */
2693
+ WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2694
+ WRITELONG(rptr, R_X86_64_32);
2695
+ WRITELONG(rptr, ptr->info.section + 2);
2696
+ WRITEDLONG(rptr, ptr->info.offset);
2697
+ }
2698
+
2699
+ WRITE_STAB(sptr, 0, N_SLINE, 0, ptr->line, ptr->info.offset);
2700
+ numstabs++;
2701
+
2702
+ /* relocation table entry */
2703
+ WRITEDLONG(rptr, (int64_t)(sptr - sbuf) - 4);
2704
+ WRITELONG(rptr, R_X86_64_32);
2705
+ WRITELONG(rptr, ptr->info.section + 2);
2706
+ WRITEDLONG(rptr, ptr->info.offset);
2707
+
2708
+ ptr = ptr->next;
2709
+ }
2710
+ }
2711
+
2712
+ /* this is an "ending" token */
2713
+ WRITE_STAB(sptr, 0, N_SO, 0, 0, 0);
2714
+ numstabs++;
2715
+
2716
+ ((struct stabentry *)sbuf)->n_desc = numstabs;
2717
+
2718
+ nasm_free(allfiles);
2719
+ nasm_free(fileidx);
2720
+
2721
+ stablen = (sptr - sbuf);
2722
+ stabrellen = (rptr - rbuf);
2723
+ stabrelbuf = rbuf;
2724
+ stabbuf = sbuf;
2725
+ stabstrbuf = ssbuf;
2726
+ }
2727
+
2728
+ static void stabs_cleanup(void)
2729
+ {
2730
+ struct linelist *ptr, *del;
2731
+ if (!stabslines)
2732
+ return;
2733
+
2734
+ ptr = stabslines;
2735
+ while (ptr) {
2736
+ del = ptr;
2737
+ ptr = ptr->next;
2738
+ nasm_free(del);
2739
+ }
2740
+
2741
+ nasm_free(stabbuf);
2742
+ nasm_free(stabrelbuf);
2743
+ nasm_free(stabstrbuf);
2744
+ }
2745
+
2746
+ /* dwarf routines */
2747
+
2748
+ static void dwarf_init(void)
2749
+ {
2750
+ ndebugs = 3; /* 3 debug symbols */
2751
+ }
2752
+
2753
+ static void dwarf_linenum(const char *filename, int32_t linenumber,
2754
+ int32_t segto)
2755
+ {
2756
+ (void)segto;
2757
+ dwarf_findfile(filename);
2758
+ debug_immcall = 1;
2759
+ currentline = linenumber;
2760
+ }
2761
+
2762
+ /* called from elf_out with type == TY_DEBUGSYMLIN */
2763
+ static void dwarf_output(int type, void *param)
2764
+ {
2765
+ int ln, aa, inx, maxln, soc;
2766
+ struct symlininfo *s;
2767
+ struct SAA *plinep;
2768
+
2769
+ (void)type;
2770
+
2771
+ s = (struct symlininfo *)param;
2772
+
2773
+ /* line number info is only gathered for executable sections */
2774
+ if (!(sects[s->section]->flags & SHF_EXECINSTR))
2775
+ return;
2776
+
2777
+ /* Check if section index has changed */
2778
+ if (!(dwarf_csect && (dwarf_csect->section) == (s->section)))
2779
+ dwarf_findsect(s->section);
2780
+
2781
+ /* do nothing unless line or file has changed */
2782
+ if (!debug_immcall)
2783
+ return;
2784
+
2785
+ ln = currentline - dwarf_csect->line;
2786
+ aa = s->offset - dwarf_csect->offset;
2787
+ inx = dwarf_clist->line;
2788
+ plinep = dwarf_csect->psaa;
2789
+ /* check for file change */
2790
+ if (!(inx == dwarf_csect->file)) {
2791
+ saa_write8(plinep,DW_LNS_set_file);
2792
+ saa_write8(plinep,inx);
2793
+ dwarf_csect->file = inx;
2794
+ }
2795
+ /* check for line change */
2796
+ if (ln) {
2797
+ /* test if in range of special op code */
2798
+ maxln = line_base + line_range;
2799
+ soc = (ln - line_base) + (line_range * aa) + opcode_base;
2800
+ if (ln >= line_base && ln < maxln && soc < 256) {
2801
+ saa_write8(plinep,soc);
2802
+ } else {
2803
+ saa_write8(plinep,DW_LNS_advance_line);
2804
+ saa_wleb128s(plinep,ln);
2805
+ if (aa) {
2806
+ saa_write8(plinep,DW_LNS_advance_pc);
2807
+ saa_wleb128u(plinep,aa);
2808
+ }
2809
+ saa_write8(plinep,DW_LNS_copy);
2810
+ }
2811
+ dwarf_csect->line = currentline;
2812
+ dwarf_csect->offset = s->offset;
2813
+ }
2814
+
2815
+ /* show change handled */
2816
+ debug_immcall = 0;
2817
+ }
2818
+
2819
+
2820
+ static void dwarf_generate(void)
2821
+ {
2822
+ uint8_t *pbuf;
2823
+ int indx;
2824
+ struct linelist *ftentry;
2825
+ struct SAA *paranges, *ppubnames, *pinfo, *pabbrev, *plines, *plinep;
2826
+ struct SAA *parangesrel, *plinesrel, *pinforel;
2827
+ struct sectlist *psect;
2828
+ size_t saalen, linepoff, totlen, highaddr;
2829
+
2830
+ if (is_elf32()) {
2831
+ /* write epilogues for each line program range */
2832
+ /* and build aranges section */
2833
+ paranges = saa_init(1L);
2834
+ parangesrel = saa_init(1L);
2835
+ saa_write16(paranges,2); /* dwarf version */
2836
+ saa_write32(parangesrel, paranges->datalen+4);
2837
+ saa_write32(parangesrel, (dwarf_infosym << 8) + R_386_32); /* reloc to info */
2838
+ saa_write32(parangesrel, 0);
2839
+ saa_write32(paranges,0); /* offset into info */
2840
+ saa_write8(paranges,4); /* pointer size */
2841
+ saa_write8(paranges,0); /* not segmented */
2842
+ saa_write32(paranges,0); /* padding */
2843
+ /* iterate though sectlist entries */
2844
+ psect = dwarf_fsect;
2845
+ totlen = 0;
2846
+ highaddr = 0;
2847
+ for (indx = 0; indx < dwarf_nsections; indx++) {
2848
+ plinep = psect->psaa;
2849
+ /* Line Number Program Epilogue */
2850
+ saa_write8(plinep,2); /* std op 2 */
2851
+ saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
2852
+ saa_write8(plinep,DW_LNS_extended_op);
2853
+ saa_write8(plinep,1); /* operand length */
2854
+ saa_write8(plinep,DW_LNE_end_sequence);
2855
+ totlen += plinep->datalen;
2856
+ /* range table relocation entry */
2857
+ saa_write32(parangesrel, paranges->datalen + 4);
2858
+ saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
2859
+ saa_write32(parangesrel, (uint32_t) 0);
2860
+ /* range table entry */
2861
+ saa_write32(paranges,0x0000); /* range start */
2862
+ saa_write32(paranges,sects[psect->section]->len); /* range length */
2863
+ highaddr += sects[psect->section]->len;
2864
+ /* done with this entry */
2865
+ psect = psect->next;
2866
+ }
2867
+ saa_write32(paranges,0); /* null address */
2868
+ saa_write32(paranges,0); /* null length */
2869
+ saalen = paranges->datalen;
2870
+ arangeslen = saalen + 4;
2871
+ arangesbuf = pbuf = nasm_malloc(arangeslen);
2872
+ WRITELONG(pbuf,saalen); /* initial length */
2873
+ saa_rnbytes(paranges, pbuf, saalen);
2874
+ saa_free(paranges);
2875
+ } else if (is_elfx32()) {
2876
+ /* write epilogues for each line program range */
2877
+ /* and build aranges section */
2878
+ paranges = saa_init(1L);
2879
+ parangesrel = saa_init(1L);
2880
+ saa_write16(paranges,3); /* dwarf version */
2881
+ saa_write32(parangesrel, paranges->datalen+4);
2882
+ saa_write32(parangesrel, (dwarf_infosym << 8) + R_X86_64_32); /* reloc to info */
2883
+ saa_write32(parangesrel, 0);
2884
+ saa_write32(paranges,0); /* offset into info */
2885
+ saa_write8(paranges,4); /* pointer size */
2886
+ saa_write8(paranges,0); /* not segmented */
2887
+ saa_write32(paranges,0); /* padding */
2888
+ /* iterate though sectlist entries */
2889
+ psect = dwarf_fsect;
2890
+ totlen = 0;
2891
+ highaddr = 0;
2892
+ for (indx = 0; indx < dwarf_nsections; indx++) {
2893
+ plinep = psect->psaa;
2894
+ /* Line Number Program Epilogue */
2895
+ saa_write8(plinep,2); /* std op 2 */
2896
+ saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
2897
+ saa_write8(plinep,DW_LNS_extended_op);
2898
+ saa_write8(plinep,1); /* operand length */
2899
+ saa_write8(plinep,DW_LNE_end_sequence);
2900
+ totlen += plinep->datalen;
2901
+ /* range table relocation entry */
2902
+ saa_write32(parangesrel, paranges->datalen + 4);
2903
+ saa_write32(parangesrel, ((uint32_t) (psect->section + 2) << 8) + R_X86_64_32);
2904
+ saa_write32(parangesrel, (uint32_t) 0);
2905
+ /* range table entry */
2906
+ saa_write32(paranges,0x0000); /* range start */
2907
+ saa_write32(paranges,sects[psect->section]->len); /* range length */
2908
+ highaddr += sects[psect->section]->len;
2909
+ /* done with this entry */
2910
+ psect = psect->next;
2911
+ }
2912
+ saa_write32(paranges,0); /* null address */
2913
+ saa_write32(paranges,0); /* null length */
2914
+ saalen = paranges->datalen;
2915
+ arangeslen = saalen + 4;
2916
+ arangesbuf = pbuf = nasm_malloc(arangeslen);
2917
+ WRITELONG(pbuf,saalen); /* initial length */
2918
+ saa_rnbytes(paranges, pbuf, saalen);
2919
+ saa_free(paranges);
2920
+ } else {
2921
+ nasm_assert(is_elf64());
2922
+ /* write epilogues for each line program range */
2923
+ /* and build aranges section */
2924
+ paranges = saa_init(1L);
2925
+ parangesrel = saa_init(1L);
2926
+ saa_write16(paranges,3); /* dwarf version */
2927
+ saa_write64(parangesrel, paranges->datalen+4);
2928
+ saa_write64(parangesrel, (dwarf_infosym << 32) + R_X86_64_32); /* reloc to info */
2929
+ saa_write64(parangesrel, 0);
2930
+ saa_write32(paranges,0); /* offset into info */
2931
+ saa_write8(paranges,8); /* pointer size */
2932
+ saa_write8(paranges,0); /* not segmented */
2933
+ saa_write32(paranges,0); /* padding */
2934
+ /* iterate though sectlist entries */
2935
+ psect = dwarf_fsect;
2936
+ totlen = 0;
2937
+ highaddr = 0;
2938
+ for (indx = 0; indx < dwarf_nsections; indx++) {
2939
+ plinep = psect->psaa;
2940
+ /* Line Number Program Epilogue */
2941
+ saa_write8(plinep,2); /* std op 2 */
2942
+ saa_write8(plinep,(sects[psect->section]->len)-psect->offset);
2943
+ saa_write8(plinep,DW_LNS_extended_op);
2944
+ saa_write8(plinep,1); /* operand length */
2945
+ saa_write8(plinep,DW_LNE_end_sequence);
2946
+ totlen += plinep->datalen;
2947
+ /* range table relocation entry */
2948
+ saa_write64(parangesrel, paranges->datalen + 4);
2949
+ saa_write64(parangesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
2950
+ saa_write64(parangesrel, (uint64_t) 0);
2951
+ /* range table entry */
2952
+ saa_write64(paranges,0x0000); /* range start */
2953
+ saa_write64(paranges,sects[psect->section]->len); /* range length */
2954
+ highaddr += sects[psect->section]->len;
2955
+ /* done with this entry */
2956
+ psect = psect->next;
2957
+ }
2958
+ saa_write64(paranges,0); /* null address */
2959
+ saa_write64(paranges,0); /* null length */
2960
+ saalen = paranges->datalen;
2961
+ arangeslen = saalen + 4;
2962
+ arangesbuf = pbuf = nasm_malloc(arangeslen);
2963
+ WRITELONG(pbuf,saalen); /* initial length */
2964
+ saa_rnbytes(paranges, pbuf, saalen);
2965
+ saa_free(paranges);
2966
+ }
2967
+
2968
+ /* build rela.aranges section */
2969
+ arangesrellen = saalen = parangesrel->datalen;
2970
+ arangesrelbuf = pbuf = nasm_malloc(arangesrellen);
2971
+ saa_rnbytes(parangesrel, pbuf, saalen);
2972
+ saa_free(parangesrel);
2973
+
2974
+ /* build pubnames section */
2975
+ ppubnames = saa_init(1L);
2976
+ saa_write16(ppubnames,3); /* dwarf version */
2977
+ saa_write32(ppubnames,0); /* offset into info */
2978
+ saa_write32(ppubnames,0); /* space used in info */
2979
+ saa_write32(ppubnames,0); /* end of list */
2980
+ saalen = ppubnames->datalen;
2981
+ pubnameslen = saalen + 4;
2982
+ pubnamesbuf = pbuf = nasm_malloc(pubnameslen);
2983
+ WRITELONG(pbuf,saalen); /* initial length */
2984
+ saa_rnbytes(ppubnames, pbuf, saalen);
2985
+ saa_free(ppubnames);
2986
+
2987
+ if (is_elf32()) {
2988
+ /* build info section */
2989
+ pinfo = saa_init(1L);
2990
+ pinforel = saa_init(1L);
2991
+ saa_write16(pinfo,2); /* dwarf version */
2992
+ saa_write32(pinforel, pinfo->datalen + 4);
2993
+ saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_386_32); /* reloc to abbrev */
2994
+ saa_write32(pinforel, 0);
2995
+ saa_write32(pinfo,0); /* offset into abbrev */
2996
+ saa_write8(pinfo,4); /* pointer size */
2997
+ saa_write8(pinfo,1); /* abbrviation number LEB128u */
2998
+ saa_write32(pinforel, pinfo->datalen + 4);
2999
+ saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3000
+ saa_write32(pinforel, 0);
3001
+ saa_write32(pinfo,0); /* DW_AT_low_pc */
3002
+ saa_write32(pinforel, pinfo->datalen + 4);
3003
+ saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3004
+ saa_write32(pinforel, 0);
3005
+ saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
3006
+ saa_write32(pinforel, pinfo->datalen + 4);
3007
+ saa_write32(pinforel, (dwarf_linesym << 8) + R_386_32); /* reloc to line */
3008
+ saa_write32(pinforel, 0);
3009
+ saa_write32(pinfo,0); /* DW_AT_stmt_list */
3010
+ saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3011
+ saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
3012
+ saa_write16(pinfo,DW_LANG_Mips_Assembler);
3013
+ saa_write8(pinfo,2); /* abbrviation number LEB128u */
3014
+ saa_write32(pinforel, pinfo->datalen + 4);
3015
+ saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_386_32);
3016
+ saa_write32(pinforel, 0);
3017
+ saa_write32(pinfo,0); /* DW_AT_low_pc */
3018
+ saa_write32(pinfo,0); /* DW_AT_frame_base */
3019
+ saa_write8(pinfo,0); /* end of entries */
3020
+ saalen = pinfo->datalen;
3021
+ infolen = saalen + 4;
3022
+ infobuf = pbuf = nasm_malloc(infolen);
3023
+ WRITELONG(pbuf,saalen); /* initial length */
3024
+ saa_rnbytes(pinfo, pbuf, saalen);
3025
+ saa_free(pinfo);
3026
+ } else if (is_elfx32()) {
3027
+ /* build info section */
3028
+ pinfo = saa_init(1L);
3029
+ pinforel = saa_init(1L);
3030
+ saa_write16(pinfo,3); /* dwarf version */
3031
+ saa_write32(pinforel, pinfo->datalen + 4);
3032
+ saa_write32(pinforel, (dwarf_abbrevsym << 8) + R_X86_64_32); /* reloc to abbrev */
3033
+ saa_write32(pinforel, 0);
3034
+ saa_write32(pinfo,0); /* offset into abbrev */
3035
+ saa_write8(pinfo,4); /* pointer size */
3036
+ saa_write8(pinfo,1); /* abbrviation number LEB128u */
3037
+ saa_write32(pinforel, pinfo->datalen + 4);
3038
+ saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3039
+ saa_write32(pinforel, 0);
3040
+ saa_write32(pinfo,0); /* DW_AT_low_pc */
3041
+ saa_write32(pinforel, pinfo->datalen + 4);
3042
+ saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3043
+ saa_write32(pinforel, 0);
3044
+ saa_write32(pinfo,highaddr); /* DW_AT_high_pc */
3045
+ saa_write32(pinforel, pinfo->datalen + 4);
3046
+ saa_write32(pinforel, (dwarf_linesym << 8) + R_X86_64_32); /* reloc to line */
3047
+ saa_write32(pinforel, 0);
3048
+ saa_write32(pinfo,0); /* DW_AT_stmt_list */
3049
+ saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3050
+ saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
3051
+ saa_write16(pinfo,DW_LANG_Mips_Assembler);
3052
+ saa_write8(pinfo,2); /* abbrviation number LEB128u */
3053
+ saa_write32(pinforel, pinfo->datalen + 4);
3054
+ saa_write32(pinforel, ((dwarf_fsect->section + 2) << 8) + R_X86_64_32);
3055
+ saa_write32(pinforel, 0);
3056
+ saa_write32(pinfo,0); /* DW_AT_low_pc */
3057
+ saa_write32(pinfo,0); /* DW_AT_frame_base */
3058
+ saa_write8(pinfo,0); /* end of entries */
3059
+ saalen = pinfo->datalen;
3060
+ infolen = saalen + 4;
3061
+ infobuf = pbuf = nasm_malloc(infolen);
3062
+ WRITELONG(pbuf,saalen); /* initial length */
3063
+ saa_rnbytes(pinfo, pbuf, saalen);
3064
+ saa_free(pinfo);
3065
+ } else {
3066
+ nasm_assert(is_elf64());
3067
+ /* build info section */
3068
+ pinfo = saa_init(1L);
3069
+ pinforel = saa_init(1L);
3070
+ saa_write16(pinfo,3); /* dwarf version */
3071
+ saa_write64(pinforel, pinfo->datalen + 4);
3072
+ saa_write64(pinforel, (dwarf_abbrevsym << 32) + R_X86_64_32); /* reloc to abbrev */
3073
+ saa_write64(pinforel, 0);
3074
+ saa_write32(pinfo,0); /* offset into abbrev */
3075
+ saa_write8(pinfo,8); /* pointer size */
3076
+ saa_write8(pinfo,1); /* abbrviation number LEB128u */
3077
+ saa_write64(pinforel, pinfo->datalen + 4);
3078
+ saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3079
+ saa_write64(pinforel, 0);
3080
+ saa_write64(pinfo,0); /* DW_AT_low_pc */
3081
+ saa_write64(pinforel, pinfo->datalen + 4);
3082
+ saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3083
+ saa_write64(pinforel, 0);
3084
+ saa_write64(pinfo,highaddr); /* DW_AT_high_pc */
3085
+ saa_write64(pinforel, pinfo->datalen + 4);
3086
+ saa_write64(pinforel, (dwarf_linesym << 32) + R_X86_64_32); /* reloc to line */
3087
+ saa_write64(pinforel, 0);
3088
+ saa_write32(pinfo,0); /* DW_AT_stmt_list */
3089
+ saa_wbytes(pinfo, elf_module, strlen(elf_module)+1);
3090
+ saa_wbytes(pinfo, nasm_signature, strlen(nasm_signature)+1);
3091
+ saa_write16(pinfo,DW_LANG_Mips_Assembler);
3092
+ saa_write8(pinfo,2); /* abbrviation number LEB128u */
3093
+ saa_write64(pinforel, pinfo->datalen + 4);
3094
+ saa_write64(pinforel, ((uint64_t)(dwarf_fsect->section + 2) << 32) + R_X86_64_64);
3095
+ saa_write64(pinforel, 0);
3096
+ saa_write64(pinfo,0); /* DW_AT_low_pc */
3097
+ saa_write64(pinfo,0); /* DW_AT_frame_base */
3098
+ saa_write8(pinfo,0); /* end of entries */
3099
+ saalen = pinfo->datalen;
3100
+ infolen = saalen + 4;
3101
+ infobuf = pbuf = nasm_malloc(infolen);
3102
+ WRITELONG(pbuf,saalen); /* initial length */
3103
+ saa_rnbytes(pinfo, pbuf, saalen);
3104
+ saa_free(pinfo);
3105
+ }
3106
+
3107
+ /* build rela.info section */
3108
+ inforellen = saalen = pinforel->datalen;
3109
+ inforelbuf = pbuf = nasm_malloc(inforellen);
3110
+ saa_rnbytes(pinforel, pbuf, saalen);
3111
+ saa_free(pinforel);
3112
+
3113
+ /* build abbrev section */
3114
+ pabbrev = saa_init(1L);
3115
+ saa_write8(pabbrev,1); /* entry number LEB128u */
3116
+ saa_write8(pabbrev,DW_TAG_compile_unit); /* tag LEB128u */
3117
+ saa_write8(pabbrev,1); /* has children */
3118
+ /* the following attributes and forms are all LEB128u values */
3119
+ saa_write8(pabbrev,DW_AT_low_pc);
3120
+ saa_write8(pabbrev,DW_FORM_addr);
3121
+ saa_write8(pabbrev,DW_AT_high_pc);
3122
+ saa_write8(pabbrev,DW_FORM_addr);
3123
+ saa_write8(pabbrev,DW_AT_stmt_list);
3124
+ saa_write8(pabbrev,DW_FORM_data4);
3125
+ saa_write8(pabbrev,DW_AT_name);
3126
+ saa_write8(pabbrev,DW_FORM_string);
3127
+ saa_write8(pabbrev,DW_AT_producer);
3128
+ saa_write8(pabbrev,DW_FORM_string);
3129
+ saa_write8(pabbrev,DW_AT_language);
3130
+ saa_write8(pabbrev,DW_FORM_data2);
3131
+ saa_write16(pabbrev,0); /* end of entry */
3132
+ /* LEB128u usage same as above */
3133
+ saa_write8(pabbrev,2); /* entry number */
3134
+ saa_write8(pabbrev,DW_TAG_subprogram);
3135
+ saa_write8(pabbrev,0); /* no children */
3136
+ saa_write8(pabbrev,DW_AT_low_pc);
3137
+ saa_write8(pabbrev,DW_FORM_addr);
3138
+ saa_write8(pabbrev,DW_AT_frame_base);
3139
+ saa_write8(pabbrev,DW_FORM_data4);
3140
+ saa_write16(pabbrev,0); /* end of entry */
3141
+ /* Terminal zero entry */
3142
+ saa_write8(pabbrev,0);
3143
+ abbrevlen = saalen = pabbrev->datalen;
3144
+ abbrevbuf = pbuf = nasm_malloc(saalen);
3145
+ saa_rnbytes(pabbrev, pbuf, saalen);
3146
+ saa_free(pabbrev);
3147
+
3148
+ /* build line section */
3149
+ /* prolog */
3150
+ plines = saa_init(1L);
3151
+ saa_write8(plines,1); /* Minimum Instruction Length */
3152
+ saa_write8(plines,1); /* Initial value of 'is_stmt' */
3153
+ saa_write8(plines,line_base); /* Line Base */
3154
+ saa_write8(plines,line_range); /* Line Range */
3155
+ saa_write8(plines,opcode_base); /* Opcode Base */
3156
+ /* standard opcode lengths (# of LEB128u operands) */
3157
+ saa_write8(plines,0); /* Std opcode 1 length */
3158
+ saa_write8(plines,1); /* Std opcode 2 length */
3159
+ saa_write8(plines,1); /* Std opcode 3 length */
3160
+ saa_write8(plines,1); /* Std opcode 4 length */
3161
+ saa_write8(plines,1); /* Std opcode 5 length */
3162
+ saa_write8(plines,0); /* Std opcode 6 length */
3163
+ saa_write8(plines,0); /* Std opcode 7 length */
3164
+ saa_write8(plines,0); /* Std opcode 8 length */
3165
+ saa_write8(plines,1); /* Std opcode 9 length */
3166
+ saa_write8(plines,0); /* Std opcode 10 length */
3167
+ saa_write8(plines,0); /* Std opcode 11 length */
3168
+ saa_write8(plines,1); /* Std opcode 12 length */
3169
+ /* Directory Table */
3170
+ saa_write8(plines,0); /* End of table */
3171
+ /* File Name Table */
3172
+ ftentry = dwarf_flist;
3173
+ for (indx = 0; indx < dwarf_numfiles; indx++) {
3174
+ saa_wbytes(plines, ftentry->filename, (int32_t)(strlen(ftentry->filename) + 1));
3175
+ saa_write8(plines,0); /* directory LEB128u */
3176
+ saa_write8(plines,0); /* time LEB128u */
3177
+ saa_write8(plines,0); /* size LEB128u */
3178
+ ftentry = ftentry->next;
3179
+ }
3180
+ saa_write8(plines,0); /* End of table */
3181
+ linepoff = plines->datalen;
3182
+ linelen = linepoff + totlen + 10;
3183
+ linebuf = pbuf = nasm_malloc(linelen);
3184
+ WRITELONG(pbuf,linelen-4); /* initial length */
3185
+ WRITESHORT(pbuf,3); /* dwarf version */
3186
+ WRITELONG(pbuf,linepoff); /* offset to line number program */
3187
+ /* write line header */
3188
+ saalen = linepoff;
3189
+ saa_rnbytes(plines, pbuf, saalen); /* read a given no. of bytes */
3190
+ pbuf += linepoff;
3191
+ saa_free(plines);
3192
+ /* concatonate line program ranges */
3193
+ linepoff += 13;
3194
+ plinesrel = saa_init(1L);
3195
+ psect = dwarf_fsect;
3196
+ if (is_elf32()) {
3197
+ for (indx = 0; indx < dwarf_nsections; indx++) {
3198
+ saa_write32(plinesrel, linepoff);
3199
+ saa_write32(plinesrel, ((uint32_t) (psect->section + 2) << 8) + R_386_32);
3200
+ saa_write32(plinesrel, (uint32_t) 0);
3201
+ plinep = psect->psaa;
3202
+ saalen = plinep->datalen;
3203
+ saa_rnbytes(plinep, pbuf, saalen);
3204
+ pbuf += saalen;
3205
+ linepoff += saalen;
3206
+ saa_free(plinep);
3207
+ /* done with this entry */
3208
+ psect = psect->next;
3209
+ }
3210
+ } else if (is_elfx32()) {
3211
+ for (indx = 0; indx < dwarf_nsections; indx++) {
3212
+ saa_write32(plinesrel, linepoff);
3213
+ saa_write32(plinesrel, ((psect->section + 2) << 8) + R_X86_64_32);
3214
+ saa_write32(plinesrel, 0);
3215
+ plinep = psect->psaa;
3216
+ saalen = plinep->datalen;
3217
+ saa_rnbytes(plinep, pbuf, saalen);
3218
+ pbuf += saalen;
3219
+ linepoff += saalen;
3220
+ saa_free(plinep);
3221
+ /* done with this entry */
3222
+ psect = psect->next;
3223
+ }
3224
+ } else {
3225
+ nasm_assert(is_elf64());
3226
+ for (indx = 0; indx < dwarf_nsections; indx++) {
3227
+ saa_write64(plinesrel, linepoff);
3228
+ saa_write64(plinesrel, ((uint64_t) (psect->section + 2) << 32) + R_X86_64_64);
3229
+ saa_write64(plinesrel, (uint64_t) 0);
3230
+ plinep = psect->psaa;
3231
+ saalen = plinep->datalen;
3232
+ saa_rnbytes(plinep, pbuf, saalen);
3233
+ pbuf += saalen;
3234
+ linepoff += saalen;
3235
+ saa_free(plinep);
3236
+ /* done with this entry */
3237
+ psect = psect->next;
3238
+ }
3239
+ }
3240
+
3241
+ /* build rela.lines section */
3242
+ linerellen =saalen = plinesrel->datalen;
3243
+ linerelbuf = pbuf = nasm_malloc(linerellen);
3244
+ saa_rnbytes(plinesrel, pbuf, saalen);
3245
+ saa_free(plinesrel);
3246
+
3247
+ /* build frame section */
3248
+ framelen = 4;
3249
+ framebuf = pbuf = nasm_malloc(framelen);
3250
+ WRITELONG(pbuf,framelen-4); /* initial length */
3251
+
3252
+ /* build loc section */
3253
+ loclen = 16;
3254
+ locbuf = pbuf = nasm_malloc(loclen);
3255
+ if (is_elf32()) {
3256
+ WRITELONG(pbuf,0); /* null beginning offset */
3257
+ WRITELONG(pbuf,0); /* null ending offset */
3258
+ } else if (is_elfx32()) {
3259
+ WRITELONG(pbuf,0); /* null beginning offset */
3260
+ WRITELONG(pbuf,0); /* null ending offset */
3261
+ } else {
3262
+ nasm_assert(is_elf64());
3263
+ WRITEDLONG(pbuf,0); /* null beginning offset */
3264
+ WRITEDLONG(pbuf,0); /* null ending offset */
3265
+ }
3266
+ }
3267
+
3268
+ static void dwarf_cleanup(void)
3269
+ {
3270
+ nasm_free(arangesbuf);
3271
+ nasm_free(arangesrelbuf);
3272
+ nasm_free(pubnamesbuf);
3273
+ nasm_free(infobuf);
3274
+ nasm_free(inforelbuf);
3275
+ nasm_free(abbrevbuf);
3276
+ nasm_free(linebuf);
3277
+ nasm_free(linerelbuf);
3278
+ nasm_free(framebuf);
3279
+ nasm_free(locbuf);
3280
+ }
3281
+
3282
+ static void dwarf_findfile(const char * fname)
3283
+ {
3284
+ int finx;
3285
+ struct linelist *match;
3286
+
3287
+ /* return if fname is current file name */
3288
+ if (dwarf_clist && !(strcmp(fname, dwarf_clist->filename)))
3289
+ return;
3290
+
3291
+ /* search for match */
3292
+ match = 0;
3293
+ if (dwarf_flist) {
3294
+ match = dwarf_flist;
3295
+ for (finx = 0; finx < dwarf_numfiles; finx++) {
3296
+ if (!(strcmp(fname, match->filename))) {
3297
+ dwarf_clist = match;
3298
+ return;
3299
+ }
3300
+ match = match->next;
3301
+ }
3302
+ }
3303
+
3304
+ /* add file name to end of list */
3305
+ dwarf_clist = nasm_malloc(sizeof(struct linelist));
3306
+ dwarf_numfiles++;
3307
+ dwarf_clist->line = dwarf_numfiles;
3308
+ dwarf_clist->filename = nasm_malloc(strlen(fname) + 1);
3309
+ strcpy(dwarf_clist->filename,fname);
3310
+ dwarf_clist->next = 0;
3311
+ if (!dwarf_flist) { /* if first entry */
3312
+ dwarf_flist = dwarf_elist = dwarf_clist;
3313
+ dwarf_clist->last = 0;
3314
+ } else { /* chain to previous entry */
3315
+ dwarf_elist->next = dwarf_clist;
3316
+ dwarf_elist = dwarf_clist;
3317
+ }
3318
+ }
3319
+
3320
+ static void dwarf_findsect(const int index)
3321
+ {
3322
+ int sinx;
3323
+ struct sectlist *match;
3324
+ struct SAA *plinep;
3325
+
3326
+ /* return if index is current section index */
3327
+ if (dwarf_csect && (dwarf_csect->section == index))
3328
+ return;
3329
+
3330
+ /* search for match */
3331
+ match = 0;
3332
+ if (dwarf_fsect) {
3333
+ match = dwarf_fsect;
3334
+ for (sinx = 0; sinx < dwarf_nsections; sinx++) {
3335
+ if (match->section == index) {
3336
+ dwarf_csect = match;
3337
+ return;
3338
+ }
3339
+ match = match->next;
3340
+ }
3341
+ }
3342
+
3343
+ /* add entry to end of list */
3344
+ dwarf_csect = nasm_malloc(sizeof(struct sectlist));
3345
+ dwarf_nsections++;
3346
+ dwarf_csect->psaa = plinep = saa_init(1L);
3347
+ dwarf_csect->line = 1;
3348
+ dwarf_csect->offset = 0;
3349
+ dwarf_csect->file = 1;
3350
+ dwarf_csect->section = index;
3351
+ dwarf_csect->next = 0;
3352
+ /* set relocatable address at start of line program */
3353
+ saa_write8(plinep,DW_LNS_extended_op);
3354
+ saa_write8(plinep,is_elf64() ? 9 : 5); /* operand length */
3355
+ saa_write8(plinep,DW_LNE_set_address);
3356
+ if (is_elf64())
3357
+ saa_write64(plinep,0); /* Start Address */
3358
+ else
3359
+ saa_write32(plinep,0); /* Start Address */
3360
+
3361
+ if (!dwarf_fsect) { /* if first entry */
3362
+ dwarf_fsect = dwarf_esect = dwarf_csect;
3363
+ dwarf_csect->last = 0;
3364
+ } else { /* chain to previous entry */
3365
+ dwarf_esect->next = dwarf_csect;
3366
+ dwarf_esect = dwarf_csect;
3367
+ }
3368
+ }
3369
+
3370
+ #endif /* defined(OF_ELF32) || defined(OF_ELF64) || defined(OF_ELFX32) */