/* * File: armelf.brew * * Simple Linker Script for 4.1.0 WinARM Tool Chain for BREW * * This linker script creates an ELF suitable for input to BREWelf2Mod. * Please read the comments and don't be afraid. * * Besides taking care of some BREW housekeeping, its big claim to fame * is KEEP()-ing the .data and .bss segments around in the 4.x GCC world * (even if empty) so BREWelf2mod (I'm using 53,248 byte version of 15 Mar 04) * doesn't go nuts and make multi-megabyte mod files. * * This script takes care of the -entry, and -T text 0 switches for you, * and, on a good day, arranges for AEEModGen.o to be linked first. * (You could add another line for AEEAppGen.o after too, then you would * not have to specify either when linking.) * * This is free and unrestricted for your use and modification. * Standard disclaimers. Please return useful changes to the forum. * * Use: * \winarm\bin\arm-elf-ld.exe --script armelf.brew * --emit-relocs * --verbose * --no-warn-mismatch * -Map "myapp.map" --cref * -L \winARM\lib\gcc\arm-elf\4.1.0\ [...] * -o "myapp.elf" * AEEAppGen.o myapp.o ... * * --emit-relocs and --script are _required_. * * * HISTORY * * 04May06 Ward Willats / VeriSign First try * 08May06 Ward Willats / VeriSign Force section with ARRModLoad to be first * 30Jul06 Ward Willats / VeriSign force alignment of .bss -- fixes odd-ball * crashes in relocation fixup code if sizes * happen to come out odd */ OUTPUT_FORMAT("elf32-littlearm") /* change or add elf32-bigarm if you need it */ OUTPUT_ARCH(arm) ENTRY(AEEMod_Load) /* don't need -entry switch anymore, silence warnings */ SECTIONS { /* This is the text section. I am setting both the RVA and LMA ...to zero. This means you don't have to use -T text 0 on the ...command line. Also, I am forcing AEEModGen.o to be first. ...this implies LD can find it, either because it is in the ...current working directory, or because of -L on the ...command line, or you adding a SEARCH_PATH() built in function ...call (does the same thing as -L) to the top of this file */ .text 0 : AT( 0 ) { /* This locates AEEMod_Load and makes sure it is first no matter ...what your optimization settings are. You _MUST_ compile ...AEEModGen.c with -ffunction-sections for this to work. The object file must be in the current/build directory. */ "AEEModGen.o"(.text.AEEMod_Load) /* and bring in all the other code */ *(.text .text.* .gnu.linkonce.t.*) /* .text and .text.func name -- if separate sections for each file */ *(.glue_7t) *(.glue_7) } /* Following provides symbolic .fini section with symbols to ...mark the end of .text, but not used by BREWelf2mod, I think. ...Dunno about RTL. "KEEP()" makes sure this emtpy sections gets ...by empty section garbage collection by ld . This is symbolic ...so "free" to keep here. */ .fini : { KEEP( *(.fini) ) } = 0 PROVIDE (__etext = .); PROVIDE (_etext = .); PROVIDE (etext = .); /* Read-Only Data */ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.* ) } /* You shouldn't have any initialized global data here, you bad ...boy, but BREWelf2mod definitely needs a .data section in the ...output file NO MATTER WHAT, so it can figure out how long the ...text section is. */ .data : { __data_start = . ; /* this label probably isn't used, but */ KEEP( *(.data .data.* .gnu.linkonce.d.* ) ) } /* Okay, uninitialized global variables go here. I found out ...by leaving this out BREWelf2mod uses this in its calculations ...too -- probably to determine image size (which it records in the ...header of the startup code it sticks on the mod file). So you must KEEP() ...it. I also added labels marking the beginning and end of bss. ...My thinking is that, although the mod startup code BREWelf2mod adds ...to the mod image _may_ zero BSS, you could guarantee it by having ...the first thing that happens in AEEMod_Load() be something like: ... ... byte * pby = (byte*) &__bss_start; ... byte * pbyEnd = (byte*) &__bss_end; ... while( pby < pbyEnd ) *pby++ = 0; ... ...or, you know, a fancy 32-bit loop for ARM. ... ... */ __bss_start = NEXT(0x8); .bss ALIGN(0x8): { KEEP( *(.bss .bss.* .gnu.linkonce.b.* ) ) *(COMMON) } __bss_end = .; /* Don't think BREW needs this either but seems good to provide ...end of everything" label */ __end__ = . ; _end = .; PROVIDE (end = .); /* Following debugging stuff I just lifted wholesale from armelf.xc */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) } .stab.excl 0 : { *(.stab.excl) } .stab.exclstr 0 : { *(.stab.exclstr) } .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } .debug 0 : { *(.debug) } .line 0 : { *(.line) } .debug_srcinfo 0 : { *(.debug_srcinfo) } .debug_sfnames 0 : { *(.debug_sfnames) } .debug_aranges 0 : { *(.debug_aranges) } .debug_pubnames 0 : { *(.debug_pubnames) } .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } .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) } /* and we don't need a stack segment for BREW since AEE ...takes care of everything */ } /* end: armelf.brew */