|
Как заставить GCC не линковать лишние функции, Пихает в бинарник всё подряд без разбора... |
|
|
|
Nov 25 2008, 06:01
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Давно уже заметил, но сегодня глянул листинг и ужаснулся. Половина бинарника - неиспользуемые функции от фримодбаса. Что-то надо с этим делать. Попутно ещё вопрос: что это за хрень получается из memcpy()? Я думал, он умнее меня сможет блоки перекидать, а он вон чего творит... Или я чего-то не понял... Код 00004f5c <memcpy>: 4f5c: 0b 12 push r11; 4f5e: 0a 12 push r10; 4f60: 0a 4f mov r15, r10; 4f62: 0b 4d mov r13, r11; 4f64: 0d 4f mov r15, r13; 4f66: 0c 4e mov r14, r12; 4f68: 0b 93 cmp #0, r11;r3 As==00 4f6a: 5e 24 jz $+190;abs 0x5028 4f6c: 0f 9e cmp r14, r15; 4f6e: 5c 24 jz $+186;abs 0x5028 4f70: 0f 9e cmp r14, r15; 4f72: 2b 2c jc $+88 ;abs 0x4fca 4f74: 0f 4e mov r14, r15; 4f76: 0f da bis r10, r15; 4f78: 1f f3 and #1, r15;r3 As==01 4f7a: 0e 24 jz $+30 ;abs 0x4f98 4f7c: 0f 4e mov r14, r15; 4f7e: 0f ea xor r10, r15; 4f80: 1f f3 and #1, r15;r3 As==01 4f82: 02 20 jnz $+6 ;abs 0x4f88 4f84: 2b 93 cmp #2, r11;r3 As==10 4f86: 1c 2c jc $+58 ;abs 0x4fc0 4f88: 0e 4b mov r11, r14; 4f8a: 0b 8e sub r14, r11; 4f8c: ed 4c 00 00 mov.b @r12, 0(r13); 4f90: 1c 53 inc r12; 4f92: 1d 53 inc r13; 4f94: 3e 53 add #-1, r14;r3 As==11 4f96: fa 23 jnz $-10 ;abs 0x4f8c 4f98: 0e 4b mov r11, r14; 4f9a: 12 c3 clrc 4f9c: 0e 10 rrc r14; 4f9e: 0e 93 cmp #0, r14;r3 As==00 4fa0: 05 24 jz $+12 ;abs 0x4fac 4fa2: bd 4c 00 00 mov @r12+, 0(r13); 4fa6: 2d 53 incd r13; 4fa8: 3e 53 add #-1, r14;r3 As==11 4faa: fb 23 jnz $-8 ;abs 0x4fa2 4fac: 0e 4b mov r11, r14; 4fae: 1e f3 and #1, r14;r3 As==01 4fb0: 3b 24 jz $+120;abs 0x5028 4fb2: ed 4c 00 00 mov.b @r12, 0(r13); 4fb6: 1c 53 inc r12; 4fb8: 1d 53 inc r13; 4fba: 3e 53 add #-1, r14;r3 As==11 4fbc: fa 23 jnz $-10 ;abs 0x4fb2 4fbe: 34 3c jmp $+106;abs 0x5028 4fc0: 0f 4e mov r14, r15; 4fc2: 1f f3 and #1, r15;r3 As==01 4fc4: 2e 43 mov #2, r14;r3 As==10 4fc6: 0e 8f sub r15, r14; 4fc8: e0 3f jmp $-62 ;abs 0x4f8a 4fca: 0c 4e mov r14, r12; 4fcc: 0c 5b add r11, r12; 4fce: 0d 4f mov r15, r13; 4fd0: 0d 5b add r11, r13; 4fd2: 0f 4c mov r12, r15; 4fd4: 0f dd bis r13, r15; 4fd6: 1f f3 and #1, r15;r3 As==01 4fd8: 0f 24 jz $+32 ;abs 0x4ff8 4fda: 0f 4c mov r12, r15; 4fdc: 0f ed xor r13, r15; 4fde: 1f f3 and #1, r15;r3 As==01 4fe0: 03 20 jnz $+8 ;abs 0x4fe8 4fe2: 3b 90 03 00 cmp #3, r11;#0x0003 4fe6: 1d 2c jc $+60 ;abs 0x5022 4fe8: 0e 4b mov r11, r14; 4fea: 0b 8e sub r14, r11; 4fec: 3d 53 add #-1, r13;r3 As==11 4fee: 3c 53 add #-1, r12;r3 As==11 4ff0: ed 4c 00 00 mov.b @r12, 0(r13); 4ff4: 3e 53 add #-1, r14;r3 As==11 4ff6: fa 23 jnz $-10 ;abs 0x4fec 4ff8: 0e 4b mov r11, r14; 4ffa: 12 c3 clrc 4ffc: 0e 10 rrc r14; 4ffe: 0e 93 cmp #0, r14;r3 As==00 5000: 06 24 jz $+14 ;abs 0x500e 5002: 2c 83 decd r12; 5004: 2d 83 decd r13; 5006: ad 4c 00 00 mov @r12, 0(r13); 500a: 3e 53 add #-1, r14;r3 As==11 500c: fa 23 jnz $-10 ;abs 0x5002 500e: 0e 4b mov r11, r14; 5010: 1e f3 and #1, r14;r3 As==01 5012: 0a 24 jz $+22 ;abs 0x5028 5014: 3d 53 add #-1, r13;r3 As==11 5016: 3c 53 add #-1, r12;r3 As==11 5018: ed 4c 00 00 mov.b @r12, 0(r13); 501c: 3e 53 add #-1, r14;r3 As==11 501e: fa 23 jnz $-10 ;abs 0x5014 5020: 03 3c jmp $+8 ;abs 0x5028 5022: 0e 4c mov r12, r14; 5024: 1e f3 and #1, r14;r3 As==01 5026: e1 3f jmp $-60 ;abs 0x4fea 5028: 0f 4a mov r10, r15; 502a: 3a 41 pop r10; 502c: 3b 41 pop r11; 502e: 30 41 ret PS; иногда бывает полезно поглядеть, чего заливаешь в железку...
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Nov 25 2008, 07:03
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(scifi @ Nov 25 2008, 09:35)  Спасибо! Попробовал всё сразу - переборщил. Output size is 115 B - всё повыкидывал... Начал по порядку - -static уже помогло. Остался вопрос с мемкопи - что он там вытворяет
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Nov 25 2008, 08:15
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Нашёл лишний ключ. --gc-sections убивает секцию .text наповал...
В общем, поколупался, нашёл. как говорится, "сам дурак". Надо было обозначить #define MB_ASCII_ENABLED ( 0 ) чтобы соответствующие функции выкидывались, иначе откуда компилятору знать
С ключами полная засада, непонятно чего они там творят, в общем решил не лечить, что работает. Выяснил подлый ключик -s, который выкидывает из эльфа все текстовые метки, и в результате листинг нечитабельный
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Nov 25 2008, 11:36
|

Участник

Группа: Участник
Сообщений: 20
Регистрация: 25-06-07
Из: Томск
Пользователь №: 28 670

|
Цитата(MrYuran @ Nov 25 2008, 15:15)  Нашёл лишний ключ. --gc-sections убивает секцию .text наповал... Странно, уж хотя бы main то должен остаться. У меня это ключ отлично работает в avr-gcc и arm-gcc.
|
|
|
|
|
Nov 25 2008, 12:56
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Написал свой memcpy: Код while(NumOfWords--) { *FlashPtr++ = *DataPtr++; } Получилось куда ни шло: (хотя можно и короче) Код 14d8: b4 53 04 00 add #-1, 4(r4);r3 As==11 14dc: b4 93 04 00 cmp #-1, 4(r4);r3 As==11 14e0: 01 20 jnz $+4 ;abs 0x14e4 14e2: 0b 3c jmp $+24 ;abs 0x14fa 14e4: 2f 44 mov @r4, r15; 14e6: 0e 4f mov r15, r14; 14e8: 1f 44 02 00 mov 2(r4), r15; 14ec: ae 4f 00 00 mov @r15, 0(r14); 14f0: a4 53 02 00 incd 2(r4) ; 14f4: a4 53 00 00 incd 0(r4) ; 14f8: ef 3f jmp $-32 ;abs 0x14d8 Непонятно, чё хрень в библиотеки насовали...
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Nov 25 2008, 15:20
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045

|
Цитата(MrYuran @ Nov 25 2008, 14:56)  Непонятно, чё хрень в библиотеки насовали... Ответ кроится в исходниках библиотеки  CODE /*- * Copyright © 1990, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Chris Torek. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */
#include <sys/cdefs.h> #include <string.h>
/* * sizeof(word) MUST BE A POWER OF TWO * SO THAT wmask BELOW IS ALL ONES */ typedef int word; /* "word" used for optimal copy speed */
#define wsize sizeof(word) #define wmask (wsize - 1)
/* * Copy a block of memory, handling overlap. * This is the routine that actually implements * (the portable versions of) bcopy, memcpy, and memmove. */ #ifdef MEMCOPY void * memcpy(dst0, src0, length) #else #ifdef MEMMOVE void * memmove(dst0, src0, length) #else void bcopy(src0, dst0, length) #endif #endif void *dst0; const void *src0; register size_t length; { register char *dst = dst0; register const char *src = src0; register size_t t;
if (length == 0 || dst == src) /* nothing to do */ goto done;
/* * Macros: loop-t-times; and loop-t-times, t>0 */ #define TLOOP(s) if (t) TLOOP1(s) #define TLOOP1(s) do { s; } while (--t)
if ((unsigned int)dst < (unsigned int)src) { /* * Copy forward. */ t = (int)src; /* only need low bits */ if ((t | (int)dst) & wmask) { /* * Try to align operands. This cannot be done * unless the low bits match. */ if ((t ^ (int)dst) & wmask || length < wsize) t = length; else t = wsize - (t & wmask); length -= t; TLOOP1(*dst++ = *src++); } /* * Copy whole words, then mop up any trailing bytes. */ t = length / wsize; TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize); t = length & wmask; TLOOP(*dst++ = *src++); } else { /* * Copy backwards. Otherwise essentially the same. * Alignment works as before, except that it takes * (t&wmask) bytes to align, not wsize-(t&wmask). */ src += length; dst += length; t = (int)src; if ((t | (int)dst) & wmask) { if ((t ^ (int)dst) & wmask || length <= wsize) t = length; else t &= wmask; length -= t; TLOOP1(*--dst = *--src); } t = length / wsize; TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src); t = length & wmask; TLOOP(*--dst = *--src); } done: #if defined(MEMCOPY) || defined(MEMMOVE) return (dst0); #else return; #endif }
|
|
|
|
|
Nov 25 2008, 15:32
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(MrYuran @ Nov 25 2008, 10:15)  Нашёл лишний ключ. --gc-sections убивает секцию .text наповал... --gc-sections имеет смысл только в комплекте с --ffunction-section. По поводу выкидывания всего - смотрите внимательно скрипт линкера. В качестве образца возьмите скрипт из последней или предпоследней версии WinAVR. Обратите внимание, что секции .initX и .vectors должны быть описаны с KEEP() в скрипте. Именно из этих секций вызывается main и обработчики прерываний, именно эти секции не должны быть выкинуты и "тянут за собой" все используемые функции.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 25 2008, 15:40
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045

|
Цитата(Сергей Борщ @ Nov 25 2008, 17:32)  --gc-sections имеет смысл только в комплекте с --ffunction-section. Почему только? Разве для каждой единицы компиляции не создается своя секция? -ffunction-section и -fdata-section таким образом повышают эффективность сборщика мусора, но не включают его. Хотя на практике имеем, что хоть одна функция из единицы компиляции всё таки да и спользуется, сводя на нет усилия сборщика мусора, без раделения функций на секции.
|
|
|
|
|
Nov 25 2008, 16:42
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(gotty @ Nov 25 2008, 17:40)  Почему только? Разве для каждой единицы компиляции не создается своя секция? А вы загляните в листинг. Все складывается в ".text". С --ffunction-section каждая функция кладется в секцию ".text.func_name". Без --function-section -gc-sections мог бы выкинуть только всю секцию .text и другие неиспользуемые секции (.initX, .finiX, .ctors и т.д.) но KEEP() в скрипте линкера не позволяет этого. Цитата(gotty @ Nov 25 2008, 17:40)  -ffunction-section и -fdata-section таким образом повышают эффективность сборщика мусора, но не включают его. Естественно. ведь -gc-sections расшифровывается как garbage collection on sections. Логично предположить, что именно этот ключ и включает сборщик мусора. Цитата(gotty @ Nov 25 2008, 17:40)  Хотя на практике имеем, что хоть одна функция из единицы компиляции всё таки да и спользуется, сводя на нет усилия сборщика мусора, без раделения функций на секции. Нет, тут вы не правы. Можете провести эксперимент (или почитать документацию на ld).
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 25 2008, 22:38
|

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

|
Цитата(sla000 @ Nov 25 2008, 16:36)  Цитата(MrYuran @ Nov 25 2008, 13:15)  Нашёл лишний ключ. --gc-sections
Странно, уж хотя бы main то должен остаться. У меня это ключ отлично работает в avr-gcc и arm-gcc. Еще добавлю пару замечаний. Во-первых, линкует линкер, а не компилятор. В смысле, что линкер входит в состав binutils, а вовсе не gcc. Но это так, в плане занудства.  Во-вторых, понять, почему линкер прилинковал к программе тот или иной модуль, хорошо помогает генерация map-файла. Там для каждого загруженного линкером модуля оказываются символы, ради которых этот модуль был загружен, и модуль, который на этот символ имеет ссылку. Поэтому настоятельно рекомендую просить линкер генерить map-файл и иногда туда внимательно смотреть. А то бывает, что из-за какого-нибудь никому не нужного __do_copy_data, к проекту как снежный ком прилинкуется с десяток библиотечных модулей...
--------------------
Всего наилучшего, Alex Mogilnikov
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|