libv8-freebsd 3.3.10.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (703) hide show
  1. data/.gitignore +9 -0
  2. data/.gitmodules +3 -0
  3. data/Gemfile +4 -0
  4. data/README.md +75 -0
  5. data/Rakefile +115 -0
  6. data/ext/libv8/extconf.rb +27 -0
  7. data/lib/libv8.rb +15 -0
  8. data/lib/libv8/Makefile +39 -0
  9. data/lib/libv8/detect_cpu.rb +27 -0
  10. data/lib/libv8/fpic-on-freebsd-amd64.patch +16 -0
  11. data/lib/libv8/fpic-on-linux-amd64.patch +13 -0
  12. data/lib/libv8/scons/CHANGES.txt +5541 -0
  13. data/lib/libv8/scons/LICENSE.txt +20 -0
  14. data/lib/libv8/scons/MANIFEST +200 -0
  15. data/lib/libv8/scons/PKG-INFO +13 -0
  16. data/lib/libv8/scons/README.txt +243 -0
  17. data/lib/libv8/scons/RELEASE.txt +100 -0
  18. data/lib/libv8/scons/engine/SCons/Action.py +1257 -0
  19. data/lib/libv8/scons/engine/SCons/Builder.py +877 -0
  20. data/lib/libv8/scons/engine/SCons/CacheDir.py +216 -0
  21. data/lib/libv8/scons/engine/SCons/Conftest.py +793 -0
  22. data/lib/libv8/scons/engine/SCons/Debug.py +220 -0
  23. data/lib/libv8/scons/engine/SCons/Defaults.py +494 -0
  24. data/lib/libv8/scons/engine/SCons/Environment.py +2417 -0
  25. data/lib/libv8/scons/engine/SCons/Errors.py +205 -0
  26. data/lib/libv8/scons/engine/SCons/Executor.py +633 -0
  27. data/lib/libv8/scons/engine/SCons/Job.py +435 -0
  28. data/lib/libv8/scons/engine/SCons/Memoize.py +244 -0
  29. data/lib/libv8/scons/engine/SCons/Node/Alias.py +152 -0
  30. data/lib/libv8/scons/engine/SCons/Node/FS.py +3302 -0
  31. data/lib/libv8/scons/engine/SCons/Node/Python.py +128 -0
  32. data/lib/libv8/scons/engine/SCons/Node/__init__.py +1329 -0
  33. data/lib/libv8/scons/engine/SCons/Options/BoolOption.py +50 -0
  34. data/lib/libv8/scons/engine/SCons/Options/EnumOption.py +50 -0
  35. data/lib/libv8/scons/engine/SCons/Options/ListOption.py +50 -0
  36. data/lib/libv8/scons/engine/SCons/Options/PackageOption.py +50 -0
  37. data/lib/libv8/scons/engine/SCons/Options/PathOption.py +76 -0
  38. data/lib/libv8/scons/engine/SCons/Options/__init__.py +67 -0
  39. data/lib/libv8/scons/engine/SCons/PathList.py +231 -0
  40. data/lib/libv8/scons/engine/SCons/Platform/__init__.py +241 -0
  41. data/lib/libv8/scons/engine/SCons/Platform/aix.py +69 -0
  42. data/lib/libv8/scons/engine/SCons/Platform/cygwin.py +55 -0
  43. data/lib/libv8/scons/engine/SCons/Platform/darwin.py +70 -0
  44. data/lib/libv8/scons/engine/SCons/Platform/hpux.py +46 -0
  45. data/lib/libv8/scons/engine/SCons/Platform/irix.py +44 -0
  46. data/lib/libv8/scons/engine/SCons/Platform/os2.py +58 -0
  47. data/lib/libv8/scons/engine/SCons/Platform/posix.py +263 -0
  48. data/lib/libv8/scons/engine/SCons/Platform/sunos.py +50 -0
  49. data/lib/libv8/scons/engine/SCons/Platform/win32.py +385 -0
  50. data/lib/libv8/scons/engine/SCons/SConf.py +1030 -0
  51. data/lib/libv8/scons/engine/SCons/SConsign.py +389 -0
  52. data/lib/libv8/scons/engine/SCons/Scanner/C.py +132 -0
  53. data/lib/libv8/scons/engine/SCons/Scanner/D.py +73 -0
  54. data/lib/libv8/scons/engine/SCons/Scanner/Dir.py +109 -0
  55. data/lib/libv8/scons/engine/SCons/Scanner/Fortran.py +316 -0
  56. data/lib/libv8/scons/engine/SCons/Scanner/IDL.py +48 -0
  57. data/lib/libv8/scons/engine/SCons/Scanner/LaTeX.py +387 -0
  58. data/lib/libv8/scons/engine/SCons/Scanner/Prog.py +101 -0
  59. data/lib/libv8/scons/engine/SCons/Scanner/RC.py +55 -0
  60. data/lib/libv8/scons/engine/SCons/Scanner/__init__.py +413 -0
  61. data/lib/libv8/scons/engine/SCons/Script/Interactive.py +384 -0
  62. data/lib/libv8/scons/engine/SCons/Script/Main.py +1405 -0
  63. data/lib/libv8/scons/engine/SCons/Script/SConsOptions.py +939 -0
  64. data/lib/libv8/scons/engine/SCons/Script/SConscript.py +640 -0
  65. data/lib/libv8/scons/engine/SCons/Script/__init__.py +412 -0
  66. data/lib/libv8/scons/engine/SCons/Sig.py +63 -0
  67. data/lib/libv8/scons/engine/SCons/Subst.py +904 -0
  68. data/lib/libv8/scons/engine/SCons/Taskmaster.py +1025 -0
  69. data/lib/libv8/scons/engine/SCons/Tool/386asm.py +61 -0
  70. data/lib/libv8/scons/engine/SCons/Tool/BitKeeper.py +67 -0
  71. data/lib/libv8/scons/engine/SCons/Tool/CVS.py +73 -0
  72. data/lib/libv8/scons/engine/SCons/Tool/FortranCommon.py +263 -0
  73. data/lib/libv8/scons/engine/SCons/Tool/JavaCommon.py +323 -0
  74. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/__init__.py +56 -0
  75. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/arch.py +61 -0
  76. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/common.py +240 -0
  77. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/netframework.py +82 -0
  78. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/sdk.py +391 -0
  79. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vc.py +459 -0
  80. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vs.py +526 -0
  81. data/lib/libv8/scons/engine/SCons/Tool/Perforce.py +103 -0
  82. data/lib/libv8/scons/engine/SCons/Tool/PharLapCommon.py +137 -0
  83. data/lib/libv8/scons/engine/SCons/Tool/RCS.py +64 -0
  84. data/lib/libv8/scons/engine/SCons/Tool/SCCS.py +64 -0
  85. data/lib/libv8/scons/engine/SCons/Tool/Subversion.py +71 -0
  86. data/lib/libv8/scons/engine/SCons/Tool/__init__.py +681 -0
  87. data/lib/libv8/scons/engine/SCons/Tool/aixc++.py +82 -0
  88. data/lib/libv8/scons/engine/SCons/Tool/aixcc.py +74 -0
  89. data/lib/libv8/scons/engine/SCons/Tool/aixf77.py +80 -0
  90. data/lib/libv8/scons/engine/SCons/Tool/aixlink.py +76 -0
  91. data/lib/libv8/scons/engine/SCons/Tool/applelink.py +71 -0
  92. data/lib/libv8/scons/engine/SCons/Tool/ar.py +63 -0
  93. data/lib/libv8/scons/engine/SCons/Tool/as.py +78 -0
  94. data/lib/libv8/scons/engine/SCons/Tool/bcc32.py +81 -0
  95. data/lib/libv8/scons/engine/SCons/Tool/c++.py +99 -0
  96. data/lib/libv8/scons/engine/SCons/Tool/cc.py +102 -0
  97. data/lib/libv8/scons/engine/SCons/Tool/cvf.py +58 -0
  98. data/lib/libv8/scons/engine/SCons/Tool/default.py +50 -0
  99. data/lib/libv8/scons/engine/SCons/Tool/dmd.py +240 -0
  100. data/lib/libv8/scons/engine/SCons/Tool/dvi.py +64 -0
  101. data/lib/libv8/scons/engine/SCons/Tool/dvipdf.py +125 -0
  102. data/lib/libv8/scons/engine/SCons/Tool/dvips.py +95 -0
  103. data/lib/libv8/scons/engine/SCons/Tool/f03.py +63 -0
  104. data/lib/libv8/scons/engine/SCons/Tool/f77.py +62 -0
  105. data/lib/libv8/scons/engine/SCons/Tool/f90.py +62 -0
  106. data/lib/libv8/scons/engine/SCons/Tool/f95.py +63 -0
  107. data/lib/libv8/scons/engine/SCons/Tool/filesystem.py +98 -0
  108. data/lib/libv8/scons/engine/SCons/Tool/fortran.py +62 -0
  109. data/lib/libv8/scons/engine/SCons/Tool/g++.py +90 -0
  110. data/lib/libv8/scons/engine/SCons/Tool/g77.py +73 -0
  111. data/lib/libv8/scons/engine/SCons/Tool/gas.py +53 -0
  112. data/lib/libv8/scons/engine/SCons/Tool/gcc.py +80 -0
  113. data/lib/libv8/scons/engine/SCons/Tool/gfortran.py +64 -0
  114. data/lib/libv8/scons/engine/SCons/Tool/gnulink.py +62 -0
  115. data/lib/libv8/scons/engine/SCons/Tool/gs.py +81 -0
  116. data/lib/libv8/scons/engine/SCons/Tool/hpc++.py +84 -0
  117. data/lib/libv8/scons/engine/SCons/Tool/hpcc.py +53 -0
  118. data/lib/libv8/scons/engine/SCons/Tool/hplink.py +77 -0
  119. data/lib/libv8/scons/engine/SCons/Tool/icc.py +59 -0
  120. data/lib/libv8/scons/engine/SCons/Tool/icl.py +52 -0
  121. data/lib/libv8/scons/engine/SCons/Tool/ifl.py +72 -0
  122. data/lib/libv8/scons/engine/SCons/Tool/ifort.py +88 -0
  123. data/lib/libv8/scons/engine/SCons/Tool/ilink.py +59 -0
  124. data/lib/libv8/scons/engine/SCons/Tool/ilink32.py +60 -0
  125. data/lib/libv8/scons/engine/SCons/Tool/install.py +283 -0
  126. data/lib/libv8/scons/engine/SCons/Tool/intelc.py +522 -0
  127. data/lib/libv8/scons/engine/SCons/Tool/ipkg.py +67 -0
  128. data/lib/libv8/scons/engine/SCons/Tool/jar.py +116 -0
  129. data/lib/libv8/scons/engine/SCons/Tool/javac.py +230 -0
  130. data/lib/libv8/scons/engine/SCons/Tool/javah.py +137 -0
  131. data/lib/libv8/scons/engine/SCons/Tool/latex.py +80 -0
  132. data/lib/libv8/scons/engine/SCons/Tool/lex.py +97 -0
  133. data/lib/libv8/scons/engine/SCons/Tool/link.py +122 -0
  134. data/lib/libv8/scons/engine/SCons/Tool/linkloc.py +112 -0
  135. data/lib/libv8/scons/engine/SCons/Tool/m4.py +63 -0
  136. data/lib/libv8/scons/engine/SCons/Tool/masm.py +77 -0
  137. data/lib/libv8/scons/engine/SCons/Tool/midl.py +88 -0
  138. data/lib/libv8/scons/engine/SCons/Tool/mingw.py +179 -0
  139. data/lib/libv8/scons/engine/SCons/Tool/mslib.py +64 -0
  140. data/lib/libv8/scons/engine/SCons/Tool/mslink.py +318 -0
  141. data/lib/libv8/scons/engine/SCons/Tool/mssdk.py +50 -0
  142. data/lib/libv8/scons/engine/SCons/Tool/msvc.py +278 -0
  143. data/lib/libv8/scons/engine/SCons/Tool/msvs.py +1806 -0
  144. data/lib/libv8/scons/engine/SCons/Tool/mwcc.py +207 -0
  145. data/lib/libv8/scons/engine/SCons/Tool/mwld.py +107 -0
  146. data/lib/libv8/scons/engine/SCons/Tool/nasm.py +72 -0
  147. data/lib/libv8/scons/engine/SCons/Tool/packaging/__init__.py +312 -0
  148. data/lib/libv8/scons/engine/SCons/Tool/packaging/ipk.py +185 -0
  149. data/lib/libv8/scons/engine/SCons/Tool/packaging/msi.py +527 -0
  150. data/lib/libv8/scons/engine/SCons/Tool/packaging/rpm.py +365 -0
  151. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_tarbz2.py +43 -0
  152. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_targz.py +43 -0
  153. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_zip.py +43 -0
  154. data/lib/libv8/scons/engine/SCons/Tool/packaging/tarbz2.py +44 -0
  155. data/lib/libv8/scons/engine/SCons/Tool/packaging/targz.py +44 -0
  156. data/lib/libv8/scons/engine/SCons/Tool/packaging/zip.py +44 -0
  157. data/lib/libv8/scons/engine/SCons/Tool/pdf.py +78 -0
  158. data/lib/libv8/scons/engine/SCons/Tool/pdflatex.py +84 -0
  159. data/lib/libv8/scons/engine/SCons/Tool/pdftex.py +109 -0
  160. data/lib/libv8/scons/engine/SCons/Tool/qt.py +336 -0
  161. data/lib/libv8/scons/engine/SCons/Tool/rmic.py +126 -0
  162. data/lib/libv8/scons/engine/SCons/Tool/rpcgen.py +70 -0
  163. data/lib/libv8/scons/engine/SCons/Tool/rpm.py +132 -0
  164. data/lib/libv8/scons/engine/SCons/Tool/sgiar.py +68 -0
  165. data/lib/libv8/scons/engine/SCons/Tool/sgic++.py +58 -0
  166. data/lib/libv8/scons/engine/SCons/Tool/sgicc.py +53 -0
  167. data/lib/libv8/scons/engine/SCons/Tool/sgilink.py +62 -0
  168. data/lib/libv8/scons/engine/SCons/Tool/sunar.py +67 -0
  169. data/lib/libv8/scons/engine/SCons/Tool/sunc++.py +142 -0
  170. data/lib/libv8/scons/engine/SCons/Tool/suncc.py +58 -0
  171. data/lib/libv8/scons/engine/SCons/Tool/sunf77.py +63 -0
  172. data/lib/libv8/scons/engine/SCons/Tool/sunf90.py +64 -0
  173. data/lib/libv8/scons/engine/SCons/Tool/sunf95.py +64 -0
  174. data/lib/libv8/scons/engine/SCons/Tool/sunlink.py +76 -0
  175. data/lib/libv8/scons/engine/SCons/Tool/swig.py +183 -0
  176. data/lib/libv8/scons/engine/SCons/Tool/tar.py +73 -0
  177. data/lib/libv8/scons/engine/SCons/Tool/tex.py +866 -0
  178. data/lib/libv8/scons/engine/SCons/Tool/textfile.py +175 -0
  179. data/lib/libv8/scons/engine/SCons/Tool/tlib.py +53 -0
  180. data/lib/libv8/scons/engine/SCons/Tool/wix.py +99 -0
  181. data/lib/libv8/scons/engine/SCons/Tool/yacc.py +140 -0
  182. data/lib/libv8/scons/engine/SCons/Tool/zip.py +99 -0
  183. data/lib/libv8/scons/engine/SCons/Util.py +1492 -0
  184. data/lib/libv8/scons/engine/SCons/Variables/BoolVariable.py +89 -0
  185. data/lib/libv8/scons/engine/SCons/Variables/EnumVariable.py +103 -0
  186. data/lib/libv8/scons/engine/SCons/Variables/ListVariable.py +135 -0
  187. data/lib/libv8/scons/engine/SCons/Variables/PackageVariable.py +106 -0
  188. data/lib/libv8/scons/engine/SCons/Variables/PathVariable.py +147 -0
  189. data/lib/libv8/scons/engine/SCons/Variables/__init__.py +312 -0
  190. data/lib/libv8/scons/engine/SCons/Warnings.py +246 -0
  191. data/lib/libv8/scons/engine/SCons/__init__.py +49 -0
  192. data/lib/libv8/scons/engine/SCons/compat/__init__.py +237 -0
  193. data/lib/libv8/scons/engine/SCons/compat/_scons_builtins.py +150 -0
  194. data/lib/libv8/scons/engine/SCons/compat/_scons_collections.py +45 -0
  195. data/lib/libv8/scons/engine/SCons/compat/_scons_dbm.py +45 -0
  196. data/lib/libv8/scons/engine/SCons/compat/_scons_hashlib.py +76 -0
  197. data/lib/libv8/scons/engine/SCons/compat/_scons_io.py +45 -0
  198. data/lib/libv8/scons/engine/SCons/compat/_scons_sets.py +563 -0
  199. data/lib/libv8/scons/engine/SCons/compat/_scons_subprocess.py +1281 -0
  200. data/lib/libv8/scons/engine/SCons/cpp.py +589 -0
  201. data/lib/libv8/scons/engine/SCons/dblite.py +254 -0
  202. data/lib/libv8/scons/engine/SCons/exitfuncs.py +77 -0
  203. data/lib/libv8/scons/os_spawnv_fix.diff +83 -0
  204. data/lib/libv8/scons/scons-time.1 +1017 -0
  205. data/lib/libv8/scons/scons.1 +15225 -0
  206. data/lib/libv8/scons/sconsign.1 +208 -0
  207. data/lib/libv8/scons/script/scons +196 -0
  208. data/lib/libv8/scons/script/scons-time +1544 -0
  209. data/lib/libv8/scons/script/scons.bat +34 -0
  210. data/lib/libv8/scons/script/sconsign +514 -0
  211. data/lib/libv8/scons/setup.cfg +5 -0
  212. data/lib/libv8/scons/setup.py +423 -0
  213. data/lib/libv8/v8/.gitignore +35 -0
  214. data/lib/libv8/v8/AUTHORS +44 -0
  215. data/lib/libv8/v8/ChangeLog +2839 -0
  216. data/lib/libv8/v8/LICENSE +52 -0
  217. data/lib/libv8/v8/LICENSE.strongtalk +29 -0
  218. data/lib/libv8/v8/LICENSE.v8 +26 -0
  219. data/lib/libv8/v8/LICENSE.valgrind +45 -0
  220. data/lib/libv8/v8/SConstruct +1478 -0
  221. data/lib/libv8/v8/build/README.txt +49 -0
  222. data/lib/libv8/v8/build/all.gyp +18 -0
  223. data/lib/libv8/v8/build/armu.gypi +32 -0
  224. data/lib/libv8/v8/build/common.gypi +144 -0
  225. data/lib/libv8/v8/build/gyp_v8 +145 -0
  226. data/lib/libv8/v8/include/v8-debug.h +395 -0
  227. data/lib/libv8/v8/include/v8-preparser.h +117 -0
  228. data/lib/libv8/v8/include/v8-profiler.h +505 -0
  229. data/lib/libv8/v8/include/v8-testing.h +104 -0
  230. data/lib/libv8/v8/include/v8.h +4124 -0
  231. data/lib/libv8/v8/include/v8stdint.h +53 -0
  232. data/lib/libv8/v8/preparser/SConscript +38 -0
  233. data/lib/libv8/v8/preparser/preparser-process.cc +379 -0
  234. data/lib/libv8/v8/src/SConscript +368 -0
  235. data/lib/libv8/v8/src/accessors.cc +767 -0
  236. data/lib/libv8/v8/src/accessors.h +123 -0
  237. data/lib/libv8/v8/src/allocation-inl.h +49 -0
  238. data/lib/libv8/v8/src/allocation.cc +122 -0
  239. data/lib/libv8/v8/src/allocation.h +143 -0
  240. data/lib/libv8/v8/src/api.cc +5845 -0
  241. data/lib/libv8/v8/src/api.h +574 -0
  242. data/lib/libv8/v8/src/apinatives.js +110 -0
  243. data/lib/libv8/v8/src/apiutils.h +73 -0
  244. data/lib/libv8/v8/src/arguments.h +118 -0
  245. data/lib/libv8/v8/src/arm/assembler-arm-inl.h +353 -0
  246. data/lib/libv8/v8/src/arm/assembler-arm.cc +2661 -0
  247. data/lib/libv8/v8/src/arm/assembler-arm.h +1375 -0
  248. data/lib/libv8/v8/src/arm/builtins-arm.cc +1658 -0
  249. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +6398 -0
  250. data/lib/libv8/v8/src/arm/code-stubs-arm.h +673 -0
  251. data/lib/libv8/v8/src/arm/codegen-arm.cc +52 -0
  252. data/lib/libv8/v8/src/arm/codegen-arm.h +91 -0
  253. data/lib/libv8/v8/src/arm/constants-arm.cc +152 -0
  254. data/lib/libv8/v8/src/arm/constants-arm.h +775 -0
  255. data/lib/libv8/v8/src/arm/cpu-arm.cc +120 -0
  256. data/lib/libv8/v8/src/arm/debug-arm.cc +317 -0
  257. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +754 -0
  258. data/lib/libv8/v8/src/arm/disasm-arm.cc +1506 -0
  259. data/lib/libv8/v8/src/arm/frames-arm.cc +45 -0
  260. data/lib/libv8/v8/src/arm/frames-arm.h +168 -0
  261. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +4375 -0
  262. data/lib/libv8/v8/src/arm/ic-arm.cc +1562 -0
  263. data/lib/libv8/v8/src/arm/lithium-arm.cc +2206 -0
  264. data/lib/libv8/v8/src/arm/lithium-arm.h +2348 -0
  265. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +4526 -0
  266. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +403 -0
  267. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +305 -0
  268. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.h +84 -0
  269. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +3163 -0
  270. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +1126 -0
  271. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +1287 -0
  272. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +253 -0
  273. data/lib/libv8/v8/src/arm/simulator-arm.cc +3424 -0
  274. data/lib/libv8/v8/src/arm/simulator-arm.h +431 -0
  275. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +4243 -0
  276. data/lib/libv8/v8/src/array.js +1366 -0
  277. data/lib/libv8/v8/src/assembler.cc +1207 -0
  278. data/lib/libv8/v8/src/assembler.h +858 -0
  279. data/lib/libv8/v8/src/ast-inl.h +112 -0
  280. data/lib/libv8/v8/src/ast.cc +1146 -0
  281. data/lib/libv8/v8/src/ast.h +2188 -0
  282. data/lib/libv8/v8/src/atomicops.h +167 -0
  283. data/lib/libv8/v8/src/atomicops_internals_arm_gcc.h +145 -0
  284. data/lib/libv8/v8/src/atomicops_internals_mips_gcc.h +169 -0
  285. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.cc +133 -0
  286. data/lib/libv8/v8/src/atomicops_internals_x86_gcc.h +287 -0
  287. data/lib/libv8/v8/src/atomicops_internals_x86_macosx.h +301 -0
  288. data/lib/libv8/v8/src/atomicops_internals_x86_msvc.h +203 -0
  289. data/lib/libv8/v8/src/bignum-dtoa.cc +655 -0
  290. data/lib/libv8/v8/src/bignum-dtoa.h +81 -0
  291. data/lib/libv8/v8/src/bignum.cc +768 -0
  292. data/lib/libv8/v8/src/bignum.h +140 -0
  293. data/lib/libv8/v8/src/bootstrapper.cc +2184 -0
  294. data/lib/libv8/v8/src/bootstrapper.h +188 -0
  295. data/lib/libv8/v8/src/builtins.cc +1707 -0
  296. data/lib/libv8/v8/src/builtins.h +371 -0
  297. data/lib/libv8/v8/src/bytecodes-irregexp.h +105 -0
  298. data/lib/libv8/v8/src/cached-powers.cc +177 -0
  299. data/lib/libv8/v8/src/cached-powers.h +65 -0
  300. data/lib/libv8/v8/src/char-predicates-inl.h +94 -0
  301. data/lib/libv8/v8/src/char-predicates.h +67 -0
  302. data/lib/libv8/v8/src/checks.cc +110 -0
  303. data/lib/libv8/v8/src/checks.h +296 -0
  304. data/lib/libv8/v8/src/circular-queue-inl.h +53 -0
  305. data/lib/libv8/v8/src/circular-queue.cc +122 -0
  306. data/lib/libv8/v8/src/circular-queue.h +103 -0
  307. data/lib/libv8/v8/src/code-stubs.cc +267 -0
  308. data/lib/libv8/v8/src/code-stubs.h +1011 -0
  309. data/lib/libv8/v8/src/code.h +70 -0
  310. data/lib/libv8/v8/src/codegen.cc +231 -0
  311. data/lib/libv8/v8/src/codegen.h +84 -0
  312. data/lib/libv8/v8/src/compilation-cache.cc +540 -0
  313. data/lib/libv8/v8/src/compilation-cache.h +287 -0
  314. data/lib/libv8/v8/src/compiler.cc +786 -0
  315. data/lib/libv8/v8/src/compiler.h +312 -0
  316. data/lib/libv8/v8/src/contexts.cc +347 -0
  317. data/lib/libv8/v8/src/contexts.h +391 -0
  318. data/lib/libv8/v8/src/conversions-inl.h +106 -0
  319. data/lib/libv8/v8/src/conversions.cc +1131 -0
  320. data/lib/libv8/v8/src/conversions.h +135 -0
  321. data/lib/libv8/v8/src/counters.cc +93 -0
  322. data/lib/libv8/v8/src/counters.h +254 -0
  323. data/lib/libv8/v8/src/cpu-profiler-inl.h +101 -0
  324. data/lib/libv8/v8/src/cpu-profiler.cc +609 -0
  325. data/lib/libv8/v8/src/cpu-profiler.h +302 -0
  326. data/lib/libv8/v8/src/cpu.h +69 -0
  327. data/lib/libv8/v8/src/d8-debug.cc +367 -0
  328. data/lib/libv8/v8/src/d8-debug.h +158 -0
  329. data/lib/libv8/v8/src/d8-posix.cc +695 -0
  330. data/lib/libv8/v8/src/d8-readline.cc +130 -0
  331. data/lib/libv8/v8/src/d8-windows.cc +42 -0
  332. data/lib/libv8/v8/src/d8.cc +803 -0
  333. data/lib/libv8/v8/src/d8.gyp +91 -0
  334. data/lib/libv8/v8/src/d8.h +235 -0
  335. data/lib/libv8/v8/src/d8.js +2798 -0
  336. data/lib/libv8/v8/src/data-flow.cc +66 -0
  337. data/lib/libv8/v8/src/data-flow.h +205 -0
  338. data/lib/libv8/v8/src/date.js +1103 -0
  339. data/lib/libv8/v8/src/dateparser-inl.h +127 -0
  340. data/lib/libv8/v8/src/dateparser.cc +178 -0
  341. data/lib/libv8/v8/src/dateparser.h +266 -0
  342. data/lib/libv8/v8/src/debug-agent.cc +447 -0
  343. data/lib/libv8/v8/src/debug-agent.h +129 -0
  344. data/lib/libv8/v8/src/debug-debugger.js +2569 -0
  345. data/lib/libv8/v8/src/debug.cc +3165 -0
  346. data/lib/libv8/v8/src/debug.h +1057 -0
  347. data/lib/libv8/v8/src/deoptimizer.cc +1256 -0
  348. data/lib/libv8/v8/src/deoptimizer.h +602 -0
  349. data/lib/libv8/v8/src/disasm.h +80 -0
  350. data/lib/libv8/v8/src/disassembler.cc +343 -0
  351. data/lib/libv8/v8/src/disassembler.h +58 -0
  352. data/lib/libv8/v8/src/diy-fp.cc +58 -0
  353. data/lib/libv8/v8/src/diy-fp.h +117 -0
  354. data/lib/libv8/v8/src/double.h +238 -0
  355. data/lib/libv8/v8/src/dtoa.cc +103 -0
  356. data/lib/libv8/v8/src/dtoa.h +85 -0
  357. data/lib/libv8/v8/src/execution.cc +849 -0
  358. data/lib/libv8/v8/src/execution.h +297 -0
  359. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +250 -0
  360. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +89 -0
  361. data/lib/libv8/v8/src/extensions/experimental/collator.cc +218 -0
  362. data/lib/libv8/v8/src/extensions/experimental/collator.h +69 -0
  363. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +94 -0
  364. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +78 -0
  365. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +54 -0
  366. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +112 -0
  367. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +60 -0
  368. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +43 -0
  369. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +49 -0
  370. data/lib/libv8/v8/src/extensions/experimental/i18n.js +180 -0
  371. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +251 -0
  372. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +95 -0
  373. data/lib/libv8/v8/src/extensions/externalize-string-extension.cc +141 -0
  374. data/lib/libv8/v8/src/extensions/externalize-string-extension.h +50 -0
  375. data/lib/libv8/v8/src/extensions/gc-extension.cc +58 -0
  376. data/lib/libv8/v8/src/extensions/gc-extension.h +49 -0
  377. data/lib/libv8/v8/src/factory.cc +1222 -0
  378. data/lib/libv8/v8/src/factory.h +442 -0
  379. data/lib/libv8/v8/src/fast-dtoa.cc +736 -0
  380. data/lib/libv8/v8/src/fast-dtoa.h +83 -0
  381. data/lib/libv8/v8/src/fixed-dtoa.cc +405 -0
  382. data/lib/libv8/v8/src/fixed-dtoa.h +55 -0
  383. data/lib/libv8/v8/src/flag-definitions.h +560 -0
  384. data/lib/libv8/v8/src/flags.cc +551 -0
  385. data/lib/libv8/v8/src/flags.h +79 -0
  386. data/lib/libv8/v8/src/frames-inl.h +247 -0
  387. data/lib/libv8/v8/src/frames.cc +1243 -0
  388. data/lib/libv8/v8/src/frames.h +870 -0
  389. data/lib/libv8/v8/src/full-codegen.cc +1374 -0
  390. data/lib/libv8/v8/src/full-codegen.h +771 -0
  391. data/lib/libv8/v8/src/func-name-inferrer.cc +92 -0
  392. data/lib/libv8/v8/src/func-name-inferrer.h +111 -0
  393. data/lib/libv8/v8/src/gdb-jit.cc +1555 -0
  394. data/lib/libv8/v8/src/gdb-jit.h +143 -0
  395. data/lib/libv8/v8/src/global-handles.cc +665 -0
  396. data/lib/libv8/v8/src/global-handles.h +284 -0
  397. data/lib/libv8/v8/src/globals.h +325 -0
  398. data/lib/libv8/v8/src/handles-inl.h +177 -0
  399. data/lib/libv8/v8/src/handles.cc +987 -0
  400. data/lib/libv8/v8/src/handles.h +382 -0
  401. data/lib/libv8/v8/src/hashmap.cc +230 -0
  402. data/lib/libv8/v8/src/hashmap.h +123 -0
  403. data/lib/libv8/v8/src/heap-inl.h +704 -0
  404. data/lib/libv8/v8/src/heap-profiler.cc +1173 -0
  405. data/lib/libv8/v8/src/heap-profiler.h +397 -0
  406. data/lib/libv8/v8/src/heap.cc +5930 -0
  407. data/lib/libv8/v8/src/heap.h +2268 -0
  408. data/lib/libv8/v8/src/hydrogen-instructions.cc +1769 -0
  409. data/lib/libv8/v8/src/hydrogen-instructions.h +3971 -0
  410. data/lib/libv8/v8/src/hydrogen.cc +6239 -0
  411. data/lib/libv8/v8/src/hydrogen.h +1202 -0
  412. data/lib/libv8/v8/src/ia32/assembler-ia32-inl.h +446 -0
  413. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +2487 -0
  414. data/lib/libv8/v8/src/ia32/assembler-ia32.h +1144 -0
  415. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +1621 -0
  416. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +6198 -0
  417. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +517 -0
  418. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +265 -0
  419. data/lib/libv8/v8/src/ia32/codegen-ia32.h +79 -0
  420. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +88 -0
  421. data/lib/libv8/v8/src/ia32/debug-ia32.cc +312 -0
  422. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +774 -0
  423. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +1628 -0
  424. data/lib/libv8/v8/src/ia32/frames-ia32.cc +45 -0
  425. data/lib/libv8/v8/src/ia32/frames-ia32.h +142 -0
  426. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +4338 -0
  427. data/lib/libv8/v8/src/ia32/ic-ia32.cc +1597 -0
  428. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +4461 -0
  429. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +375 -0
  430. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +475 -0
  431. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.h +110 -0
  432. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +2261 -0
  433. data/lib/libv8/v8/src/ia32/lithium-ia32.h +2396 -0
  434. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +2136 -0
  435. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +775 -0
  436. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +1263 -0
  437. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +216 -0
  438. data/lib/libv8/v8/src/ia32/simulator-ia32.cc +30 -0
  439. data/lib/libv8/v8/src/ia32/simulator-ia32.h +74 -0
  440. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +3847 -0
  441. data/lib/libv8/v8/src/ic-inl.h +130 -0
  442. data/lib/libv8/v8/src/ic.cc +2577 -0
  443. data/lib/libv8/v8/src/ic.h +736 -0
  444. data/lib/libv8/v8/src/inspector.cc +63 -0
  445. data/lib/libv8/v8/src/inspector.h +62 -0
  446. data/lib/libv8/v8/src/interpreter-irregexp.cc +659 -0
  447. data/lib/libv8/v8/src/interpreter-irregexp.h +49 -0
  448. data/lib/libv8/v8/src/isolate-inl.h +50 -0
  449. data/lib/libv8/v8/src/isolate.cc +1869 -0
  450. data/lib/libv8/v8/src/isolate.h +1382 -0
  451. data/lib/libv8/v8/src/json-parser.cc +504 -0
  452. data/lib/libv8/v8/src/json-parser.h +161 -0
  453. data/lib/libv8/v8/src/json.js +342 -0
  454. data/lib/libv8/v8/src/jsregexp.cc +5385 -0
  455. data/lib/libv8/v8/src/jsregexp.h +1492 -0
  456. data/lib/libv8/v8/src/list-inl.h +212 -0
  457. data/lib/libv8/v8/src/list.h +174 -0
  458. data/lib/libv8/v8/src/lithium-allocator-inl.h +142 -0
  459. data/lib/libv8/v8/src/lithium-allocator.cc +2123 -0
  460. data/lib/libv8/v8/src/lithium-allocator.h +630 -0
  461. data/lib/libv8/v8/src/lithium.cc +190 -0
  462. data/lib/libv8/v8/src/lithium.h +597 -0
  463. data/lib/libv8/v8/src/liveedit-debugger.js +1082 -0
  464. data/lib/libv8/v8/src/liveedit.cc +1691 -0
  465. data/lib/libv8/v8/src/liveedit.h +180 -0
  466. data/lib/libv8/v8/src/liveobjectlist-inl.h +126 -0
  467. data/lib/libv8/v8/src/liveobjectlist.cc +2589 -0
  468. data/lib/libv8/v8/src/liveobjectlist.h +322 -0
  469. data/lib/libv8/v8/src/log-inl.h +59 -0
  470. data/lib/libv8/v8/src/log-utils.cc +428 -0
  471. data/lib/libv8/v8/src/log-utils.h +231 -0
  472. data/lib/libv8/v8/src/log.cc +1993 -0
  473. data/lib/libv8/v8/src/log.h +476 -0
  474. data/lib/libv8/v8/src/macro-assembler.h +120 -0
  475. data/lib/libv8/v8/src/macros.py +178 -0
  476. data/lib/libv8/v8/src/mark-compact.cc +3143 -0
  477. data/lib/libv8/v8/src/mark-compact.h +506 -0
  478. data/lib/libv8/v8/src/math.js +264 -0
  479. data/lib/libv8/v8/src/messages.cc +179 -0
  480. data/lib/libv8/v8/src/messages.h +113 -0
  481. data/lib/libv8/v8/src/messages.js +1096 -0
  482. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +312 -0
  483. data/lib/libv8/v8/src/mips/assembler-mips.cc +1960 -0
  484. data/lib/libv8/v8/src/mips/assembler-mips.h +1138 -0
  485. data/lib/libv8/v8/src/mips/builtins-mips.cc +1628 -0
  486. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +6656 -0
  487. data/lib/libv8/v8/src/mips/code-stubs-mips.h +682 -0
  488. data/lib/libv8/v8/src/mips/codegen-mips.cc +52 -0
  489. data/lib/libv8/v8/src/mips/codegen-mips.h +98 -0
  490. data/lib/libv8/v8/src/mips/constants-mips.cc +352 -0
  491. data/lib/libv8/v8/src/mips/constants-mips.h +739 -0
  492. data/lib/libv8/v8/src/mips/cpu-mips.cc +96 -0
  493. data/lib/libv8/v8/src/mips/debug-mips.cc +308 -0
  494. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +91 -0
  495. data/lib/libv8/v8/src/mips/disasm-mips.cc +1050 -0
  496. data/lib/libv8/v8/src/mips/frames-mips.cc +47 -0
  497. data/lib/libv8/v8/src/mips/frames-mips.h +219 -0
  498. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +4388 -0
  499. data/lib/libv8/v8/src/mips/ic-mips.cc +1580 -0
  500. data/lib/libv8/v8/src/mips/lithium-codegen-mips.h +65 -0
  501. data/lib/libv8/v8/src/mips/lithium-mips.h +307 -0
  502. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +4056 -0
  503. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +1214 -0
  504. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +1251 -0
  505. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +252 -0
  506. data/lib/libv8/v8/src/mips/simulator-mips.cc +2621 -0
  507. data/lib/libv8/v8/src/mips/simulator-mips.h +401 -0
  508. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +4285 -0
  509. data/lib/libv8/v8/src/mirror-debugger.js +2382 -0
  510. data/lib/libv8/v8/src/mksnapshot.cc +328 -0
  511. data/lib/libv8/v8/src/natives.h +64 -0
  512. data/lib/libv8/v8/src/objects-debug.cc +738 -0
  513. data/lib/libv8/v8/src/objects-inl.h +4323 -0
  514. data/lib/libv8/v8/src/objects-printer.cc +829 -0
  515. data/lib/libv8/v8/src/objects-visiting.cc +148 -0
  516. data/lib/libv8/v8/src/objects-visiting.h +424 -0
  517. data/lib/libv8/v8/src/objects.cc +10585 -0
  518. data/lib/libv8/v8/src/objects.h +6838 -0
  519. data/lib/libv8/v8/src/parser.cc +4997 -0
  520. data/lib/libv8/v8/src/parser.h +765 -0
  521. data/lib/libv8/v8/src/platform-cygwin.cc +779 -0
  522. data/lib/libv8/v8/src/platform-freebsd.cc +826 -0
  523. data/lib/libv8/v8/src/platform-linux.cc +1149 -0
  524. data/lib/libv8/v8/src/platform-macos.cc +830 -0
  525. data/lib/libv8/v8/src/platform-nullos.cc +479 -0
  526. data/lib/libv8/v8/src/platform-openbsd.cc +640 -0
  527. data/lib/libv8/v8/src/platform-posix.cc +424 -0
  528. data/lib/libv8/v8/src/platform-solaris.cc +762 -0
  529. data/lib/libv8/v8/src/platform-tls-mac.h +62 -0
  530. data/lib/libv8/v8/src/platform-tls-win32.h +62 -0
  531. data/lib/libv8/v8/src/platform-tls.h +50 -0
  532. data/lib/libv8/v8/src/platform-win32.cc +2021 -0
  533. data/lib/libv8/v8/src/platform.h +667 -0
  534. data/lib/libv8/v8/src/preparse-data-format.h +62 -0
  535. data/lib/libv8/v8/src/preparse-data.cc +183 -0
  536. data/lib/libv8/v8/src/preparse-data.h +225 -0
  537. data/lib/libv8/v8/src/preparser-api.cc +220 -0
  538. data/lib/libv8/v8/src/preparser.cc +1450 -0
  539. data/lib/libv8/v8/src/preparser.h +493 -0
  540. data/lib/libv8/v8/src/prettyprinter.cc +1493 -0
  541. data/lib/libv8/v8/src/prettyprinter.h +223 -0
  542. data/lib/libv8/v8/src/profile-generator-inl.h +128 -0
  543. data/lib/libv8/v8/src/profile-generator.cc +3098 -0
  544. data/lib/libv8/v8/src/profile-generator.h +1126 -0
  545. data/lib/libv8/v8/src/property.cc +105 -0
  546. data/lib/libv8/v8/src/property.h +365 -0
  547. data/lib/libv8/v8/src/proxy.js +83 -0
  548. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp-inl.h +78 -0
  549. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.cc +471 -0
  550. data/lib/libv8/v8/src/regexp-macro-assembler-irregexp.h +142 -0
  551. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.cc +373 -0
  552. data/lib/libv8/v8/src/regexp-macro-assembler-tracer.h +104 -0
  553. data/lib/libv8/v8/src/regexp-macro-assembler.cc +267 -0
  554. data/lib/libv8/v8/src/regexp-macro-assembler.h +243 -0
  555. data/lib/libv8/v8/src/regexp-stack.cc +111 -0
  556. data/lib/libv8/v8/src/regexp-stack.h +147 -0
  557. data/lib/libv8/v8/src/regexp.js +483 -0
  558. data/lib/libv8/v8/src/rewriter.cc +360 -0
  559. data/lib/libv8/v8/src/rewriter.h +50 -0
  560. data/lib/libv8/v8/src/runtime-profiler.cc +489 -0
  561. data/lib/libv8/v8/src/runtime-profiler.h +201 -0
  562. data/lib/libv8/v8/src/runtime.cc +12227 -0
  563. data/lib/libv8/v8/src/runtime.h +652 -0
  564. data/lib/libv8/v8/src/runtime.js +649 -0
  565. data/lib/libv8/v8/src/safepoint-table.cc +256 -0
  566. data/lib/libv8/v8/src/safepoint-table.h +270 -0
  567. data/lib/libv8/v8/src/scanner-base.cc +952 -0
  568. data/lib/libv8/v8/src/scanner-base.h +670 -0
  569. data/lib/libv8/v8/src/scanner.cc +345 -0
  570. data/lib/libv8/v8/src/scanner.h +146 -0
  571. data/lib/libv8/v8/src/scopeinfo.cc +646 -0
  572. data/lib/libv8/v8/src/scopeinfo.h +254 -0
  573. data/lib/libv8/v8/src/scopes.cc +1150 -0
  574. data/lib/libv8/v8/src/scopes.h +507 -0
  575. data/lib/libv8/v8/src/serialize.cc +1574 -0
  576. data/lib/libv8/v8/src/serialize.h +589 -0
  577. data/lib/libv8/v8/src/shell.h +55 -0
  578. data/lib/libv8/v8/src/simulator.h +43 -0
  579. data/lib/libv8/v8/src/small-pointer-list.h +163 -0
  580. data/lib/libv8/v8/src/smart-pointer.h +109 -0
  581. data/lib/libv8/v8/src/snapshot-common.cc +83 -0
  582. data/lib/libv8/v8/src/snapshot-empty.cc +54 -0
  583. data/lib/libv8/v8/src/snapshot.h +91 -0
  584. data/lib/libv8/v8/src/spaces-inl.h +529 -0
  585. data/lib/libv8/v8/src/spaces.cc +3145 -0
  586. data/lib/libv8/v8/src/spaces.h +2369 -0
  587. data/lib/libv8/v8/src/splay-tree-inl.h +310 -0
  588. data/lib/libv8/v8/src/splay-tree.h +205 -0
  589. data/lib/libv8/v8/src/string-search.cc +41 -0
  590. data/lib/libv8/v8/src/string-search.h +568 -0
  591. data/lib/libv8/v8/src/string-stream.cc +592 -0
  592. data/lib/libv8/v8/src/string-stream.h +191 -0
  593. data/lib/libv8/v8/src/string.js +994 -0
  594. data/lib/libv8/v8/src/strtod.cc +440 -0
  595. data/lib/libv8/v8/src/strtod.h +40 -0
  596. data/lib/libv8/v8/src/stub-cache.cc +1965 -0
  597. data/lib/libv8/v8/src/stub-cache.h +924 -0
  598. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +3925 -0
  599. data/lib/libv8/v8/src/token.cc +63 -0
  600. data/lib/libv8/v8/src/token.h +288 -0
  601. data/lib/libv8/v8/src/type-info.cc +507 -0
  602. data/lib/libv8/v8/src/type-info.h +272 -0
  603. data/lib/libv8/v8/src/unbound-queue-inl.h +95 -0
  604. data/lib/libv8/v8/src/unbound-queue.h +69 -0
  605. data/lib/libv8/v8/src/unicode-inl.h +238 -0
  606. data/lib/libv8/v8/src/unicode.cc +1624 -0
  607. data/lib/libv8/v8/src/unicode.h +280 -0
  608. data/lib/libv8/v8/src/uri.js +408 -0
  609. data/lib/libv8/v8/src/utils-inl.h +48 -0
  610. data/lib/libv8/v8/src/utils.cc +371 -0
  611. data/lib/libv8/v8/src/utils.h +800 -0
  612. data/lib/libv8/v8/src/v8-counters.cc +62 -0
  613. data/lib/libv8/v8/src/v8-counters.h +314 -0
  614. data/lib/libv8/v8/src/v8.cc +213 -0
  615. data/lib/libv8/v8/src/v8.h +131 -0
  616. data/lib/libv8/v8/src/v8checks.h +64 -0
  617. data/lib/libv8/v8/src/v8dll-main.cc +44 -0
  618. data/lib/libv8/v8/src/v8globals.h +512 -0
  619. data/lib/libv8/v8/src/v8memory.h +82 -0
  620. data/lib/libv8/v8/src/v8natives.js +1310 -0
  621. data/lib/libv8/v8/src/v8preparserdll-main.cc +39 -0
  622. data/lib/libv8/v8/src/v8threads.cc +464 -0
  623. data/lib/libv8/v8/src/v8threads.h +165 -0
  624. data/lib/libv8/v8/src/v8utils.h +319 -0
  625. data/lib/libv8/v8/src/variables.cc +114 -0
  626. data/lib/libv8/v8/src/variables.h +167 -0
  627. data/lib/libv8/v8/src/version.cc +116 -0
  628. data/lib/libv8/v8/src/version.h +68 -0
  629. data/lib/libv8/v8/src/vm-state-inl.h +138 -0
  630. data/lib/libv8/v8/src/vm-state.h +71 -0
  631. data/lib/libv8/v8/src/win32-headers.h +96 -0
  632. data/lib/libv8/v8/src/x64/assembler-x64-inl.h +462 -0
  633. data/lib/libv8/v8/src/x64/assembler-x64.cc +3027 -0
  634. data/lib/libv8/v8/src/x64/assembler-x64.h +1633 -0
  635. data/lib/libv8/v8/src/x64/builtins-x64.cc +1520 -0
  636. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +5132 -0
  637. data/lib/libv8/v8/src/x64/code-stubs-x64.h +514 -0
  638. data/lib/libv8/v8/src/x64/codegen-x64.cc +146 -0
  639. data/lib/libv8/v8/src/x64/codegen-x64.h +76 -0
  640. data/lib/libv8/v8/src/x64/cpu-x64.cc +88 -0
  641. data/lib/libv8/v8/src/x64/debug-x64.cc +319 -0
  642. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +815 -0
  643. data/lib/libv8/v8/src/x64/disasm-x64.cc +1832 -0
  644. data/lib/libv8/v8/src/x64/frames-x64.cc +45 -0
  645. data/lib/libv8/v8/src/x64/frames-x64.h +130 -0
  646. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +4318 -0
  647. data/lib/libv8/v8/src/x64/ic-x64.cc +1608 -0
  648. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +4267 -0
  649. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +367 -0
  650. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.cc +320 -0
  651. data/lib/libv8/v8/src/x64/lithium-gap-resolver-x64.h +74 -0
  652. data/lib/libv8/v8/src/x64/lithium-x64.cc +2202 -0
  653. data/lib/libv8/v8/src/x64/lithium-x64.h +2333 -0
  654. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +3745 -0
  655. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +1290 -0
  656. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +1398 -0
  657. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +282 -0
  658. data/lib/libv8/v8/src/x64/simulator-x64.cc +27 -0
  659. data/lib/libv8/v8/src/x64/simulator-x64.h +72 -0
  660. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +3610 -0
  661. data/lib/libv8/v8/src/zone-inl.h +140 -0
  662. data/lib/libv8/v8/src/zone.cc +196 -0
  663. data/lib/libv8/v8/src/zone.h +240 -0
  664. data/lib/libv8/v8/tools/codemap.js +265 -0
  665. data/lib/libv8/v8/tools/consarray.js +93 -0
  666. data/lib/libv8/v8/tools/csvparser.js +78 -0
  667. data/lib/libv8/v8/tools/disasm.py +92 -0
  668. data/lib/libv8/v8/tools/freebsd-tick-processor +10 -0
  669. data/lib/libv8/v8/tools/gc-nvp-trace-processor.py +342 -0
  670. data/lib/libv8/v8/tools/gcmole/README +62 -0
  671. data/lib/libv8/v8/tools/gcmole/gccause.lua +60 -0
  672. data/lib/libv8/v8/tools/gcmole/gcmole.cc +1261 -0
  673. data/lib/libv8/v8/tools/gcmole/gcmole.lua +378 -0
  674. data/lib/libv8/v8/tools/generate-ten-powers.scm +286 -0
  675. data/lib/libv8/v8/tools/grokdump.py +841 -0
  676. data/lib/libv8/v8/tools/gyp/v8.gyp +995 -0
  677. data/lib/libv8/v8/tools/js2c.py +364 -0
  678. data/lib/libv8/v8/tools/jsmin.py +280 -0
  679. data/lib/libv8/v8/tools/linux-tick-processor +35 -0
  680. data/lib/libv8/v8/tools/ll_prof.py +942 -0
  681. data/lib/libv8/v8/tools/logreader.js +185 -0
  682. data/lib/libv8/v8/tools/mac-nm +18 -0
  683. data/lib/libv8/v8/tools/mac-tick-processor +6 -0
  684. data/lib/libv8/v8/tools/oom_dump/README +31 -0
  685. data/lib/libv8/v8/tools/oom_dump/SConstruct +42 -0
  686. data/lib/libv8/v8/tools/oom_dump/oom_dump.cc +288 -0
  687. data/lib/libv8/v8/tools/presubmit.py +305 -0
  688. data/lib/libv8/v8/tools/process-heap-prof.py +120 -0
  689. data/lib/libv8/v8/tools/profile.js +751 -0
  690. data/lib/libv8/v8/tools/profile_view.js +219 -0
  691. data/lib/libv8/v8/tools/run-valgrind.py +77 -0
  692. data/lib/libv8/v8/tools/splaytree.js +316 -0
  693. data/lib/libv8/v8/tools/stats-viewer.py +468 -0
  694. data/lib/libv8/v8/tools/test.py +1510 -0
  695. data/lib/libv8/v8/tools/tickprocessor-driver.js +59 -0
  696. data/lib/libv8/v8/tools/tickprocessor.js +877 -0
  697. data/lib/libv8/v8/tools/utils.py +96 -0
  698. data/lib/libv8/v8/tools/visual_studio/README.txt +12 -0
  699. data/lib/libv8/v8/tools/windows-tick-processor.bat +30 -0
  700. data/lib/libv8/version.rb +6 -0
  701. data/libv8.gemspec +36 -0
  702. data/thefrontside.png +0 -0
  703. metadata +776 -0
@@ -0,0 +1,3925 @@
1
+ /* -*- c -*-
2
+ ----------------------------------------------------------------
3
+
4
+ Notice that the following BSD-style license applies to this one
5
+ file (valgrind.h) only. The rest of Valgrind is licensed under the
6
+ terms of the GNU General Public License, version 2, unless
7
+ otherwise indicated. See the COPYING file in the source
8
+ distribution for details.
9
+
10
+ ----------------------------------------------------------------
11
+
12
+ This file is part of Valgrind, a dynamic binary instrumentation
13
+ framework.
14
+
15
+ Copyright (C) 2000-2007 Julian Seward. All rights reserved.
16
+
17
+ Redistribution and use in source and binary forms, with or without
18
+ modification, are permitted provided that the following conditions
19
+ are met:
20
+
21
+ 1. Redistributions of source code must retain the above copyright
22
+ notice, this list of conditions and the following disclaimer.
23
+
24
+ 2. The origin of this software must not be misrepresented; you must
25
+ not claim that you wrote the original software. If you use this
26
+ software in a product, an acknowledgment in the product
27
+ documentation would be appreciated but is not required.
28
+
29
+ 3. Altered source versions must be plainly marked as such, and must
30
+ not be misrepresented as being the original software.
31
+
32
+ 4. The name of the author may not be used to endorse or promote
33
+ products derived from this software without specific prior written
34
+ permission.
35
+
36
+ THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
37
+ OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
38
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
40
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
43
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
44
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
45
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
46
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47
+
48
+ ----------------------------------------------------------------
49
+
50
+ Notice that the above BSD-style license applies to this one file
51
+ (valgrind.h) only. The entire rest of Valgrind is licensed under
52
+ the terms of the GNU General Public License, version 2. See the
53
+ COPYING file in the source distribution for details.
54
+
55
+ ----------------------------------------------------------------
56
+ */
57
+
58
+
59
+ /* This file is for inclusion into client (your!) code.
60
+
61
+ You can use these macros to manipulate and query Valgrind's
62
+ execution inside your own programs.
63
+
64
+ The resulting executables will still run without Valgrind, just a
65
+ little bit more slowly than they otherwise would, but otherwise
66
+ unchanged. When not running on valgrind, each client request
67
+ consumes very few (eg. 7) instructions, so the resulting performance
68
+ loss is negligible unless you plan to execute client requests
69
+ millions of times per second. Nevertheless, if that is still a
70
+ problem, you can compile with the NVALGRIND symbol defined (gcc
71
+ -DNVALGRIND) so that client requests are not even compiled in. */
72
+
73
+ #ifndef __VALGRIND_H
74
+ #define __VALGRIND_H
75
+
76
+ #include <stdarg.h>
77
+ #include <stdint.h>
78
+
79
+ /* Nb: this file might be included in a file compiled with -ansi. So
80
+ we can't use C++ style "//" comments nor the "asm" keyword (instead
81
+ use "__asm__"). */
82
+
83
+ /* Derive some tags indicating what the target platform is. Note
84
+ that in this file we're using the compiler's CPP symbols for
85
+ identifying architectures, which are different to the ones we use
86
+ within the rest of Valgrind. Note, __powerpc__ is active for both
87
+ 32 and 64-bit PPC, whereas __powerpc64__ is only active for the
88
+ latter (on Linux, that is). */
89
+ #undef PLAT_x86_linux
90
+ #undef PLAT_amd64_linux
91
+ #undef PLAT_ppc32_linux
92
+ #undef PLAT_ppc64_linux
93
+ #undef PLAT_ppc32_aix5
94
+ #undef PLAT_ppc64_aix5
95
+
96
+ #if !defined(_AIX) && defined(__i386__)
97
+ # define PLAT_x86_linux 1
98
+ #elif !defined(_AIX) && defined(__x86_64__)
99
+ # define PLAT_amd64_linux 1
100
+ #elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
101
+ # define PLAT_ppc32_linux 1
102
+ #elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
103
+ # define PLAT_ppc64_linux 1
104
+ #elif defined(_AIX) && defined(__64BIT__)
105
+ # define PLAT_ppc64_aix5 1
106
+ #elif defined(_AIX) && !defined(__64BIT__)
107
+ # define PLAT_ppc32_aix5 1
108
+ #endif
109
+
110
+
111
+ /* If we're not compiling for our target platform, don't generate
112
+ any inline asms. */
113
+ #if !defined(PLAT_x86_linux) && !defined(PLAT_amd64_linux) \
114
+ && !defined(PLAT_ppc32_linux) && !defined(PLAT_ppc64_linux) \
115
+ && !defined(PLAT_ppc32_aix5) && !defined(PLAT_ppc64_aix5)
116
+ # if !defined(NVALGRIND)
117
+ # define NVALGRIND 1
118
+ # endif
119
+ #endif
120
+
121
+
122
+ /* ------------------------------------------------------------------ */
123
+ /* ARCHITECTURE SPECIFICS for SPECIAL INSTRUCTIONS. There is nothing */
124
+ /* in here of use to end-users -- skip to the next section. */
125
+ /* ------------------------------------------------------------------ */
126
+
127
+ #if defined(NVALGRIND)
128
+
129
+ /* Define NVALGRIND to completely remove the Valgrind magic sequence
130
+ from the compiled code (analogous to NDEBUG's effects on
131
+ assert()) */
132
+ #define VALGRIND_DO_CLIENT_REQUEST( \
133
+ _zzq_rlval, _zzq_default, _zzq_request, \
134
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
135
+ { \
136
+ (_zzq_rlval) = (_zzq_default); \
137
+ }
138
+
139
+ #else /* ! NVALGRIND */
140
+
141
+ /* The following defines the magic code sequences which the JITter
142
+ spots and handles magically. Don't look too closely at them as
143
+ they will rot your brain.
144
+
145
+ The assembly code sequences for all architectures is in this one
146
+ file. This is because this file must be stand-alone, and we don't
147
+ want to have multiple files.
148
+
149
+ For VALGRIND_DO_CLIENT_REQUEST, we must ensure that the default
150
+ value gets put in the return slot, so that everything works when
151
+ this is executed not under Valgrind. Args are passed in a memory
152
+ block, and so there's no intrinsic limit to the number that could
153
+ be passed, but it's currently five.
154
+
155
+ The macro args are:
156
+ _zzq_rlval result lvalue
157
+ _zzq_default default value (result returned when running on real CPU)
158
+ _zzq_request request code
159
+ _zzq_arg1..5 request params
160
+
161
+ The other two macros are used to support function wrapping, and are
162
+ a lot simpler. VALGRIND_GET_NR_CONTEXT returns the value of the
163
+ guest's NRADDR pseudo-register and whatever other information is
164
+ needed to safely run the call original from the wrapper: on
165
+ ppc64-linux, the R2 value at the divert point is also needed. This
166
+ information is abstracted into a user-visible type, OrigFn.
167
+
168
+ VALGRIND_CALL_NOREDIR_* behaves the same as the following on the
169
+ guest, but guarantees that the branch instruction will not be
170
+ redirected: x86: call *%eax, amd64: call *%rax, ppc32/ppc64:
171
+ branch-and-link-to-r11. VALGRIND_CALL_NOREDIR is just text, not a
172
+ complete inline asm, since it needs to be combined with more magic
173
+ inline asm stuff to be useful.
174
+ */
175
+
176
+ /* ------------------------- x86-linux ------------------------- */
177
+
178
+ #if defined(PLAT_x86_linux)
179
+
180
+ typedef
181
+ struct {
182
+ unsigned int nraddr; /* where's the code? */
183
+ }
184
+ OrigFn;
185
+
186
+ #define __SPECIAL_INSTRUCTION_PREAMBLE \
187
+ "roll $3, %%edi ; roll $13, %%edi\n\t" \
188
+ "roll $29, %%edi ; roll $19, %%edi\n\t"
189
+
190
+ #define VALGRIND_DO_CLIENT_REQUEST( \
191
+ _zzq_rlval, _zzq_default, _zzq_request, \
192
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
193
+ { volatile unsigned int _zzq_args[6]; \
194
+ volatile unsigned int _zzq_result; \
195
+ _zzq_args[0] = (unsigned int)(_zzq_request); \
196
+ _zzq_args[1] = (unsigned int)(_zzq_arg1); \
197
+ _zzq_args[2] = (unsigned int)(_zzq_arg2); \
198
+ _zzq_args[3] = (unsigned int)(_zzq_arg3); \
199
+ _zzq_args[4] = (unsigned int)(_zzq_arg4); \
200
+ _zzq_args[5] = (unsigned int)(_zzq_arg5); \
201
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
202
+ /* %EDX = client_request ( %EAX ) */ \
203
+ "xchgl %%ebx,%%ebx" \
204
+ : "=d" (_zzq_result) \
205
+ : "a" (&_zzq_args[0]), "0" (_zzq_default) \
206
+ : "cc", "memory" \
207
+ ); \
208
+ _zzq_rlval = _zzq_result; \
209
+ }
210
+
211
+ #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
212
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
213
+ volatile unsigned int __addr; \
214
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
215
+ /* %EAX = guest_NRADDR */ \
216
+ "xchgl %%ecx,%%ecx" \
217
+ : "=a" (__addr) \
218
+ : \
219
+ : "cc", "memory" \
220
+ ); \
221
+ _zzq_orig->nraddr = __addr; \
222
+ }
223
+
224
+ #define VALGRIND_CALL_NOREDIR_EAX \
225
+ __SPECIAL_INSTRUCTION_PREAMBLE \
226
+ /* call-noredir *%EAX */ \
227
+ "xchgl %%edx,%%edx\n\t"
228
+ #endif /* PLAT_x86_linux */
229
+
230
+ /* ------------------------ amd64-linux ------------------------ */
231
+
232
+ #if defined(PLAT_amd64_linux)
233
+
234
+ typedef
235
+ struct {
236
+ uint64_t nraddr; /* where's the code? */
237
+ }
238
+ OrigFn;
239
+
240
+ #define __SPECIAL_INSTRUCTION_PREAMBLE \
241
+ "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \
242
+ "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
243
+
244
+ #define VALGRIND_DO_CLIENT_REQUEST( \
245
+ _zzq_rlval, _zzq_default, _zzq_request, \
246
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
247
+ { volatile uint64_t _zzq_args[6]; \
248
+ volatile uint64_t _zzq_result; \
249
+ _zzq_args[0] = (uint64_t)(_zzq_request); \
250
+ _zzq_args[1] = (uint64_t)(_zzq_arg1); \
251
+ _zzq_args[2] = (uint64_t)(_zzq_arg2); \
252
+ _zzq_args[3] = (uint64_t)(_zzq_arg3); \
253
+ _zzq_args[4] = (uint64_t)(_zzq_arg4); \
254
+ _zzq_args[5] = (uint64_t)(_zzq_arg5); \
255
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
256
+ /* %RDX = client_request ( %RAX ) */ \
257
+ "xchgq %%rbx,%%rbx" \
258
+ : "=d" (_zzq_result) \
259
+ : "a" (&_zzq_args[0]), "0" (_zzq_default) \
260
+ : "cc", "memory" \
261
+ ); \
262
+ _zzq_rlval = _zzq_result; \
263
+ }
264
+
265
+ #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
266
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
267
+ volatile uint64_t __addr; \
268
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
269
+ /* %RAX = guest_NRADDR */ \
270
+ "xchgq %%rcx,%%rcx" \
271
+ : "=a" (__addr) \
272
+ : \
273
+ : "cc", "memory" \
274
+ ); \
275
+ _zzq_orig->nraddr = __addr; \
276
+ }
277
+
278
+ #define VALGRIND_CALL_NOREDIR_RAX \
279
+ __SPECIAL_INSTRUCTION_PREAMBLE \
280
+ /* call-noredir *%RAX */ \
281
+ "xchgq %%rdx,%%rdx\n\t"
282
+ #endif /* PLAT_amd64_linux */
283
+
284
+ /* ------------------------ ppc32-linux ------------------------ */
285
+
286
+ #if defined(PLAT_ppc32_linux)
287
+
288
+ typedef
289
+ struct {
290
+ unsigned int nraddr; /* where's the code? */
291
+ }
292
+ OrigFn;
293
+
294
+ #define __SPECIAL_INSTRUCTION_PREAMBLE \
295
+ "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
296
+ "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
297
+
298
+ #define VALGRIND_DO_CLIENT_REQUEST( \
299
+ _zzq_rlval, _zzq_default, _zzq_request, \
300
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
301
+ \
302
+ { unsigned int _zzq_args[6]; \
303
+ unsigned int _zzq_result; \
304
+ unsigned int* _zzq_ptr; \
305
+ _zzq_args[0] = (unsigned int)(_zzq_request); \
306
+ _zzq_args[1] = (unsigned int)(_zzq_arg1); \
307
+ _zzq_args[2] = (unsigned int)(_zzq_arg2); \
308
+ _zzq_args[3] = (unsigned int)(_zzq_arg3); \
309
+ _zzq_args[4] = (unsigned int)(_zzq_arg4); \
310
+ _zzq_args[5] = (unsigned int)(_zzq_arg5); \
311
+ _zzq_ptr = _zzq_args; \
312
+ __asm__ volatile("mr 3,%1\n\t" /*default*/ \
313
+ "mr 4,%2\n\t" /*ptr*/ \
314
+ __SPECIAL_INSTRUCTION_PREAMBLE \
315
+ /* %R3 = client_request ( %R4 ) */ \
316
+ "or 1,1,1\n\t" \
317
+ "mr %0,3" /*result*/ \
318
+ : "=b" (_zzq_result) \
319
+ : "b" (_zzq_default), "b" (_zzq_ptr) \
320
+ : "cc", "memory", "r3", "r4"); \
321
+ _zzq_rlval = _zzq_result; \
322
+ }
323
+
324
+ #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
325
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
326
+ unsigned int __addr; \
327
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
328
+ /* %R3 = guest_NRADDR */ \
329
+ "or 2,2,2\n\t" \
330
+ "mr %0,3" \
331
+ : "=b" (__addr) \
332
+ : \
333
+ : "cc", "memory", "r3" \
334
+ ); \
335
+ _zzq_orig->nraddr = __addr; \
336
+ }
337
+
338
+ #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
339
+ __SPECIAL_INSTRUCTION_PREAMBLE \
340
+ /* branch-and-link-to-noredir *%R11 */ \
341
+ "or 3,3,3\n\t"
342
+ #endif /* PLAT_ppc32_linux */
343
+
344
+ /* ------------------------ ppc64-linux ------------------------ */
345
+
346
+ #if defined(PLAT_ppc64_linux)
347
+
348
+ typedef
349
+ struct {
350
+ uint64_t nraddr; /* where's the code? */
351
+ uint64_t r2; /* what tocptr do we need? */
352
+ }
353
+ OrigFn;
354
+
355
+ #define __SPECIAL_INSTRUCTION_PREAMBLE \
356
+ "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
357
+ "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
358
+
359
+ #define VALGRIND_DO_CLIENT_REQUEST( \
360
+ _zzq_rlval, _zzq_default, _zzq_request, \
361
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
362
+ \
363
+ { uint64_t _zzq_args[6]; \
364
+ register uint64_t _zzq_result __asm__("r3"); \
365
+ register uint64_t* _zzq_ptr __asm__("r4"); \
366
+ _zzq_args[0] = (uint64_t)(_zzq_request); \
367
+ _zzq_args[1] = (uint64_t)(_zzq_arg1); \
368
+ _zzq_args[2] = (uint64_t)(_zzq_arg2); \
369
+ _zzq_args[3] = (uint64_t)(_zzq_arg3); \
370
+ _zzq_args[4] = (uint64_t)(_zzq_arg4); \
371
+ _zzq_args[5] = (uint64_t)(_zzq_arg5); \
372
+ _zzq_ptr = _zzq_args; \
373
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
374
+ /* %R3 = client_request ( %R4 ) */ \
375
+ "or 1,1,1" \
376
+ : "=r" (_zzq_result) \
377
+ : "0" (_zzq_default), "r" (_zzq_ptr) \
378
+ : "cc", "memory"); \
379
+ _zzq_rlval = _zzq_result; \
380
+ }
381
+
382
+ #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
383
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
384
+ register uint64_t __addr __asm__("r3"); \
385
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
386
+ /* %R3 = guest_NRADDR */ \
387
+ "or 2,2,2" \
388
+ : "=r" (__addr) \
389
+ : \
390
+ : "cc", "memory" \
391
+ ); \
392
+ _zzq_orig->nraddr = __addr; \
393
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
394
+ /* %R3 = guest_NRADDR_GPR2 */ \
395
+ "or 4,4,4" \
396
+ : "=r" (__addr) \
397
+ : \
398
+ : "cc", "memory" \
399
+ ); \
400
+ _zzq_orig->r2 = __addr; \
401
+ }
402
+
403
+ #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
404
+ __SPECIAL_INSTRUCTION_PREAMBLE \
405
+ /* branch-and-link-to-noredir *%R11 */ \
406
+ "or 3,3,3\n\t"
407
+
408
+ #endif /* PLAT_ppc64_linux */
409
+
410
+ /* ------------------------ ppc32-aix5 ------------------------- */
411
+
412
+ #if defined(PLAT_ppc32_aix5)
413
+
414
+ typedef
415
+ struct {
416
+ unsigned int nraddr; /* where's the code? */
417
+ unsigned int r2; /* what tocptr do we need? */
418
+ }
419
+ OrigFn;
420
+
421
+ #define __SPECIAL_INSTRUCTION_PREAMBLE \
422
+ "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
423
+ "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
424
+
425
+ #define VALGRIND_DO_CLIENT_REQUEST( \
426
+ _zzq_rlval, _zzq_default, _zzq_request, \
427
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
428
+ \
429
+ { unsigned int _zzq_args[7]; \
430
+ register unsigned int _zzq_result; \
431
+ register unsigned int* _zzq_ptr; \
432
+ _zzq_args[0] = (unsigned int)(_zzq_request); \
433
+ _zzq_args[1] = (unsigned int)(_zzq_arg1); \
434
+ _zzq_args[2] = (unsigned int)(_zzq_arg2); \
435
+ _zzq_args[3] = (unsigned int)(_zzq_arg3); \
436
+ _zzq_args[4] = (unsigned int)(_zzq_arg4); \
437
+ _zzq_args[5] = (unsigned int)(_zzq_arg5); \
438
+ _zzq_args[6] = (unsigned int)(_zzq_default); \
439
+ _zzq_ptr = _zzq_args; \
440
+ __asm__ volatile("mr 4,%1\n\t" \
441
+ "lwz 3, 24(4)\n\t" \
442
+ __SPECIAL_INSTRUCTION_PREAMBLE \
443
+ /* %R3 = client_request ( %R4 ) */ \
444
+ "or 1,1,1\n\t" \
445
+ "mr %0,3" \
446
+ : "=b" (_zzq_result) \
447
+ : "b" (_zzq_ptr) \
448
+ : "r3", "r4", "cc", "memory"); \
449
+ _zzq_rlval = _zzq_result; \
450
+ }
451
+
452
+ #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
453
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
454
+ register unsigned int __addr; \
455
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
456
+ /* %R3 = guest_NRADDR */ \
457
+ "or 2,2,2\n\t" \
458
+ "mr %0,3" \
459
+ : "=b" (__addr) \
460
+ : \
461
+ : "r3", "cc", "memory" \
462
+ ); \
463
+ _zzq_orig->nraddr = __addr; \
464
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
465
+ /* %R3 = guest_NRADDR_GPR2 */ \
466
+ "or 4,4,4\n\t" \
467
+ "mr %0,3" \
468
+ : "=b" (__addr) \
469
+ : \
470
+ : "r3", "cc", "memory" \
471
+ ); \
472
+ _zzq_orig->r2 = __addr; \
473
+ }
474
+
475
+ #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
476
+ __SPECIAL_INSTRUCTION_PREAMBLE \
477
+ /* branch-and-link-to-noredir *%R11 */ \
478
+ "or 3,3,3\n\t"
479
+
480
+ #endif /* PLAT_ppc32_aix5 */
481
+
482
+ /* ------------------------ ppc64-aix5 ------------------------- */
483
+
484
+ #if defined(PLAT_ppc64_aix5)
485
+
486
+ typedef
487
+ struct {
488
+ uint64_t nraddr; /* where's the code? */
489
+ uint64_t r2; /* what tocptr do we need? */
490
+ }
491
+ OrigFn;
492
+
493
+ #define __SPECIAL_INSTRUCTION_PREAMBLE \
494
+ "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
495
+ "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
496
+
497
+ #define VALGRIND_DO_CLIENT_REQUEST( \
498
+ _zzq_rlval, _zzq_default, _zzq_request, \
499
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
500
+ \
501
+ { uint64_t _zzq_args[7]; \
502
+ register uint64_t _zzq_result; \
503
+ register uint64_t* _zzq_ptr; \
504
+ _zzq_args[0] = (unsigned int long long)(_zzq_request); \
505
+ _zzq_args[1] = (unsigned int long long)(_zzq_arg1); \
506
+ _zzq_args[2] = (unsigned int long long)(_zzq_arg2); \
507
+ _zzq_args[3] = (unsigned int long long)(_zzq_arg3); \
508
+ _zzq_args[4] = (unsigned int long long)(_zzq_arg4); \
509
+ _zzq_args[5] = (unsigned int long long)(_zzq_arg5); \
510
+ _zzq_args[6] = (unsigned int long long)(_zzq_default); \
511
+ _zzq_ptr = _zzq_args; \
512
+ __asm__ volatile("mr 4,%1\n\t" \
513
+ "ld 3, 48(4)\n\t" \
514
+ __SPECIAL_INSTRUCTION_PREAMBLE \
515
+ /* %R3 = client_request ( %R4 ) */ \
516
+ "or 1,1,1\n\t" \
517
+ "mr %0,3" \
518
+ : "=b" (_zzq_result) \
519
+ : "b" (_zzq_ptr) \
520
+ : "r3", "r4", "cc", "memory"); \
521
+ _zzq_rlval = _zzq_result; \
522
+ }
523
+
524
+ #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
525
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
526
+ register uint64_t __addr; \
527
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
528
+ /* %R3 = guest_NRADDR */ \
529
+ "or 2,2,2\n\t" \
530
+ "mr %0,3" \
531
+ : "=b" (__addr) \
532
+ : \
533
+ : "r3", "cc", "memory" \
534
+ ); \
535
+ _zzq_orig->nraddr = __addr; \
536
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
537
+ /* %R3 = guest_NRADDR_GPR2 */ \
538
+ "or 4,4,4\n\t" \
539
+ "mr %0,3" \
540
+ : "=b" (__addr) \
541
+ : \
542
+ : "r3", "cc", "memory" \
543
+ ); \
544
+ _zzq_orig->r2 = __addr; \
545
+ }
546
+
547
+ #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
548
+ __SPECIAL_INSTRUCTION_PREAMBLE \
549
+ /* branch-and-link-to-noredir *%R11 */ \
550
+ "or 3,3,3\n\t"
551
+
552
+ #endif /* PLAT_ppc64_aix5 */
553
+
554
+ /* Insert assembly code for other platforms here... */
555
+
556
+ #endif /* NVALGRIND */
557
+
558
+
559
+ /* ------------------------------------------------------------------ */
560
+ /* PLATFORM SPECIFICS for FUNCTION WRAPPING. This is all very */
561
+ /* ugly. It's the least-worst tradeoff I can think of. */
562
+ /* ------------------------------------------------------------------ */
563
+
564
+ /* This section defines magic (a.k.a appalling-hack) macros for doing
565
+ guaranteed-no-redirection macros, so as to get from function
566
+ wrappers to the functions they are wrapping. The whole point is to
567
+ construct standard call sequences, but to do the call itself with a
568
+ special no-redirect call pseudo-instruction that the JIT
569
+ understands and handles specially. This section is long and
570
+ repetitious, and I can't see a way to make it shorter.
571
+
572
+ The naming scheme is as follows:
573
+
574
+ CALL_FN_{W,v}_{v,W,WW,WWW,WWWW,5W,6W,7W,etc}
575
+
576
+ 'W' stands for "word" and 'v' for "void". Hence there are
577
+ different macros for calling arity 0, 1, 2, 3, 4, etc, functions,
578
+ and for each, the possibility of returning a word-typed result, or
579
+ no result.
580
+ */
581
+
582
+ /* Use these to write the name of your wrapper. NOTE: duplicates
583
+ VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
584
+
585
+ #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
586
+ _vgwZU_##soname##_##fnname
587
+
588
+ #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
589
+ _vgwZZ_##soname##_##fnname
590
+
591
+ /* Use this macro from within a wrapper function to collect the
592
+ context (address and possibly other info) of the original function.
593
+ Once you have that you can then use it in one of the CALL_FN_
594
+ macros. The type of the argument _lval is OrigFn. */
595
+ #define VALGRIND_GET_ORIG_FN(_lval) VALGRIND_GET_NR_CONTEXT(_lval)
596
+
597
+ /* Derivatives of the main macros below, for calling functions
598
+ returning void. */
599
+
600
+ #define CALL_FN_v_v(fnptr) \
601
+ do { volatile unsigned long _junk; \
602
+ CALL_FN_W_v(_junk,fnptr); } while (0)
603
+
604
+ #define CALL_FN_v_W(fnptr, arg1) \
605
+ do { volatile unsigned long _junk; \
606
+ CALL_FN_W_W(_junk,fnptr,arg1); } while (0)
607
+
608
+ #define CALL_FN_v_WW(fnptr, arg1,arg2) \
609
+ do { volatile unsigned long _junk; \
610
+ CALL_FN_W_WW(_junk,fnptr,arg1,arg2); } while (0)
611
+
612
+ #define CALL_FN_v_WWW(fnptr, arg1,arg2,arg3) \
613
+ do { volatile unsigned long _junk; \
614
+ CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
615
+
616
+ /* ------------------------- x86-linux ------------------------- */
617
+
618
+ #if defined(PLAT_x86_linux)
619
+
620
+ /* These regs are trashed by the hidden call. No need to mention eax
621
+ as gcc can already see that, plus causes gcc to bomb. */
622
+ #define __CALLER_SAVED_REGS /*"eax"*/ "ecx", "edx"
623
+
624
+ /* These CALL_FN_ macros assume that on x86-linux, sizeof(unsigned
625
+ long) == 4. */
626
+
627
+ #define CALL_FN_W_v(lval, orig) \
628
+ do { \
629
+ volatile OrigFn _orig = (orig); \
630
+ volatile unsigned long _argvec[1]; \
631
+ volatile unsigned long _res; \
632
+ _argvec[0] = (unsigned long)_orig.nraddr; \
633
+ __asm__ volatile( \
634
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
635
+ VALGRIND_CALL_NOREDIR_EAX \
636
+ : /*out*/ "=a" (_res) \
637
+ : /*in*/ "a" (&_argvec[0]) \
638
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
639
+ ); \
640
+ lval = (__typeof__(lval)) _res; \
641
+ } while (0)
642
+
643
+ #define CALL_FN_W_W(lval, orig, arg1) \
644
+ do { \
645
+ volatile OrigFn _orig = (orig); \
646
+ volatile unsigned long _argvec[2]; \
647
+ volatile unsigned long _res; \
648
+ _argvec[0] = (unsigned long)_orig.nraddr; \
649
+ _argvec[1] = (unsigned long)(arg1); \
650
+ __asm__ volatile( \
651
+ "pushl 4(%%eax)\n\t" \
652
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
653
+ VALGRIND_CALL_NOREDIR_EAX \
654
+ "addl $4, %%esp\n" \
655
+ : /*out*/ "=a" (_res) \
656
+ : /*in*/ "a" (&_argvec[0]) \
657
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
658
+ ); \
659
+ lval = (__typeof__(lval)) _res; \
660
+ } while (0)
661
+
662
+ #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
663
+ do { \
664
+ volatile OrigFn _orig = (orig); \
665
+ volatile unsigned long _argvec[3]; \
666
+ volatile unsigned long _res; \
667
+ _argvec[0] = (unsigned long)_orig.nraddr; \
668
+ _argvec[1] = (unsigned long)(arg1); \
669
+ _argvec[2] = (unsigned long)(arg2); \
670
+ __asm__ volatile( \
671
+ "pushl 8(%%eax)\n\t" \
672
+ "pushl 4(%%eax)\n\t" \
673
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
674
+ VALGRIND_CALL_NOREDIR_EAX \
675
+ "addl $8, %%esp\n" \
676
+ : /*out*/ "=a" (_res) \
677
+ : /*in*/ "a" (&_argvec[0]) \
678
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
679
+ ); \
680
+ lval = (__typeof__(lval)) _res; \
681
+ } while (0)
682
+
683
+ #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
684
+ do { \
685
+ volatile OrigFn _orig = (orig); \
686
+ volatile unsigned long _argvec[4]; \
687
+ volatile unsigned long _res; \
688
+ _argvec[0] = (unsigned long)_orig.nraddr; \
689
+ _argvec[1] = (unsigned long)(arg1); \
690
+ _argvec[2] = (unsigned long)(arg2); \
691
+ _argvec[3] = (unsigned long)(arg3); \
692
+ __asm__ volatile( \
693
+ "pushl 12(%%eax)\n\t" \
694
+ "pushl 8(%%eax)\n\t" \
695
+ "pushl 4(%%eax)\n\t" \
696
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
697
+ VALGRIND_CALL_NOREDIR_EAX \
698
+ "addl $12, %%esp\n" \
699
+ : /*out*/ "=a" (_res) \
700
+ : /*in*/ "a" (&_argvec[0]) \
701
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
702
+ ); \
703
+ lval = (__typeof__(lval)) _res; \
704
+ } while (0)
705
+
706
+ #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
707
+ do { \
708
+ volatile OrigFn _orig = (orig); \
709
+ volatile unsigned long _argvec[5]; \
710
+ volatile unsigned long _res; \
711
+ _argvec[0] = (unsigned long)_orig.nraddr; \
712
+ _argvec[1] = (unsigned long)(arg1); \
713
+ _argvec[2] = (unsigned long)(arg2); \
714
+ _argvec[3] = (unsigned long)(arg3); \
715
+ _argvec[4] = (unsigned long)(arg4); \
716
+ __asm__ volatile( \
717
+ "pushl 16(%%eax)\n\t" \
718
+ "pushl 12(%%eax)\n\t" \
719
+ "pushl 8(%%eax)\n\t" \
720
+ "pushl 4(%%eax)\n\t" \
721
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
722
+ VALGRIND_CALL_NOREDIR_EAX \
723
+ "addl $16, %%esp\n" \
724
+ : /*out*/ "=a" (_res) \
725
+ : /*in*/ "a" (&_argvec[0]) \
726
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
727
+ ); \
728
+ lval = (__typeof__(lval)) _res; \
729
+ } while (0)
730
+
731
+ #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
732
+ do { \
733
+ volatile OrigFn _orig = (orig); \
734
+ volatile unsigned long _argvec[6]; \
735
+ volatile unsigned long _res; \
736
+ _argvec[0] = (unsigned long)_orig.nraddr; \
737
+ _argvec[1] = (unsigned long)(arg1); \
738
+ _argvec[2] = (unsigned long)(arg2); \
739
+ _argvec[3] = (unsigned long)(arg3); \
740
+ _argvec[4] = (unsigned long)(arg4); \
741
+ _argvec[5] = (unsigned long)(arg5); \
742
+ __asm__ volatile( \
743
+ "pushl 20(%%eax)\n\t" \
744
+ "pushl 16(%%eax)\n\t" \
745
+ "pushl 12(%%eax)\n\t" \
746
+ "pushl 8(%%eax)\n\t" \
747
+ "pushl 4(%%eax)\n\t" \
748
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
749
+ VALGRIND_CALL_NOREDIR_EAX \
750
+ "addl $20, %%esp\n" \
751
+ : /*out*/ "=a" (_res) \
752
+ : /*in*/ "a" (&_argvec[0]) \
753
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
754
+ ); \
755
+ lval = (__typeof__(lval)) _res; \
756
+ } while (0)
757
+
758
+ #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
759
+ do { \
760
+ volatile OrigFn _orig = (orig); \
761
+ volatile unsigned long _argvec[7]; \
762
+ volatile unsigned long _res; \
763
+ _argvec[0] = (unsigned long)_orig.nraddr; \
764
+ _argvec[1] = (unsigned long)(arg1); \
765
+ _argvec[2] = (unsigned long)(arg2); \
766
+ _argvec[3] = (unsigned long)(arg3); \
767
+ _argvec[4] = (unsigned long)(arg4); \
768
+ _argvec[5] = (unsigned long)(arg5); \
769
+ _argvec[6] = (unsigned long)(arg6); \
770
+ __asm__ volatile( \
771
+ "pushl 24(%%eax)\n\t" \
772
+ "pushl 20(%%eax)\n\t" \
773
+ "pushl 16(%%eax)\n\t" \
774
+ "pushl 12(%%eax)\n\t" \
775
+ "pushl 8(%%eax)\n\t" \
776
+ "pushl 4(%%eax)\n\t" \
777
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
778
+ VALGRIND_CALL_NOREDIR_EAX \
779
+ "addl $24, %%esp\n" \
780
+ : /*out*/ "=a" (_res) \
781
+ : /*in*/ "a" (&_argvec[0]) \
782
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
783
+ ); \
784
+ lval = (__typeof__(lval)) _res; \
785
+ } while (0)
786
+
787
+ #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
788
+ arg7) \
789
+ do { \
790
+ volatile OrigFn _orig = (orig); \
791
+ volatile unsigned long _argvec[8]; \
792
+ volatile unsigned long _res; \
793
+ _argvec[0] = (unsigned long)_orig.nraddr; \
794
+ _argvec[1] = (unsigned long)(arg1); \
795
+ _argvec[2] = (unsigned long)(arg2); \
796
+ _argvec[3] = (unsigned long)(arg3); \
797
+ _argvec[4] = (unsigned long)(arg4); \
798
+ _argvec[5] = (unsigned long)(arg5); \
799
+ _argvec[6] = (unsigned long)(arg6); \
800
+ _argvec[7] = (unsigned long)(arg7); \
801
+ __asm__ volatile( \
802
+ "pushl 28(%%eax)\n\t" \
803
+ "pushl 24(%%eax)\n\t" \
804
+ "pushl 20(%%eax)\n\t" \
805
+ "pushl 16(%%eax)\n\t" \
806
+ "pushl 12(%%eax)\n\t" \
807
+ "pushl 8(%%eax)\n\t" \
808
+ "pushl 4(%%eax)\n\t" \
809
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
810
+ VALGRIND_CALL_NOREDIR_EAX \
811
+ "addl $28, %%esp\n" \
812
+ : /*out*/ "=a" (_res) \
813
+ : /*in*/ "a" (&_argvec[0]) \
814
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
815
+ ); \
816
+ lval = (__typeof__(lval)) _res; \
817
+ } while (0)
818
+
819
+ #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
820
+ arg7,arg8) \
821
+ do { \
822
+ volatile OrigFn _orig = (orig); \
823
+ volatile unsigned long _argvec[9]; \
824
+ volatile unsigned long _res; \
825
+ _argvec[0] = (unsigned long)_orig.nraddr; \
826
+ _argvec[1] = (unsigned long)(arg1); \
827
+ _argvec[2] = (unsigned long)(arg2); \
828
+ _argvec[3] = (unsigned long)(arg3); \
829
+ _argvec[4] = (unsigned long)(arg4); \
830
+ _argvec[5] = (unsigned long)(arg5); \
831
+ _argvec[6] = (unsigned long)(arg6); \
832
+ _argvec[7] = (unsigned long)(arg7); \
833
+ _argvec[8] = (unsigned long)(arg8); \
834
+ __asm__ volatile( \
835
+ "pushl 32(%%eax)\n\t" \
836
+ "pushl 28(%%eax)\n\t" \
837
+ "pushl 24(%%eax)\n\t" \
838
+ "pushl 20(%%eax)\n\t" \
839
+ "pushl 16(%%eax)\n\t" \
840
+ "pushl 12(%%eax)\n\t" \
841
+ "pushl 8(%%eax)\n\t" \
842
+ "pushl 4(%%eax)\n\t" \
843
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
844
+ VALGRIND_CALL_NOREDIR_EAX \
845
+ "addl $32, %%esp\n" \
846
+ : /*out*/ "=a" (_res) \
847
+ : /*in*/ "a" (&_argvec[0]) \
848
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
849
+ ); \
850
+ lval = (__typeof__(lval)) _res; \
851
+ } while (0)
852
+
853
+ #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
854
+ arg7,arg8,arg9) \
855
+ do { \
856
+ volatile OrigFn _orig = (orig); \
857
+ volatile unsigned long _argvec[10]; \
858
+ volatile unsigned long _res; \
859
+ _argvec[0] = (unsigned long)_orig.nraddr; \
860
+ _argvec[1] = (unsigned long)(arg1); \
861
+ _argvec[2] = (unsigned long)(arg2); \
862
+ _argvec[3] = (unsigned long)(arg3); \
863
+ _argvec[4] = (unsigned long)(arg4); \
864
+ _argvec[5] = (unsigned long)(arg5); \
865
+ _argvec[6] = (unsigned long)(arg6); \
866
+ _argvec[7] = (unsigned long)(arg7); \
867
+ _argvec[8] = (unsigned long)(arg8); \
868
+ _argvec[9] = (unsigned long)(arg9); \
869
+ __asm__ volatile( \
870
+ "pushl 36(%%eax)\n\t" \
871
+ "pushl 32(%%eax)\n\t" \
872
+ "pushl 28(%%eax)\n\t" \
873
+ "pushl 24(%%eax)\n\t" \
874
+ "pushl 20(%%eax)\n\t" \
875
+ "pushl 16(%%eax)\n\t" \
876
+ "pushl 12(%%eax)\n\t" \
877
+ "pushl 8(%%eax)\n\t" \
878
+ "pushl 4(%%eax)\n\t" \
879
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
880
+ VALGRIND_CALL_NOREDIR_EAX \
881
+ "addl $36, %%esp\n" \
882
+ : /*out*/ "=a" (_res) \
883
+ : /*in*/ "a" (&_argvec[0]) \
884
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
885
+ ); \
886
+ lval = (__typeof__(lval)) _res; \
887
+ } while (0)
888
+
889
+ #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
890
+ arg7,arg8,arg9,arg10) \
891
+ do { \
892
+ volatile OrigFn _orig = (orig); \
893
+ volatile unsigned long _argvec[11]; \
894
+ volatile unsigned long _res; \
895
+ _argvec[0] = (unsigned long)_orig.nraddr; \
896
+ _argvec[1] = (unsigned long)(arg1); \
897
+ _argvec[2] = (unsigned long)(arg2); \
898
+ _argvec[3] = (unsigned long)(arg3); \
899
+ _argvec[4] = (unsigned long)(arg4); \
900
+ _argvec[5] = (unsigned long)(arg5); \
901
+ _argvec[6] = (unsigned long)(arg6); \
902
+ _argvec[7] = (unsigned long)(arg7); \
903
+ _argvec[8] = (unsigned long)(arg8); \
904
+ _argvec[9] = (unsigned long)(arg9); \
905
+ _argvec[10] = (unsigned long)(arg10); \
906
+ __asm__ volatile( \
907
+ "pushl 40(%%eax)\n\t" \
908
+ "pushl 36(%%eax)\n\t" \
909
+ "pushl 32(%%eax)\n\t" \
910
+ "pushl 28(%%eax)\n\t" \
911
+ "pushl 24(%%eax)\n\t" \
912
+ "pushl 20(%%eax)\n\t" \
913
+ "pushl 16(%%eax)\n\t" \
914
+ "pushl 12(%%eax)\n\t" \
915
+ "pushl 8(%%eax)\n\t" \
916
+ "pushl 4(%%eax)\n\t" \
917
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
918
+ VALGRIND_CALL_NOREDIR_EAX \
919
+ "addl $40, %%esp\n" \
920
+ : /*out*/ "=a" (_res) \
921
+ : /*in*/ "a" (&_argvec[0]) \
922
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
923
+ ); \
924
+ lval = (__typeof__(lval)) _res; \
925
+ } while (0)
926
+
927
+ #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
928
+ arg6,arg7,arg8,arg9,arg10, \
929
+ arg11) \
930
+ do { \
931
+ volatile OrigFn _orig = (orig); \
932
+ volatile unsigned long _argvec[12]; \
933
+ volatile unsigned long _res; \
934
+ _argvec[0] = (unsigned long)_orig.nraddr; \
935
+ _argvec[1] = (unsigned long)(arg1); \
936
+ _argvec[2] = (unsigned long)(arg2); \
937
+ _argvec[3] = (unsigned long)(arg3); \
938
+ _argvec[4] = (unsigned long)(arg4); \
939
+ _argvec[5] = (unsigned long)(arg5); \
940
+ _argvec[6] = (unsigned long)(arg6); \
941
+ _argvec[7] = (unsigned long)(arg7); \
942
+ _argvec[8] = (unsigned long)(arg8); \
943
+ _argvec[9] = (unsigned long)(arg9); \
944
+ _argvec[10] = (unsigned long)(arg10); \
945
+ _argvec[11] = (unsigned long)(arg11); \
946
+ __asm__ volatile( \
947
+ "pushl 44(%%eax)\n\t" \
948
+ "pushl 40(%%eax)\n\t" \
949
+ "pushl 36(%%eax)\n\t" \
950
+ "pushl 32(%%eax)\n\t" \
951
+ "pushl 28(%%eax)\n\t" \
952
+ "pushl 24(%%eax)\n\t" \
953
+ "pushl 20(%%eax)\n\t" \
954
+ "pushl 16(%%eax)\n\t" \
955
+ "pushl 12(%%eax)\n\t" \
956
+ "pushl 8(%%eax)\n\t" \
957
+ "pushl 4(%%eax)\n\t" \
958
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
959
+ VALGRIND_CALL_NOREDIR_EAX \
960
+ "addl $44, %%esp\n" \
961
+ : /*out*/ "=a" (_res) \
962
+ : /*in*/ "a" (&_argvec[0]) \
963
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
964
+ ); \
965
+ lval = (__typeof__(lval)) _res; \
966
+ } while (0)
967
+
968
+ #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
969
+ arg6,arg7,arg8,arg9,arg10, \
970
+ arg11,arg12) \
971
+ do { \
972
+ volatile OrigFn _orig = (orig); \
973
+ volatile unsigned long _argvec[13]; \
974
+ volatile unsigned long _res; \
975
+ _argvec[0] = (unsigned long)_orig.nraddr; \
976
+ _argvec[1] = (unsigned long)(arg1); \
977
+ _argvec[2] = (unsigned long)(arg2); \
978
+ _argvec[3] = (unsigned long)(arg3); \
979
+ _argvec[4] = (unsigned long)(arg4); \
980
+ _argvec[5] = (unsigned long)(arg5); \
981
+ _argvec[6] = (unsigned long)(arg6); \
982
+ _argvec[7] = (unsigned long)(arg7); \
983
+ _argvec[8] = (unsigned long)(arg8); \
984
+ _argvec[9] = (unsigned long)(arg9); \
985
+ _argvec[10] = (unsigned long)(arg10); \
986
+ _argvec[11] = (unsigned long)(arg11); \
987
+ _argvec[12] = (unsigned long)(arg12); \
988
+ __asm__ volatile( \
989
+ "pushl 48(%%eax)\n\t" \
990
+ "pushl 44(%%eax)\n\t" \
991
+ "pushl 40(%%eax)\n\t" \
992
+ "pushl 36(%%eax)\n\t" \
993
+ "pushl 32(%%eax)\n\t" \
994
+ "pushl 28(%%eax)\n\t" \
995
+ "pushl 24(%%eax)\n\t" \
996
+ "pushl 20(%%eax)\n\t" \
997
+ "pushl 16(%%eax)\n\t" \
998
+ "pushl 12(%%eax)\n\t" \
999
+ "pushl 8(%%eax)\n\t" \
1000
+ "pushl 4(%%eax)\n\t" \
1001
+ "movl (%%eax), %%eax\n\t" /* target->%eax */ \
1002
+ VALGRIND_CALL_NOREDIR_EAX \
1003
+ "addl $48, %%esp\n" \
1004
+ : /*out*/ "=a" (_res) \
1005
+ : /*in*/ "a" (&_argvec[0]) \
1006
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1007
+ ); \
1008
+ lval = (__typeof__(lval)) _res; \
1009
+ } while (0)
1010
+
1011
+ #endif /* PLAT_x86_linux */
1012
+
1013
+ /* ------------------------ amd64-linux ------------------------ */
1014
+
1015
+ #if defined(PLAT_amd64_linux)
1016
+
1017
+ /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
1018
+
1019
+ /* These regs are trashed by the hidden call. */
1020
+ #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \
1021
+ "rdi", "r8", "r9", "r10", "r11"
1022
+
1023
+ /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
1024
+ long) == 8. */
1025
+
1026
+ /* NB 9 Sept 07. There is a nasty kludge here in all these CALL_FN_
1027
+ macros. In order not to trash the stack redzone, we need to drop
1028
+ %rsp by 128 before the hidden call, and restore afterwards. The
1029
+ nastyness is that it is only by luck that the stack still appears
1030
+ to be unwindable during the hidden call - since then the behaviour
1031
+ of any routine using this macro does not match what the CFI data
1032
+ says. Sigh.
1033
+
1034
+ Why is this important? Imagine that a wrapper has a stack
1035
+ allocated local, and passes to the hidden call, a pointer to it.
1036
+ Because gcc does not know about the hidden call, it may allocate
1037
+ that local in the redzone. Unfortunately the hidden call may then
1038
+ trash it before it comes to use it. So we must step clear of the
1039
+ redzone, for the duration of the hidden call, to make it safe.
1040
+
1041
+ Probably the same problem afflicts the other redzone-style ABIs too
1042
+ (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
1043
+ self describing (none of this CFI nonsense) so at least messing
1044
+ with the stack pointer doesn't give a danger of non-unwindable
1045
+ stack. */
1046
+
1047
+ #define CALL_FN_W_v(lval, orig) \
1048
+ do { \
1049
+ volatile OrigFn _orig = (orig); \
1050
+ volatile unsigned long _argvec[1]; \
1051
+ volatile unsigned long _res; \
1052
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1053
+ __asm__ volatile( \
1054
+ "subq $128,%%rsp\n\t" \
1055
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1056
+ VALGRIND_CALL_NOREDIR_RAX \
1057
+ "addq $128,%%rsp\n\t" \
1058
+ : /*out*/ "=a" (_res) \
1059
+ : /*in*/ "a" (&_argvec[0]) \
1060
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1061
+ ); \
1062
+ lval = (__typeof__(lval)) _res; \
1063
+ } while (0)
1064
+
1065
+ #define CALL_FN_W_W(lval, orig, arg1) \
1066
+ do { \
1067
+ volatile OrigFn _orig = (orig); \
1068
+ volatile unsigned long _argvec[2]; \
1069
+ volatile unsigned long _res; \
1070
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1071
+ _argvec[1] = (unsigned long)(arg1); \
1072
+ __asm__ volatile( \
1073
+ "subq $128,%%rsp\n\t" \
1074
+ "movq 8(%%rax), %%rdi\n\t" \
1075
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1076
+ VALGRIND_CALL_NOREDIR_RAX \
1077
+ "addq $128,%%rsp\n\t" \
1078
+ : /*out*/ "=a" (_res) \
1079
+ : /*in*/ "a" (&_argvec[0]) \
1080
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1081
+ ); \
1082
+ lval = (__typeof__(lval)) _res; \
1083
+ } while (0)
1084
+
1085
+ #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
1086
+ do { \
1087
+ volatile OrigFn _orig = (orig); \
1088
+ volatile unsigned long _argvec[3]; \
1089
+ volatile unsigned long _res; \
1090
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1091
+ _argvec[1] = (unsigned long)(arg1); \
1092
+ _argvec[2] = (unsigned long)(arg2); \
1093
+ __asm__ volatile( \
1094
+ "subq $128,%%rsp\n\t" \
1095
+ "movq 16(%%rax), %%rsi\n\t" \
1096
+ "movq 8(%%rax), %%rdi\n\t" \
1097
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1098
+ VALGRIND_CALL_NOREDIR_RAX \
1099
+ "addq $128,%%rsp\n\t" \
1100
+ : /*out*/ "=a" (_res) \
1101
+ : /*in*/ "a" (&_argvec[0]) \
1102
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1103
+ ); \
1104
+ lval = (__typeof__(lval)) _res; \
1105
+ } while (0)
1106
+
1107
+ #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
1108
+ do { \
1109
+ volatile OrigFn _orig = (orig); \
1110
+ volatile unsigned long _argvec[4]; \
1111
+ volatile unsigned long _res; \
1112
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1113
+ _argvec[1] = (unsigned long)(arg1); \
1114
+ _argvec[2] = (unsigned long)(arg2); \
1115
+ _argvec[3] = (unsigned long)(arg3); \
1116
+ __asm__ volatile( \
1117
+ "subq $128,%%rsp\n\t" \
1118
+ "movq 24(%%rax), %%rdx\n\t" \
1119
+ "movq 16(%%rax), %%rsi\n\t" \
1120
+ "movq 8(%%rax), %%rdi\n\t" \
1121
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1122
+ VALGRIND_CALL_NOREDIR_RAX \
1123
+ "addq $128,%%rsp\n\t" \
1124
+ : /*out*/ "=a" (_res) \
1125
+ : /*in*/ "a" (&_argvec[0]) \
1126
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1127
+ ); \
1128
+ lval = (__typeof__(lval)) _res; \
1129
+ } while (0)
1130
+
1131
+ #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
1132
+ do { \
1133
+ volatile OrigFn _orig = (orig); \
1134
+ volatile unsigned long _argvec[5]; \
1135
+ volatile unsigned long _res; \
1136
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1137
+ _argvec[1] = (unsigned long)(arg1); \
1138
+ _argvec[2] = (unsigned long)(arg2); \
1139
+ _argvec[3] = (unsigned long)(arg3); \
1140
+ _argvec[4] = (unsigned long)(arg4); \
1141
+ __asm__ volatile( \
1142
+ "subq $128,%%rsp\n\t" \
1143
+ "movq 32(%%rax), %%rcx\n\t" \
1144
+ "movq 24(%%rax), %%rdx\n\t" \
1145
+ "movq 16(%%rax), %%rsi\n\t" \
1146
+ "movq 8(%%rax), %%rdi\n\t" \
1147
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1148
+ VALGRIND_CALL_NOREDIR_RAX \
1149
+ "addq $128,%%rsp\n\t" \
1150
+ : /*out*/ "=a" (_res) \
1151
+ : /*in*/ "a" (&_argvec[0]) \
1152
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1153
+ ); \
1154
+ lval = (__typeof__(lval)) _res; \
1155
+ } while (0)
1156
+
1157
+ #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
1158
+ do { \
1159
+ volatile OrigFn _orig = (orig); \
1160
+ volatile unsigned long _argvec[6]; \
1161
+ volatile unsigned long _res; \
1162
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1163
+ _argvec[1] = (unsigned long)(arg1); \
1164
+ _argvec[2] = (unsigned long)(arg2); \
1165
+ _argvec[3] = (unsigned long)(arg3); \
1166
+ _argvec[4] = (unsigned long)(arg4); \
1167
+ _argvec[5] = (unsigned long)(arg5); \
1168
+ __asm__ volatile( \
1169
+ "subq $128,%%rsp\n\t" \
1170
+ "movq 40(%%rax), %%r8\n\t" \
1171
+ "movq 32(%%rax), %%rcx\n\t" \
1172
+ "movq 24(%%rax), %%rdx\n\t" \
1173
+ "movq 16(%%rax), %%rsi\n\t" \
1174
+ "movq 8(%%rax), %%rdi\n\t" \
1175
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1176
+ VALGRIND_CALL_NOREDIR_RAX \
1177
+ "addq $128,%%rsp\n\t" \
1178
+ : /*out*/ "=a" (_res) \
1179
+ : /*in*/ "a" (&_argvec[0]) \
1180
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1181
+ ); \
1182
+ lval = (__typeof__(lval)) _res; \
1183
+ } while (0)
1184
+
1185
+ #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
1186
+ do { \
1187
+ volatile OrigFn _orig = (orig); \
1188
+ volatile unsigned long _argvec[7]; \
1189
+ volatile unsigned long _res; \
1190
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1191
+ _argvec[1] = (unsigned long)(arg1); \
1192
+ _argvec[2] = (unsigned long)(arg2); \
1193
+ _argvec[3] = (unsigned long)(arg3); \
1194
+ _argvec[4] = (unsigned long)(arg4); \
1195
+ _argvec[5] = (unsigned long)(arg5); \
1196
+ _argvec[6] = (unsigned long)(arg6); \
1197
+ __asm__ volatile( \
1198
+ "subq $128,%%rsp\n\t" \
1199
+ "movq 48(%%rax), %%r9\n\t" \
1200
+ "movq 40(%%rax), %%r8\n\t" \
1201
+ "movq 32(%%rax), %%rcx\n\t" \
1202
+ "movq 24(%%rax), %%rdx\n\t" \
1203
+ "movq 16(%%rax), %%rsi\n\t" \
1204
+ "movq 8(%%rax), %%rdi\n\t" \
1205
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1206
+ "addq $128,%%rsp\n\t" \
1207
+ VALGRIND_CALL_NOREDIR_RAX \
1208
+ : /*out*/ "=a" (_res) \
1209
+ : /*in*/ "a" (&_argvec[0]) \
1210
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1211
+ ); \
1212
+ lval = (__typeof__(lval)) _res; \
1213
+ } while (0)
1214
+
1215
+ #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1216
+ arg7) \
1217
+ do { \
1218
+ volatile OrigFn _orig = (orig); \
1219
+ volatile unsigned long _argvec[8]; \
1220
+ volatile unsigned long _res; \
1221
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1222
+ _argvec[1] = (unsigned long)(arg1); \
1223
+ _argvec[2] = (unsigned long)(arg2); \
1224
+ _argvec[3] = (unsigned long)(arg3); \
1225
+ _argvec[4] = (unsigned long)(arg4); \
1226
+ _argvec[5] = (unsigned long)(arg5); \
1227
+ _argvec[6] = (unsigned long)(arg6); \
1228
+ _argvec[7] = (unsigned long)(arg7); \
1229
+ __asm__ volatile( \
1230
+ "subq $128,%%rsp\n\t" \
1231
+ "pushq 56(%%rax)\n\t" \
1232
+ "movq 48(%%rax), %%r9\n\t" \
1233
+ "movq 40(%%rax), %%r8\n\t" \
1234
+ "movq 32(%%rax), %%rcx\n\t" \
1235
+ "movq 24(%%rax), %%rdx\n\t" \
1236
+ "movq 16(%%rax), %%rsi\n\t" \
1237
+ "movq 8(%%rax), %%rdi\n\t" \
1238
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1239
+ VALGRIND_CALL_NOREDIR_RAX \
1240
+ "addq $8, %%rsp\n" \
1241
+ "addq $128,%%rsp\n\t" \
1242
+ : /*out*/ "=a" (_res) \
1243
+ : /*in*/ "a" (&_argvec[0]) \
1244
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1245
+ ); \
1246
+ lval = (__typeof__(lval)) _res; \
1247
+ } while (0)
1248
+
1249
+ #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1250
+ arg7,arg8) \
1251
+ do { \
1252
+ volatile OrigFn _orig = (orig); \
1253
+ volatile unsigned long _argvec[9]; \
1254
+ volatile unsigned long _res; \
1255
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1256
+ _argvec[1] = (unsigned long)(arg1); \
1257
+ _argvec[2] = (unsigned long)(arg2); \
1258
+ _argvec[3] = (unsigned long)(arg3); \
1259
+ _argvec[4] = (unsigned long)(arg4); \
1260
+ _argvec[5] = (unsigned long)(arg5); \
1261
+ _argvec[6] = (unsigned long)(arg6); \
1262
+ _argvec[7] = (unsigned long)(arg7); \
1263
+ _argvec[8] = (unsigned long)(arg8); \
1264
+ __asm__ volatile( \
1265
+ "subq $128,%%rsp\n\t" \
1266
+ "pushq 64(%%rax)\n\t" \
1267
+ "pushq 56(%%rax)\n\t" \
1268
+ "movq 48(%%rax), %%r9\n\t" \
1269
+ "movq 40(%%rax), %%r8\n\t" \
1270
+ "movq 32(%%rax), %%rcx\n\t" \
1271
+ "movq 24(%%rax), %%rdx\n\t" \
1272
+ "movq 16(%%rax), %%rsi\n\t" \
1273
+ "movq 8(%%rax), %%rdi\n\t" \
1274
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1275
+ VALGRIND_CALL_NOREDIR_RAX \
1276
+ "addq $16, %%rsp\n" \
1277
+ "addq $128,%%rsp\n\t" \
1278
+ : /*out*/ "=a" (_res) \
1279
+ : /*in*/ "a" (&_argvec[0]) \
1280
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1281
+ ); \
1282
+ lval = (__typeof__(lval)) _res; \
1283
+ } while (0)
1284
+
1285
+ #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1286
+ arg7,arg8,arg9) \
1287
+ do { \
1288
+ volatile OrigFn _orig = (orig); \
1289
+ volatile unsigned long _argvec[10]; \
1290
+ volatile unsigned long _res; \
1291
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1292
+ _argvec[1] = (unsigned long)(arg1); \
1293
+ _argvec[2] = (unsigned long)(arg2); \
1294
+ _argvec[3] = (unsigned long)(arg3); \
1295
+ _argvec[4] = (unsigned long)(arg4); \
1296
+ _argvec[5] = (unsigned long)(arg5); \
1297
+ _argvec[6] = (unsigned long)(arg6); \
1298
+ _argvec[7] = (unsigned long)(arg7); \
1299
+ _argvec[8] = (unsigned long)(arg8); \
1300
+ _argvec[9] = (unsigned long)(arg9); \
1301
+ __asm__ volatile( \
1302
+ "subq $128,%%rsp\n\t" \
1303
+ "pushq 72(%%rax)\n\t" \
1304
+ "pushq 64(%%rax)\n\t" \
1305
+ "pushq 56(%%rax)\n\t" \
1306
+ "movq 48(%%rax), %%r9\n\t" \
1307
+ "movq 40(%%rax), %%r8\n\t" \
1308
+ "movq 32(%%rax), %%rcx\n\t" \
1309
+ "movq 24(%%rax), %%rdx\n\t" \
1310
+ "movq 16(%%rax), %%rsi\n\t" \
1311
+ "movq 8(%%rax), %%rdi\n\t" \
1312
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1313
+ VALGRIND_CALL_NOREDIR_RAX \
1314
+ "addq $24, %%rsp\n" \
1315
+ "addq $128,%%rsp\n\t" \
1316
+ : /*out*/ "=a" (_res) \
1317
+ : /*in*/ "a" (&_argvec[0]) \
1318
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1319
+ ); \
1320
+ lval = (__typeof__(lval)) _res; \
1321
+ } while (0)
1322
+
1323
+ #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1324
+ arg7,arg8,arg9,arg10) \
1325
+ do { \
1326
+ volatile OrigFn _orig = (orig); \
1327
+ volatile unsigned long _argvec[11]; \
1328
+ volatile unsigned long _res; \
1329
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1330
+ _argvec[1] = (unsigned long)(arg1); \
1331
+ _argvec[2] = (unsigned long)(arg2); \
1332
+ _argvec[3] = (unsigned long)(arg3); \
1333
+ _argvec[4] = (unsigned long)(arg4); \
1334
+ _argvec[5] = (unsigned long)(arg5); \
1335
+ _argvec[6] = (unsigned long)(arg6); \
1336
+ _argvec[7] = (unsigned long)(arg7); \
1337
+ _argvec[8] = (unsigned long)(arg8); \
1338
+ _argvec[9] = (unsigned long)(arg9); \
1339
+ _argvec[10] = (unsigned long)(arg10); \
1340
+ __asm__ volatile( \
1341
+ "subq $128,%%rsp\n\t" \
1342
+ "pushq 80(%%rax)\n\t" \
1343
+ "pushq 72(%%rax)\n\t" \
1344
+ "pushq 64(%%rax)\n\t" \
1345
+ "pushq 56(%%rax)\n\t" \
1346
+ "movq 48(%%rax), %%r9\n\t" \
1347
+ "movq 40(%%rax), %%r8\n\t" \
1348
+ "movq 32(%%rax), %%rcx\n\t" \
1349
+ "movq 24(%%rax), %%rdx\n\t" \
1350
+ "movq 16(%%rax), %%rsi\n\t" \
1351
+ "movq 8(%%rax), %%rdi\n\t" \
1352
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1353
+ VALGRIND_CALL_NOREDIR_RAX \
1354
+ "addq $32, %%rsp\n" \
1355
+ "addq $128,%%rsp\n\t" \
1356
+ : /*out*/ "=a" (_res) \
1357
+ : /*in*/ "a" (&_argvec[0]) \
1358
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1359
+ ); \
1360
+ lval = (__typeof__(lval)) _res; \
1361
+ } while (0)
1362
+
1363
+ #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1364
+ arg7,arg8,arg9,arg10,arg11) \
1365
+ do { \
1366
+ volatile OrigFn _orig = (orig); \
1367
+ volatile unsigned long _argvec[12]; \
1368
+ volatile unsigned long _res; \
1369
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1370
+ _argvec[1] = (unsigned long)(arg1); \
1371
+ _argvec[2] = (unsigned long)(arg2); \
1372
+ _argvec[3] = (unsigned long)(arg3); \
1373
+ _argvec[4] = (unsigned long)(arg4); \
1374
+ _argvec[5] = (unsigned long)(arg5); \
1375
+ _argvec[6] = (unsigned long)(arg6); \
1376
+ _argvec[7] = (unsigned long)(arg7); \
1377
+ _argvec[8] = (unsigned long)(arg8); \
1378
+ _argvec[9] = (unsigned long)(arg9); \
1379
+ _argvec[10] = (unsigned long)(arg10); \
1380
+ _argvec[11] = (unsigned long)(arg11); \
1381
+ __asm__ volatile( \
1382
+ "subq $128,%%rsp\n\t" \
1383
+ "pushq 88(%%rax)\n\t" \
1384
+ "pushq 80(%%rax)\n\t" \
1385
+ "pushq 72(%%rax)\n\t" \
1386
+ "pushq 64(%%rax)\n\t" \
1387
+ "pushq 56(%%rax)\n\t" \
1388
+ "movq 48(%%rax), %%r9\n\t" \
1389
+ "movq 40(%%rax), %%r8\n\t" \
1390
+ "movq 32(%%rax), %%rcx\n\t" \
1391
+ "movq 24(%%rax), %%rdx\n\t" \
1392
+ "movq 16(%%rax), %%rsi\n\t" \
1393
+ "movq 8(%%rax), %%rdi\n\t" \
1394
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1395
+ VALGRIND_CALL_NOREDIR_RAX \
1396
+ "addq $40, %%rsp\n" \
1397
+ "addq $128,%%rsp\n\t" \
1398
+ : /*out*/ "=a" (_res) \
1399
+ : /*in*/ "a" (&_argvec[0]) \
1400
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1401
+ ); \
1402
+ lval = (__typeof__(lval)) _res; \
1403
+ } while (0)
1404
+
1405
+ #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1406
+ arg7,arg8,arg9,arg10,arg11,arg12) \
1407
+ do { \
1408
+ volatile OrigFn _orig = (orig); \
1409
+ volatile unsigned long _argvec[13]; \
1410
+ volatile unsigned long _res; \
1411
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1412
+ _argvec[1] = (unsigned long)(arg1); \
1413
+ _argvec[2] = (unsigned long)(arg2); \
1414
+ _argvec[3] = (unsigned long)(arg3); \
1415
+ _argvec[4] = (unsigned long)(arg4); \
1416
+ _argvec[5] = (unsigned long)(arg5); \
1417
+ _argvec[6] = (unsigned long)(arg6); \
1418
+ _argvec[7] = (unsigned long)(arg7); \
1419
+ _argvec[8] = (unsigned long)(arg8); \
1420
+ _argvec[9] = (unsigned long)(arg9); \
1421
+ _argvec[10] = (unsigned long)(arg10); \
1422
+ _argvec[11] = (unsigned long)(arg11); \
1423
+ _argvec[12] = (unsigned long)(arg12); \
1424
+ __asm__ volatile( \
1425
+ "subq $128,%%rsp\n\t" \
1426
+ "pushq 96(%%rax)\n\t" \
1427
+ "pushq 88(%%rax)\n\t" \
1428
+ "pushq 80(%%rax)\n\t" \
1429
+ "pushq 72(%%rax)\n\t" \
1430
+ "pushq 64(%%rax)\n\t" \
1431
+ "pushq 56(%%rax)\n\t" \
1432
+ "movq 48(%%rax), %%r9\n\t" \
1433
+ "movq 40(%%rax), %%r8\n\t" \
1434
+ "movq 32(%%rax), %%rcx\n\t" \
1435
+ "movq 24(%%rax), %%rdx\n\t" \
1436
+ "movq 16(%%rax), %%rsi\n\t" \
1437
+ "movq 8(%%rax), %%rdi\n\t" \
1438
+ "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1439
+ VALGRIND_CALL_NOREDIR_RAX \
1440
+ "addq $48, %%rsp\n" \
1441
+ "addq $128,%%rsp\n\t" \
1442
+ : /*out*/ "=a" (_res) \
1443
+ : /*in*/ "a" (&_argvec[0]) \
1444
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1445
+ ); \
1446
+ lval = (__typeof__(lval)) _res; \
1447
+ } while (0)
1448
+
1449
+ #endif /* PLAT_amd64_linux */
1450
+
1451
+ /* ------------------------ ppc32-linux ------------------------ */
1452
+
1453
+ #if defined(PLAT_ppc32_linux)
1454
+
1455
+ /* This is useful for finding out about the on-stack stuff:
1456
+
1457
+ extern int f9 ( int,int,int,int,int,int,int,int,int );
1458
+ extern int f10 ( int,int,int,int,int,int,int,int,int,int );
1459
+ extern int f11 ( int,int,int,int,int,int,int,int,int,int,int );
1460
+ extern int f12 ( int,int,int,int,int,int,int,int,int,int,int,int );
1461
+
1462
+ int g9 ( void ) {
1463
+ return f9(11,22,33,44,55,66,77,88,99);
1464
+ }
1465
+ int g10 ( void ) {
1466
+ return f10(11,22,33,44,55,66,77,88,99,110);
1467
+ }
1468
+ int g11 ( void ) {
1469
+ return f11(11,22,33,44,55,66,77,88,99,110,121);
1470
+ }
1471
+ int g12 ( void ) {
1472
+ return f12(11,22,33,44,55,66,77,88,99,110,121,132);
1473
+ }
1474
+ */
1475
+
1476
+ /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
1477
+
1478
+ /* These regs are trashed by the hidden call. */
1479
+ #define __CALLER_SAVED_REGS \
1480
+ "lr", "ctr", "xer", \
1481
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
1482
+ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
1483
+ "r11", "r12", "r13"
1484
+
1485
+ /* These CALL_FN_ macros assume that on ppc32-linux,
1486
+ sizeof(unsigned long) == 4. */
1487
+
1488
+ #define CALL_FN_W_v(lval, orig) \
1489
+ do { \
1490
+ volatile OrigFn _orig = (orig); \
1491
+ volatile unsigned long _argvec[1]; \
1492
+ volatile unsigned long _res; \
1493
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1494
+ __asm__ volatile( \
1495
+ "mr 11,%1\n\t" \
1496
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1497
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1498
+ "mr %0,3" \
1499
+ : /*out*/ "=r" (_res) \
1500
+ : /*in*/ "r" (&_argvec[0]) \
1501
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1502
+ ); \
1503
+ lval = (__typeof__(lval)) _res; \
1504
+ } while (0)
1505
+
1506
+ #define CALL_FN_W_W(lval, orig, arg1) \
1507
+ do { \
1508
+ volatile OrigFn _orig = (orig); \
1509
+ volatile unsigned long _argvec[2]; \
1510
+ volatile unsigned long _res; \
1511
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1512
+ _argvec[1] = (unsigned long)arg1; \
1513
+ __asm__ volatile( \
1514
+ "mr 11,%1\n\t" \
1515
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1516
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1517
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1518
+ "mr %0,3" \
1519
+ : /*out*/ "=r" (_res) \
1520
+ : /*in*/ "r" (&_argvec[0]) \
1521
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1522
+ ); \
1523
+ lval = (__typeof__(lval)) _res; \
1524
+ } while (0)
1525
+
1526
+ #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
1527
+ do { \
1528
+ volatile OrigFn _orig = (orig); \
1529
+ volatile unsigned long _argvec[3]; \
1530
+ volatile unsigned long _res; \
1531
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1532
+ _argvec[1] = (unsigned long)arg1; \
1533
+ _argvec[2] = (unsigned long)arg2; \
1534
+ __asm__ volatile( \
1535
+ "mr 11,%1\n\t" \
1536
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1537
+ "lwz 4,8(11)\n\t" \
1538
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1539
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1540
+ "mr %0,3" \
1541
+ : /*out*/ "=r" (_res) \
1542
+ : /*in*/ "r" (&_argvec[0]) \
1543
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1544
+ ); \
1545
+ lval = (__typeof__(lval)) _res; \
1546
+ } while (0)
1547
+
1548
+ #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
1549
+ do { \
1550
+ volatile OrigFn _orig = (orig); \
1551
+ volatile unsigned long _argvec[4]; \
1552
+ volatile unsigned long _res; \
1553
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1554
+ _argvec[1] = (unsigned long)arg1; \
1555
+ _argvec[2] = (unsigned long)arg2; \
1556
+ _argvec[3] = (unsigned long)arg3; \
1557
+ __asm__ volatile( \
1558
+ "mr 11,%1\n\t" \
1559
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1560
+ "lwz 4,8(11)\n\t" \
1561
+ "lwz 5,12(11)\n\t" \
1562
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1563
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1564
+ "mr %0,3" \
1565
+ : /*out*/ "=r" (_res) \
1566
+ : /*in*/ "r" (&_argvec[0]) \
1567
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1568
+ ); \
1569
+ lval = (__typeof__(lval)) _res; \
1570
+ } while (0)
1571
+
1572
+ #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
1573
+ do { \
1574
+ volatile OrigFn _orig = (orig); \
1575
+ volatile unsigned long _argvec[5]; \
1576
+ volatile unsigned long _res; \
1577
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1578
+ _argvec[1] = (unsigned long)arg1; \
1579
+ _argvec[2] = (unsigned long)arg2; \
1580
+ _argvec[3] = (unsigned long)arg3; \
1581
+ _argvec[4] = (unsigned long)arg4; \
1582
+ __asm__ volatile( \
1583
+ "mr 11,%1\n\t" \
1584
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1585
+ "lwz 4,8(11)\n\t" \
1586
+ "lwz 5,12(11)\n\t" \
1587
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1588
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1589
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1590
+ "mr %0,3" \
1591
+ : /*out*/ "=r" (_res) \
1592
+ : /*in*/ "r" (&_argvec[0]) \
1593
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1594
+ ); \
1595
+ lval = (__typeof__(lval)) _res; \
1596
+ } while (0)
1597
+
1598
+ #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
1599
+ do { \
1600
+ volatile OrigFn _orig = (orig); \
1601
+ volatile unsigned long _argvec[6]; \
1602
+ volatile unsigned long _res; \
1603
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1604
+ _argvec[1] = (unsigned long)arg1; \
1605
+ _argvec[2] = (unsigned long)arg2; \
1606
+ _argvec[3] = (unsigned long)arg3; \
1607
+ _argvec[4] = (unsigned long)arg4; \
1608
+ _argvec[5] = (unsigned long)arg5; \
1609
+ __asm__ volatile( \
1610
+ "mr 11,%1\n\t" \
1611
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1612
+ "lwz 4,8(11)\n\t" \
1613
+ "lwz 5,12(11)\n\t" \
1614
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1615
+ "lwz 7,20(11)\n\t" \
1616
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1617
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1618
+ "mr %0,3" \
1619
+ : /*out*/ "=r" (_res) \
1620
+ : /*in*/ "r" (&_argvec[0]) \
1621
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1622
+ ); \
1623
+ lval = (__typeof__(lval)) _res; \
1624
+ } while (0)
1625
+
1626
+ #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
1627
+ do { \
1628
+ volatile OrigFn _orig = (orig); \
1629
+ volatile unsigned long _argvec[7]; \
1630
+ volatile unsigned long _res; \
1631
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1632
+ _argvec[1] = (unsigned long)arg1; \
1633
+ _argvec[2] = (unsigned long)arg2; \
1634
+ _argvec[3] = (unsigned long)arg3; \
1635
+ _argvec[4] = (unsigned long)arg4; \
1636
+ _argvec[5] = (unsigned long)arg5; \
1637
+ _argvec[6] = (unsigned long)arg6; \
1638
+ __asm__ volatile( \
1639
+ "mr 11,%1\n\t" \
1640
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1641
+ "lwz 4,8(11)\n\t" \
1642
+ "lwz 5,12(11)\n\t" \
1643
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1644
+ "lwz 7,20(11)\n\t" \
1645
+ "lwz 8,24(11)\n\t" \
1646
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1647
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1648
+ "mr %0,3" \
1649
+ : /*out*/ "=r" (_res) \
1650
+ : /*in*/ "r" (&_argvec[0]) \
1651
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1652
+ ); \
1653
+ lval = (__typeof__(lval)) _res; \
1654
+ } while (0)
1655
+
1656
+ #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1657
+ arg7) \
1658
+ do { \
1659
+ volatile OrigFn _orig = (orig); \
1660
+ volatile unsigned long _argvec[8]; \
1661
+ volatile unsigned long _res; \
1662
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1663
+ _argvec[1] = (unsigned long)arg1; \
1664
+ _argvec[2] = (unsigned long)arg2; \
1665
+ _argvec[3] = (unsigned long)arg3; \
1666
+ _argvec[4] = (unsigned long)arg4; \
1667
+ _argvec[5] = (unsigned long)arg5; \
1668
+ _argvec[6] = (unsigned long)arg6; \
1669
+ _argvec[7] = (unsigned long)arg7; \
1670
+ __asm__ volatile( \
1671
+ "mr 11,%1\n\t" \
1672
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1673
+ "lwz 4,8(11)\n\t" \
1674
+ "lwz 5,12(11)\n\t" \
1675
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1676
+ "lwz 7,20(11)\n\t" \
1677
+ "lwz 8,24(11)\n\t" \
1678
+ "lwz 9,28(11)\n\t" \
1679
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1680
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1681
+ "mr %0,3" \
1682
+ : /*out*/ "=r" (_res) \
1683
+ : /*in*/ "r" (&_argvec[0]) \
1684
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1685
+ ); \
1686
+ lval = (__typeof__(lval)) _res; \
1687
+ } while (0)
1688
+
1689
+ #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1690
+ arg7,arg8) \
1691
+ do { \
1692
+ volatile OrigFn _orig = (orig); \
1693
+ volatile unsigned long _argvec[9]; \
1694
+ volatile unsigned long _res; \
1695
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1696
+ _argvec[1] = (unsigned long)arg1; \
1697
+ _argvec[2] = (unsigned long)arg2; \
1698
+ _argvec[3] = (unsigned long)arg3; \
1699
+ _argvec[4] = (unsigned long)arg4; \
1700
+ _argvec[5] = (unsigned long)arg5; \
1701
+ _argvec[6] = (unsigned long)arg6; \
1702
+ _argvec[7] = (unsigned long)arg7; \
1703
+ _argvec[8] = (unsigned long)arg8; \
1704
+ __asm__ volatile( \
1705
+ "mr 11,%1\n\t" \
1706
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1707
+ "lwz 4,8(11)\n\t" \
1708
+ "lwz 5,12(11)\n\t" \
1709
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1710
+ "lwz 7,20(11)\n\t" \
1711
+ "lwz 8,24(11)\n\t" \
1712
+ "lwz 9,28(11)\n\t" \
1713
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
1714
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1715
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1716
+ "mr %0,3" \
1717
+ : /*out*/ "=r" (_res) \
1718
+ : /*in*/ "r" (&_argvec[0]) \
1719
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1720
+ ); \
1721
+ lval = (__typeof__(lval)) _res; \
1722
+ } while (0)
1723
+
1724
+ #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1725
+ arg7,arg8,arg9) \
1726
+ do { \
1727
+ volatile OrigFn _orig = (orig); \
1728
+ volatile unsigned long _argvec[10]; \
1729
+ volatile unsigned long _res; \
1730
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1731
+ _argvec[1] = (unsigned long)arg1; \
1732
+ _argvec[2] = (unsigned long)arg2; \
1733
+ _argvec[3] = (unsigned long)arg3; \
1734
+ _argvec[4] = (unsigned long)arg4; \
1735
+ _argvec[5] = (unsigned long)arg5; \
1736
+ _argvec[6] = (unsigned long)arg6; \
1737
+ _argvec[7] = (unsigned long)arg7; \
1738
+ _argvec[8] = (unsigned long)arg8; \
1739
+ _argvec[9] = (unsigned long)arg9; \
1740
+ __asm__ volatile( \
1741
+ "mr 11,%1\n\t" \
1742
+ "addi 1,1,-16\n\t" \
1743
+ /* arg9 */ \
1744
+ "lwz 3,36(11)\n\t" \
1745
+ "stw 3,8(1)\n\t" \
1746
+ /* args1-8 */ \
1747
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1748
+ "lwz 4,8(11)\n\t" \
1749
+ "lwz 5,12(11)\n\t" \
1750
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1751
+ "lwz 7,20(11)\n\t" \
1752
+ "lwz 8,24(11)\n\t" \
1753
+ "lwz 9,28(11)\n\t" \
1754
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
1755
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1756
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1757
+ "addi 1,1,16\n\t" \
1758
+ "mr %0,3" \
1759
+ : /*out*/ "=r" (_res) \
1760
+ : /*in*/ "r" (&_argvec[0]) \
1761
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1762
+ ); \
1763
+ lval = (__typeof__(lval)) _res; \
1764
+ } while (0)
1765
+
1766
+ #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1767
+ arg7,arg8,arg9,arg10) \
1768
+ do { \
1769
+ volatile OrigFn _orig = (orig); \
1770
+ volatile unsigned long _argvec[11]; \
1771
+ volatile unsigned long _res; \
1772
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1773
+ _argvec[1] = (unsigned long)arg1; \
1774
+ _argvec[2] = (unsigned long)arg2; \
1775
+ _argvec[3] = (unsigned long)arg3; \
1776
+ _argvec[4] = (unsigned long)arg4; \
1777
+ _argvec[5] = (unsigned long)arg5; \
1778
+ _argvec[6] = (unsigned long)arg6; \
1779
+ _argvec[7] = (unsigned long)arg7; \
1780
+ _argvec[8] = (unsigned long)arg8; \
1781
+ _argvec[9] = (unsigned long)arg9; \
1782
+ _argvec[10] = (unsigned long)arg10; \
1783
+ __asm__ volatile( \
1784
+ "mr 11,%1\n\t" \
1785
+ "addi 1,1,-16\n\t" \
1786
+ /* arg10 */ \
1787
+ "lwz 3,40(11)\n\t" \
1788
+ "stw 3,12(1)\n\t" \
1789
+ /* arg9 */ \
1790
+ "lwz 3,36(11)\n\t" \
1791
+ "stw 3,8(1)\n\t" \
1792
+ /* args1-8 */ \
1793
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1794
+ "lwz 4,8(11)\n\t" \
1795
+ "lwz 5,12(11)\n\t" \
1796
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1797
+ "lwz 7,20(11)\n\t" \
1798
+ "lwz 8,24(11)\n\t" \
1799
+ "lwz 9,28(11)\n\t" \
1800
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
1801
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1802
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1803
+ "addi 1,1,16\n\t" \
1804
+ "mr %0,3" \
1805
+ : /*out*/ "=r" (_res) \
1806
+ : /*in*/ "r" (&_argvec[0]) \
1807
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1808
+ ); \
1809
+ lval = (__typeof__(lval)) _res; \
1810
+ } while (0)
1811
+
1812
+ #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1813
+ arg7,arg8,arg9,arg10,arg11) \
1814
+ do { \
1815
+ volatile OrigFn _orig = (orig); \
1816
+ volatile unsigned long _argvec[12]; \
1817
+ volatile unsigned long _res; \
1818
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1819
+ _argvec[1] = (unsigned long)arg1; \
1820
+ _argvec[2] = (unsigned long)arg2; \
1821
+ _argvec[3] = (unsigned long)arg3; \
1822
+ _argvec[4] = (unsigned long)arg4; \
1823
+ _argvec[5] = (unsigned long)arg5; \
1824
+ _argvec[6] = (unsigned long)arg6; \
1825
+ _argvec[7] = (unsigned long)arg7; \
1826
+ _argvec[8] = (unsigned long)arg8; \
1827
+ _argvec[9] = (unsigned long)arg9; \
1828
+ _argvec[10] = (unsigned long)arg10; \
1829
+ _argvec[11] = (unsigned long)arg11; \
1830
+ __asm__ volatile( \
1831
+ "mr 11,%1\n\t" \
1832
+ "addi 1,1,-32\n\t" \
1833
+ /* arg11 */ \
1834
+ "lwz 3,44(11)\n\t" \
1835
+ "stw 3,16(1)\n\t" \
1836
+ /* arg10 */ \
1837
+ "lwz 3,40(11)\n\t" \
1838
+ "stw 3,12(1)\n\t" \
1839
+ /* arg9 */ \
1840
+ "lwz 3,36(11)\n\t" \
1841
+ "stw 3,8(1)\n\t" \
1842
+ /* args1-8 */ \
1843
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1844
+ "lwz 4,8(11)\n\t" \
1845
+ "lwz 5,12(11)\n\t" \
1846
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1847
+ "lwz 7,20(11)\n\t" \
1848
+ "lwz 8,24(11)\n\t" \
1849
+ "lwz 9,28(11)\n\t" \
1850
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
1851
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1852
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1853
+ "addi 1,1,32\n\t" \
1854
+ "mr %0,3" \
1855
+ : /*out*/ "=r" (_res) \
1856
+ : /*in*/ "r" (&_argvec[0]) \
1857
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1858
+ ); \
1859
+ lval = (__typeof__(lval)) _res; \
1860
+ } while (0)
1861
+
1862
+ #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
1863
+ arg7,arg8,arg9,arg10,arg11,arg12) \
1864
+ do { \
1865
+ volatile OrigFn _orig = (orig); \
1866
+ volatile unsigned long _argvec[13]; \
1867
+ volatile unsigned long _res; \
1868
+ _argvec[0] = (unsigned long)_orig.nraddr; \
1869
+ _argvec[1] = (unsigned long)arg1; \
1870
+ _argvec[2] = (unsigned long)arg2; \
1871
+ _argvec[3] = (unsigned long)arg3; \
1872
+ _argvec[4] = (unsigned long)arg4; \
1873
+ _argvec[5] = (unsigned long)arg5; \
1874
+ _argvec[6] = (unsigned long)arg6; \
1875
+ _argvec[7] = (unsigned long)arg7; \
1876
+ _argvec[8] = (unsigned long)arg8; \
1877
+ _argvec[9] = (unsigned long)arg9; \
1878
+ _argvec[10] = (unsigned long)arg10; \
1879
+ _argvec[11] = (unsigned long)arg11; \
1880
+ _argvec[12] = (unsigned long)arg12; \
1881
+ __asm__ volatile( \
1882
+ "mr 11,%1\n\t" \
1883
+ "addi 1,1,-32\n\t" \
1884
+ /* arg12 */ \
1885
+ "lwz 3,48(11)\n\t" \
1886
+ "stw 3,20(1)\n\t" \
1887
+ /* arg11 */ \
1888
+ "lwz 3,44(11)\n\t" \
1889
+ "stw 3,16(1)\n\t" \
1890
+ /* arg10 */ \
1891
+ "lwz 3,40(11)\n\t" \
1892
+ "stw 3,12(1)\n\t" \
1893
+ /* arg9 */ \
1894
+ "lwz 3,36(11)\n\t" \
1895
+ "stw 3,8(1)\n\t" \
1896
+ /* args1-8 */ \
1897
+ "lwz 3,4(11)\n\t" /* arg1->r3 */ \
1898
+ "lwz 4,8(11)\n\t" \
1899
+ "lwz 5,12(11)\n\t" \
1900
+ "lwz 6,16(11)\n\t" /* arg4->r6 */ \
1901
+ "lwz 7,20(11)\n\t" \
1902
+ "lwz 8,24(11)\n\t" \
1903
+ "lwz 9,28(11)\n\t" \
1904
+ "lwz 10,32(11)\n\t" /* arg8->r10 */ \
1905
+ "lwz 11,0(11)\n\t" /* target->r11 */ \
1906
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1907
+ "addi 1,1,32\n\t" \
1908
+ "mr %0,3" \
1909
+ : /*out*/ "=r" (_res) \
1910
+ : /*in*/ "r" (&_argvec[0]) \
1911
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1912
+ ); \
1913
+ lval = (__typeof__(lval)) _res; \
1914
+ } while (0)
1915
+
1916
+ #endif /* PLAT_ppc32_linux */
1917
+
1918
+ /* ------------------------ ppc64-linux ------------------------ */
1919
+
1920
+ #if defined(PLAT_ppc64_linux)
1921
+
1922
+ /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
1923
+
1924
+ /* These regs are trashed by the hidden call. */
1925
+ #define __CALLER_SAVED_REGS \
1926
+ "lr", "ctr", "xer", \
1927
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
1928
+ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
1929
+ "r11", "r12", "r13"
1930
+
1931
+ /* These CALL_FN_ macros assume that on ppc64-linux, sizeof(unsigned
1932
+ long) == 8. */
1933
+
1934
+ #define CALL_FN_W_v(lval, orig) \
1935
+ do { \
1936
+ volatile OrigFn _orig = (orig); \
1937
+ volatile unsigned long _argvec[3+0]; \
1938
+ volatile unsigned long _res; \
1939
+ /* _argvec[0] holds current r2 across the call */ \
1940
+ _argvec[1] = (unsigned long)_orig.r2; \
1941
+ _argvec[2] = (unsigned long)_orig.nraddr; \
1942
+ __asm__ volatile( \
1943
+ "mr 11,%1\n\t" \
1944
+ "std 2,-16(11)\n\t" /* save tocptr */ \
1945
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
1946
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
1947
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1948
+ "mr 11,%1\n\t" \
1949
+ "mr %0,3\n\t" \
1950
+ "ld 2,-16(11)" /* restore tocptr */ \
1951
+ : /*out*/ "=r" (_res) \
1952
+ : /*in*/ "r" (&_argvec[2]) \
1953
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1954
+ ); \
1955
+ lval = (__typeof__(lval)) _res; \
1956
+ } while (0)
1957
+
1958
+ #define CALL_FN_W_W(lval, orig, arg1) \
1959
+ do { \
1960
+ volatile OrigFn _orig = (orig); \
1961
+ volatile unsigned long _argvec[3+1]; \
1962
+ volatile unsigned long _res; \
1963
+ /* _argvec[0] holds current r2 across the call */ \
1964
+ _argvec[1] = (unsigned long)_orig.r2; \
1965
+ _argvec[2] = (unsigned long)_orig.nraddr; \
1966
+ _argvec[2+1] = (unsigned long)arg1; \
1967
+ __asm__ volatile( \
1968
+ "mr 11,%1\n\t" \
1969
+ "std 2,-16(11)\n\t" /* save tocptr */ \
1970
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
1971
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
1972
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
1973
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
1974
+ "mr 11,%1\n\t" \
1975
+ "mr %0,3\n\t" \
1976
+ "ld 2,-16(11)" /* restore tocptr */ \
1977
+ : /*out*/ "=r" (_res) \
1978
+ : /*in*/ "r" (&_argvec[2]) \
1979
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1980
+ ); \
1981
+ lval = (__typeof__(lval)) _res; \
1982
+ } while (0)
1983
+
1984
+ #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
1985
+ do { \
1986
+ volatile OrigFn _orig = (orig); \
1987
+ volatile unsigned long _argvec[3+2]; \
1988
+ volatile unsigned long _res; \
1989
+ /* _argvec[0] holds current r2 across the call */ \
1990
+ _argvec[1] = (unsigned long)_orig.r2; \
1991
+ _argvec[2] = (unsigned long)_orig.nraddr; \
1992
+ _argvec[2+1] = (unsigned long)arg1; \
1993
+ _argvec[2+2] = (unsigned long)arg2; \
1994
+ __asm__ volatile( \
1995
+ "mr 11,%1\n\t" \
1996
+ "std 2,-16(11)\n\t" /* save tocptr */ \
1997
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
1998
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
1999
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2000
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2001
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2002
+ "mr 11,%1\n\t" \
2003
+ "mr %0,3\n\t" \
2004
+ "ld 2,-16(11)" /* restore tocptr */ \
2005
+ : /*out*/ "=r" (_res) \
2006
+ : /*in*/ "r" (&_argvec[2]) \
2007
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2008
+ ); \
2009
+ lval = (__typeof__(lval)) _res; \
2010
+ } while (0)
2011
+
2012
+ #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
2013
+ do { \
2014
+ volatile OrigFn _orig = (orig); \
2015
+ volatile unsigned long _argvec[3+3]; \
2016
+ volatile unsigned long _res; \
2017
+ /* _argvec[0] holds current r2 across the call */ \
2018
+ _argvec[1] = (unsigned long)_orig.r2; \
2019
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2020
+ _argvec[2+1] = (unsigned long)arg1; \
2021
+ _argvec[2+2] = (unsigned long)arg2; \
2022
+ _argvec[2+3] = (unsigned long)arg3; \
2023
+ __asm__ volatile( \
2024
+ "mr 11,%1\n\t" \
2025
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2026
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2027
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2028
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2029
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2030
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2031
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2032
+ "mr 11,%1\n\t" \
2033
+ "mr %0,3\n\t" \
2034
+ "ld 2,-16(11)" /* restore tocptr */ \
2035
+ : /*out*/ "=r" (_res) \
2036
+ : /*in*/ "r" (&_argvec[2]) \
2037
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2038
+ ); \
2039
+ lval = (__typeof__(lval)) _res; \
2040
+ } while (0)
2041
+
2042
+ #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
2043
+ do { \
2044
+ volatile OrigFn _orig = (orig); \
2045
+ volatile unsigned long _argvec[3+4]; \
2046
+ volatile unsigned long _res; \
2047
+ /* _argvec[0] holds current r2 across the call */ \
2048
+ _argvec[1] = (unsigned long)_orig.r2; \
2049
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2050
+ _argvec[2+1] = (unsigned long)arg1; \
2051
+ _argvec[2+2] = (unsigned long)arg2; \
2052
+ _argvec[2+3] = (unsigned long)arg3; \
2053
+ _argvec[2+4] = (unsigned long)arg4; \
2054
+ __asm__ volatile( \
2055
+ "mr 11,%1\n\t" \
2056
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2057
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2058
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2059
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2060
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2061
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2062
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2063
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2064
+ "mr 11,%1\n\t" \
2065
+ "mr %0,3\n\t" \
2066
+ "ld 2,-16(11)" /* restore tocptr */ \
2067
+ : /*out*/ "=r" (_res) \
2068
+ : /*in*/ "r" (&_argvec[2]) \
2069
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2070
+ ); \
2071
+ lval = (__typeof__(lval)) _res; \
2072
+ } while (0)
2073
+
2074
+ #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
2075
+ do { \
2076
+ volatile OrigFn _orig = (orig); \
2077
+ volatile unsigned long _argvec[3+5]; \
2078
+ volatile unsigned long _res; \
2079
+ /* _argvec[0] holds current r2 across the call */ \
2080
+ _argvec[1] = (unsigned long)_orig.r2; \
2081
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2082
+ _argvec[2+1] = (unsigned long)arg1; \
2083
+ _argvec[2+2] = (unsigned long)arg2; \
2084
+ _argvec[2+3] = (unsigned long)arg3; \
2085
+ _argvec[2+4] = (unsigned long)arg4; \
2086
+ _argvec[2+5] = (unsigned long)arg5; \
2087
+ __asm__ volatile( \
2088
+ "mr 11,%1\n\t" \
2089
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2090
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2091
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2092
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2093
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2094
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2095
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2096
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2097
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2098
+ "mr 11,%1\n\t" \
2099
+ "mr %0,3\n\t" \
2100
+ "ld 2,-16(11)" /* restore tocptr */ \
2101
+ : /*out*/ "=r" (_res) \
2102
+ : /*in*/ "r" (&_argvec[2]) \
2103
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2104
+ ); \
2105
+ lval = (__typeof__(lval)) _res; \
2106
+ } while (0)
2107
+
2108
+ #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
2109
+ do { \
2110
+ volatile OrigFn _orig = (orig); \
2111
+ volatile unsigned long _argvec[3+6]; \
2112
+ volatile unsigned long _res; \
2113
+ /* _argvec[0] holds current r2 across the call */ \
2114
+ _argvec[1] = (unsigned long)_orig.r2; \
2115
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2116
+ _argvec[2+1] = (unsigned long)arg1; \
2117
+ _argvec[2+2] = (unsigned long)arg2; \
2118
+ _argvec[2+3] = (unsigned long)arg3; \
2119
+ _argvec[2+4] = (unsigned long)arg4; \
2120
+ _argvec[2+5] = (unsigned long)arg5; \
2121
+ _argvec[2+6] = (unsigned long)arg6; \
2122
+ __asm__ volatile( \
2123
+ "mr 11,%1\n\t" \
2124
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2125
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2126
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2127
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2128
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2129
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2130
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2131
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2132
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2133
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2134
+ "mr 11,%1\n\t" \
2135
+ "mr %0,3\n\t" \
2136
+ "ld 2,-16(11)" /* restore tocptr */ \
2137
+ : /*out*/ "=r" (_res) \
2138
+ : /*in*/ "r" (&_argvec[2]) \
2139
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2140
+ ); \
2141
+ lval = (__typeof__(lval)) _res; \
2142
+ } while (0)
2143
+
2144
+ #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2145
+ arg7) \
2146
+ do { \
2147
+ volatile OrigFn _orig = (orig); \
2148
+ volatile unsigned long _argvec[3+7]; \
2149
+ volatile unsigned long _res; \
2150
+ /* _argvec[0] holds current r2 across the call */ \
2151
+ _argvec[1] = (unsigned long)_orig.r2; \
2152
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2153
+ _argvec[2+1] = (unsigned long)arg1; \
2154
+ _argvec[2+2] = (unsigned long)arg2; \
2155
+ _argvec[2+3] = (unsigned long)arg3; \
2156
+ _argvec[2+4] = (unsigned long)arg4; \
2157
+ _argvec[2+5] = (unsigned long)arg5; \
2158
+ _argvec[2+6] = (unsigned long)arg6; \
2159
+ _argvec[2+7] = (unsigned long)arg7; \
2160
+ __asm__ volatile( \
2161
+ "mr 11,%1\n\t" \
2162
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2163
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2164
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2165
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2166
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2167
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2168
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2169
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2170
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2171
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2172
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2173
+ "mr 11,%1\n\t" \
2174
+ "mr %0,3\n\t" \
2175
+ "ld 2,-16(11)" /* restore tocptr */ \
2176
+ : /*out*/ "=r" (_res) \
2177
+ : /*in*/ "r" (&_argvec[2]) \
2178
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2179
+ ); \
2180
+ lval = (__typeof__(lval)) _res; \
2181
+ } while (0)
2182
+
2183
+ #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2184
+ arg7,arg8) \
2185
+ do { \
2186
+ volatile OrigFn _orig = (orig); \
2187
+ volatile unsigned long _argvec[3+8]; \
2188
+ volatile unsigned long _res; \
2189
+ /* _argvec[0] holds current r2 across the call */ \
2190
+ _argvec[1] = (unsigned long)_orig.r2; \
2191
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2192
+ _argvec[2+1] = (unsigned long)arg1; \
2193
+ _argvec[2+2] = (unsigned long)arg2; \
2194
+ _argvec[2+3] = (unsigned long)arg3; \
2195
+ _argvec[2+4] = (unsigned long)arg4; \
2196
+ _argvec[2+5] = (unsigned long)arg5; \
2197
+ _argvec[2+6] = (unsigned long)arg6; \
2198
+ _argvec[2+7] = (unsigned long)arg7; \
2199
+ _argvec[2+8] = (unsigned long)arg8; \
2200
+ __asm__ volatile( \
2201
+ "mr 11,%1\n\t" \
2202
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2203
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2204
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2205
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2206
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2207
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2208
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2209
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2210
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2211
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2212
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2213
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2214
+ "mr 11,%1\n\t" \
2215
+ "mr %0,3\n\t" \
2216
+ "ld 2,-16(11)" /* restore tocptr */ \
2217
+ : /*out*/ "=r" (_res) \
2218
+ : /*in*/ "r" (&_argvec[2]) \
2219
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2220
+ ); \
2221
+ lval = (__typeof__(lval)) _res; \
2222
+ } while (0)
2223
+
2224
+ #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2225
+ arg7,arg8,arg9) \
2226
+ do { \
2227
+ volatile OrigFn _orig = (orig); \
2228
+ volatile unsigned long _argvec[3+9]; \
2229
+ volatile unsigned long _res; \
2230
+ /* _argvec[0] holds current r2 across the call */ \
2231
+ _argvec[1] = (unsigned long)_orig.r2; \
2232
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2233
+ _argvec[2+1] = (unsigned long)arg1; \
2234
+ _argvec[2+2] = (unsigned long)arg2; \
2235
+ _argvec[2+3] = (unsigned long)arg3; \
2236
+ _argvec[2+4] = (unsigned long)arg4; \
2237
+ _argvec[2+5] = (unsigned long)arg5; \
2238
+ _argvec[2+6] = (unsigned long)arg6; \
2239
+ _argvec[2+7] = (unsigned long)arg7; \
2240
+ _argvec[2+8] = (unsigned long)arg8; \
2241
+ _argvec[2+9] = (unsigned long)arg9; \
2242
+ __asm__ volatile( \
2243
+ "mr 11,%1\n\t" \
2244
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2245
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2246
+ "addi 1,1,-128\n\t" /* expand stack frame */ \
2247
+ /* arg9 */ \
2248
+ "ld 3,72(11)\n\t" \
2249
+ "std 3,112(1)\n\t" \
2250
+ /* args1-8 */ \
2251
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2252
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2253
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2254
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2255
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2256
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2257
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2258
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2259
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2260
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2261
+ "mr 11,%1\n\t" \
2262
+ "mr %0,3\n\t" \
2263
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
2264
+ "addi 1,1,128" /* restore frame */ \
2265
+ : /*out*/ "=r" (_res) \
2266
+ : /*in*/ "r" (&_argvec[2]) \
2267
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2268
+ ); \
2269
+ lval = (__typeof__(lval)) _res; \
2270
+ } while (0)
2271
+
2272
+ #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2273
+ arg7,arg8,arg9,arg10) \
2274
+ do { \
2275
+ volatile OrigFn _orig = (orig); \
2276
+ volatile unsigned long _argvec[3+10]; \
2277
+ volatile unsigned long _res; \
2278
+ /* _argvec[0] holds current r2 across the call */ \
2279
+ _argvec[1] = (unsigned long)_orig.r2; \
2280
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2281
+ _argvec[2+1] = (unsigned long)arg1; \
2282
+ _argvec[2+2] = (unsigned long)arg2; \
2283
+ _argvec[2+3] = (unsigned long)arg3; \
2284
+ _argvec[2+4] = (unsigned long)arg4; \
2285
+ _argvec[2+5] = (unsigned long)arg5; \
2286
+ _argvec[2+6] = (unsigned long)arg6; \
2287
+ _argvec[2+7] = (unsigned long)arg7; \
2288
+ _argvec[2+8] = (unsigned long)arg8; \
2289
+ _argvec[2+9] = (unsigned long)arg9; \
2290
+ _argvec[2+10] = (unsigned long)arg10; \
2291
+ __asm__ volatile( \
2292
+ "mr 11,%1\n\t" \
2293
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2294
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2295
+ "addi 1,1,-128\n\t" /* expand stack frame */ \
2296
+ /* arg10 */ \
2297
+ "ld 3,80(11)\n\t" \
2298
+ "std 3,120(1)\n\t" \
2299
+ /* arg9 */ \
2300
+ "ld 3,72(11)\n\t" \
2301
+ "std 3,112(1)\n\t" \
2302
+ /* args1-8 */ \
2303
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2304
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2305
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2306
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2307
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2308
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2309
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2310
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2311
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2312
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2313
+ "mr 11,%1\n\t" \
2314
+ "mr %0,3\n\t" \
2315
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
2316
+ "addi 1,1,128" /* restore frame */ \
2317
+ : /*out*/ "=r" (_res) \
2318
+ : /*in*/ "r" (&_argvec[2]) \
2319
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2320
+ ); \
2321
+ lval = (__typeof__(lval)) _res; \
2322
+ } while (0)
2323
+
2324
+ #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2325
+ arg7,arg8,arg9,arg10,arg11) \
2326
+ do { \
2327
+ volatile OrigFn _orig = (orig); \
2328
+ volatile unsigned long _argvec[3+11]; \
2329
+ volatile unsigned long _res; \
2330
+ /* _argvec[0] holds current r2 across the call */ \
2331
+ _argvec[1] = (unsigned long)_orig.r2; \
2332
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2333
+ _argvec[2+1] = (unsigned long)arg1; \
2334
+ _argvec[2+2] = (unsigned long)arg2; \
2335
+ _argvec[2+3] = (unsigned long)arg3; \
2336
+ _argvec[2+4] = (unsigned long)arg4; \
2337
+ _argvec[2+5] = (unsigned long)arg5; \
2338
+ _argvec[2+6] = (unsigned long)arg6; \
2339
+ _argvec[2+7] = (unsigned long)arg7; \
2340
+ _argvec[2+8] = (unsigned long)arg8; \
2341
+ _argvec[2+9] = (unsigned long)arg9; \
2342
+ _argvec[2+10] = (unsigned long)arg10; \
2343
+ _argvec[2+11] = (unsigned long)arg11; \
2344
+ __asm__ volatile( \
2345
+ "mr 11,%1\n\t" \
2346
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2347
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2348
+ "addi 1,1,-144\n\t" /* expand stack frame */ \
2349
+ /* arg11 */ \
2350
+ "ld 3,88(11)\n\t" \
2351
+ "std 3,128(1)\n\t" \
2352
+ /* arg10 */ \
2353
+ "ld 3,80(11)\n\t" \
2354
+ "std 3,120(1)\n\t" \
2355
+ /* arg9 */ \
2356
+ "ld 3,72(11)\n\t" \
2357
+ "std 3,112(1)\n\t" \
2358
+ /* args1-8 */ \
2359
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2360
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2361
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2362
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2363
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2364
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2365
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2366
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2367
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2368
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2369
+ "mr 11,%1\n\t" \
2370
+ "mr %0,3\n\t" \
2371
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
2372
+ "addi 1,1,144" /* restore frame */ \
2373
+ : /*out*/ "=r" (_res) \
2374
+ : /*in*/ "r" (&_argvec[2]) \
2375
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2376
+ ); \
2377
+ lval = (__typeof__(lval)) _res; \
2378
+ } while (0)
2379
+
2380
+ #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2381
+ arg7,arg8,arg9,arg10,arg11,arg12) \
2382
+ do { \
2383
+ volatile OrigFn _orig = (orig); \
2384
+ volatile unsigned long _argvec[3+12]; \
2385
+ volatile unsigned long _res; \
2386
+ /* _argvec[0] holds current r2 across the call */ \
2387
+ _argvec[1] = (unsigned long)_orig.r2; \
2388
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2389
+ _argvec[2+1] = (unsigned long)arg1; \
2390
+ _argvec[2+2] = (unsigned long)arg2; \
2391
+ _argvec[2+3] = (unsigned long)arg3; \
2392
+ _argvec[2+4] = (unsigned long)arg4; \
2393
+ _argvec[2+5] = (unsigned long)arg5; \
2394
+ _argvec[2+6] = (unsigned long)arg6; \
2395
+ _argvec[2+7] = (unsigned long)arg7; \
2396
+ _argvec[2+8] = (unsigned long)arg8; \
2397
+ _argvec[2+9] = (unsigned long)arg9; \
2398
+ _argvec[2+10] = (unsigned long)arg10; \
2399
+ _argvec[2+11] = (unsigned long)arg11; \
2400
+ _argvec[2+12] = (unsigned long)arg12; \
2401
+ __asm__ volatile( \
2402
+ "mr 11,%1\n\t" \
2403
+ "std 2,-16(11)\n\t" /* save tocptr */ \
2404
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
2405
+ "addi 1,1,-144\n\t" /* expand stack frame */ \
2406
+ /* arg12 */ \
2407
+ "ld 3,96(11)\n\t" \
2408
+ "std 3,136(1)\n\t" \
2409
+ /* arg11 */ \
2410
+ "ld 3,88(11)\n\t" \
2411
+ "std 3,128(1)\n\t" \
2412
+ /* arg10 */ \
2413
+ "ld 3,80(11)\n\t" \
2414
+ "std 3,120(1)\n\t" \
2415
+ /* arg9 */ \
2416
+ "ld 3,72(11)\n\t" \
2417
+ "std 3,112(1)\n\t" \
2418
+ /* args1-8 */ \
2419
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
2420
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
2421
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
2422
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
2423
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
2424
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
2425
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
2426
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
2427
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
2428
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2429
+ "mr 11,%1\n\t" \
2430
+ "mr %0,3\n\t" \
2431
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
2432
+ "addi 1,1,144" /* restore frame */ \
2433
+ : /*out*/ "=r" (_res) \
2434
+ : /*in*/ "r" (&_argvec[2]) \
2435
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2436
+ ); \
2437
+ lval = (__typeof__(lval)) _res; \
2438
+ } while (0)
2439
+
2440
+ #endif /* PLAT_ppc64_linux */
2441
+
2442
+ /* ------------------------ ppc32-aix5 ------------------------- */
2443
+
2444
+ #if defined(PLAT_ppc32_aix5)
2445
+
2446
+ /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2447
+
2448
+ /* These regs are trashed by the hidden call. */
2449
+ #define __CALLER_SAVED_REGS \
2450
+ "lr", "ctr", "xer", \
2451
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
2452
+ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
2453
+ "r11", "r12", "r13"
2454
+
2455
+ /* Expand the stack frame, copying enough info that unwinding
2456
+ still works. Trashes r3. */
2457
+
2458
+ #define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \
2459
+ "addi 1,1,-" #_n_fr "\n\t" \
2460
+ "lwz 3," #_n_fr "(1)\n\t" \
2461
+ "stw 3,0(1)\n\t"
2462
+
2463
+ #define VG_CONTRACT_FRAME_BY(_n_fr) \
2464
+ "addi 1,1," #_n_fr "\n\t"
2465
+
2466
+ /* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
2467
+ long) == 4. */
2468
+
2469
+ #define CALL_FN_W_v(lval, orig) \
2470
+ do { \
2471
+ volatile OrigFn _orig = (orig); \
2472
+ volatile unsigned long _argvec[3+0]; \
2473
+ volatile unsigned long _res; \
2474
+ /* _argvec[0] holds current r2 across the call */ \
2475
+ _argvec[1] = (unsigned long)_orig.r2; \
2476
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2477
+ __asm__ volatile( \
2478
+ "mr 11,%1\n\t" \
2479
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2480
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2481
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2482
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2483
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2484
+ "mr 11,%1\n\t" \
2485
+ "mr %0,3\n\t" \
2486
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2487
+ VG_CONTRACT_FRAME_BY(512) \
2488
+ : /*out*/ "=r" (_res) \
2489
+ : /*in*/ "r" (&_argvec[2]) \
2490
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2491
+ ); \
2492
+ lval = (__typeof__(lval)) _res; \
2493
+ } while (0)
2494
+
2495
+ #define CALL_FN_W_W(lval, orig, arg1) \
2496
+ do { \
2497
+ volatile OrigFn _orig = (orig); \
2498
+ volatile unsigned long _argvec[3+1]; \
2499
+ volatile unsigned long _res; \
2500
+ /* _argvec[0] holds current r2 across the call */ \
2501
+ _argvec[1] = (unsigned long)_orig.r2; \
2502
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2503
+ _argvec[2+1] = (unsigned long)arg1; \
2504
+ __asm__ volatile( \
2505
+ "mr 11,%1\n\t" \
2506
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2507
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2508
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2509
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2510
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2511
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2512
+ "mr 11,%1\n\t" \
2513
+ "mr %0,3\n\t" \
2514
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2515
+ VG_CONTRACT_FRAME_BY(512) \
2516
+ : /*out*/ "=r" (_res) \
2517
+ : /*in*/ "r" (&_argvec[2]) \
2518
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2519
+ ); \
2520
+ lval = (__typeof__(lval)) _res; \
2521
+ } while (0)
2522
+
2523
+ #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
2524
+ do { \
2525
+ volatile OrigFn _orig = (orig); \
2526
+ volatile unsigned long _argvec[3+2]; \
2527
+ volatile unsigned long _res; \
2528
+ /* _argvec[0] holds current r2 across the call */ \
2529
+ _argvec[1] = (unsigned long)_orig.r2; \
2530
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2531
+ _argvec[2+1] = (unsigned long)arg1; \
2532
+ _argvec[2+2] = (unsigned long)arg2; \
2533
+ __asm__ volatile( \
2534
+ "mr 11,%1\n\t" \
2535
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2536
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2537
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2538
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2539
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2540
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2541
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2542
+ "mr 11,%1\n\t" \
2543
+ "mr %0,3\n\t" \
2544
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2545
+ VG_CONTRACT_FRAME_BY(512) \
2546
+ : /*out*/ "=r" (_res) \
2547
+ : /*in*/ "r" (&_argvec[2]) \
2548
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2549
+ ); \
2550
+ lval = (__typeof__(lval)) _res; \
2551
+ } while (0)
2552
+
2553
+ #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
2554
+ do { \
2555
+ volatile OrigFn _orig = (orig); \
2556
+ volatile unsigned long _argvec[3+3]; \
2557
+ volatile unsigned long _res; \
2558
+ /* _argvec[0] holds current r2 across the call */ \
2559
+ _argvec[1] = (unsigned long)_orig.r2; \
2560
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2561
+ _argvec[2+1] = (unsigned long)arg1; \
2562
+ _argvec[2+2] = (unsigned long)arg2; \
2563
+ _argvec[2+3] = (unsigned long)arg3; \
2564
+ __asm__ volatile( \
2565
+ "mr 11,%1\n\t" \
2566
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2567
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2568
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2569
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2570
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2571
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2572
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2573
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2574
+ "mr 11,%1\n\t" \
2575
+ "mr %0,3\n\t" \
2576
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2577
+ VG_CONTRACT_FRAME_BY(512) \
2578
+ : /*out*/ "=r" (_res) \
2579
+ : /*in*/ "r" (&_argvec[2]) \
2580
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2581
+ ); \
2582
+ lval = (__typeof__(lval)) _res; \
2583
+ } while (0)
2584
+
2585
+ #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
2586
+ do { \
2587
+ volatile OrigFn _orig = (orig); \
2588
+ volatile unsigned long _argvec[3+4]; \
2589
+ volatile unsigned long _res; \
2590
+ /* _argvec[0] holds current r2 across the call */ \
2591
+ _argvec[1] = (unsigned long)_orig.r2; \
2592
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2593
+ _argvec[2+1] = (unsigned long)arg1; \
2594
+ _argvec[2+2] = (unsigned long)arg2; \
2595
+ _argvec[2+3] = (unsigned long)arg3; \
2596
+ _argvec[2+4] = (unsigned long)arg4; \
2597
+ __asm__ volatile( \
2598
+ "mr 11,%1\n\t" \
2599
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2600
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2601
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2602
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2603
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2604
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2605
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
2606
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2607
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2608
+ "mr 11,%1\n\t" \
2609
+ "mr %0,3\n\t" \
2610
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2611
+ VG_CONTRACT_FRAME_BY(512) \
2612
+ : /*out*/ "=r" (_res) \
2613
+ : /*in*/ "r" (&_argvec[2]) \
2614
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2615
+ ); \
2616
+ lval = (__typeof__(lval)) _res; \
2617
+ } while (0)
2618
+
2619
+ #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
2620
+ do { \
2621
+ volatile OrigFn _orig = (orig); \
2622
+ volatile unsigned long _argvec[3+5]; \
2623
+ volatile unsigned long _res; \
2624
+ /* _argvec[0] holds current r2 across the call */ \
2625
+ _argvec[1] = (unsigned long)_orig.r2; \
2626
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2627
+ _argvec[2+1] = (unsigned long)arg1; \
2628
+ _argvec[2+2] = (unsigned long)arg2; \
2629
+ _argvec[2+3] = (unsigned long)arg3; \
2630
+ _argvec[2+4] = (unsigned long)arg4; \
2631
+ _argvec[2+5] = (unsigned long)arg5; \
2632
+ __asm__ volatile( \
2633
+ "mr 11,%1\n\t" \
2634
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2635
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2636
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2637
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2638
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2639
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2640
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
2641
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
2642
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2643
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2644
+ "mr 11,%1\n\t" \
2645
+ "mr %0,3\n\t" \
2646
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2647
+ VG_CONTRACT_FRAME_BY(512) \
2648
+ : /*out*/ "=r" (_res) \
2649
+ : /*in*/ "r" (&_argvec[2]) \
2650
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2651
+ ); \
2652
+ lval = (__typeof__(lval)) _res; \
2653
+ } while (0)
2654
+
2655
+ #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
2656
+ do { \
2657
+ volatile OrigFn _orig = (orig); \
2658
+ volatile unsigned long _argvec[3+6]; \
2659
+ volatile unsigned long _res; \
2660
+ /* _argvec[0] holds current r2 across the call */ \
2661
+ _argvec[1] = (unsigned long)_orig.r2; \
2662
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2663
+ _argvec[2+1] = (unsigned long)arg1; \
2664
+ _argvec[2+2] = (unsigned long)arg2; \
2665
+ _argvec[2+3] = (unsigned long)arg3; \
2666
+ _argvec[2+4] = (unsigned long)arg4; \
2667
+ _argvec[2+5] = (unsigned long)arg5; \
2668
+ _argvec[2+6] = (unsigned long)arg6; \
2669
+ __asm__ volatile( \
2670
+ "mr 11,%1\n\t" \
2671
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2672
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2673
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2674
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2675
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2676
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2677
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
2678
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
2679
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
2680
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2681
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2682
+ "mr 11,%1\n\t" \
2683
+ "mr %0,3\n\t" \
2684
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2685
+ VG_CONTRACT_FRAME_BY(512) \
2686
+ : /*out*/ "=r" (_res) \
2687
+ : /*in*/ "r" (&_argvec[2]) \
2688
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2689
+ ); \
2690
+ lval = (__typeof__(lval)) _res; \
2691
+ } while (0)
2692
+
2693
+ #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2694
+ arg7) \
2695
+ do { \
2696
+ volatile OrigFn _orig = (orig); \
2697
+ volatile unsigned long _argvec[3+7]; \
2698
+ volatile unsigned long _res; \
2699
+ /* _argvec[0] holds current r2 across the call */ \
2700
+ _argvec[1] = (unsigned long)_orig.r2; \
2701
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2702
+ _argvec[2+1] = (unsigned long)arg1; \
2703
+ _argvec[2+2] = (unsigned long)arg2; \
2704
+ _argvec[2+3] = (unsigned long)arg3; \
2705
+ _argvec[2+4] = (unsigned long)arg4; \
2706
+ _argvec[2+5] = (unsigned long)arg5; \
2707
+ _argvec[2+6] = (unsigned long)arg6; \
2708
+ _argvec[2+7] = (unsigned long)arg7; \
2709
+ __asm__ volatile( \
2710
+ "mr 11,%1\n\t" \
2711
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2712
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2713
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2714
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2715
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2716
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2717
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
2718
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
2719
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
2720
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
2721
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2722
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2723
+ "mr 11,%1\n\t" \
2724
+ "mr %0,3\n\t" \
2725
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2726
+ VG_CONTRACT_FRAME_BY(512) \
2727
+ : /*out*/ "=r" (_res) \
2728
+ : /*in*/ "r" (&_argvec[2]) \
2729
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2730
+ ); \
2731
+ lval = (__typeof__(lval)) _res; \
2732
+ } while (0)
2733
+
2734
+ #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2735
+ arg7,arg8) \
2736
+ do { \
2737
+ volatile OrigFn _orig = (orig); \
2738
+ volatile unsigned long _argvec[3+8]; \
2739
+ volatile unsigned long _res; \
2740
+ /* _argvec[0] holds current r2 across the call */ \
2741
+ _argvec[1] = (unsigned long)_orig.r2; \
2742
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2743
+ _argvec[2+1] = (unsigned long)arg1; \
2744
+ _argvec[2+2] = (unsigned long)arg2; \
2745
+ _argvec[2+3] = (unsigned long)arg3; \
2746
+ _argvec[2+4] = (unsigned long)arg4; \
2747
+ _argvec[2+5] = (unsigned long)arg5; \
2748
+ _argvec[2+6] = (unsigned long)arg6; \
2749
+ _argvec[2+7] = (unsigned long)arg7; \
2750
+ _argvec[2+8] = (unsigned long)arg8; \
2751
+ __asm__ volatile( \
2752
+ "mr 11,%1\n\t" \
2753
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2754
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2755
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2756
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2757
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2758
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2759
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
2760
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
2761
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
2762
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
2763
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
2764
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2765
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2766
+ "mr 11,%1\n\t" \
2767
+ "mr %0,3\n\t" \
2768
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2769
+ VG_CONTRACT_FRAME_BY(512) \
2770
+ : /*out*/ "=r" (_res) \
2771
+ : /*in*/ "r" (&_argvec[2]) \
2772
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2773
+ ); \
2774
+ lval = (__typeof__(lval)) _res; \
2775
+ } while (0)
2776
+
2777
+ #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2778
+ arg7,arg8,arg9) \
2779
+ do { \
2780
+ volatile OrigFn _orig = (orig); \
2781
+ volatile unsigned long _argvec[3+9]; \
2782
+ volatile unsigned long _res; \
2783
+ /* _argvec[0] holds current r2 across the call */ \
2784
+ _argvec[1] = (unsigned long)_orig.r2; \
2785
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2786
+ _argvec[2+1] = (unsigned long)arg1; \
2787
+ _argvec[2+2] = (unsigned long)arg2; \
2788
+ _argvec[2+3] = (unsigned long)arg3; \
2789
+ _argvec[2+4] = (unsigned long)arg4; \
2790
+ _argvec[2+5] = (unsigned long)arg5; \
2791
+ _argvec[2+6] = (unsigned long)arg6; \
2792
+ _argvec[2+7] = (unsigned long)arg7; \
2793
+ _argvec[2+8] = (unsigned long)arg8; \
2794
+ _argvec[2+9] = (unsigned long)arg9; \
2795
+ __asm__ volatile( \
2796
+ "mr 11,%1\n\t" \
2797
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2798
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2799
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2800
+ VG_EXPAND_FRAME_BY_trashes_r3(64) \
2801
+ /* arg9 */ \
2802
+ "lwz 3,36(11)\n\t" \
2803
+ "stw 3,56(1)\n\t" \
2804
+ /* args1-8 */ \
2805
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2806
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2807
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2808
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
2809
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
2810
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
2811
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
2812
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
2813
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2814
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2815
+ "mr 11,%1\n\t" \
2816
+ "mr %0,3\n\t" \
2817
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2818
+ VG_CONTRACT_FRAME_BY(64) \
2819
+ VG_CONTRACT_FRAME_BY(512) \
2820
+ : /*out*/ "=r" (_res) \
2821
+ : /*in*/ "r" (&_argvec[2]) \
2822
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2823
+ ); \
2824
+ lval = (__typeof__(lval)) _res; \
2825
+ } while (0)
2826
+
2827
+ #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2828
+ arg7,arg8,arg9,arg10) \
2829
+ do { \
2830
+ volatile OrigFn _orig = (orig); \
2831
+ volatile unsigned long _argvec[3+10]; \
2832
+ volatile unsigned long _res; \
2833
+ /* _argvec[0] holds current r2 across the call */ \
2834
+ _argvec[1] = (unsigned long)_orig.r2; \
2835
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2836
+ _argvec[2+1] = (unsigned long)arg1; \
2837
+ _argvec[2+2] = (unsigned long)arg2; \
2838
+ _argvec[2+3] = (unsigned long)arg3; \
2839
+ _argvec[2+4] = (unsigned long)arg4; \
2840
+ _argvec[2+5] = (unsigned long)arg5; \
2841
+ _argvec[2+6] = (unsigned long)arg6; \
2842
+ _argvec[2+7] = (unsigned long)arg7; \
2843
+ _argvec[2+8] = (unsigned long)arg8; \
2844
+ _argvec[2+9] = (unsigned long)arg9; \
2845
+ _argvec[2+10] = (unsigned long)arg10; \
2846
+ __asm__ volatile( \
2847
+ "mr 11,%1\n\t" \
2848
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2849
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2850
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2851
+ VG_EXPAND_FRAME_BY_trashes_r3(64) \
2852
+ /* arg10 */ \
2853
+ "lwz 3,40(11)\n\t" \
2854
+ "stw 3,60(1)\n\t" \
2855
+ /* arg9 */ \
2856
+ "lwz 3,36(11)\n\t" \
2857
+ "stw 3,56(1)\n\t" \
2858
+ /* args1-8 */ \
2859
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2860
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2861
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2862
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
2863
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
2864
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
2865
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
2866
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
2867
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2868
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2869
+ "mr 11,%1\n\t" \
2870
+ "mr %0,3\n\t" \
2871
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2872
+ VG_CONTRACT_FRAME_BY(64) \
2873
+ VG_CONTRACT_FRAME_BY(512) \
2874
+ : /*out*/ "=r" (_res) \
2875
+ : /*in*/ "r" (&_argvec[2]) \
2876
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2877
+ ); \
2878
+ lval = (__typeof__(lval)) _res; \
2879
+ } while (0)
2880
+
2881
+ #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2882
+ arg7,arg8,arg9,arg10,arg11) \
2883
+ do { \
2884
+ volatile OrigFn _orig = (orig); \
2885
+ volatile unsigned long _argvec[3+11]; \
2886
+ volatile unsigned long _res; \
2887
+ /* _argvec[0] holds current r2 across the call */ \
2888
+ _argvec[1] = (unsigned long)_orig.r2; \
2889
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2890
+ _argvec[2+1] = (unsigned long)arg1; \
2891
+ _argvec[2+2] = (unsigned long)arg2; \
2892
+ _argvec[2+3] = (unsigned long)arg3; \
2893
+ _argvec[2+4] = (unsigned long)arg4; \
2894
+ _argvec[2+5] = (unsigned long)arg5; \
2895
+ _argvec[2+6] = (unsigned long)arg6; \
2896
+ _argvec[2+7] = (unsigned long)arg7; \
2897
+ _argvec[2+8] = (unsigned long)arg8; \
2898
+ _argvec[2+9] = (unsigned long)arg9; \
2899
+ _argvec[2+10] = (unsigned long)arg10; \
2900
+ _argvec[2+11] = (unsigned long)arg11; \
2901
+ __asm__ volatile( \
2902
+ "mr 11,%1\n\t" \
2903
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2904
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2905
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2906
+ VG_EXPAND_FRAME_BY_trashes_r3(72) \
2907
+ /* arg11 */ \
2908
+ "lwz 3,44(11)\n\t" \
2909
+ "stw 3,64(1)\n\t" \
2910
+ /* arg10 */ \
2911
+ "lwz 3,40(11)\n\t" \
2912
+ "stw 3,60(1)\n\t" \
2913
+ /* arg9 */ \
2914
+ "lwz 3,36(11)\n\t" \
2915
+ "stw 3,56(1)\n\t" \
2916
+ /* args1-8 */ \
2917
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2918
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2919
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2920
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
2921
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
2922
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
2923
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
2924
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
2925
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2926
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2927
+ "mr 11,%1\n\t" \
2928
+ "mr %0,3\n\t" \
2929
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2930
+ VG_CONTRACT_FRAME_BY(72) \
2931
+ VG_CONTRACT_FRAME_BY(512) \
2932
+ : /*out*/ "=r" (_res) \
2933
+ : /*in*/ "r" (&_argvec[2]) \
2934
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2935
+ ); \
2936
+ lval = (__typeof__(lval)) _res; \
2937
+ } while (0)
2938
+
2939
+ #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
2940
+ arg7,arg8,arg9,arg10,arg11,arg12) \
2941
+ do { \
2942
+ volatile OrigFn _orig = (orig); \
2943
+ volatile unsigned long _argvec[3+12]; \
2944
+ volatile unsigned long _res; \
2945
+ /* _argvec[0] holds current r2 across the call */ \
2946
+ _argvec[1] = (unsigned long)_orig.r2; \
2947
+ _argvec[2] = (unsigned long)_orig.nraddr; \
2948
+ _argvec[2+1] = (unsigned long)arg1; \
2949
+ _argvec[2+2] = (unsigned long)arg2; \
2950
+ _argvec[2+3] = (unsigned long)arg3; \
2951
+ _argvec[2+4] = (unsigned long)arg4; \
2952
+ _argvec[2+5] = (unsigned long)arg5; \
2953
+ _argvec[2+6] = (unsigned long)arg6; \
2954
+ _argvec[2+7] = (unsigned long)arg7; \
2955
+ _argvec[2+8] = (unsigned long)arg8; \
2956
+ _argvec[2+9] = (unsigned long)arg9; \
2957
+ _argvec[2+10] = (unsigned long)arg10; \
2958
+ _argvec[2+11] = (unsigned long)arg11; \
2959
+ _argvec[2+12] = (unsigned long)arg12; \
2960
+ __asm__ volatile( \
2961
+ "mr 11,%1\n\t" \
2962
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
2963
+ "stw 2,-8(11)\n\t" /* save tocptr */ \
2964
+ "lwz 2,-4(11)\n\t" /* use nraddr's tocptr */ \
2965
+ VG_EXPAND_FRAME_BY_trashes_r3(72) \
2966
+ /* arg12 */ \
2967
+ "lwz 3,48(11)\n\t" \
2968
+ "stw 3,68(1)\n\t" \
2969
+ /* arg11 */ \
2970
+ "lwz 3,44(11)\n\t" \
2971
+ "stw 3,64(1)\n\t" \
2972
+ /* arg10 */ \
2973
+ "lwz 3,40(11)\n\t" \
2974
+ "stw 3,60(1)\n\t" \
2975
+ /* arg9 */ \
2976
+ "lwz 3,36(11)\n\t" \
2977
+ "stw 3,56(1)\n\t" \
2978
+ /* args1-8 */ \
2979
+ "lwz 3, 4(11)\n\t" /* arg1->r3 */ \
2980
+ "lwz 4, 8(11)\n\t" /* arg2->r4 */ \
2981
+ "lwz 5, 12(11)\n\t" /* arg3->r5 */ \
2982
+ "lwz 6, 16(11)\n\t" /* arg4->r6 */ \
2983
+ "lwz 7, 20(11)\n\t" /* arg5->r7 */ \
2984
+ "lwz 8, 24(11)\n\t" /* arg6->r8 */ \
2985
+ "lwz 9, 28(11)\n\t" /* arg7->r9 */ \
2986
+ "lwz 10, 32(11)\n\t" /* arg8->r10 */ \
2987
+ "lwz 11, 0(11)\n\t" /* target->r11 */ \
2988
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
2989
+ "mr 11,%1\n\t" \
2990
+ "mr %0,3\n\t" \
2991
+ "lwz 2,-8(11)\n\t" /* restore tocptr */ \
2992
+ VG_CONTRACT_FRAME_BY(72) \
2993
+ VG_CONTRACT_FRAME_BY(512) \
2994
+ : /*out*/ "=r" (_res) \
2995
+ : /*in*/ "r" (&_argvec[2]) \
2996
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2997
+ ); \
2998
+ lval = (__typeof__(lval)) _res; \
2999
+ } while (0)
3000
+
3001
+ #endif /* PLAT_ppc32_aix5 */
3002
+
3003
+ /* ------------------------ ppc64-aix5 ------------------------- */
3004
+
3005
+ #if defined(PLAT_ppc64_aix5)
3006
+
3007
+ /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
3008
+
3009
+ /* These regs are trashed by the hidden call. */
3010
+ #define __CALLER_SAVED_REGS \
3011
+ "lr", "ctr", "xer", \
3012
+ "cr0", "cr1", "cr2", "cr3", "cr4", "cr5", "cr6", "cr7", \
3013
+ "r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", \
3014
+ "r11", "r12", "r13"
3015
+
3016
+ /* Expand the stack frame, copying enough info that unwinding
3017
+ still works. Trashes r3. */
3018
+
3019
+ #define VG_EXPAND_FRAME_BY_trashes_r3(_n_fr) \
3020
+ "addi 1,1,-" #_n_fr "\n\t" \
3021
+ "ld 3," #_n_fr "(1)\n\t" \
3022
+ "std 3,0(1)\n\t"
3023
+
3024
+ #define VG_CONTRACT_FRAME_BY(_n_fr) \
3025
+ "addi 1,1," #_n_fr "\n\t"
3026
+
3027
+ /* These CALL_FN_ macros assume that on ppc64-aix5, sizeof(unsigned
3028
+ long) == 8. */
3029
+
3030
+ #define CALL_FN_W_v(lval, orig) \
3031
+ do { \
3032
+ volatile OrigFn _orig = (orig); \
3033
+ volatile unsigned long _argvec[3+0]; \
3034
+ volatile unsigned long _res; \
3035
+ /* _argvec[0] holds current r2 across the call */ \
3036
+ _argvec[1] = (unsigned long)_orig.r2; \
3037
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3038
+ __asm__ volatile( \
3039
+ "mr 11,%1\n\t" \
3040
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3041
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3042
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3043
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3044
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3045
+ "mr 11,%1\n\t" \
3046
+ "mr %0,3\n\t" \
3047
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3048
+ VG_CONTRACT_FRAME_BY(512) \
3049
+ : /*out*/ "=r" (_res) \
3050
+ : /*in*/ "r" (&_argvec[2]) \
3051
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3052
+ ); \
3053
+ lval = (__typeof__(lval)) _res; \
3054
+ } while (0)
3055
+
3056
+ #define CALL_FN_W_W(lval, orig, arg1) \
3057
+ do { \
3058
+ volatile OrigFn _orig = (orig); \
3059
+ volatile unsigned long _argvec[3+1]; \
3060
+ volatile unsigned long _res; \
3061
+ /* _argvec[0] holds current r2 across the call */ \
3062
+ _argvec[1] = (unsigned long)_orig.r2; \
3063
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3064
+ _argvec[2+1] = (unsigned long)arg1; \
3065
+ __asm__ volatile( \
3066
+ "mr 11,%1\n\t" \
3067
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3068
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3069
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3070
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3071
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3072
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3073
+ "mr 11,%1\n\t" \
3074
+ "mr %0,3\n\t" \
3075
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3076
+ VG_CONTRACT_FRAME_BY(512) \
3077
+ : /*out*/ "=r" (_res) \
3078
+ : /*in*/ "r" (&_argvec[2]) \
3079
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3080
+ ); \
3081
+ lval = (__typeof__(lval)) _res; \
3082
+ } while (0)
3083
+
3084
+ #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
3085
+ do { \
3086
+ volatile OrigFn _orig = (orig); \
3087
+ volatile unsigned long _argvec[3+2]; \
3088
+ volatile unsigned long _res; \
3089
+ /* _argvec[0] holds current r2 across the call */ \
3090
+ _argvec[1] = (unsigned long)_orig.r2; \
3091
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3092
+ _argvec[2+1] = (unsigned long)arg1; \
3093
+ _argvec[2+2] = (unsigned long)arg2; \
3094
+ __asm__ volatile( \
3095
+ "mr 11,%1\n\t" \
3096
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3097
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3098
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3099
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3100
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3101
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3102
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3103
+ "mr 11,%1\n\t" \
3104
+ "mr %0,3\n\t" \
3105
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3106
+ VG_CONTRACT_FRAME_BY(512) \
3107
+ : /*out*/ "=r" (_res) \
3108
+ : /*in*/ "r" (&_argvec[2]) \
3109
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3110
+ ); \
3111
+ lval = (__typeof__(lval)) _res; \
3112
+ } while (0)
3113
+
3114
+ #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
3115
+ do { \
3116
+ volatile OrigFn _orig = (orig); \
3117
+ volatile unsigned long _argvec[3+3]; \
3118
+ volatile unsigned long _res; \
3119
+ /* _argvec[0] holds current r2 across the call */ \
3120
+ _argvec[1] = (unsigned long)_orig.r2; \
3121
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3122
+ _argvec[2+1] = (unsigned long)arg1; \
3123
+ _argvec[2+2] = (unsigned long)arg2; \
3124
+ _argvec[2+3] = (unsigned long)arg3; \
3125
+ __asm__ volatile( \
3126
+ "mr 11,%1\n\t" \
3127
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3128
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3129
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3130
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3131
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3132
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3133
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3134
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3135
+ "mr 11,%1\n\t" \
3136
+ "mr %0,3\n\t" \
3137
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3138
+ VG_CONTRACT_FRAME_BY(512) \
3139
+ : /*out*/ "=r" (_res) \
3140
+ : /*in*/ "r" (&_argvec[2]) \
3141
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3142
+ ); \
3143
+ lval = (__typeof__(lval)) _res; \
3144
+ } while (0)
3145
+
3146
+ #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
3147
+ do { \
3148
+ volatile OrigFn _orig = (orig); \
3149
+ volatile unsigned long _argvec[3+4]; \
3150
+ volatile unsigned long _res; \
3151
+ /* _argvec[0] holds current r2 across the call */ \
3152
+ _argvec[1] = (unsigned long)_orig.r2; \
3153
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3154
+ _argvec[2+1] = (unsigned long)arg1; \
3155
+ _argvec[2+2] = (unsigned long)arg2; \
3156
+ _argvec[2+3] = (unsigned long)arg3; \
3157
+ _argvec[2+4] = (unsigned long)arg4; \
3158
+ __asm__ volatile( \
3159
+ "mr 11,%1\n\t" \
3160
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3161
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3162
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3163
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3164
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3165
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3166
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3167
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3168
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3169
+ "mr 11,%1\n\t" \
3170
+ "mr %0,3\n\t" \
3171
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3172
+ VG_CONTRACT_FRAME_BY(512) \
3173
+ : /*out*/ "=r" (_res) \
3174
+ : /*in*/ "r" (&_argvec[2]) \
3175
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3176
+ ); \
3177
+ lval = (__typeof__(lval)) _res; \
3178
+ } while (0)
3179
+
3180
+ #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
3181
+ do { \
3182
+ volatile OrigFn _orig = (orig); \
3183
+ volatile unsigned long _argvec[3+5]; \
3184
+ volatile unsigned long _res; \
3185
+ /* _argvec[0] holds current r2 across the call */ \
3186
+ _argvec[1] = (unsigned long)_orig.r2; \
3187
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3188
+ _argvec[2+1] = (unsigned long)arg1; \
3189
+ _argvec[2+2] = (unsigned long)arg2; \
3190
+ _argvec[2+3] = (unsigned long)arg3; \
3191
+ _argvec[2+4] = (unsigned long)arg4; \
3192
+ _argvec[2+5] = (unsigned long)arg5; \
3193
+ __asm__ volatile( \
3194
+ "mr 11,%1\n\t" \
3195
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3196
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3197
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3198
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3199
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3200
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3201
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3202
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3203
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3204
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3205
+ "mr 11,%1\n\t" \
3206
+ "mr %0,3\n\t" \
3207
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3208
+ VG_CONTRACT_FRAME_BY(512) \
3209
+ : /*out*/ "=r" (_res) \
3210
+ : /*in*/ "r" (&_argvec[2]) \
3211
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3212
+ ); \
3213
+ lval = (__typeof__(lval)) _res; \
3214
+ } while (0)
3215
+
3216
+ #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
3217
+ do { \
3218
+ volatile OrigFn _orig = (orig); \
3219
+ volatile unsigned long _argvec[3+6]; \
3220
+ volatile unsigned long _res; \
3221
+ /* _argvec[0] holds current r2 across the call */ \
3222
+ _argvec[1] = (unsigned long)_orig.r2; \
3223
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3224
+ _argvec[2+1] = (unsigned long)arg1; \
3225
+ _argvec[2+2] = (unsigned long)arg2; \
3226
+ _argvec[2+3] = (unsigned long)arg3; \
3227
+ _argvec[2+4] = (unsigned long)arg4; \
3228
+ _argvec[2+5] = (unsigned long)arg5; \
3229
+ _argvec[2+6] = (unsigned long)arg6; \
3230
+ __asm__ volatile( \
3231
+ "mr 11,%1\n\t" \
3232
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3233
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3234
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3235
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3236
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3237
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3238
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3239
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3240
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3241
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3242
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3243
+ "mr 11,%1\n\t" \
3244
+ "mr %0,3\n\t" \
3245
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3246
+ VG_CONTRACT_FRAME_BY(512) \
3247
+ : /*out*/ "=r" (_res) \
3248
+ : /*in*/ "r" (&_argvec[2]) \
3249
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3250
+ ); \
3251
+ lval = (__typeof__(lval)) _res; \
3252
+ } while (0)
3253
+
3254
+ #define CALL_FN_W_7W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3255
+ arg7) \
3256
+ do { \
3257
+ volatile OrigFn _orig = (orig); \
3258
+ volatile unsigned long _argvec[3+7]; \
3259
+ volatile unsigned long _res; \
3260
+ /* _argvec[0] holds current r2 across the call */ \
3261
+ _argvec[1] = (unsigned long)_orig.r2; \
3262
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3263
+ _argvec[2+1] = (unsigned long)arg1; \
3264
+ _argvec[2+2] = (unsigned long)arg2; \
3265
+ _argvec[2+3] = (unsigned long)arg3; \
3266
+ _argvec[2+4] = (unsigned long)arg4; \
3267
+ _argvec[2+5] = (unsigned long)arg5; \
3268
+ _argvec[2+6] = (unsigned long)arg6; \
3269
+ _argvec[2+7] = (unsigned long)arg7; \
3270
+ __asm__ volatile( \
3271
+ "mr 11,%1\n\t" \
3272
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3273
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3274
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3275
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3276
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3277
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3278
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3279
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3280
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3281
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3282
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3283
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3284
+ "mr 11,%1\n\t" \
3285
+ "mr %0,3\n\t" \
3286
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3287
+ VG_CONTRACT_FRAME_BY(512) \
3288
+ : /*out*/ "=r" (_res) \
3289
+ : /*in*/ "r" (&_argvec[2]) \
3290
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3291
+ ); \
3292
+ lval = (__typeof__(lval)) _res; \
3293
+ } while (0)
3294
+
3295
+ #define CALL_FN_W_8W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3296
+ arg7,arg8) \
3297
+ do { \
3298
+ volatile OrigFn _orig = (orig); \
3299
+ volatile unsigned long _argvec[3+8]; \
3300
+ volatile unsigned long _res; \
3301
+ /* _argvec[0] holds current r2 across the call */ \
3302
+ _argvec[1] = (unsigned long)_orig.r2; \
3303
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3304
+ _argvec[2+1] = (unsigned long)arg1; \
3305
+ _argvec[2+2] = (unsigned long)arg2; \
3306
+ _argvec[2+3] = (unsigned long)arg3; \
3307
+ _argvec[2+4] = (unsigned long)arg4; \
3308
+ _argvec[2+5] = (unsigned long)arg5; \
3309
+ _argvec[2+6] = (unsigned long)arg6; \
3310
+ _argvec[2+7] = (unsigned long)arg7; \
3311
+ _argvec[2+8] = (unsigned long)arg8; \
3312
+ __asm__ volatile( \
3313
+ "mr 11,%1\n\t" \
3314
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3315
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3316
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3317
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3318
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3319
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3320
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3321
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3322
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3323
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3324
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
3325
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3326
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3327
+ "mr 11,%1\n\t" \
3328
+ "mr %0,3\n\t" \
3329
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3330
+ VG_CONTRACT_FRAME_BY(512) \
3331
+ : /*out*/ "=r" (_res) \
3332
+ : /*in*/ "r" (&_argvec[2]) \
3333
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3334
+ ); \
3335
+ lval = (__typeof__(lval)) _res; \
3336
+ } while (0)
3337
+
3338
+ #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3339
+ arg7,arg8,arg9) \
3340
+ do { \
3341
+ volatile OrigFn _orig = (orig); \
3342
+ volatile unsigned long _argvec[3+9]; \
3343
+ volatile unsigned long _res; \
3344
+ /* _argvec[0] holds current r2 across the call */ \
3345
+ _argvec[1] = (unsigned long)_orig.r2; \
3346
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3347
+ _argvec[2+1] = (unsigned long)arg1; \
3348
+ _argvec[2+2] = (unsigned long)arg2; \
3349
+ _argvec[2+3] = (unsigned long)arg3; \
3350
+ _argvec[2+4] = (unsigned long)arg4; \
3351
+ _argvec[2+5] = (unsigned long)arg5; \
3352
+ _argvec[2+6] = (unsigned long)arg6; \
3353
+ _argvec[2+7] = (unsigned long)arg7; \
3354
+ _argvec[2+8] = (unsigned long)arg8; \
3355
+ _argvec[2+9] = (unsigned long)arg9; \
3356
+ __asm__ volatile( \
3357
+ "mr 11,%1\n\t" \
3358
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3359
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3360
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3361
+ VG_EXPAND_FRAME_BY_trashes_r3(128) \
3362
+ /* arg9 */ \
3363
+ "ld 3,72(11)\n\t" \
3364
+ "std 3,112(1)\n\t" \
3365
+ /* args1-8 */ \
3366
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3367
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3368
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3369
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3370
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3371
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3372
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3373
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
3374
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3375
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3376
+ "mr 11,%1\n\t" \
3377
+ "mr %0,3\n\t" \
3378
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3379
+ VG_CONTRACT_FRAME_BY(128) \
3380
+ VG_CONTRACT_FRAME_BY(512) \
3381
+ : /*out*/ "=r" (_res) \
3382
+ : /*in*/ "r" (&_argvec[2]) \
3383
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3384
+ ); \
3385
+ lval = (__typeof__(lval)) _res; \
3386
+ } while (0)
3387
+
3388
+ #define CALL_FN_W_10W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3389
+ arg7,arg8,arg9,arg10) \
3390
+ do { \
3391
+ volatile OrigFn _orig = (orig); \
3392
+ volatile unsigned long _argvec[3+10]; \
3393
+ volatile unsigned long _res; \
3394
+ /* _argvec[0] holds current r2 across the call */ \
3395
+ _argvec[1] = (unsigned long)_orig.r2; \
3396
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3397
+ _argvec[2+1] = (unsigned long)arg1; \
3398
+ _argvec[2+2] = (unsigned long)arg2; \
3399
+ _argvec[2+3] = (unsigned long)arg3; \
3400
+ _argvec[2+4] = (unsigned long)arg4; \
3401
+ _argvec[2+5] = (unsigned long)arg5; \
3402
+ _argvec[2+6] = (unsigned long)arg6; \
3403
+ _argvec[2+7] = (unsigned long)arg7; \
3404
+ _argvec[2+8] = (unsigned long)arg8; \
3405
+ _argvec[2+9] = (unsigned long)arg9; \
3406
+ _argvec[2+10] = (unsigned long)arg10; \
3407
+ __asm__ volatile( \
3408
+ "mr 11,%1\n\t" \
3409
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3410
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3411
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3412
+ VG_EXPAND_FRAME_BY_trashes_r3(128) \
3413
+ /* arg10 */ \
3414
+ "ld 3,80(11)\n\t" \
3415
+ "std 3,120(1)\n\t" \
3416
+ /* arg9 */ \
3417
+ "ld 3,72(11)\n\t" \
3418
+ "std 3,112(1)\n\t" \
3419
+ /* args1-8 */ \
3420
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3421
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3422
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3423
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3424
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3425
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3426
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3427
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
3428
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3429
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3430
+ "mr 11,%1\n\t" \
3431
+ "mr %0,3\n\t" \
3432
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3433
+ VG_CONTRACT_FRAME_BY(128) \
3434
+ VG_CONTRACT_FRAME_BY(512) \
3435
+ : /*out*/ "=r" (_res) \
3436
+ : /*in*/ "r" (&_argvec[2]) \
3437
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3438
+ ); \
3439
+ lval = (__typeof__(lval)) _res; \
3440
+ } while (0)
3441
+
3442
+ #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3443
+ arg7,arg8,arg9,arg10,arg11) \
3444
+ do { \
3445
+ volatile OrigFn _orig = (orig); \
3446
+ volatile unsigned long _argvec[3+11]; \
3447
+ volatile unsigned long _res; \
3448
+ /* _argvec[0] holds current r2 across the call */ \
3449
+ _argvec[1] = (unsigned long)_orig.r2; \
3450
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3451
+ _argvec[2+1] = (unsigned long)arg1; \
3452
+ _argvec[2+2] = (unsigned long)arg2; \
3453
+ _argvec[2+3] = (unsigned long)arg3; \
3454
+ _argvec[2+4] = (unsigned long)arg4; \
3455
+ _argvec[2+5] = (unsigned long)arg5; \
3456
+ _argvec[2+6] = (unsigned long)arg6; \
3457
+ _argvec[2+7] = (unsigned long)arg7; \
3458
+ _argvec[2+8] = (unsigned long)arg8; \
3459
+ _argvec[2+9] = (unsigned long)arg9; \
3460
+ _argvec[2+10] = (unsigned long)arg10; \
3461
+ _argvec[2+11] = (unsigned long)arg11; \
3462
+ __asm__ volatile( \
3463
+ "mr 11,%1\n\t" \
3464
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3465
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3466
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3467
+ VG_EXPAND_FRAME_BY_trashes_r3(144) \
3468
+ /* arg11 */ \
3469
+ "ld 3,88(11)\n\t" \
3470
+ "std 3,128(1)\n\t" \
3471
+ /* arg10 */ \
3472
+ "ld 3,80(11)\n\t" \
3473
+ "std 3,120(1)\n\t" \
3474
+ /* arg9 */ \
3475
+ "ld 3,72(11)\n\t" \
3476
+ "std 3,112(1)\n\t" \
3477
+ /* args1-8 */ \
3478
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3479
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3480
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3481
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3482
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3483
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3484
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3485
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
3486
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3487
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3488
+ "mr 11,%1\n\t" \
3489
+ "mr %0,3\n\t" \
3490
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3491
+ VG_CONTRACT_FRAME_BY(144) \
3492
+ VG_CONTRACT_FRAME_BY(512) \
3493
+ : /*out*/ "=r" (_res) \
3494
+ : /*in*/ "r" (&_argvec[2]) \
3495
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3496
+ ); \
3497
+ lval = (__typeof__(lval)) _res; \
3498
+ } while (0)
3499
+
3500
+ #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3501
+ arg7,arg8,arg9,arg10,arg11,arg12) \
3502
+ do { \
3503
+ volatile OrigFn _orig = (orig); \
3504
+ volatile unsigned long _argvec[3+12]; \
3505
+ volatile unsigned long _res; \
3506
+ /* _argvec[0] holds current r2 across the call */ \
3507
+ _argvec[1] = (unsigned long)_orig.r2; \
3508
+ _argvec[2] = (unsigned long)_orig.nraddr; \
3509
+ _argvec[2+1] = (unsigned long)arg1; \
3510
+ _argvec[2+2] = (unsigned long)arg2; \
3511
+ _argvec[2+3] = (unsigned long)arg3; \
3512
+ _argvec[2+4] = (unsigned long)arg4; \
3513
+ _argvec[2+5] = (unsigned long)arg5; \
3514
+ _argvec[2+6] = (unsigned long)arg6; \
3515
+ _argvec[2+7] = (unsigned long)arg7; \
3516
+ _argvec[2+8] = (unsigned long)arg8; \
3517
+ _argvec[2+9] = (unsigned long)arg9; \
3518
+ _argvec[2+10] = (unsigned long)arg10; \
3519
+ _argvec[2+11] = (unsigned long)arg11; \
3520
+ _argvec[2+12] = (unsigned long)arg12; \
3521
+ __asm__ volatile( \
3522
+ "mr 11,%1\n\t" \
3523
+ VG_EXPAND_FRAME_BY_trashes_r3(512) \
3524
+ "std 2,-16(11)\n\t" /* save tocptr */ \
3525
+ "ld 2,-8(11)\n\t" /* use nraddr's tocptr */ \
3526
+ VG_EXPAND_FRAME_BY_trashes_r3(144) \
3527
+ /* arg12 */ \
3528
+ "ld 3,96(11)\n\t" \
3529
+ "std 3,136(1)\n\t" \
3530
+ /* arg11 */ \
3531
+ "ld 3,88(11)\n\t" \
3532
+ "std 3,128(1)\n\t" \
3533
+ /* arg10 */ \
3534
+ "ld 3,80(11)\n\t" \
3535
+ "std 3,120(1)\n\t" \
3536
+ /* arg9 */ \
3537
+ "ld 3,72(11)\n\t" \
3538
+ "std 3,112(1)\n\t" \
3539
+ /* args1-8 */ \
3540
+ "ld 3, 8(11)\n\t" /* arg1->r3 */ \
3541
+ "ld 4, 16(11)\n\t" /* arg2->r4 */ \
3542
+ "ld 5, 24(11)\n\t" /* arg3->r5 */ \
3543
+ "ld 6, 32(11)\n\t" /* arg4->r6 */ \
3544
+ "ld 7, 40(11)\n\t" /* arg5->r7 */ \
3545
+ "ld 8, 48(11)\n\t" /* arg6->r8 */ \
3546
+ "ld 9, 56(11)\n\t" /* arg7->r9 */ \
3547
+ "ld 10, 64(11)\n\t" /* arg8->r10 */ \
3548
+ "ld 11, 0(11)\n\t" /* target->r11 */ \
3549
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
3550
+ "mr 11,%1\n\t" \
3551
+ "mr %0,3\n\t" \
3552
+ "ld 2,-16(11)\n\t" /* restore tocptr */ \
3553
+ VG_CONTRACT_FRAME_BY(144) \
3554
+ VG_CONTRACT_FRAME_BY(512) \
3555
+ : /*out*/ "=r" (_res) \
3556
+ : /*in*/ "r" (&_argvec[2]) \
3557
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3558
+ ); \
3559
+ lval = (__typeof__(lval)) _res; \
3560
+ } while (0)
3561
+
3562
+ #endif /* PLAT_ppc64_aix5 */
3563
+
3564
+
3565
+ /* ------------------------------------------------------------------ */
3566
+ /* ARCHITECTURE INDEPENDENT MACROS for CLIENT REQUESTS. */
3567
+ /* */
3568
+ /* ------------------------------------------------------------------ */
3569
+
3570
+ /* Some request codes. There are many more of these, but most are not
3571
+ exposed to end-user view. These are the public ones, all of the
3572
+ form 0x1000 + small_number.
3573
+
3574
+ Core ones are in the range 0x00000000--0x0000ffff. The non-public
3575
+ ones start at 0x2000.
3576
+ */
3577
+
3578
+ /* These macros are used by tools -- they must be public, but don't
3579
+ embed them into other programs. */
3580
+ #define VG_USERREQ_TOOL_BASE(a,b) \
3581
+ ((unsigned int)(((a)&0xff) << 24 | ((b)&0xff) << 16))
3582
+ #define VG_IS_TOOL_USERREQ(a, b, v) \
3583
+ (VG_USERREQ_TOOL_BASE(a,b) == ((v) & 0xffff0000))
3584
+
3585
+ /* !! ABIWARNING !! ABIWARNING !! ABIWARNING !! ABIWARNING !!
3586
+ This enum comprises an ABI exported by Valgrind to programs
3587
+ which use client requests. DO NOT CHANGE THE ORDER OF THESE
3588
+ ENTRIES, NOR DELETE ANY -- add new ones at the end. */
3589
+ typedef
3590
+ enum { VG_USERREQ__RUNNING_ON_VALGRIND = 0x1001,
3591
+ VG_USERREQ__DISCARD_TRANSLATIONS = 0x1002,
3592
+
3593
+ /* These allow any function to be called from the simulated
3594
+ CPU but run on the real CPU. Nb: the first arg passed to
3595
+ the function is always the ThreadId of the running
3596
+ thread! So CLIENT_CALL0 actually requires a 1 arg
3597
+ function, etc. */
3598
+ VG_USERREQ__CLIENT_CALL0 = 0x1101,
3599
+ VG_USERREQ__CLIENT_CALL1 = 0x1102,
3600
+ VG_USERREQ__CLIENT_CALL2 = 0x1103,
3601
+ VG_USERREQ__CLIENT_CALL3 = 0x1104,
3602
+
3603
+ /* Can be useful in regression testing suites -- eg. can
3604
+ send Valgrind's output to /dev/null and still count
3605
+ errors. */
3606
+ VG_USERREQ__COUNT_ERRORS = 0x1201,
3607
+
3608
+ /* These are useful and can be interpreted by any tool that
3609
+ tracks malloc() et al, by using vg_replace_malloc.c. */
3610
+ VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
3611
+ VG_USERREQ__FREELIKE_BLOCK = 0x1302,
3612
+ /* Memory pool support. */
3613
+ VG_USERREQ__CREATE_MEMPOOL = 0x1303,
3614
+ VG_USERREQ__DESTROY_MEMPOOL = 0x1304,
3615
+ VG_USERREQ__MEMPOOL_ALLOC = 0x1305,
3616
+ VG_USERREQ__MEMPOOL_FREE = 0x1306,
3617
+ VG_USERREQ__MEMPOOL_TRIM = 0x1307,
3618
+ VG_USERREQ__MOVE_MEMPOOL = 0x1308,
3619
+ VG_USERREQ__MEMPOOL_CHANGE = 0x1309,
3620
+ VG_USERREQ__MEMPOOL_EXISTS = 0x130a,
3621
+
3622
+ /* Allow printfs to valgrind log. */
3623
+ VG_USERREQ__PRINTF = 0x1401,
3624
+ VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
3625
+
3626
+ /* Stack support. */
3627
+ VG_USERREQ__STACK_REGISTER = 0x1501,
3628
+ VG_USERREQ__STACK_DEREGISTER = 0x1502,
3629
+ VG_USERREQ__STACK_CHANGE = 0x1503
3630
+ } Vg_ClientRequest;
3631
+
3632
+ #if !defined(__GNUC__)
3633
+ # define __extension__ /* */
3634
+ #endif
3635
+
3636
+ /* Returns the number of Valgrinds this code is running under. That
3637
+ is, 0 if running natively, 1 if running under Valgrind, 2 if
3638
+ running under Valgrind which is running under another Valgrind,
3639
+ etc. */
3640
+ #define RUNNING_ON_VALGRIND __extension__ \
3641
+ ({unsigned int _qzz_res; \
3642
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0 /* if not */, \
3643
+ VG_USERREQ__RUNNING_ON_VALGRIND, \
3644
+ 0, 0, 0, 0, 0); \
3645
+ _qzz_res; \
3646
+ })
3647
+
3648
+
3649
+ /* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
3650
+ _qzz_len - 1]. Useful if you are debugging a JITter or some such,
3651
+ since it provides a way to make sure valgrind will retranslate the
3652
+ invalidated area. Returns no value. */
3653
+ #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
3654
+ {unsigned int _qzz_res; \
3655
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3656
+ VG_USERREQ__DISCARD_TRANSLATIONS, \
3657
+ _qzz_addr, _qzz_len, 0, 0, 0); \
3658
+ }
3659
+
3660
+
3661
+ /* These requests are for getting Valgrind itself to print something.
3662
+ Possibly with a backtrace. This is a really ugly hack. */
3663
+
3664
+ #if defined(NVALGRIND)
3665
+
3666
+ # define VALGRIND_PRINTF(...)
3667
+ # define VALGRIND_PRINTF_BACKTRACE(...)
3668
+
3669
+ #else /* NVALGRIND */
3670
+
3671
+ /* Modern GCC will optimize the static routine out if unused,
3672
+ and unused attribute will shut down warnings about it. */
3673
+ static int VALGRIND_PRINTF(const char *format, ...)
3674
+ __attribute__((format(__printf__, 1, 2), __unused__));
3675
+ static int
3676
+ VALGRIND_PRINTF(const char *format, ...)
3677
+ {
3678
+ unsigned long _qzz_res;
3679
+ va_list vargs;
3680
+ va_start(vargs, format);
3681
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
3682
+ (unsigned long)format, (unsigned long)vargs,
3683
+ 0, 0, 0);
3684
+ va_end(vargs);
3685
+ return (int)_qzz_res;
3686
+ }
3687
+
3688
+ static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
3689
+ __attribute__((format(__printf__, 1, 2), __unused__));
3690
+ static int
3691
+ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
3692
+ {
3693
+ unsigned long _qzz_res;
3694
+ va_list vargs;
3695
+ va_start(vargs, format);
3696
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
3697
+ (unsigned long)format, (unsigned long)vargs,
3698
+ 0, 0, 0);
3699
+ va_end(vargs);
3700
+ return (int)_qzz_res;
3701
+ }
3702
+
3703
+ #endif /* NVALGRIND */
3704
+
3705
+
3706
+ /* These requests allow control to move from the simulated CPU to the
3707
+ real CPU, calling an arbitary function.
3708
+
3709
+ Note that the current ThreadId is inserted as the first argument.
3710
+ So this call:
3711
+
3712
+ VALGRIND_NON_SIMD_CALL2(f, arg1, arg2)
3713
+
3714
+ requires f to have this signature:
3715
+
3716
+ Word f(Word tid, Word arg1, Word arg2)
3717
+
3718
+ where "Word" is a word-sized type.
3719
+
3720
+ Note that these client requests are not entirely reliable. For example,
3721
+ if you call a function with them that subsequently calls printf(),
3722
+ there's a high chance Valgrind will crash. Generally, your prospects of
3723
+ these working are made higher if the called function does not refer to
3724
+ any global variables, and does not refer to any libc or other functions
3725
+ (printf et al). Any kind of entanglement with libc or dynamic linking is
3726
+ likely to have a bad outcome, for tricky reasons which we've grappled
3727
+ with a lot in the past.
3728
+ */
3729
+ #define VALGRIND_NON_SIMD_CALL0(_qyy_fn) \
3730
+ __extension__ \
3731
+ ({unsigned long _qyy_res; \
3732
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
3733
+ VG_USERREQ__CLIENT_CALL0, \
3734
+ _qyy_fn, \
3735
+ 0, 0, 0, 0); \
3736
+ _qyy_res; \
3737
+ })
3738
+
3739
+ #define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
3740
+ __extension__ \
3741
+ ({unsigned long _qyy_res; \
3742
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
3743
+ VG_USERREQ__CLIENT_CALL1, \
3744
+ _qyy_fn, \
3745
+ _qyy_arg1, 0, 0, 0); \
3746
+ _qyy_res; \
3747
+ })
3748
+
3749
+ #define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
3750
+ __extension__ \
3751
+ ({unsigned long _qyy_res; \
3752
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
3753
+ VG_USERREQ__CLIENT_CALL2, \
3754
+ _qyy_fn, \
3755
+ _qyy_arg1, _qyy_arg2, 0, 0); \
3756
+ _qyy_res; \
3757
+ })
3758
+
3759
+ #define VALGRIND_NON_SIMD_CALL3(_qyy_fn, _qyy_arg1, _qyy_arg2, _qyy_arg3) \
3760
+ __extension__ \
3761
+ ({unsigned long _qyy_res; \
3762
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
3763
+ VG_USERREQ__CLIENT_CALL3, \
3764
+ _qyy_fn, \
3765
+ _qyy_arg1, _qyy_arg2, \
3766
+ _qyy_arg3, 0); \
3767
+ _qyy_res; \
3768
+ })
3769
+
3770
+
3771
+ /* Counts the number of errors that have been recorded by a tool. Nb:
3772
+ the tool must record the errors with VG_(maybe_record_error)() or
3773
+ VG_(unique_error)() for them to be counted. */
3774
+ #define VALGRIND_COUNT_ERRORS \
3775
+ __extension__ \
3776
+ ({unsigned int _qyy_res; \
3777
+ VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
3778
+ VG_USERREQ__COUNT_ERRORS, \
3779
+ 0, 0, 0, 0, 0); \
3780
+ _qyy_res; \
3781
+ })
3782
+
3783
+ /* Mark a block of memory as having been allocated by a malloc()-like
3784
+ function. `addr' is the start of the usable block (ie. after any
3785
+ redzone) `rzB' is redzone size if the allocator can apply redzones;
3786
+ use '0' if not. Adding redzones makes it more likely Valgrind will spot
3787
+ block overruns. `is_zeroed' indicates if the memory is zeroed, as it is
3788
+ for calloc(). Put it immediately after the point where a block is
3789
+ allocated.
3790
+
3791
+ If you're using Memcheck: If you're allocating memory via superblocks,
3792
+ and then handing out small chunks of each superblock, if you don't have
3793
+ redzones on your small blocks, it's worth marking the superblock with
3794
+ VALGRIND_MAKE_MEM_NOACCESS when it's created, so that block overruns are
3795
+ detected. But if you can put redzones on, it's probably better to not do
3796
+ this, so that messages for small overruns are described in terms of the
3797
+ small block rather than the superblock (but if you have a big overrun
3798
+ that skips over a redzone, you could miss an error this way). See
3799
+ memcheck/tests/custom_alloc.c for an example.
3800
+
3801
+ WARNING: if your allocator uses malloc() or 'new' to allocate
3802
+ superblocks, rather than mmap() or brk(), this will not work properly --
3803
+ you'll likely get assertion failures during leak detection. This is
3804
+ because Valgrind doesn't like seeing overlapping heap blocks. Sorry.
3805
+
3806
+ Nb: block must be freed via a free()-like function specified
3807
+ with VALGRIND_FREELIKE_BLOCK or mismatch errors will occur. */
3808
+ #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
3809
+ {unsigned int _qzz_res; \
3810
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3811
+ VG_USERREQ__MALLOCLIKE_BLOCK, \
3812
+ addr, sizeB, rzB, is_zeroed, 0); \
3813
+ }
3814
+
3815
+ /* Mark a block of memory as having been freed by a free()-like function.
3816
+ `rzB' is redzone size; it must match that given to
3817
+ VALGRIND_MALLOCLIKE_BLOCK. Memory not freed will be detected by the leak
3818
+ checker. Put it immediately after the point where the block is freed. */
3819
+ #define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
3820
+ {unsigned int _qzz_res; \
3821
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3822
+ VG_USERREQ__FREELIKE_BLOCK, \
3823
+ addr, rzB, 0, 0, 0); \
3824
+ }
3825
+
3826
+ /* Create a memory pool. */
3827
+ #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
3828
+ {unsigned int _qzz_res; \
3829
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3830
+ VG_USERREQ__CREATE_MEMPOOL, \
3831
+ pool, rzB, is_zeroed, 0, 0); \
3832
+ }
3833
+
3834
+ /* Destroy a memory pool. */
3835
+ #define VALGRIND_DESTROY_MEMPOOL(pool) \
3836
+ {unsigned int _qzz_res; \
3837
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3838
+ VG_USERREQ__DESTROY_MEMPOOL, \
3839
+ pool, 0, 0, 0, 0); \
3840
+ }
3841
+
3842
+ /* Associate a piece of memory with a memory pool. */
3843
+ #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
3844
+ {unsigned int _qzz_res; \
3845
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3846
+ VG_USERREQ__MEMPOOL_ALLOC, \
3847
+ pool, addr, size, 0, 0); \
3848
+ }
3849
+
3850
+ /* Disassociate a piece of memory from a memory pool. */
3851
+ #define VALGRIND_MEMPOOL_FREE(pool, addr) \
3852
+ {unsigned int _qzz_res; \
3853
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3854
+ VG_USERREQ__MEMPOOL_FREE, \
3855
+ pool, addr, 0, 0, 0); \
3856
+ }
3857
+
3858
+ /* Disassociate any pieces outside a particular range. */
3859
+ #define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \
3860
+ {unsigned int _qzz_res; \
3861
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3862
+ VG_USERREQ__MEMPOOL_TRIM, \
3863
+ pool, addr, size, 0, 0); \
3864
+ }
3865
+
3866
+ /* Resize and/or move a piece associated with a memory pool. */
3867
+ #define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \
3868
+ {unsigned int _qzz_res; \
3869
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3870
+ VG_USERREQ__MOVE_MEMPOOL, \
3871
+ poolA, poolB, 0, 0, 0); \
3872
+ }
3873
+
3874
+ /* Resize and/or move a piece associated with a memory pool. */
3875
+ #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \
3876
+ {unsigned int _qzz_res; \
3877
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3878
+ VG_USERREQ__MEMPOOL_CHANGE, \
3879
+ pool, addrA, addrB, size, 0); \
3880
+ }
3881
+
3882
+ /* Return 1 if a mempool exists, else 0. */
3883
+ #define VALGRIND_MEMPOOL_EXISTS(pool) \
3884
+ ({unsigned int _qzz_res; \
3885
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3886
+ VG_USERREQ__MEMPOOL_EXISTS, \
3887
+ pool, 0, 0, 0, 0); \
3888
+ _qzz_res; \
3889
+ })
3890
+
3891
+ /* Mark a piece of memory as being a stack. Returns a stack id. */
3892
+ #define VALGRIND_STACK_REGISTER(start, end) \
3893
+ ({unsigned int _qzz_res; \
3894
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3895
+ VG_USERREQ__STACK_REGISTER, \
3896
+ start, end, 0, 0, 0); \
3897
+ _qzz_res; \
3898
+ })
3899
+
3900
+ /* Unmark the piece of memory associated with a stack id as being a
3901
+ stack. */
3902
+ #define VALGRIND_STACK_DEREGISTER(id) \
3903
+ {unsigned int _qzz_res; \
3904
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3905
+ VG_USERREQ__STACK_DEREGISTER, \
3906
+ id, 0, 0, 0, 0); \
3907
+ }
3908
+
3909
+ /* Change the start and end address of the stack id. */
3910
+ #define VALGRIND_STACK_CHANGE(id, start, end) \
3911
+ {unsigned int _qzz_res; \
3912
+ VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3913
+ VG_USERREQ__STACK_CHANGE, \
3914
+ id, start, end, 0, 0); \
3915
+ }
3916
+
3917
+
3918
+ #undef PLAT_x86_linux
3919
+ #undef PLAT_amd64_linux
3920
+ #undef PLAT_ppc32_linux
3921
+ #undef PLAT_ppc64_linux
3922
+ #undef PLAT_ppc32_aix5
3923
+ #undef PLAT_ppc64_aix5
3924
+
3925
+ #endif /* __VALGRIND_H */