This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Linker relaxation and SEC_EXCLUDE issue.


I believe there is a problem with when we choose to mark output
sections with the SEC_EXCLUDE flag if we are also performing
linker relaxation.

Consider three output section A B C in that order, A and C have
some content from input sections, B does have an input section
specifier but no matching input sections, so no content.  However,
B does contain: " . = ALIGN (8);".

Now, if 'A' happens to end on an 8 byte boundary then B will have
no content, and the ALIGN will not move 'dot' at all, as a result
we mark B as SEC_EXCLUDE within ldlang.c:strip_excluded_output_sections.

However, if we have linker relaxation turned on then it is possible that
section 'A' might shrink (or maybe even grow, do any 'relaxation' passes 
grow sections?), in any case, if 'A' changes size then as we loop round
in ldlang.c:lang_relax_sections the ALIGN statement in 'B' now needs to
come into play to provide the required alignment; section 'B' is no longer
empty, and so having is marked SEC_EXCLUDE is incorrect.

The funny side of this bug is the result, as we perform linker relaxation 
we *set* the size of the output section based on the input sections, and we
*increase* the size of the output section to add any required padding if we
see an ALIGN statement.  However, the code in ldlang.c:size_input_section
that sets the size of the output section is not hit if the output section
is marked as SEC_EXCLUDE, the result is the size of the output section is
not reset each time round the linker relaxation loop, and as the ALIGN is
now adding some padding, out section 'B' continues to grow for each linker
relaxation pass; this in turn pushes output section 'C' to higher and higher
addresses.

I do have a reproducible test for the xtensa target, the files are listed below,
I configured binutils with: 'configure --target="xtensa*-*-elf"', then grab the
test.s, test.ld, and Makefile from the bottom of the email, drop them into an
empty directory and:

  make LD=<path-to-ld> AS=<path-to-as> OBJDUMP=<path-to-objdump>

this creates test.relax.objdump and test.no-relax.objdump.  Take a look at
test.relax.objdump and the placement of the ".problem.section", this is
section 'C' from my above text, it's been placed at 0x1c, I believe it
should have been placed at 0x10 instead.  Also the ".alignment.section"
('B' above) is not included in the final ELF as it was marked SEC_EXCLUDE
but I believe it should have been as it needs to provide the padding between
the end of ".text" ('A' above) and ".problem.section".

I don't currently have a patch as I'm not sure the best place to fix this issue,
I am investigating ways to fix this issue, but I'd like to put the issue before
the group in the hope someone can offer some good advice.

Thanks
Andrew




;; START: test.s
        .text
        call0   dest
        _nop
        _nop
        _nop.n

        .section ".text.dest"
        .global dest
        .align 8
dest:
        nop

        .section ".more.dumb", "ax"
        .global more_dumb_label
more_dumb_label:
        nop
        nop
;; END: test.s


/* START: test.ld */

SECTIONS
{
  .literal :
  {
    *(.literal)
  }

  .text.dest :
  {
    *(.text.dest)
  }

  .text : 
  {
    _text_start = .;
    *(.text)
  }

  .alignment.section :
  {
    *(.empty.*)
    . = ALIGN(8);
    empty_label = .;
  }

  .problem.section :
  {
    _problem_label = .;
    *(.more.dumb)
  }

}

/* END: test.ld */


# START: Makefile

AS := as
LD := ld
OBJDUMP := objdump

.PHONY: all clean no-relax relax
all : no-relax relax

relax: test.o
	$(LD) -relax -Ttest.ld -o test.relax.x test.o
	$(OBJDUMP) -zD test.relax.x > test.relax.objdump

no-relax: test.o
	$(LD) -no-relax -Ttest.ld -o test.no-relax.x test.o
	$(OBJDUMP) -zD test.no-relax.x > test.no-relax.objdump

test.o:
	$(AS) --transform --longcalls -o test.o test.s


clean :
	-rm -f test.o
	-rm -f test.relax.x test.relax.objdump
	-rm -f test.no-relax.x test.no-relax.objdump

# END: Makefile




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]