EmbDev.net

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


von Prabu 8. (Company: Nimble) (prabu)


Rate this post
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

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.

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 
etc).Please
guide me about how to solve this Issue.

Thanks,

von Prabu 8. (Company: Nimble) (prabu)


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

von Martin T. (mthomas) (Moderator)


Rate this post
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
> etc).Please
> 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)

von Clifford S. (clifford)


Rate this post
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/removing-unused-functionsdead-codes-with-gccgnu-ld/ 
may be useful, but it is essentially what Martin has already advised.

von Prabu 8. (Company: Nimble) (prabu)


Rate this post
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,

von Clifford S. (clifford)


Rate this post
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.


>
> Please guide me??If anyone faced this issue already please share your
> 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.

von Prabu 8. (Company: Nimble) (prabu)


Rate this post
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.

von Martin T. (mthomas) (Moderator)


Rate this post
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/Optimize-Options.html#index-ffunction_002dsections-791

http://sourceware.org/binutils/docs/ld/Options.html#index-g_t_002d_002dgc_002dsections-168

von Prabu 8. (Company: Nimble) (prabu)


Rate this post
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

von Martin T. (mthomas) (Moderator)


Rate this post
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:
1
mysuperentry:
2
.global mysuperentry
3
@ 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.

Please log in before posting. Registration is free and takes only a minute.
Existing account
Do you have a Google/GoogleMail account? No registration required!
Log in with Google account
No account? Register here.