|
-ffunction-sections и -fdata-sections, хочу прояснить |
|
|
|
Jul 5 2010, 16:31
|

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

|
Здравствуйте уважаемые любители 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
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jul 5 2010, 17:25
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
Цитата(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? посмотрите в какие функции лишниие и напишите.
|
|
|
|
|
Jul 5 2010, 17:46
|

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

|
Цитата(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 (результаты одинаковые)
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jul 5 2010, 18:33
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

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

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
поробывал своей сборкой. собираю код состоящий из одного пустого 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 у Вас особенная
|
|
|
|
|
Jul 8 2010, 09:47
|

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

|
Попробовал именно с Вашим исходником тестовый проектик: 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. Тогда линкер не может всё это хозяйство выкинуть. Но даже если это так, линкер должен раскручивать нити взаимосвязей секций и обрезать эти нити на корю или максимально близко к корню, если они идут в никуда. ИМХО.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jul 9 2010, 14:12
|

бессмертным стать можно тремя способами
    
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912

|
Цитата(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 как неопределенный и все.
|
|
|
|
|
Oct 15 2010, 14:49
|

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

|
Поэкспериментировал ещё немного и понял вот ещё что. Если компилить так, Код 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?
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Oct 15 2010, 15:49
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(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. Анатолий.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|