Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: -ffunction-sections и -fdata-sections
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
demiurg_spb
Здравствуйте уважаемые любители gcc!
Хочу прояснить один момент.
При:
Код
CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections
LDFLAGS += -Wl,--gc-section
и:
Код
MATH_LIB = -lm
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
и фактически при пустом проекте не выкидывается все эти
неиспользуемые мной библиотечные функции (проект собирается и без этих либ).
Размер выходного файла увеличивается на 2,5КБ.

Объясните пожалуйста кто-нибудь почему?
Может потому, что они (либы) были скомпилены без -ffunction-sections и -fdata-sections?

PS: avr-gcc (WinAVR 20100110) 4.3.3
klen
Цитата(demiurg_spb @ Jul 5 2010, 20:31) *
Здравствуйте уважаемые любители gcc!
Хочу прояснить один момент.
При:
Код
CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections
LDFLAGS += -Wl,--gc-section
и:
Код
MATH_LIB = -lm
PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt
и фактически при пустом проекте не выкидывается все эти
неиспользуемые мной библиотечные функции (проект собирается и без этих либ).
Размер выходного файла увеличивается на 2,5КБ.

Объясните пожалуйста кто-нибудь почему?
Может потому, что они (либы) были скомпилены без -ffunction-sections и -fdata-sections?

PS: avr-gcc (WinAVR 20100110) 4.3.3

скорее всего -lprintf_flt
она собрана с -ffunction-sections?
посмотрите в какие функции лишниие и напишите.
demiurg_spb
Цитата(klen @ Jul 5 2010, 21:25) *
скорее всего -lprintf_flt
она собрана с -ffunction-sections?
как это узнать (собирал ведь её не я)?

Цитата
посмотрите в какие функции лишниие и напишите.
Докладываю:-)
По моему мнению всё это лишнее (кусочек map файла):
Код
.text.avr-libc
                0x00000376      0x6d0 c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5\libprintf_flt.a(vfprintf_flt.o)
                0x00000376                vfprintf
.text.libgcc   0x00000a46       0x38 c:/winavr/bin/../lib/gcc/avr/4.3.3/avr5\libgcc.a(_prologue.o)
                0x00000a46                __prologue_saves__
.text.libgcc   0x00000a7e       0x36 c:/winavr/bin/../lib/gcc/avr/4.3.3/avr5\libgcc.a(_epilogue.o)
                0x00000a7e                __epilogue_restores__
.text.avr-libc
                0x00000ab4      0x1b0 c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5\libc.a(ftoa_engine.o)
                0x00000ab4                __ftoa_engine
.text.avr-libc
                0x00000c64       0x16 c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5\libc.a(strnlen_P.o)
                0x00000c64                strnlen_P
.text.avr-libc
                0x00000c7a       0x16 c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5\libc.a(strnlen.o)
                0x00000c7a                strnlen
.text.avr-libc
                0x00000c90       0x58 c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5\libc.a(fputc.o)
                0x00000c90                fputc
.text.avr-libc
                0x00000ce8       0xbc c:/winavr/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr5\libc.a(ultoa_invert.o)
                0x00000ce8                __ultoa_invert

судя по map-файлу либы avr-libc и libgcc собраны без -ffunction-sections

А вообще можно библиотеки собирать с кучей секций, да так чтоб их (секции) потом при подключении либ линкер видел и выкидывал?

PS:Даже можно и без этого
Код
MATH_LIB = -lm
(результаты одинаковые)
klen
Цитата(demiurg_spb @ Jul 5 2010, 21:46) *
А вообще можно библиотеки собирать с кучей секций, да так чтоб их (секции) потом при подключении либ линкер видел и выкидывал?
PS:Даже можно и без этого
Код
MATH_LIB = -lm
(результаты одинаковые)

ну я к примеру так и собираю wink.gif всегда
demiurg_spb
Цитата(klen @ Jul 5 2010, 22:33) *
ну я к примеру так и собираю wink.gif всегда
Намёк понял:-) Попробую...
Сергей Борщ
Цитата(demiurg_spb @ Jul 5 2010, 20:46) *
судя по map-файлу либы avr-libc и libgcc собраны без -ffunction-sections
Насколько понимаю - это не должно влиять. Функции из библиотеки подтягиваются только в том случае, если к ним есть обращение. Надо разобраться - что именно заставляет подтягивать эти функкции из библиотеки.
demiurg_spb
Цитата(Сергей Борщ @ Jul 6 2010, 13:42) *
Насколько понимаю - это не должно влиять. Функции из библиотеки подтягиваются только в том случае, если к ним есть обращение. Надо разобраться - что именно заставляет подтягивать эти функкции из библиотеки.
Умом я это тоже понимаю, но проект ведь и без них собирается.
Более того, я не увидел ни одного вызова, из перечисленных мной ранее функций в листинге моей программы. Вот что странно.
AHTOXA
Возможно, эти библиотеки используют какие-то статические структуры данных, а функция их инициализации помещена куда-то в секцию .init. Тогда линкер не может всё это хозяйство выкинуть.
klen
поробывал своей сборкой.
собираю код состоящий из одного пустого main + 2 функции которые заведомо не используются чтоб проверить -Wl,-gc-sections + -ffunction-sections -fdata-sections.
стотрб листинг - что с -lprintf_flt что без - лишнего кода нет:
Код
#include <string.h>

void b(char *b, char *d, char f)
{
  char count = f;
  do
  {
    *(d++) = *(b++);
  } while ( f-- );
  
}

void cpy ( char* x , char* y , size_t s  )
{
  if ( !s ) return;
  size_t t = s;
  do
   {
     *(y++) = *(x++);
   }
  while( --t );
}

int main ()
{
return 1;
}


на выходе
avr-gcc -mmcu=atmega32 a.c -ggdb3 -Os -lprintf_flt -Wl,-gc-sections -ffunction-sections -fdata-sections
avr-objdump -h -C -S a.out > a.txt

Код
Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         0000009c  00000000  00000000  00000054  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .stab         000006b4  00000000  00000000  000000f0  2**2
                  CONTENTS, READONLY, DEBUGGING
  2 .stabstr      00000067  00000000  00000000  000007a4  2**0
                  CONTENTS, READONLY, DEBUGGING
  3 .debug_aranges 00000030  00000000  00000000  0000080b  2**0
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_pubnames 00000029  00000000  00000000  0000083b  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_info   00000106  00000000  00000000  00000864  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_abbrev 000000ac  00000000  00000000  0000096a  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_line   00000129  00000000  00000000  00000a16  2**0
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_frame  00000040  00000000  00000000  00000b40  2**2
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_str    0000006a  00000000  00000000  00000b80  2**0
                  CONTENTS, READONLY, DEBUGGING
10 .debug_loc    000000c3  00000000  00000000  00000bea  2**0
                  CONTENTS, READONLY, DEBUGGING
11 .debug_macinfo 00001883  00000000  00000000  00000cad  2**0
                  CONTENTS, READONLY, DEBUGGING
12 .debug_pubtypes 0000001d  00000000  00000000  00002530  2**0
                  CONTENTS, READONLY, DEBUGGING
13 .debug_ranges 00000020  00000000  00000000  0000254d  2**0
                  CONTENTS, READONLY, DEBUGGING

Disassembly of section .text:

00000000 <__vectors>:
  size_t t = s;
  do
   {
     *(y++) = *(x++);
   }
  while( --t );
   0:    0c 94 2a 00     jmp    0x54; 0x54 <__ctors_end>
   4:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
   8:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
   c:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  10:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  14:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  18:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  1c:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  20:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  24:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  28:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  2c:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  30:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  34:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  38:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  3c:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  40:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  44:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  48:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  4c:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>
  50:    0c 94 47 00     jmp    0x8e; 0x8e <__bad_interrupt>

00000054 <__ctors_end>:
  54:    11 24           eor    r1, r1
  56:    1f be           out    0x3f, r1; 63
  58:    cf e5           ldi    r28, 0x5F; 95
  5a:    d8 e0           ldi    r29, 0x08; 8
  5c:    de bf           out    0x3e, r29; 62
  5e:    cd bf           out    0x3d, r28; 61

00000060 <__do_copy_data>:
  60:    10 e0           ldi    r17, 0x00; 0
  62:    a0 e6           ldi    r26, 0x60; 96
  64:    b0 e0           ldi    r27, 0x00; 0
  66:    ec e9           ldi    r30, 0x9C; 156
  68:    f0 e0           ldi    r31, 0x00; 0
  6a:    02 c0           rjmp    .+4     ; 0x70 <__do_copy_data+0x10>
  6c:    05 90           lpm    r0, Z+
  6e:    0d 92           st    X+, r0
  70:    a0 36           cpi    r26, 0x60; 96
  72:    b1 07           cpc    r27, r17
  74:    d9 f7           brne    .-10    ; 0x6c <__do_copy_data+0xc>

00000076 <__do_clear_bss>:
  76:    10 e0           ldi    r17, 0x00; 0
  78:    a0 e6           ldi    r26, 0x60; 96
  7a:    b0 e0           ldi    r27, 0x00; 0
  7c:    01 c0           rjmp    .+2     ; 0x80 <.do_clear_bss_start>

0000007e <.do_clear_bss_loop>:
  7e:    1d 92           st    X+, r1

00000080 <.do_clear_bss_start>:
  80:    a0 36           cpi    r26, 0x60; 96
  82:    b1 07           cpc    r27, r17
  84:    e1 f7           brne    .-8     ; 0x7e <.do_clear_bss_loop>
  86:    0e 94 49 00     call    0x92; 0x92 <main>
  8a:    0c 94 4c 00     jmp    0x98; 0x98 <_exit>

0000008e <__bad_interrupt>:
  8e:    0c 94 00 00     jmp    0; 0x0 <__vectors>

00000092 <main>:
}

int main ()
{
return 1;
  92:    81 e0           ldi    r24, 0x01; 1
  94:    90 e0           ldi    r25, 0x00; 0
  96:    08 95           ret

00000098 <_exit>:
  98:    f8 94           cli

0000009a <__stop_program>:
  9a:    ff cf           rjmp    .-2     ; 0x9a <__stop_program>


вродебы так и должно работать. видимо всетаки -lprintf_flt у Вас особенная
demiurg_spb
Попробовал именно с Вашим исходником тестовый проектик:
c либой:
CODE
avr-gcc (WinAVR 20100110) 4.3.3
Copyright © 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Compiling C: main.c
avr-gcc -c -mmcu=atmega64 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -ffunction-sections -fdata-sections -Wl,--relax -Wa,-adhlns=./obj/main.lst -I. -std=gnu99 -Wundef -MMD -MP -MF ./obj/dep/main.o.d main.c -o obj/main.o

Linking: bin/TestUart/TestUart.elf
avr-gcc -mmcu=atmega64 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -ffunction-sections -fdata-sections -Wl,--relax -Wa,-adhlns=./obj/main.o -I. -std=gnu99 -Wundef -MMD -MP -MF ./obj/dep/TestUart.elf.d obj/main.o --output bin/TestUart/TestUart.elf -Wl,--gc-section -Wl,-u,vfprintf -lprintf_flt -lm

Creating load file for Flash: bin/TestUart/TestUart.hex
avr-objcopy -O ihex -R .eeprom bin/TestUart/TestUart.elf bin/TestUart/TestUart.hex

Creating load file for EEPROM: bin/TestUart/TestUart.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex bin/TestUart/TestUart.elf bin/TestUart/TestUart.eep || exit 0

Creating Extended Listing: bin/TestUart/TestUart.lss
avr-objdump -h -S bin/TestUart/TestUart.elf > bin/TestUart/TestUart.lss

Creating Symbol Table: bin/TestUart/TestUart.sym
avr-nm -n bin/TestUart/TestUart.elf > bin/TestUart/TestUart.sym

Size after:
AVR Memory Usage
----------------
Device: atmega64

Program: 3032 bytes (4.6% Full)
(.text + .data + .bootloader)

Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)

без либы:
CODE
avr-gcc (WinAVR 20100110) 4.3.3
Copyright © 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Compiling C: main.c
avr-gcc -c -mmcu=atmega64 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -ffunction-sections -fdata-sections -Wl,--relax -Wa,-adhlns=./obj/main.lst -I. -std=gnu99 -Wundef -MMD -MP -MF ./obj/dep/main.o.d main.c -o obj/main.o

Linking: bin/TestUart/TestUart.elf
avr-gcc -mmcu=atmega64 -I. -gdwarf-2 -DF_CPU=14745600UL -Os -ffunction-sections -fdata-sections -Wl,--relax -Wa,-adhlns=./obj/main.o -I. -std=gnu99 -Wundef -MMD -MP -MF ./obj/dep/TestUart.elf.d obj/main.o --output bin/TestUart/TestUart.elf -Wl,--gc-section -lm

Creating load file for Flash: bin/TestUart/TestUart.hex
avr-objcopy -O ihex -R .eeprom bin/TestUart/TestUart.elf bin/TestUart/TestUart.hex

Creating load file for EEPROM: bin/TestUart/TestUart.eep
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" \
--change-section-lma .eeprom=0 --no-change-warnings -O ihex bin/TestUart/TestUart.elf bin/TestUart/TestUart.eep || exit 0

Creating Extended Listing: bin/TestUart/TestUart.lss
avr-objdump -h -S bin/TestUart/TestUart.elf > bin/TestUart/TestUart.lss

Creating Symbol Table: bin/TestUart/TestUart.sym
avr-nm -n bin/TestUart/TestUart.elf > bin/TestUart/TestUart.sym

Size after:
AVR Memory Usage
----------------
Device: atmega64

Program: 168 bytes (0.3% Full)
(.text + .data + .bootloader)

Data: 0 bytes (0.0% Full)
(.data + .bss + .noinit)



Цитата(klen @ Jul 7 2010, 19:39) *
вродебы так и должно работать. видимо всетаки -lprintf_flt у Вас особенная

Даже и не знаю...

Цитата(AHTOXA @ Jul 7 2010, 14:49) *
Возможно, эти библиотеки используют какие-то статические структуры данных, а функция их инициализации помещена куда-то в секцию .init. Тогда линкер не может всё это хозяйство выкинуть.

Но даже если это так, линкер должен раскручивать нити взаимосвязей секций
и обрезать эти нити на корю или максимально близко к корню, если они идут в никуда. ИМХО.
ReAl
Цитата(klen @ Jul 7 2010, 18:39) *
что с -lprintf_flt что без - лишнего кода нет:

там ещё такой ключик -Wl,-u,vfprintf
klen
Цитата(ReAl @ Jul 9 2010, 13:19) *
там ещё такой ключик -Wl,-u,vfprintf

$ avr-gcc -mmcu=atmega32 a.c -ggdb3 -Os -lprintf_flt -Wl,-gc-sections -ffunction-sections -fdata-sections | avr-size a.out
text data bss dec hex filename
156 0 0 156 9c a.out



avr-gcc -mmcu=atmega32 a.c -ggdb3 -Os -lprintf_flt -Wl,-gc-sections -ffunction-sections -fdata-sections -Wl,-u,vfprintf | avr-size a.out
text data bss dec hex filename
156 0 0 156 9c a.out

-Wl,-u,vfprintf по идее не должно ниначто влиять, оно помечает символ vfprintf как неопределенный и все.
ReAl
Это если библиотки собраны с -ffunction-sections
А если нет, то -Wl,-u,vfprintf заставляет взять vprintf из libprintf_flt даже если на него ссылок по тексту нет, а -gc-sections не может потом это выбросить, так как оно в .text сидит.
demiurg_spb
Поэкспериментировал ещё немного и понял вот ещё что.
Если компилить так,
Код
CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections
LDFLAGS += -Wl,--gc-section
PRINTF_LIB =
SCANF_LIB =
MATH_LIB = -lm

то на мелких проектах (не использующих printf scanf) можно существенно выиграть флеша в сравнении с
Код
CFLAGS += -ffunction-sections
CFLAGS += -fdata-sections
LDFLAGS += -Wl,--gc-section
PRINTF_LIB = -Wl,-u,vfprintf -lprintf_min
SCANF_LIB = -Wl,-u,vfscanf -lscanf_min
MATH_LIB = -lm

Хотел спросить, эти линкуемые либы, которые не выкидываются, являются частью avr-libc?
aesok
Цитата(demiurg_spb @ Oct 15 2010, 18:49) *
Код
PRINTF_LIB = -Wl,-u,vfprintf -lprintf_min
SCANF_LIB = -Wl,-u,vfscanf -lscanf_min
MATH_LIB = -lm

Хотел спросить, эти линкуемые либы, которые не выкидываются, являются частью avr-libc?


Да, libscanf_min.a и libprintf_min.a входят в avr-libc.

Анатолий.
demiurg_spb
Спасибо! Но насколько я понял feedback стоит давать не авторам avr-libc,
а тем кто собирает эти либы (в моём случае автору WinAVR). Я правильно мыслю?
aesok
Цитата(demiurg_spb @ Oct 16 2010, 13:32) *
Спасибо! Но насколько я понял feedback стоит давать не авторам avr-libc,
а тем кто собирает эти либы (в моём случае автору WinAVR). Я правильно мыслю?


Не понял вопроса.
Eric Weddington занимаеться сборкой WinAVR и является автором avr-libc.

Анатолий.
demiurg_spb
Цитата(aesok @ Oct 16 2010, 17:28) *
Не понял вопроса.
Нестрашно:-)
Зато я ответ понял. Спасибо!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.