реклама на сайте
подробности

 
 
> linker
Злодей
сообщение Jun 17 2009, 11:24
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142



Здравствуйте!

WinAVR, родной makefile.

main.c
Код
#include <avr/io.h>

int do_not_link_me( int arg )
{
    return arg * arg;
}

int main( void )
{
}


main.lss ( По сути листинг прошивки )
Код
int do_not_link_me( int arg )
{
  88:    88 9f           mul    r24, r24
  8a:    90 01           movw    r18, r0
  8c:    89 9f           mul    r24, r25
  8e:    30 0d           add    r19, r0
  90:    98 9f           mul    r25, r24
  92:    30 0d           add    r19, r0
  94:    11 24           eor    r1, r1
    return arg * arg;
}


Хочу так, что бы в прошивке не было неиспользуемых функций. Усердно читаю и пробую ld options...

Помогите, пожалуста, терминами ( как эту проблему правильно называть ) ну и с решением. Спасибо!
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 21)
Злодей
сообщение Jun 17 2009, 13:09
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142



Добавлю, что в приведённом примере функция не линкуется если её объявить static.

Что сделать, бы модули неиспользуемые не линковать? Некоторые доки вгоняют в полную печаль...
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Jun 17 2009, 13:13
Сообщение #3


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Уже обсуждалось на форуме, поищите, пожалуйста. Сообщения, кажется, от Сергея Борща.


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
Злодей
сообщение Jun 17 2009, 13:34
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142



Спасибо, коллега подсказал параметры компиляции -ffunction-sections -fdata-sections и компоновки -Wl,--gc-sections.

LDFLAGS += -Wl,--gc-sections
CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections

Всё Шикарно smile.gif
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Jun 18 2009, 12:16
Сообщение #5


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Именно они, но я их не могу запомнить.

bb-offtopic.gif Не пора ли этот вопрос в FAQ отправлять?


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
Злодей
сообщение Jun 18 2009, 22:11
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 149
Регистрация: 29-04-08
Из: Петербург
Пользователь №: 37 142



Тогда сразу в -Os ... Вероятно, есть ньюансы, из-за которых их туда не добавляют?

(А то забуду) В FAQ надо отправить hex2bin и bin2hex посредством srecord krapula.gif

Сообщение отредактировал Злодей - Jun 18 2009, 22:12
Go to the top of the page
 
+Quote Post
alx2
сообщение Jun 19 2009, 18:16
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(Злодей @ Jun 17 2009, 18:09) *
Добавлю, что в приведённом примере функция не линкуется если её объявить static.
Хочу добавить, что иначе и быть не может: у статических объектов область видимости - файл, поэтому линкеру они не видны, он о их существовании ничего не знает (исключением, по-моему, яувляются только статические члены классов).
Цитата(Злодей @ Jun 19 2009, 03:11) *
(А то забуду) В FAQ надо отправить hex2bin и bin2hex посредством srecord
А что это и для чего?


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jun 20 2009, 18:31
Сообщение #8


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(alx2 @ Jun 19 2009, 21:16) *
у статических объектов область видимости - файл, поэтому линкеру они не видны, он о их существовании ничего не знает (исключением, по-моему, яувляются только статические члены классов).

Такие обьекты должны быть видны линкеру посредством их использования другими (нестатическими) обьектами\функциями. В примпре, приведённом у топикстартера, функция int do_not_link_me( int arg ) нигде не используется, поэтому если её обьявить статической, она справедливо будет выкинута.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 20 2009, 20:18
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Для GCC:

Единицей обработки компилятора является одна функция или переменная. Если функция или переменная объявлена как static и не используется в компилируемом файле то компилятор ее выкидывает. Если же функция или переменная используется или является глобальной, то она кладется в объектный файл в общую секцию .text (функция) и в .data или .bss (переменная) (если для них не указан атрибут section). Ключи -ffunction-sections и -fdata-sections компилятора изменяют это поведение компилятора и заставляют его в объектном файле для каждой функции и переменной создавать отдельную секцию.

Единицей обработки линкера является секция, вне зависимости от того сколько функций или переменных в этой секции находиться. По умолчанию ликер собирает все секции из входных файлов и кладет в результирующий объектный файл. Ключ --gc-sections изменет это поведение и заставляет линкер не класть в результирующий файл секции на которые нет ссылок из других секций. Секции которые обязательно должны присутствовать в результирующем файле, например секция со стартап кодом из которого вызывается функция main, описывается в скрипте линкера с помощью команды KEEP ().

Выводы.
1. Неиспользуемые stаtiс функции и переменные оптимизируются компилятором. Старайтесь использовать слово static в ваших программах это улучшает их читаемость и потенциально уменьшает размер.

2. -ffunction-sections и -fdata-sections на высоких уровнях оптимизации не включаются по двум причинам:
a) увеличение времени работы линкера, при использовании этих ключей сильно увеличивается количество секций которые должен обработать линкер.
б) в описании этих ключей есть предостережение что при их использовании возможны проблемы с отладкой. Мне не встречались сообщения с описаниями проблем для AVR платформы.

Анатолий.

Сообщение отредактировал aesok - Jun 20 2009, 20:34
Go to the top of the page
 
+Quote Post
alx2
сообщение Jun 21 2009, 14:24
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(IgorKossak @ Jun 20 2009, 23:31) *
Такие обьекты должны быть видны линкеру посредством их использования другими (нестатическими) обьектами\функциями.
? Не понял. Что значит "видны посредством использования"?
Код
$ cat test2.c
static int foo(int x)
{
    return x + 5;
}

int bar(int x)
{
    return foo(x * 2);
}
$ gcc -c test2.c
$ nm -g test2.o
0000000c T bar


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jun 21 2009, 17:17
Сообщение #11


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(alx2 @ Jun 21 2009, 17:24) *
? Не понял. Что значит "видны посредством использования"?

В Вашем же примере статическая функция static int foo(int x) вызывается в int bar(int x), поэтому (если в свою очередь последняя функция также используется в приложении) линкер не должен её выкинуть.
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 21 2009, 18:58
Сообщение #12


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(IgorKossak @ Jun 21 2009, 21:17) *
В Вашем же примере статическая функция static int foo(int x) вызывается в int bar(int x), поэтому (если в свою очередь последняя функция также используется в приложении) линкер не должен её выкинуть.


Только компилятор может выкидывать функции. А линкер может выкидывать только секции, вне зависимости сколько в ней функций (или переменных). Если есть ссылка хоть на одну функцию или переменную в секции то линкет оставляет всю секцию целиком. А вот сколько функций (переменных) положит компилятор в секцию управляеться ключем -ffunction-sections (-fdata-sections).

Анатолий.

Сообщение отредактировал aesok - Jun 21 2009, 19:17
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Jun 22 2009, 06:29
Сообщение #13


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Да, Вы правы, оговорился. Но независимо от того, кто чем занимается, результат останется прежним.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 22 2009, 14:41
Сообщение #14


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(IgorKossak @ Jun 22 2009, 10:29) *
результат останется прежним...
Почтиsmile.gif Компилятор может также с лёгкостью заинлайнить статическую функцию.
И как такового "экземпляра" функции не будет вовсе, как пролога эпилога и call/ret.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Jun 22 2009, 16:05
Сообщение #15


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Цитата(demiurg_spb @ Jun 22 2009, 18:41) *
Почтиsmile.gif Компилятор может также с лёгкостью заинлайнить статическую функцию.
И как такового "экземпляра" функции не будет вовсе, как пролога эпилога и call/ret.

объявление:
Код
static inline void __attribute__ ((always_inline)) foo(void);


тело:
Код
void foo(void)
{
....
}


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 22 2009, 16:14
Сообщение #16


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(mdmitry @ Jun 22 2009, 20:05) *
объявление:...
Что Вы хотели этим сказать, что бывает атрибут always_inline? Так это в мануале прописано... Тут разговор о другом, что даже без упоминания о inline, простой статик частенько позволяет компилятору инлайнить статические функции. Всё. Конец мысли.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
mdmitry
сообщение Jun 22 2009, 16:22
Сообщение #17


Начинающий профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 25-10-06
Из: СПб
Пользователь №: 21 648



Гарантированно инлайн и никаких мыслей более


--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 22 2009, 16:26
Сообщение #18


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(mdmitry @ Jun 22 2009, 20:22) *
Гарантированно инлайн и никаких мыслей более
Для этих целей у меня специальный макрос заготовлен:
Код
#define INLINE __inline__ __attribute__((always_inline))


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jun 22 2009, 16:58
Сообщение #19


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(demiurg_spb @ Jun 22 2009, 19:26) *
Для этих целей у меня специальный макрос заготовлен:
Код
#define INLINE __inline__ __attribute__((always_inline))

И обязательно рядом
Код
#define NOINLINE __attribute__((noinline))

тоже бывает нужен.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
alx2
сообщение Jun 23 2009, 09:29
Сообщение #20


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(IgorKossak @ Jun 21 2009, 22:17) *
В Вашем же примере статическая функция static int foo(int x) вызывается в int bar(int x), поэтому (если в свою очередь последняя функция также используется в приложении) линкер не должен её выкинуть.
Верно, что не должен, но не поэтому. Как уже сказал aesok, линкер не работает с функциями. Линкер работает с секциями. Он либо включает секцию в выходной файл, либо не включает. Целью приведенного мной примера было показать, что в сгенеренном ассемблером объектном файле вообще нет глобального символа foo, таким образом, линкер вообще не узнает о существовании такой функции.


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 23 2009, 18:11
Сообщение #21


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(alx2 @ Jun 23 2009, 13:29) *
Целью приведенного мной примера было показать, что в сгенеренном ассемблером объектном файле вообще нет глобального символа foo,


Нет, нету глобального символа foo, потому что функция foo статическая и ее область видимости ограничивается одним модулем.

Цитата(alx2 @ Jun 23 2009, 13:29) *
таким образом, линкер вообще не узнает о существовании такой функции.


Если компилятор не проинлайнит функцию foo, а то линкер увидет метку foo. И в даном случае при компиляции примера без оптимизации видим:

Код
$ nm  test2.o
00000000 b .bss
00000000 d .data
00000000 t .text
0000000b T _bar
00000000 t _foo



Анатолий.
Go to the top of the page
 
+Quote Post
alx2
сообщение Jun 24 2009, 10:54
Сообщение #22


Местный
***

Группа: Участник
Сообщений: 340
Регистрация: 25-10-05
Из: Пермь, Россия
Пользователь №: 10 091



Цитата(aesok @ Jun 23 2009, 23:11) *
Если компилятор не проинлайнит функцию foo, а то линкер увидет метку foo.
Код
00000000 t _foo
Так это же локальный символ - буква "t" маленькая. Разве линкер работает с локальными символами? Я почему-то считал, что он работает только с глобальными, а локальные его интересовать совершенно не должны. Это будет диверсия, если линкер удовлетворит внешнюю ссылку локальным объектом...


--------------------
Всего наилучшего,
Alex Mogilnikov
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th July 2025 - 05:16
Рейтинг@Mail.ru


Страница сгенерированна за 0.01569 секунд с 7
ELECTRONIX ©2004-2016