# Forum: ARM programming with GCC/GNU tools How to remove unreference code(functions,data) from outputfile

 Author: Prabu 8. (Company: Nimble) (prabu) Posted on: 2010-03-09 14:58

Rate this post
 0 ▲ useful ▼ not useful
Hi all,
Greetings!!.

We are using GNUARM,Freertos with eclipse for my application.

In my project,we have created lib file(.a) for reducing final Output
code.
Then by using .a file, i have developed application.I am facing
following problem.

1.If i use any one function in my application,all non static(extern)
functions(related to that particular .o file) are included in my output
file.static functions are not included unless i use that in
application.I have seen this in .map file.I am using GCC 4.1.1.

To solve this,i used
CFLAGS = -ffunction-sections -fdata-sections
LFLAGS = --gc-sections

then i use, GCC4.2.2 version.But i got some .dll missing error.
Then i used that .dlls.

After that linker error issue has solved.
and .hex file created.But when i saw map file,all codes(referenced code)
were removed. and .text section size is o,.data section size also 0.

I have also mentioned --entry=0x00000000 in .mak file.still issue not
solved.It seems that all codes removed(reference,unreferenced
guide me about how to solve this Issue.

Thanks,

 Author: Prabu 8. (Company: Nimble) (prabu) Posted on: 2010-03-11 05:08

Rate this post
 0 ▲ useful ▼ not useful
Is any had experience with problem??

 Author: Martin T. (mthomas) (Moderator) Posted on: 2010-03-11 12:05

Rate this post
 0 ▲ useful ▼ not useful
Prabu 84 wrote:
> Hi all,
>        Greetings!!.
>
> We are using GNUARM,Freertos with eclipse for my application.
GNUARM means files from gnuarm.com?

> In my project,we have created lib file(.a) for reducing final Output
> code.
> Then by using .a file, i have developed application.I am facing
> following problem.
>
> 1.If i use any one function in my application,all non static(extern)
> functions(related to that particular .o file) are included in my output
> file.static functions are not included unless i use that in
> application.I have seen this in .map file.I am using GCC 4.1.1.

The smallest unit for the linker when not using unused-code-removal is
an object file. So if you do not want to use any special compiler- or
linker-options (like -ffunction-sections, gc-sections...) you can create
one object file per function where each function is implemented in a
source-file. This method is usually used by libcs, see for example the
newlib source-code. Another method is to envelop every function in a
souce file with #if/#endif and use defines so compile the source several
times into separate object files for each fuction. I have seen this
method in older versions of LMI librarys but don't know if still used.

>   To solve this,i used
> CFLAGS = -ffunction-sections -fdata-sections
> LFLAGS = --gc-sections

Is the linker called directly? If not (called by the frontend) use
-Wl,--gc-sections. There is not need for --gc-sections when creating an
archive (.a) AFAIK (it's just an archive of objects at not linked code).

> I was getting link error, no memory to load like that
> then i use, GCC4.2.2 version.But i got some .dll missing error.
> Then i used that .dlls.

Not enough information. What dll-files do you mean (something from
Cygwin)? IRC GCC supports -ffunction-sections/data-sections from version
4.0.

> After that linker error issue has solved.
> and .hex file created.But when i saw map file,all codes(referenced code)
> were removed. and .text section size is o,.data section size also 0.

The linker-script has to be prepared for the function- and data-sections
to the linker knows how to handle the per-function input-sections. Maybe
your linker-script has a line like this *(.text) and nothing else for
the text input-section. If yes try to modify to *(.text .text.*)

> I have also mentioned --entry=0x00000000 in .mak file.still issue not
> solved.It seems that all codes removed(reference,unreferenced
> guide me about how to solve this Issue.

Yes, the entry is also imporant to tell the linker where "used code"
starts. I have never used --entry as command line-paramater and with an
address. You may try to put an ENTRY-entry at the start of your
linker-script where you give the name/label for code called on reset.
E.g.: ENTRY(My_Reset_Handler)

 Author: Clifford S. (clifford) Posted on: 2010-03-13 12:51

Rate this post
 0 ▲ useful ▼ not useful
When building a library, granularity is important to minimise final link
size without any special action on the part of the linker; typically the
"one file per externally callable function" rule should be applied, or
in the case of C++, probably one class per-file since placing member
functions in separate files would be very tedious; but this is
nonetheless an argument for small well designed cohesive classes.

Functions that are always only ever practically used together may be
defined in a common source without detriment; things with open/close,
alloc/free, or construct/destruct type semantics for example spring to
mind.  Also this is where the justification for "one class per
compilation unit" for C++ comes from; well designed classes with
cohesive functionality should cause little dead-code bloat, since
generally if you use one function, you are likely to use most of the
closely related ones.

Where you are at the moment this:
http://embeddedfreak.wordpress.com/2009/02/10/remo...
may be useful, but it is essentially what Martin has already advised.

 Author: Prabu 8. (Company: Nimble) (prabu) Posted on: 2010-03-16 17:01

Rate this post
 0 ▲ useful ▼ not useful
My Question is,

1. In same project with GNUARM 4.1.1 version,we are linking
standard(newlib) libarary

such as libgcc.a.libc.a,libc.a etc.But this static library behaves as
expected. which means only includes referenced functions.Not inlcuded
all functions.
But My static library behaving differently compared to standard new lib
libarary.So i am suspecting that " way of my library creation or way of
my library linking" is not proper.

My static lib crated as follows,

$(TARGET_LIB).a :$(TARGET_ASM_OBJ) $(TARGET_THUMB_OBJ)$(TARGET_ARM_OBJ)
arm-elf-ar -r "$(PACKAGE)/$(TARGET_LIB).a" $(TARGET_THUMB_OBJ)$(TARGET_ARM_OBJ)
cp Source/boot.o $(PACKAGE)/ Please guide me??If anyone faced this issue already please share your experience??? Thanks,  Author: Clifford S. (clifford) Posted on: 2010-03-16 22:01 Rate this post  0 ▲ useful ▼ not useful Prabu 84 wrote: > My Question is, > It was well understood what your question was, and I believe that it has been answered. In what manner do the answers given not resolve your query. Prabu 84 wrote: > My static lib crated as follows, > >$(TARGET_LIB).a :$(TARGET_ASM_OBJ)$(TARGET_THUMB_OBJ)$(TARGET_ARM_OBJ) > arm-elf-ar -r "$(PACKAGE)/$(TARGET_LIB).a"$(TARGET_THUMB_OBJ)
> $(TARGET_ARM_OBJ) > cp Source/boot.o$(PACKAGE)/
>
That gives no indication of the granularity of your project unless we
knew how many object files the TARGET_ARM_OBJ macro refers to, and what
size they were, and in turn perhaps how many functions they included.

The point is that if you include one function from any object file, the
whole object file is linked.  So the solution is to make the object
files as granular as possible.  If all your functions are in one object
file, you'll get the whole library, and in that circumstance the use of
a library over a single object file is almost pointless.

>
> experience???
>
You have been given guidance, but seem to be ignoring answers that are
either not what you want to hear or which perhaps you do not understand.

 Author: Prabu 8. (Company: Nimble) (prabu) Posted on: 2010-03-31 15:43

Rate this post
 0 ▲ useful ▼ not useful
Sorry for my delay response.
Your information is very useful for me to fix this Issue.

In my text section i have changed following modification.

*(.text)   ->  (*(.text .text.*)

*(.data)   ->  *(.data .data.*)

*(.bss)   ->  *(.bss .bss.*)

Now its seems to be working for me.Could you please explain detaily abou
above modification??which means what it tells to linker..

Thanks for ur response.

 Author: Martin T. (mthomas) (Moderator) Posted on: 2010-03-31 20:34

Rate this post
 0 ▲ useful ▼ not useful
Prabu 84 wrote:
> Sorry for my delay response.
> Your information is very useful for me to fix this Issue.
>
> In my text section i have changed following modification.
>
> *(.text)   ->  (*(.text .text.*)
>
> *(.data)   ->  *(.data .data.*)
>
> *(.bss)   ->  *(.bss .bss.*)
>
> Now its seems to be working for me.

good

> Could you please explain detaily abou
> above modification??which means what it tells to linker..

I have already written a little bit on this in a previous message in
this thread. But of cause there is an official documentation. See:

http://gcc.gnu.org/onlinedocs/gcc-4.4.3/gcc/Optimi...

http://sourceware.org/binutils/docs/ld/Options.htm...

 Author: Prabu 8. (Company: Nimble) (prabu) Posted on: 2010-04-01 13:17

Rate this post
 0 ▲ useful ▼ not useful
Thanks.If i use assembly startup code means How can i give entry from ld
script.

For C Reset_handler entry its works fine.ENTRY(My_Reset_Handler)

But startup code is assembly means how should i give entry???

In this case start code(address 0) not use for any code(seen this in map
file).If i am not give entry means code size(.text section) is zero.
Plase give any sample code.Thanks

 Author: Martin T. (mthomas) (Moderator) Posted on: 2010-04-03 12:58

Rate this post
 0 ▲ useful ▼ not useful
Prabu 84 wrote:
> Thanks.If i use assembly startup code means How can i give entry from ld
> script.
>
> For C Reset_handler entry its works fine.ENTRY(My_Reset_Handler)
>
> But startup code is assembly means how should i give entry???

Use a label and make it "visible" to the linker with .global You may try
this:

 mysuperentry: .global mysuperentry @ startup-code goes here 

> In this case start code(address 0) not use for any code(seen this in map
> file).If i am not give entry means code size(.text section) is zero.

Usually there is a vector-table at the start of memory which refers to
the startup-code (on ARM7 it the first instruction on CM3 the second
value). If put the table in a special section (.section in GNU-assembler
or section-attribute in GCC) and force the linker to keep this section
(KEEP()) there might be no need for an extra ENTRY(). KEEPing the
vector-table is a good idea anyway.

• $formula (LaTeX syntax)$