Я столкнулся с странной проблемой, несколько похожей на this. У меня есть собственный DLL-проект Windows Phone 8, в основном C++, но с источником сборки ARM. Источник находится в режиме ARM (то есть не Thumb). C++ скомпилирован в Thumb.Совместим с ARM (не Thumb) на WinPhone8?
Приложение аварийно завершает работу, когда C++ пытается вызвать процедуру сборки. Команда вызова при разборке представляет собой BLX с немедленным смещением - он должен переключать режим обратно на ARM, безоговорочно, но каким-то образом это не так.
У меня есть детали исключения. Код исключения - 0xc000001d (недопустимая операция), а значение ПК в структуре контекста crash равно 0x696d5985. Это невозможно в любом режиме - он смещен, бит равен нулю. Инструкция BLX идет 1b f0 0c eb
- если вы расшифровываете, это двухкомпонентный BLX-стиль в полном порядке, с 4-выровненным смещением. Флаг T в контексте сбоя - SET (CPSR = 0x60000010).
У меня нет устройства, но журнал сбоев из бета-тестера довольно убедительный. У меня есть запись журнала отладки прямо перед вызовом в сборку. Затем крушение.
EDIT: related. Они утверждают, однако, что сам ассемблер (armasm
) переводит ARM в Thumb. Это не относится ко мне - по крайней мере, не статически. DLL содержит соответствующий код ARM, как указано в источнике сборки (CODE32
).
EDIT: попробовал с несколько иной последовательности прыжков:
ldr r12, target
and r12, r12, #0xfffffffe ; To be sure
bx r12 ;BX to a register with a cleared 0th bit. Doesn't get any more explicit than that.
Тот же результат. Похоже, есть какой-то странный код, который происходит где-то в Магазине, или сама ОС ловит переключатели режимов и предотвращает их.
Модификацию кода можно, вероятно, обнаружить, сбросив части исполняемого файла в журнал сбоев вместе с остальными данными об аварии. Но что я могу сделать с помехами ОС, не доходя до полной кодовой базы до Thumb? Он не просто перекомпилирует.
EDIT для dwelch: последовательность вызова в скомпилированном коде C выглядит следующим образом:
.text:1000A35E MOV R2, #g_Host ;Three parameters
.text:1000A366 MOV R1, R5
.text:1000A368 MOV R0, R6
.text:1000A36A BLX Func ; Code bytes 1B F0 0C EB
BLX к немедленному адресу в режиме переключения. Это не условно, как bx register
. Мишень вызова является преобразователем:
.text:10025984 B Func_Impl
И адрес аварии этого преобразователь плюс один: 5985.
Это разборка скомпилированного DLL, но у меня нет никакой гарантии, что это именно то, что выполнение на устройстве. Пользователь в связанном потоке MSDN утверждал, что они посмотрели на дизассемблирование в отладчике и увидели Thumb, где должна была быть ARM. Microsoft, IIRC, имеет патент на изменение кода приложения на пути от издателя до устройства; это может быть причиной.
Включили ли вы все необходимые флаги взаимодействия при создании своей библиотеки и приложения? –
Их нет. И команда BLX предполагает, что toolchain знает, что происходит. –
hmmmmm .... Должно быть что-то мы не знаем. Правда, инструкции Thumb были очень ограничены, но Thumb2 - другое животное, даже более эффективное, чем режим ARM. Я думаю, что пришло время сбросить режим ARM и перейти на кодирование в режиме Thumb2. –