Padding between .text and .data

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Padding between .text and .data

Shaun Jackman
In the linker script, armelf.xc, -- and likely other elf targets --
this line places 256 bytes of padding between the output .text and
.data sections.

  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = ALIGN(256) + (. & (256 - 1));

Why is this padding necessary?

Please cc me in your reply. Thanks,
Shaun
Reply | Threaded
Open this post in threaded view
|

Re: Padding between .text and .data

DJ Delorie-2

> In the linker script, armelf.xc, -- and likely other elf targets --
> this line places 256 bytes of padding between the output .text and
> .data sections.
>
>   /* Adjust the address for the data segment.  We want to adjust up to
>      the same address within the page on the next page up.  */
>   . = ALIGN(256) + (. & (256 - 1));
>
> Why is this padding necessary?

It puts *up to* 256 bytes.  It aligns the data to start on the next
"page" so that data and code are always in separate pages and the
memory management unit can deal with them separately (read-only,
shared, page in, etc).  Might also help keep the icache and dcache
sane.

Older linkers padded to 512 byte boundaries to optimize disk access,
since disk sectors are usually 512 bytes.
Reply | Threaded
Open this post in threaded view
|

Re: Padding between .text and .data

Shaun Jackman
On 2/14/06, DJ Delorie <[hidden email]> wrote:
> >   /* Adjust the address for the data segment.  We want to adjust up to
> >      the same address within the page on the next page up.  */
> >   . = ALIGN(256) + (. & (256 - 1));
>
> It puts *up to* 256 bytes.  It aligns the data to start on the next
> "page" so that data and code are always in separate pages and the
> memory management unit can deal with them separately (read-only,
> shared, page in, etc).  Might also help keep the icache and dcache
> sane.

It looks as though this inserts either exactly zero bytes if the
section happens to already be aligned, or exactly 256 bytes if the
section is unaligned, with this latter case being far more likely. If
the .text and .data sections must be in different pages for the MMU's
sake, I understand the ALIGN(256) requirement. What's the reason for
the additional (. & (256 - 1)) bytes placed at the beginning of the
next page?

Cheers,
Shaun
Reply | Threaded
Open this post in threaded view
|

Re: Padding between .text and .data

DJ Delorie-2

> > >   . = ALIGN(256) + (. & (256 - 1));
>
> It looks as though this inserts either exactly zero bytes if the
> section happens to already be aligned, or exactly 256 bytes if the
> section is unaligned, with this latter case being far more likely. If
> the .text and .data sections must be in different pages for the MMU's
> sake, I understand the ALIGN(256) requirement. What's the reason for
> the additional (. & (256 - 1)) bytes placed at the beginning of the
> next page?

I misread; this is the *other* optimization. Sorry.

The idea here is that you want data in the file and data in memory to
both be similarly aligned; such that if you break memory up into
sector-sized blocks, the data in each block corresponds to a block of
data on disk.

Thus, even though the data segment might start, say, 100k beyond the
end of code when in memory, the gap is always *exactly* some multiple
of disk blocks, and there's no bytes wasted on the disk.

Example:

        .text 00000000 - 00000123
        .data   10000124 - 10001234

Note that there's a huge gap between the two in the memory map, but on
disk you can put .data's first byte immediately after .text's last
byte, and still have a block-to-block alignment between disk and
memory (i.e. you can read block 0x100-0x1ff and store it at 00000100
if you needed .text, or 10000100 if you needed .data)
Reply | Threaded
Open this post in threaded view
|

Re: Padding between .text and .data

Shaun Jackman
On 2/15/06, DJ Delorie <[hidden email]> wrote:
...
> The idea here is that you want data in the file and data in memory to
> both be similarly aligned; such that if you break memory up into
> sector-sized blocks, the data in each block corresponds to a block of
> data on disk.
...

Thanks for the explanation, DJ. This value of 256 seems fairly
arbitrary and hardware specific. For example, it shows up on my
embedded ARM7 system, which has no MMU. Is the idea that the VMA of
the sections are arbitrary anyways, and so this optimization shouldn't
hurt anything?

I discovered this optimization, because it showed up as zeros in my
flash image when I used objcopy -Obinary, which is an unfortunate side
effect for me. One solution, of course, is to use a custom linker
script. I'm currently using the default linker script though, and I'd
rather continue doing that than maintaining my own. Any other
suggestions?

Cheers,
Shaun
Reply | Threaded
Open this post in threaded view
|

Re: Padding between .text and .data

DJ Delorie-2

> One solution, of course, is to use a custom linker script.

Yup.
Reply | Threaded
Open this post in threaded view
|

RE: Padding between .text and .data

Dave Korn
In reply to this post by Shaun Jackman
On 15 February 2006 17:19, Shaun Jackman wrote:

> On 2/15/06, DJ Delorie <[hidden email]> wrote:
> ...
>> The idea here is that you want data in the file and data in memory to
>> both be similarly aligned; such that if you break memory up into
>> sector-sized blocks, the data in each block corresponds to a block of
>> data on disk.
> ...
>
> Thanks for the explanation, DJ. This value of 256 seems fairly
> arbitrary and hardware specific.

  Linker scripts are, in general!  It's the correct place for this sort of
knowledge about memory mapping and layouts.

> I discovered this optimization, because it showed up as zeros in my
> flash image when I used objcopy -Obinary, which is an unfortunate side
> effect for me. One solution, of course, is to use a custom linker
> script. I'm currently using the default linker script though, and I'd
> rather continue doing that than maintaining my own. Any other
> suggestions?

  You shouldn't need to 'maintain' your linker script unless you change
binutils version, in which case you would need to generate a new variant from
the more up-to-date default linker script from the new binutils.

  Having said that, is it possible that you could generate your own linker
script by some kind of postprocessing on the default linker script?


    cheers,
      DaveK
--
Can't think of a witty .sigline today....

Reply | Threaded
Open this post in threaded view
|

Re: Padding between .text and .data

Shaun Jackman
On 2/15/06, Dave Korn <[hidden email]> wrote:
> > Thanks for the explanation, DJ. This value of 256 seems fairly
> > arbitrary and hardware specific.
>
>   Linker scripts are, in general!  It's the correct place for this sort of
> knowledge about memory mapping and layouts.

I agree; however, this target-specific optimization makes no sense for
my target and seems to be applied too broadly.

>   You shouldn't need to 'maintain' your linker script unless you change
> binutils version, in which case you would need to generate a new variant from
> the more up-to-date default linker script from the new binutils.

I'm typically running a binutils from CVS, so changing my binutils
version is a fairly regular event.

>   Having said that, is it possible that you could generate your own linker
> script by some kind of postprocessing on the default linker script?

Yes. In a way, I already do by maintaining a diff against the default
linker script. I'd rather avoid this sort of hackery though.

Cheers,
Shaun
Reply | Threaded
Open this post in threaded view
|

Re: Padding between .text and .data

Daniel Jacobowitz-2
On Wed, Feb 15, 2006 at 12:16:23PM -0700, Shaun Jackman wrote:
> On 2/15/06, Dave Korn <[hidden email]> wrote:
> > > Thanks for the explanation, DJ. This value of 256 seems fairly
> > > arbitrary and hardware specific.
> >
> >   Linker scripts are, in general!  It's the correct place for this sort of
> > knowledge about memory mapping and layouts.
>
> I agree; however, this target-specific optimization makes no sense for
> my target and seems to be applied too broadly.

Take a look at the default emulparams files.  This comes from
MAXPAGESIZE=256 in ld/emulparams/armelf.sh.  Many architectures have
a "standard" page size (ARM doesn't really seem to).

--
Daniel Jacobowitz
CodeSourcery
Reply | Threaded
Open this post in threaded view
|

Re: Padding between .text and .data

Shaun Jackman
On 2/15/06, Daniel Jacobowitz <[hidden email]> wrote:
> Take a look at the default emulparams files.  This comes from
> MAXPAGESIZE=256 in ld/emulparams/armelf.sh.  Many architectures have
> a "standard" page size (ARM doesn't really seem to).

Thanks for the pointer, Daniel! I'll change MAXPAGESIZE from 256 to 4
in my tree.

Cheers,
Shaun
Reply | Threaded
Open this post in threaded view
|

Re: Padding between .text and .data

Ian Lance Taylor
In reply to this post by Shaun Jackman
Shaun Jackman <[hidden email]> writes:

> I discovered this optimization, because it showed up as zeros in my
> flash image when I used objcopy -Obinary, which is an unfortunate side
> effect for me. One solution, of course, is to use a custom linker
> script. I'm currently using the default linker script though, and I'd
> rather continue doing that than maintaining my own. Any other
> suggestions?

Use the -N option.

Ian