spry
@spry

GCC, добавление кода в определенном месте делает программу нерабочей (изза размер кода видимо)?

Итак, имеем код для отладки того что происходит:
#define x86_emit_byte(value) \<br/>
 *translation_ptr = value; \<br/>
 translation_ptr++ \<br/>
<br/>
void function_cc x86_emit_translation_exit(p_u8 *p_translation_ptr)<br/>
{<br/>
 u8* translation_ptr = *p_translation_ptr;<br/>
 x86_emit_byte(0x90);<br/>
.... и так 100 строк...<br/>
 x86_emit_byte(0x90);<br/>
 *p_translation_ptr = translation_ptr;<br/>
}<br/>



Это кусок динамического транслятора, или же рекомпайлера. Изначально тут должен эмититься код размером около 100 байт, для теста представим что это все nop-ы. Так вот. Если емитить эти 100 байт вот так влоб, то транслятор перестает работать, не падает, просто перестает. По непонятным причинам. Если этот код заменить на цикл эмиттинга хоть килобайта nop-ов — все замечательно. Тоесть что зависит от размера самого транслятора а не кода что он эмитит. Обьектники транслятора относительно небольшие, до метра все 10 штук. Я уже 2 дня бьюсь над этим, но ничего пока не получается. Изначально транслятор не мой, я его редактирую, потому особо много рассказать не могу. Потому если что-то важное не уточнил, спрашивайте конечно. То что меня беспокоит — это одна функция которая вызывает этот кусок. Она размером в обьектнике около 0x70000 байт (о_О?). Уже не знаю на что грешить, поскольку транслятор не валится. Он просто перестает адекватно работать.
  • Вопрос задан
  • 2414 просмотров
Пригласить эксперта
Ответы на вопрос 4
@mt_
А если записать дефайн в одну строчку, заработает?
#define x86_emit_byte(value) *(translation_ptr++) = value;
Ответ написан
mraleph
@mraleph
Информации, конечно, маловато для осмысленного совета, но вот что бы я сделал:

0) для очистки совести и исключения бага gcc отключил бы оптимизации -O0, скорее всего проблема как была так и останется, и можно будет проглядеть неоптимизированный код этой функции и убедится, что гцц ничего не наврал;

1) вместо восьми nop (малейшее значение при котором перестает работать), выдал бы 7 nop и 1 int 3 (0xCC). или много-много int 3 и посмотрел кто на них наступает, на эти «нопы» и что там за ними следует, куда там потом управление после этих нопов должно попасть (может там мусор какой-то?)
Ответ написан
@Trotil
А указатель, передаваемый в функцию, на что именно указывает?
Он может занопить кусок какого-то кода, причём после затирание фрагмента определённой величины может не привести к плохим последствиям, а вот больше или меньше — уже вызовет проблему.
Ответ написан
@Trotil
Посмотрел.
Короче, вы записываете ассемблерные вставки по какому-то диапазону адресов *p_translation_ptr = 0x90, а затем зачем-то пихаете туда сам адрес последней инструкцией:

*p_translation_ptr = translation_ptr;

Получается какая-то неведомая ассемблерная инструкция (если скажите адрес, то можно будет наверное сказать — какая именно получается), в которой через каждые 128 проходов цикла инвертируется какой-то важный бит, в результате чего инструкция, сконструированная по адресу то прокатывает, то не прокатывает.

Извините, что если не так понял в коде — спать хочется.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы