Jump to content
    

GCC и сложности LTO

Проверяю сборку своего проекта для STM32F4 с разным и ключами (уровни оптимизации и lto). Вариант '-Os -flto=auto' ломается со странной проблемой, при этом собираются и работают другие варианты, например '-O3 -flto=auto' или '-Os'.

Quote

/usr/libexec/gcc/armv7m-none-eabi/ld: /tmp/ccdBSkLl.ltrans1.ltrans.o: in function `tlm_reg_flush_line.constprop.0':
/home/amaora/devel/phobia/src/tlm.c:246: undefined reference to `memset'

В указанной строке вот это.

			if (reg->proc != NULL) {

				reg_t		lreg = { .link = &rval };

				reg->proc(&lreg, &rval, NULL);
			}

Ну захотелось компилятору сделать memset ну и ладно, он у меня есть и используется в других местах, например во freertos или usb стеке. Но в чем проблема? почему undefined reference когда есть такая функция?

void *memset(void *d, int c, size_t n)
{
	uint32_t	fill, *ld = (uint32_t *) d;

	if (((uint32_t) ld & 3U) == 0) {

		fill = (uint8_t) c;
		fill |= (fill << 8);
		fill |= (fill << 16);

		for (; n >= 4; n -= 4) {

			*ld++ = fill;
		}
	}

	{
		uint8_t		*bd = (uint8_t *) ld;

		for (; n >= 1; n -= 1) {

			*bd++ = (uint8_t) c;
		}
	}

	return d;
}

Непонятно, что именно он не нашёл. Весь проект только C, нет файлов C++.

Quote

$ armv7m-none-eabi-gcc --version
armv7m-none-eabi-gcc (Gentoo 13.2.1_p20230826 p7) 13.2.1 20230826

Вот здесь говорят, что надо собирать свой libc (где лежит код memset) без lto. Как-то вот так странно этот механизм построен, что среди обрабатываемых lto функций линкер не смотрит, а нужен уже скомпилированный код memset. Отучить вставлять libc вызовы туда где их не было, тоже похоже нельзя.

Share this post


Link to post
Share on other sites

memset() где определен? В отдельной уже собранной библиотеке?

Вот что говорит дока на ARM CLang

Цитата

Caution

Object files generated using the -flto option are not suitable for creating static libraries, or ROPI or RWPI images.

т.е. потенциальное переписывание библиотечных функций как раз запрещено при использовании LTO.

Share this post


Link to post
Share on other sites

__attribute__((used)) перед вашим мемсетом должен помочь, вроде бы

 

Share this post


Link to post
Share on other sites

13 часов назад, amaora сказал:

undefined reference to

Несколько лет назад пытался попробовать LTO - столкнулся с такой ошибкой практически во всех своих проектах (удавалось собрать с __attribute__((used)), но в каждом проекте в своих местах), поэтому надолго забил на LTO. Но недавно решил снова проверить с последней имеющейся у меня доступной версией gcc (arm-none-eabi-gcc (Arm GNU Toolchain 12.2.Rel1 (Build arm-12.24)) 12.2.1 20221205) и, о чудо, все мои проекты собрались. Какой версией собираете вы? Если не самая последняя - может стоит попробовать обновиться?

Share this post


Link to post
Share on other sites

12 hours ago, Arlleex said:

memset() где определен? В отдельной уже собранной библиотеке?

Нет отдельных библиотек, все исходники под LTO. Но сейчас пробую уже разные варианты.

 

12 hours ago, tgruzd said:

__attribute__((used)) перед вашим мемсетом должен помочь, вроде бы

Да, действительно помогает. Тогда можно предположить, что с LTO компилятор делает частную реализацию (какую-то memset.lto_priv.0, которая например всегда заполняет нулями, потому что в коде только так все используют memset с параметром 0), а функции с именем memset не оказывается.

 

11 hours ago, Сергей Борщ said:

Какой версией собираете вы?

13.2.1 20230826

Edited by amaora

Share this post


Link to post
Share on other sites

On 11/13/2023 at 8:23 PM, amaora said:
			*ld++ = fill;
		}
	}

	{
		uint8_t		*bd = (uint8_t *) ld;

else не видно

Share this post


Link to post
Share on other sites

25 minutes ago, x893 said:

else не видно

И не нужно, сначала идёт заполнение словами, при условии выравненности адреса, а затем остаток заполняется байтами. Хотя новые компиляторы такое и сами умеют уже при включённой оптимизации.

Share this post


Link to post
Share on other sites

47 minutes ago, amaora said:

И не нужно, сначала идёт заполнение словами, при условии выравненности адреса, а затем остаток заполняется байтами. Хотя новые компиляторы такое и сами умеют уже при включённой оптимизации.

Тупанул

Share this post


Link to post
Share on other sites

В итоге добавил в объявление функций memset и memcpy атрибуты __attribute__ ((noclone, noinline, used)).

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...