linker allocation order VS declaration order

nick clifton nickc@redhat.com
Tue Jul 31 13:38:00 GMT 2012


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



More information about the Binutils mailing list