Ответ 1
Вам нужно отключить эту оптимизацию с помощью -fno-builtin. Однажды у меня возникла эта проблема при попытке скомпилировать memcpy для библиотеки C. Он называл себя. К сожалению,
В настоящее время я использую GCC 4.5.3, скомпилированный для PowerPC 440, и компилирую код, который не требует libc. У меня нет прямых вызовов memcpy(), но компилятор, кажется, вставляет его во время сборки.
Существуют такие параметры компоновщика, как -nostdlib, -nostartfiles, -nodefaultlibs, но я не могу их использовать, поскольку я не выполняю этап связывания. Я только компилирую. Что-то вроде этого:
$ powerpc-440-eabi-gcc -O2 -g -c -o output.o input.c
Если я проверяю output.o на nm, я вижу ссылку на memcpy:
$ powerpc-440-eabi-nm output.o | grep memcpy
U memcpy
$
Справочная страница GCC дает понять, как удалить вызовы memcpy и других вызовов libc с помощью компоновщика, но я не хочу, чтобы компилятор вставлял их в первую очередь, поскольку я использую совершенно другой компоновщик ( не GNU ld, и он не знает о libc).
Спасибо за любую помощь, которую вы можете предоставить.
Вам нужно отключить эту оптимизацию с помощью -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, и цель не реализует шаблон улавливания, тогда GCC испустит вызов для прерывания.
Нет необходимости в -fno-builtins
или -ffreestanding
, поскольку они будут излишне отключать многие важные оптимизации
Это фактически "оптимизировано" gcc tree-loop-distribute-patterns, поэтому, чтобы отключить нежелательное поведение, сохраняя полезные встроенные возможности, вы можете просто использовать:
-fno-tree-loop-distribute-patterns
Musl-libc использует этот флаг для своей сборки и имеет следующую заметку в своей конфигурации script (я просмотрел источник и не нашел никаких макросов, поэтому этого должно быть достаточно)
# Проверьте параметры, которые могут потребоваться, чтобы предотвратить компилятор от
# создание самореферентных версий memcpy, memmove, memcmp,
# и memset. Действительно, мы должны добавить проверку, чтобы определить, # достаточно, и если нет, добавьте макрос, чтобы нанести ущерб этим
# функции с изменчивой...
# tryflag CFLAGS_MEMOPS -fno-tree-loop-distribute-patterns
Вы также можете добавить это как атрибут к отдельным функциям в gcc, используя его атрибут optimize, так что другие функции могут выиграть от вызова mem*()
Вы также можете сделать свой двоичный файл "автономным":
Стандарт ISO C определяет (в разделе 4) два класса соответствующей реализации. Соответствующая размещенная реализация поддерживает весь стандарт [...]; соответствующая отдельно стоящая реализация требуется только для предоставления определенных библиотечных средств: тех, которые находятся в, и; начиная с AMD1, также и в; и в C99, также в и. [...].
Стандарт также определяет две среды для программ: автономную среду, требуемую для всех реализаций и которая может не иметь библиотечных средств, кроме тех, которые требуются для автономных реализаций, где обработка запуска и завершения программы определяется реализацией, и размещенная среда, которая не требуется, в котором предоставляются все возможности библиотеки, а запуск осуществляется через функцию int main (void) или int main (int, char * []).
Ядро ОС будет автономной средой; программа, использующая возможности операционной системы, обычно находится в размещенной реализации.
(параграф добавлен мной)
Подробнее здесь. И соответствующую опцию gcc/s (ключевые слова -ffreestanding
или -fno-builtin
) можно найти здесь.