.data LMA overlapps .data VMA addresses
I am quite new to linker script concepts. I have ran into some strange problems.
the sections does not seem to have the right addresses for VMA.
For example if we look at the .data sections the VMA that has been provided in inside LMA+size. (meaning that during start-up once I copy the data from LMA to VMA the last bytes of LMA addresses will have been overwritten)
This is how the result looks like, see .data and you will see what I mean:
Sections: Idx Name Size VMA LMA File off Algn 0 .rcw 00000008 20000000 20000000 00010000 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 1 .init 00000628 20000008 20000008 00010008 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .text 000177f8 20000630 20000630 00010630 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 3 .flash_data 00000010 20017e28 20017e28 00027e28 2**0 CONTENTS, ALLOC, LOAD, READONLY, CODE 4 .rodata 00000ec0 20017e38 20017e38 00027e38 2**4 CONTENTS, ALLOC, LOAD, READONLY, DATA 5 .xcptn 000008e8 20019000 20019000 00029000 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 6 .extram 00002080 2001a000 200198e8 0002a000 2**13 CONTENTS, ALLOC, LOAD, DATA 7 .data 000008f0 2001c080 2001b968 0002c080 2**3 CONTENTS, ALLOC, LOAD, DATA 8 .got 00000010 2001c970 2001c258 0002c970 2**2 CONTENTS, ALLOC, LOAD, CODE 9 .got2 00000220 2001c980 2001c268 0002c980 2**2 CONTENTS, ALLOC, LOAD, DATA 10 .sdata 00000038 2001cba0 2001c488 0002cba0 2**2 CONTENTS, ALLOC, LOAD, DATA 11 .sbss 00000088 2001cbd8 2001c4c0 0002cbd8 2**2 ALLOC 12 .bss 0000bbbc 2001cc60 2001c548 0002cbd8 2**2 ALLOC 13 .isrvectbl 00000d88 2002881c 20028104 0002cbd8 2**2 ALLOC 14 .debug_aranges 00001618 00000000 00000000 0002cbd8 2**3 CONTENTS, READONLY, DEBUGGING 15 .debug_pubnames 00002843 00000000 00000000 0002e1f0 2**0 CONTENTS, READONLY, DEBUGGING 16 .debug_info 0003f23a 00000000 00000000 00030a33 2**0 CONTENTS, READONLY, DEBUGGING 17 .debug_abbrev 00009c89 00000000 00000000 0006fc6d 2**0 CONTENTS, READONLY, DEBUGGING 18 .debug_line 0000ae64 00000000 00000000 000798f6 2**0 CONTENTS, READONLY, DEBUGGING 19 .debug_frame 00003bb8 00000000 00000000 0008475c 2**2 CONTENTS, READONLY, DEBUGGING 20 .debug_str 00007b24 00000000 00000000 00088314 2**0 CONTENTS, READONLY, DEBUGGING 21 .debug_loc 00015465 00000000 00000000 0008fe38 2**0 CONTENTS, READONLY, DEBUGGING 22 .debug_ranges 00001768 00000000 00000000 000a52a0 2**3 CONTENTS, READONLY, DEBUGGING 23 .comment 00000750 00000000 00000000 000a6a08 2**0 CONTENTS, READONLY 24 .gnu.attributes 00000012 00000000 00000000 000a7158 2**0 CONTENTS, READONLY
the following ld-script is the one that has been provided to me:
ENTRY(__start) /* ***************************************************************** * PE_MPC5554_rom.ld * GNU powerpc-eabispe Linker Script for the MPC5554 * By default, this application runs in internal flash, SRAM, and cache * c. 2005, P&E Microcomputer Systems, Inc. * REV AUTHOR DATE DESCRIPTION OF CHANGE * --- ----------- ---------- --------------------- * 0.1 C.Baker FSL 19/Jul/06 Changed memory layout, stack * variables, and filename. * 0.2 C.Baker FSL 21/Sep/06 Changed stack in cache address. ***************************************************************** */ MEMORY { /* 32M External SRAM */ ext_ram : org = 0x20000000, len = 0x02000000 /* 32M on the G3 board */ /* Internal Flash RCW */ /* MPC5567 2M Internal Flash, but subtract two 128K blocks for use by emulated eeprom. */ /* but subtract one 128K block for use by BAM. */ /* MPC5567 80K Internal SRAM */ flash_rcw : org = 0x00000000, len = 0x8 int_flash : org = 0x00000008, len = 0x001BFFF8 int_sram : org = 0x40000000, len = 0x14000 /* e4_flash is reserved for emulated eeprom in partition 9 of the High Address Space. */ e4_flash : org = 0x001C0000, len = 0x40000 } /* The performance of applications can, potentially, be improved by locking */ /* the stack into the cache. However, as this complicates debugging (e.g., */ /* function parameters are not visible from GDB) it is only advisable for */ /* production code, not during development. Set STACK_IN_CACHE to 1 in the */ /* application's "config.inc" to lock the stack into cache. Otherwise, set */ /* STACK_IN_CACHE to 0, and the stack will be placed at the top of the */ /* internal RAM. */ /* Stack Address Parameters */ /* __SP_END = DEFINED( STACK_IN_CACHE ) ? 0x40040000 : 0x40013000; */ __SP_END = 0x40013000; __STACK_SIZE = 0x1000; __SP_INIT = __SP_END + __STACK_SIZE; /* Optionally define this variable with the address of heap __heap_start = __SP_END; */ /****************************************************************/ SECTIONS { .rcw : { KEEP( *(.rcw) ) } > ext_ram /* CRT0 startup code */ .pecrt0 ALIGN(8) : { *(.pecrt0) PEFILL = .; . = ALIGN(8); } > ext_ram .interp ALIGN(8) : { *(.interp) . = ALIGN(8); } > ext_ram .hash ALIGN(8) : { *(.hash) . = ALIGN(8); } > ext_ram .dynsym ALIGN(8) : { *(.dynsym) . = ALIGN(8); } > ext_ram .dynstr ALIGN(8) : { *(.dynstr) . = ALIGN(8); } > ext_ram .rela.dyn ALIGN(8) : { *(.rela.init) *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) *(.rela.fini) *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) *(.rela.ctors) *(.rela.dtors) *(.rela.got) *(.rela.sdata .rela.sdata.* .rela.gnu.linkonce.s.*) *(.rela.sbss .rela.sbss.* .rela.gnu.linkonce.sb.*) *(.rela.sdata2 .rela.sdata2.* .rela.gnu.linkonce.s2.*) *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) . = ALIGN(8); } > ext_ram .init ALIGN(8) : { PROVIDE (__init = .); KEEP( *(.init) ) . = ALIGN(8); } > ext_ram .text ALIGN(8) : { *(.text) *(.text.*) *(.gnu.warning) *(.gnu.linkonce.t*) __eabi = (.); /*PE*/ LONG(0x4E800020); . = ALIGN(8); } > ext_ram .fini ALIGN(8) : { /*PROVIDE (__fini = .);*/ KEEP( *(.fini) ) . = ALIGN(8); } > ext_ram .flash_data ALIGN(8) : { KEEP( *(.flash_data)) . = ALIGN(8); } > ext_ram .rodata ALIGN(8) : { . = ALIGN(8); *(.rodata) *(.rodata.*) *(.gnu.linkonce.r*) . = ALIGN(8); } > ext_ram .rodata1 ALIGN(8) : { *(.rodata1) . = ALIGN(8); } > ext_ram .PPC.EMB.apuinfo ALIGN(8) : { *(.PPC.EMB.apuinfo) . = ALIGN(8); } > ext_ram AT > ext_ram /* ISR table for software vector mode */ .isrvectbl ALIGN(0x800) : ONLY_IF_RO { KEEP( *(.isrvectbl) ) } > ext_ram PROVIDE (__EXCEPT_START__ = .); /* IVOR4Handler */ .xcptn ALIGN(8) : { KEEP( *(.xcptn) ) . = ALIGN(8); } > ext_ram PROVIDE (__EXCEPT_END__ = .); etext = .; _etext = .; __etext = .; /******************************************************************/ NEXT_LOAD_ADDR = .; __EXTDATA_ROM = .; .extram : AT (NEXT_LOAD_ADDR) { *(.extram) . = ALIGN(4); } > ext_ram /******************************************************************/ NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.extram); /*NEXT_LOAD_ADDR = .; __DATA_ROM = .;*/ __DATA_ROM = NEXT_LOAD_ADDR; /* .PPC.EMB.sdata2 0x20100000 : AT (NEXT_LOAD_ADDR)*/ .PPC.EMB.sdata2 : AT (NEXT_LOAD_ADDR) { _SDA2_BASE_ = .; __SDATA2_START__ = .; *(.PPC.EMB.sdata2) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.PPC.EMB.sdata2); .sdata2 : AT (NEXT_LOAD_ADDR) { *(.sdata2) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.sdata2); .PPC.EMB.sbss2 : AT (NEXT_LOAD_ADDR) { *(.PPC.EMB.sbss2) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.PPC.EMB.sbss2); .sbss2 : AT (NEXT_LOAD_ADDR) { *(.sbss2) __SBSS2_END__ = .; . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.sbss2); .data : { *(.data) *(.data.*) *(.gnu.linkonce.d*) CONSTRUCTORS . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.data); .data1 : { *(.data1) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.data1); PROVIDE (__GOT_START__ = .); .got : { *(.got) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_AD开发者_运维知识库DR + SIZEOF(.got); .got.plt : { *(.got.plt) . = ALIGN(8); } > ext_ram PROVIDE (__GOT_END__ = .); NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got.plt); .got1 : { *(.got1) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got1); PROVIDE (__GOT2_START__ = .); .got2 : { *(.got2) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.got2); PROVIDE (__CTOR_LIST__ = .); .ctors : { /*KEEP (*crtbegin.o(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) KEEP (*(SORT(.ctors.*)))*/ KEEP (*(.ctors)) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.ctors); PROVIDE (__CTOR_END__ = .); PROVIDE (__DTOR_LIST__ = .); .dtors : AT (NEXT_LOAD_ADDR) { /*KEEP (*crtbegin.o(.dtors)) KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) KEEP (*(SORT(.dtors.*)))*/ KEEP (*(.dtors)) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.dtors); PROVIDE (__DTOR_END__ = .); PROVIDE (__FIXUP_START__ = .); .fixup : AT (NEXT_LOAD_ADDR) { *(.fixup) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.fixup); PROVIDE (__FIXUP_END__ = .); PROVIDE (__GOT2_END__ = .); .dynamic : AT (NEXT_LOAD_ADDR) { *(.dynamic) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.dynamic); .plt : AT (NEXT_LOAD_ADDR) { *(.plt) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.plt); /* We want the small data sections together, so single-instruction offsets can access them all, and initialized data all before uninitialized, so we can shorten the on-disk segment size. */ __SDATA_ROM = .; .sdata : { __SDATA_START__ = .; _SDA_BASE_ = .; *(.sdata) . = ALIGN(8); } > ext_ram NEXT_LOAD_ADDR = NEXT_LOAD_ADDR + SIZEOF(.sdata); .PPC.EMB.sdata0 : AT (NEXT_LOAD_ADDR) { __SDATA_END__ = .; . = ALIGN(8); } > ext_ram __DATA_ROM_END = .; edata = .; _edata = .; __edata = .; /******************************************************************/ .sbss BLOCK (4): { PROVIDE (__sbss_start = .); PROVIDE (___sbss_start = .); *(.sbss) *(.scommon) *(.dynsbss) } > ext_ram .PPC.EMB.sbss0 BLOCK (4): { *(.PPC.EMB.sbss0) PROVIDE (__sbss_end = .); PROVIDE (___sbss_end = .); PROVIDE (__SBSS_END__ = .); } > ext_ram .bss BLOCK (4): { PROVIDE (__bss_start = .); PROVIDE (___bss_start = .); *(.dynbss) *(.bss) *(COMMON) PROVIDE (__bss_end = .); } > ext_ram .isrvectbl BLOCK (4) (NOLOAD): ONLY_IF_RW { . = ALIGN(0x800); KEEP( *(.isrvectbl) ) } > ext_ram /* ISR table for software vector mode */ /******************************************************************/ /* Heap grows from lower to higer addresses Stack grows from higer to lower addresses */ /* Define position of heap */ /* Default to location contiguous with .bss section in RAM */ _end = DEFINED (__heap_start) ? __heap_start : ALIGN(8); PROVIDE(end = _end); PROVIDE(__end = _end); /******************************************************************/ .gcc_except_table : {*(.gcc_except_table)} /* These are needed for ELF backends which have not yet been converted to the new style linker. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } /* DWARF debug sections. Symbols in the DWARF debugging sections are relative to the beginning of the section so we begin them at 0. */ /* DWARF 1 */ .debug 0 : { *(.debug) } .line 0 : { *(.line) } /* GNU DWARF 1 extensions */ .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } /* DWARF 1.1 and DWARF 2 */ .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } /* DWARF 2 */ .debug_info 0 : { *(.debug_info) } .debug_abbrev 0 : { *(.debug_abbrev) } .debug_line 0 : { *(.debug_line) } .debug_frame 0 : { *(.debug_frame) } .debug_str 0 : { *(.debug_str) } .debug_loc 0 : { *(.debug_loc) } .debug_macinfo 0 : { *(.debug_macinfo) } /* SGI/MIPS DWARF 2 extensions */ .debug_weaknames 0 : { *(.debug_weaknames) } .debug_funcnames 0 : { *(.debug_funcnames) } .debug_typenames 0 : { *(.debug_typenames) } .debug_varnames 0 : { *(.debug_varnames) } /* */ .eh_frame 0 : { *(.eh_frame) } /******************************************************************/ __SRAM_CPY_START = ADDR(.PPC.EMB.sdata2); __IV_ADDR = ADDR(.xcptn); __SRAM_LOAD = (_end); __SRAM_LOAD_SIZE = (SIZEOF(.flash_data) / 4); __EXTRAM_CPY_START = ADDR(.extram); __EXTRAM_CPY_END = ADDR(.extram)+SIZEOF(.extram); __BSS_SIZE = ((__bss_end - __bss_start) / 4); __SBSS_SIZE = ((__sbss_end - __sbss_start) / 4); TEMPSIZE = SIZEOF(.PPC.EMB.sdata2)+SIZEOF(.sdata2)+SIZEOF(.PPC.EMB.sbss2)+SIZEOF(.sbss2)+SIZEOF(.data)+SIZEOF(.data1); TEMPSIZE = TEMPSIZE + SIZEOF(.got)+SIZEOF(.got.plt)+SIZEOF(.got1)+SIZEOF(.got2)+SIZEOF(.ctors); TEMPSIZE = TEMPSIZE + SIZEOF(.dtors)+SIZEOF(.fixup)+SIZEOF(.dynamic)+SIZEOF(.plt); TEMPSIZE = TEMPSIZE + SIZEOF(.sdata)+SIZEOF(.PPC.EMB.sdata0); __ROM_COPY_SIZE = (TEMPSIZE); __DATA_VMA = ADDR(.data); __DATA_LMA = LOADADDR(.data); __DATA_LMA_END = __DATA_LMA + SIZEOF(.data); __GOT_VMA = ADDR(.got); __GOT_LMA = LOADADDR(.got); __GOT_LMA_END = __GOT_LMA + SIZEOF(.got); __GOT2_VMA = ADDR(.got2); __GOT2_LMA = LOADADDR(.got2); __GOT2_LMA_END = __GOT_LMA + SIZEOF(.got2); __SDATA_VMA = ADDR(.sdata); __SDATA_LMA = LOADADDR(.sdata); __SDATA_LMA_END = __SDATA_LMA + SIZEOF(.sdata); }
EDIT1: I get no error/warning when I make all. The linker is suppose to build everything for external memory with starts at 0x20 000000.
It seems your linker skript tries to compress the image for storage in flash. During runtime your image is copied to other addresses maybe because of MMU alignment restrictions.
Does the linker emit an error message or is this just that your code does not behave correctly at runtime?
The copy problem you mentioned can be easily bypassed if you copy the sections "backwards".
Copy the last item of the .data section to its runtime address, then copy the next-to-last item to its runtime address...
精彩评论