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]

Using FILL(n) or =FILLEXP in linker scripts


Hello.

The super short version of our question is:  are FILL/FILLEXPs actually
written out to the ELF file, like initialized data?  Or are they just
stored as a "do this at startup", like .bss sections?

We are using a custom linker script with GNU ld 2.17 targeting powerpc-elf
(embedded, no OS yet, bare metal, etc).  It started as a copy of the stock
elf32ppc.x script, heavily modified by somebody who does not really know
compilers and is learning about linker scripts as he goes (me).

Under normal conditions, we have some output sections listed, and after
the sections we define some symbols to delimit two subsequent "chunks"
of memory.  Example with internal confusing names replaced:

.....
.last_example_block : {
    .......
    __last_example_block_end = .;
} > ram

/* Chunk one runs from the end of the last block to here. */
. = . + _CHUNK_ONE_SIZE;
. = ALIGN(16);
__chunk_one_top = .;

/* Chunk two follows, with its own markers. */
__chunk_two_bottom = .;
. = . + _CHUNK_TWO_SIZE;
. = ALIGN(16);
__chunk_two_top = .;

That all works fine.  (Based on ld.info, I think the ALIGN statement is
supposed to be able to be merged with the "sizing" statement preceding
it, but we couldn't get that syntax to work.  No big deal.)

Here's the problem:  for debugging, we'd like to occasionally fill either
of those "chunks" with a constant pattern; typically, the second of the
two chunks.  Fill expressions only work within section blocks according
to the manual, so we replace the last bit of that script with:

.internal_chunk_two : {
    FILL(0xDEADBEEF)           /* attempt one */
    __chunk_two_bottom = .;
    . = . + _CHUNK_TWO_SIZE;
    . = ALIGN(16);
    __chunk_two_top = .;
} > ram =0xDEADBEEF           /* attempt two */

Neither FILL nor FILLEXP work here.  We get two things wrong:  first,
the ELF file as written to disk doesn't contain our fill pattern.
The file *is* much larger, as one would expect -- it's writing out the
contents of that chunk instead of just storing the endpoints.  But the
contents are all explicit zeros.

The second problem is that the two chunks overlap.  Using the example
names, the new .internal_chunk_two is being placed immediately
after .last_example_block, and so __last_example_block_end and
__chunk_two_bottom have the same address.  (The first "chunk" is
typically small, so it ends up actually *inside* the second one, with
ensuing hilarity.)

Our questions:
(1)  What are we doing wrong with the fill expression?
(2)  Shouldn't the line ". = . + _CHUNK_ONE_SIZE;" have moved the location
counter forward in memory for the references in .internal_chunk_two?
We seem to have worked around the issue by using "__chunk_two_bottom =
__chunk_one_top;" in that output section, but I don't know if that's
the correct solution, or why the first way isn't working.


Any light which anyone could shed would be very appreciated.

Ti


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