Какой код мог привести к генерации JAL в середину функции в MIPS бинарнике
От: overkrik  
Дата: 02.09.12 15:02
Оценка:
Приветствую,

имеется MIPS бинарник, исходный код на C, компилятор GNU C 2.9-что-то (версия где-то 96-98 года), платформа PSX.

В коде определена функция — декомпрессор LZ77 формата, состоящий из следующих блоков:

1. Аллокация памяти для несжатых данных
2. Помещение в регистры указателей на начало выделеной памяти и на начало сжатых данных
3. Собственно декомпрессия

В большинстве мест эта функция вызывается нормально, JAL'ом в начало пролога, но в одном месте в адресе вызова указано не начало, а адрес п.3, т.е. вызов происходит по следующему сценарию:

1. В регистры помещается адрес статического буффера и сжатых данных (т.е. пропускается этап аллокации внутри функции которая будет вызвана)
2. Вызов функции декомпрессии, но адрес вызова не в начало, а п.3

Я совершенно не понимаю, что такое могли написать оригинальные авторы кода, чтобы компилятор создал такой переход, тем более что во всех мануалах по MIPS которые я встречал чётко прописано что JAL должен быть совершён в начало пролога функции(хотя конечно никто не запрещает прописать любой адрес).

Что я попробовал:

1. Простое goto естественно не работает по причине области видимости меток.
2. longjmp/setjmp генерирует другой код, с явным вызовом этих функций.
3. Извращение со специфичным для GCC взятием указателя на метку создаёт похожий код, но всё-же вычисляет адрес куда прыгать, а не знает его уже заранее. Возможно, это я что-то делаю не так, но из-за особенности областей видимости сделать константный указатель на метку у меня не получается.

Что у меня пока не получается точно проверить такие теории:

1. Это какой-то очень хитрый инлайнинг.
2. Часть функции декомпрессии определена как макрос(например, но это пальцем в небо) и компилятор понял что этот код вставлен в два места и положил в бинарник его только один раз.
3. Ручками написанный asm в сишном исходнике, специально для этого случая.

Может быть кто-то встречал такое или может предложить что в C коде теоретически может к такому привести? Мне кажется, что в условиях сурового эмбеда авторы кода меньше всего хотели писать какие-то хитрые хаки ради вполне стандартной задачи, которую можно было решить просто разнесением функции декомпрессии на две, и это скорее всего оптимизация компилятора...
mips disassembly
Re: Какой код мог привести к генерации JAL в середину функции в MIPS бинарнике
От: sgenie  
Дата: 02.09.12 21:15
Оценка:
Первое (да сбоственно и единственное), что приходит в голову — оптимизация. Раз адрес известен заранее, значит компилятор его уже у себя в таблицы засунул.
Re: Какой код мог привести к генерации JAL в середину функции в MIPS бинарнике
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 03.09.12 04:11
Оценка:
Здравствуйте, overkrik, Вы писали:

O>Что у меня пока не получается точно проверить такие теории:

O>1. Это какой-то очень хитрый инлайнинг.

Это вероятнее всего. Проверяется снижением уровня оптимизации, явным запретом inline в опциях компиляции.

Учти ещё, что обычно высокие уровни оптимизации рассчитываются на ускорение по времени за счёт разбухания кода. Для ужатия кода нужна опция -Os.
The God is real, unless declared integer.
Re[2]: Какой код мог привести к генерации JAL в середину функции в MIPS бинарник
От: Erop Россия  
Дата: 03.09.12 07:27
Оценка:
Здравствуйте, netch80, Вы писали:

N>Учти ещё, что обычно высокие уровни оптимизации рассчитываются на ускорение по времени за счёт разбухания кода. Для ужатия кода нужна опция -Os.


Я так понимаю, что исходники недоступны. Были бы доступны, ТС просто посмотрел что написано в том странном месте висходниках...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: Какой код мог привести к генерации JAL в середину функции в MIPS бинарник
От: overkrik  
Дата: 03.09.12 07:37
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, netch80, Вы писали:


N>>Учти ещё, что обычно высокие уровни оптимизации рассчитываются на ускорение по времени за счёт разбухания кода. Для ужатия кода нужна опция -Os.


E>Я так понимаю, что исходники недоступны. Были бы доступны, ТС просто посмотрел что написано в том странном месте висходниках...


Исходники недоступны, иначе всё было-бы тривиально, поэтому и приходится выдумывать
Re[2]: Какой код мог привести к генерации JAL в середину функции в MIPS бинарник
От: overkrik  
Дата: 03.09.12 07:40
Оценка:
Здравствуйте, netch80, Вы писали:

N>Здравствуйте, overkrik, Вы писали:


O>>Что у меня пока не получается точно проверить такие теории:

O>>1. Это какой-то очень хитрый инлайнинг.

N>Это вероятнее всего. Проверяется снижением уровня оптимизации, явным запретом inline в опциях компиляции.


N>Учти ещё, что обычно высокие уровни оптимизации рассчитываются на ускорение по времени за счёт разбухания кода. Для ужатия кода нужна опция -Os.


У меня к сожалению нет исходника и в этом вся проблема, но за -Os спасибо, попробую посмотреть, что будет в бинарник попадать с моими тестами.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.