frida 16.2.0 → 16.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. package/BSDmakefile +6 -0
  2. package/Makefile +16 -0
  3. package/README.md +14 -11
  4. package/configure +18 -0
  5. package/configure.bat +22 -0
  6. package/dist/native.js +0 -8
  7. package/lib/application.ts +98 -0
  8. package/lib/authentication.ts +3 -0
  9. package/lib/build.py +50 -0
  10. package/lib/bus.ts +30 -0
  11. package/lib/cancellable.ts +33 -0
  12. package/lib/child.ts +15 -0
  13. package/lib/crash.ts +11 -0
  14. package/lib/device.ts +329 -0
  15. package/lib/device_manager.ts +69 -0
  16. package/lib/endpoint_parameters.ts +56 -0
  17. package/lib/icon.ts +15 -0
  18. package/lib/index.ts +311 -0
  19. package/lib/iostream.ts +78 -0
  20. package/lib/meson.build +53 -0
  21. package/lib/native.ts +9 -0
  22. package/lib/portal_membership.ts +10 -0
  23. package/lib/portal_service.ts +105 -0
  24. package/lib/process.ts +57 -0
  25. package/lib/relay.ts +44 -0
  26. package/lib/script.ts +352 -0
  27. package/lib/session.ts +113 -0
  28. package/lib/signals.ts +45 -0
  29. package/lib/socket_address.ts +35 -0
  30. package/lib/spawn.ts +4 -0
  31. package/lib/system_parameters.ts +78 -0
  32. package/make.bat +23 -0
  33. package/meson.build +160 -0
  34. package/meson.options +11 -0
  35. package/package.json +27 -6
  36. package/releng/deps.py +1133 -0
  37. package/releng/deps.toml +391 -0
  38. package/releng/devkit-assets/frida-core-example-unix.c +188 -0
  39. package/releng/devkit-assets/frida-core-example-windows.c +197 -0
  40. package/releng/devkit-assets/frida-core-example.sln +28 -0
  41. package/releng/devkit-assets/frida-core-example.vcxproj +157 -0
  42. package/releng/devkit-assets/frida-core-example.vcxproj.filters +27 -0
  43. package/releng/devkit-assets/frida-gum-example-unix.c +122 -0
  44. package/releng/devkit-assets/frida-gum-example-windows.c +132 -0
  45. package/releng/devkit-assets/frida-gum-example.sln +28 -0
  46. package/releng/devkit-assets/frida-gum-example.vcxproj +157 -0
  47. package/releng/devkit-assets/frida-gum-example.vcxproj.filters +27 -0
  48. package/releng/devkit-assets/frida-gumjs-example-unix.c +84 -0
  49. package/releng/devkit-assets/frida-gumjs-example-windows.c +91 -0
  50. package/releng/devkit-assets/frida-gumjs-example.sln +28 -0
  51. package/releng/devkit-assets/frida-gumjs-example.vcxproj +157 -0
  52. package/releng/devkit-assets/frida-gumjs-example.vcxproj.filters +27 -0
  53. package/releng/devkit.py +535 -0
  54. package/releng/env.py +420 -0
  55. package/releng/env_android.py +150 -0
  56. package/releng/env_apple.py +176 -0
  57. package/releng/env_generic.py +373 -0
  58. package/releng/frida_version.py +69 -0
  59. package/releng/machine_file.py +44 -0
  60. package/releng/machine_spec.py +290 -0
  61. package/releng/meson/meson.py +27 -0
  62. package/releng/meson/mesonbuild/__init__.py +0 -0
  63. package/releng/meson/mesonbuild/_pathlib.py +63 -0
  64. package/releng/meson/mesonbuild/_typing.py +69 -0
  65. package/releng/meson/mesonbuild/arglist.py +321 -0
  66. package/releng/meson/mesonbuild/ast/__init__.py +23 -0
  67. package/releng/meson/mesonbuild/ast/interpreter.py +441 -0
  68. package/releng/meson/mesonbuild/ast/introspection.py +374 -0
  69. package/releng/meson/mesonbuild/ast/postprocess.py +109 -0
  70. package/releng/meson/mesonbuild/ast/printer.py +620 -0
  71. package/releng/meson/mesonbuild/ast/visitor.py +161 -0
  72. package/releng/meson/mesonbuild/backend/__init__.py +0 -0
  73. package/releng/meson/mesonbuild/backend/backends.py +2047 -0
  74. package/releng/meson/mesonbuild/backend/ninjabackend.py +3808 -0
  75. package/releng/meson/mesonbuild/backend/nonebackend.py +26 -0
  76. package/releng/meson/mesonbuild/backend/vs2010backend.py +2078 -0
  77. package/releng/meson/mesonbuild/backend/vs2012backend.py +35 -0
  78. package/releng/meson/mesonbuild/backend/vs2013backend.py +34 -0
  79. package/releng/meson/mesonbuild/backend/vs2015backend.py +35 -0
  80. package/releng/meson/mesonbuild/backend/vs2017backend.py +59 -0
  81. package/releng/meson/mesonbuild/backend/vs2019backend.py +54 -0
  82. package/releng/meson/mesonbuild/backend/vs2022backend.py +54 -0
  83. package/releng/meson/mesonbuild/backend/xcodebackend.py +1781 -0
  84. package/releng/meson/mesonbuild/build.py +3249 -0
  85. package/releng/meson/mesonbuild/cargo/__init__.py +5 -0
  86. package/releng/meson/mesonbuild/cargo/builder.py +238 -0
  87. package/releng/meson/mesonbuild/cargo/cfg.py +274 -0
  88. package/releng/meson/mesonbuild/cargo/interpreter.py +733 -0
  89. package/releng/meson/mesonbuild/cargo/manifest.py +227 -0
  90. package/releng/meson/mesonbuild/cargo/version.py +95 -0
  91. package/releng/meson/mesonbuild/cmake/__init__.py +28 -0
  92. package/releng/meson/mesonbuild/cmake/common.py +331 -0
  93. package/releng/meson/mesonbuild/cmake/data/__init__.py +0 -0
  94. package/releng/meson/mesonbuild/cmake/data/preload.cmake +82 -0
  95. package/releng/meson/mesonbuild/cmake/executor.py +241 -0
  96. package/releng/meson/mesonbuild/cmake/fileapi.py +324 -0
  97. package/releng/meson/mesonbuild/cmake/generator.py +186 -0
  98. package/releng/meson/mesonbuild/cmake/interpreter.py +1267 -0
  99. package/releng/meson/mesonbuild/cmake/toolchain.py +248 -0
  100. package/releng/meson/mesonbuild/cmake/traceparser.py +814 -0
  101. package/releng/meson/mesonbuild/cmake/tracetargets.py +161 -0
  102. package/releng/meson/mesonbuild/compilers/__init__.py +86 -0
  103. package/releng/meson/mesonbuild/compilers/asm.py +307 -0
  104. package/releng/meson/mesonbuild/compilers/c.py +788 -0
  105. package/releng/meson/mesonbuild/compilers/c_function_attributes.py +143 -0
  106. package/releng/meson/mesonbuild/compilers/compilers.py +1388 -0
  107. package/releng/meson/mesonbuild/compilers/cpp.py +1035 -0
  108. package/releng/meson/mesonbuild/compilers/cs.py +136 -0
  109. package/releng/meson/mesonbuild/compilers/cuda.py +806 -0
  110. package/releng/meson/mesonbuild/compilers/cython.py +91 -0
  111. package/releng/meson/mesonbuild/compilers/d.py +861 -0
  112. package/releng/meson/mesonbuild/compilers/detect.py +1396 -0
  113. package/releng/meson/mesonbuild/compilers/fortran.py +523 -0
  114. package/releng/meson/mesonbuild/compilers/java.py +113 -0
  115. package/releng/meson/mesonbuild/compilers/mixins/__init__.py +0 -0
  116. package/releng/meson/mesonbuild/compilers/mixins/arm.py +167 -0
  117. package/releng/meson/mesonbuild/compilers/mixins/ccrx.py +113 -0
  118. package/releng/meson/mesonbuild/compilers/mixins/clang.py +170 -0
  119. package/releng/meson/mesonbuild/compilers/mixins/clike.py +1330 -0
  120. package/releng/meson/mesonbuild/compilers/mixins/compcert.py +117 -0
  121. package/releng/meson/mesonbuild/compilers/mixins/elbrus.py +93 -0
  122. package/releng/meson/mesonbuild/compilers/mixins/emscripten.py +89 -0
  123. package/releng/meson/mesonbuild/compilers/mixins/gnu.py +629 -0
  124. package/releng/meson/mesonbuild/compilers/mixins/intel.py +167 -0
  125. package/releng/meson/mesonbuild/compilers/mixins/islinker.py +120 -0
  126. package/releng/meson/mesonbuild/compilers/mixins/metrowerks.py +279 -0
  127. package/releng/meson/mesonbuild/compilers/mixins/pgi.py +88 -0
  128. package/releng/meson/mesonbuild/compilers/mixins/ti.py +130 -0
  129. package/releng/meson/mesonbuild/compilers/mixins/visualstudio.py +458 -0
  130. package/releng/meson/mesonbuild/compilers/mixins/xc16.py +111 -0
  131. package/releng/meson/mesonbuild/compilers/objc.py +120 -0
  132. package/releng/meson/mesonbuild/compilers/objcpp.py +102 -0
  133. package/releng/meson/mesonbuild/compilers/rust.py +230 -0
  134. package/releng/meson/mesonbuild/compilers/swift.py +131 -0
  135. package/releng/meson/mesonbuild/compilers/vala.py +121 -0
  136. package/releng/meson/mesonbuild/coredata.py +1532 -0
  137. package/releng/meson/mesonbuild/dependencies/__init__.py +252 -0
  138. package/releng/meson/mesonbuild/dependencies/base.py +663 -0
  139. package/releng/meson/mesonbuild/dependencies/boost.py +1083 -0
  140. package/releng/meson/mesonbuild/dependencies/cmake.py +656 -0
  141. package/releng/meson/mesonbuild/dependencies/coarrays.py +80 -0
  142. package/releng/meson/mesonbuild/dependencies/configtool.py +163 -0
  143. package/releng/meson/mesonbuild/dependencies/cuda.py +295 -0
  144. package/releng/meson/mesonbuild/dependencies/data/CMakeLists.txt +102 -0
  145. package/releng/meson/mesonbuild/dependencies/data/CMakeListsLLVM.txt +204 -0
  146. package/releng/meson/mesonbuild/dependencies/data/CMakePathInfo.txt +31 -0
  147. package/releng/meson/mesonbuild/dependencies/data/__init__.py +0 -0
  148. package/releng/meson/mesonbuild/dependencies/detect.py +225 -0
  149. package/releng/meson/mesonbuild/dependencies/dev.py +707 -0
  150. package/releng/meson/mesonbuild/dependencies/dub.py +424 -0
  151. package/releng/meson/mesonbuild/dependencies/factory.py +146 -0
  152. package/releng/meson/mesonbuild/dependencies/framework.py +111 -0
  153. package/releng/meson/mesonbuild/dependencies/hdf5.py +168 -0
  154. package/releng/meson/mesonbuild/dependencies/misc.py +618 -0
  155. package/releng/meson/mesonbuild/dependencies/mpi.py +231 -0
  156. package/releng/meson/mesonbuild/dependencies/pkgconfig.py +570 -0
  157. package/releng/meson/mesonbuild/dependencies/platform.py +52 -0
  158. package/releng/meson/mesonbuild/dependencies/python.py +431 -0
  159. package/releng/meson/mesonbuild/dependencies/qt.py +484 -0
  160. package/releng/meson/mesonbuild/dependencies/scalapack.py +142 -0
  161. package/releng/meson/mesonbuild/dependencies/ui.py +281 -0
  162. package/releng/meson/mesonbuild/depfile.py +82 -0
  163. package/releng/meson/mesonbuild/envconfig.py +480 -0
  164. package/releng/meson/mesonbuild/environment.py +987 -0
  165. package/releng/meson/mesonbuild/interpreter/__init__.py +47 -0
  166. package/releng/meson/mesonbuild/interpreter/compiler.py +900 -0
  167. package/releng/meson/mesonbuild/interpreter/dependencyfallbacks.py +386 -0
  168. package/releng/meson/mesonbuild/interpreter/interpreter.py +3595 -0
  169. package/releng/meson/mesonbuild/interpreter/interpreterobjects.py +1096 -0
  170. package/releng/meson/mesonbuild/interpreter/kwargs.py +479 -0
  171. package/releng/meson/mesonbuild/interpreter/mesonmain.py +487 -0
  172. package/releng/meson/mesonbuild/interpreter/primitives/__init__.py +29 -0
  173. package/releng/meson/mesonbuild/interpreter/primitives/array.py +108 -0
  174. package/releng/meson/mesonbuild/interpreter/primitives/boolean.py +52 -0
  175. package/releng/meson/mesonbuild/interpreter/primitives/dict.py +88 -0
  176. package/releng/meson/mesonbuild/interpreter/primitives/integer.py +86 -0
  177. package/releng/meson/mesonbuild/interpreter/primitives/range.py +38 -0
  178. package/releng/meson/mesonbuild/interpreter/primitives/string.py +247 -0
  179. package/releng/meson/mesonbuild/interpreter/type_checking.py +853 -0
  180. package/releng/meson/mesonbuild/interpreterbase/__init__.py +126 -0
  181. package/releng/meson/mesonbuild/interpreterbase/_unholder.py +25 -0
  182. package/releng/meson/mesonbuild/interpreterbase/baseobjects.py +174 -0
  183. package/releng/meson/mesonbuild/interpreterbase/decorators.py +806 -0
  184. package/releng/meson/mesonbuild/interpreterbase/disabler.py +35 -0
  185. package/releng/meson/mesonbuild/interpreterbase/exceptions.py +22 -0
  186. package/releng/meson/mesonbuild/interpreterbase/helpers.py +67 -0
  187. package/releng/meson/mesonbuild/interpreterbase/interpreterbase.py +665 -0
  188. package/releng/meson/mesonbuild/interpreterbase/operator.py +32 -0
  189. package/releng/meson/mesonbuild/linkers/__init__.py +20 -0
  190. package/releng/meson/mesonbuild/linkers/base.py +39 -0
  191. package/releng/meson/mesonbuild/linkers/detect.py +229 -0
  192. package/releng/meson/mesonbuild/linkers/linkers.py +1614 -0
  193. package/releng/meson/mesonbuild/mcompile.py +380 -0
  194. package/releng/meson/mesonbuild/mconf.py +368 -0
  195. package/releng/meson/mesonbuild/mdevenv.py +234 -0
  196. package/releng/meson/mesonbuild/mdist.py +376 -0
  197. package/releng/meson/mesonbuild/mesondata.py +38 -0
  198. package/releng/meson/mesonbuild/mesonlib.py +23 -0
  199. package/releng/meson/mesonbuild/mesonmain.py +289 -0
  200. package/releng/meson/mesonbuild/minit.py +204 -0
  201. package/releng/meson/mesonbuild/minstall.py +864 -0
  202. package/releng/meson/mesonbuild/mintro.py +667 -0
  203. package/releng/meson/mesonbuild/mlog.py +542 -0
  204. package/releng/meson/mesonbuild/modules/__init__.py +270 -0
  205. package/releng/meson/mesonbuild/modules/cmake.py +442 -0
  206. package/releng/meson/mesonbuild/modules/cuda.py +377 -0
  207. package/releng/meson/mesonbuild/modules/dlang.py +117 -0
  208. package/releng/meson/mesonbuild/modules/external_project.py +306 -0
  209. package/releng/meson/mesonbuild/modules/fs.py +323 -0
  210. package/releng/meson/mesonbuild/modules/gnome.py +2215 -0
  211. package/releng/meson/mesonbuild/modules/hotdoc.py +487 -0
  212. package/releng/meson/mesonbuild/modules/i18n.py +405 -0
  213. package/releng/meson/mesonbuild/modules/icestorm.py +123 -0
  214. package/releng/meson/mesonbuild/modules/java.py +112 -0
  215. package/releng/meson/mesonbuild/modules/keyval.py +65 -0
  216. package/releng/meson/mesonbuild/modules/modtest.py +33 -0
  217. package/releng/meson/mesonbuild/modules/pkgconfig.py +744 -0
  218. package/releng/meson/mesonbuild/modules/python.py +556 -0
  219. package/releng/meson/mesonbuild/modules/python3.py +85 -0
  220. package/releng/meson/mesonbuild/modules/qt.py +621 -0
  221. package/releng/meson/mesonbuild/modules/qt4.py +23 -0
  222. package/releng/meson/mesonbuild/modules/qt5.py +23 -0
  223. package/releng/meson/mesonbuild/modules/qt6.py +22 -0
  224. package/releng/meson/mesonbuild/modules/rust.py +355 -0
  225. package/releng/meson/mesonbuild/modules/simd.py +114 -0
  226. package/releng/meson/mesonbuild/modules/sourceset.py +291 -0
  227. package/releng/meson/mesonbuild/modules/wayland.py +151 -0
  228. package/releng/meson/mesonbuild/modules/windows.py +207 -0
  229. package/releng/meson/mesonbuild/mparser.py +1114 -0
  230. package/releng/meson/mesonbuild/msetup.py +365 -0
  231. package/releng/meson/mesonbuild/msubprojects.py +764 -0
  232. package/releng/meson/mesonbuild/mtest.py +2201 -0
  233. package/releng/meson/mesonbuild/munstable_coredata.py +107 -0
  234. package/releng/meson/mesonbuild/optinterpreter.py +276 -0
  235. package/releng/meson/mesonbuild/programs.py +367 -0
  236. package/releng/meson/mesonbuild/rewriter.py +1075 -0
  237. package/releng/meson/mesonbuild/scripts/__init__.py +10 -0
  238. package/releng/meson/mesonbuild/scripts/clangformat.py +55 -0
  239. package/releng/meson/mesonbuild/scripts/clangtidy.py +30 -0
  240. package/releng/meson/mesonbuild/scripts/cleantrees.py +35 -0
  241. package/releng/meson/mesonbuild/scripts/cmake_run_ctgt.py +103 -0
  242. package/releng/meson/mesonbuild/scripts/cmd_or_ps.ps1 +17 -0
  243. package/releng/meson/mesonbuild/scripts/copy.py +19 -0
  244. package/releng/meson/mesonbuild/scripts/coverage.py +214 -0
  245. package/releng/meson/mesonbuild/scripts/delwithsuffix.py +27 -0
  246. package/releng/meson/mesonbuild/scripts/depfixer.py +495 -0
  247. package/releng/meson/mesonbuild/scripts/depscan.py +198 -0
  248. package/releng/meson/mesonbuild/scripts/dirchanger.py +20 -0
  249. package/releng/meson/mesonbuild/scripts/env2mfile.py +402 -0
  250. package/releng/meson/mesonbuild/scripts/externalproject.py +106 -0
  251. package/releng/meson/mesonbuild/scripts/gettext.py +86 -0
  252. package/releng/meson/mesonbuild/scripts/gtkdochelper.py +286 -0
  253. package/releng/meson/mesonbuild/scripts/hotdochelper.py +40 -0
  254. package/releng/meson/mesonbuild/scripts/itstool.py +77 -0
  255. package/releng/meson/mesonbuild/scripts/meson_exe.py +115 -0
  256. package/releng/meson/mesonbuild/scripts/msgfmthelper.py +29 -0
  257. package/releng/meson/mesonbuild/scripts/pycompile.py +54 -0
  258. package/releng/meson/mesonbuild/scripts/python_info.py +121 -0
  259. package/releng/meson/mesonbuild/scripts/regen_checker.py +55 -0
  260. package/releng/meson/mesonbuild/scripts/run_tool.py +58 -0
  261. package/releng/meson/mesonbuild/scripts/scanbuild.py +57 -0
  262. package/releng/meson/mesonbuild/scripts/symbolextractor.py +322 -0
  263. package/releng/meson/mesonbuild/scripts/tags.py +44 -0
  264. package/releng/meson/mesonbuild/scripts/test_loaded_modules.py +14 -0
  265. package/releng/meson/mesonbuild/scripts/uninstall.py +41 -0
  266. package/releng/meson/mesonbuild/scripts/vcstagger.py +35 -0
  267. package/releng/meson/mesonbuild/scripts/yasm.py +24 -0
  268. package/releng/meson/mesonbuild/templates/__init__.py +0 -0
  269. package/releng/meson/mesonbuild/templates/cpptemplates.py +143 -0
  270. package/releng/meson/mesonbuild/templates/cstemplates.py +90 -0
  271. package/releng/meson/mesonbuild/templates/ctemplates.py +126 -0
  272. package/releng/meson/mesonbuild/templates/cudatemplates.py +143 -0
  273. package/releng/meson/mesonbuild/templates/dlangtemplates.py +109 -0
  274. package/releng/meson/mesonbuild/templates/fortrantemplates.py +101 -0
  275. package/releng/meson/mesonbuild/templates/javatemplates.py +94 -0
  276. package/releng/meson/mesonbuild/templates/mesontemplates.py +70 -0
  277. package/releng/meson/mesonbuild/templates/objcpptemplates.py +126 -0
  278. package/releng/meson/mesonbuild/templates/objctemplates.py +126 -0
  279. package/releng/meson/mesonbuild/templates/rusttemplates.py +79 -0
  280. package/releng/meson/mesonbuild/templates/samplefactory.py +41 -0
  281. package/releng/meson/mesonbuild/templates/sampleimpl.py +160 -0
  282. package/releng/meson/mesonbuild/templates/valatemplates.py +82 -0
  283. package/releng/meson/mesonbuild/utils/__init__.py +0 -0
  284. package/releng/meson/mesonbuild/utils/core.py +166 -0
  285. package/releng/meson/mesonbuild/utils/platform.py +27 -0
  286. package/releng/meson/mesonbuild/utils/posix.py +32 -0
  287. package/releng/meson/mesonbuild/utils/universal.py +2445 -0
  288. package/releng/meson/mesonbuild/utils/vsenv.py +126 -0
  289. package/releng/meson/mesonbuild/utils/win32.py +29 -0
  290. package/releng/meson/mesonbuild/wrap/__init__.py +59 -0
  291. package/releng/meson/mesonbuild/wrap/wrap.py +846 -0
  292. package/releng/meson/mesonbuild/wrap/wraptool.py +198 -0
  293. package/releng/meson-scripts/BSDmakefile +6 -0
  294. package/releng/meson-scripts/Makefile +16 -0
  295. package/releng/meson-scripts/configure +18 -0
  296. package/releng/meson-scripts/configure.bat +22 -0
  297. package/releng/meson-scripts/make.bat +23 -0
  298. package/releng/meson_configure.py +506 -0
  299. package/releng/meson_make.py +131 -0
  300. package/releng/mkdevkit.py +107 -0
  301. package/releng/mkfatmacho.py +54 -0
  302. package/releng/post-process-oabi.py +97 -0
  303. package/releng/progress.py +14 -0
  304. package/releng/sync-from-upstream.py +185 -0
  305. package/releng/tomlkit/tomlkit/__init__.py +59 -0
  306. package/releng/tomlkit/tomlkit/_compat.py +22 -0
  307. package/releng/tomlkit/tomlkit/_types.py +83 -0
  308. package/releng/tomlkit/tomlkit/_utils.py +158 -0
  309. package/releng/tomlkit/tomlkit/api.py +308 -0
  310. package/releng/tomlkit/tomlkit/container.py +875 -0
  311. package/releng/tomlkit/tomlkit/exceptions.py +227 -0
  312. package/releng/tomlkit/tomlkit/items.py +1967 -0
  313. package/releng/tomlkit/tomlkit/parser.py +1141 -0
  314. package/releng/tomlkit/tomlkit/py.typed +0 -0
  315. package/releng/tomlkit/tomlkit/source.py +180 -0
  316. package/releng/tomlkit/tomlkit/toml_char.py +52 -0
  317. package/releng/tomlkit/tomlkit/toml_document.py +7 -0
  318. package/releng/tomlkit/tomlkit/toml_file.py +58 -0
  319. package/releng/winenv.py +140 -0
  320. package/scripts/adjust-version.py +19 -0
  321. package/scripts/detect-version.py +40 -0
  322. package/scripts/fetch-abi-bits.py +343 -0
  323. package/scripts/install.js +23 -0
  324. package/scripts/package.py +15 -0
  325. package/src/addon.cc +76 -0
  326. package/src/application.cc +148 -0
  327. package/src/application.h +31 -0
  328. package/src/authentication.cc +174 -0
  329. package/src/authentication.h +24 -0
  330. package/src/bus.cc +167 -0
  331. package/src/bus.h +33 -0
  332. package/src/cancellable.cc +117 -0
  333. package/src/cancellable.h +31 -0
  334. package/src/child.cc +150 -0
  335. package/src/child.h +32 -0
  336. package/src/crash.cc +122 -0
  337. package/src/crash.h +30 -0
  338. package/src/device.cc +1302 -0
  339. package/src/device.h +55 -0
  340. package/src/device_manager.cc +362 -0
  341. package/src/device_manager.h +35 -0
  342. package/src/endpoint_parameters.cc +171 -0
  343. package/src/endpoint_parameters.h +28 -0
  344. package/src/glib_context.cc +62 -0
  345. package/src/glib_context.h +29 -0
  346. package/src/glib_object.cc +25 -0
  347. package/src/glib_object.h +37 -0
  348. package/src/iostream.cc +247 -0
  349. package/src/iostream.h +30 -0
  350. package/src/meson.build +26 -0
  351. package/src/operation.h +94 -0
  352. package/src/portal_membership.cc +100 -0
  353. package/src/portal_membership.h +26 -0
  354. package/src/portal_service.cc +401 -0
  355. package/src/portal_service.h +40 -0
  356. package/src/process.cc +135 -0
  357. package/src/process.h +30 -0
  358. package/src/relay.cc +139 -0
  359. package/src/relay.h +31 -0
  360. package/src/runtime.cc +443 -0
  361. package/src/runtime.h +64 -0
  362. package/src/script.cc +301 -0
  363. package/src/script.h +36 -0
  364. package/src/session.cc +860 -0
  365. package/src/session.h +42 -0
  366. package/src/signals.cc +334 -0
  367. package/src/signals.h +47 -0
  368. package/src/spawn.cc +95 -0
  369. package/src/spawn.h +27 -0
  370. package/src/usage_monitor.h +117 -0
  371. package/src/uv_context.cc +118 -0
  372. package/src/uv_context.h +40 -0
  373. package/src/win_delay_load_hook.cc +63 -0
  374. package/subprojects/frida-core.wrap +8 -0
  375. package/subprojects/nan.wrap +9 -0
  376. package/subprojects/packagefiles/nan.patch +13 -0
  377. package/test/data/index.ts +13 -0
  378. package/test/data/unixvictim-linux-x86 +0 -0
  379. package/test/data/unixvictim-linux-x86_64 +0 -0
  380. package/test/data/unixvictim-macos +0 -0
  381. package/test/device.ts +27 -0
  382. package/test/device_manager.ts +16 -0
  383. package/test/labrat.ts +32 -0
  384. package/test/script.ts +176 -0
  385. package/test/session.ts +73 -0
  386. package/tsconfig.json +18 -0
@@ -0,0 +1,535 @@
1
+ from collections import OrderedDict
2
+ import itertools
3
+ import os
4
+ from pathlib import Path
5
+ import re
6
+ import shlex
7
+ import shutil
8
+ import subprocess
9
+ import tempfile
10
+ from typing import Mapping, Sequence, Union
11
+
12
+ from . import env
13
+ from .machine_spec import MachineSpec
14
+
15
+
16
+ REPO_ROOT = Path(__file__).resolve().parent.parent
17
+
18
+ DEVKITS = {
19
+ "frida-gum": ("frida-gum-1.0", Path("gum") / "gum.h"),
20
+ "frida-gumjs": ("frida-gumjs-1.0", Path("gumjs") / "gumscriptbackend.h"),
21
+ "frida-core": ("frida-core-1.0", Path("frida-core.h")),
22
+ }
23
+
24
+ ASSETS_PATH = Path(__file__).parent / "devkit-assets"
25
+
26
+ INCLUDE_PATTERN = re.compile(r"#include\s+[<\"](.*?)[>\"]")
27
+
28
+
29
+ class CompilerApplication:
30
+ def __init__(self,
31
+ kit: str,
32
+ machine: MachineSpec,
33
+ meson_config: Mapping[str, Union[str, Sequence[str]]],
34
+ output_dir: Path):
35
+ self.kit = kit
36
+ package, umbrella_header = DEVKITS[kit]
37
+ self.package = package
38
+ self.umbrella_header = umbrella_header
39
+
40
+ self.machine = machine
41
+ self.meson_config = meson_config
42
+ self.compiler_argument_syntax = None
43
+ self.output_dir = output_dir
44
+ self.library_filename = None
45
+
46
+ def run(self):
47
+ output_dir = self.output_dir
48
+ kit = self.kit
49
+
50
+ self.compiler_argument_syntax = detect_compiler_argument_syntax(self.meson_config)
51
+ self.library_filename = compute_library_filename(self.kit, self.compiler_argument_syntax)
52
+
53
+ output_dir.mkdir(parents=True, exist_ok=True)
54
+
55
+ (extra_ldflags, thirdparty_symbol_mappings) = self._generate_library()
56
+
57
+ umbrella_header_path = compute_umbrella_header_path(self.machine,
58
+ self.package,
59
+ self.umbrella_header,
60
+ self.meson_config)
61
+
62
+ header_file = output_dir / f"{kit}.h"
63
+ if not umbrella_header_path.exists():
64
+ raise Exception(f"Header not found: {umbrella_header_path}")
65
+ header_source = self._generate_header(umbrella_header_path, thirdparty_symbol_mappings)
66
+ header_file.write_text(header_source, encoding="utf-8")
67
+
68
+ example_file = output_dir / f"{kit}-example.c"
69
+ example_source = self._generate_example(example_file, extra_ldflags)
70
+ example_file.write_text(example_source, encoding="utf-8")
71
+
72
+ extra_files = []
73
+
74
+ extra_files += self._generate_gir()
75
+
76
+ if self.compiler_argument_syntax == "msvc":
77
+ for msvs_asset in itertools.chain(ASSETS_PATH.glob(f"{kit}-*.sln"), ASSETS_PATH.glob(f"{kit}-*.vcxproj*")):
78
+ shutil.copy(msvs_asset, output_dir)
79
+ extra_files.append(msvs_asset.name)
80
+
81
+ return [header_file.name, self.library_filename, example_file.name] + extra_files
82
+
83
+ def _generate_gir(self):
84
+ if self.kit != "frida-core":
85
+ return []
86
+
87
+ gir_path = Path(query_pkgconfig_variable("frida_girdir", self.package, self.meson_config)) / "Frida-1.0.gir"
88
+ gir_name = "frida-core.gir"
89
+
90
+ shutil.copy(gir_path, self.output_dir / gir_name)
91
+
92
+ return [gir_name]
93
+
94
+ def _generate_header(self, umbrella_header_path, thirdparty_symbol_mappings):
95
+ kit = self.kit
96
+ package = self.package
97
+ machine = self.machine
98
+ meson_config = self.meson_config
99
+
100
+ c_args = meson_config.get("c_args", [])
101
+
102
+ include_cflags = query_pkgconfig_cflags(package, meson_config)
103
+
104
+ if self.compiler_argument_syntax == "msvc":
105
+ preprocessor = subprocess.run(meson_config["c"] + c_args + ["/nologo", "/E", umbrella_header_path] + include_cflags,
106
+ stdout=subprocess.PIPE,
107
+ stderr=subprocess.PIPE,
108
+ encoding="utf-8")
109
+ if preprocessor.returncode != 0:
110
+ raise Exception(f"Failed to spawn preprocessor: {preprocessor.stderr}")
111
+ lines = preprocessor.stdout.split("\n")
112
+
113
+ mapping_prefix = "#line "
114
+ header_refs = [line[line.index("\"") + 1:line.rindex("\"")].replace("\\\\", "/") for line in lines if line.startswith(mapping_prefix)]
115
+
116
+ header_files = deduplicate(header_refs)
117
+ frida_root_slashed = REPO_ROOT.as_posix()
118
+ header_files = [Path(h) for h in header_files if bool(re.match("^" + frida_root_slashed, h, re.I))]
119
+ else:
120
+ header_dependencies = subprocess.run(
121
+ meson_config["c"] + c_args + include_cflags + ["-E", "-M", umbrella_header_path],
122
+ capture_output=True,
123
+ encoding="utf-8",
124
+ check=True).stdout
125
+ _, raw_header_files = header_dependencies.split(": ", maxsplit=1)
126
+ header_files = [Path(item) for item in shlex.split(raw_header_files) if item != "\n"]
127
+ header_files = [h for h in header_files if h.is_relative_to(REPO_ROOT)]
128
+
129
+ devkit_header_lines = []
130
+ umbrella_header = header_files[0]
131
+ processed_header_files = {umbrella_header}
132
+ ingest_header(umbrella_header, header_files, processed_header_files, devkit_header_lines)
133
+ if kit == "frida-gumjs":
134
+ inspector_server_header = umbrella_header_path.parent / "guminspectorserver.h"
135
+ ingest_header(inspector_server_header, header_files, processed_header_files, devkit_header_lines)
136
+ if kit == "frida-core" and machine.os == "android":
137
+ selinux_header = umbrella_header_path.parent / "frida-selinux.h"
138
+ ingest_header(selinux_header, header_files, processed_header_files, devkit_header_lines)
139
+ devkit_header = u"".join(devkit_header_lines)
140
+
141
+ if package.startswith("frida-gumjs"):
142
+ config = """#ifndef GUM_STATIC
143
+ # define GUM_STATIC
144
+ #endif
145
+
146
+ """
147
+ else:
148
+ config = ""
149
+
150
+ if machine.os == "windows":
151
+ deps = ["dnsapi", "iphlpapi", "psapi", "shlwapi", "winmm", "ws2_32"]
152
+ if package == "frida-core-1.0":
153
+ deps.extend(["advapi32", "crypt32", "gdi32", "kernel32", "ole32", "secur32", "shell32", "user32"])
154
+ deps.sort()
155
+
156
+ frida_pragmas = f"#pragma comment(lib, \"{compute_library_filename(kit, self.compiler_argument_syntax)}\")"
157
+ dep_pragmas = "\n".join([f"#pragma comment(lib, \"{dep}.lib\")" for dep in deps])
158
+
159
+ config += f"#ifdef _MSC_VER\n\n{frida_pragmas}\n\n{dep_pragmas}\n\n#endif\n\n"
160
+
161
+ if len(thirdparty_symbol_mappings) > 0:
162
+ public_mappings = []
163
+ for original, renamed in extract_public_thirdparty_symbol_mappings(thirdparty_symbol_mappings):
164
+ public_mappings.append((original, renamed))
165
+ if f"define {original}" not in devkit_header and f"define {original}" not in devkit_header:
166
+ continue
167
+ def fixup_macro(match):
168
+ prefix = match.group(1)
169
+ suffix = re.sub(f"\\b{original}\\b", renamed, match.group(2))
170
+ return f"#undef {original}\n{prefix}{original}{suffix}"
171
+ devkit_header = re.sub(r"^([ \t]*#[ \t]*define[ \t]*){0}\b((.*\\\n)*.*)$".format(original), fixup_macro, devkit_header, flags=re.MULTILINE)
172
+
173
+ config += "#ifndef __FRIDA_SYMBOL_MAPPINGS__\n"
174
+ config += "#define __FRIDA_SYMBOL_MAPPINGS__\n\n"
175
+ config += "\n".join([f"#define {original} {renamed}" for original, renamed in public_mappings]) + "\n\n"
176
+ config += "#endif\n\n"
177
+
178
+ return (config + devkit_header).replace("\r\n", "\n")
179
+
180
+ def _generate_library(self):
181
+ library_flags = call_pkgconfig(["--static", "--libs", self.package], self.meson_config).split(" ")
182
+
183
+ library_dirs = infer_library_dirs(library_flags)
184
+ library_names = infer_library_names(library_flags)
185
+ library_paths, extra_flags = resolve_library_paths(library_names, library_dirs, self.machine)
186
+ extra_flags += infer_linker_flags(library_flags)
187
+
188
+ if self.compiler_argument_syntax == "msvc":
189
+ thirdparty_symbol_mappings = self._do_generate_library_msvc(library_paths)
190
+ else:
191
+ thirdparty_symbol_mappings = self._do_generate_library_unix(library_paths)
192
+
193
+ return (extra_flags, thirdparty_symbol_mappings)
194
+
195
+ def _do_generate_library_msvc(self, library_paths):
196
+ subprocess.run(self.meson_config["lib"] + ["/nologo", "/out:" + str(self.output_dir / self.library_filename)] + library_paths,
197
+ capture_output=True,
198
+ encoding="utf-8",
199
+ check=True)
200
+
201
+ thirdparty_symbol_mappings = []
202
+
203
+ return thirdparty_symbol_mappings
204
+
205
+ def _do_generate_library_unix(self, library_paths):
206
+ output_path = self.output_dir / self.library_filename
207
+ output_path.unlink(missing_ok=True)
208
+
209
+ v8_libs = [path for path in library_paths if path.name.startswith("libv8")]
210
+ if len(v8_libs) > 0:
211
+ v8_libdir = v8_libs[0].parent
212
+ libcxx_libs = list((v8_libdir / "c++").glob("*.a"))
213
+ library_paths.extend(libcxx_libs)
214
+
215
+ meson_config = self.meson_config
216
+
217
+ ar = meson_config.get("ar", ["ar"])
218
+ ar_help = subprocess.run(ar + ["--help"],
219
+ stdout=subprocess.PIPE,
220
+ stderr=subprocess.STDOUT,
221
+ encoding="utf-8").stdout
222
+ mri_supported = "-M [<mri-script]" in ar_help
223
+
224
+ if mri_supported:
225
+ mri = ["create " + str(output_path)]
226
+ mri += [f"addlib {path}" for path in library_paths]
227
+ mri += ["save", "end"]
228
+ subprocess.run(ar + ["-M"],
229
+ input="\n".join(mri),
230
+ encoding="utf-8",
231
+ check=True)
232
+ elif self.machine.is_apple:
233
+ subprocess.run(meson_config.get("libtool", ["xcrun", "libtool"]) +
234
+ ["-static", "-o", output_path] + library_paths,
235
+ capture_output=True,
236
+ check=True)
237
+ else:
238
+ combined_dir = Path(tempfile.mkdtemp(prefix="devkit"))
239
+ object_names = set()
240
+
241
+ for library_path in library_paths:
242
+ scratch_dir = Path(tempfile.mkdtemp(prefix="devkit"))
243
+
244
+ subprocess.run(ar + ["x", library_path],
245
+ cwd=scratch_dir,
246
+ capture_output=True,
247
+ check=True)
248
+ for object_name in [entry.name for entry in scratch_dir.iterdir() if entry.name.endswith(".o")]:
249
+ object_path = scratch_dir / object_name
250
+ while object_name in object_names:
251
+ object_name = "_" + object_name
252
+ object_names.add(object_name)
253
+ shutil.move(object_path, combined_dir / object_name)
254
+
255
+ shutil.rmtree(scratch_dir)
256
+
257
+ subprocess.run(ar + ["rcs", output_path] + list(object_names),
258
+ cwd=combined_dir,
259
+ capture_output=True,
260
+ check=True)
261
+
262
+ shutil.rmtree(combined_dir)
263
+
264
+ objcopy = meson_config.get("objcopy", None)
265
+ if objcopy is not None:
266
+ thirdparty_symbol_mappings = get_thirdparty_symbol_mappings(output_path, meson_config)
267
+
268
+ renames = "\n".join([f"{original} {renamed}" for original, renamed in thirdparty_symbol_mappings]) + "\n"
269
+ with tempfile.NamedTemporaryFile() as renames_file:
270
+ renames_file.write(renames.encode("utf-8"))
271
+ renames_file.flush()
272
+ subprocess.run(objcopy + ["--redefine-syms=" + renames_file.name, output_path],
273
+ check=True)
274
+ else:
275
+ thirdparty_symbol_mappings = []
276
+
277
+ return thirdparty_symbol_mappings
278
+
279
+ def _generate_example(self, source_file, extra_ldflags):
280
+ kit = self.kit
281
+ machine = self.machine
282
+
283
+ os_flavor = "windows" if machine.os == "windows" else "unix"
284
+
285
+ example_code = (ASSETS_PATH / f"{kit}-example-{os_flavor}.c").read_text(encoding="utf-8")
286
+
287
+ if machine.os == "windows":
288
+ return example_code
289
+ else:
290
+ if machine.is_apple or machine.os == "android":
291
+ cc = "clang++" if kit == "frida-gumjs" else "clang"
292
+ else:
293
+ cc = "g++" if kit == "frida-gumjs" else "gcc"
294
+ meson_config = self.meson_config
295
+ cflags = meson_config.get("common_flags", []) + meson_config.get("c_args", [])
296
+ ldflags = meson_config.get("c_link_args", [])
297
+
298
+ (cflags, ldflags) = tweak_flags(cflags, extra_ldflags + ldflags)
299
+
300
+ if cc == "g++":
301
+ ldflags.append("-static-libstdc++")
302
+
303
+ params = {
304
+ "cc": cc,
305
+ "cflags": shlex.join(cflags),
306
+ "ldflags": shlex.join(ldflags),
307
+ "source_filename": source_file.name,
308
+ "program_filename": source_file.stem,
309
+ "library_name": kit
310
+ }
311
+
312
+ preamble = """\
313
+ /*
314
+ * Compile with:
315
+ *
316
+ * %(cc)s %(cflags)s %(source_filename)s -o %(program_filename)s -L. -l%(library_name)s %(ldflags)s
317
+ *
318
+ * Visit https://frida.re to learn more about Frida.
319
+ */""" % params
320
+
321
+ return preamble + "\n\n" + example_code
322
+
323
+
324
+ def ingest_header(header, all_header_files, processed_header_files, result):
325
+ with header.open(encoding="utf-8") as f:
326
+ for line in f:
327
+ match = INCLUDE_PATTERN.match(line.strip())
328
+ if match is not None:
329
+ name_parts = tuple(match.group(1).split("/"))
330
+ num_parts = len(name_parts)
331
+ inline = False
332
+ for other_header in all_header_files:
333
+ if other_header.parts[-num_parts:] == name_parts:
334
+ inline = True
335
+ if other_header not in processed_header_files:
336
+ processed_header_files.add(other_header)
337
+ ingest_header(other_header, all_header_files, processed_header_files, result)
338
+ break
339
+ if not inline:
340
+ result.append(line)
341
+ else:
342
+ result.append(line)
343
+
344
+
345
+ def extract_public_thirdparty_symbol_mappings(mappings):
346
+ public_prefixes = ["g_", "glib_", "gobject_", "gio_", "gee_", "json_", "cs_"]
347
+ return [(original, renamed) for original, renamed in mappings if any([original.startswith(prefix) for prefix in public_prefixes])]
348
+
349
+
350
+ def get_thirdparty_symbol_mappings(library, meson_config):
351
+ return [(name, "_frida_" + name) for name in get_thirdparty_symbol_names(library, meson_config)]
352
+
353
+
354
+ def get_thirdparty_symbol_names(library, meson_config):
355
+ visible_names = list(set([name for kind, name in get_symbols(library, meson_config) if kind in ("T", "D", "B", "R", "C")]))
356
+ visible_names.sort()
357
+
358
+ frida_prefixes = ["frida", "_frida", "gum", "_gum"]
359
+ thirdparty_names = [name for name in visible_names if not any([name.startswith(prefix) for prefix in frida_prefixes])]
360
+
361
+ return thirdparty_names
362
+
363
+
364
+ def get_symbols(library, meson_config):
365
+ result = []
366
+
367
+ for line in subprocess.run(meson_config.get("nm", "nm") + [library],
368
+ capture_output=True,
369
+ encoding="utf-8",
370
+ check=True).stdout.split("\n"):
371
+ tokens = line.split(" ")
372
+ if len(tokens) < 3:
373
+ continue
374
+ (kind, name) = tokens[-2:]
375
+ result.append((kind, name))
376
+
377
+ return result
378
+
379
+
380
+ def infer_include_dirs(flags):
381
+ return [Path(flag[2:]) for flag in flags if flag.startswith("-I")]
382
+
383
+
384
+ def infer_library_dirs(flags):
385
+ return [Path(flag[2:]) for flag in flags if flag.startswith("-L")]
386
+
387
+
388
+ def infer_library_names(flags):
389
+ return [flag[2:] for flag in flags if flag.startswith("-l")]
390
+
391
+
392
+ def infer_linker_flags(flags):
393
+ return [flag for flag in flags if flag.startswith("-Wl") or flag == "-pthread"]
394
+
395
+
396
+ def resolve_library_paths(names, dirs, machine):
397
+ paths = []
398
+ flags = []
399
+ for name in names:
400
+ library_path = None
401
+ for d in dirs:
402
+ candidate = d / f"lib{name}.a"
403
+ if candidate.exists():
404
+ library_path = candidate
405
+ break
406
+ if library_path is not None and not is_os_library(library_path, machine):
407
+ paths.append(library_path)
408
+ else:
409
+ flags.append(f"-l{name}")
410
+ return (deduplicate(paths), flags)
411
+
412
+
413
+ def is_os_library(path, machine):
414
+ if machine.os == "linux":
415
+ return path.name in {"libdl.a", "libm.a", "libpthread.a"}
416
+ return False
417
+
418
+
419
+ def query_pkgconfig_cflags(package, meson_config):
420
+ raw_flags = call_pkgconfig(["--cflags", package], meson_config)
421
+ return shlex.split(raw_flags)
422
+
423
+
424
+ def query_pkgconfig_variable(name, package, meson_config):
425
+ return call_pkgconfig([f"--variable={name}", package], meson_config)
426
+
427
+
428
+ def call_pkgconfig(argv, meson_config):
429
+ pc_env = {
430
+ **os.environ,
431
+ "PKG_CONFIG_PATH": os.pathsep.join(meson_config.get("pkg_config_path", [])),
432
+ }
433
+ return subprocess.run(meson_config.get("pkg-config", ["pkg-config"]) + argv,
434
+ capture_output=True,
435
+ encoding="utf-8",
436
+ check=True,
437
+ env=pc_env).stdout.strip()
438
+
439
+
440
+ def detect_compiler_argument_syntax(meson_config):
441
+ if subprocess.run(meson_config["c"],
442
+ capture_output=True,
443
+ encoding="utf-8").stderr.startswith("Microsoft "):
444
+ return "msvc"
445
+
446
+ return "unix"
447
+
448
+
449
+ def compute_library_filename(kit, compiler_argument_syntax):
450
+ if compiler_argument_syntax == "msvc":
451
+ return f"{kit}.lib"
452
+ else:
453
+ return f"lib{kit}.a"
454
+
455
+
456
+ def compute_umbrella_header_path(machine, package, umbrella_header, meson_config):
457
+ for incdir in infer_include_dirs(query_pkgconfig_cflags(package, meson_config)):
458
+ candidate = (incdir / umbrella_header)
459
+ if candidate.exists():
460
+ return candidate
461
+ raise Exception(f"Unable to resolve umbrella header path for {umbrella_header}")
462
+
463
+
464
+ def tweak_flags(cflags, ldflags):
465
+ tweaked_cflags = []
466
+ tweaked_ldflags = []
467
+
468
+ pending_cflags = cflags[:]
469
+ while len(pending_cflags) > 0:
470
+ flag = pending_cflags.pop(0)
471
+ if flag == "-include":
472
+ pending_cflags.pop(0)
473
+ else:
474
+ tweaked_cflags.append(flag)
475
+
476
+ tweaked_cflags = deduplicate(tweaked_cflags)
477
+ existing_cflags = set(tweaked_cflags)
478
+
479
+ pending_ldflags = ldflags[:]
480
+ seen_libs = set()
481
+ seen_flags = set()
482
+ while len(pending_ldflags) > 0:
483
+ flag = pending_ldflags.pop(0)
484
+ if flag in ("-arch", "-isysroot") and flag in existing_cflags:
485
+ pending_ldflags.pop(0)
486
+ else:
487
+ if flag == "-isysroot":
488
+ sysroot = pending_ldflags.pop(0)
489
+ if "MacOSX" in sysroot:
490
+ tweaked_ldflags.append("-isysroot \"$(xcrun --sdk macosx --show-sdk-path)\"")
491
+ elif "iPhoneOS" in sysroot:
492
+ tweaked_ldflags.append("-isysroot \"$(xcrun --sdk iphoneos --show-sdk-path)\"")
493
+ continue
494
+ elif flag == "-L":
495
+ pending_ldflags.pop(0)
496
+ continue
497
+ elif flag.startswith("-L"):
498
+ continue
499
+ elif flag.startswith("-l"):
500
+ if flag in seen_libs:
501
+ continue
502
+ seen_libs.add(flag)
503
+ elif flag == "-pthread":
504
+ if flag in seen_flags:
505
+ continue
506
+ seen_flags.add(flag)
507
+ tweaked_ldflags.append(flag)
508
+
509
+ pending_ldflags = tweaked_ldflags
510
+ tweaked_ldflags = []
511
+ while len(pending_ldflags) > 0:
512
+ flag = pending_ldflags.pop(0)
513
+
514
+ raw_flags = []
515
+ while flag.startswith("-Wl,"):
516
+ raw_flags.append(flag[4:])
517
+ if len(pending_ldflags) > 0:
518
+ flag = pending_ldflags.pop(0)
519
+ else:
520
+ flag = None
521
+ break
522
+ if len(raw_flags) > 0:
523
+ merged_flags = "-Wl," + ",".join(raw_flags)
524
+ if "--icf=" in merged_flags:
525
+ tweaked_ldflags.append("-fuse-ld=gold")
526
+ tweaked_ldflags.append(merged_flags)
527
+
528
+ if flag is not None and flag not in existing_cflags:
529
+ tweaked_ldflags.append(flag)
530
+
531
+ return (tweaked_cflags, tweaked_ldflags)
532
+
533
+
534
+ def deduplicate(items):
535
+ return list(OrderedDict.fromkeys(items))