对于在 ubuntu 16.04 amd64 上发布的 glibc 2.23,出于同样的原因,对 my binary kludge (1 bit patch) 进行了改编。包 libc6 (2.23-0ubuntu7) 是从 https://packages.ubuntu.com/xenial/amd64/libc6 下载的,文件 ld-2.23.so 已编辑(保留原始副本,或将补丁保存到不同的路径并更改您自己的二进制文件的 INTERP 部分以使用不同的路径):
83 3D 5B C9 20 00 06 cmpl $0x6, smth...
7E 21 jle some_forward_label
B8 07 00 00 00 mov $0x7, %eax
31 C9 xor %ecx,%ecx
0F A2 cpuid
从__get_cpu_features 调用了the get_common_indeces: if (cpu_features->max_cpuid >= 7) __cpuid_count (7, 0, ... 的代码。 EAX=7 leaf of cpuid has all info needed to detect AVX2 support and enable it,所以我只是跳过了带有cpuid eax=0x7,ecx=0 的片段,并通过更改0x7e 0x21 into 0x7f 0x21 将其结果保存到内存的某些部分。
因此,二进制补丁就像将83 3D xx xx xx xx 06 7E xx B8 07 00 00 00 31 C9 0F A2(其中xx 可以是任何字节)替换为83 3D xx xx xx xx 06 7F xx B8 07 00 00 00 31 C9 0F A2。您可以使用任何十六进制编辑器或一些二进制差异来执行此操作。在 2.23-0ubuntu7 中,此代码位于 0x0193B0 - 0x0193B9 是 7e 要更改为 7f。
如果您的 root fs 可能使用没有 eax=7 cpuid 叶支持的 CPU(前 Intel Core CPU)或在模拟此类 pre Intel Core CPU 的虚拟机中启动,则该补丁将变得愚蠢并且不要全局使用补丁文件(@987654326 @)。
您可以将修补文件放在与/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 的原始路径(符号链接到/lib/x86_64-linux-gnu/ld-2.23.so 文件)的长度相等或更短的路径中。例如/lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2。然后使用相同的十六进制编辑器将您的程序可执行文件(ELF)的字符串“/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2”替换为“/lib_x86_64-linux-gnu_ld-linux-noAVX2。 so.2",或者使用 patchelf 工具from the patchelf package:
cp /lib/x86_64-linux-gnu/ld-2.23.so /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
bless /lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2
# or any other hex editor
patchelf --set-interpreter /lib_x86_64-linux-gnu_ld-linux-no-AVX2.so.2 ./my_program