libv8 3.3.10.4 → 3.5.10.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (538) hide show
  1. data/lib/libv8/scons/CHANGES.txt +24 -231
  2. data/lib/libv8/scons/LICENSE.txt +1 -1
  3. data/lib/libv8/scons/MANIFEST +0 -1
  4. data/lib/libv8/scons/PKG-INFO +1 -1
  5. data/lib/libv8/scons/README.txt +9 -9
  6. data/lib/libv8/scons/RELEASE.txt +75 -77
  7. data/lib/libv8/scons/engine/SCons/Action.py +6 -22
  8. data/lib/libv8/scons/engine/SCons/Builder.py +2 -2
  9. data/lib/libv8/scons/engine/SCons/CacheDir.py +2 -2
  10. data/lib/libv8/scons/engine/SCons/Debug.py +2 -2
  11. data/lib/libv8/scons/engine/SCons/Defaults.py +10 -24
  12. data/lib/libv8/scons/engine/SCons/Environment.py +19 -118
  13. data/lib/libv8/scons/engine/SCons/Errors.py +2 -2
  14. data/lib/libv8/scons/engine/SCons/Executor.py +2 -2
  15. data/lib/libv8/scons/engine/SCons/Job.py +2 -2
  16. data/lib/libv8/scons/engine/SCons/Memoize.py +2 -2
  17. data/lib/libv8/scons/engine/SCons/Node/Alias.py +2 -2
  18. data/lib/libv8/scons/engine/SCons/Node/FS.py +121 -281
  19. data/lib/libv8/scons/engine/SCons/Node/Python.py +2 -2
  20. data/lib/libv8/scons/engine/SCons/Node/__init__.py +5 -6
  21. data/lib/libv8/scons/engine/SCons/Options/BoolOption.py +2 -2
  22. data/lib/libv8/scons/engine/SCons/Options/EnumOption.py +2 -2
  23. data/lib/libv8/scons/engine/SCons/Options/ListOption.py +2 -2
  24. data/lib/libv8/scons/engine/SCons/Options/PackageOption.py +2 -2
  25. data/lib/libv8/scons/engine/SCons/Options/PathOption.py +2 -2
  26. data/lib/libv8/scons/engine/SCons/Options/__init__.py +2 -2
  27. data/lib/libv8/scons/engine/SCons/PathList.py +2 -2
  28. data/lib/libv8/scons/engine/SCons/Platform/__init__.py +2 -2
  29. data/lib/libv8/scons/engine/SCons/Platform/aix.py +2 -2
  30. data/lib/libv8/scons/engine/SCons/Platform/cygwin.py +2 -2
  31. data/lib/libv8/scons/engine/SCons/Platform/darwin.py +3 -27
  32. data/lib/libv8/scons/engine/SCons/Platform/hpux.py +2 -2
  33. data/lib/libv8/scons/engine/SCons/Platform/irix.py +2 -2
  34. data/lib/libv8/scons/engine/SCons/Platform/os2.py +2 -2
  35. data/lib/libv8/scons/engine/SCons/Platform/posix.py +2 -2
  36. data/lib/libv8/scons/engine/SCons/Platform/sunos.py +2 -2
  37. data/lib/libv8/scons/engine/SCons/Platform/win32.py +2 -2
  38. data/lib/libv8/scons/engine/SCons/SConf.py +2 -2
  39. data/lib/libv8/scons/engine/SCons/SConsign.py +3 -9
  40. data/lib/libv8/scons/engine/SCons/Scanner/C.py +2 -2
  41. data/lib/libv8/scons/engine/SCons/Scanner/D.py +2 -2
  42. data/lib/libv8/scons/engine/SCons/Scanner/Dir.py +2 -2
  43. data/lib/libv8/scons/engine/SCons/Scanner/Fortran.py +2 -2
  44. data/lib/libv8/scons/engine/SCons/Scanner/IDL.py +2 -2
  45. data/lib/libv8/scons/engine/SCons/Scanner/LaTeX.py +2 -5
  46. data/lib/libv8/scons/engine/SCons/Scanner/Prog.py +2 -2
  47. data/lib/libv8/scons/engine/SCons/Scanner/RC.py +3 -3
  48. data/lib/libv8/scons/engine/SCons/Scanner/__init__.py +2 -2
  49. data/lib/libv8/scons/engine/SCons/Script/Interactive.py +2 -2
  50. data/lib/libv8/scons/engine/SCons/Script/Main.py +11 -82
  51. data/lib/libv8/scons/engine/SCons/Script/SConsOptions.py +5 -5
  52. data/lib/libv8/scons/engine/SCons/Script/SConscript.py +2 -2
  53. data/lib/libv8/scons/engine/SCons/Script/__init__.py +2 -2
  54. data/lib/libv8/scons/engine/SCons/Sig.py +2 -2
  55. data/lib/libv8/scons/engine/SCons/Subst.py +2 -2
  56. data/lib/libv8/scons/engine/SCons/Taskmaster.py +2 -10
  57. data/lib/libv8/scons/engine/SCons/Tool/386asm.py +2 -2
  58. data/lib/libv8/scons/engine/SCons/Tool/BitKeeper.py +2 -2
  59. data/lib/libv8/scons/engine/SCons/Tool/CVS.py +2 -2
  60. data/lib/libv8/scons/engine/SCons/Tool/FortranCommon.py +2 -19
  61. data/lib/libv8/scons/engine/SCons/Tool/JavaCommon.py +2 -2
  62. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/__init__.py +2 -2
  63. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/arch.py +2 -2
  64. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/common.py +2 -2
  65. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/netframework.py +2 -2
  66. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/sdk.py +2 -2
  67. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vc.py +6 -9
  68. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vs.py +2 -29
  69. data/lib/libv8/scons/engine/SCons/Tool/Perforce.py +2 -2
  70. data/lib/libv8/scons/engine/SCons/Tool/PharLapCommon.py +2 -2
  71. data/lib/libv8/scons/engine/SCons/Tool/RCS.py +2 -2
  72. data/lib/libv8/scons/engine/SCons/Tool/SCCS.py +2 -2
  73. data/lib/libv8/scons/engine/SCons/Tool/Subversion.py +2 -2
  74. data/lib/libv8/scons/engine/SCons/Tool/__init__.py +3 -3
  75. data/lib/libv8/scons/engine/SCons/Tool/aixc++.py +2 -2
  76. data/lib/libv8/scons/engine/SCons/Tool/aixcc.py +2 -2
  77. data/lib/libv8/scons/engine/SCons/Tool/aixf77.py +2 -2
  78. data/lib/libv8/scons/engine/SCons/Tool/aixlink.py +2 -2
  79. data/lib/libv8/scons/engine/SCons/Tool/applelink.py +2 -2
  80. data/lib/libv8/scons/engine/SCons/Tool/ar.py +2 -2
  81. data/lib/libv8/scons/engine/SCons/Tool/as.py +2 -2
  82. data/lib/libv8/scons/engine/SCons/Tool/bcc32.py +2 -2
  83. data/lib/libv8/scons/engine/SCons/Tool/c++.py +2 -2
  84. data/lib/libv8/scons/engine/SCons/Tool/cc.py +2 -2
  85. data/lib/libv8/scons/engine/SCons/Tool/cvf.py +2 -2
  86. data/lib/libv8/scons/engine/SCons/Tool/default.py +2 -2
  87. data/lib/libv8/scons/engine/SCons/Tool/dmd.py +7 -24
  88. data/lib/libv8/scons/engine/SCons/Tool/dvi.py +2 -2
  89. data/lib/libv8/scons/engine/SCons/Tool/dvipdf.py +2 -3
  90. data/lib/libv8/scons/engine/SCons/Tool/dvips.py +2 -3
  91. data/lib/libv8/scons/engine/SCons/Tool/f77.py +2 -2
  92. data/lib/libv8/scons/engine/SCons/Tool/f90.py +2 -2
  93. data/lib/libv8/scons/engine/SCons/Tool/f95.py +2 -2
  94. data/lib/libv8/scons/engine/SCons/Tool/filesystem.py +2 -2
  95. data/lib/libv8/scons/engine/SCons/Tool/fortran.py +2 -2
  96. data/lib/libv8/scons/engine/SCons/Tool/g++.py +2 -2
  97. data/lib/libv8/scons/engine/SCons/Tool/g77.py +2 -2
  98. data/lib/libv8/scons/engine/SCons/Tool/gas.py +2 -2
  99. data/lib/libv8/scons/engine/SCons/Tool/gcc.py +2 -2
  100. data/lib/libv8/scons/engine/SCons/Tool/gfortran.py +3 -3
  101. data/lib/libv8/scons/engine/SCons/Tool/gnulink.py +3 -2
  102. data/lib/libv8/scons/engine/SCons/Tool/gs.py +2 -2
  103. data/lib/libv8/scons/engine/SCons/Tool/hpc++.py +2 -2
  104. data/lib/libv8/scons/engine/SCons/Tool/hpcc.py +2 -2
  105. data/lib/libv8/scons/engine/SCons/Tool/hplink.py +2 -2
  106. data/lib/libv8/scons/engine/SCons/Tool/icc.py +2 -2
  107. data/lib/libv8/scons/engine/SCons/Tool/icl.py +2 -2
  108. data/lib/libv8/scons/engine/SCons/Tool/ifl.py +2 -2
  109. data/lib/libv8/scons/engine/SCons/Tool/ifort.py +2 -2
  110. data/lib/libv8/scons/engine/SCons/Tool/ilink.py +2 -2
  111. data/lib/libv8/scons/engine/SCons/Tool/ilink32.py +2 -2
  112. data/lib/libv8/scons/engine/SCons/Tool/install.py +3 -57
  113. data/lib/libv8/scons/engine/SCons/Tool/intelc.py +25 -65
  114. data/lib/libv8/scons/engine/SCons/Tool/ipkg.py +2 -2
  115. data/lib/libv8/scons/engine/SCons/Tool/jar.py +3 -9
  116. data/lib/libv8/scons/engine/SCons/Tool/javac.py +2 -2
  117. data/lib/libv8/scons/engine/SCons/Tool/javah.py +2 -2
  118. data/lib/libv8/scons/engine/SCons/Tool/latex.py +2 -3
  119. data/lib/libv8/scons/engine/SCons/Tool/lex.py +2 -2
  120. data/lib/libv8/scons/engine/SCons/Tool/link.py +5 -6
  121. data/lib/libv8/scons/engine/SCons/Tool/linkloc.py +2 -2
  122. data/lib/libv8/scons/engine/SCons/Tool/m4.py +2 -2
  123. data/lib/libv8/scons/engine/SCons/Tool/masm.py +2 -2
  124. data/lib/libv8/scons/engine/SCons/Tool/midl.py +2 -2
  125. data/lib/libv8/scons/engine/SCons/Tool/mingw.py +10 -31
  126. data/lib/libv8/scons/engine/SCons/Tool/mslib.py +2 -2
  127. data/lib/libv8/scons/engine/SCons/Tool/mslink.py +9 -61
  128. data/lib/libv8/scons/engine/SCons/Tool/mssdk.py +2 -2
  129. data/lib/libv8/scons/engine/SCons/Tool/msvc.py +11 -21
  130. data/lib/libv8/scons/engine/SCons/Tool/msvs.py +59 -477
  131. data/lib/libv8/scons/engine/SCons/Tool/mwcc.py +2 -2
  132. data/lib/libv8/scons/engine/SCons/Tool/mwld.py +2 -2
  133. data/lib/libv8/scons/engine/SCons/Tool/nasm.py +2 -2
  134. data/lib/libv8/scons/engine/SCons/Tool/packaging/__init__.py +2 -2
  135. data/lib/libv8/scons/engine/SCons/Tool/packaging/ipk.py +2 -2
  136. data/lib/libv8/scons/engine/SCons/Tool/packaging/msi.py +2 -2
  137. data/lib/libv8/scons/engine/SCons/Tool/packaging/rpm.py +2 -2
  138. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_tarbz2.py +2 -2
  139. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_targz.py +2 -2
  140. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_zip.py +2 -2
  141. data/lib/libv8/scons/engine/SCons/Tool/packaging/tarbz2.py +2 -2
  142. data/lib/libv8/scons/engine/SCons/Tool/packaging/targz.py +2 -2
  143. data/lib/libv8/scons/engine/SCons/Tool/packaging/zip.py +2 -2
  144. data/lib/libv8/scons/engine/SCons/Tool/pdf.py +2 -2
  145. data/lib/libv8/scons/engine/SCons/Tool/pdflatex.py +2 -3
  146. data/lib/libv8/scons/engine/SCons/Tool/pdftex.py +2 -3
  147. data/lib/libv8/scons/engine/SCons/Tool/qt.py +2 -2
  148. data/lib/libv8/scons/engine/SCons/Tool/rmic.py +3 -9
  149. data/lib/libv8/scons/engine/SCons/Tool/rpcgen.py +2 -2
  150. data/lib/libv8/scons/engine/SCons/Tool/rpm.py +2 -2
  151. data/lib/libv8/scons/engine/SCons/Tool/sgiar.py +2 -2
  152. data/lib/libv8/scons/engine/SCons/Tool/sgic++.py +2 -2
  153. data/lib/libv8/scons/engine/SCons/Tool/sgicc.py +2 -2
  154. data/lib/libv8/scons/engine/SCons/Tool/sgilink.py +3 -2
  155. data/lib/libv8/scons/engine/SCons/Tool/sunar.py +2 -2
  156. data/lib/libv8/scons/engine/SCons/Tool/sunc++.py +2 -2
  157. data/lib/libv8/scons/engine/SCons/Tool/suncc.py +2 -2
  158. data/lib/libv8/scons/engine/SCons/Tool/sunf77.py +2 -2
  159. data/lib/libv8/scons/engine/SCons/Tool/sunf90.py +2 -2
  160. data/lib/libv8/scons/engine/SCons/Tool/sunf95.py +2 -2
  161. data/lib/libv8/scons/engine/SCons/Tool/sunlink.py +3 -2
  162. data/lib/libv8/scons/engine/SCons/Tool/swig.py +5 -6
  163. data/lib/libv8/scons/engine/SCons/Tool/tar.py +2 -2
  164. data/lib/libv8/scons/engine/SCons/Tool/tex.py +43 -96
  165. data/lib/libv8/scons/engine/SCons/Tool/textfile.py +2 -2
  166. data/lib/libv8/scons/engine/SCons/Tool/tlib.py +2 -2
  167. data/lib/libv8/scons/engine/SCons/Tool/wix.py +2 -2
  168. data/lib/libv8/scons/engine/SCons/Tool/yacc.py +2 -12
  169. data/lib/libv8/scons/engine/SCons/Tool/zip.py +2 -2
  170. data/lib/libv8/scons/engine/SCons/Util.py +3 -3
  171. data/lib/libv8/scons/engine/SCons/Variables/BoolVariable.py +2 -2
  172. data/lib/libv8/scons/engine/SCons/Variables/EnumVariable.py +3 -3
  173. data/lib/libv8/scons/engine/SCons/Variables/ListVariable.py +2 -2
  174. data/lib/libv8/scons/engine/SCons/Variables/PackageVariable.py +2 -2
  175. data/lib/libv8/scons/engine/SCons/Variables/PathVariable.py +2 -2
  176. data/lib/libv8/scons/engine/SCons/Variables/__init__.py +2 -2
  177. data/lib/libv8/scons/engine/SCons/Warnings.py +2 -2
  178. data/lib/libv8/scons/engine/SCons/__init__.py +6 -6
  179. data/lib/libv8/scons/engine/SCons/compat/__init__.py +2 -2
  180. data/lib/libv8/scons/engine/SCons/compat/_scons_builtins.py +2 -2
  181. data/lib/libv8/scons/engine/SCons/compat/_scons_collections.py +2 -2
  182. data/lib/libv8/scons/engine/SCons/compat/_scons_dbm.py +2 -2
  183. data/lib/libv8/scons/engine/SCons/compat/_scons_hashlib.py +2 -2
  184. data/lib/libv8/scons/engine/SCons/compat/_scons_io.py +2 -2
  185. data/lib/libv8/scons/engine/SCons/cpp.py +2 -2
  186. data/lib/libv8/scons/engine/SCons/dblite.py +1 -4
  187. data/lib/libv8/scons/engine/SCons/exitfuncs.py +2 -2
  188. data/lib/libv8/scons/scons-time.1 +3 -3
  189. data/lib/libv8/scons/scons.1 +1164 -1170
  190. data/lib/libv8/scons/sconsign.1 +3 -3
  191. data/lib/libv8/scons/script/scons +22 -22
  192. data/lib/libv8/scons/script/scons-time +2 -2
  193. data/lib/libv8/scons/script/scons.bat +4 -7
  194. data/lib/libv8/scons/script/sconsign +20 -21
  195. data/lib/libv8/scons/setup.cfg +1 -0
  196. data/lib/libv8/scons/setup.py +40 -38
  197. data/lib/libv8/v8/.gitignore +1 -1
  198. data/lib/libv8/v8/AUTHORS +2 -0
  199. data/lib/libv8/v8/ChangeLog +387 -0
  200. data/lib/libv8/v8/Makefile +171 -0
  201. data/lib/libv8/v8/SConstruct +124 -51
  202. data/lib/libv8/v8/build/README.txt +31 -14
  203. data/lib/libv8/v8/build/all.gyp +11 -4
  204. data/lib/libv8/v8/build/armu.gypi +6 -2
  205. data/lib/libv8/v8/build/common.gypi +240 -94
  206. data/lib/libv8/v8/build/gyp_v8 +32 -4
  207. data/lib/libv8/v8/build/standalone.gypi +200 -0
  208. data/lib/libv8/v8/include/v8-debug.h +0 -0
  209. data/lib/libv8/v8/include/v8-profiler.h +8 -11
  210. data/lib/libv8/v8/include/v8.h +191 -108
  211. data/lib/libv8/v8/preparser/SConscript +2 -2
  212. data/lib/libv8/v8/preparser/preparser-process.cc +3 -3
  213. data/lib/libv8/v8/preparser/preparser.gyp +42 -0
  214. data/lib/libv8/v8/src/SConscript +33 -8
  215. data/lib/libv8/v8/src/accessors.cc +77 -43
  216. data/lib/libv8/v8/src/api.cc +393 -191
  217. data/lib/libv8/v8/src/api.h +4 -8
  218. data/lib/libv8/v8/src/apinatives.js +15 -3
  219. data/lib/libv8/v8/src/arguments.h +8 -0
  220. data/lib/libv8/v8/src/arm/assembler-arm.cc +120 -120
  221. data/lib/libv8/v8/src/arm/assembler-arm.h +92 -43
  222. data/lib/libv8/v8/src/arm/builtins-arm.cc +32 -39
  223. data/lib/libv8/v8/src/arm/code-stubs-arm.cc +572 -351
  224. data/lib/libv8/v8/src/arm/code-stubs-arm.h +8 -77
  225. data/lib/libv8/v8/src/arm/codegen-arm.h +0 -2
  226. data/lib/libv8/v8/src/arm/deoptimizer-arm.cc +50 -30
  227. data/lib/libv8/v8/src/arm/disasm-arm.cc +1 -1
  228. data/lib/libv8/v8/src/arm/frames-arm.h +9 -5
  229. data/lib/libv8/v8/src/arm/full-codegen-arm.cc +331 -432
  230. data/lib/libv8/v8/src/arm/ic-arm.cc +192 -124
  231. data/lib/libv8/v8/src/arm/lithium-arm.cc +216 -232
  232. data/lib/libv8/v8/src/arm/lithium-arm.h +106 -259
  233. data/lib/libv8/v8/src/arm/lithium-codegen-arm.cc +633 -642
  234. data/lib/libv8/v8/src/arm/lithium-codegen-arm.h +4 -4
  235. data/lib/libv8/v8/src/arm/lithium-gap-resolver-arm.cc +1 -3
  236. data/lib/libv8/v8/src/arm/macro-assembler-arm.cc +260 -185
  237. data/lib/libv8/v8/src/arm/macro-assembler-arm.h +45 -25
  238. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.cc +25 -13
  239. data/lib/libv8/v8/src/arm/regexp-macro-assembler-arm.h +3 -0
  240. data/lib/libv8/v8/src/arm/stub-cache-arm.cc +413 -226
  241. data/lib/libv8/v8/src/array.js +38 -18
  242. data/lib/libv8/v8/src/assembler.cc +12 -5
  243. data/lib/libv8/v8/src/assembler.h +15 -9
  244. data/lib/libv8/v8/src/ast-inl.h +34 -25
  245. data/lib/libv8/v8/src/ast.cc +141 -72
  246. data/lib/libv8/v8/src/ast.h +255 -181
  247. data/lib/libv8/v8/src/bignum.cc +3 -4
  248. data/lib/libv8/v8/src/bootstrapper.cc +55 -11
  249. data/lib/libv8/v8/src/bootstrapper.h +3 -2
  250. data/lib/libv8/v8/src/builtins.cc +8 -2
  251. data/lib/libv8/v8/src/builtins.h +4 -0
  252. data/lib/libv8/v8/src/cached-powers.cc +8 -4
  253. data/lib/libv8/v8/src/checks.h +3 -3
  254. data/lib/libv8/v8/src/code-stubs.cc +173 -28
  255. data/lib/libv8/v8/src/code-stubs.h +104 -148
  256. data/lib/libv8/v8/src/codegen.cc +8 -8
  257. data/lib/libv8/v8/src/compilation-cache.cc +2 -47
  258. data/lib/libv8/v8/src/compilation-cache.h +0 -10
  259. data/lib/libv8/v8/src/compiler.cc +27 -16
  260. data/lib/libv8/v8/src/compiler.h +13 -18
  261. data/lib/libv8/v8/src/contexts.cc +107 -72
  262. data/lib/libv8/v8/src/contexts.h +70 -34
  263. data/lib/libv8/v8/src/conversions-inl.h +572 -14
  264. data/lib/libv8/v8/src/conversions.cc +9 -707
  265. data/lib/libv8/v8/src/conversions.h +23 -12
  266. data/lib/libv8/v8/src/cpu-profiler-inl.h +2 -19
  267. data/lib/libv8/v8/src/cpu-profiler.cc +4 -21
  268. data/lib/libv8/v8/src/cpu-profiler.h +8 -17
  269. data/lib/libv8/v8/src/d8-debug.cc +5 -3
  270. data/lib/libv8/v8/src/d8-debug.h +6 -7
  271. data/lib/libv8/v8/src/d8-posix.cc +1 -10
  272. data/lib/libv8/v8/src/d8.cc +721 -219
  273. data/lib/libv8/v8/src/d8.gyp +37 -12
  274. data/lib/libv8/v8/src/d8.h +141 -19
  275. data/lib/libv8/v8/src/d8.js +17 -8
  276. data/lib/libv8/v8/src/date.js +16 -5
  277. data/lib/libv8/v8/src/dateparser-inl.h +242 -39
  278. data/lib/libv8/v8/src/dateparser.cc +38 -4
  279. data/lib/libv8/v8/src/dateparser.h +170 -28
  280. data/lib/libv8/v8/src/debug-agent.cc +5 -3
  281. data/lib/libv8/v8/src/debug-agent.h +11 -7
  282. data/lib/libv8/v8/src/debug-debugger.js +65 -34
  283. data/lib/libv8/v8/src/debug.cc +30 -60
  284. data/lib/libv8/v8/src/debug.h +5 -3
  285. data/lib/libv8/v8/src/deoptimizer.cc +227 -10
  286. data/lib/libv8/v8/src/deoptimizer.h +133 -9
  287. data/lib/libv8/v8/src/disassembler.cc +22 -14
  288. data/lib/libv8/v8/src/diy-fp.cc +4 -3
  289. data/lib/libv8/v8/src/diy-fp.h +3 -3
  290. data/lib/libv8/v8/src/elements.cc +634 -0
  291. data/lib/libv8/v8/src/elements.h +95 -0
  292. data/lib/libv8/v8/src/execution.cc +5 -21
  293. data/lib/libv8/v8/src/extensions/experimental/break-iterator.cc +3 -1
  294. data/lib/libv8/v8/src/extensions/experimental/break-iterator.h +1 -1
  295. data/lib/libv8/v8/src/extensions/experimental/collator.cc +6 -2
  296. data/lib/libv8/v8/src/extensions/experimental/collator.h +1 -2
  297. data/lib/libv8/v8/src/extensions/experimental/datetime-format.cc +384 -0
  298. data/lib/libv8/v8/src/extensions/experimental/datetime-format.h +83 -0
  299. data/lib/libv8/v8/src/extensions/experimental/experimental.gyp +18 -7
  300. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.cc +12 -16
  301. data/lib/libv8/v8/src/extensions/experimental/i18n-extension.h +1 -1
  302. data/lib/libv8/v8/src/extensions/experimental/i18n-js2c.py +126 -0
  303. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.cc +3 -4
  304. data/lib/libv8/v8/src/extensions/experimental/i18n-locale.h +1 -1
  305. data/lib/libv8/v8/src/{shell.h → extensions/experimental/i18n-natives.h} +8 -20
  306. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.cc +45 -1
  307. data/lib/libv8/v8/src/extensions/experimental/i18n-utils.h +21 -1
  308. data/lib/libv8/v8/src/extensions/experimental/i18n.js +211 -11
  309. data/lib/libv8/v8/src/extensions/experimental/language-matcher.cc +4 -3
  310. data/lib/libv8/v8/src/extensions/experimental/language-matcher.h +1 -1
  311. data/lib/libv8/v8/src/extensions/experimental/number-format.cc +374 -0
  312. data/lib/libv8/v8/src/extensions/experimental/number-format.h +71 -0
  313. data/lib/libv8/v8/src/factory.cc +89 -18
  314. data/lib/libv8/v8/src/factory.h +36 -8
  315. data/lib/libv8/v8/src/flag-definitions.h +11 -44
  316. data/lib/libv8/v8/src/frames-inl.h +8 -1
  317. data/lib/libv8/v8/src/frames.cc +39 -3
  318. data/lib/libv8/v8/src/frames.h +10 -3
  319. data/lib/libv8/v8/src/full-codegen.cc +311 -293
  320. data/lib/libv8/v8/src/full-codegen.h +183 -143
  321. data/lib/libv8/v8/src/func-name-inferrer.cc +29 -15
  322. data/lib/libv8/v8/src/func-name-inferrer.h +19 -9
  323. data/lib/libv8/v8/src/gdb-jit.cc +658 -55
  324. data/lib/libv8/v8/src/gdb-jit.h +6 -2
  325. data/lib/libv8/v8/src/global-handles.cc +368 -312
  326. data/lib/libv8/v8/src/global-handles.h +29 -36
  327. data/lib/libv8/v8/src/globals.h +3 -1
  328. data/lib/libv8/v8/src/handles.cc +43 -69
  329. data/lib/libv8/v8/src/handles.h +21 -16
  330. data/lib/libv8/v8/src/heap-inl.h +11 -13
  331. data/lib/libv8/v8/src/heap-profiler.cc +0 -999
  332. data/lib/libv8/v8/src/heap-profiler.h +0 -303
  333. data/lib/libv8/v8/src/heap.cc +366 -141
  334. data/lib/libv8/v8/src/heap.h +87 -26
  335. data/lib/libv8/v8/src/hydrogen-instructions.cc +192 -81
  336. data/lib/libv8/v8/src/hydrogen-instructions.h +711 -482
  337. data/lib/libv8/v8/src/hydrogen.cc +1146 -629
  338. data/lib/libv8/v8/src/hydrogen.h +100 -64
  339. data/lib/libv8/v8/src/ia32/assembler-ia32.cc +19 -0
  340. data/lib/libv8/v8/src/ia32/assembler-ia32.h +15 -2
  341. data/lib/libv8/v8/src/ia32/builtins-ia32.cc +34 -39
  342. data/lib/libv8/v8/src/ia32/code-stubs-ia32.cc +675 -377
  343. data/lib/libv8/v8/src/ia32/code-stubs-ia32.h +8 -69
  344. data/lib/libv8/v8/src/ia32/codegen-ia32.cc +1 -0
  345. data/lib/libv8/v8/src/ia32/codegen-ia32.h +0 -2
  346. data/lib/libv8/v8/src/ia32/cpu-ia32.cc +3 -2
  347. data/lib/libv8/v8/src/ia32/deoptimizer-ia32.cc +28 -3
  348. data/lib/libv8/v8/src/ia32/disasm-ia32.cc +21 -10
  349. data/lib/libv8/v8/src/ia32/frames-ia32.h +6 -5
  350. data/lib/libv8/v8/src/ia32/full-codegen-ia32.cc +459 -465
  351. data/lib/libv8/v8/src/ia32/ic-ia32.cc +196 -147
  352. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.cc +575 -650
  353. data/lib/libv8/v8/src/ia32/lithium-codegen-ia32.h +19 -21
  354. data/lib/libv8/v8/src/ia32/lithium-gap-resolver-ia32.cc +7 -2
  355. data/lib/libv8/v8/src/ia32/lithium-ia32.cc +261 -256
  356. data/lib/libv8/v8/src/ia32/lithium-ia32.h +234 -335
  357. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.cc +224 -67
  358. data/lib/libv8/v8/src/ia32/macro-assembler-ia32.h +63 -19
  359. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.cc +22 -8
  360. data/lib/libv8/v8/src/ia32/regexp-macro-assembler-ia32.h +3 -0
  361. data/lib/libv8/v8/src/ia32/stub-cache-ia32.cc +380 -239
  362. data/lib/libv8/v8/src/ic.cc +198 -234
  363. data/lib/libv8/v8/src/ic.h +32 -30
  364. data/lib/libv8/v8/src/interpreter-irregexp.cc +6 -4
  365. data/lib/libv8/v8/src/isolate.cc +112 -95
  366. data/lib/libv8/v8/src/isolate.h +55 -71
  367. data/lib/libv8/v8/src/json-parser.h +486 -48
  368. data/lib/libv8/v8/src/json.js +28 -23
  369. data/lib/libv8/v8/src/jsregexp.cc +163 -208
  370. data/lib/libv8/v8/src/jsregexp.h +0 -1
  371. data/lib/libv8/v8/src/lithium-allocator-inl.h +29 -27
  372. data/lib/libv8/v8/src/lithium-allocator.cc +22 -17
  373. data/lib/libv8/v8/src/lithium-allocator.h +8 -8
  374. data/lib/libv8/v8/src/lithium.cc +16 -11
  375. data/lib/libv8/v8/src/lithium.h +31 -34
  376. data/lib/libv8/v8/src/liveedit.cc +111 -15
  377. data/lib/libv8/v8/src/liveedit.h +3 -4
  378. data/lib/libv8/v8/src/liveobjectlist.cc +116 -80
  379. data/lib/libv8/v8/src/liveobjectlist.h +2 -2
  380. data/lib/libv8/v8/src/log-inl.h +0 -4
  381. data/lib/libv8/v8/src/log-utils.cc +25 -143
  382. data/lib/libv8/v8/src/log-utils.h +13 -92
  383. data/lib/libv8/v8/src/log.cc +26 -249
  384. data/lib/libv8/v8/src/log.h +6 -17
  385. data/lib/libv8/v8/src/macros.py +9 -6
  386. data/lib/libv8/v8/src/mark-compact.cc +276 -56
  387. data/lib/libv8/v8/src/mark-compact.h +20 -0
  388. data/lib/libv8/v8/src/messages.js +93 -39
  389. data/lib/libv8/v8/src/mips/assembler-mips-inl.h +9 -3
  390. data/lib/libv8/v8/src/mips/assembler-mips.cc +297 -189
  391. data/lib/libv8/v8/src/mips/assembler-mips.h +121 -54
  392. data/lib/libv8/v8/src/mips/builtins-mips.cc +23 -24
  393. data/lib/libv8/v8/src/mips/code-stubs-mips.cc +484 -263
  394. data/lib/libv8/v8/src/mips/code-stubs-mips.h +8 -83
  395. data/lib/libv8/v8/src/mips/codegen-mips.h +0 -2
  396. data/lib/libv8/v8/src/mips/constants-mips.h +37 -11
  397. data/lib/libv8/v8/src/mips/deoptimizer-mips.cc +6 -1
  398. data/lib/libv8/v8/src/mips/frames-mips.h +8 -7
  399. data/lib/libv8/v8/src/mips/full-codegen-mips.cc +258 -419
  400. data/lib/libv8/v8/src/mips/ic-mips.cc +181 -121
  401. data/lib/libv8/v8/src/mips/macro-assembler-mips.cc +640 -382
  402. data/lib/libv8/v8/src/mips/macro-assembler-mips.h +94 -89
  403. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.cc +23 -10
  404. data/lib/libv8/v8/src/mips/regexp-macro-assembler-mips.h +6 -1
  405. data/lib/libv8/v8/src/mips/simulator-mips.cc +249 -49
  406. data/lib/libv8/v8/src/mips/simulator-mips.h +25 -1
  407. data/lib/libv8/v8/src/mips/stub-cache-mips.cc +373 -161
  408. data/lib/libv8/v8/src/mirror-debugger.js +55 -8
  409. data/lib/libv8/v8/src/misc-intrinsics.h +89 -0
  410. data/lib/libv8/v8/src/mksnapshot.cc +36 -4
  411. data/lib/libv8/v8/src/natives.h +5 -2
  412. data/lib/libv8/v8/src/objects-debug.cc +73 -6
  413. data/lib/libv8/v8/src/objects-inl.h +529 -164
  414. data/lib/libv8/v8/src/objects-printer.cc +67 -12
  415. data/lib/libv8/v8/src/objects-visiting.cc +13 -2
  416. data/lib/libv8/v8/src/objects-visiting.h +41 -1
  417. data/lib/libv8/v8/src/objects.cc +2200 -1177
  418. data/lib/libv8/v8/src/objects.h +912 -283
  419. data/lib/libv8/v8/src/parser.cc +566 -371
  420. data/lib/libv8/v8/src/parser.h +35 -33
  421. data/lib/libv8/v8/src/platform-cygwin.cc +10 -25
  422. data/lib/libv8/v8/src/platform-freebsd.cc +4 -29
  423. data/lib/libv8/v8/src/platform-linux.cc +60 -57
  424. data/lib/libv8/v8/src/platform-macos.cc +4 -27
  425. data/lib/libv8/v8/src/platform-nullos.cc +3 -16
  426. data/lib/libv8/v8/src/platform-openbsd.cc +247 -85
  427. data/lib/libv8/v8/src/platform-posix.cc +43 -1
  428. data/lib/libv8/v8/src/platform-solaris.cc +151 -112
  429. data/lib/libv8/v8/src/platform-tls.h +1 -1
  430. data/lib/libv8/v8/src/platform-win32.cc +65 -39
  431. data/lib/libv8/v8/src/platform.h +17 -14
  432. data/lib/libv8/v8/src/preparse-data-format.h +2 -2
  433. data/lib/libv8/v8/src/preparse-data.h +8 -2
  434. data/lib/libv8/v8/src/preparser-api.cc +2 -18
  435. data/lib/libv8/v8/src/preparser.cc +106 -65
  436. data/lib/libv8/v8/src/preparser.h +26 -5
  437. data/lib/libv8/v8/src/prettyprinter.cc +25 -43
  438. data/lib/libv8/v8/src/profile-generator-inl.h +0 -4
  439. data/lib/libv8/v8/src/profile-generator.cc +213 -34
  440. data/lib/libv8/v8/src/profile-generator.h +9 -9
  441. data/lib/libv8/v8/src/property.h +1 -0
  442. data/lib/libv8/v8/src/proxy.js +74 -4
  443. data/lib/libv8/v8/src/regexp-macro-assembler.cc +10 -6
  444. data/lib/libv8/v8/src/regexp.js +16 -11
  445. data/lib/libv8/v8/src/rewriter.cc +24 -133
  446. data/lib/libv8/v8/src/runtime-profiler.cc +27 -151
  447. data/lib/libv8/v8/src/runtime-profiler.h +5 -31
  448. data/lib/libv8/v8/src/runtime.cc +1450 -681
  449. data/lib/libv8/v8/src/runtime.h +47 -31
  450. data/lib/libv8/v8/src/runtime.js +2 -1
  451. data/lib/libv8/v8/src/scanner-base.cc +358 -220
  452. data/lib/libv8/v8/src/scanner-base.h +30 -138
  453. data/lib/libv8/v8/src/scanner.cc +0 -18
  454. data/lib/libv8/v8/src/scanner.h +0 -15
  455. data/lib/libv8/v8/src/scopeinfo.cc +3 -1
  456. data/lib/libv8/v8/src/scopeinfo.h +1 -6
  457. data/lib/libv8/v8/src/scopes.cc +243 -253
  458. data/lib/libv8/v8/src/scopes.h +58 -109
  459. data/lib/libv8/v8/src/serialize.cc +12 -54
  460. data/lib/libv8/v8/src/serialize.h +47 -0
  461. data/lib/libv8/v8/src/small-pointer-list.h +25 -0
  462. data/lib/libv8/v8/src/spaces-inl.h +4 -50
  463. data/lib/libv8/v8/src/spaces.cc +64 -131
  464. data/lib/libv8/v8/src/spaces.h +19 -70
  465. data/lib/libv8/v8/src/string-stream.cc +3 -1
  466. data/lib/libv8/v8/src/string.js +10 -6
  467. data/lib/libv8/v8/src/strtod.cc +7 -3
  468. data/lib/libv8/v8/src/stub-cache.cc +59 -129
  469. data/lib/libv8/v8/src/stub-cache.h +42 -54
  470. data/lib/libv8/v8/src/third_party/valgrind/valgrind.h +1447 -1339
  471. data/lib/libv8/v8/src/token.cc +4 -4
  472. data/lib/libv8/v8/src/token.h +6 -5
  473. data/lib/libv8/v8/src/type-info.cc +173 -129
  474. data/lib/libv8/v8/src/type-info.h +40 -22
  475. data/lib/libv8/v8/src/utils.cc +25 -304
  476. data/lib/libv8/v8/src/utils.h +118 -3
  477. data/lib/libv8/v8/src/v8-counters.h +3 -6
  478. data/lib/libv8/v8/src/v8.cc +34 -27
  479. data/lib/libv8/v8/src/v8.h +7 -7
  480. data/lib/libv8/v8/src/v8conversions.cc +129 -0
  481. data/lib/libv8/v8/src/v8conversions.h +60 -0
  482. data/lib/libv8/v8/src/v8globals.h +15 -6
  483. data/lib/libv8/v8/src/v8natives.js +300 -78
  484. data/lib/libv8/v8/src/v8threads.cc +14 -6
  485. data/lib/libv8/v8/src/v8threads.h +4 -1
  486. data/lib/libv8/v8/src/v8utils.cc +360 -0
  487. data/lib/libv8/v8/src/v8utils.h +17 -66
  488. data/lib/libv8/v8/src/variables.cc +7 -12
  489. data/lib/libv8/v8/src/variables.h +12 -10
  490. data/lib/libv8/v8/src/version.cc +2 -2
  491. data/lib/libv8/v8/src/vm-state-inl.h +0 -41
  492. data/lib/libv8/v8/src/vm-state.h +0 -11
  493. data/lib/libv8/v8/src/weakmap.js +103 -0
  494. data/lib/libv8/v8/src/x64/assembler-x64.h +6 -3
  495. data/lib/libv8/v8/src/x64/builtins-x64.cc +25 -22
  496. data/lib/libv8/v8/src/x64/code-stubs-x64.cc +523 -250
  497. data/lib/libv8/v8/src/x64/code-stubs-x64.h +8 -71
  498. data/lib/libv8/v8/src/x64/codegen-x64.cc +1 -0
  499. data/lib/libv8/v8/src/x64/codegen-x64.h +0 -2
  500. data/lib/libv8/v8/src/x64/cpu-x64.cc +2 -1
  501. data/lib/libv8/v8/src/x64/deoptimizer-x64.cc +40 -8
  502. data/lib/libv8/v8/src/x64/disasm-x64.cc +12 -10
  503. data/lib/libv8/v8/src/x64/frames-x64.h +7 -6
  504. data/lib/libv8/v8/src/x64/full-codegen-x64.cc +310 -415
  505. data/lib/libv8/v8/src/x64/ic-x64.cc +180 -117
  506. data/lib/libv8/v8/src/x64/lithium-codegen-x64.cc +411 -523
  507. data/lib/libv8/v8/src/x64/lithium-codegen-x64.h +11 -6
  508. data/lib/libv8/v8/src/x64/lithium-x64.cc +191 -216
  509. data/lib/libv8/v8/src/x64/lithium-x64.h +112 -263
  510. data/lib/libv8/v8/src/x64/macro-assembler-x64.cc +177 -61
  511. data/lib/libv8/v8/src/x64/macro-assembler-x64.h +23 -7
  512. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.cc +21 -9
  513. data/lib/libv8/v8/src/x64/regexp-macro-assembler-x64.h +6 -0
  514. data/lib/libv8/v8/src/x64/stub-cache-x64.cc +273 -107
  515. data/lib/libv8/v8/src/zone.cc +31 -22
  516. data/lib/libv8/v8/src/zone.h +12 -6
  517. data/lib/libv8/v8/tools/codemap.js +8 -0
  518. data/lib/libv8/v8/tools/gcmole/Makefile +43 -0
  519. data/lib/libv8/v8/tools/gcmole/gcmole.lua +0 -2
  520. data/lib/libv8/v8/tools/gdb-v8-support.py +154 -0
  521. data/lib/libv8/v8/tools/grokdump.py +44 -35
  522. data/lib/libv8/v8/tools/gyp/v8.gyp +94 -248
  523. data/lib/libv8/v8/tools/js2c.py +83 -52
  524. data/lib/libv8/v8/tools/linux-tick-processor +4 -6
  525. data/lib/libv8/v8/tools/ll_prof.py +3 -3
  526. data/lib/libv8/v8/tools/oom_dump/README +3 -1
  527. data/lib/libv8/v8/tools/presubmit.py +11 -4
  528. data/lib/libv8/v8/tools/profile.js +46 -2
  529. data/lib/libv8/v8/tools/splaytree.js +11 -0
  530. data/lib/libv8/v8/tools/stats-viewer.py +15 -11
  531. data/lib/libv8/v8/tools/test-wrapper-gypbuild.py +227 -0
  532. data/lib/libv8/v8/tools/test.py +28 -8
  533. data/lib/libv8/v8/tools/tickprocessor.js +0 -16
  534. data/lib/libv8/version.rb +1 -1
  535. data/libv8.gemspec +2 -2
  536. metadata +31 -19
  537. data/lib/libv8/scons/engine/SCons/Tool/f03.py +0 -63
  538. data/lib/libv8/v8/src/json-parser.cc +0 -504
@@ -46,8 +46,10 @@ namespace internal {
46
46
  // invalidate the cache whenever a prototype map is changed. The stub
47
47
  // validates the map chain as in the mono-morphic case.
48
48
 
49
+ class SmallMapList;
49
50
  class StubCache;
50
51
 
52
+
51
53
  class SCTableReference {
52
54
  public:
53
55
  Address address() const { return address_; }
@@ -183,15 +185,11 @@ class StubCache {
183
185
  Map* transition,
184
186
  StrictModeFlag strict_mode);
185
187
 
186
- MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreExternalArray(
188
+ MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreElement(
187
189
  JSObject* receiver,
188
190
  bool is_store,
189
191
  StrictModeFlag strict_mode);
190
192
 
191
- MUST_USE_RESULT MaybeObject* ComputeKeyedLoadOrStoreFastElement(
192
- JSObject* receiver,
193
- bool is_store,
194
- StrictModeFlag strict_mode);
195
193
  // ---
196
194
 
197
195
  MUST_USE_RESULT MaybeObject* ComputeCallField(
@@ -265,6 +263,10 @@ class StubCache {
265
263
  Code::Kind kind,
266
264
  Code::ExtraICState state);
267
265
 
266
+ MUST_USE_RESULT MaybeObject* ComputeCallArguments(int argc,
267
+ InLoopFlag in_loop,
268
+ Code::Kind kind);
269
+
268
270
  MUST_USE_RESULT MaybeObject* ComputeCallMegamorphic(int argc,
269
271
  InLoopFlag in_loop,
270
272
  Code::Kind kind,
@@ -294,7 +296,7 @@ class StubCache {
294
296
  void Clear();
295
297
 
296
298
  // Collect all maps that match the name and flags.
297
- void CollectMatchingMaps(ZoneMapList* types,
299
+ void CollectMatchingMaps(SmallMapList* types,
298
300
  String* name,
299
301
  Code::Flags flags);
300
302
 
@@ -355,7 +357,7 @@ class StubCache {
355
357
  // shift are equal. Shifting down the length field to get the
356
358
  // hash code would effectively throw away two bits of the hash
357
359
  // code.
358
- ASSERT(kHeapObjectTagSize == String::kHashShift);
360
+ STATIC_ASSERT(kHeapObjectTagSize == String::kHashShift);
359
361
  // Compute the hash of the name (use entire hash field).
360
362
  ASSERT(name->HasHashCode());
361
363
  uint32_t field = name->hash_field();
@@ -429,6 +431,7 @@ class StubCompiler BASE_EMBEDDED {
429
431
  MUST_USE_RESULT MaybeObject* CompileCallPreMonomorphic(Code::Flags flags);
430
432
  MUST_USE_RESULT MaybeObject* CompileCallNormal(Code::Flags flags);
431
433
  MUST_USE_RESULT MaybeObject* CompileCallMegamorphic(Code::Flags flags);
434
+ MUST_USE_RESULT MaybeObject* CompileCallArguments(Code::Flags flags);
432
435
  MUST_USE_RESULT MaybeObject* CompileCallMiss(Code::Flags flags);
433
436
  #ifdef ENABLE_DEBUGGER_SUPPORT
434
437
  MUST_USE_RESULT MaybeObject* CompileCallDebugBreak(Code::Flags flags);
@@ -650,17 +653,21 @@ class KeyedLoadStubCompiler: public StubCompiler {
650
653
  MUST_USE_RESULT MaybeObject* CompileLoadStringLength(String* name);
651
654
  MUST_USE_RESULT MaybeObject* CompileLoadFunctionPrototype(String* name);
652
655
 
653
- MUST_USE_RESULT MaybeObject* CompileLoadFastElement(Map* receiver_map);
656
+ MUST_USE_RESULT MaybeObject* CompileLoadElement(Map* receiver_map);
654
657
 
655
658
  MUST_USE_RESULT MaybeObject* CompileLoadMegamorphic(
656
659
  MapList* receiver_maps,
657
660
  CodeList* handler_ics);
658
661
 
659
662
  static void GenerateLoadExternalArray(MacroAssembler* masm,
660
- ExternalArrayType array_type);
663
+ JSObject::ElementsKind elements_kind);
661
664
 
662
665
  static void GenerateLoadFastElement(MacroAssembler* masm);
663
666
 
667
+ static void GenerateLoadFastDoubleElement(MacroAssembler* masm);
668
+
669
+ static void GenerateLoadDictionaryElement(MacroAssembler* masm);
670
+
664
671
  private:
665
672
  MaybeObject* GetCode(PropertyType type,
666
673
  String* name,
@@ -705,7 +712,7 @@ class KeyedStoreStubCompiler: public StubCompiler {
705
712
  Map* transition,
706
713
  String* name);
707
714
 
708
- MUST_USE_RESULT MaybeObject* CompileStoreFastElement(Map* receiver_map);
715
+ MUST_USE_RESULT MaybeObject* CompileStoreElement(Map* receiver_map);
709
716
 
710
717
  MUST_USE_RESULT MaybeObject* CompileStoreMegamorphic(
711
718
  MapList* receiver_maps,
@@ -714,8 +721,13 @@ class KeyedStoreStubCompiler: public StubCompiler {
714
721
  static void GenerateStoreFastElement(MacroAssembler* masm,
715
722
  bool is_js_array);
716
723
 
724
+ static void GenerateStoreFastDoubleElement(MacroAssembler* masm,
725
+ bool is_js_array);
726
+
717
727
  static void GenerateStoreExternalArray(MacroAssembler* masm,
718
- ExternalArrayType array_type);
728
+ JSObject::ElementsKind elements_kind);
729
+
730
+ static void GenerateStoreDictionaryElement(MacroAssembler* masm);
719
731
 
720
732
  private:
721
733
  MaybeObject* GetCode(PropertyType type,
@@ -748,25 +760,30 @@ class CallStubCompiler: public StubCompiler {
748
760
  Code::ExtraICState extra_ic_state,
749
761
  InlineCacheHolderFlag cache_holder);
750
762
 
751
- MUST_USE_RESULT MaybeObject* CompileCallField(JSObject* object,
752
- JSObject* holder,
753
- int index,
754
- String* name);
755
- MUST_USE_RESULT MaybeObject* CompileCallConstant(Object* object,
756
- JSObject* holder,
757
- JSFunction* function,
758
- String* name,
759
- CheckType check);
760
- MUST_USE_RESULT MaybeObject* CompileCallInterceptor(JSObject* object,
761
- JSObject* holder,
762
- String* name);
763
+ MUST_USE_RESULT MaybeObject* CompileCallField(
764
+ JSObject* object,
765
+ JSObject* holder,
766
+ int index,
767
+ String* name);
768
+
769
+ MUST_USE_RESULT MaybeObject* CompileCallConstant(
770
+ Object* object,
771
+ JSObject* holder,
772
+ JSFunction* function,
773
+ String* name,
774
+ CheckType check);
775
+
776
+ MUST_USE_RESULT MaybeObject* CompileCallInterceptor(
777
+ JSObject* object,
778
+ JSObject* holder,
779
+ String* name);
780
+
763
781
  MUST_USE_RESULT MaybeObject* CompileCallGlobal(
764
782
  JSObject* object,
765
783
  GlobalObject* holder,
766
784
  JSGlobalPropertyCell* cell,
767
785
  JSFunction* function,
768
- String* name,
769
- Code::ExtraICState extra_ic_state);
786
+ String* name);
770
787
 
771
788
  static bool HasCustomCallGenerator(JSFunction* function);
772
789
 
@@ -889,35 +906,6 @@ class CallOptimization BASE_EMBEDDED {
889
906
  CallHandlerInfo* api_call_info_;
890
907
  };
891
908
 
892
- class ExternalArrayLoadStubCompiler: public StubCompiler {
893
- public:
894
- explicit ExternalArrayLoadStubCompiler(StrictModeFlag strict_mode)
895
- : strict_mode_(strict_mode) { }
896
-
897
- MUST_USE_RESULT MaybeObject* CompileLoad(
898
- JSObject* receiver, ExternalArrayType array_type);
899
-
900
- private:
901
- MaybeObject* GetCode();
902
-
903
- StrictModeFlag strict_mode_;
904
- };
905
-
906
-
907
- class ExternalArrayStoreStubCompiler: public StubCompiler {
908
- public:
909
- explicit ExternalArrayStoreStubCompiler(StrictModeFlag strict_mode)
910
- : strict_mode_(strict_mode) {}
911
-
912
- MUST_USE_RESULT MaybeObject* CompileStore(
913
- JSObject* receiver, ExternalArrayType array_type);
914
-
915
- private:
916
- MaybeObject* GetCode();
917
-
918
- StrictModeFlag strict_mode_;
919
- };
920
-
921
909
 
922
910
  } } // namespace v8::internal
923
911
 
@@ -12,7 +12,7 @@
12
12
  This file is part of Valgrind, a dynamic binary instrumentation
13
13
  framework.
14
14
 
15
- Copyright (C) 2000-2007 Julian Seward. All rights reserved.
15
+ Copyright (C) 2000-2010 Julian Seward. All rights reserved.
16
16
 
17
17
  Redistribution and use in source and binary forms, with or without
18
18
  modification, are permitted provided that the following conditions
@@ -73,6 +73,25 @@
73
73
  #ifndef __VALGRIND_H
74
74
  #define __VALGRIND_H
75
75
 
76
+
77
+ /* ------------------------------------------------------------------ */
78
+ /* VERSION NUMBER OF VALGRIND */
79
+ /* ------------------------------------------------------------------ */
80
+
81
+ /* Specify Valgrind's version number, so that user code can
82
+ conditionally compile based on our version number. Note that these
83
+ were introduced at version 3.6 and so do not exist in version 3.5
84
+ or earlier. The recommended way to use them to check for "version
85
+ X.Y or later" is (eg)
86
+
87
+ #if defined(__VALGRIND_MAJOR__) && defined(__VALGRIND_MINOR__) \
88
+ && (__VALGRIND_MAJOR__ > 3 \
89
+ || (__VALGRIND_MAJOR__ == 3 && __VALGRIND_MINOR__ >= 6))
90
+ */
91
+ #define __VALGRIND_MAJOR__ 3
92
+ #define __VALGRIND_MINOR__ 6
93
+
94
+
76
95
  #include <stdarg.h>
77
96
  #include <stdint.h>
78
97
 
@@ -85,34 +104,44 @@
85
104
  identifying architectures, which are different to the ones we use
86
105
  within the rest of Valgrind. Note, __powerpc__ is active for both
87
106
  32 and 64-bit PPC, whereas __powerpc64__ is only active for the
88
- latter (on Linux, that is). */
107
+ latter (on Linux, that is).
108
+
109
+ Misc note: how to find out what's predefined in gcc by default:
110
+ gcc -Wp,-dM somefile.c
111
+ */
112
+ #undef PLAT_x86_darwin
113
+ #undef PLAT_amd64_darwin
114
+ #undef PLAT_x86_win32
89
115
  #undef PLAT_x86_linux
90
116
  #undef PLAT_amd64_linux
91
117
  #undef PLAT_ppc32_linux
92
118
  #undef PLAT_ppc64_linux
93
- #undef PLAT_ppc32_aix5
94
- #undef PLAT_ppc64_aix5
95
-
96
- #if !defined(_AIX) && defined(__i386__)
119
+ #undef PLAT_arm_linux
120
+ #undef PLAT_s390x_linux
121
+
122
+
123
+ #if defined(__APPLE__) && defined(__i386__)
124
+ # define PLAT_x86_darwin 1
125
+ #elif defined(__APPLE__) && defined(__x86_64__)
126
+ # define PLAT_amd64_darwin 1
127
+ #elif defined(__MINGW32__) || defined(__CYGWIN32__) \
128
+ || (defined(_WIN32) && defined(_M_IX86))
129
+ # define PLAT_x86_win32 1
130
+ #elif defined(__linux__) && defined(__i386__)
97
131
  # define PLAT_x86_linux 1
98
- #elif !defined(_AIX) && defined(__x86_64__)
132
+ #elif defined(__linux__) && defined(__x86_64__)
99
133
  # define PLAT_amd64_linux 1
100
- #elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
134
+ #elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
101
135
  # define PLAT_ppc32_linux 1
102
- #elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
136
+ #elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
103
137
  # 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
-
138
+ #elif defined(__linux__) && defined(__arm__)
139
+ # define PLAT_arm_linux 1
140
+ #elif defined(__linux__) && defined(__s390__) && defined(__s390x__)
141
+ # define PLAT_s390x_linux 1
142
+ #else
111
143
  /* If we're not compiling for our target platform, don't generate
112
144
  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
145
  # if !defined(NVALGRIND)
117
146
  # define NVALGRIND 1
118
147
  # endif
@@ -124,17 +153,31 @@
124
153
  /* in here of use to end-users -- skip to the next section. */
125
154
  /* ------------------------------------------------------------------ */
126
155
 
156
+ /*
157
+ * VALGRIND_DO_CLIENT_REQUEST(): a statement that invokes a Valgrind client
158
+ * request. Accepts both pointers and integers as arguments.
159
+ *
160
+ * VALGRIND_DO_CLIENT_REQUEST_EXPR(): a C expression that invokes a Valgrind
161
+ * client request and whose value equals the client request result. Accepts
162
+ * both pointers and integers as arguments.
163
+ */
164
+
165
+ #define VALGRIND_DO_CLIENT_REQUEST(_zzq_rlval, _zzq_default, \
166
+ _zzq_request, _zzq_arg1, _zzq_arg2, \
167
+ _zzq_arg3, _zzq_arg4, _zzq_arg5) \
168
+ { (_zzq_rlval) = VALGRIND_DO_CLIENT_REQUEST_EXPR((_zzq_default), \
169
+ (_zzq_request), (_zzq_arg1), (_zzq_arg2), \
170
+ (_zzq_arg3), (_zzq_arg4), (_zzq_arg5)); }
171
+
127
172
  #if defined(NVALGRIND)
128
173
 
129
174
  /* Define NVALGRIND to completely remove the Valgrind magic sequence
130
175
  from the compiled code (analogous to NDEBUG's effects on
131
176
  assert()) */
132
- #define VALGRIND_DO_CLIENT_REQUEST( \
133
- _zzq_rlval, _zzq_default, _zzq_request, \
177
+ #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
178
+ _zzq_default, _zzq_request, \
134
179
  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
135
- { \
136
- (_zzq_rlval) = (_zzq_default); \
137
- }
180
+ (_zzq_default)
138
181
 
139
182
  #else /* ! NVALGRIND */
140
183
 
@@ -173,9 +216,10 @@
173
216
  inline asm stuff to be useful.
174
217
  */
175
218
 
176
- /* ------------------------- x86-linux ------------------------- */
219
+ /* ------------------------- x86-{linux,darwin} ---------------- */
177
220
 
178
- #if defined(PLAT_x86_linux)
221
+ #if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin) \
222
+ || (defined(PLAT_x86_win32) && defined(__GNUC__))
179
223
 
180
224
  typedef
181
225
  struct {
@@ -187,10 +231,11 @@ typedef
187
231
  "roll $3, %%edi ; roll $13, %%edi\n\t" \
188
232
  "roll $29, %%edi ; roll $19, %%edi\n\t"
189
233
 
190
- #define VALGRIND_DO_CLIENT_REQUEST( \
191
- _zzq_rlval, _zzq_default, _zzq_request, \
234
+ #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
235
+ _zzq_default, _zzq_request, \
192
236
  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
193
- { volatile unsigned int _zzq_args[6]; \
237
+ __extension__ \
238
+ ({volatile unsigned int _zzq_args[6]; \
194
239
  volatile unsigned int _zzq_result; \
195
240
  _zzq_args[0] = (unsigned int)(_zzq_request); \
196
241
  _zzq_args[1] = (unsigned int)(_zzq_arg1); \
@@ -205,8 +250,8 @@ typedef
205
250
  : "a" (&_zzq_args[0]), "0" (_zzq_default) \
206
251
  : "cc", "memory" \
207
252
  ); \
208
- _zzq_rlval = _zzq_result; \
209
- }
253
+ _zzq_result; \
254
+ })
210
255
 
211
256
  #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
212
257
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
@@ -225,11 +270,77 @@ typedef
225
270
  __SPECIAL_INSTRUCTION_PREAMBLE \
226
271
  /* call-noredir *%EAX */ \
227
272
  "xchgl %%edx,%%edx\n\t"
228
- #endif /* PLAT_x86_linux */
273
+ #endif /* PLAT_x86_linux || PLAT_x86_darwin || (PLAT_x86_win32 && __GNUC__) */
274
+
275
+ /* ------------------------- x86-Win32 ------------------------- */
276
+
277
+ #if defined(PLAT_x86_win32) && !defined(__GNUC__)
278
+
279
+ typedef
280
+ struct {
281
+ unsigned int nraddr; /* where's the code? */
282
+ }
283
+ OrigFn;
284
+
285
+ #if defined(_MSC_VER)
286
+
287
+ #define __SPECIAL_INSTRUCTION_PREAMBLE \
288
+ __asm rol edi, 3 __asm rol edi, 13 \
289
+ __asm rol edi, 29 __asm rol edi, 19
290
+
291
+ #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
292
+ _zzq_default, _zzq_request, \
293
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
294
+ valgrind_do_client_request_expr((uintptr_t)(_zzq_default), \
295
+ (uintptr_t)(_zzq_request), (uintptr_t)(_zzq_arg1), \
296
+ (uintptr_t)(_zzq_arg2), (uintptr_t)(_zzq_arg3), \
297
+ (uintptr_t)(_zzq_arg4), (uintptr_t)(_zzq_arg5))
298
+
299
+ static __inline uintptr_t
300
+ valgrind_do_client_request_expr(uintptr_t _zzq_default, uintptr_t _zzq_request,
301
+ uintptr_t _zzq_arg1, uintptr_t _zzq_arg2,
302
+ uintptr_t _zzq_arg3, uintptr_t _zzq_arg4,
303
+ uintptr_t _zzq_arg5)
304
+ {
305
+ volatile uintptr_t _zzq_args[6];
306
+ volatile unsigned int _zzq_result;
307
+ _zzq_args[0] = (uintptr_t)(_zzq_request);
308
+ _zzq_args[1] = (uintptr_t)(_zzq_arg1);
309
+ _zzq_args[2] = (uintptr_t)(_zzq_arg2);
310
+ _zzq_args[3] = (uintptr_t)(_zzq_arg3);
311
+ _zzq_args[4] = (uintptr_t)(_zzq_arg4);
312
+ _zzq_args[5] = (uintptr_t)(_zzq_arg5);
313
+ __asm { __asm lea eax, _zzq_args __asm mov edx, _zzq_default
314
+ __SPECIAL_INSTRUCTION_PREAMBLE
315
+ /* %EDX = client_request ( %EAX ) */
316
+ __asm xchg ebx,ebx
317
+ __asm mov _zzq_result, edx
318
+ }
319
+ return _zzq_result;
320
+ }
229
321
 
230
- /* ------------------------ amd64-linux ------------------------ */
322
+ #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
323
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
324
+ volatile unsigned int __addr; \
325
+ __asm { __SPECIAL_INSTRUCTION_PREAMBLE \
326
+ /* %EAX = guest_NRADDR */ \
327
+ __asm xchg ecx,ecx \
328
+ __asm mov __addr, eax \
329
+ } \
330
+ _zzq_orig->nraddr = __addr; \
331
+ }
332
+
333
+ #define VALGRIND_CALL_NOREDIR_EAX ERROR
334
+
335
+ #else
336
+ #error Unsupported compiler.
337
+ #endif
231
338
 
232
- #if defined(PLAT_amd64_linux)
339
+ #endif /* PLAT_x86_win32 */
340
+
341
+ /* ------------------------ amd64-{linux,darwin} --------------- */
342
+
343
+ #if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin)
233
344
 
234
345
  typedef
235
346
  struct {
@@ -241,10 +352,11 @@ typedef
241
352
  "rolq $3, %%rdi ; rolq $13, %%rdi\n\t" \
242
353
  "rolq $61, %%rdi ; rolq $51, %%rdi\n\t"
243
354
 
244
- #define VALGRIND_DO_CLIENT_REQUEST( \
245
- _zzq_rlval, _zzq_default, _zzq_request, \
355
+ #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
356
+ _zzq_default, _zzq_request, \
246
357
  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
247
- { volatile uint64_t _zzq_args[6]; \
358
+ __extension__ \
359
+ ({ volatile uint64_t _zzq_args[6]; \
248
360
  volatile uint64_t _zzq_result; \
249
361
  _zzq_args[0] = (uint64_t)(_zzq_request); \
250
362
  _zzq_args[1] = (uint64_t)(_zzq_arg1); \
@@ -259,8 +371,8 @@ typedef
259
371
  : "a" (&_zzq_args[0]), "0" (_zzq_default) \
260
372
  : "cc", "memory" \
261
373
  ); \
262
- _zzq_rlval = _zzq_result; \
263
- }
374
+ _zzq_result; \
375
+ })
264
376
 
265
377
  #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
266
378
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
@@ -279,7 +391,7 @@ typedef
279
391
  __SPECIAL_INSTRUCTION_PREAMBLE \
280
392
  /* call-noredir *%RAX */ \
281
393
  "xchgq %%rdx,%%rdx\n\t"
282
- #endif /* PLAT_amd64_linux */
394
+ #endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
283
395
 
284
396
  /* ------------------------ ppc32-linux ------------------------ */
285
397
 
@@ -295,11 +407,12 @@ typedef
295
407
  "rlwinm 0,0,3,0,0 ; rlwinm 0,0,13,0,0\n\t" \
296
408
  "rlwinm 0,0,29,0,0 ; rlwinm 0,0,19,0,0\n\t"
297
409
 
298
- #define VALGRIND_DO_CLIENT_REQUEST( \
299
- _zzq_rlval, _zzq_default, _zzq_request, \
410
+ #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
411
+ _zzq_default, _zzq_request, \
300
412
  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
301
413
  \
302
- { unsigned int _zzq_args[6]; \
414
+ __extension__ \
415
+ ({ unsigned int _zzq_args[6]; \
303
416
  unsigned int _zzq_result; \
304
417
  unsigned int* _zzq_ptr; \
305
418
  _zzq_args[0] = (unsigned int)(_zzq_request); \
@@ -318,8 +431,8 @@ typedef
318
431
  : "=b" (_zzq_result) \
319
432
  : "b" (_zzq_default), "b" (_zzq_ptr) \
320
433
  : "cc", "memory", "r3", "r4"); \
321
- _zzq_rlval = _zzq_result; \
322
- }
434
+ _zzq_result; \
435
+ })
323
436
 
324
437
  #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
325
438
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
@@ -356,11 +469,12 @@ typedef
356
469
  "rotldi 0,0,3 ; rotldi 0,0,13\n\t" \
357
470
  "rotldi 0,0,61 ; rotldi 0,0,51\n\t"
358
471
 
359
- #define VALGRIND_DO_CLIENT_REQUEST( \
360
- _zzq_rlval, _zzq_default, _zzq_request, \
472
+ #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
473
+ _zzq_default, _zzq_request, \
361
474
  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
362
475
  \
363
- { uint64_t _zzq_args[6]; \
476
+ __extension__ \
477
+ ({ uint64_t _zzq_args[6]; \
364
478
  register uint64_t _zzq_result __asm__("r3"); \
365
479
  register uint64_t* _zzq_ptr __asm__("r4"); \
366
480
  _zzq_args[0] = (uint64_t)(_zzq_request); \
@@ -376,8 +490,8 @@ typedef
376
490
  : "=r" (_zzq_result) \
377
491
  : "0" (_zzq_default), "r" (_zzq_ptr) \
378
492
  : "cc", "memory"); \
379
- _zzq_rlval = _zzq_result; \
380
- }
493
+ _zzq_result; \
494
+ })
381
495
 
382
496
  #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
383
497
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
@@ -407,149 +521,135 @@ typedef
407
521
 
408
522
  #endif /* PLAT_ppc64_linux */
409
523
 
410
- /* ------------------------ ppc32-aix5 ------------------------- */
524
+ /* ------------------------- arm-linux ------------------------- */
411
525
 
412
- #if defined(PLAT_ppc32_aix5)
526
+ #if defined(PLAT_arm_linux)
413
527
 
414
528
  typedef
415
529
  struct {
416
530
  unsigned int nraddr; /* where's the code? */
417
- unsigned int r2; /* what tocptr do we need? */
418
531
  }
419
532
  OrigFn;
420
533
 
421
534
  #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"
535
+ "mov r12, r12, ror #3 ; mov r12, r12, ror #13 \n\t" \
536
+ "mov r12, r12, ror #29 ; mov r12, r12, ror #19 \n\t"
424
537
 
425
- #define VALGRIND_DO_CLIENT_REQUEST( \
426
- _zzq_rlval, _zzq_default, _zzq_request, \
538
+ #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
539
+ _zzq_default, _zzq_request, \
427
540
  _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
428
541
  \
429
- { unsigned int _zzq_args[7]; \
430
- register unsigned int _zzq_result; \
431
- register unsigned int* _zzq_ptr; \
542
+ __extension__ \
543
+ ({volatile unsigned int _zzq_args[6]; \
544
+ volatile unsigned int _zzq_result; \
432
545
  _zzq_args[0] = (unsigned int)(_zzq_request); \
433
546
  _zzq_args[1] = (unsigned int)(_zzq_arg1); \
434
547
  _zzq_args[2] = (unsigned int)(_zzq_arg2); \
435
548
  _zzq_args[3] = (unsigned int)(_zzq_arg3); \
436
549
  _zzq_args[4] = (unsigned int)(_zzq_arg4); \
437
550
  _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" \
551
+ __asm__ volatile("mov r3, %1\n\t" /*default*/ \
552
+ "mov r4, %2\n\t" /*ptr*/ \
442
553
  __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
- }
554
+ /* R3 = client_request ( R4 ) */ \
555
+ "orr r10, r10, r10\n\t" \
556
+ "mov %0, r3" /*result*/ \
557
+ : "=r" (_zzq_result) \
558
+ : "r" (_zzq_default), "r" (&_zzq_args[0]) \
559
+ : "cc","memory", "r3", "r4"); \
560
+ _zzq_result; \
561
+ })
451
562
 
452
563
  #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
453
564
  { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
454
- register unsigned int __addr; \
565
+ unsigned int __addr; \
455
566
  __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
456
- /* %R3 = guest_NRADDR */ \
457
- "or 2,2,2\n\t" \
458
- "mr %0,3" \
459
- : "=b" (__addr) \
567
+ /* R3 = guest_NRADDR */ \
568
+ "orr r11, r11, r11\n\t" \
569
+ "mov %0, r3" \
570
+ : "=r" (__addr) \
460
571
  : \
461
- : "r3", "cc", "memory" \
572
+ : "cc", "memory", "r3" \
462
573
  ); \
463
574
  _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
575
  }
474
576
 
475
- #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R11 \
577
+ #define VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
476
578
  __SPECIAL_INSTRUCTION_PREAMBLE \
477
- /* branch-and-link-to-noredir *%R11 */ \
478
- "or 3,3,3\n\t"
579
+ /* branch-and-link-to-noredir *%R4 */ \
580
+ "orr r12, r12, r12\n\t"
479
581
 
480
- #endif /* PLAT_ppc32_aix5 */
582
+ #endif /* PLAT_arm_linux */
481
583
 
482
- /* ------------------------ ppc64-aix5 ------------------------- */
584
+ /* ------------------------ s390x-linux ------------------------ */
483
585
 
484
- #if defined(PLAT_ppc64_aix5)
586
+ #if defined(PLAT_s390x_linux)
485
587
 
486
588
  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; \
589
+ struct {
590
+ uint64_t nraddr; /* where's the code? */
545
591
  }
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 */
592
+ OrigFn;
593
+
594
+ /* __SPECIAL_INSTRUCTION_PREAMBLE will be used to identify Valgrind specific
595
+ * code. This detection is implemented in platform specific toIR.c
596
+ * (e.g. VEX/priv/guest_s390_decoder.c).
597
+ */
598
+ #define __SPECIAL_INSTRUCTION_PREAMBLE \
599
+ "lr 15,15\n\t" \
600
+ "lr 1,1\n\t" \
601
+ "lr 2,2\n\t" \
602
+ "lr 3,3\n\t"
603
+
604
+ #define __CLIENT_REQUEST_CODE "lr 2,2\n\t"
605
+ #define __GET_NR_CONTEXT_CODE "lr 3,3\n\t"
606
+ #define __CALL_NO_REDIR_CODE "lr 4,4\n\t"
607
+
608
+ #define VALGRIND_DO_CLIENT_REQUEST_EXPR( \
609
+ _zzq_default, _zzq_request, \
610
+ _zzq_arg1, _zzq_arg2, _zzq_arg3, _zzq_arg4, _zzq_arg5) \
611
+ __extension__ \
612
+ ({volatile uint64_t _zzq_args[6]; \
613
+ volatile uint64_t _zzq_result; \
614
+ _zzq_args[0] = (uint64_t)(_zzq_request); \
615
+ _zzq_args[1] = (uint64_t)(_zzq_arg1); \
616
+ _zzq_args[2] = (uint64_t)(_zzq_arg2); \
617
+ _zzq_args[3] = (uint64_t)(_zzq_arg3); \
618
+ _zzq_args[4] = (uint64_t)(_zzq_arg4); \
619
+ _zzq_args[5] = (uint64_t)(_zzq_arg5); \
620
+ __asm__ volatile(/* r2 = args */ \
621
+ "lgr 2,%1\n\t" \
622
+ /* r3 = default */ \
623
+ "lgr 3,%2\n\t" \
624
+ __SPECIAL_INSTRUCTION_PREAMBLE \
625
+ __CLIENT_REQUEST_CODE \
626
+ /* results = r3 */ \
627
+ "lgr %0, 3\n\t" \
628
+ : "=d" (_zzq_result) \
629
+ : "a" (&_zzq_args[0]), "0" (_zzq_default) \
630
+ : "cc", "2", "3", "memory" \
631
+ ); \
632
+ _zzq_result; \
633
+ })
634
+
635
+ #define VALGRIND_GET_NR_CONTEXT(_zzq_rlval) \
636
+ { volatile OrigFn* _zzq_orig = &(_zzq_rlval); \
637
+ volatile uint64_t __addr; \
638
+ __asm__ volatile(__SPECIAL_INSTRUCTION_PREAMBLE \
639
+ __GET_NR_CONTEXT_CODE \
640
+ "lgr %0, 3\n\t" \
641
+ : "=a" (__addr) \
642
+ : \
643
+ : "cc", "3", "memory" \
644
+ ); \
645
+ _zzq_orig->nraddr = __addr; \
646
+ }
647
+
648
+ #define VALGRIND_CALL_NOREDIR_R1 \
649
+ __SPECIAL_INSTRUCTION_PREAMBLE \
650
+ __CALL_NO_REDIR_CODE
651
+
652
+ #endif /* PLAT_s390x_linux */
553
653
 
554
654
  /* Insert assembly code for other platforms here... */
555
655
 
@@ -582,11 +682,15 @@ typedef
582
682
  /* Use these to write the name of your wrapper. NOTE: duplicates
583
683
  VG_WRAP_FUNCTION_Z{U,Z} in pub_tool_redir.h. */
584
684
 
685
+ /* Use an extra level of macroisation so as to ensure the soname/fnname
686
+ args are fully macro-expanded before pasting them together. */
687
+ #define VG_CONCAT4(_aa,_bb,_cc,_dd) _aa##_bb##_cc##_dd
688
+
585
689
  #define I_WRAP_SONAME_FNNAME_ZU(soname,fnname) \
586
- _vgwZU_##soname##_##fnname
690
+ VG_CONCAT4(_vgwZU_,soname,_,fnname)
587
691
 
588
692
  #define I_WRAP_SONAME_FNNAME_ZZ(soname,fnname) \
589
- _vgwZZ_##soname##_##fnname
693
+ VG_CONCAT4(_vgwZZ_,soname,_,fnname)
590
694
 
591
695
  /* Use this macro from within a wrapper function to collect the
592
696
  context (address and possibly other info) of the original function.
@@ -613,9 +717,25 @@ typedef
613
717
  do { volatile unsigned long _junk; \
614
718
  CALL_FN_W_WWW(_junk,fnptr,arg1,arg2,arg3); } while (0)
615
719
 
616
- /* ------------------------- x86-linux ------------------------- */
720
+ #define CALL_FN_v_WWWW(fnptr, arg1,arg2,arg3,arg4) \
721
+ do { volatile unsigned long _junk; \
722
+ CALL_FN_W_WWWW(_junk,fnptr,arg1,arg2,arg3,arg4); } while (0)
723
+
724
+ #define CALL_FN_v_5W(fnptr, arg1,arg2,arg3,arg4,arg5) \
725
+ do { volatile unsigned long _junk; \
726
+ CALL_FN_W_5W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5); } while (0)
727
+
728
+ #define CALL_FN_v_6W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6) \
729
+ do { volatile unsigned long _junk; \
730
+ CALL_FN_W_6W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6); } while (0)
731
+
732
+ #define CALL_FN_v_7W(fnptr, arg1,arg2,arg3,arg4,arg5,arg6,arg7) \
733
+ do { volatile unsigned long _junk; \
734
+ CALL_FN_W_7W(_junk,fnptr,arg1,arg2,arg3,arg4,arg5,arg6,arg7); } while (0)
735
+
736
+ /* ------------------------- x86-{linux,darwin} ---------------- */
617
737
 
618
- #if defined(PLAT_x86_linux)
738
+ #if defined(PLAT_x86_linux) || defined(PLAT_x86_darwin)
619
739
 
620
740
  /* These regs are trashed by the hidden call. No need to mention eax
621
741
  as gcc can already see that, plus causes gcc to bomb. */
@@ -648,10 +768,11 @@ typedef
648
768
  _argvec[0] = (unsigned long)_orig.nraddr; \
649
769
  _argvec[1] = (unsigned long)(arg1); \
650
770
  __asm__ volatile( \
771
+ "subl $12, %%esp\n\t" \
651
772
  "pushl 4(%%eax)\n\t" \
652
773
  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
653
774
  VALGRIND_CALL_NOREDIR_EAX \
654
- "addl $4, %%esp\n" \
775
+ "addl $16, %%esp\n" \
655
776
  : /*out*/ "=a" (_res) \
656
777
  : /*in*/ "a" (&_argvec[0]) \
657
778
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
@@ -668,11 +789,12 @@ typedef
668
789
  _argvec[1] = (unsigned long)(arg1); \
669
790
  _argvec[2] = (unsigned long)(arg2); \
670
791
  __asm__ volatile( \
792
+ "subl $8, %%esp\n\t" \
671
793
  "pushl 8(%%eax)\n\t" \
672
794
  "pushl 4(%%eax)\n\t" \
673
795
  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
674
796
  VALGRIND_CALL_NOREDIR_EAX \
675
- "addl $8, %%esp\n" \
797
+ "addl $16, %%esp\n" \
676
798
  : /*out*/ "=a" (_res) \
677
799
  : /*in*/ "a" (&_argvec[0]) \
678
800
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
@@ -690,12 +812,13 @@ typedef
690
812
  _argvec[2] = (unsigned long)(arg2); \
691
813
  _argvec[3] = (unsigned long)(arg3); \
692
814
  __asm__ volatile( \
815
+ "subl $4, %%esp\n\t" \
693
816
  "pushl 12(%%eax)\n\t" \
694
817
  "pushl 8(%%eax)\n\t" \
695
818
  "pushl 4(%%eax)\n\t" \
696
819
  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
697
820
  VALGRIND_CALL_NOREDIR_EAX \
698
- "addl $12, %%esp\n" \
821
+ "addl $16, %%esp\n" \
699
822
  : /*out*/ "=a" (_res) \
700
823
  : /*in*/ "a" (&_argvec[0]) \
701
824
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
@@ -740,6 +863,7 @@ typedef
740
863
  _argvec[4] = (unsigned long)(arg4); \
741
864
  _argvec[5] = (unsigned long)(arg5); \
742
865
  __asm__ volatile( \
866
+ "subl $12, %%esp\n\t" \
743
867
  "pushl 20(%%eax)\n\t" \
744
868
  "pushl 16(%%eax)\n\t" \
745
869
  "pushl 12(%%eax)\n\t" \
@@ -747,7 +871,7 @@ typedef
747
871
  "pushl 4(%%eax)\n\t" \
748
872
  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
749
873
  VALGRIND_CALL_NOREDIR_EAX \
750
- "addl $20, %%esp\n" \
874
+ "addl $32, %%esp\n" \
751
875
  : /*out*/ "=a" (_res) \
752
876
  : /*in*/ "a" (&_argvec[0]) \
753
877
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
@@ -768,6 +892,7 @@ typedef
768
892
  _argvec[5] = (unsigned long)(arg5); \
769
893
  _argvec[6] = (unsigned long)(arg6); \
770
894
  __asm__ volatile( \
895
+ "subl $8, %%esp\n\t" \
771
896
  "pushl 24(%%eax)\n\t" \
772
897
  "pushl 20(%%eax)\n\t" \
773
898
  "pushl 16(%%eax)\n\t" \
@@ -776,7 +901,7 @@ typedef
776
901
  "pushl 4(%%eax)\n\t" \
777
902
  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
778
903
  VALGRIND_CALL_NOREDIR_EAX \
779
- "addl $24, %%esp\n" \
904
+ "addl $32, %%esp\n" \
780
905
  : /*out*/ "=a" (_res) \
781
906
  : /*in*/ "a" (&_argvec[0]) \
782
907
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
@@ -799,6 +924,7 @@ typedef
799
924
  _argvec[6] = (unsigned long)(arg6); \
800
925
  _argvec[7] = (unsigned long)(arg7); \
801
926
  __asm__ volatile( \
927
+ "subl $4, %%esp\n\t" \
802
928
  "pushl 28(%%eax)\n\t" \
803
929
  "pushl 24(%%eax)\n\t" \
804
930
  "pushl 20(%%eax)\n\t" \
@@ -808,7 +934,7 @@ typedef
808
934
  "pushl 4(%%eax)\n\t" \
809
935
  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
810
936
  VALGRIND_CALL_NOREDIR_EAX \
811
- "addl $28, %%esp\n" \
937
+ "addl $32, %%esp\n" \
812
938
  : /*out*/ "=a" (_res) \
813
939
  : /*in*/ "a" (&_argvec[0]) \
814
940
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
@@ -867,6 +993,7 @@ typedef
867
993
  _argvec[8] = (unsigned long)(arg8); \
868
994
  _argvec[9] = (unsigned long)(arg9); \
869
995
  __asm__ volatile( \
996
+ "subl $12, %%esp\n\t" \
870
997
  "pushl 36(%%eax)\n\t" \
871
998
  "pushl 32(%%eax)\n\t" \
872
999
  "pushl 28(%%eax)\n\t" \
@@ -878,7 +1005,7 @@ typedef
878
1005
  "pushl 4(%%eax)\n\t" \
879
1006
  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
880
1007
  VALGRIND_CALL_NOREDIR_EAX \
881
- "addl $36, %%esp\n" \
1008
+ "addl $48, %%esp\n" \
882
1009
  : /*out*/ "=a" (_res) \
883
1010
  : /*in*/ "a" (&_argvec[0]) \
884
1011
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
@@ -904,6 +1031,7 @@ typedef
904
1031
  _argvec[9] = (unsigned long)(arg9); \
905
1032
  _argvec[10] = (unsigned long)(arg10); \
906
1033
  __asm__ volatile( \
1034
+ "subl $8, %%esp\n\t" \
907
1035
  "pushl 40(%%eax)\n\t" \
908
1036
  "pushl 36(%%eax)\n\t" \
909
1037
  "pushl 32(%%eax)\n\t" \
@@ -916,7 +1044,7 @@ typedef
916
1044
  "pushl 4(%%eax)\n\t" \
917
1045
  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
918
1046
  VALGRIND_CALL_NOREDIR_EAX \
919
- "addl $40, %%esp\n" \
1047
+ "addl $48, %%esp\n" \
920
1048
  : /*out*/ "=a" (_res) \
921
1049
  : /*in*/ "a" (&_argvec[0]) \
922
1050
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
@@ -944,6 +1072,7 @@ typedef
944
1072
  _argvec[10] = (unsigned long)(arg10); \
945
1073
  _argvec[11] = (unsigned long)(arg11); \
946
1074
  __asm__ volatile( \
1075
+ "subl $4, %%esp\n\t" \
947
1076
  "pushl 44(%%eax)\n\t" \
948
1077
  "pushl 40(%%eax)\n\t" \
949
1078
  "pushl 36(%%eax)\n\t" \
@@ -957,7 +1086,7 @@ typedef
957
1086
  "pushl 4(%%eax)\n\t" \
958
1087
  "movl (%%eax), %%eax\n\t" /* target->%eax */ \
959
1088
  VALGRIND_CALL_NOREDIR_EAX \
960
- "addl $44, %%esp\n" \
1089
+ "addl $48, %%esp\n" \
961
1090
  : /*out*/ "=a" (_res) \
962
1091
  : /*in*/ "a" (&_argvec[0]) \
963
1092
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
@@ -1008,11 +1137,11 @@ typedef
1008
1137
  lval = (__typeof__(lval)) _res; \
1009
1138
  } while (0)
1010
1139
 
1011
- #endif /* PLAT_x86_linux */
1140
+ #endif /* PLAT_x86_linux || PLAT_x86_darwin */
1012
1141
 
1013
- /* ------------------------ amd64-linux ------------------------ */
1142
+ /* ------------------------ amd64-{linux,darwin} --------------- */
1014
1143
 
1015
- #if defined(PLAT_amd64_linux)
1144
+ #if defined(PLAT_amd64_linux) || defined(PLAT_amd64_darwin)
1016
1145
 
1017
1146
  /* ARGREGS: rdi rsi rdx rcx r8 r9 (the rest on stack in R-to-L order) */
1018
1147
 
@@ -1020,6 +1149,78 @@ typedef
1020
1149
  #define __CALLER_SAVED_REGS /*"rax",*/ "rcx", "rdx", "rsi", \
1021
1150
  "rdi", "r8", "r9", "r10", "r11"
1022
1151
 
1152
+ /* This is all pretty complex. It's so as to make stack unwinding
1153
+ work reliably. See bug 243270. The basic problem is the sub and
1154
+ add of 128 of %rsp in all of the following macros. If gcc believes
1155
+ the CFA is in %rsp, then unwinding may fail, because what's at the
1156
+ CFA is not what gcc "expected" when it constructs the CFIs for the
1157
+ places where the macros are instantiated.
1158
+
1159
+ But we can't just add a CFI annotation to increase the CFA offset
1160
+ by 128, to match the sub of 128 from %rsp, because we don't know
1161
+ whether gcc has chosen %rsp as the CFA at that point, or whether it
1162
+ has chosen some other register (eg, %rbp). In the latter case,
1163
+ adding a CFI annotation to change the CFA offset is simply wrong.
1164
+
1165
+ So the solution is to get hold of the CFA using
1166
+ __builtin_dwarf_cfa(), put it in a known register, and add a
1167
+ CFI annotation to say what the register is. We choose %rbp for
1168
+ this (perhaps perversely), because:
1169
+
1170
+ (1) %rbp is already subject to unwinding. If a new register was
1171
+ chosen then the unwinder would have to unwind it in all stack
1172
+ traces, which is expensive, and
1173
+
1174
+ (2) %rbp is already subject to precise exception updates in the
1175
+ JIT. If a new register was chosen, we'd have to have precise
1176
+ exceptions for it too, which reduces performance of the
1177
+ generated code.
1178
+
1179
+ However .. one extra complication. We can't just whack the result
1180
+ of __builtin_dwarf_cfa() into %rbp and then add %rbp to the
1181
+ list of trashed registers at the end of the inline assembly
1182
+ fragments; gcc won't allow %rbp to appear in that list. Hence
1183
+ instead we need to stash %rbp in %r15 for the duration of the asm,
1184
+ and say that %r15 is trashed instead. gcc seems happy to go with
1185
+ that.
1186
+
1187
+ Oh .. and this all needs to be conditionalised so that it is
1188
+ unchanged from before this commit, when compiled with older gccs
1189
+ that don't support __builtin_dwarf_cfa. Furthermore, since
1190
+ this header file is freestanding, it has to be independent of
1191
+ config.h, and so the following conditionalisation cannot depend on
1192
+ configure time checks.
1193
+
1194
+ Although it's not clear from
1195
+ 'defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)',
1196
+ this expression excludes Darwin.
1197
+ .cfi directives in Darwin assembly appear to be completely
1198
+ different and I haven't investigated how they work.
1199
+
1200
+ For even more entertainment value, note we have to use the
1201
+ completely undocumented __builtin_dwarf_cfa(), which appears to
1202
+ really compute the CFA, whereas __builtin_frame_address(0) claims
1203
+ to but actually doesn't. See
1204
+ https://bugs.kde.org/show_bug.cgi?id=243270#c47
1205
+ */
1206
+ #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
1207
+ # define __FRAME_POINTER \
1208
+ ,"r"(__builtin_dwarf_cfa())
1209
+ # define VALGRIND_CFI_PROLOGUE \
1210
+ "movq %%rbp, %%r15\n\t" \
1211
+ "movq %2, %%rbp\n\t" \
1212
+ ".cfi_remember_state\n\t" \
1213
+ ".cfi_def_cfa rbp, 0\n\t"
1214
+ # define VALGRIND_CFI_EPILOGUE \
1215
+ "movq %%r15, %%rbp\n\t" \
1216
+ ".cfi_restore_state\n\t"
1217
+ #else
1218
+ # define __FRAME_POINTER
1219
+ # define VALGRIND_CFI_PROLOGUE
1220
+ # define VALGRIND_CFI_EPILOGUE
1221
+ #endif
1222
+
1223
+
1023
1224
  /* These CALL_FN_ macros assume that on amd64-linux, sizeof(unsigned
1024
1225
  long) == 8. */
1025
1226
 
@@ -1039,7 +1240,7 @@ typedef
1039
1240
  redzone, for the duration of the hidden call, to make it safe.
1040
1241
 
1041
1242
  Probably the same problem afflicts the other redzone-style ABIs too
1042
- (ppc64-linux, ppc32-aix5, ppc64-aix5); but for those, the stack is
1243
+ (ppc64-linux); but for those, the stack is
1043
1244
  self describing (none of this CFI nonsense) so at least messing
1044
1245
  with the stack pointer doesn't give a danger of non-unwindable
1045
1246
  stack. */
@@ -1051,13 +1252,15 @@ typedef
1051
1252
  volatile unsigned long _res; \
1052
1253
  _argvec[0] = (unsigned long)_orig.nraddr; \
1053
1254
  __asm__ volatile( \
1255
+ VALGRIND_CFI_PROLOGUE \
1054
1256
  "subq $128,%%rsp\n\t" \
1055
1257
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1056
1258
  VALGRIND_CALL_NOREDIR_RAX \
1057
1259
  "addq $128,%%rsp\n\t" \
1260
+ VALGRIND_CFI_EPILOGUE \
1058
1261
  : /*out*/ "=a" (_res) \
1059
- : /*in*/ "a" (&_argvec[0]) \
1060
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1262
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1263
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1061
1264
  ); \
1062
1265
  lval = (__typeof__(lval)) _res; \
1063
1266
  } while (0)
@@ -1070,14 +1273,16 @@ typedef
1070
1273
  _argvec[0] = (unsigned long)_orig.nraddr; \
1071
1274
  _argvec[1] = (unsigned long)(arg1); \
1072
1275
  __asm__ volatile( \
1276
+ VALGRIND_CFI_PROLOGUE \
1073
1277
  "subq $128,%%rsp\n\t" \
1074
1278
  "movq 8(%%rax), %%rdi\n\t" \
1075
1279
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1076
1280
  VALGRIND_CALL_NOREDIR_RAX \
1077
1281
  "addq $128,%%rsp\n\t" \
1282
+ VALGRIND_CFI_EPILOGUE \
1078
1283
  : /*out*/ "=a" (_res) \
1079
- : /*in*/ "a" (&_argvec[0]) \
1080
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1284
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1285
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1081
1286
  ); \
1082
1287
  lval = (__typeof__(lval)) _res; \
1083
1288
  } while (0)
@@ -1091,15 +1296,17 @@ typedef
1091
1296
  _argvec[1] = (unsigned long)(arg1); \
1092
1297
  _argvec[2] = (unsigned long)(arg2); \
1093
1298
  __asm__ volatile( \
1299
+ VALGRIND_CFI_PROLOGUE \
1094
1300
  "subq $128,%%rsp\n\t" \
1095
1301
  "movq 16(%%rax), %%rsi\n\t" \
1096
1302
  "movq 8(%%rax), %%rdi\n\t" \
1097
1303
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1098
1304
  VALGRIND_CALL_NOREDIR_RAX \
1099
1305
  "addq $128,%%rsp\n\t" \
1306
+ VALGRIND_CFI_EPILOGUE \
1100
1307
  : /*out*/ "=a" (_res) \
1101
- : /*in*/ "a" (&_argvec[0]) \
1102
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1308
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1309
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1103
1310
  ); \
1104
1311
  lval = (__typeof__(lval)) _res; \
1105
1312
  } while (0)
@@ -1114,6 +1321,7 @@ typedef
1114
1321
  _argvec[2] = (unsigned long)(arg2); \
1115
1322
  _argvec[3] = (unsigned long)(arg3); \
1116
1323
  __asm__ volatile( \
1324
+ VALGRIND_CFI_PROLOGUE \
1117
1325
  "subq $128,%%rsp\n\t" \
1118
1326
  "movq 24(%%rax), %%rdx\n\t" \
1119
1327
  "movq 16(%%rax), %%rsi\n\t" \
@@ -1121,9 +1329,10 @@ typedef
1121
1329
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1122
1330
  VALGRIND_CALL_NOREDIR_RAX \
1123
1331
  "addq $128,%%rsp\n\t" \
1332
+ VALGRIND_CFI_EPILOGUE \
1124
1333
  : /*out*/ "=a" (_res) \
1125
- : /*in*/ "a" (&_argvec[0]) \
1126
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1334
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1335
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1127
1336
  ); \
1128
1337
  lval = (__typeof__(lval)) _res; \
1129
1338
  } while (0)
@@ -1139,6 +1348,7 @@ typedef
1139
1348
  _argvec[3] = (unsigned long)(arg3); \
1140
1349
  _argvec[4] = (unsigned long)(arg4); \
1141
1350
  __asm__ volatile( \
1351
+ VALGRIND_CFI_PROLOGUE \
1142
1352
  "subq $128,%%rsp\n\t" \
1143
1353
  "movq 32(%%rax), %%rcx\n\t" \
1144
1354
  "movq 24(%%rax), %%rdx\n\t" \
@@ -1147,9 +1357,10 @@ typedef
1147
1357
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1148
1358
  VALGRIND_CALL_NOREDIR_RAX \
1149
1359
  "addq $128,%%rsp\n\t" \
1360
+ VALGRIND_CFI_EPILOGUE \
1150
1361
  : /*out*/ "=a" (_res) \
1151
- : /*in*/ "a" (&_argvec[0]) \
1152
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1362
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1363
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1153
1364
  ); \
1154
1365
  lval = (__typeof__(lval)) _res; \
1155
1366
  } while (0)
@@ -1166,6 +1377,7 @@ typedef
1166
1377
  _argvec[4] = (unsigned long)(arg4); \
1167
1378
  _argvec[5] = (unsigned long)(arg5); \
1168
1379
  __asm__ volatile( \
1380
+ VALGRIND_CFI_PROLOGUE \
1169
1381
  "subq $128,%%rsp\n\t" \
1170
1382
  "movq 40(%%rax), %%r8\n\t" \
1171
1383
  "movq 32(%%rax), %%rcx\n\t" \
@@ -1175,9 +1387,10 @@ typedef
1175
1387
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1176
1388
  VALGRIND_CALL_NOREDIR_RAX \
1177
1389
  "addq $128,%%rsp\n\t" \
1390
+ VALGRIND_CFI_EPILOGUE \
1178
1391
  : /*out*/ "=a" (_res) \
1179
- : /*in*/ "a" (&_argvec[0]) \
1180
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1392
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1393
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1181
1394
  ); \
1182
1395
  lval = (__typeof__(lval)) _res; \
1183
1396
  } while (0)
@@ -1195,6 +1408,7 @@ typedef
1195
1408
  _argvec[5] = (unsigned long)(arg5); \
1196
1409
  _argvec[6] = (unsigned long)(arg6); \
1197
1410
  __asm__ volatile( \
1411
+ VALGRIND_CFI_PROLOGUE \
1198
1412
  "subq $128,%%rsp\n\t" \
1199
1413
  "movq 48(%%rax), %%r9\n\t" \
1200
1414
  "movq 40(%%rax), %%r8\n\t" \
@@ -1203,11 +1417,12 @@ typedef
1203
1417
  "movq 16(%%rax), %%rsi\n\t" \
1204
1418
  "movq 8(%%rax), %%rdi\n\t" \
1205
1419
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1206
- "addq $128,%%rsp\n\t" \
1207
1420
  VALGRIND_CALL_NOREDIR_RAX \
1421
+ "addq $128,%%rsp\n\t" \
1422
+ VALGRIND_CFI_EPILOGUE \
1208
1423
  : /*out*/ "=a" (_res) \
1209
- : /*in*/ "a" (&_argvec[0]) \
1210
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1424
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1425
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1211
1426
  ); \
1212
1427
  lval = (__typeof__(lval)) _res; \
1213
1428
  } while (0)
@@ -1227,7 +1442,8 @@ typedef
1227
1442
  _argvec[6] = (unsigned long)(arg6); \
1228
1443
  _argvec[7] = (unsigned long)(arg7); \
1229
1444
  __asm__ volatile( \
1230
- "subq $128,%%rsp\n\t" \
1445
+ VALGRIND_CFI_PROLOGUE \
1446
+ "subq $136,%%rsp\n\t" \
1231
1447
  "pushq 56(%%rax)\n\t" \
1232
1448
  "movq 48(%%rax), %%r9\n\t" \
1233
1449
  "movq 40(%%rax), %%r8\n\t" \
@@ -1238,10 +1454,11 @@ typedef
1238
1454
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1239
1455
  VALGRIND_CALL_NOREDIR_RAX \
1240
1456
  "addq $8, %%rsp\n" \
1241
- "addq $128,%%rsp\n\t" \
1457
+ "addq $136,%%rsp\n\t" \
1458
+ VALGRIND_CFI_EPILOGUE \
1242
1459
  : /*out*/ "=a" (_res) \
1243
- : /*in*/ "a" (&_argvec[0]) \
1244
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1460
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1461
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1245
1462
  ); \
1246
1463
  lval = (__typeof__(lval)) _res; \
1247
1464
  } while (0)
@@ -1262,6 +1479,7 @@ typedef
1262
1479
  _argvec[7] = (unsigned long)(arg7); \
1263
1480
  _argvec[8] = (unsigned long)(arg8); \
1264
1481
  __asm__ volatile( \
1482
+ VALGRIND_CFI_PROLOGUE \
1265
1483
  "subq $128,%%rsp\n\t" \
1266
1484
  "pushq 64(%%rax)\n\t" \
1267
1485
  "pushq 56(%%rax)\n\t" \
@@ -1275,9 +1493,10 @@ typedef
1275
1493
  VALGRIND_CALL_NOREDIR_RAX \
1276
1494
  "addq $16, %%rsp\n" \
1277
1495
  "addq $128,%%rsp\n\t" \
1496
+ VALGRIND_CFI_EPILOGUE \
1278
1497
  : /*out*/ "=a" (_res) \
1279
- : /*in*/ "a" (&_argvec[0]) \
1280
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1498
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1499
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1281
1500
  ); \
1282
1501
  lval = (__typeof__(lval)) _res; \
1283
1502
  } while (0)
@@ -1299,7 +1518,8 @@ typedef
1299
1518
  _argvec[8] = (unsigned long)(arg8); \
1300
1519
  _argvec[9] = (unsigned long)(arg9); \
1301
1520
  __asm__ volatile( \
1302
- "subq $128,%%rsp\n\t" \
1521
+ VALGRIND_CFI_PROLOGUE \
1522
+ "subq $136,%%rsp\n\t" \
1303
1523
  "pushq 72(%%rax)\n\t" \
1304
1524
  "pushq 64(%%rax)\n\t" \
1305
1525
  "pushq 56(%%rax)\n\t" \
@@ -1312,10 +1532,11 @@ typedef
1312
1532
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1313
1533
  VALGRIND_CALL_NOREDIR_RAX \
1314
1534
  "addq $24, %%rsp\n" \
1315
- "addq $128,%%rsp\n\t" \
1535
+ "addq $136,%%rsp\n\t" \
1536
+ VALGRIND_CFI_EPILOGUE \
1316
1537
  : /*out*/ "=a" (_res) \
1317
- : /*in*/ "a" (&_argvec[0]) \
1318
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1538
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1539
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1319
1540
  ); \
1320
1541
  lval = (__typeof__(lval)) _res; \
1321
1542
  } while (0)
@@ -1338,6 +1559,7 @@ typedef
1338
1559
  _argvec[9] = (unsigned long)(arg9); \
1339
1560
  _argvec[10] = (unsigned long)(arg10); \
1340
1561
  __asm__ volatile( \
1562
+ VALGRIND_CFI_PROLOGUE \
1341
1563
  "subq $128,%%rsp\n\t" \
1342
1564
  "pushq 80(%%rax)\n\t" \
1343
1565
  "pushq 72(%%rax)\n\t" \
@@ -1353,9 +1575,10 @@ typedef
1353
1575
  VALGRIND_CALL_NOREDIR_RAX \
1354
1576
  "addq $32, %%rsp\n" \
1355
1577
  "addq $128,%%rsp\n\t" \
1578
+ VALGRIND_CFI_EPILOGUE \
1356
1579
  : /*out*/ "=a" (_res) \
1357
- : /*in*/ "a" (&_argvec[0]) \
1358
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1580
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1581
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1359
1582
  ); \
1360
1583
  lval = (__typeof__(lval)) _res; \
1361
1584
  } while (0)
@@ -1379,7 +1602,8 @@ typedef
1379
1602
  _argvec[10] = (unsigned long)(arg10); \
1380
1603
  _argvec[11] = (unsigned long)(arg11); \
1381
1604
  __asm__ volatile( \
1382
- "subq $128,%%rsp\n\t" \
1605
+ VALGRIND_CFI_PROLOGUE \
1606
+ "subq $136,%%rsp\n\t" \
1383
1607
  "pushq 88(%%rax)\n\t" \
1384
1608
  "pushq 80(%%rax)\n\t" \
1385
1609
  "pushq 72(%%rax)\n\t" \
@@ -1394,10 +1618,11 @@ typedef
1394
1618
  "movq (%%rax), %%rax\n\t" /* target->%rax */ \
1395
1619
  VALGRIND_CALL_NOREDIR_RAX \
1396
1620
  "addq $40, %%rsp\n" \
1397
- "addq $128,%%rsp\n\t" \
1621
+ "addq $136,%%rsp\n\t" \
1622
+ VALGRIND_CFI_EPILOGUE \
1398
1623
  : /*out*/ "=a" (_res) \
1399
- : /*in*/ "a" (&_argvec[0]) \
1400
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1624
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1625
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1401
1626
  ); \
1402
1627
  lval = (__typeof__(lval)) _res; \
1403
1628
  } while (0)
@@ -1422,6 +1647,7 @@ typedef
1422
1647
  _argvec[11] = (unsigned long)(arg11); \
1423
1648
  _argvec[12] = (unsigned long)(arg12); \
1424
1649
  __asm__ volatile( \
1650
+ VALGRIND_CFI_PROLOGUE \
1425
1651
  "subq $128,%%rsp\n\t" \
1426
1652
  "pushq 96(%%rax)\n\t" \
1427
1653
  "pushq 88(%%rax)\n\t" \
@@ -1439,14 +1665,15 @@ typedef
1439
1665
  VALGRIND_CALL_NOREDIR_RAX \
1440
1666
  "addq $48, %%rsp\n" \
1441
1667
  "addq $128,%%rsp\n\t" \
1668
+ VALGRIND_CFI_EPILOGUE \
1442
1669
  : /*out*/ "=a" (_res) \
1443
- : /*in*/ "a" (&_argvec[0]) \
1444
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
1670
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
1671
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS, "r15" \
1445
1672
  ); \
1446
1673
  lval = (__typeof__(lval)) _res; \
1447
1674
  } while (0)
1448
1675
 
1449
- #endif /* PLAT_amd64_linux */
1676
+ #endif /* PLAT_amd64_linux || PLAT_amd64_darwin */
1450
1677
 
1451
1678
  /* ------------------------ ppc32-linux ------------------------ */
1452
1679
 
@@ -2439,54 +2666,28 @@ typedef
2439
2666
 
2440
2667
  #endif /* PLAT_ppc64_linux */
2441
2668
 
2442
- /* ------------------------ ppc32-aix5 ------------------------- */
2669
+ /* ------------------------- arm-linux ------------------------- */
2443
2670
 
2444
- #if defined(PLAT_ppc32_aix5)
2445
-
2446
- /* ARGREGS: r3 r4 r5 r6 r7 r8 r9 r10 (the rest on stack somewhere) */
2671
+ #if defined(PLAT_arm_linux)
2447
2672
 
2448
2673
  /* 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"
2674
+ #define __CALLER_SAVED_REGS "r0", "r1", "r2", "r3","r4","r14"
2465
2675
 
2466
- /* These CALL_FN_ macros assume that on ppc32-aix5, sizeof(unsigned
2676
+ /* These CALL_FN_ macros assume that on arm-linux, sizeof(unsigned
2467
2677
  long) == 4. */
2468
2678
 
2469
2679
  #define CALL_FN_W_v(lval, orig) \
2470
2680
  do { \
2471
2681
  volatile OrigFn _orig = (orig); \
2472
- volatile unsigned long _argvec[3+0]; \
2682
+ volatile unsigned long _argvec[1]; \
2473
2683
  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; \
2684
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2477
2685
  __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) \
2686
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2687
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2688
+ "mov %0, r0\n" \
2488
2689
  : /*out*/ "=r" (_res) \
2489
- : /*in*/ "r" (&_argvec[2]) \
2690
+ : /*in*/ "0" (&_argvec[0]) \
2490
2691
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2491
2692
  ); \
2492
2693
  lval = (__typeof__(lval)) _res; \
@@ -2495,27 +2696,18 @@ typedef
2495
2696
  #define CALL_FN_W_W(lval, orig, arg1) \
2496
2697
  do { \
2497
2698
  volatile OrigFn _orig = (orig); \
2498
- volatile unsigned long _argvec[3+1]; \
2699
+ volatile unsigned long _argvec[2]; \
2499
2700
  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; \
2701
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2702
+ _argvec[1] = (unsigned long)(arg1); \
2504
2703
  __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) \
2704
+ "ldr r0, [%1, #4] \n\t" \
2705
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2706
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2707
+ "mov %0, r0\n" \
2516
2708
  : /*out*/ "=r" (_res) \
2517
- : /*in*/ "r" (&_argvec[2]) \
2518
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2709
+ : /*in*/ "0" (&_argvec[0]) \
2710
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2519
2711
  ); \
2520
2712
  lval = (__typeof__(lval)) _res; \
2521
2713
  } while (0)
@@ -2523,28 +2715,19 @@ typedef
2523
2715
  #define CALL_FN_W_WW(lval, orig, arg1,arg2) \
2524
2716
  do { \
2525
2717
  volatile OrigFn _orig = (orig); \
2526
- volatile unsigned long _argvec[3+2]; \
2718
+ volatile unsigned long _argvec[3]; \
2527
2719
  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; \
2720
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2721
+ _argvec[1] = (unsigned long)(arg1); \
2722
+ _argvec[2] = (unsigned long)(arg2); \
2533
2723
  __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) \
2724
+ "ldr r0, [%1, #4] \n\t" \
2725
+ "ldr r1, [%1, #8] \n\t" \
2726
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2727
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2728
+ "mov %0, r0\n" \
2546
2729
  : /*out*/ "=r" (_res) \
2547
- : /*in*/ "r" (&_argvec[2]) \
2730
+ : /*in*/ "0" (&_argvec[0]) \
2548
2731
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2549
2732
  ); \
2550
2733
  lval = (__typeof__(lval)) _res; \
@@ -2553,30 +2736,21 @@ typedef
2553
2736
  #define CALL_FN_W_WWW(lval, orig, arg1,arg2,arg3) \
2554
2737
  do { \
2555
2738
  volatile OrigFn _orig = (orig); \
2556
- volatile unsigned long _argvec[3+3]; \
2739
+ volatile unsigned long _argvec[4]; \
2557
2740
  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; \
2741
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2742
+ _argvec[1] = (unsigned long)(arg1); \
2743
+ _argvec[2] = (unsigned long)(arg2); \
2744
+ _argvec[3] = (unsigned long)(arg3); \
2564
2745
  __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) \
2746
+ "ldr r0, [%1, #4] \n\t" \
2747
+ "ldr r1, [%1, #8] \n\t" \
2748
+ "ldr r2, [%1, #12] \n\t" \
2749
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2750
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2751
+ "mov %0, r0\n" \
2578
2752
  : /*out*/ "=r" (_res) \
2579
- : /*in*/ "r" (&_argvec[2]) \
2753
+ : /*in*/ "0" (&_argvec[0]) \
2580
2754
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2581
2755
  ); \
2582
2756
  lval = (__typeof__(lval)) _res; \
@@ -2585,32 +2759,23 @@ typedef
2585
2759
  #define CALL_FN_W_WWWW(lval, orig, arg1,arg2,arg3,arg4) \
2586
2760
  do { \
2587
2761
  volatile OrigFn _orig = (orig); \
2588
- volatile unsigned long _argvec[3+4]; \
2762
+ volatile unsigned long _argvec[5]; \
2589
2763
  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; \
2764
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2765
+ _argvec[1] = (unsigned long)(arg1); \
2766
+ _argvec[2] = (unsigned long)(arg2); \
2767
+ _argvec[3] = (unsigned long)(arg3); \
2768
+ _argvec[4] = (unsigned long)(arg4); \
2597
2769
  __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) \
2770
+ "ldr r0, [%1, #4] \n\t" \
2771
+ "ldr r1, [%1, #8] \n\t" \
2772
+ "ldr r2, [%1, #12] \n\t" \
2773
+ "ldr r3, [%1, #16] \n\t" \
2774
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2775
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2776
+ "mov %0, r0" \
2612
2777
  : /*out*/ "=r" (_res) \
2613
- : /*in*/ "r" (&_argvec[2]) \
2778
+ : /*in*/ "0" (&_argvec[0]) \
2614
2779
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
2615
2780
  ); \
2616
2781
  lval = (__typeof__(lval)) _res; \
@@ -2619,595 +2784,27 @@ typedef
2619
2784
  #define CALL_FN_W_5W(lval, orig, arg1,arg2,arg3,arg4,arg5) \
2620
2785
  do { \
2621
2786
  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]; \
2787
+ volatile unsigned long _argvec[6]; \
3184
2788
  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; \
2789
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2790
+ _argvec[1] = (unsigned long)(arg1); \
2791
+ _argvec[2] = (unsigned long)(arg2); \
2792
+ _argvec[3] = (unsigned long)(arg3); \
2793
+ _argvec[4] = (unsigned long)(arg4); \
2794
+ _argvec[5] = (unsigned long)(arg5); \
3193
2795
  __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) \
2796
+ "ldr r0, [%1, #20] \n\t" \
2797
+ "push {r0} \n\t" \
2798
+ "ldr r0, [%1, #4] \n\t" \
2799
+ "ldr r1, [%1, #8] \n\t" \
2800
+ "ldr r2, [%1, #12] \n\t" \
2801
+ "ldr r3, [%1, #16] \n\t" \
2802
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2803
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2804
+ "add sp, sp, #4 \n\t" \
2805
+ "mov %0, r0" \
3209
2806
  : /*out*/ "=r" (_res) \
3210
- : /*in*/ "r" (&_argvec[2]) \
2807
+ : /*in*/ "0" (&_argvec[0]) \
3211
2808
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3212
2809
  ); \
3213
2810
  lval = (__typeof__(lval)) _res; \
@@ -3216,36 +2813,29 @@ typedef
3216
2813
  #define CALL_FN_W_6W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6) \
3217
2814
  do { \
3218
2815
  volatile OrigFn _orig = (orig); \
3219
- volatile unsigned long _argvec[3+6]; \
2816
+ volatile unsigned long _argvec[7]; \
3220
2817
  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; \
2818
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2819
+ _argvec[1] = (unsigned long)(arg1); \
2820
+ _argvec[2] = (unsigned long)(arg2); \
2821
+ _argvec[3] = (unsigned long)(arg3); \
2822
+ _argvec[4] = (unsigned long)(arg4); \
2823
+ _argvec[5] = (unsigned long)(arg5); \
2824
+ _argvec[6] = (unsigned long)(arg6); \
3230
2825
  __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) \
2826
+ "ldr r0, [%1, #20] \n\t" \
2827
+ "ldr r1, [%1, #24] \n\t" \
2828
+ "push {r0, r1} \n\t" \
2829
+ "ldr r0, [%1, #4] \n\t" \
2830
+ "ldr r1, [%1, #8] \n\t" \
2831
+ "ldr r2, [%1, #12] \n\t" \
2832
+ "ldr r3, [%1, #16] \n\t" \
2833
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2834
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2835
+ "add sp, sp, #8 \n\t" \
2836
+ "mov %0, r0" \
3247
2837
  : /*out*/ "=r" (_res) \
3248
- : /*in*/ "r" (&_argvec[2]) \
2838
+ : /*in*/ "0" (&_argvec[0]) \
3249
2839
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3250
2840
  ); \
3251
2841
  lval = (__typeof__(lval)) _res; \
@@ -3255,38 +2845,31 @@ typedef
3255
2845
  arg7) \
3256
2846
  do { \
3257
2847
  volatile OrigFn _orig = (orig); \
3258
- volatile unsigned long _argvec[3+7]; \
2848
+ volatile unsigned long _argvec[8]; \
3259
2849
  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; \
2850
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2851
+ _argvec[1] = (unsigned long)(arg1); \
2852
+ _argvec[2] = (unsigned long)(arg2); \
2853
+ _argvec[3] = (unsigned long)(arg3); \
2854
+ _argvec[4] = (unsigned long)(arg4); \
2855
+ _argvec[5] = (unsigned long)(arg5); \
2856
+ _argvec[6] = (unsigned long)(arg6); \
2857
+ _argvec[7] = (unsigned long)(arg7); \
3270
2858
  __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) \
2859
+ "ldr r0, [%1, #20] \n\t" \
2860
+ "ldr r1, [%1, #24] \n\t" \
2861
+ "ldr r2, [%1, #28] \n\t" \
2862
+ "push {r0, r1, r2} \n\t" \
2863
+ "ldr r0, [%1, #4] \n\t" \
2864
+ "ldr r1, [%1, #8] \n\t" \
2865
+ "ldr r2, [%1, #12] \n\t" \
2866
+ "ldr r3, [%1, #16] \n\t" \
2867
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2868
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2869
+ "add sp, sp, #12 \n\t" \
2870
+ "mov %0, r0" \
3288
2871
  : /*out*/ "=r" (_res) \
3289
- : /*in*/ "r" (&_argvec[2]) \
2872
+ : /*in*/ "0" (&_argvec[0]) \
3290
2873
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3291
2874
  ); \
3292
2875
  lval = (__typeof__(lval)) _res; \
@@ -3296,40 +2879,33 @@ typedef
3296
2879
  arg7,arg8) \
3297
2880
  do { \
3298
2881
  volatile OrigFn _orig = (orig); \
3299
- volatile unsigned long _argvec[3+8]; \
2882
+ volatile unsigned long _argvec[9]; \
3300
2883
  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; \
2884
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2885
+ _argvec[1] = (unsigned long)(arg1); \
2886
+ _argvec[2] = (unsigned long)(arg2); \
2887
+ _argvec[3] = (unsigned long)(arg3); \
2888
+ _argvec[4] = (unsigned long)(arg4); \
2889
+ _argvec[5] = (unsigned long)(arg5); \
2890
+ _argvec[6] = (unsigned long)(arg6); \
2891
+ _argvec[7] = (unsigned long)(arg7); \
2892
+ _argvec[8] = (unsigned long)(arg8); \
3312
2893
  __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) \
2894
+ "ldr r0, [%1, #20] \n\t" \
2895
+ "ldr r1, [%1, #24] \n\t" \
2896
+ "ldr r2, [%1, #28] \n\t" \
2897
+ "ldr r3, [%1, #32] \n\t" \
2898
+ "push {r0, r1, r2, r3} \n\t" \
2899
+ "ldr r0, [%1, #4] \n\t" \
2900
+ "ldr r1, [%1, #8] \n\t" \
2901
+ "ldr r2, [%1, #12] \n\t" \
2902
+ "ldr r3, [%1, #16] \n\t" \
2903
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2904
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2905
+ "add sp, sp, #16 \n\t" \
2906
+ "mov %0, r0" \
3331
2907
  : /*out*/ "=r" (_res) \
3332
- : /*in*/ "r" (&_argvec[2]) \
2908
+ : /*in*/ "0" (&_argvec[0]) \
3333
2909
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3334
2910
  ); \
3335
2911
  lval = (__typeof__(lval)) _res; \
@@ -3338,48 +2914,36 @@ typedef
3338
2914
  #define CALL_FN_W_9W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3339
2915
  arg7,arg8,arg9) \
3340
2916
  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; \
2917
+ volatile OrigFn _orig = (orig); \
2918
+ volatile unsigned long _argvec[10]; \
2919
+ volatile unsigned long _res; \
2920
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2921
+ _argvec[1] = (unsigned long)(arg1); \
2922
+ _argvec[2] = (unsigned long)(arg2); \
2923
+ _argvec[3] = (unsigned long)(arg3); \
2924
+ _argvec[4] = (unsigned long)(arg4); \
2925
+ _argvec[5] = (unsigned long)(arg5); \
2926
+ _argvec[6] = (unsigned long)(arg6); \
2927
+ _argvec[7] = (unsigned long)(arg7); \
2928
+ _argvec[8] = (unsigned long)(arg8); \
2929
+ _argvec[9] = (unsigned long)(arg9); \
3356
2930
  __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) \
2931
+ "ldr r0, [%1, #20] \n\t" \
2932
+ "ldr r1, [%1, #24] \n\t" \
2933
+ "ldr r2, [%1, #28] \n\t" \
2934
+ "ldr r3, [%1, #32] \n\t" \
2935
+ "ldr r4, [%1, #36] \n\t" \
2936
+ "push {r0, r1, r2, r3, r4} \n\t" \
2937
+ "ldr r0, [%1, #4] \n\t" \
2938
+ "ldr r1, [%1, #8] \n\t" \
2939
+ "ldr r2, [%1, #12] \n\t" \
2940
+ "ldr r3, [%1, #16] \n\t" \
2941
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2942
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2943
+ "add sp, sp, #20 \n\t" \
2944
+ "mov %0, r0" \
3381
2945
  : /*out*/ "=r" (_res) \
3382
- : /*in*/ "r" (&_argvec[2]) \
2946
+ : /*in*/ "0" (&_argvec[0]) \
3383
2947
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3384
2948
  ); \
3385
2949
  lval = (__typeof__(lval)) _res; \
@@ -3389,177 +2953,612 @@ typedef
3389
2953
  arg7,arg8,arg9,arg10) \
3390
2954
  do { \
3391
2955
  volatile OrigFn _orig = (orig); \
3392
- volatile unsigned long _argvec[3+10]; \
2956
+ volatile unsigned long _argvec[11]; \
3393
2957
  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; \
2958
+ _argvec[0] = (unsigned long)_orig.nraddr; \
2959
+ _argvec[1] = (unsigned long)(arg1); \
2960
+ _argvec[2] = (unsigned long)(arg2); \
2961
+ _argvec[3] = (unsigned long)(arg3); \
2962
+ _argvec[4] = (unsigned long)(arg4); \
2963
+ _argvec[5] = (unsigned long)(arg5); \
2964
+ _argvec[6] = (unsigned long)(arg6); \
2965
+ _argvec[7] = (unsigned long)(arg7); \
2966
+ _argvec[8] = (unsigned long)(arg8); \
2967
+ _argvec[9] = (unsigned long)(arg9); \
2968
+ _argvec[10] = (unsigned long)(arg10); \
3407
2969
  __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) \
2970
+ "ldr r0, [%1, #40] \n\t" \
2971
+ "push {r0} \n\t" \
2972
+ "ldr r0, [%1, #20] \n\t" \
2973
+ "ldr r1, [%1, #24] \n\t" \
2974
+ "ldr r2, [%1, #28] \n\t" \
2975
+ "ldr r3, [%1, #32] \n\t" \
2976
+ "ldr r4, [%1, #36] \n\t" \
2977
+ "push {r0, r1, r2, r3, r4} \n\t" \
2978
+ "ldr r0, [%1, #4] \n\t" \
2979
+ "ldr r1, [%1, #8] \n\t" \
2980
+ "ldr r2, [%1, #12] \n\t" \
2981
+ "ldr r3, [%1, #16] \n\t" \
2982
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
2983
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
2984
+ "add sp, sp, #24 \n\t" \
2985
+ "mov %0, r0" \
3435
2986
  : /*out*/ "=r" (_res) \
3436
- : /*in*/ "r" (&_argvec[2]) \
2987
+ : /*in*/ "0" (&_argvec[0]) \
3437
2988
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3438
2989
  ); \
3439
2990
  lval = (__typeof__(lval)) _res; \
3440
2991
  } while (0)
3441
2992
 
3442
- #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3443
- arg7,arg8,arg9,arg10,arg11) \
2993
+ #define CALL_FN_W_11W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
2994
+ arg6,arg7,arg8,arg9,arg10, \
2995
+ arg11) \
3444
2996
  do { \
3445
2997
  volatile OrigFn _orig = (orig); \
3446
- volatile unsigned long _argvec[3+11]; \
2998
+ volatile unsigned long _argvec[12]; \
3447
2999
  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; \
3000
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3001
+ _argvec[1] = (unsigned long)(arg1); \
3002
+ _argvec[2] = (unsigned long)(arg2); \
3003
+ _argvec[3] = (unsigned long)(arg3); \
3004
+ _argvec[4] = (unsigned long)(arg4); \
3005
+ _argvec[5] = (unsigned long)(arg5); \
3006
+ _argvec[6] = (unsigned long)(arg6); \
3007
+ _argvec[7] = (unsigned long)(arg7); \
3008
+ _argvec[8] = (unsigned long)(arg8); \
3009
+ _argvec[9] = (unsigned long)(arg9); \
3010
+ _argvec[10] = (unsigned long)(arg10); \
3011
+ _argvec[11] = (unsigned long)(arg11); \
3462
3012
  __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) \
3013
+ "ldr r0, [%1, #40] \n\t" \
3014
+ "ldr r1, [%1, #44] \n\t" \
3015
+ "push {r0, r1} \n\t" \
3016
+ "ldr r0, [%1, #20] \n\t" \
3017
+ "ldr r1, [%1, #24] \n\t" \
3018
+ "ldr r2, [%1, #28] \n\t" \
3019
+ "ldr r3, [%1, #32] \n\t" \
3020
+ "ldr r4, [%1, #36] \n\t" \
3021
+ "push {r0, r1, r2, r3, r4} \n\t" \
3022
+ "ldr r0, [%1, #4] \n\t" \
3023
+ "ldr r1, [%1, #8] \n\t" \
3024
+ "ldr r2, [%1, #12] \n\t" \
3025
+ "ldr r3, [%1, #16] \n\t" \
3026
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
3027
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3028
+ "add sp, sp, #28 \n\t" \
3029
+ "mov %0, r0" \
3493
3030
  : /*out*/ "=r" (_res) \
3494
- : /*in*/ "r" (&_argvec[2]) \
3495
- : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3031
+ : /*in*/ "0" (&_argvec[0]) \
3032
+ : /*trash*/ "cc", "memory",__CALLER_SAVED_REGS \
3496
3033
  ); \
3497
3034
  lval = (__typeof__(lval)) _res; \
3498
3035
  } while (0)
3499
3036
 
3500
- #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5,arg6, \
3501
- arg7,arg8,arg9,arg10,arg11,arg12) \
3037
+ #define CALL_FN_W_12W(lval, orig, arg1,arg2,arg3,arg4,arg5, \
3038
+ arg6,arg7,arg8,arg9,arg10, \
3039
+ arg11,arg12) \
3502
3040
  do { \
3503
3041
  volatile OrigFn _orig = (orig); \
3504
- volatile unsigned long _argvec[3+12]; \
3042
+ volatile unsigned long _argvec[13]; \
3505
3043
  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; \
3044
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3045
+ _argvec[1] = (unsigned long)(arg1); \
3046
+ _argvec[2] = (unsigned long)(arg2); \
3047
+ _argvec[3] = (unsigned long)(arg3); \
3048
+ _argvec[4] = (unsigned long)(arg4); \
3049
+ _argvec[5] = (unsigned long)(arg5); \
3050
+ _argvec[6] = (unsigned long)(arg6); \
3051
+ _argvec[7] = (unsigned long)(arg7); \
3052
+ _argvec[8] = (unsigned long)(arg8); \
3053
+ _argvec[9] = (unsigned long)(arg9); \
3054
+ _argvec[10] = (unsigned long)(arg10); \
3055
+ _argvec[11] = (unsigned long)(arg11); \
3056
+ _argvec[12] = (unsigned long)(arg12); \
3521
3057
  __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) \
3058
+ "ldr r0, [%1, #40] \n\t" \
3059
+ "ldr r1, [%1, #44] \n\t" \
3060
+ "ldr r2, [%1, #48] \n\t" \
3061
+ "push {r0, r1, r2} \n\t" \
3062
+ "ldr r0, [%1, #20] \n\t" \
3063
+ "ldr r1, [%1, #24] \n\t" \
3064
+ "ldr r2, [%1, #28] \n\t" \
3065
+ "ldr r3, [%1, #32] \n\t" \
3066
+ "ldr r4, [%1, #36] \n\t" \
3067
+ "push {r0, r1, r2, r3, r4} \n\t" \
3068
+ "ldr r0, [%1, #4] \n\t" \
3069
+ "ldr r1, [%1, #8] \n\t" \
3070
+ "ldr r2, [%1, #12] \n\t" \
3071
+ "ldr r3, [%1, #16] \n\t" \
3072
+ "ldr r4, [%1] \n\t" /* target->r4 */ \
3073
+ VALGRIND_BRANCH_AND_LINK_TO_NOREDIR_R4 \
3074
+ "add sp, sp, #32 \n\t" \
3075
+ "mov %0, r0" \
3555
3076
  : /*out*/ "=r" (_res) \
3556
- : /*in*/ "r" (&_argvec[2]) \
3077
+ : /*in*/ "0" (&_argvec[0]) \
3557
3078
  : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS \
3558
3079
  ); \
3559
3080
  lval = (__typeof__(lval)) _res; \
3560
3081
  } while (0)
3561
3082
 
3562
- #endif /* PLAT_ppc64_aix5 */
3083
+ #endif /* PLAT_arm_linux */
3084
+
3085
+ /* ------------------------- s390x-linux ------------------------- */
3086
+
3087
+ #if defined(PLAT_s390x_linux)
3088
+
3089
+ /* Similar workaround as amd64 (see above), but we use r11 as frame
3090
+ pointer and save the old r11 in r7. r11 might be used for
3091
+ argvec, therefore we copy argvec in r1 since r1 is clobbered
3092
+ after the call anyway. */
3093
+ #if defined(__GNUC__) && defined(__GCC_HAVE_DWARF2_CFI_ASM)
3094
+ # define __FRAME_POINTER \
3095
+ ,"d"(__builtin_dwarf_cfa())
3096
+ # define VALGRIND_CFI_PROLOGUE \
3097
+ ".cfi_remember_state\n\t" \
3098
+ "lgr 1,%1\n\t" /* copy the argvec pointer in r1 */ \
3099
+ "lgr 7,11\n\t" \
3100
+ "lgr 11,%2\n\t" \
3101
+ ".cfi_def_cfa r11, 0\n\t"
3102
+ # define VALGRIND_CFI_EPILOGUE \
3103
+ "lgr 11, 7\n\t" \
3104
+ ".cfi_restore_state\n\t"
3105
+ #else
3106
+ # define __FRAME_POINTER
3107
+ # define VALGRIND_CFI_PROLOGUE \
3108
+ "lgr 1,%1\n\t"
3109
+ # define VALGRIND_CFI_EPILOGUE
3110
+ #endif
3111
+
3112
+
3113
+
3114
+
3115
+ /* These regs are trashed by the hidden call. Note that we overwrite
3116
+ r14 in s390_irgen_noredir (VEX/priv/guest_s390_irgen.c) to give the
3117
+ function a proper return address. All others are ABI defined call
3118
+ clobbers. */
3119
+ #define __CALLER_SAVED_REGS "0","1","2","3","4","5","14", \
3120
+ "f0","f1","f2","f3","f4","f5","f6","f7"
3121
+
3122
+
3123
+ #define CALL_FN_W_v(lval, orig) \
3124
+ do { \
3125
+ volatile OrigFn _orig = (orig); \
3126
+ volatile unsigned long _argvec[1]; \
3127
+ volatile unsigned long _res; \
3128
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3129
+ __asm__ volatile( \
3130
+ VALGRIND_CFI_PROLOGUE \
3131
+ "aghi 15,-160\n\t" \
3132
+ "lg 1, 0(1)\n\t" /* target->r1 */ \
3133
+ VALGRIND_CALL_NOREDIR_R1 \
3134
+ "lgr %0, 2\n\t" \
3135
+ "aghi 15,160\n\t" \
3136
+ VALGRIND_CFI_EPILOGUE \
3137
+ : /*out*/ "=d" (_res) \
3138
+ : /*in*/ "d" (&_argvec[0]) __FRAME_POINTER \
3139
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3140
+ ); \
3141
+ lval = (__typeof__(lval)) _res; \
3142
+ } while (0)
3143
+
3144
+ /* The call abi has the arguments in r2-r6 and stack */
3145
+ #define CALL_FN_W_W(lval, orig, arg1) \
3146
+ do { \
3147
+ volatile OrigFn _orig = (orig); \
3148
+ volatile unsigned long _argvec[2]; \
3149
+ volatile unsigned long _res; \
3150
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3151
+ _argvec[1] = (unsigned long)arg1; \
3152
+ __asm__ volatile( \
3153
+ VALGRIND_CFI_PROLOGUE \
3154
+ "aghi 15,-160\n\t" \
3155
+ "lg 2, 8(1)\n\t" \
3156
+ "lg 1, 0(1)\n\t" \
3157
+ VALGRIND_CALL_NOREDIR_R1 \
3158
+ "lgr %0, 2\n\t" \
3159
+ "aghi 15,160\n\t" \
3160
+ VALGRIND_CFI_EPILOGUE \
3161
+ : /*out*/ "=d" (_res) \
3162
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3163
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3164
+ ); \
3165
+ lval = (__typeof__(lval)) _res; \
3166
+ } while (0)
3167
+
3168
+ #define CALL_FN_W_WW(lval, orig, arg1, arg2) \
3169
+ do { \
3170
+ volatile OrigFn _orig = (orig); \
3171
+ volatile unsigned long _argvec[3]; \
3172
+ volatile unsigned long _res; \
3173
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3174
+ _argvec[1] = (unsigned long)arg1; \
3175
+ _argvec[2] = (unsigned long)arg2; \
3176
+ __asm__ volatile( \
3177
+ VALGRIND_CFI_PROLOGUE \
3178
+ "aghi 15,-160\n\t" \
3179
+ "lg 2, 8(1)\n\t" \
3180
+ "lg 3,16(1)\n\t" \
3181
+ "lg 1, 0(1)\n\t" \
3182
+ VALGRIND_CALL_NOREDIR_R1 \
3183
+ "lgr %0, 2\n\t" \
3184
+ "aghi 15,160\n\t" \
3185
+ VALGRIND_CFI_EPILOGUE \
3186
+ : /*out*/ "=d" (_res) \
3187
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3188
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3189
+ ); \
3190
+ lval = (__typeof__(lval)) _res; \
3191
+ } while (0)
3192
+
3193
+ #define CALL_FN_W_WWW(lval, orig, arg1, arg2, arg3) \
3194
+ do { \
3195
+ volatile OrigFn _orig = (orig); \
3196
+ volatile unsigned long _argvec[4]; \
3197
+ volatile unsigned long _res; \
3198
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3199
+ _argvec[1] = (unsigned long)arg1; \
3200
+ _argvec[2] = (unsigned long)arg2; \
3201
+ _argvec[3] = (unsigned long)arg3; \
3202
+ __asm__ volatile( \
3203
+ VALGRIND_CFI_PROLOGUE \
3204
+ "aghi 15,-160\n\t" \
3205
+ "lg 2, 8(1)\n\t" \
3206
+ "lg 3,16(1)\n\t" \
3207
+ "lg 4,24(1)\n\t" \
3208
+ "lg 1, 0(1)\n\t" \
3209
+ VALGRIND_CALL_NOREDIR_R1 \
3210
+ "lgr %0, 2\n\t" \
3211
+ "aghi 15,160\n\t" \
3212
+ VALGRIND_CFI_EPILOGUE \
3213
+ : /*out*/ "=d" (_res) \
3214
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3215
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3216
+ ); \
3217
+ lval = (__typeof__(lval)) _res; \
3218
+ } while (0)
3219
+
3220
+ #define CALL_FN_W_WWWW(lval, orig, arg1, arg2, arg3, arg4) \
3221
+ do { \
3222
+ volatile OrigFn _orig = (orig); \
3223
+ volatile unsigned long _argvec[5]; \
3224
+ volatile unsigned long _res; \
3225
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3226
+ _argvec[1] = (unsigned long)arg1; \
3227
+ _argvec[2] = (unsigned long)arg2; \
3228
+ _argvec[3] = (unsigned long)arg3; \
3229
+ _argvec[4] = (unsigned long)arg4; \
3230
+ __asm__ volatile( \
3231
+ VALGRIND_CFI_PROLOGUE \
3232
+ "aghi 15,-160\n\t" \
3233
+ "lg 2, 8(1)\n\t" \
3234
+ "lg 3,16(1)\n\t" \
3235
+ "lg 4,24(1)\n\t" \
3236
+ "lg 5,32(1)\n\t" \
3237
+ "lg 1, 0(1)\n\t" \
3238
+ VALGRIND_CALL_NOREDIR_R1 \
3239
+ "lgr %0, 2\n\t" \
3240
+ "aghi 15,160\n\t" \
3241
+ VALGRIND_CFI_EPILOGUE \
3242
+ : /*out*/ "=d" (_res) \
3243
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3244
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"7" \
3245
+ ); \
3246
+ lval = (__typeof__(lval)) _res; \
3247
+ } while (0)
3248
+
3249
+ #define CALL_FN_W_5W(lval, orig, arg1, arg2, arg3, arg4, arg5) \
3250
+ do { \
3251
+ volatile OrigFn _orig = (orig); \
3252
+ volatile unsigned long _argvec[6]; \
3253
+ volatile unsigned long _res; \
3254
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3255
+ _argvec[1] = (unsigned long)arg1; \
3256
+ _argvec[2] = (unsigned long)arg2; \
3257
+ _argvec[3] = (unsigned long)arg3; \
3258
+ _argvec[4] = (unsigned long)arg4; \
3259
+ _argvec[5] = (unsigned long)arg5; \
3260
+ __asm__ volatile( \
3261
+ VALGRIND_CFI_PROLOGUE \
3262
+ "aghi 15,-160\n\t" \
3263
+ "lg 2, 8(1)\n\t" \
3264
+ "lg 3,16(1)\n\t" \
3265
+ "lg 4,24(1)\n\t" \
3266
+ "lg 5,32(1)\n\t" \
3267
+ "lg 6,40(1)\n\t" \
3268
+ "lg 1, 0(1)\n\t" \
3269
+ VALGRIND_CALL_NOREDIR_R1 \
3270
+ "lgr %0, 2\n\t" \
3271
+ "aghi 15,160\n\t" \
3272
+ VALGRIND_CFI_EPILOGUE \
3273
+ : /*out*/ "=d" (_res) \
3274
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3275
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3276
+ ); \
3277
+ lval = (__typeof__(lval)) _res; \
3278
+ } while (0)
3279
+
3280
+ #define CALL_FN_W_6W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3281
+ arg6) \
3282
+ do { \
3283
+ volatile OrigFn _orig = (orig); \
3284
+ volatile unsigned long _argvec[7]; \
3285
+ volatile unsigned long _res; \
3286
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3287
+ _argvec[1] = (unsigned long)arg1; \
3288
+ _argvec[2] = (unsigned long)arg2; \
3289
+ _argvec[3] = (unsigned long)arg3; \
3290
+ _argvec[4] = (unsigned long)arg4; \
3291
+ _argvec[5] = (unsigned long)arg5; \
3292
+ _argvec[6] = (unsigned long)arg6; \
3293
+ __asm__ volatile( \
3294
+ VALGRIND_CFI_PROLOGUE \
3295
+ "aghi 15,-168\n\t" \
3296
+ "lg 2, 8(1)\n\t" \
3297
+ "lg 3,16(1)\n\t" \
3298
+ "lg 4,24(1)\n\t" \
3299
+ "lg 5,32(1)\n\t" \
3300
+ "lg 6,40(1)\n\t" \
3301
+ "mvc 160(8,15), 48(1)\n\t" \
3302
+ "lg 1, 0(1)\n\t" \
3303
+ VALGRIND_CALL_NOREDIR_R1 \
3304
+ "lgr %0, 2\n\t" \
3305
+ "aghi 15,168\n\t" \
3306
+ VALGRIND_CFI_EPILOGUE \
3307
+ : /*out*/ "=d" (_res) \
3308
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3309
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3310
+ ); \
3311
+ lval = (__typeof__(lval)) _res; \
3312
+ } while (0)
3313
+
3314
+ #define CALL_FN_W_7W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3315
+ arg6, arg7) \
3316
+ do { \
3317
+ volatile OrigFn _orig = (orig); \
3318
+ volatile unsigned long _argvec[8]; \
3319
+ volatile unsigned long _res; \
3320
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3321
+ _argvec[1] = (unsigned long)arg1; \
3322
+ _argvec[2] = (unsigned long)arg2; \
3323
+ _argvec[3] = (unsigned long)arg3; \
3324
+ _argvec[4] = (unsigned long)arg4; \
3325
+ _argvec[5] = (unsigned long)arg5; \
3326
+ _argvec[6] = (unsigned long)arg6; \
3327
+ _argvec[7] = (unsigned long)arg7; \
3328
+ __asm__ volatile( \
3329
+ VALGRIND_CFI_PROLOGUE \
3330
+ "aghi 15,-176\n\t" \
3331
+ "lg 2, 8(1)\n\t" \
3332
+ "lg 3,16(1)\n\t" \
3333
+ "lg 4,24(1)\n\t" \
3334
+ "lg 5,32(1)\n\t" \
3335
+ "lg 6,40(1)\n\t" \
3336
+ "mvc 160(8,15), 48(1)\n\t" \
3337
+ "mvc 168(8,15), 56(1)\n\t" \
3338
+ "lg 1, 0(1)\n\t" \
3339
+ VALGRIND_CALL_NOREDIR_R1 \
3340
+ "lgr %0, 2\n\t" \
3341
+ "aghi 15,176\n\t" \
3342
+ VALGRIND_CFI_EPILOGUE \
3343
+ : /*out*/ "=d" (_res) \
3344
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3345
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3346
+ ); \
3347
+ lval = (__typeof__(lval)) _res; \
3348
+ } while (0)
3349
+
3350
+ #define CALL_FN_W_8W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3351
+ arg6, arg7 ,arg8) \
3352
+ do { \
3353
+ volatile OrigFn _orig = (orig); \
3354
+ volatile unsigned long _argvec[9]; \
3355
+ volatile unsigned long _res; \
3356
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3357
+ _argvec[1] = (unsigned long)arg1; \
3358
+ _argvec[2] = (unsigned long)arg2; \
3359
+ _argvec[3] = (unsigned long)arg3; \
3360
+ _argvec[4] = (unsigned long)arg4; \
3361
+ _argvec[5] = (unsigned long)arg5; \
3362
+ _argvec[6] = (unsigned long)arg6; \
3363
+ _argvec[7] = (unsigned long)arg7; \
3364
+ _argvec[8] = (unsigned long)arg8; \
3365
+ __asm__ volatile( \
3366
+ VALGRIND_CFI_PROLOGUE \
3367
+ "aghi 15,-184\n\t" \
3368
+ "lg 2, 8(1)\n\t" \
3369
+ "lg 3,16(1)\n\t" \
3370
+ "lg 4,24(1)\n\t" \
3371
+ "lg 5,32(1)\n\t" \
3372
+ "lg 6,40(1)\n\t" \
3373
+ "mvc 160(8,15), 48(1)\n\t" \
3374
+ "mvc 168(8,15), 56(1)\n\t" \
3375
+ "mvc 176(8,15), 64(1)\n\t" \
3376
+ "lg 1, 0(1)\n\t" \
3377
+ VALGRIND_CALL_NOREDIR_R1 \
3378
+ "lgr %0, 2\n\t" \
3379
+ "aghi 15,184\n\t" \
3380
+ VALGRIND_CFI_EPILOGUE \
3381
+ : /*out*/ "=d" (_res) \
3382
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3383
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3384
+ ); \
3385
+ lval = (__typeof__(lval)) _res; \
3386
+ } while (0)
3387
+
3388
+ #define CALL_FN_W_9W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3389
+ arg6, arg7 ,arg8, arg9) \
3390
+ do { \
3391
+ volatile OrigFn _orig = (orig); \
3392
+ volatile unsigned long _argvec[10]; \
3393
+ volatile unsigned long _res; \
3394
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3395
+ _argvec[1] = (unsigned long)arg1; \
3396
+ _argvec[2] = (unsigned long)arg2; \
3397
+ _argvec[3] = (unsigned long)arg3; \
3398
+ _argvec[4] = (unsigned long)arg4; \
3399
+ _argvec[5] = (unsigned long)arg5; \
3400
+ _argvec[6] = (unsigned long)arg6; \
3401
+ _argvec[7] = (unsigned long)arg7; \
3402
+ _argvec[8] = (unsigned long)arg8; \
3403
+ _argvec[9] = (unsigned long)arg9; \
3404
+ __asm__ volatile( \
3405
+ VALGRIND_CFI_PROLOGUE \
3406
+ "aghi 15,-192\n\t" \
3407
+ "lg 2, 8(1)\n\t" \
3408
+ "lg 3,16(1)\n\t" \
3409
+ "lg 4,24(1)\n\t" \
3410
+ "lg 5,32(1)\n\t" \
3411
+ "lg 6,40(1)\n\t" \
3412
+ "mvc 160(8,15), 48(1)\n\t" \
3413
+ "mvc 168(8,15), 56(1)\n\t" \
3414
+ "mvc 176(8,15), 64(1)\n\t" \
3415
+ "mvc 184(8,15), 72(1)\n\t" \
3416
+ "lg 1, 0(1)\n\t" \
3417
+ VALGRIND_CALL_NOREDIR_R1 \
3418
+ "lgr %0, 2\n\t" \
3419
+ "aghi 15,192\n\t" \
3420
+ VALGRIND_CFI_EPILOGUE \
3421
+ : /*out*/ "=d" (_res) \
3422
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3423
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3424
+ ); \
3425
+ lval = (__typeof__(lval)) _res; \
3426
+ } while (0)
3427
+
3428
+ #define CALL_FN_W_10W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3429
+ arg6, arg7 ,arg8, arg9, arg10) \
3430
+ do { \
3431
+ volatile OrigFn _orig = (orig); \
3432
+ volatile unsigned long _argvec[11]; \
3433
+ volatile unsigned long _res; \
3434
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3435
+ _argvec[1] = (unsigned long)arg1; \
3436
+ _argvec[2] = (unsigned long)arg2; \
3437
+ _argvec[3] = (unsigned long)arg3; \
3438
+ _argvec[4] = (unsigned long)arg4; \
3439
+ _argvec[5] = (unsigned long)arg5; \
3440
+ _argvec[6] = (unsigned long)arg6; \
3441
+ _argvec[7] = (unsigned long)arg7; \
3442
+ _argvec[8] = (unsigned long)arg8; \
3443
+ _argvec[9] = (unsigned long)arg9; \
3444
+ _argvec[10] = (unsigned long)arg10; \
3445
+ __asm__ volatile( \
3446
+ VALGRIND_CFI_PROLOGUE \
3447
+ "aghi 15,-200\n\t" \
3448
+ "lg 2, 8(1)\n\t" \
3449
+ "lg 3,16(1)\n\t" \
3450
+ "lg 4,24(1)\n\t" \
3451
+ "lg 5,32(1)\n\t" \
3452
+ "lg 6,40(1)\n\t" \
3453
+ "mvc 160(8,15), 48(1)\n\t" \
3454
+ "mvc 168(8,15), 56(1)\n\t" \
3455
+ "mvc 176(8,15), 64(1)\n\t" \
3456
+ "mvc 184(8,15), 72(1)\n\t" \
3457
+ "mvc 192(8,15), 80(1)\n\t" \
3458
+ "lg 1, 0(1)\n\t" \
3459
+ VALGRIND_CALL_NOREDIR_R1 \
3460
+ "lgr %0, 2\n\t" \
3461
+ "aghi 15,200\n\t" \
3462
+ VALGRIND_CFI_EPILOGUE \
3463
+ : /*out*/ "=d" (_res) \
3464
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3465
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3466
+ ); \
3467
+ lval = (__typeof__(lval)) _res; \
3468
+ } while (0)
3469
+
3470
+ #define CALL_FN_W_11W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3471
+ arg6, arg7 ,arg8, arg9, arg10, arg11) \
3472
+ do { \
3473
+ volatile OrigFn _orig = (orig); \
3474
+ volatile unsigned long _argvec[12]; \
3475
+ volatile unsigned long _res; \
3476
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3477
+ _argvec[1] = (unsigned long)arg1; \
3478
+ _argvec[2] = (unsigned long)arg2; \
3479
+ _argvec[3] = (unsigned long)arg3; \
3480
+ _argvec[4] = (unsigned long)arg4; \
3481
+ _argvec[5] = (unsigned long)arg5; \
3482
+ _argvec[6] = (unsigned long)arg6; \
3483
+ _argvec[7] = (unsigned long)arg7; \
3484
+ _argvec[8] = (unsigned long)arg8; \
3485
+ _argvec[9] = (unsigned long)arg9; \
3486
+ _argvec[10] = (unsigned long)arg10; \
3487
+ _argvec[11] = (unsigned long)arg11; \
3488
+ __asm__ volatile( \
3489
+ VALGRIND_CFI_PROLOGUE \
3490
+ "aghi 15,-208\n\t" \
3491
+ "lg 2, 8(1)\n\t" \
3492
+ "lg 3,16(1)\n\t" \
3493
+ "lg 4,24(1)\n\t" \
3494
+ "lg 5,32(1)\n\t" \
3495
+ "lg 6,40(1)\n\t" \
3496
+ "mvc 160(8,15), 48(1)\n\t" \
3497
+ "mvc 168(8,15), 56(1)\n\t" \
3498
+ "mvc 176(8,15), 64(1)\n\t" \
3499
+ "mvc 184(8,15), 72(1)\n\t" \
3500
+ "mvc 192(8,15), 80(1)\n\t" \
3501
+ "mvc 200(8,15), 88(1)\n\t" \
3502
+ "lg 1, 0(1)\n\t" \
3503
+ VALGRIND_CALL_NOREDIR_R1 \
3504
+ "lgr %0, 2\n\t" \
3505
+ "aghi 15,208\n\t" \
3506
+ VALGRIND_CFI_EPILOGUE \
3507
+ : /*out*/ "=d" (_res) \
3508
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3509
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3510
+ ); \
3511
+ lval = (__typeof__(lval)) _res; \
3512
+ } while (0)
3513
+
3514
+ #define CALL_FN_W_12W(lval, orig, arg1, arg2, arg3, arg4, arg5, \
3515
+ arg6, arg7 ,arg8, arg9, arg10, arg11, arg12)\
3516
+ do { \
3517
+ volatile OrigFn _orig = (orig); \
3518
+ volatile unsigned long _argvec[13]; \
3519
+ volatile unsigned long _res; \
3520
+ _argvec[0] = (unsigned long)_orig.nraddr; \
3521
+ _argvec[1] = (unsigned long)arg1; \
3522
+ _argvec[2] = (unsigned long)arg2; \
3523
+ _argvec[3] = (unsigned long)arg3; \
3524
+ _argvec[4] = (unsigned long)arg4; \
3525
+ _argvec[5] = (unsigned long)arg5; \
3526
+ _argvec[6] = (unsigned long)arg6; \
3527
+ _argvec[7] = (unsigned long)arg7; \
3528
+ _argvec[8] = (unsigned long)arg8; \
3529
+ _argvec[9] = (unsigned long)arg9; \
3530
+ _argvec[10] = (unsigned long)arg10; \
3531
+ _argvec[11] = (unsigned long)arg11; \
3532
+ _argvec[12] = (unsigned long)arg12; \
3533
+ __asm__ volatile( \
3534
+ VALGRIND_CFI_PROLOGUE \
3535
+ "aghi 15,-216\n\t" \
3536
+ "lg 2, 8(1)\n\t" \
3537
+ "lg 3,16(1)\n\t" \
3538
+ "lg 4,24(1)\n\t" \
3539
+ "lg 5,32(1)\n\t" \
3540
+ "lg 6,40(1)\n\t" \
3541
+ "mvc 160(8,15), 48(1)\n\t" \
3542
+ "mvc 168(8,15), 56(1)\n\t" \
3543
+ "mvc 176(8,15), 64(1)\n\t" \
3544
+ "mvc 184(8,15), 72(1)\n\t" \
3545
+ "mvc 192(8,15), 80(1)\n\t" \
3546
+ "mvc 200(8,15), 88(1)\n\t" \
3547
+ "mvc 208(8,15), 96(1)\n\t" \
3548
+ "lg 1, 0(1)\n\t" \
3549
+ VALGRIND_CALL_NOREDIR_R1 \
3550
+ "lgr %0, 2\n\t" \
3551
+ "aghi 15,216\n\t" \
3552
+ VALGRIND_CFI_EPILOGUE \
3553
+ : /*out*/ "=d" (_res) \
3554
+ : /*in*/ "a" (&_argvec[0]) __FRAME_POINTER \
3555
+ : /*trash*/ "cc", "memory", __CALLER_SAVED_REGS,"6","7" \
3556
+ ); \
3557
+ lval = (__typeof__(lval)) _res; \
3558
+ } while (0)
3559
+
3560
+
3561
+ #endif /* PLAT_s390x_linux */
3563
3562
 
3564
3563
 
3565
3564
  /* ------------------------------------------------------------------ */
@@ -3605,9 +3604,14 @@ typedef
3605
3604
  errors. */
3606
3605
  VG_USERREQ__COUNT_ERRORS = 0x1201,
3607
3606
 
3607
+ /* Allows a string (gdb monitor command) to be passed to the tool
3608
+ Used for interaction with vgdb/gdb */
3609
+ VG_USERREQ__GDB_MONITOR_COMMAND = 0x1202,
3610
+
3608
3611
  /* These are useful and can be interpreted by any tool that
3609
3612
  tracks malloc() et al, by using vg_replace_malloc.c. */
3610
3613
  VG_USERREQ__MALLOCLIKE_BLOCK = 0x1301,
3614
+ VG_USERREQ__RESIZEINPLACE_BLOCK = 0x130b,
3611
3615
  VG_USERREQ__FREELIKE_BLOCK = 0x1302,
3612
3616
  /* Memory pool support. */
3613
3617
  VG_USERREQ__CREATE_MEMPOOL = 0x1303,
@@ -3620,30 +3624,43 @@ typedef
3620
3624
  VG_USERREQ__MEMPOOL_EXISTS = 0x130a,
3621
3625
 
3622
3626
  /* Allow printfs to valgrind log. */
3627
+ /* The first two pass the va_list argument by value, which
3628
+ assumes it is the same size as or smaller than a UWord,
3629
+ which generally isn't the case. Hence are deprecated.
3630
+ The second two pass the vargs by reference and so are
3631
+ immune to this problem. */
3632
+ /* both :: char* fmt, va_list vargs (DEPRECATED) */
3623
3633
  VG_USERREQ__PRINTF = 0x1401,
3624
3634
  VG_USERREQ__PRINTF_BACKTRACE = 0x1402,
3635
+ /* both :: char* fmt, va_list* vargs */
3636
+ VG_USERREQ__PRINTF_VALIST_BY_REF = 0x1403,
3637
+ VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF = 0x1404,
3625
3638
 
3626
3639
  /* Stack support. */
3627
3640
  VG_USERREQ__STACK_REGISTER = 0x1501,
3628
3641
  VG_USERREQ__STACK_DEREGISTER = 0x1502,
3629
- VG_USERREQ__STACK_CHANGE = 0x1503
3642
+ VG_USERREQ__STACK_CHANGE = 0x1503,
3643
+
3644
+ /* Wine support */
3645
+ VG_USERREQ__LOAD_PDB_DEBUGINFO = 0x1601,
3646
+
3647
+ /* Querying of debug info. */
3648
+ VG_USERREQ__MAP_IP_TO_SRCLOC = 0x1701
3630
3649
  } Vg_ClientRequest;
3631
3650
 
3632
3651
  #if !defined(__GNUC__)
3633
3652
  # define __extension__ /* */
3634
3653
  #endif
3635
3654
 
3655
+
3636
3656
  /* Returns the number of Valgrinds this code is running under. That
3637
3657
  is, 0 if running natively, 1 if running under Valgrind, 2 if
3638
3658
  running under Valgrind which is running under another Valgrind,
3639
3659
  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
- })
3660
+ #define RUNNING_ON_VALGRIND \
3661
+ (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* if not */, \
3662
+ VG_USERREQ__RUNNING_ON_VALGRIND, \
3663
+ 0, 0, 0, 0, 0) \
3647
3664
 
3648
3665
 
3649
3666
  /* Discard translation of code in the range [_qzz_addr .. _qzz_addr +
@@ -3651,56 +3668,93 @@ typedef
3651
3668
  since it provides a way to make sure valgrind will retranslate the
3652
3669
  invalidated area. Returns no value. */
3653
3670
  #define VALGRIND_DISCARD_TRANSLATIONS(_qzz_addr,_qzz_len) \
3654
- {unsigned int _qzz_res; \
3655
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3671
+ (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3656
3672
  VG_USERREQ__DISCARD_TRANSLATIONS, \
3657
- _qzz_addr, _qzz_len, 0, 0, 0); \
3658
- }
3673
+ _qzz_addr, _qzz_len, 0, 0, 0)
3659
3674
 
3660
3675
 
3661
3676
  /* 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 */
3677
+ Possibly with a backtrace. This is a really ugly hack. The return value
3678
+ is the number of characters printed, excluding the "**<pid>** " part at the
3679
+ start and the backtrace (if present). */
3670
3680
 
3681
+ #if defined(__GNUC__) || defined(__INTEL_COMPILER)
3671
3682
  /* Modern GCC will optimize the static routine out if unused,
3672
3683
  and unused attribute will shut down warnings about it. */
3673
3684
  static int VALGRIND_PRINTF(const char *format, ...)
3674
3685
  __attribute__((format(__printf__, 1, 2), __unused__));
3686
+ #endif
3675
3687
  static int
3688
+ #if defined(_MSC_VER)
3689
+ __inline
3690
+ #endif
3676
3691
  VALGRIND_PRINTF(const char *format, ...)
3677
3692
  {
3693
+ #if defined(NVALGRIND)
3694
+ return 0;
3695
+ #else /* NVALGRIND */
3696
+ #if defined(_MSC_VER)
3697
+ uintptr_t _qzz_res;
3698
+ #else
3678
3699
  unsigned long _qzz_res;
3700
+ #endif
3679
3701
  va_list vargs;
3680
3702
  va_start(vargs, format);
3681
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF,
3682
- (unsigned long)format, (unsigned long)vargs,
3703
+ #if defined(_MSC_VER)
3704
+ _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3705
+ VG_USERREQ__PRINTF_VALIST_BY_REF,
3706
+ (uintptr_t)format,
3707
+ (uintptr_t)&vargs,
3708
+ 0, 0, 0);
3709
+ #else
3710
+ _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3711
+ VG_USERREQ__PRINTF_VALIST_BY_REF,
3712
+ (unsigned long)format,
3713
+ (unsigned long)&vargs,
3683
3714
  0, 0, 0);
3715
+ #endif
3684
3716
  va_end(vargs);
3685
3717
  return (int)_qzz_res;
3718
+ #endif /* NVALGRIND */
3686
3719
  }
3687
3720
 
3721
+ #if defined(__GNUC__) || defined(__INTEL_COMPILER)
3688
3722
  static int VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
3689
3723
  __attribute__((format(__printf__, 1, 2), __unused__));
3724
+ #endif
3690
3725
  static int
3726
+ #if defined(_MSC_VER)
3727
+ __inline
3728
+ #endif
3691
3729
  VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
3692
3730
  {
3731
+ #if defined(NVALGRIND)
3732
+ return 0;
3733
+ #else /* NVALGRIND */
3734
+ #if defined(_MSC_VER)
3735
+ uintptr_t _qzz_res;
3736
+ #else
3693
3737
  unsigned long _qzz_res;
3738
+ #endif
3694
3739
  va_list vargs;
3695
3740
  va_start(vargs, format);
3696
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, VG_USERREQ__PRINTF_BACKTRACE,
3697
- (unsigned long)format, (unsigned long)vargs,
3741
+ #if defined(_MSC_VER)
3742
+ _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3743
+ VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
3744
+ (uintptr_t)format,
3745
+ (uintptr_t)&vargs,
3746
+ 0, 0, 0);
3747
+ #else
3748
+ _qzz_res = VALGRIND_DO_CLIENT_REQUEST_EXPR(0,
3749
+ VG_USERREQ__PRINTF_BACKTRACE_VALIST_BY_REF,
3750
+ (unsigned long)format,
3751
+ (unsigned long)&vargs,
3698
3752
  0, 0, 0);
3753
+ #endif
3699
3754
  va_end(vargs);
3700
3755
  return (int)_qzz_res;
3701
- }
3702
-
3703
3756
  #endif /* NVALGRIND */
3757
+ }
3704
3758
 
3705
3759
 
3706
3760
  /* These requests allow control to move from the simulated CPU to the
@@ -3727,199 +3781,253 @@ VALGRIND_PRINTF_BACKTRACE(const char *format, ...)
3727
3781
  with a lot in the past.
3728
3782
  */
3729
3783
  #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
- })
3784
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
3785
+ VG_USERREQ__CLIENT_CALL0, \
3786
+ _qyy_fn, \
3787
+ 0, 0, 0, 0)
3788
+
3789
+ #define VALGRIND_NON_SIMD_CALL1(_qyy_fn, _qyy_arg1) \
3790
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
3791
+ VG_USERREQ__CLIENT_CALL1, \
3792
+ _qyy_fn, \
3793
+ _qyy_arg1, 0, 0, 0)
3794
+
3795
+ #define VALGRIND_NON_SIMD_CALL2(_qyy_fn, _qyy_arg1, _qyy_arg2) \
3796
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
3797
+ VG_USERREQ__CLIENT_CALL2, \
3798
+ _qyy_fn, \
3799
+ _qyy_arg1, _qyy_arg2, 0, 0)
3758
3800
 
3759
3801
  #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
- })
3802
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0 /* default return */, \
3803
+ VG_USERREQ__CLIENT_CALL3, \
3804
+ _qyy_fn, \
3805
+ _qyy_arg1, _qyy_arg2, \
3806
+ _qyy_arg3, 0)
3769
3807
 
3770
3808
 
3771
3809
  /* Counts the number of errors that have been recorded by a tool. Nb:
3772
3810
  the tool must record the errors with VG_(maybe_record_error)() or
3773
3811
  VG_(unique_error)() for them to be counted. */
3774
3812
  #define VALGRIND_COUNT_ERRORS \
3775
- __extension__ \
3776
- ({unsigned int _qyy_res; \
3777
- VALGRIND_DO_CLIENT_REQUEST(_qyy_res, 0 /* default return */, \
3813
+ (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR( \
3814
+ 0 /* default return */, \
3778
3815
  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.
3816
+ 0, 0, 0, 0, 0)
3817
+
3818
+ /* Several Valgrind tools (Memcheck, Massif, Helgrind, DRD) rely on knowing
3819
+ when heap blocks are allocated in order to give accurate results. This
3820
+ happens automatically for the standard allocator functions such as
3821
+ malloc(), calloc(), realloc(), memalign(), new, new[], free(), delete,
3822
+ delete[], etc.
3823
+
3824
+ But if your program uses a custom allocator, this doesn't automatically
3825
+ happen, and Valgrind will not do as well. For example, if you allocate
3826
+ superblocks with mmap() and then allocates chunks of the superblocks, all
3827
+ Valgrind's observations will be at the mmap() level and it won't know that
3828
+ the chunks should be considered separate entities. In Memcheck's case,
3829
+ that means you probably won't get heap block overrun detection (because
3830
+ there won't be redzones marked as unaddressable) and you definitely won't
3831
+ get any leak detection.
3832
+
3833
+ The following client requests allow a custom allocator to be annotated so
3834
+ that it can be handled accurately by Valgrind.
3835
+
3836
+ VALGRIND_MALLOCLIKE_BLOCK marks a region of memory as having been allocated
3837
+ by a malloc()-like function. For Memcheck (an illustrative case), this
3838
+ does two things:
3839
+
3840
+ - It records that the block has been allocated. This means any addresses
3841
+ within the block mentioned in error messages will be
3842
+ identified as belonging to the block. It also means that if the block
3843
+ isn't freed it will be detected by the leak checker.
3844
+
3845
+ - It marks the block as being addressable and undefined (if 'is_zeroed' is
3846
+ not set), or addressable and defined (if 'is_zeroed' is set). This
3847
+ controls how accesses to the block by the program are handled.
3790
3848
 
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. */
3849
+ 'addr' is the start of the usable block (ie. after any
3850
+ redzone), 'sizeB' is its size. 'rzB' is the redzone size if the allocator
3851
+ can apply redzones -- these are blocks of padding at the start and end of
3852
+ each block. Adding redzones is recommended as it makes it much more likely
3853
+ Valgrind will spot block overruns. `is_zeroed' indicates if the memory is
3854
+ zeroed (or filled with another predictable value), as is the case for
3855
+ calloc().
3856
+
3857
+ VALGRIND_MALLOCLIKE_BLOCK should be put immediately after the point where a
3858
+ heap block -- that will be used by the client program -- is allocated.
3859
+ It's best to put it at the outermost level of the allocator if possible;
3860
+ for example, if you have a function my_alloc() which calls
3861
+ internal_alloc(), and the client request is put inside internal_alloc(),
3862
+ stack traces relating to the heap block will contain entries for both
3863
+ my_alloc() and internal_alloc(), which is probably not what you want.
3864
+
3865
+ For Memcheck users: if you use VALGRIND_MALLOCLIKE_BLOCK to carve out
3866
+ custom blocks from within a heap block, B, that has been allocated with
3867
+ malloc/calloc/new/etc, then block B will be *ignored* during leak-checking
3868
+ -- the custom blocks will take precedence.
3869
+
3870
+ VALGRIND_FREELIKE_BLOCK is the partner to VALGRIND_MALLOCLIKE_BLOCK. For
3871
+ Memcheck, it does two things:
3872
+
3873
+ - It records that the block has been deallocated. This assumes that the
3874
+ block was annotated as having been allocated via
3875
+ VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued.
3876
+
3877
+ - It marks the block as being unaddressable.
3878
+
3879
+ VALGRIND_FREELIKE_BLOCK should be put immediately after the point where a
3880
+ heap block is deallocated.
3881
+
3882
+ VALGRIND_RESIZEINPLACE_BLOCK informs a tool about reallocation. For
3883
+ Memcheck, it does four things:
3884
+
3885
+ - It records that the size of a block has been changed. This assumes that
3886
+ the block was annotated as having been allocated via
3887
+ VALGRIND_MALLOCLIKE_BLOCK. Otherwise, an error will be issued.
3888
+
3889
+ - If the block shrunk, it marks the freed memory as being unaddressable.
3890
+
3891
+ - If the block grew, it marks the new area as undefined and defines a red
3892
+ zone past the end of the new block.
3893
+
3894
+ - The V-bits of the overlap between the old and the new block are preserved.
3895
+
3896
+ VALGRIND_RESIZEINPLACE_BLOCK should be put after allocation of the new block
3897
+ and before deallocation of the old block.
3898
+
3899
+ In many cases, these three client requests will not be enough to get your
3900
+ allocator working well with Memcheck. More specifically, if your allocator
3901
+ writes to freed blocks in any way then a VALGRIND_MAKE_MEM_UNDEFINED call
3902
+ will be necessary to mark the memory as addressable just before the zeroing
3903
+ occurs, otherwise you'll get a lot of invalid write errors. For example,
3904
+ you'll need to do this if your allocator recycles freed blocks, but it
3905
+ zeroes them before handing them back out (via VALGRIND_MALLOCLIKE_BLOCK).
3906
+ Alternatively, if your allocator reuses freed blocks for allocator-internal
3907
+ data structures, VALGRIND_MAKE_MEM_UNDEFINED calls will also be necessary.
3908
+
3909
+ Really, what's happening is a blurring of the lines between the client
3910
+ program and the allocator... after VALGRIND_FREELIKE_BLOCK is called, the
3911
+ memory should be considered unaddressable to the client program, but the
3912
+ allocator knows more than the rest of the client program and so may be able
3913
+ to safely access it. Extra client requests are necessary for Valgrind to
3914
+ understand the distinction between the allocator and the rest of the
3915
+ program.
3916
+
3917
+ Ignored if addr == 0.
3918
+ */
3808
3919
  #define VALGRIND_MALLOCLIKE_BLOCK(addr, sizeB, rzB, is_zeroed) \
3809
- {unsigned int _qzz_res; \
3810
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3920
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3811
3921
  VG_USERREQ__MALLOCLIKE_BLOCK, \
3812
- addr, sizeB, rzB, is_zeroed, 0); \
3813
- }
3922
+ addr, sizeB, rzB, is_zeroed, 0)
3923
+
3924
+ /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
3925
+ Ignored if addr == 0.
3926
+ */
3927
+ #define VALGRIND_RESIZEINPLACE_BLOCK(addr, oldSizeB, newSizeB, rzB) \
3928
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3929
+ VG_USERREQ__RESIZEINPLACE_BLOCK, \
3930
+ addr, oldSizeB, newSizeB, rzB, 0)
3814
3931
 
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. */
3932
+ /* See the comment for VALGRIND_MALLOCLIKE_BLOCK for details.
3933
+ Ignored if addr == 0.
3934
+ */
3819
3935
  #define VALGRIND_FREELIKE_BLOCK(addr, rzB) \
3820
- {unsigned int _qzz_res; \
3821
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3936
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3822
3937
  VG_USERREQ__FREELIKE_BLOCK, \
3823
- addr, rzB, 0, 0, 0); \
3824
- }
3938
+ addr, rzB, 0, 0, 0)
3825
3939
 
3826
3940
  /* Create a memory pool. */
3827
3941
  #define VALGRIND_CREATE_MEMPOOL(pool, rzB, is_zeroed) \
3828
- {unsigned int _qzz_res; \
3829
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3942
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3830
3943
  VG_USERREQ__CREATE_MEMPOOL, \
3831
- pool, rzB, is_zeroed, 0, 0); \
3832
- }
3944
+ pool, rzB, is_zeroed, 0, 0)
3833
3945
 
3834
3946
  /* Destroy a memory pool. */
3835
3947
  #define VALGRIND_DESTROY_MEMPOOL(pool) \
3836
- {unsigned int _qzz_res; \
3837
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3948
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3838
3949
  VG_USERREQ__DESTROY_MEMPOOL, \
3839
- pool, 0, 0, 0, 0); \
3840
- }
3950
+ pool, 0, 0, 0, 0)
3841
3951
 
3842
3952
  /* Associate a piece of memory with a memory pool. */
3843
3953
  #define VALGRIND_MEMPOOL_ALLOC(pool, addr, size) \
3844
- {unsigned int _qzz_res; \
3845
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3954
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3846
3955
  VG_USERREQ__MEMPOOL_ALLOC, \
3847
- pool, addr, size, 0, 0); \
3848
- }
3956
+ pool, addr, size, 0, 0)
3849
3957
 
3850
3958
  /* Disassociate a piece of memory from a memory pool. */
3851
3959
  #define VALGRIND_MEMPOOL_FREE(pool, addr) \
3852
- {unsigned int _qzz_res; \
3853
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3960
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3854
3961
  VG_USERREQ__MEMPOOL_FREE, \
3855
- pool, addr, 0, 0, 0); \
3856
- }
3962
+ pool, addr, 0, 0, 0)
3857
3963
 
3858
3964
  /* Disassociate any pieces outside a particular range. */
3859
3965
  #define VALGRIND_MEMPOOL_TRIM(pool, addr, size) \
3860
- {unsigned int _qzz_res; \
3861
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3966
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3862
3967
  VG_USERREQ__MEMPOOL_TRIM, \
3863
- pool, addr, size, 0, 0); \
3864
- }
3968
+ pool, addr, size, 0, 0)
3865
3969
 
3866
3970
  /* Resize and/or move a piece associated with a memory pool. */
3867
3971
  #define VALGRIND_MOVE_MEMPOOL(poolA, poolB) \
3868
- {unsigned int _qzz_res; \
3869
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3972
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3870
3973
  VG_USERREQ__MOVE_MEMPOOL, \
3871
- poolA, poolB, 0, 0, 0); \
3872
- }
3974
+ poolA, poolB, 0, 0, 0)
3873
3975
 
3874
3976
  /* Resize and/or move a piece associated with a memory pool. */
3875
3977
  #define VALGRIND_MEMPOOL_CHANGE(pool, addrA, addrB, size) \
3876
- {unsigned int _qzz_res; \
3877
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3978
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3878
3979
  VG_USERREQ__MEMPOOL_CHANGE, \
3879
- pool, addrA, addrB, size, 0); \
3880
- }
3980
+ pool, addrA, addrB, size, 0)
3881
3981
 
3882
3982
  /* Return 1 if a mempool exists, else 0. */
3883
3983
  #define VALGRIND_MEMPOOL_EXISTS(pool) \
3884
- ({unsigned int _qzz_res; \
3885
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3984
+ (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3886
3985
  VG_USERREQ__MEMPOOL_EXISTS, \
3887
- pool, 0, 0, 0, 0); \
3888
- _qzz_res; \
3889
- })
3986
+ pool, 0, 0, 0, 0)
3890
3987
 
3891
3988
  /* Mark a piece of memory as being a stack. Returns a stack id. */
3892
3989
  #define VALGRIND_STACK_REGISTER(start, end) \
3893
- ({unsigned int _qzz_res; \
3894
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3990
+ (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3895
3991
  VG_USERREQ__STACK_REGISTER, \
3896
- start, end, 0, 0, 0); \
3897
- _qzz_res; \
3898
- })
3992
+ start, end, 0, 0, 0)
3899
3993
 
3900
3994
  /* Unmark the piece of memory associated with a stack id as being a
3901
3995
  stack. */
3902
3996
  #define VALGRIND_STACK_DEREGISTER(id) \
3903
- {unsigned int _qzz_res; \
3904
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
3997
+ (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3905
3998
  VG_USERREQ__STACK_DEREGISTER, \
3906
- id, 0, 0, 0, 0); \
3907
- }
3999
+ id, 0, 0, 0, 0)
3908
4000
 
3909
4001
  /* Change the start and end address of the stack id. */
3910
4002
  #define VALGRIND_STACK_CHANGE(id, start, end) \
3911
- {unsigned int _qzz_res; \
3912
- VALGRIND_DO_CLIENT_REQUEST(_qzz_res, 0, \
4003
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
3913
4004
  VG_USERREQ__STACK_CHANGE, \
3914
- id, start, end, 0, 0); \
3915
- }
3916
-
3917
-
4005
+ id, start, end, 0, 0)
4006
+
4007
+ /* Load PDB debug info for Wine PE image_map. */
4008
+ #define VALGRIND_LOAD_PDB_DEBUGINFO(fd, ptr, total_size, delta) \
4009
+ VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
4010
+ VG_USERREQ__LOAD_PDB_DEBUGINFO, \
4011
+ fd, ptr, total_size, delta, 0)
4012
+
4013
+ /* Map a code address to a source file name and line number. buf64
4014
+ must point to a 64-byte buffer in the caller's address space. The
4015
+ result will be dumped in there and is guaranteed to be zero
4016
+ terminated. If no info is found, the first byte is set to zero. */
4017
+ #define VALGRIND_MAP_IP_TO_SRCLOC(addr, buf64) \
4018
+ (unsigned)VALGRIND_DO_CLIENT_REQUEST_EXPR(0, \
4019
+ VG_USERREQ__MAP_IP_TO_SRCLOC, \
4020
+ addr, buf64, 0, 0, 0)
4021
+
4022
+
4023
+ #undef PLAT_x86_darwin
4024
+ #undef PLAT_amd64_darwin
4025
+ #undef PLAT_x86_win32
3918
4026
  #undef PLAT_x86_linux
3919
4027
  #undef PLAT_amd64_linux
3920
4028
  #undef PLAT_ppc32_linux
3921
4029
  #undef PLAT_ppc64_linux
3922
- #undef PLAT_ppc32_aix5
3923
- #undef PLAT_ppc64_aix5
4030
+ #undef PLAT_arm_linux
4031
+ #undef PLAT_s390x_linux
3924
4032
 
3925
4033
  #endif /* __VALGRIND_H */