|
linker |
|
|
|
Jun 17 2009, 11:24
|

Частый гость
 
Группа: Участник
Сообщений: 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... Помогите, пожалуста, терминами ( как эту проблему правильно называть ) ну и с решением. Спасибо!
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 21)
|
Jun 17 2009, 13:34
|

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

|
Спасибо, коллега подсказал параметры компиляции -ffunction-sections -fdata-sections и компоновки -Wl,--gc-sections. LDFLAGS += -Wl,--gc-sections CFLAGS += -ffunction-sections CFLAGS += -fdata-sections Всё Шикарно
|
|
|
|
|
Jun 19 2009, 18:16
|

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

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

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

|
Цитата(alx2 @ Jun 19 2009, 21:16)  у статических объектов область видимости - файл, поэтому линкеру они не видны, он о их существовании ничего не знает (исключением, по-моему, яувляются только статические члены классов). Такие обьекты должны быть видны линкеру посредством их использования другими (нестатическими) обьектами\функциями. В примпре, приведённом у топикстартера, функция int do_not_link_me( int arg ) нигде не используется, поэтому если её обьявить статической, она справедливо будет выкинута.
|
|
|
|
|
Jun 21 2009, 14:24
|

Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jun 21 2009, 18:58
|
Знающий
   
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jun 22 2009, 16:05
|

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

|
Цитата(demiurg_spb @ Jun 22 2009, 18:41)  Почти  Компилятор может также с лёгкостью заинлайнить статическую функцию. И как такового "экземпляра" функции не будет вовсе, как пролога эпилога и call/ret. объявление: Код static inline void __attribute__ ((always_inline)) foo(void); тело: Код void foo(void) { .... }
--------------------
Наука изощряет ум; ученье вострит память. Козьма Прутков
|
|
|
|
|
Jun 22 2009, 16:26
|

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

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

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

|
Цитата(demiurg_spb @ Jun 22 2009, 19:26)  Для этих целей у меня специальный макрос заготовлен: Код #define INLINE __inline__ __attribute__((always_inline)) И обязательно рядом Код #define NOINLINE __attribute__((noinline)) тоже бывает нужен.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jun 23 2009, 09:29
|

Местный
  
Группа: Участник
Сообщений: 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
|
|
|
|
|
Jun 23 2009, 18:11
|
Знающий
   
Группа: Участник
Сообщений: 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 Анатолий.
|
|
|
|
|
Jun 24 2009, 10:54
|

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

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