Перейти к содержанию
    

-ffunction-sections и -fdata-sections

Здравствуйте уважаемые любители 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте уважаемые любители 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?

посмотрите в какие функции лишниие и напишите.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

скорее всего -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

(результаты одинаковые)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

PS:Даже можно и без этого

MATH_LIB = -lm

(результаты одинаковые)

ну я к примеру так и собираю ;) всегда

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ну я к примеру так и собираю ;) всегда
Намёк понял:-) Попробую...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

судя по map-файлу либы avr-libc и libgcc собраны без -ffunction-sections
Насколько понимаю - это не должно влиять. Функции из библиотеки подтягиваются только в том случае, если к ним есть обращение. Надо разобраться - что именно заставляет подтягивать эти функкции из библиотеки.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Насколько понимаю - это не должно влиять. Функции из библиотеки подтягиваются только в том случае, если к ним есть обращение. Надо разобраться - что именно заставляет подтягивать эти функкции из библиотеки.
Умом я это тоже понимаю, но проект ведь и без них собирается.

Более того, я не увидел ни одного вызова, из перечисленных мной ранее функций в листинге моей программы. Вот что странно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Возможно, эти библиотеки используют какие-то статические структуры данных, а функция их инициализации помещена куда-то в секцию .init. Тогда линкер не может всё это хозяйство выкинуть.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

поробывал своей сборкой.

собираю код состоящий из одного пустого 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 у Вас особенная

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробовал именно с Вашим исходником тестовый проектик:

c либой:

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)

без либы:

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)

 

 

вродебы так и должно работать. видимо всетаки -lprintf_flt у Вас особенная

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

 

Возможно, эти библиотеки используют какие-то статические структуры данных, а функция их инициализации помещена куда-то в секцию .init. Тогда линкер не может всё это хозяйство выкинуть.

Но даже если это так, линкер должен раскручивать нити взаимосвязей секций

и обрезать эти нити на корю или максимально близко к корню, если они идут в никуда. ИМХО.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что с -lprintf_flt что без - лишнего кода нет:

там ещё такой ключик -Wl,-u,vfprintf

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

там ещё такой ключик -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 как неопределенный и все.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это если библиотки собраны с -ffunction-sections

А если нет, то -Wl,-u,vfprintf заставляет взять vprintf из libprintf_flt даже если на него ссылок по тексту нет, а -gc-sections не может потом это выбросить, так как оно в .text сидит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Поэкспериментировал ещё немного и понял вот ещё что.

Если компилить так,

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?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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.

 

Анатолий.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...