aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorpg <pg@yandex-team.com>2025-02-18 09:50:57 +0300
committerpg <pg@yandex-team.com>2025-02-18 10:14:31 +0300
commitd506a01f2c1668b2a6720099c110304f5b015765 (patch)
treed65a4fdc55ec2c30a4b77018f9886c8bcfd6ef9e /contrib
parentb9824e1dc11c30a60d6416b9d345758bc7901544 (diff)
downloadydb-d506a01f2c1668b2a6720099c110304f5b015765.tar.gz
refactor out py2 protobuf herobora after
commit_hash:8241ea2d9e5c3d12ca4c8902cdac23ed6630d4ce
Diffstat (limited to 'contrib')
-rw-r--r--contrib/libs/protobuf_old/protoherobora.py195
-rw-r--r--contrib/libs/protobuf_old/ya.make2
2 files changed, 197 insertions, 0 deletions
diff --git a/contrib/libs/protobuf_old/protoherobora.py b/contrib/libs/protobuf_old/protoherobora.py
new file mode 100644
index 0000000000..9b85a204bc
--- /dev/null
+++ b/contrib/libs/protobuf_old/protoherobora.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python3
+
+import subprocess
+import os
+import sys
+import json
+
+
+# TODO: dedup
+def is_cmdfile_arg(arg):
+ # type: (str) -> bool
+ return arg.startswith('@')
+
+
+def cmdfile_path(arg):
+ # type: (str) -> str
+ return arg[1:]
+
+
+def read_from_command_file(arg):
+ # type: (str) -> list[str]
+ with open(arg) as afile:
+ return afile.read().splitlines()
+
+
+def skip_markers(args):
+ # type: (list[str]) -> list[str]
+ res = []
+ for arg in args:
+ if arg == '--ya-start-command-file' or arg == '--ya-end-command-file':
+ continue
+ res.append(arg)
+ return res
+
+
+def iter_args(
+ args, # type: list[str]
+ ):
+ for arg in args:
+ if not is_cmdfile_arg(arg):
+ if arg == '--ya-start-command-file' or arg == '--ya-end-command-file':
+ continue
+ yield arg
+ else:
+ for cmdfile_arg in read_from_command_file(cmdfile_path(arg)):
+ yield cmdfile_arg
+
+
+def get_args(args):
+ # type: (list[str]) -> list[str]
+ return list(iter_args(args))
+# end TODO
+
+
+def run(*args):
+ return subprocess.check_output(list(args), shell=False).strip()
+
+
+def gen_renames_1(d):
+ for l in d.split('\n'):
+ l = l.strip()
+
+ if ' ' in l:
+ yield l.split(' ')[-1]
+
+
+def gen_renames_2(p, d):
+ for s in gen_renames_1(d):
+ """
+ Since clang-17, the option -fsanitize-address-globals-dead-stripping
+ has been enabled by default. Due to this, we have broken optimization
+ that merges calls to the `asan.module_ctor` function, as we are renaming
+ symbols with a prefix of 'py2_'. When this flag is enabled, and
+ the functions are not merged, false-positive ODR (One Definition Rule)
+ violations occur on objects such as `typeinfo std::exception`, because
+ the runtime is trying to handle global objects that have already been handled.
+ """
+ if 'asan_globals' in s:
+ continue
+ yield s + ' ' + p + s
+
+
+def gen_renames(p, d):
+ return '\n'.join(gen_renames_2(p, d)).strip() + '\n'
+
+
+def rename_syms(where, ret, libs):
+ p = 'py2_'
+
+ # join libs
+ run(where + 'llvm-ar', 'qcL', ret, *libs)
+
+ # find symbols to rename
+ syms = run(where + 'llvm-nm', '--extern-only', '--defined-only', '-A', ret)
+
+ # prepare rename plan
+ renames = gen_renames(p, syms)
+
+ with open('syms', 'w') as f:
+ f.write(renames)
+
+ # rename symbols
+ run(where + 'llvm-objcopy', '--redefine-syms=syms', ret)
+
+ # back-rename some symbols
+ args = [
+ where + 'llvm-objcopy',
+ '--redefine-sym',
+ p + 'init_api_implementation=init6google8protobuf8internal19_api_implementation',
+ '--redefine-sym',
+ p + 'init_message=init6google8protobuf5pyext8_message',
+ '--redefine-sym',
+ p + 'init6google8protobuf8internal19_api_implementation=init6google8protobuf8internal19_api_implementation',
+ '--redefine-sym',
+ p + 'init6google8protobuf5pyext8_message=init6google8protobuf5pyext8_message',
+ '--redefine-sym',
+ p + '_init6google8protobuf8internal19_api_implementation=_init6google8protobuf8internal19_api_implementation',
+ '--redefine-sym',
+ p + '_init6google8protobuf5pyext8_message=_init6google8protobuf5pyext8_message',
+ ret,
+ ]
+
+ run(*args)
+ return ret
+
+
+def find_lld(args):
+ for x in args:
+ if 'lld-link' in x:
+ return x
+
+ raise IndexError()
+
+
+def fix_py2(cmd, have_comand_files=False, prefix='lib', suffix='a'):
+ args = cmd
+
+ if have_comand_files:
+ args = get_args(cmd)
+
+ if 'protobuf_old' not in str(args):
+ return cmd
+
+ py2_libs = [prefix + 'contrib-libs-protobuf_old.' + suffix, prefix + 'pypython-protobuf-py2.' + suffix]
+
+ def need_rename(x):
+ for v in py2_libs:
+ if v in x:
+ return True
+
+ return False
+
+ old = []
+ lib = []
+
+ try:
+ where = os.path.dirname(cmd[cmd.index('--objcopy-exe') + 1]) + '/'
+ except ValueError:
+ where = os.path.dirname(find_lld(cmd)) + '/'
+
+ for x in args:
+ if need_rename(x):
+ lib.append(x)
+ else:
+ old.append(x)
+
+ name = rename_syms(where, 'libprotoherobora.' + suffix, lib)
+
+ if not have_comand_files:
+ return old + [name]
+
+ for file in cmd:
+ if is_cmdfile_arg(file):
+ cmd_file_path = cmdfile_path(file)
+ args = read_from_command_file(cmd_file_path)
+ if not 'protobuf_old' in str(args):
+ continue
+ with open(cmd_file_path, 'w') as afile:
+ for arg in args:
+ if not need_rename(arg):
+ afile.write(arg + '\n')
+ afile.write(name)
+
+ return cmd
+
+
+if __name__ == '__main__':
+ args = sys.argv[1:]
+
+ if 'lld-link' in str(args):
+ cmd = fix_py2(args, have_comand_files=True, prefix='', suffix='lib')
+ else:
+ cmd = fix_py2(args)
+
+ sys.stdout.write(json.dumps(cmd))
diff --git a/contrib/libs/protobuf_old/ya.make b/contrib/libs/protobuf_old/ya.make
index 50a3d8cd79..39f6a558a8 100644
--- a/contrib/libs/protobuf_old/ya.make
+++ b/contrib/libs/protobuf_old/ya.make
@@ -2,6 +2,8 @@
LIBRARY()
+LD_PLUGIN(protoherobora.py)
+
LICENSE(
BSD-3-Clause AND
Protobuf-License