On 2010-06-21, JMGross <[email protected]> wrote:

> Unfortunately., my boss really dislikes me posting our project code into
> the world.

Yes, bosses can be funny that way.

> I didn't set up a separate project for checking. I just took a
> randomly chosen existing project, added the function foo() to one of
> the object files and it always appeared in the binary. No matter
> whether I used the switches or not. Only difference weas that with
> -ffunction-sections it appeared in a seaction .text.foo rather than
> .text in the object file assembly listing. Then I put it ito a
> separate object file, added it to the project and again it was
> included into the binary.
>
>>> Onother example. Once again any project. One object file was added to
>>> the project, containing the above function. Again the binaries are
>>> identical, no matter whether -gc-sections was used or not. foo() was
>>> always part of the binary.
>>
>>> Is it possible that if not ld itself then the linker scripts have
>>> been altered in a way that breaks -gc-sections?
>
>> That's possible.  If you can post an example that fails for you and
>> works for us, then we can start trying to track down the source of the
>> problem.
>
> If I understood the linker scripts correctly, the linker will put all
> .text and .text.* compiler segments into the linker text segment.

After the unreferenced .text.* sections are discarded, the remaining
ones will all be placed into the .text section in the output file.

> So there are no empty segments to be discarded by -gc-sections.

I'm not sure what "empty segments" you're talking about.

> (well, empty segments won't add to the binary anyway, as they are
> empty. So the GCC description of this flag is a bit misleading)
>
> The question is why the linker keeps the .text.* parts even if they
> are never referenced.

Are you _sure_ you passed the -gc-sections flag to the linker?


> Linktest.c:
> int main(void){
> }//main()
>
> dummy.c:
> void foo(void){
> }
>
> makefile:
> #put the name of the project here
>     NAME = Linktest
>
> #put your C sourcefiles here
>       SRC     = $(NAME).c dummy.c
>
> #put additional assembler source file here
>       ASRC =
>
> #additional includes to compile
>       INC     =
>
> #define include path for common code files
>   INCSRC = ../EPOS_COMMON_3
>
> #put the name of the target mcu here
>     MCU = msp430x5438
>
> #compiler flags
>       CPFLAGS = -std=gnu99 -g -Os -Wall -Wcast-align -Wcast-qual -Wimplicit 
> -Wnested-externs -Winline \
>                                 -Wpointer-arith -Wredundant-decls 
> -Wreturn-type -Wshadow -Wstrict-prototypes -Wswitch -Wunused -Wundef \
>                                 -Wunreachable-code 
> #linker flags
>       LDFLAGS =
>
> #----------------------------------------------------------------------------------
> # MSPGCC standard Makefile part 3
> # 
> ---------------------------------------------------------------------------------
>
> ###### BLOCK 1) define some variables based on the MSP base path in $(MSP) 
> #######
>
>       CC                      = 
> @c:/Programme/msp430/mspgcc_0812/bin/msp430-gcc
>       AS                      = 
> @c:/Programme/msp430/mspgcc_0812/bin/msp430-gcc -x assembler-with-cpp
>       AR                      = @c:/Programme/msp430/mspgcc_0812/bin/msp430-ar
>       RM                      = @rm -f
>       RN                      = @mv
>       OUT               = coff
>       CP                      = cp
>       BIN               = @c:/Programme/msp430/mspgcc_0812/bin/msp430-objcopy
>       SIZE            = @c:/Programme/msp430/mspgcc_0812/bin/msp430-size -t
>       RAMUSAGE = @c:/Programme/msp430/mspgcc_0812/bin/msp430-ram-usage
>       INCDIR  = .
>       OBJDIR  = obj
>       TRGDIR  = lib
>       BINDIR  = bin
>       LIBDIR  = $(MSP)/msp430/lib
>       SHELL           = sh.exe
>
>       DUMP            = @c:/Programme/msp430/mspgcc_0812/bin/msp430-objdump
>       JTAG            = @c:/Programme/msp430/mspgcc_0812/bin/msp430-jtag
>       TITXT   = @c:/Programme/msp430/mspgcc_0812/bin/ihex2titext
>
>
>
> ###### BLOCK 3) define all project specific object files ######
>
>       OBJ             = $(ASRC:.s=.o) $(SRC:.c=.o)
>       CPFLAGS += -mmcu=$(MCU)
> # -ffunction-sections
>       ASFLAGS += -mmcu=$(MCU)
>       LDFLAGS += -mmcu=$(MCU)
> # -gc-sections
>
> ###### BLOCK 5) compile: instructions to create assembler and/or object files 
> from C source ######
>
> %.o:  %.c
>       $(CC) -c $(CPFLAGS) -Wa,-ahlms=$(addprefix $(OBJDIR)/,$(notdir 
> $(<:.c=.lst))) -I$(INCDIR) -I$(INCSRC) $< -o $(OBJDIR)/$@
>       $(SIZE) $(OBJDIR)/$@ | grep -e .o
>
>
> %.s : %.c
>       $(CC) -S $(CPFLAGS) -I$(INCDIR) -I$(INCSRC) $< -o $(OBJDIR)/$@
>
>
> ###### BLOCK 6) assemble: instructions to create object file from assembler 
> files ######
>
> %.o : %.s
>       $(AS) -c $(ASFLAGS) -I$(INCDIR) $< -o $(OBJDIR)/$@
>
>
> ###### BLOCK 7)  arch: instructions to create library output file from object 
> files ######
>
> $(NAME).elf : $(OBJ)
>       $(CC) $(LDFLAGS) $(addprefix $(OBJDIR)/,$(OBJ)) -o $(TRGDIR)/$(NAME).elf
>
> $(NAME).hex : $(NAME).elf
>       $(BIN) -O ihex $(TRGDIR)/$(NAME).elf $(BINDIR)/$(NAME).hex
>
> $(NAME).txt : $(NAME).hex
>       $(TITXT) -o $(BINDIR)/$(NAME).txt $(BINDIR)/$(NAME).hex
>
> all: $(NAME).txt
>       $(SIZE) $(TRGDIR)/$(NAME).elf
>
> ###### BLOCK 8)  make instruction to delete created files ######
>
> clean : $(SRC) $(ASRC)
>       @echo "deleting files..."
>       $(RM) $(addprefix $(OBJDIR)/,$(OBJ)) $(addprefix 
> $(OBJDIR)/,$(OBJ:.o=.lst))
>       $(RM) $(TRGDIR)/$(NAME).a
>       $(RM) $(TRGDIR)/$(NAME).elf
>       $(RM) $(TRGDIR)/$(NAME).lst
>       $(RM) $(BINDIR)/$(NAME).hex
>       $(RM) makefile.d
>       @echo "rebuilding dependencies..."
>       $(CC) -mmcu=$(MCU) -E -MM -I. -I$(INCSRC) $^ > makefile.d
>       @echo "CLEAN complete."
>
> ###### calculate dependencies #############
> #makefile.d : $(SRC) $(ASRC)
> #     $(CC) -mmcu=$(MCU) -E -MM -I. -I$(INCSRC) $^ > makefile.d
> # -E stop after preprocessing, output preprocessor output
> # -M create include rule isntead of preprocessor output
> # -MM like -M but ignore includes from system directory
>
> ###### dependecies, add any dependencies you need here ###################
> -include makefile.d
>
> if 'dummy.c' is included to the SRC-line, the function foo() is placed into 
> the binary, even if never referenced or used.
> Based on your explanations, I'd expect it to never appear there (unreachable).

Thank you for posting a real example.  Now we can figure out what's
going on.

First, both -ffunction-sections and -gc-sections flags are commented
out in your makefile.

Second, it's '--gc-sections' not '-gc-sections'

Third, if you uncomment them and add the second hyphen, you're still
not passing --gc-sections flag to the linker, you're passing it to the
compiler (which should have resulted in a error message).

If you want to pass the --gc-sections flag to the linker via the gcc
command line, you need to use either "-W,--gc-sections" or "-Xlinker 
--gc-sections"

-- 
Grant Edwards               grant.b.edwards        Yow! I want you to MEMORIZE
                                  at               the collected poems of
                              gmail.com            EDNA ST VINCENT MILLAY
                                                   ... BACKWARDS!!


Reply via email to