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!!