Обратная отладка GDB AVX2

Итак, у меня есть новый модный процессор, который поддерживает набор команд avx2. Это здорово, но нарушает обратную отладку GDB. При компиляции без оптимизации код по-прежнему использует разделяемые библиотеки, например, вызывает memset(), которая затем запускается и вызывает оптимизированную для avx2 версию memset. Это здорово, но avx2 не поддерживается записью GDB.

запись процесса не поддерживает инструкцию 0xc5 по адресу 0x7ffff690dd80.

0xc5 здесь префикс vex.

обратная отладка прекрасно работает с процессором, который не поддерживает avx2. Как получить libc и т. Д., Чтобы не использовать оптимизированные для avx2 версии библиотечных вызовов, чтобы я мог использовать запись gdb, шаг назад и т. Д.?

я пробовал

LD_BIND_NOW=1
LD_HWCAP_MASK=0
compiling with -static

И если не считать отладку на старой машине, у меня нет идей.

1 ответ

Решение

Для вашего glibc 2.23, поставляемого на ubuntu 16.04 amd64, есть адаптация моего двоичного kludge (1-битный патч), сделанная точно по той же причине. пакет 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_common_indeces : if (cpu_features->max_cpuid >= 7) __cpuid_count (7, 0, ... звонил из __get_cpu_features, EAX=7 лист cpuid имеет всю информацию, необходимую для обнаружения поддержки AVX2 и включения ее, поэтому я просто пропустил фрагмент с cpuid eax=0x7,ecx=0 и сохранение его результатов в некоторых частях памяти путем изменения 0x7e 0x21 в 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.

Патч тупой и не используйте пропатченный файл глобально, если ваша корневая файловая система может быть запущена с ЦП без поддержки листьев eax=7 cpuid (до процессора Intel Core) или в виртуальной машине, эмулирующей такой процессор до Intel Core ( "Pentium D 8xx / 9xx ", Pentium 4, Pentium M - выйдет из строя).

Вы можете поместить пропатченный файл по пути, имя которого равно по длине или короче исходного пути /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, Затем используйте тот же hexeditor для замены строки "/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2" исполняемого файла вашей программы (ELF) в "/lib_x86_64-linux-gnu_ld-linux-noAVX2.so.2", или используйте инструмент patchelf из patchelf пакет:

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
Другие вопросы по тегам