Обходной путь доступа к памяти без выравнивания ARM - PullRequest
10 голосов
/ 25 февраля 2011

Мне нужно перенести исходный код с платформы ARM, на которой работает Linux. К сожалению, у меня возникли проблемы с выравниванием памяти. Источник использует приведение указателей и интенсивный доступ.

Код, подобный приведенному ниже, распространяется по кодовой базе как вирус. Я могу точно определить проблемные места благодаря опции командной строки gcc -Wcast-align, но есть более тысячи экземпляров.

u = (IEC_BOOL);
(((*(IEC_LINT*)pSP).H < b.H) 
   || (((*(IEC_LINT*)pSP).H == b.H) && ((*(IEC_LINT*)pSP).L < b.L) )) ? 1 : 0);
*(IEC_DWORD OS_SPTR *)pSP = 
    (IEC_DWORD)(*(IEC_DWORD OS_SPTR *)pSP >> u);  
*(IEC_DWORD OS_SPTR *)pSP = 
    (IEC_DWORD)(*(IEC_DWORD OS_SPTR *)pSP << -u);  
u = (IEC_BYTE)((*(IEC_DINT*)pSP != b) ? 1 : 0);  
*(IEC_DWORD*)pSP = (IEC_DWORD)(*(IEC_DWORD*)pSP & w);  
(*(IEC_ULINT*)pSP).H += u.H;   
(((*(IEC_ULINT OS_SPTR *)pSP).H == b.H) 
    && ((*(IEC_ULINT OS_SPTR *)pSP).L > b.L))) ? 1 : 0);
u = (IEC_BYTE)((*(IEC_REAL*)pSP >= b) ? 1 : 0);

Использование echo 2 > /proc/cpu/alignment on позволяет ядру Linux устранять проблемы, но производительность приложения снижается до уровня, который больше не является приемлемым.

Я искал в сети что-то похожее на ключевое слово __unaligned или __packed для компилятора GCC (v4.4.1), но пока еще пусто.

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

Ребята, есть ли у вас какие-либо предложения, как выполнить эту работу? Я думаю, что плагин компилятора gcc 4.5 был бы излишним, но есть ли что-то лучше, чем регулярные выражения? какие еще предложения вы можете придумать? Не обязательно все проблемные случаи должны быть исправлены, так как я все еще могу полагаться на Ядро для нескольких более редких случаев.

Ответы [ 3 ]

7 голосов
/ 25 февраля 2011

Существует __attribute__((__packed__)), который может помочь в некоторых случаях, но я действительно считаю, что этот код следует очистить скорее раньше, чем позже, потому что, скорее всего, вы потратите больше времени на решение проблем, чем на его устранение. раз и навсегда.

2 голосов
/ 26 февраля 2011

Ого, это безобразный беспорядок.Возиться с компилятором никуда не денется.Код недопустим на ВСЕХ архитектурах, но просто работает на некоторых (например, x86).Я бы исправил сам код.

К сожалению, нет красивого способа сделать это.Однако, вы могли бы пройти длинный путь с длинным списком поиска и замены, а затем вручную исправить все остальное.Я бы начал с удаления объявлений этих типов данных, поэтому, если вы скомпилируете любой пропущенный код, произойдет ошибка.Затем ищите и заменяйте фрагменты, такие как "* (IEC_DWORD OS_SPTR *) pSP =" with "set_dword (pSP," . Создайте встроенную функцию "set_dword", чтобы выполнитьПравильно. Продолжайте использовать столько легко заменяемых фрагментов, сколько вы можете себе представить. Все еще будет большое количество исправлений вручную.

Единственный другой способ сделать это - плагин компилятора, как вы предлагаете, и чтобы каждый указатель во всем модуле компиляции имел выравнивание 1. Затем компилятор будет загружать / хранить все байты. Вероятно, в конечном итоге это будет сделано не только для того кода, который вы намеревались.так легко достичь, как это звучит.

0 голосов
/ 25 февраля 2011

Мы можем предположить, что проблема возникла из-за того, что ARM является 32-битной машиной, а Linux-бокс работает в 64-битном режиме, в качестве альтернативы, код может предполагать, что он работает на 16-битной машине.

Одним из способов было бы посмотреть на базовую структуру, к которой осуществляется доступ. Элементы "H" и "L" могут быть 32-битными типами, к которым обращаются, как будто они 64-битные.

Попробуйте изменить типы L и H, чтобы код работал лучше.

(Предположительно, это удар в воздух, поскольку фрагмент кода не раскрывает подробности приложения или базовых структур.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...