public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* linker allocation order VS declaration order
@ 2012-07-31  9:09 Hua Yanghao
  2012-07-31 13:38 ` nick clifton
  0 siblings, 1 reply; 3+ messages in thread
From: Hua Yanghao @ 2012-07-31  9:09 UTC (permalink / raw)
  To: binutils

Hi,
While porting an old arm RVDS based code to arm-GCC,
I found a behavior difference regarding variable allocation order
with regard to its declaration order in C file.

I know this is bad design and should not be relied on,
but that's the burden must be carried for the porting.

For example, if in a C file, two variable declared:
int a;
int b;

After compilation, a and b is in bss section (common section).
The linker script could be:
.bss 0x8000 : { *(COMMON) }

Here the RVDS always place a @ 0x8000 and b @ 0x8004,
however for GNU/Binutils the placement is completely random.
Sometimes if I initialized a and b to 0, which in theory should have
no difference but in reality do change the address for a and b.

So here my question is,in GNU/ld is there any way to make the
variable allocation order (or assignment order) exactly the same
as the declaration order?

Thanks,
Yanghao

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: linker allocation order VS declaration order
  2012-07-31  9:09 linker allocation order VS declaration order Hua Yanghao
@ 2012-07-31 13:38 ` nick clifton
  2012-08-01  2:08   ` Hua Yanghao
  0 siblings, 1 reply; 3+ messages in thread
From: nick clifton @ 2012-07-31 13:38 UTC (permalink / raw)
  To: Hua Yanghao; +Cc: binutils

Hi Yanghao,
> I know this is bad design and should not be relied on,
> but that's the burden must be carried for the porting.

Really you should fix the code to remove this reliance.  It really is 
bad practice to code that way.  That said...


> So here my question is,in GNU/ld is there any way to make the
> variable allocation order (or assignment order) exactly the same
> as the declaration order?

You don't say which version of the binutils you are using.  I will 
assume however that you are using the latest development sources, since 
otherwise this problem might have already been addressed.

The short answer is "no".

One possibility however, which might work, is to compile the program 
with -fdata-section and -fno-common specified.  Then all of the 
variables will be placed in individually named sections.  Next you would 
have to create a linker script which assigns these specific sections to 
the generic output section in the order that you desire.  (You would 
only need to do this for those variable whose ordering matters).

For example:

   % cat order.c
   int a;
   int b;
   int c;

   % gcc -fdata-sections -fno-common -c order.c

   % readelf -S order.o
   [...]
    [ 4] .bss.a  NOBITS    00000000 000034 000004 00  WA  0   0  4
    [ 5] .bss.b  NOBITS    00000000 000034 000004 00  WA  0   0  4
    [ 6] .bss.c  NOBITS    00000000 000034 000004 00  WA  0   0  4
   [...]

   % cat b-after-a.script
   SECTIONS
   {
         .bss :
         {
            *(.bss.a)
            *(.bss.b)
            *(.bss.*)
            *(.bss)
         }
   }

   % ld -T b-after-a.script order.o -Map b-after-a.map

   % cat b-after-a.map
   [...]
   .bss          0x00000000        0xc
     *(.bss.a)
      .bss.a     0x00000000        0x4 order.o
                 0x00000000                a
    *(.bss.b)
      .bss.b     0x00000004        0x4 order.o
                 0x00000004                b
    *(.bss.*)
      .bss.c     0x00000008        0x4 order.o
                 0x00000008                c
    *(.bss)
      .bss       0x0000000c        0x0 order.o

   % cat b-before-a.script
   SECTIONS
   {
         .bss :
         {
            *(.bss.b)
            *(.bss.a)
            *(.bss.*)
            *(.bss)
         }
   }

   % ld -T b-before-a.script order.o -Map b-before-a.map

   % cat b-before-a.map
  .bss           0x00000000        0xc
    *(.bss.b)
      .bss.b     0x00000000        0x4 order.o
                 0x00000000                b
    *(.bss.a)
      .bss.a     0x00000004        0x4 order.o
                 0x00000004                a
    *(.bss.*)
      .bss.c     0x00000008        0x4 order.o
                 0x00000008                c
    *(.bss)
      .bss       0x0000000c        0x0 order.o


This is complex I know, but I would hope that you would only have to do 
it for a few particular variables.

Cheers
   Nick

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: linker allocation order VS declaration order
  2012-07-31 13:38 ` nick clifton
@ 2012-08-01  2:08   ` Hua Yanghao
  0 siblings, 0 replies; 3+ messages in thread
From: Hua Yanghao @ 2012-08-01  2:08 UTC (permalink / raw)
  To: nick clifton; +Cc: binutils

Hi Nick,
Thanks a lot for the information.
Figured out another way works also, in linker script sections,
a variable can be directly assigned an address like:
a = 0x8000
b = 0x8004
...

I'm using binutils 2.22, not the latest dev version though.
I guess the previous designer is just lucky since ARM linker do
place those variables in order as its declaration.

And sure we will change the design soon ...

Best Regards,
Yanghao

On Tue, Jul 31, 2012 at 8:32 PM, nick clifton <nickc@redhat.com> wrote:
> Hi Yanghao,
>
>> I know this is bad design and should not be relied on,
>> but that's the burden must be carried for the porting.
>
>
> Really you should fix the code to remove this reliance.  It really is bad
> practice to code that way.  That said...
>
>
>
>> So here my question is,in GNU/ld is there any way to make the
>> variable allocation order (or assignment order) exactly the same
>> as the declaration order?
>
>
> You don't say which version of the binutils you are using.  I will assume
> however that you are using the latest development sources, since otherwise
> this problem might have already been addressed.
>
> The short answer is "no".
>
> One possibility however, which might work, is to compile the program with
> -fdata-section and -fno-common specified.  Then all of the variables will be
> placed in individually named sections.  Next you would have to create a
> linker script which assigns these specific sections to the generic output
> section in the order that you desire.  (You would only need to do this for
> those variable whose ordering matters).
>
> For example:
>
>   % cat order.c
>   int a;
>   int b;
>   int c;
>
>   % gcc -fdata-sections -fno-common -c order.c
>
>   % readelf -S order.o
>   [...]
>    [ 4] .bss.a  NOBITS    00000000 000034 000004 00  WA  0   0  4
>    [ 5] .bss.b  NOBITS    00000000 000034 000004 00  WA  0   0  4
>    [ 6] .bss.c  NOBITS    00000000 000034 000004 00  WA  0   0  4
>   [...]
>
>   % cat b-after-a.script
>   SECTIONS
>   {
>         .bss :
>         {
>            *(.bss.a)
>            *(.bss.b)
>            *(.bss.*)
>            *(.bss)
>         }
>   }
>
>   % ld -T b-after-a.script order.o -Map b-after-a.map
>
>   % cat b-after-a.map
>   [...]
>   .bss          0x00000000        0xc
>     *(.bss.a)
>      .bss.a     0x00000000        0x4 order.o
>                 0x00000000                a
>    *(.bss.b)
>      .bss.b     0x00000004        0x4 order.o
>                 0x00000004                b
>    *(.bss.*)
>      .bss.c     0x00000008        0x4 order.o
>                 0x00000008                c
>    *(.bss)
>      .bss       0x0000000c        0x0 order.o
>
>   % cat b-before-a.script
>   SECTIONS
>   {
>         .bss :
>         {
>            *(.bss.b)
>            *(.bss.a)
>            *(.bss.*)
>            *(.bss)
>         }
>   }
>
>   % ld -T b-before-a.script order.o -Map b-before-a.map
>
>   % cat b-before-a.map
>  .bss           0x00000000        0xc
>    *(.bss.b)
>      .bss.b     0x00000000        0x4 order.o
>                 0x00000000                b
>    *(.bss.a)
>      .bss.a     0x00000004        0x4 order.o
>                 0x00000004                a
>    *(.bss.*)
>      .bss.c     0x00000008        0x4 order.o
>                 0x00000008                c
>    *(.bss)
>      .bss       0x0000000c        0x0 order.o
>
>
> This is complex I know, but I would hope that you would only have to do it
> for a few particular variables.
>
> Cheers
>   Nick
>

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-08-01  2:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-31  9:09 linker allocation order VS declaration order Hua Yanghao
2012-07-31 13:38 ` nick clifton
2012-08-01  2:08   ` Hua Yanghao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).