Получение GCC для компиляции без вставки вызова memcpy

в настоящее время я использую GCC 4.5.3, скомпилированный для PowerPC 440, и компилирую некоторый код, который не требует libc. У меня нет прямых вызовов memcpy(), но компилятор, похоже, вставляет его во время сборки.

есть параметры компоновщика, такие как-nostdlib,- nostartfiles, - nodefaultlibs, но я не могу их использовать, поскольку я не делаю фазу связывания. Я только собираю материал. С чем-то вроде этого:

$ powerpc-440-eabi-gcc -O2 -g -c -o output.o input.c

Если я проверю выход.o с nm, я вижу a ссылка на функции memcpy:

$ powerpc-440-eabi-nm output.o | grep memcpy
     U memcpy
$ 

страница GCC man дает понять, как удалить вызовы memcpy и другие вызовы libc с помощью компоновщика, но я не хочу, чтобы компилятор вставлял их в первую очередь, поскольку я использую совершенно другой компоновщик (не LD GNU, и он не знает о libc).

Спасибо за любую помощь вы можете предоставить.

4 ответов


вам нужно отключить эту оптимизацию с помощью-fno-builtin. У меня была эта проблема однажды при попытке скомпилировать memcpy для библиотеки C. Он называл себя. Упс!


Gcc испускает вызов memcpy в некоторых обстоятельствах, например, если вы копируете структуру. Нет способа изменить поведение GCC, но вы можете попытаться избежать этого, изменив свой код, чтобы избежать такой копии. Лучше всего посмотреть на сборку, чтобы понять, почему gcc испустил memcpy и попытаться обойти его. Это будет раздражать, хотя, так как вам в основном нужно понять, как работает gcc.

выписка из http://gcc.gnu.org/onlinedocs/gcc/Standards.html:

большинство процедур поддержки компилятора, используемых GCC, присутствуют в libgcc, но есть несколько исключений. GCC требует, чтобы автономная среда предоставляла memcpy, memmove, memset и memcmp. Наконец, если_ _ builtin _ trap используется, и цель не реализует шаблон trap, то GCC выдаст вызов для прерывания.


вы также можете сделать свой двоичный файл "автономным":

стандарт ISO C определяет (в пункте 4) два класса соответствующей реализации. Соответствующая размещенная реализация поддерживает весь стандарт [...]; соответствующая автономная реализация требуется только для обеспечения определенных библиотечных объектов: те, в , , и ; начиная с AMD1, также те, в ; и в C99, также те, в и . [...].

стандарт также определяет два условия для программы, автономная среда, требуемая от всех реализаций и которая может не иметь библиотечных средств за пределами требуемых автономных реализаций, где обработка запуска и завершения программы определяется реализацией, и размещенная среда, которая не требуется, в которой все библиотечные средства предоставляются и запуск осуществляется через функцию int main (void) или int main (int, char *[]).

ядро ОС будет автономной средой; программа, использующая средства операционной системы, обычно находится в размещенной реализации.

(абзац введен мной)

больше здесь. И соответствующий параметр gcc / s (ключевые слова -freestanding или -fno-builtin) можно найти здесь.


не нужно -fno-builtins или -ffreestanding поскольку они будут излишне отключать многие важные оптимизации

это фактически "оптимизировано" шаблонами дерева-цикла-распределения gcc, поэтому, чтобы отключить нежелательное поведение, сохраняя полезные встроенные возможности, вы можете просто использовать:

-fno-tree-loop-distribute-patterns

Musl-libc использует этот флаг для своей сборки и имеет следующее примечание в своем скрипте настройки (я просмотрел источник и не нашел любые макросы, так это должны будет достаточно)

# проверьте параметры, которые могут потребоваться для предотвращения компилятора от
# создание самореферентных версий memcpy,, memmove, memcmp,
# и остановлюсь. Действительно, мы должны добавить проверку, чтобы определить, если это
# option достаточно, и если нет, добавьте макрос, чтобы искалечить эти
функции # с летучими...
# tryflag CFLAGS_MEMOPS - fno-tree-loop-distribute-patterns

вы также можете добавить это как атрибут к отдельным функциям в gcc, используя его атрибут optimize, чтобы другие функции могли извлечь выгоду из вызова mem*()