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

Как заставить GCC не линковать лишние функции

Давно уже заметил, но сегодня глянул листинг и ужаснулся. Половина бинарника - неиспользуемые функции от фримодбаса.

Что-то надо с этим делать.

Попутно ещё вопрос: что это за хрень получается из 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; иногда бывает полезно поглядеть, чего заливаешь в железку...

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


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

Давно уже заметил, но сегодня глянул листинг и ужаснулся. Половина бинарника - неиспользуемые функции от фримодбаса.

Что-то надо с этим делать.

http://gcc.gnu.org/ml/gcc-help/2003-08/msg00128.html

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


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

Спасибо!

Попробовал всё сразу - переборщил.

Output size is 115 B - всё повыкидывал...

Начал по порядку - -static уже помогло.

Остался вопрос с мемкопи - что он там вытворяет

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


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

Попробовал всё сразу - переборщил.

На самом деле классический универсальный вариант - пользоваться библиотеками для подобных вещей.

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


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

http://electronix.ru/forum/index.php?showt...amp;st=30 - вот совсем недавно я об этом говорил (и ранее по ветке так же). надо же иной раз и другие ветки форума читать, и поиском пользоваться...

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


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

Нашёл лишний ключ.

--gc-sections убивает секцию .text наповал...

 

В общем, поколупался, нашёл.

как говорится, "сам дурак".

Надо было обозначить #define MB_ASCII_ENABLED ( 0 )

чтобы соответствующие функции выкидывались, иначе откуда компилятору знать

 

С ключами полная засада, непонятно чего они там творят, в общем решил не лечить, что работает.

Выяснил подлый ключик -s, который выкидывает из эльфа все текстовые метки, и в результате листинг нечитабельный

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


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

Нашёл лишний ключ.

--gc-sections убивает секцию .text наповал...

 

Странно, уж хотя бы main то должен остаться. У меня это ключ отлично работает в avr-gcc и arm-gcc.

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


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

Написал свой 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

Непонятно, чё хрень в библиотеки насовали...

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


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

Непонятно, чё хрень в библиотеки насовали...

 

Ответ кроится в исходниках библиотеки :)

/*-
* 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
}

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


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

Нашёл лишний ключ.

--gc-sections убивает секцию .text наповал...

--gc-sections имеет смысл только в комплекте с --ffunction-section.

По поводу выкидывания всего - смотрите внимательно скрипт линкера. В качестве образца возьмите скрипт из последней или предпоследней версии WinAVR. Обратите внимание, что секции .initX и .vectors должны быть описаны с KEEP() в скрипте. Именно из этих секций вызывается main и обработчики прерываний, именно эти секции не должны быть выкинуты и "тянут за собой" все используемые функции.

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


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

--gc-sections имеет смысл только в комплекте с --ffunction-section.
Почему только? Разве для каждой единицы компиляции не создается своя секция? -ffunction-section и -fdata-section таким образом повышают эффективность сборщика мусора, но

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

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


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

Почему только? Разве для каждой единицы компиляции не создается своя секция?
А вы загляните в листинг. Все складывается в ".text". С --ffunction-section каждая функция кладется в секцию ".text.func_name". Без --function-section -gc-sections мог бы выкинуть только всю секцию .text и другие неиспользуемые секции (.initX, .finiX, .ctors и т.д.) но KEEP() в скрипте линкера не позволяет этого.
-ffunction-section и -fdata-section таким образом повышают эффективность сборщика мусора, но не включают его.
Естественно. ведь -gc-sections расшифровывается как garbage collection on sections. Логично предположить, что именно этот ключ и включает сборщик мусора.
Хотя на практике имеем, что хоть одна функция из единицы компиляции всё таки да и спользуется, сводя на нет усилия сборщика мусора, без раделения функций на секции.
Нет, тут вы не правы. Можете провести эксперимент (или почитать документацию на ld).

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


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

сдедал ЭТО. всунул -ffunction-sections и -Wl,-gc-sections. Про KEEP я не знал, засунул в него секцию векторов - далее все тянется друг за дружку. Спасибо за урок.

получил минус 10% кода, все также хорошо работает.

 

век живи, век учись - как был дурак, так и останешся :)

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


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

Нашёл лишний ключ. --gc-sections

Странно, уж хотя бы main то должен остаться. У меня это ключ отлично работает в avr-gcc и arm-gcc.
Еще добавлю пару замечаний. Во-первых, линкует линкер, а не компилятор. В смысле, что линкер входит в состав binutils, а вовсе не gcc. Но это так, в плане занудства. :)

Во-вторых, понять, почему линкер прилинковал к программе тот или иной модуль, хорошо помогает генерация map-файла. Там для каждого загруженного линкером модуля оказываются символы, ради которых этот модуль был загружен, и модуль, который на этот символ имеет ссылку. Поэтому настоятельно рекомендую просить линкер генерить map-файл и иногда туда внимательно смотреть. А то бывает, что из-за какого-нибудь никому не нужного __do_copy_data, к проекту как снежный ком прилинкуется с десяток библиотечных модулей... :)

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


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

...

Поэтому настоятельно рекомендую просить линкер генерить map-файл и иногда туда внимательно смотреть. А то бывает, что из-за какого-нибудь никому не нужного __do_copy_data, к проекту как снежный ком прилинкуется с десяток библиотечных модулей... :)

 

Простите за глупый вопрос :)

А как по map файлу понять кому нужна та или иная функция?

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


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

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

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

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

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

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

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

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

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

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