LINUX.ORG.RU
решено ФорумTalks

plasma^W opera не падает

 , , , ,


0

3

http://img6.imageshack.us/img6/6051/201306011733261366x768s.png
http://img211.imageshack.us/img211/659/1lk3.png
(Тут должна быть картинка нормально отрисованной Opera Mini. Но на неё смотреть скучно)

Суть: берётся пример bitmap-plasma из android-ndk, собирается под arm Opera Mini 7.5. Из готовой apk вытаскивается .so, в полуавтоматическом режиме разбирается на инструкции, из них генерируется набор «исходников» на C. Дальше это подсовывается компилятору из NDK, который собирает .so-шку для x86. so-шка вставляется в apk. Собранное приложение запускается в эмуляторе android'а, в котором крутится штатный образ для x86. Приложение (Plasma Opera Mini) работает и не падает. Но немного глючит подлагивает в mips-устройстве.

Радость.

★★★★★

Последнее исправление: i-rinat (всего исправлений: 2)

Ответ на: комментарий от snaf

Будешь продолжать?

Конечно. Препятствий полно и без юридических тонкостей.

i-rinat ★★★★★
() автор топика

Opera теперь тоже не падает, правда и не работает. Зацикливается на одних и тех же вызовах. С падениями было как-то проще.

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Теперь даже показывает простые странички, но портятся картинки. А код лезет в непонятные места. Надо разбираться релокациями в elf'ах.

http://img825.imageshack.us/img825/4559/bsr.png

i-rinat ★★★★★
() автор топика
Последнее исправление: i-rinat (всего исправлений: 1)

Попробовал собрать под целевое устройство. Выяснилось, что это все эти преобразования адресов жутко тормозят, пользоваться браузером невозможно. Возможно, какой-нибудь хитровыкрученный анализатор кода позволит избавиться от большинства этих преобразований, но делать его нереально долго. И вообще непонятно как.

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Остались странные глюки на jpeg изображениях

нашёл-таки ошибку в декодировании одной инструкции, теперь вроде с картинками всё в порядке. Осталось разобраться с тормозами.

i-rinat ★★★★★
() автор топика

Нереально круто. Сколько времени занимает реверс, дописывание, компиляция для эмуля и отладка одной либы, в сумме? Может быть когда-нибудь скайп с meego harmattan портируешь? :3 там и опера кстати есть...
он там простой, даже видеочата нет, и не падает совершенно... по сравнению с десктопным клиентом - рай, + умеет telepathy.

NeverLoved ★★★★★
()
Ответ на: комментарий от NeverLoved

Сколько времени занимает реверс, дописывание, компиляция для эмуля и отладка одной либы, в сумме?

Два месяца в сумме. (Плюс неизвестное пока время на оптимизации). Запуск готового рекомпилятора — примерно секунду, компиляция — 1-10 минут.

с meego harmattan

это же совершенно другое, другая ОС, другое API.

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Обратная разработка бинарника, затем компиляция в целевую архитектуру.

Как понимаю, получилось только потому, что опера писалась на языке довольно высокого уровня и поэтому проблем кода/данных и самомодифицирующегося кода не было?
Результат впечатляет!

GAMer ★★★★★
()
Ответ на: комментарий от GAMer

Как понимаю, получилось только потому, что опера писалась на языке довольно высокого уровня и поэтому проблем кода/данных и самомодифицирующегося кода не было?

Да, именно так. Код генерируется компилятором, который даже внутри соблюдает соглашения вызова и не делает хитрых трюков. Там ещё есть простор для оптимизаций, так что я не теряю надежды повысить скорость работы до приемлемой.

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Другая, полностью нативный линукс... Хотя да, тут сложней будет по идее. В опере в той же одна либа бинарная (остальное - ява), а тут вся программа - бинарь. Хрень сморозил, прошу простить :3

NeverLoved ★★★★★
()
Ответ на: комментарий от i-rinat

повысить скорость работы

<теоретически> А не выгоднее для этого не переводить бинарник в Си код, а попробовать декомпилировать в IR LLVM например? Может так вычистится больше мусора?

GAMer ★★★★★
()
Ответ на: комментарий от NeverLoved

Хотя да, тут сложней будет по идее.

Сложнее, потому что принципы GUI другие. Тут не обойдёшься простой трансляцией.

а тут вся программа - бинарь.

А это проще, как мне кажется. Организовать интерфейс с другими частями — проблема не меньшая, чем собственно рекомпиляция. В случае с библиотекой функция может вернуть хосту указатель на другую функцию. Для этого случая вторую надо будет оборачивать в прокси, который соглашения вызовов преобразовывает, а в первой вместо адреса второй подсовывать адрес прокси. В простом бинарнике можно просто за собой таскать все зависимости (исходники же есть).

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от GAMer

декомпилировать в IR LLVM например

Может быть.

У меня сейчас тормоза от того, что каждое чтение и каждая запись прогоняются через отдельные функции, которые проверяют, что за адрес им передали. Если адрес находится в .data или .bss, чтение-запись происходят оттуда, если нет, то чтение-запись по сырому адресу. Не знаю, настолько ли умный анализатор у LLVM, чтобы отслеживать и оптимизировать такое.

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Если адрес находится в .data или .bss, чтение-запись происходят оттуда, если нет, то чтение-запись по сырому адресу.

Я так высоко не соображаю уже, но разве все эти сегменты мапятся не в одно адресное пространство? Но если тут хитрее, то статической рекомпиляцией уже наверное не обойтись и надо будет делать динамическую - из одного и того же места чтение/запись должны идти на одинаковых условиях, поэтому функцию с проверками можно будет при первом её вызове из данного места убирать и заменять её на непосредственный код чтения/записи.

GAMer ★★★★★
()
Ответ на: комментарий от GAMer

но разве все эти сегменты мапятся не в одно адресное пространство?

В одно, более того, мапятся они вообще скопом. Беда в том, что .data и .bss находятся за .text, а .text сильно изменится — там же теперь другой код (и его больше).

делать динамическую

Это слишком сложно. Отладить такое я не смогу, это точно.

из одного и того же места чтение/запись должны идти на одинаковых условиях

Это не всегда так, например, в функцию могут передавать ссылку на структуру, которую надо заполнить. Часть вызовов может ссылаться на .bss, а часть на кучу.

Я думаю отслеживать значения регистров на этапе рекомпиляции. Тогда можно будет для большинства случаев определить, откуда ведётся адресация и таким образом решить, .bss это, стек или куча.

i-rinat ★★★★★
() автор топика
Ответ на: комментарий от i-rinat

Я думаю отслеживать значения регистров на этапе рекомпиляции. Тогда можно будет для большинства случаев определить, откуда ведётся адресация и таким образом решить, .bss это, стек или куча.

Оказалось, что я перемудрил и всё гораздо проще. Все адреса в .data и .bss вычисляются от r15, поэтому оказалось достаточно запихнуть весь libom.so в глобальный массив и отсчитывать r15 от начала этого массива. Тогда все чтения и записи могут быть прямыми и астрономический оверхед снимается. Сейчас на телефоне подлагивает, но листать страницы уже реально, не то что раньше.

Бинарник я выложил на https://github.com/i-rinat/mips-apk, если кому захочется попробовать.

i-rinat ★★★★★
() автор топика

Добавил вывод покрытия кода, обновил список функций для libom.so, поменял динамический вызов функций с линейного списка на большой switch-case (улучшилась отзывчивость), флаги и регистры кроме r0-r3 и r13 сделал локальными для функций (вроде ничего не поменялось), добавил ещё пару функций из JNIEnv и выкатил вторую альфа-версию.

Вышло вполне юзабельно, работает плавно.

i-rinat ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.