English 中文(简体)
LD linker: Target address aligning but not address in ROM
原标题:

I have a program that s resident in flash and will run from flash. Early in the program data segments are copied from flash to ram. I m using a linker script like (simplified):

.text      :
{
  *(.text)
} > FLASH
_etext = .;
PROVIDE (etext = .);

.rodata     :
{
  PROVIDE(__COPY_DATA_START__ = .); 
  *(.rodata) 
} > ram AT>flash

PROVIDE (__SDATA2_START__ = .);
.sdata2   :
{ 
  *(.sdata2)
} > ram AT>flash

PROVIDE (__sbss2_start = . );
.sbss2   : { 
  *(.sbss2) 
  . = ALIGN(4)
} > ram AT>flash
PROVIDE (__sbss2_end = . );
PROVIDE (__SBSS2_END__ = .);

.data    :
{
  *(.data)
  *(.gnu.linkonce.d*)
  CONSTRUCTORS
  *(.eh_frame)
} > ram AT>flash
PROVIDE (__END_COPY__ = .);

I want the sections to be aligned on 4-byte boundaries (architecture is PowerPC 32-bit). Some of the data sections include sub-word items. I m finding that the ALIGN instruction aligns the VMA address in RAM but doesn t align the LMA. So my copy-to-ram routine fails because the two areas don t correspond byte-for-byte.

My copy routine looks like

r3 = address in flash of _etext
r4 = address in ram of __COPY_DATA_START__
words to copy = (__END_COPY__ - COPY_DATA_START) / 4

while (words to copy)
  * r4++ = *r3++

When the loop gets to an aligned bit, the destination points to some pad bytes, but the source data doesn t include the align-padding so the data gets put too early in memory.

I can tell this from the map file because it looks like (contrived example)

.rodata         0x00000000      0xb15 load address 0xfff13000
                0x00000000                PROVIDE (__COPY_DATA_START__, .)

.sdata          0x00000b18      0x10  load address 0xfff13b15  <<< origin 0xb18 is aligned but load address hasn t moved on by the padding bytes

Does anyone know the solution to this problem?

Thank you

Chris

最佳回答

I ve had some success by using a different form of the "AT" linker script command. If I use

  _etext = .;
  PROVIDE (etext = .);
  .rodata : AT (_etext)
  { 
... contents of section ...
  }

  .sdata2 : AT (_etext + SIZEOF(.rodata) + SIZEOF(.gcc_except_table))
  { 
... contents of section ...
  } > ram

  .sbss2 : AT (_etext + SIZEOF(.rodata) + SIZEOF(.gcc_except_table) + SIZEOF(.sdata2) )
  { 
... contents of section ...
    . = ALIGN(16);
  } > ram 

Then it seems to align as I would expect. The SIZEOF( ) + SIZEOF( ) ... string gets pretty long by the end of the file but at least it works.

(Additional info: Normally you wouldn t copy the rodata section into ram because it s read only. On my system the flash can t handle the kind of accesses requured for floating point constants, so I do need to copy it into RAM even though it won t be modified).

问题回答

It does not appear that you stated which linker you are using, but your script looks like a GNU linker script (so I will assume it is). To align both the VMA and LMA of a section using a GNU linker script do something like this...

.section_name ALIGN( vma_alignment ) : ALIGN( lma_alignment ){
  ...section contents
}

.section_name is the name of the output section to align, and can be any legal name. The ALIGN statement on the left of the colon affects the VMA alignment, and the ALIGN statement on the right of the colon affects the LMA alignment. In your case you want vma_alignment = lma_alignment = 4. See section 3.6.1 of the GNU Linker reference manual.

So your overall script should look like the one below...

.text      :
{
  *(.text)
} > FLASH
_etext = .;
PROVIDE (etext = .);

.rodata ALIGN(4)  : ALIGN(4)
{
  PROVIDE(__VMA_COPY_DATA_START__ = ADDR(.rodata)); /*The runtime address of .rodata*/
  PROVIDE(__LMA_COPY_DATA_START__ = LOADADDR(.rodata)); /*The load address of .rodata*/

  *(.rodata) 
} > ram AT>flash

PROVIDE (__SDATA2_START__ = .);
.sdata2   :
{ 
  *(.sdata2)
} > ram AT>flash

PROVIDE (__sbss2_start = . );
.sbss2   : { 
  *(.sbss2) 
  . = ALIGN(4)
} > ram AT>flash
PROVIDE (__sbss2_end = . );
PROVIDE (__SBSS2_END__ = .);

.data    :
{
  *(.data)
  *(.gnu.linkonce.d*)
  CONSTRUCTORS
  *(.eh_frame)
} > ram AT>flash
 /*
 *align address so that (__END_COPY__ -  __VMA_COPY_DATA_START__) / 4 does not round down.
 *If alignment is not done then the copy routine could potentially drop up to 3 bytes at 
 *the end of the .data section if the section does not end on a multiple of 4 bytes.
 */
. = ALIGN(4)
PROVIDE (__END_COPY__ = .);

And your copy routine would look like...

r3 = address in flash of __LMA_COPY_DATA_START__
r4 = address in ram of   __VMA_COPY_DATA_START__
words_to_copy = (__END_COPY__ -  __VMA_COPY_DATA_START__) / 4

while (words_to_copy){
  * r4++ = *r3++
  words_to_copy--
}




相关问题
Where are the symbols etext, edata and end defined?

This is a code from Linux man page: #include <stdio.h> #include <stdlib.h> extern char etext, edata, end; int main() { printf("First address past: "); printf(" program text (...

Problem statically linking MFC libraries

I have a Visual Studio 6 workspace I m trying to convert to a Visual Studio 2008 solution. The output of said solution is a .dll. It has to be a .dll and it needs to statically link MFC as I can t ...

Create a shared lib using another shared lib

I have a shared library "libwiston.so". I am using this to create another shared library called "libAnimation.so", which will be used by another project. Now, the second library "libAnimation.so" can ...

C++ linker - Lack of duplicate symbols

Why does the following code not give me a duplicate symbol linker error for Impl? I ran across this problem in some code I inherited and I m recreating a shorter version here for simplicity. I have ...

problem w/ linking static function g++

I am trying to build a small program and I have my own library libfoo. I have a camera class that is calling a static function from my Vector3 class (i.e. crossProduct). My camera class and Vector3 ...

Extract statically linked libraries from an executable

I m not sure if this is even possible, but given an executable file (foo.exe), with has many libraries which has been linked statically. Is there any software that extract from this file the .lib ( ...

热门标签