HOWTO: Compile with GNU WinARM 4.1.0 | developer.brewmp.com HOWTO: Compile with GNU WinARM 4.1.0 | developer.brewmp.com

Developer

HOWTO: Compile with GNU WinARM 4.1.0

05May06 - PART ONE

This post is a HOWTO of information describing how I was able to build
(several) working brew MOD files using the WinARM 4.1.0 toolchain. It
collects info I've already posted here and elsewhere into one place
and also provides a custom BREW-specific linker script for the GNU ld
linker.

I hope this information saves you headaches, but unfortunately I can't
support you and the standard disclaimers apply. I've tried my best to
be accurate, but a lot of this area is poorly or un-documented, so
sometimes I guess and sometimes guess wrong (or only half-right).

Caveat developer!

We do C++ work in the native Win32 environment, so my steps are skewed
to that environment. I have compiled a project of over 400 source
files resulting in a MOD of over 1 MB.

So, onward, through the fog...

A) WHY WOULD YOU WANT TO DO THIS?

The gnude toolchain most folks seem to be using (as BREWelf2mod was
originally developed against it) is now 3 years old, and its ARM code
generation is by today's standards, poor. This (and the way BREWelf2mod
packages up the output MOD file) means that GNU mod files have gotten
a reputation "for being at least 20% larger than ADS!" Yeah, but this
situation probably changes if you use a recent compiler, plus:

o You gain access to mutable, unitialized global variables with GNU (.bss)

o You can take advantage of the LightBlue project's clever work that maps
BREW interface structures directly to C++ vtables.
(http://lightblue.tigris.org/)

o It is free.

At the end of this post I'll review how module loading works and the
current state of BREW C++ toolchains (as I understand it).

B) WHAT DOES NOT WORK?

o THUMB. I can't make this go with gnude (which does not even compile
some of our source) nor with WinARM. I have just started to debug this
with my WinARM-generated module, but it doesn't even clearly seem
related to interworking at this point. AEEMod__Load executes to the
end, but either as that routine is exited or sometime after, the phone
blows up. (And yes, AEEModGen and AEEAppGen are compiled in ARM mode.)

o Some optimizations: An -O2 compile reset my phone.

o The usual things: RTTI, GNU exceptions, floating point.

C) STEP-BY-STEP

1. Download the latest WinARM (4.1.0 at this writing) from
http://gandalf.arubi.uni-kl.de/avr_projects/arm_projects/#winarm.
I used this because it was the most recent one I could find that ran
natively under Win32 (no CygWin) and was pre-built.

2. Unpack.

3. Compile your C++ sources with:

\winarm\bin\arm-elf-g++.exe
-mlittle-endian // or -mbig-endian if that's your target
-mcpu=arm7tdmi // or the right CPU for you, this is common
-mapcs-frame // use the "standard" arm procedure call standard
// (linked calling frames on the stack)

-fno-builtin // Don't generate inline versions memcpy(), memset()
// etc. Both because they may make the code larger, and
// because you need to call the BREW versions MEMCPY()
// and so forth.

-ffunction-sections // put each function in a separate .text._foo section
// this lets the linker throw away ones that are not
// called when it "garbage collects" (drops empty)
// sections. The default behavior for GCC ld 4.x seems
// to be to garbage collect, so the old --gc-sections switch
// is no longer necessary or recognized. (But, the
// new --no-gc-sections switch is, if you need to
// keep an uncalled section around for some reason.
// But for this, changing the linker script is
// probably a better choice.)

-fno-exceptions // nope, you can't have C++ exceptions. And if you
// try it you'll suck in a bunch of library stuff
// that won't link.

-fno-unwind-tables // When exceptions are thrown the stack needs to
// "unwound" and destructors called. These tables
// are not supported.

-fno-rtti // Nope, no runtime type identification either, so
// no new-fnagled dynamic_cast<>()-ing either.

// All of these -fno-xxx things pull in library stuff and
// use globals. It may be possible to support
// them at a later time with open-source loaders
// and a good understanding of run-time internals.

-DDEBUG // If you need it

-DDYNAMIC_APP // Everyone includes this in applets, but I never
// see it used in the BREW headers (I think) Is it
// vestiagl? Or does it do something?

-I "C:\Program Files\BREW 3.1.5\sdk\inc" // and other include paths...
// repeat the -I for each one

-o applet.o // Your output (EABI ELF) file

-c applet.c // Your input source

4. Compile your C sources with:

\winarm\bin\arm-elf-gcc.exe
-mlittle-endian
-mcpu=arm7tdmi
-mapcs-frame
-fno-builtin
-ffunction-sections
-DDEBUG
-DDYNAMIC_APP
-I "C:\Program Files\BREW 3.1.5\sdk\inc"
-o AEEModGen.o -c AEEModGen.c

You should use the C compiler for both AEEModGen.o and AEEAppGen.o.

If you are compiling thumb, AEEModGen.o (and probably AEEAppGen.o)
need to be compiled in ARM mode (with interworking support -- add
-mthumb-interwork to all of the compiler command lines, and -mthumb to
the modules you want to actually be compiled to thumb instructions).

Since thumb doesn't work I won't talk about anymore, except to note
that the startup code BREWelf2mod sticks on your module seems to a
jump through a register to hit AEEMod_Load() and could probably hit a
thumb target. More likely, the Brew AEE has trouble calling thumb code
directly to new-up the instances (though perhaps some clever person
could switch to thumb with some preamble code right inside the
routines the AEE calls....GNU has "attribute" keywords to build stuff
like this...)

5. Link.

This is where things get tricky. The idea is to make an ELF file that
can be fed to BREWelf2mod. Now, BREWelf2mod needs to see some things
in the ELF file, or it will gack. Specifically:

o It needs access to every rellocation in the ELF file.

o It needs your code (the .text section) to be based at an address of
zero (so the simple-minded tiny loader BREWelf2mod sticks on your MOD
file can "fix up" (locate) your program easily.

o It needs your file to have a .data and .bss section that follow your
.text section -- or it won't be able figure out how big things are
(and will happily make a multi-megabyte MOD file...)

o It needs AEEMod_Load() to be the first thing in your ELF file's
.text section.

o There is an unconfirmed report BREWelf2mod can't process functions
with more than, perhaps 255 characters in the name. This is because it
consumes the output of a program it exec()s to get the rellocation
list as ASCII: objdump, and may only have a fixed buffer inside to
hold the lines. Nicely, it just outputs a broken file if this happens.

So...if you do something mad like trying to use templates in your C++,
this might bite you. Be careful.

Anyway, back to linking. To get the rellocations to be placed in the
ELF output, use --emit-relocs.

Now, traditionally, to get the .text scection loaded at zero you had
to use "-T text 0." And to quiet a linker warning you had to provide an
entry point, AEEMod_Load(), with "-entry AEEMod_Load." And to get all
the rellocations together, sorted and in the right place in the
output, you either had to use the right (.xc) linker script -- that,
thankfully, gnude used by default OR force it to use the (.xc) script
with a -zcombreloc switch when using other toolchains (Sourcery).

And to get AEEModGen.o first you had to stick it first on the command
line with something like this:

AEEModLoad.o AEEAppGen.o -( onelib twolib threelib -)

Note: unlike a lot of other linkers, GNU only searchs libraries once
unless you "group" them -- that what the -( and -) switches above do
to the example libraries "onelib" "twolib" and "threelib."

I guess this didn't even work for some folks and they wound up putting
AEEMod_Load() into a separate file. I've never had _that_ problem.

Finally, to be sure a .bss and .data section were in your output, you
didn't have to do ANYTHING -- if you were a good BREW programmer they
would both be empty, but the old gnude chain would keep them around
anyway. Not so with 4.1.0, it drops them faster than you can say
"empty section" -- so BREWelf2mod would get confused and make ENORMOUS
output files.....

05May06 PART TWO
The way to address this is with a "linker script." This program that
tells ld how to take the input files and arrange them in the output.
(Equivalent to ADS scatter files). In that scrpit, you can do
everything you can do on the command line PLUS, keep the .data and
.bss sections around no matter what. Very handy.
And...as long as I was writing a linker script, I figured I'd
automatically load AEEModGen.o first, set the text section offset to
zero, and provide an entry point so you don't have to.
So, given we have a custom linker script, the link command becomes:
\winarm\bin\arm-elf-ld.exe
--script armelf.brew // req: use custom script
--emit-relocs // req: BREWelf2mod needs the relocation info
--verbose // opt: be verbose, handy
--no-warn-mismatch // opt: you shouldn't have mismatch warnings, esp
// if not generating thumb code. Usually this warns
// you try to glue an interworking supporting object
// to one that does not, or ld _thinks_ does not...
-Map "wardtest.map" --cref // opt: make a cross referenced map if you need it
-L \winARM\lib\gcc\arm-elf\4.1.0\ // this is where to look if building ARM. If thumb
// you'll have mixed ARM and thumb calling the library
// and need to go down into the interworking and
// interworking/thumb directories.
-lgcc // This is the only one I've needed to link everything
-o "wardtest.elf" // output file
AEEAppGen.o // input file
applet.o // input file
Note that I did not specify AEEModGen.o. The linker script takes care
of this. See next section.
About __cxa_purevirtual, memcpy(), memset(): The compiler generates
these by itself and they need to be satisfied. Qualcomm provides a
module called GCCResolver.o to do this, or you can just define them in
your code. __cxa_purevirtual needs to do nothing. memcpy(), memset(),
strlen() (or any others) need to call their BREW AEEStdLib.h
equivalents.
That's right GCCResolver is not from GNU and has nothing to do with
DNS!
Here is a more complicated input file scheme
\winARM\bin\arm-elf-ld.exe
--verbose
--no-warn-mismatch
-Map "myapp.map" --cref
--emit-relocs
-L "mylibpath1" -L "mylibpath2" ... // quotes optional
--script armelf.brew
-o "myapp.elf" AEEAppGen.o -( -l LONE -l LTWO -l LTHREE -l LFOUR -l gcc -)
This says that somewhere in "mylibpaths" I have 4 libraries: libONE.a,
libTWO.a, libTHREE.a, libFOUR.a and libgcc.a.
Note again I did not specify AEEModGen.o -- don't have to. The
armelf.brew linker script brings it in for me.
6. Run BREWelf2mod and pray.
I talk about BREWelf2mod below. The key thing is that it strips all
the ELF stuff off your image, squirts out your code and a table of
relocations and slaps a 0x9C long startup routine onto your file
before AEEMod_Load().
To get the relocations, it exec()s arm-elf-objdump and processes the
ASCII list of reloactions that come out.
Now, BREWelf2mod and the loader only understand a couple of
rellocation types, specifically R_ARM_PC24 and R_ARM_ABS32. If you
have compiled straight ARM code all the way, that should be all that
is in your objdump output. So you can use the objdump that comes with
the WinARM toolchain:
BREWelf2mod myapp.elf myapp.mod \winARM\bin\arm-elf-objdump.exe
(If you build thumb, the new toolchain's objdump emit an R_THM_CALL
relocation instead of the old name for this, R_ARM_PC22. You can get
around this by specifying an old version of objdump -- like the one
from gnude:
BREWelf2mod myapp.elf myapp.mod \gnude\bin\arm-elf-objdump.exe
...or..writing a wrapper program, or maybe just patching the string in
the BREWelf2mod.exe directly.
BTW, I am using BREWElf2Mod of 15 March 2004, at 52,248 bytes.
7. Download your module with Apploader and start debugging.

05May06 PART TWO
The way to address this is with a "linker script." This program that
tells ld how to take the input files and arrange them in the output.
(Equivalent to ADS scatter files). In that scrpit, you can do
everything you can do on the command line PLUS, keep the .data and
.bss sections around no matter what. Very handy.
And...as long as I was writing a linker script, I figured I'd
automatically load AEEModGen.o first, set the text section offset to
zero, and provide an entry point so you don't have to.
So, given we have a custom linker script, the link command becomes:
\winarm\bin\arm-elf-ld.exe
--script armelf.brew // req: use custom script
--emit-relocs // req: BREWelf2mod needs the relocation info
--verbose // opt: be verbose, handy
--no-warn-mismatch // opt: you shouldn't have mismatch warnings, esp
// if not generating thumb code. Usually this warns
// you try to glue an interworking supporting object
// to one that does not, or ld _thinks_ does not...
-Map "wardtest.map" --cref // opt: make a cross referenced map if you need it
-L \winARM\lib\gcc\arm-elf\4.1.0\ // this is where to look if building ARM. If thumb
// you'll have mixed ARM and thumb calling the library
// and need to go down into the interworking and
// interworking/thumb directories.
-lgcc // This is the only one I've needed to link everything
-o "wardtest.elf" // output file
AEEAppGen.o // input file
applet.o // input file
Note that I did not specify AEEModGen.o. The linker script takes care
of this. See next section.
About __cxa_purevirtual, memcpy(), memset(): The compiler generates
these by itself and they need to be satisfied. Qualcomm provides a
module called GCCResolver.o to do this, or you can just define them in
your code. __cxa_purevirtual needs to do nothing. memcpy(), memset(),
strlen() (or any others) need to call their BREW AEEStdLib.h
equivalents.
That's right GCCResolver is not from GNU and has nothing to do with
DNS!
Here is a more complicated input file scheme
\winARM\bin\arm-elf-ld.exe
--verbose
--no-warn-mismatch
-Map "myapp.map" --cref
--emit-relocs
-L "mylibpath1" -L "mylibpath2" ... // quotes optional
--script armelf.brew
-o "myapp.elf" AEEAppGen.o -( -l LONE -l LTWO -l LTHREE -l LFOUR -l gcc -)
This says that somewhere in "mylibpaths" I have 4 libraries: libONE.a,
libTWO.a, libTHREE.a, libFOUR.a and libgcc.a.
Note again I did not specify AEEModGen.o -- don't have to. The
armelf.brew linker script brings it in for me.
6. Run BREWelf2mod and pray.
I talk about BREWelf2mod below. The key thing is that it strips all
the ELF stuff off your image, squirts out your code and a table of
relocations and slaps a 0x9C long startup routine onto your file
before AEEMod_Load().
To get the relocations, it exec()s arm-elf-objdump and processes the
ASCII list of reloactions that come out.
Now, BREWelf2mod and the loader only understand a couple of
rellocation types, specifically R_ARM_PC24 and R_ARM_ABS32. If you
have compiled straight ARM code all the way, that should be all that
is in your objdump output. So you can use the objdump that comes with
the WinARM toolchain:
BREWelf2mod myapp.elf myapp.mod \winARM\bin\arm-elf-objdump.exe
(If you build thumb, the new toolchain's objdump emit an R_THM_CALL
relocation instead of the old name for this, R_ARM_PC22. You can get
around this by specifying an old version of objdump -- like the one
from gnude:
BREWelf2mod myapp.elf myapp.mod \gnude\bin\arm-elf-objdump.exe
...or..writing a wrapper program, or maybe just patching the string in
the BREWelf2mod.exe directly.
BTW, I am using BREWElf2Mod of 15 March 2004, at 52,248 bytes.
7. Download your module with Apploader and start debugging.

05May06 PART THREE
D) THE LINKER SCRIPT
This is my first linker script, so I may have made stupid mistakes,
but so far it is working. I used
http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/s...
to learn about this. Hopefully it is not too out of date.
My philosophy was to start with nothing and add stuff I needed or
seemed "nice to have" -- this way I understand the reason for
everything in there. The default GNU linker scripts are so terrifying
because they include everything for every platform. We don't need
that.
Take this text and put it in a "armelf.brew" file and call it with the
--script switch to LD as shown above.
/*
* 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
*
*/
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 )
{
AEEModGen.o(.text)
*(.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 = .;
.bss : { 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 */

05May06 PART THREE
D) THE LINKER SCRIPT
This is my first linker script, so I may have made stupid mistakes,
but so far it is working. I used
http://www.redhat.com/docs/manuals/enterprise/RHEL-4-Manual/gnu-linker/s...
to learn about this. Hopefully it is not too out of date.
My philosophy was to start with nothing and add stuff I needed or
seemed "nice to have" -- this way I understand the reason for
everything in there. The default GNU linker scripts are so terrifying
because they include everything for every platform. We don't need
that.
Take this text and put it in a "armelf.brew" file and call it with the
--script switch to LD as shown above.
/*
* 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
*
*/
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 )
{
AEEModGen.o(.text)
*(.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 = .;
.bss : { 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 */

05May06 PART FIVE
E) DEVELOPMENT TOOLS OVERIVEW
I already posted this elsewhere, but I've updated and here is my read as of early May 2006:
GNU Gnude:
Pro:
Works
Cons:
Thumb broken
Big executable
Old compiler
GNU WinARM:
Pro:
Works
Recent compiler
Smaller image
Cons:
Thumb Borken
All GNU in general:
Pro:
Free, open source
Rellocation fixup of mod by startup code means
tables of function pointers and string
constant addresses supported, fast
vtable dispatching, and unitialized
global variables (possibly) supported in
.BSS. Also C++ vtable mapping schemes like
"lightblue" supported.
Cons:
Half-hearted Qualcomm support
Crummy documentation
ADS 1.2:
Pro:
thumb works, small mod
Cons:
-ropi model (no load-time fixup) means no tables of function ptrs,
tables of string constants, inefficient
calling to far targets, no global variables.
Slow win32 compiles (maybe local phenomenon)
Note: lightblue has plans to fix this by persuing a scheme
similar to that used for gnu: that is, using a special
program to process and slapping run-time fixup code on
the start.
RVDS 2.x:
Pro:
recent, "the future"
Cons:
vtable implementation not -ropi compliant so
(pure) virtuals don't work ??? Under guise of
Green Hills "embedded C++" standard?

05May06 PART FIVE
E) DEVELOPMENT TOOLS OVERIVEW
I already posted this elsewhere, but I've updated and here is my read as of early May 2006:
GNU Gnude:
Pro:
Works
Cons:
Thumb broken
Big executable
Old compiler
GNU WinARM:
Pro:
Works
Recent compiler
Smaller image
Cons:
Thumb Borken
All GNU in general:
Pro:
Free, open source
Rellocation fixup of mod by startup code means
tables of function pointers and string
constant addresses supported, fast
vtable dispatching, and unitialized
global variables (possibly) supported in
.BSS. Also C++ vtable mapping schemes like
"lightblue" supported.
Cons:
Half-hearted Qualcomm support
Crummy documentation
ADS 1.2:
Pro:
thumb works, small mod
Cons:
-ropi model (no load-time fixup) means no tables of function ptrs,
tables of string constants, inefficient
calling to far targets, no global variables.
Slow win32 compiles (maybe local phenomenon)
Note: lightblue has plans to fix this by persuing a scheme
similar to that used for gnu: that is, using a special
program to process and slapping run-time fixup code on
the start.
RVDS 2.x:
Pro:
recent, "the future"
Cons:
vtable implementation not -ropi compliant so
(pure) virtuals don't work ??? Under guise of
Green Hills "embedded C++" standard?

05May06 PART FIVE (Yeah, that last one was really part Four. E-Mail with no size limits and pushed info sure beats forums!)
F) TUTORIAL ON LINKING, LOCATING AND LOADING IN BREW AND ELSEWHERE.
When you compile a program with GCC ARM the resulting file is in a
format called ELF or ARM-ELF. This stands for "executable and linking
format" -- a souped-up version of the old "Portable Executable" (PE)
format still used on Win32 (that superceeded earlier 16 bits formats
such as the New Executable (NE) and old MS-DOS files (MZ -- "Mark
Zbikowski") files. ELF files are structured as a header and then a
series of logical sections that the linker makes up. Some of these are
common and the operating system loader relies on being able to find
them to get a program into memory, set it up for execution, and run
it. For example, the .text section contains the program code (and is
generally marked read-only). The .rodata section contains "read-only"
or rommable data -- string constants, tables, "const" stuff. This is
the only kind of data we like in BREW. On a desktop machine the .data
section contains intialized variables, and the .bss section ("block
start symbol" or "block storage start" annacronistic Unix name)
contains a bunch of zeros for uninitailzed global variables (actually,
it contains how big such a section should be, the bytes aren't
actually in the file -- the OS loader allocs that memory and zeros it
when it is preparing the program to run.
The idea of ELF as a "standard" is that many operating systems can
load and run those files (Linux, Symbian, BREW). ELF is part of a
larger notion of an Application Binary Interface (ABI) that specifies
how executables, object files and libraries/archive files should be
structures so compilers/linkers/debuggers (collectively: "toolchains")
can interoperate with each other. ARM limited blessed an ABI around
1998. This is called the "Extended/Embedded ABI" or EABI. Tool makers
(including GNU) have been modifying their tools to track this. (It
appears even this spec is slighty revised over time, since the latest
EABI paper I have from ARM is dated January 2006. Early GNU and early
ARM compilers (including ADS 1.2) did not follow the EABI spec and
thus do not interoperate. The latest RVDS 2.x series of ARM compiles
and recent GNU compilers (late v3 and v4) do support it and, in
theory, interoperate.
On an operating system with a Memory Management Unit (MMU) (most
Linux, all Win32) an application can be run at what seems (to the
application) to be a fixed address. Thanks to the miracle of virtual
address space mapping to physical hardware, each application can
believe it is running at the same address in memory (0x80000000 for
example). This makes a linker's job very easy, all it has to do is
start the program counter at that number count up from there. Further,
it can figure out the absolute addresses of every symbol in the
program (both code and data) and stomp absolute values into the code
where required. This process is called "locating" the executable.
Now with libraries (DLL, dynamic shared objects, etc.) and on BREW it
gets more complicated. In the case of BREW, there is no MMU and the
application will run in real memory at possibly any address. The BREW
applet loader would like to be as simple and stupid as possible and
just allocate some heap memory, read the applet file into it, and call
the first byte. This is, in fact, what it does. The problem is, if the
linker does not know the run address, how does the executable image
get located -- or as we say "fixed up" -- so it can run without
crashing?
We now enter the thrilling realm of rellocations. When the linker
slams together all the object modules it also outputs a rellocation
section(s) (.reloc) that contains a list of places of that need to
have their address adjusted in some way. A simple approach (and one
kind, ABS32 reloc) is to simply add the 32 bit base load address of
the applet to the location. Other rellocations involve calculating
offsets and adding them. It all depends on the addressing mode of the
instruction being fixed up and what is required to let it find the
data or code it is after.
Recall that an ELF file has a header and all the "good stuff" is
tucked away in sections. This is not something you can just suck into
memory and jump to. To solve this, Qualcomm (QC) provides a utility in
the VSAddins directory of the SDK called BREWelf2mod. This utility
does several things:
1. It strips off the ELF header of the input file
2. It secretly runs the GNU objdump utility to get an ASCII list of
relocations in the ELF file.
3. It runs through the rellocations and "cooks them" so they are easy
to apply. In fact, it gets it down to a sorted list of places in the
image that need to have the actual loaded address added to them (the
addenend).
Note that in a big program, this data can be of fair size and is one
of the reasons GNU gets a rap for big images on ARM. (There are tricks
that could fix this with more development.)
4. It slaps a short (0x9C byte) startup routine on the front of the
output image. This is the code that first gets control when BREW
jumps to location zero in an applet. It fixes up the rellocations in
the image and after that, winds up executing AEEMod__Load().
If you are curious, the layout of this startup code looks like this
(from my limited poking around):
+----------------------------------+
| jump to relocation fixup code |
+----------------------------------+
| offset of data |
| size of image minus this startup |
| offset of data |
| offset of AEEMod_Load or place |
| make jump to it |
+----------------------------------+
| |
| |
| reloaction fixup code |
| |
| |
+----------------------------------+
| mystery pointer |
| mystery pointer |
| version of BREW stdlib |
| ptr to stdlib interface |
+----------------------------------+
| AEEMod_Load() |
+\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/+
Note there is no need to explicitly compile position independent code,
because this scheme is postion independent. In fact, if you do compile
position independent (-fPIC) it won't work because GNU implements this
by creating some "thunk sections" -- the global offset table (or .got)
these are not supported by elf2mod startup code. (Thumb "interworking"
calls can generate thunks too -- to switch from 16 to 32 bit
instructions and back -- but that's a different thing -- and something
I have not gotten to work yet anyway.)
By contrast, the ADS toolchain only compiles position independent
(-ropi). This means no startup code is required to fix it up at
runtime, AEE can just call the first byte and off it goes, but you
can't have tables of function pointers, or mutable global variables.
It also means vtable dispatching and long jumps are inefficient,
having to go through "jump veneers" if the target is too far away.
G) CONCLUSION
Hopes this helps and does not mislead. Please post your comments and
corrections if you can. We all need to share what we know. Or think we
know!
Good luck with your projects.
Ward Willats
VeriSign
"All your bases are belong to us"
(Just kidding, I don't work for the evil part of the company...)

05May06 PART FIVE (Yeah, that last one was really part Four. E-Mail with no size limits and pushed info sure beats forums!)
F) TUTORIAL ON LINKING, LOCATING AND LOADING IN BREW AND ELSEWHERE.
When you compile a program with GCC ARM the resulting file is in a
format called ELF or ARM-ELF. This stands for "executable and linking
format" -- a souped-up version of the old "Portable Executable" (PE)
format still used on Win32 (that superceeded earlier 16 bits formats
such as the New Executable (NE) and old MS-DOS files (MZ -- "Mark
Zbikowski") files. ELF files are structured as a header and then a
series of logical sections that the linker makes up. Some of these are
common and the operating system loader relies on being able to find
them to get a program into memory, set it up for execution, and run
it. For example, the .text section contains the program code (and is
generally marked read-only). The .rodata section contains "read-only"
or rommable data -- string constants, tables, "const" stuff. This is
the only kind of data we like in BREW. On a desktop machine the .data
section contains intialized variables, and the .bss section ("block
start symbol" or "block storage start" annacronistic Unix name)
contains a bunch of zeros for uninitailzed global variables (actually,
it contains how big such a section should be, the bytes aren't
actually in the file -- the OS loader allocs that memory and zeros it
when it is preparing the program to run.
The idea of ELF as a "standard" is that many operating systems can
load and run those files (Linux, Symbian, BREW). ELF is part of a
larger notion of an Application Binary Interface (ABI) that specifies
how executables, object files and libraries/archive files should be
structures so compilers/linkers/debuggers (collectively: "toolchains")
can interoperate with each other. ARM limited blessed an ABI around
1998. This is called the "Extended/Embedded ABI" or EABI. Tool makers
(including GNU) have been modifying their tools to track this. (It
appears even this spec is slighty revised over time, since the latest
EABI paper I have from ARM is dated January 2006. Early GNU and early
ARM compilers (including ADS 1.2) did not follow the EABI spec and
thus do not interoperate. The latest RVDS 2.x series of ARM compiles
and recent GNU compilers (late v3 and v4) do support it and, in
theory, interoperate.
On an operating system with a Memory Management Unit (MMU) (most
Linux, all Win32) an application can be run at what seems (to the
application) to be a fixed address. Thanks to the miracle of virtual
address space mapping to physical hardware, each application can
believe it is running at the same address in memory (0x80000000 for
example). This makes a linker's job very easy, all it has to do is
start the program counter at that number count up from there. Further,
it can figure out the absolute addresses of every symbol in the
program (both code and data) and stomp absolute values into the code
where required. This process is called "locating" the executable.
Now with libraries (DLL, dynamic shared objects, etc.) and on BREW it
gets more complicated. In the case of BREW, there is no MMU and the
application will run in real memory at possibly any address. The BREW
applet loader would like to be as simple and stupid as possible and
just allocate some heap memory, read the applet file into it, and call
the first byte. This is, in fact, what it does. The problem is, if the
linker does not know the run address, how does the executable image
get located -- or as we say "fixed up" -- so it can run without
crashing?
We now enter the thrilling realm of rellocations. When the linker
slams together all the object modules it also outputs a rellocation
section(s) (.reloc) that contains a list of places of that need to
have their address adjusted in some way. A simple approach (and one
kind, ABS32 reloc) is to simply add the 32 bit base load address of
the applet to the location. Other rellocations involve calculating
offsets and adding them. It all depends on the addressing mode of the
instruction being fixed up and what is required to let it find the
data or code it is after.
Recall that an ELF file has a header and all the "good stuff" is
tucked away in sections. This is not something you can just suck into
memory and jump to. To solve this, Qualcomm (QC) provides a utility in
the VSAddins directory of the SDK called BREWelf2mod. This utility
does several things:
1. It strips off the ELF header of the input file
2. It secretly runs the GNU objdump utility to get an ASCII list of
relocations in the ELF file.
3. It runs through the rellocations and "cooks them" so they are easy
to apply. In fact, it gets it down to a sorted list of places in the
image that need to have the actual loaded address added to them (the
addenend).
Note that in a big program, this data can be of fair size and is one
of the reasons GNU gets a rap for big images on ARM. (There are tricks
that could fix this with more development.)
4. It slaps a short (0x9C byte) startup routine on the front of the
output image. This is the code that first gets control when BREW
jumps to location zero in an applet. It fixes up the rellocations in
the image and after that, winds up executing AEEMod__Load().
If you are curious, the layout of this startup code looks like this
(from my limited poking around):
+----------------------------------+
| jump to relocation fixup code |
+----------------------------------+
| offset of data |
| size of image minus this startup |
| offset of data |
| offset of AEEMod_Load or place |
| make jump to it |
+----------------------------------+
| |
| |
| reloaction fixup code |
| |
| |
+----------------------------------+
| mystery pointer |
| mystery pointer |
| version of BREW stdlib |
| ptr to stdlib interface |
+----------------------------------+
| AEEMod_Load() |
+\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/+
Note there is no need to explicitly compile position independent code,
because this scheme is postion independent. In fact, if you do compile
position independent (-fPIC) it won't work because GNU implements this
by creating some "thunk sections" -- the global offset table (or .got)
these are not supported by elf2mod startup code. (Thumb "interworking"
calls can generate thunks too -- to switch from 16 to 32 bit
instructions and back -- but that's a different thing -- and something
I have not gotten to work yet anyway.)
By contrast, the ADS toolchain only compiles position independent
(-ropi). This means no startup code is required to fix it up at
runtime, AEE can just call the first byte and off it goes, but you
can't have tables of function pointers, or mutable global variables.
It also means vtable dispatching and long jumps are inefficient,
having to go through "jump veneers" if the target is too far away.
G) CONCLUSION
Hopes this helps and does not mislead. Please post your comments and
corrections if you can. We all need to share what we know. Or think we
know!
Good luck with your projects.
Ward Willats
VeriSign
"All your bases are belong to us"
(Just kidding, I don't work for the evil part of the company...)

-O2 may have caused my executable to crash because it turns on -falign-functions. I am thinking this may have moved AEEMod_Load() forward a little. -Os _should_ be OK since it disables -falign-functions (while keeping most other -O2 optimizations).
This is just conjecture. I have not investigated.

-O2 may have caused my executable to crash because it turns on -falign-functions. I am thinking this may have moved AEEMod_Load() forward a little. -Os _should_ be OK since it disables -falign-functions (while keeping most other -O2 optimizations).
This is just conjecture. I have not investigated.

Ah, OK, I get it. If I optimize for size with -Os the compiler re-orders the sections so AEEMod_Load is not first. Now I understand why some of you folks have had to move AEEMod_Load into a separate compilation unit!
You'd think the linker script could handle this, but I'm not sure. Hmmm. Must think.
Without optimization:
.text 0x00000000 0x3e8 D:\lsurf\bpm\src\applications\bpm\ARM GNU Debug\AEEModGen.o
0x00000000 AEEMod_Load
0x00000054 AEEStaticMod_New
With optimization:
.text 0x00000000 0x22c D:\lsurf\bpm\src\applications\bpm\ARM GNU Debug\AEEModGen.o
0x00000104 AEEMod_Load
0x00000000 AEEStaticMod_New

Ah, OK, I get it. If I optimize for size with -Os the compiler re-orders the sections so AEEMod_Load is not first. Now I understand why some of you folks have had to move AEEMod_Load into a separate compilation unit!
You'd think the linker script could handle this, but I'm not sure. Hmmm. Must think.
Without optimization:
.text 0x00000000 0x3e8 D:\lsurf\bpm\src\applications\bpm\ARM GNU Debug\AEEModGen.o
0x00000000 AEEMod_Load
0x00000054 AEEStaticMod_New
With optimization:
.text 0x00000000 0x22c D:\lsurf\bpm\src\applications\bpm\ARM GNU Debug\AEEModGen.o
0x00000104 AEEMod_Load
0x00000000 AEEStaticMod_New

OK, this updated linker script adds specific instruction to put the .text.AEEMod_Load section first. You MUST compile AEEModGen.c with -ffunction-sections for this to work.
The feature of this is that you will no longer have to put AEEMod_Load by itself in a separate file, no matter what optimizations you are running.
With this fix I finally have an omptimized-for-size version of my module running. Yippie!
/*
* 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
*/
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.
*/
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 = .;
.bss : { 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 */

OK, this updated linker script adds specific instruction to put the .text.AEEMod_Load section first. You MUST compile AEEModGen.c with -ffunction-sections for this to work.
The feature of this is that you will no longer have to put AEEMod_Load by itself in a separate file, no matter what optimizations you are running.
With this fix I finally have an omptimized-for-size version of my module running. Yippie!
/*
* 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
*/
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.
*/
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 = .;
.bss : { 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 */

THUMB SUCCESS (?!)
I have finally had some success with thumb. In fact, I have a version
of my big app running now compiled with 4.1.0 thumb.
My original strategy was to compile this way (non-interworking
switches ommitted):
AEEAppGen.c - -mthumb-interwork -mapcs-frame
AEEModGen.c - -mthumb-interwork -mapcs-frame
RestOfApplet.cpp - -mthumb-interwork -mtpcs-frame -mthumb
Link with: 4.1.10/thumb/interwork/gcc
...the thinking being that AEE would call the ARM code in AEEModGen
and we'd flip over to thumb on the call to (the C++)
AEEClsCreateInstance(). The return from AEEClsCreateInstance would
then be smart enough to return to ARM mode on exit.
Well, it seems that call (first switch to thumb) was failing and
nothing I did could make it go.
What wound up working was to compile EVERYTHING in thumb:
AEEAppGen.c - -mthumb -mtpcs-frame -mcallee-super-interworking
AEEModGen.c - -mthumb -mtpcs-frame -mcallee-super-interworking
RestOfApplet.cpp - -mthumb -mtpcs-frame
Link with: 4.1.10/thumb/gcc
The "callee-super-interworking" switch inserts some preamble code to
switch into thumb mode at the start of the public functions AEE calls,
so you don't have to compile AEEAppGen or AEEModGen in ARM mode. In
fact, everything in the applet can be in thumb.
Callbacks from BREW seem to be working too (we do some socket stuff).
I was worried about this.
There is one trick to make a mod. As I wrote previously, BREWelf2Mod
does not understand R_ARM_THM_CALL. To get around this, I used the
gnude objdump utility (that emits the old names):
BREWelf2mod test.elf test.mod \gnude\bin\arm-elf-objdump.exe
^^^^^
It would be nice to do a wrapper for winarm objdump that handles this
and also drops the (unnecessary) __cxa_pure_virtual() fixups. That would
make things even smaller.
So....I'm not an expert, and I don't have a debugger for my target. I
don't understand why more "traditional" approach doesn't work, but
this workaround seems to go OK at the moment.

THUMB SUCCESS (?!)
I have finally had some success with thumb. In fact, I have a version
of my big app running now compiled with 4.1.0 thumb.
My original strategy was to compile this way (non-interworking
switches ommitted):
AEEAppGen.c - -mthumb-interwork -mapcs-frame
AEEModGen.c - -mthumb-interwork -mapcs-frame
RestOfApplet.cpp - -mthumb-interwork -mtpcs-frame -mthumb
Link with: 4.1.10/thumb/interwork/gcc
...the thinking being that AEE would call the ARM code in AEEModGen
and we'd flip over to thumb on the call to (the C++)
AEEClsCreateInstance(). The return from AEEClsCreateInstance would
then be smart enough to return to ARM mode on exit.
Well, it seems that call (first switch to thumb) was failing and
nothing I did could make it go.
What wound up working was to compile EVERYTHING in thumb:
AEEAppGen.c - -mthumb -mtpcs-frame -mcallee-super-interworking
AEEModGen.c - -mthumb -mtpcs-frame -mcallee-super-interworking
RestOfApplet.cpp - -mthumb -mtpcs-frame
Link with: 4.1.10/thumb/gcc
The "callee-super-interworking" switch inserts some preamble code to
switch into thumb mode at the start of the public functions AEE calls,
so you don't have to compile AEEAppGen or AEEModGen in ARM mode. In
fact, everything in the applet can be in thumb.
Callbacks from BREW seem to be working too (we do some socket stuff).
I was worried about this.
There is one trick to make a mod. As I wrote previously, BREWelf2Mod
does not understand R_ARM_THM_CALL. To get around this, I used the
gnude objdump utility (that emits the old names):
BREWelf2mod test.elf test.mod \gnude\bin\arm-elf-objdump.exe
^^^^^
It would be nice to do a wrapper for winarm objdump that handles this
and also drops the (unnecessary) __cxa_pure_virtual() fixups. That would
make things even smaller.
So....I'm not an expert, and I don't have a debugger for my target. I
don't understand why more "traditional" approach doesn't work, but
this workaround seems to go OK at the moment.

I have reprinted and updated all this material on my own site:
http://brew.wardco.com/index.html
...and I have written a filter you can put in a batch file to transform the output of WinARM's objdump so BREWelf2mod can process it. It also drops __cxa_pure_virtual relocations for a slightly smaller mod file.
http://brew.wardco.com/BREWe2modFilter.cpp

I have reprinted and updated all this material on my own site:
http://brew.wardco.com/index.html
...and I have written a filter you can put in a batch file to transform the output of WinARM's objdump so BREWelf2mod can process it. It also drops __cxa_pure_virtual relocations for a slightly smaller mod file.
http://brew.wardco.com/BREWe2modFilter.cpp

Nicely done! Thanks for this wardw! I am sure this will help lots of people! I will try it and let you know.... but that site for WinARM is down for some reason. Does any body else know a site that I can download?
EDIT: nvm, the site is back up...

Nicely done! Thanks for this wardw! I am sure this will help lots of people! I will try it and let you know.... but that site for WinARM is down for some reason. Does any body else know a site that I can download?
EDIT: nvm, the site is back up...

I'm trying to compile my application with winarm using this help... My app. using STL heavily and when i'm linking it I have such results:
AutorizationForm.o: In function `operator new(unsigned long)':
AutorizationForm.cpp:(.text._Znwm+0x0): multiple definition of `operator new(unsigned long)'
SonoMobile.o:SonoMobile.cpp:(.text._Znwm+0x0): first defined here
AutorizationForm.o: In function `operator delete(void*)':
AutorizationForm.cpp:(.text._ZdlPv+0x0): multiple definition of `operator delete(void*)'
......
SonoMobile.o:SonoMobile.cpp:(.text._ZdaPv+0x0): first defined here
c:\brew\winarm\bin\arm-elf-ld.exe: AEEAppGen.o(AEEApplet_New): warning: interworking not enabled.
first occurrence: SonoMobile.o: thumb call to arm
SonoMobile.o: In function `AEEClsCreateInstance':
SonoMobile.cpp:(.text.AEEClsCreateInstance+0x70): warning: internal error: dangerous error
AuthorizationManager.o: In function `AuthorizationManager::~AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerD1Ev+0xa6): undefined reference to `std::basic_string, std::allocator >::~basic_string()'
AuthorizationManager.o: In function `AuthorizationManager::~AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerD2Ev+0xa6): undefined reference to `std::basic_string< char, std::char_traits< char >, std::allocator< char > >::~basic_string()'
AuthorizationManager.o: In function `XmlRpc::XmlRpcClient::setResponse(std::string)':
AuthorizationManager.cpp:(.text._ZN6XmlRpc12XmlRpcClient11setResponseESs[_ZN6XmlRpc12XmlRpcClient11setResponseESs]+0x34): undefined reference to `std::string::operator=(std::string const&)'
AuthorizationManager.o: In function `AuthorizationManager::AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerC1Ev+0x28): undefined reference to `std::basic_string, std::allocator >::basic_string()'
....................................
So, can somebody give an advise about linking all this... if it possible at all...
--

I'm trying to compile my application with winarm using this help... My app. using STL heavily and when i'm linking it I have such results:
AutorizationForm.o: In function `operator new(unsigned long)':
AutorizationForm.cpp:(.text._Znwm+0x0): multiple definition of `operator new(unsigned long)'
SonoMobile.o:SonoMobile.cpp:(.text._Znwm+0x0): first defined here
AutorizationForm.o: In function `operator delete(void*)':
AutorizationForm.cpp:(.text._ZdlPv+0x0): multiple definition of `operator delete(void*)'
......
SonoMobile.o:SonoMobile.cpp:(.text._ZdaPv+0x0): first defined here
c:\brew\winarm\bin\arm-elf-ld.exe: AEEAppGen.o(AEEApplet_New): warning: interworking not enabled.
first occurrence: SonoMobile.o: thumb call to arm
SonoMobile.o: In function `AEEClsCreateInstance':
SonoMobile.cpp:(.text.AEEClsCreateInstance+0x70): warning: internal error: dangerous error
AuthorizationManager.o: In function `AuthorizationManager::~AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerD1Ev+0xa6): undefined reference to `std::basic_string, std::allocator >::~basic_string()'
AuthorizationManager.o: In function `AuthorizationManager::~AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerD2Ev+0xa6): undefined reference to `std::basic_string< char, std::char_traits< char >, std::allocator< char > >::~basic_string()'
AuthorizationManager.o: In function `XmlRpc::XmlRpcClient::setResponse(std::string)':
AuthorizationManager.cpp:(.text._ZN6XmlRpc12XmlRpcClient11setResponseESs[_ZN6XmlRpc12XmlRpcClient11setResponseESs]+0x34): undefined reference to `std::string::operator=(std::string const&)'
AuthorizationManager.o: In function `AuthorizationManager::AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerC1Ev+0x28): undefined reference to `std::basic_string, std::allocator >::basic_string()'
....................................
So, can somebody give an advise about linking all this... if it possible at all...
--

mr.j8 wrote:I'm trying to compile my application with winarm using this help... My app. using STL heavily and when i'm linking it I have such results:
AutorizationForm.o: In function `operator new(unsigned long)':
AutorizationForm.cpp:(.text._Znwm+0x0): multiple definition of `operator new(unsigned long)'
SonoMobile.o:SonoMobile.cpp:(.text._Znwm+0x0): first defined here
AutorizationForm.o: In function `operator delete(void*)':
AutorizationForm.cpp:(.text._ZdlPv+0x0): multiple definition of `operator delete(void*)'Did you override new and delete in multiple places? Just define it in the global header once.Quote:SonoMobile.o:SonoMobile.cpp:(.text._ZdaPv+0x0): first defined here
c:\brew\winarm\bin\arm-elf-ld.exe: AEEAppGen.o(AEEApplet_New): warning: interworking not enabled.
first occurrence: SonoMobile.o: thumb call to arm
SonoMobile.o: In function `AEEClsCreateInstance':
SonoMobile.cpp:(.text.AEEClsCreateInstance+0x70): warning: internal error: dangerous error
AuthorizationManager.o: In function `AuthorizationManager::~AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerD1Ev+0xa6): undefined reference to `std::basic_string, std::allocator >::~basic_string()'
AuthorizationManager.o: In function `AuthorizationManager::~AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerD2Ev+0xa6): undefined reference to `std::basic_string< char, std::char_traits< char >, std::allocator< char > >::~basic_string()'
AuthorizationManager.o: In function `XmlRpc::XmlRpcClient::setResponse(std::string)':
AuthorizationManager.cpp:(.text._ZN6XmlRpc12XmlRpcClient11setResponseESs[_ZN6XmlRpc12XmlRpcClient11setResponseESs]+0x34): undefined reference to `std::string::operator=(std::string const&)'
AuthorizationManager.o: In function `AuthorizationManager::AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerC1Ev+0x28): undefined reference to `std::basic_string, std::allocator >::basic_string()'You can't use any of the std libraries. Either you can write your own string class to support AECHAR or use one of the BREW libraries out there: lightblue
HTH

mr.j8 wrote:I'm trying to compile my application with winarm using this help... My app. using STL heavily and when i'm linking it I have such results:
AutorizationForm.o: In function `operator new(unsigned long)':
AutorizationForm.cpp:(.text._Znwm+0x0): multiple definition of `operator new(unsigned long)'
SonoMobile.o:SonoMobile.cpp:(.text._Znwm+0x0): first defined here
AutorizationForm.o: In function `operator delete(void*)':
AutorizationForm.cpp:(.text._ZdlPv+0x0): multiple definition of `operator delete(void*)'Did you override new and delete in multiple places? Just define it in the global header once.Quote:SonoMobile.o:SonoMobile.cpp:(.text._ZdaPv+0x0): first defined here
c:\brew\winarm\bin\arm-elf-ld.exe: AEEAppGen.o(AEEApplet_New): warning: interworking not enabled.
first occurrence: SonoMobile.o: thumb call to arm
SonoMobile.o: In function `AEEClsCreateInstance':
SonoMobile.cpp:(.text.AEEClsCreateInstance+0x70): warning: internal error: dangerous error
AuthorizationManager.o: In function `AuthorizationManager::~AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerD1Ev+0xa6): undefined reference to `std::basic_string, std::allocator >::~basic_string()'
AuthorizationManager.o: In function `AuthorizationManager::~AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerD2Ev+0xa6): undefined reference to `std::basic_string< char, std::char_traits< char >, std::allocator< char > >::~basic_string()'
AuthorizationManager.o: In function `XmlRpc::XmlRpcClient::setResponse(std::string)':
AuthorizationManager.cpp:(.text._ZN6XmlRpc12XmlRpcClient11setResponseESs[_ZN6XmlRpc12XmlRpcClient11setResponseESs]+0x34): undefined reference to `std::string::operator=(std::string const&)'
AuthorizationManager.o: In function `AuthorizationManager::AuthorizationManager()':
AuthorizationManager.cpp:(.text._ZN20AuthorizationManagerC1Ev+0x28): undefined reference to `std::basic_string, std::allocator >::basic_string()'You can't use any of the std libraries. Either you can write your own string class to support AECHAR or use one of the BREW libraries out there: lightblue
HTH

Hi Ward,
I finally tried out the WinARM with your linker script. At first, I was able to generate a mod file with very close size to the RVCT 1.2. However, I wasn't able to run it since the handset just power cycles after starting it. But, if I change the compilation mode to arm (instead of thumb) it works like a charm. I really want the smaller version of the mod. Please help me point out what I am doing wrong (or point me in the right direction).BREW_HOME = c:\BREW\BREWV315\sdk
ARM_HOME = C:\WinARM
TARGET = helloworld
OBJS = GCCResolver.o AEEModGen.o AEEAppGen.o helloworld.o
APP_INCLUDES = -I $(BREW_HOME)\inc
#-------------------------------------------------------------------------------
# Target file name and type definitions
#-------------------------------------------------------------------------------
EXETYPE = elf # Target image file format
MODULE = mod # Downloadable module extension
#-------------------------------------------------------------------------------
# Target compile time symbol definitions
# Tells the SDK source stuffs that we're building a dynamic app.
#-------------------------------------------------------------------------------
DYNAPP = -DDYNAMIC_APP
#-------------------------------------------------------------------------------
# Software tool and environment definitions
#-------------------------------------------------------------------------------
AEESRCPATH = $(BREW_HOME)\src
AEEINCPATH = $(BREW_HOME)\inc
ARMBIN = $(ARM_HOME)\bin # ARM ADS application directory
ARMINC = $(ARM_HOME)\include # ARM ADS include file directory
ARMLIB = $(ARM_HOME)\lib # ARM ADS library directory
ARMCC = $(ARMBIN)\arm-elf-gcc # ARM ADS ARM 32-bit inst. set ANSI C compiler
ARMCPP = $(ARMBIN)\arm-elf-g++ # ARM ADS ARM 32-bit inst. set ANSI CPP compiler
LD = $(ARMBIN)\arm-elf-ld # ARM ADS linker
HEXTOOL = $(ARMBIN)\BREWelf2mod # ARM ADS utility to create hex file from image
FILTER = $(ARMBIN)\elf2mod # Batch file containing the filter
OBJ_CMD = -o # Command line option to specify output filename
#-------------------------------------------------------------------------------
# Processor architecture options
#-------------------------------------------------------------------------------
CPU = -mcpu=arm7tdmi # ARM7TDMI target processor
#-------------------------------------------------------------------------------
# ARM Procedure Call Standard (APCS) options
#-------------------------------------------------------------------------------
APCS_CPP_SRC = -mthumb -mtpcs-frame -fno-rtti
APCS_C_SRC = -mthumb -mtpcs-frame
APCS_BREW = -mthumb -mtpcs-frame -mcallee-super-interworking
#-------------------------------------------------------------------------------
# Compiler output options
#-------------------------------------------------------------------------------
OUT = -c # Object file output only
#-------------------------------------------------------------------------------
# Compiler/assembler debug options
#-------------------------------------------------------------------------------
DBG = -DDEBUG # Enable debug
#-------------------------------------------------------------------------------
# Compiler optimization options
#-------------------------------------------------------------------------------
OPT = -Os # Full compiler optimization for space
#-------------------------------------------------------------------------------
# Compiler code generation options
#-------------------------------------------------------------------------------
END = -mlittle-endian # Compile for little endian memory architecture
CODE_CPP = $(END) -fno-builtin -ffunction-sections -fno-exceptions -fno-unwind-tables
CODE_C = $(END) -fno-builtin -ffunction-sections
#-------------------------------------------------------------------------------
# Include file search path options
#-------------------------------------------------------------------------------
INC = -I. -I$(AEEINCPATH) $(APP_INCLUDES)
#-------------------------------------------------------------------------------
# Linker options
#-------------------------------------------------------------------------------
LINK_CMD = -o # Command line option to specify output file
# on linking
#-------------------------------------------------------------------------------
# Compiler flag definitions
#-------------------------------------------------------------------------------
CPPFLAGS1 = $(OUT) $(DYNAPP) $(CPU) $(APCS_CPP_SRC) $(CODE_CPP) $(CHK) $(DBG)
CFLAGS_BREW1 = $(OUT) $(DYNAPP) $(CPU) $(APCS_BREW) $(CODE_C) $(CHK) $(DBG)
CFLAGS1 = $(OUT) $(DYNAPP) $(CPU) $(APCS_C_SRC) $(CODE_C) $(CHK) $(DBG)
CPPFLAGS = $(CPPFLAGS1) $(OPT)
CFLAGS_BREW = $(CFLAGS_BREW1) $(OPT)
CFLAGS = $(CFLAGS1) $(OPT)
#-------------------------------------------------------------------------------
# Linker flag definitions
#-------------------------------------------------------------------------------
DIR1 = C:\WinARM\lib\gcc\arm-elf\4.1.1\thumb\interwork
LFLAGS = --script C:\WinARM\armelf.brew --cref --emit-relocs --no-warn-mismatch -L $(DIR1)
#-------------------------------------------------------------------------------
# Default target
#-------------------------------------------------------------------------------
all : $(TARGET).$(MODULE)
#-------------------------------------------------------------------------------
# Clean target
#-------------------------------------------------------------------------------
# The object subdirectory, target image file, and target hex file are deleted.
clean :
@echo ---------------------------------------------------------------
@echo CLEAN
-del /f $(OBJS)
-del /f $(TARGET).$(EXETYPE)
-del /f $(TARGET).$(MODULE)
@echo ---------------------------------------------------------------
#===============================================================================
# DEFAULT SUFFIX RULES
#===============================================================================
# The following are the default suffix rules used to compile all objects that
# are not specifically included in one of the module specific rules defined
# in the next section.
# The following macros are used to specify the output object file, MSG_FILE
# symbol definition and input source file on the compile line in the rules
# defined below.
SRC_CPP_FILE = $(@F:.o=.cpp) # Input source file specification
SRC_C_FILE = $(@F:.o=.c) # Input source file specification
OBJ_FILE = $(OBJ_CMD) $(@F) # Output object file specification
.SUFFIXES :
.SUFFIXES : .o .dep .c .cpp
#-------------------------------------------------------------------------------
# C code inference rules
#-------------------------------------------------------------------------------
.cpp.o:
@echo ---------------------------------------------------------------
@echo OBJECT $(@F)
$(ARMCPP) $(CPPFLAGS) $(INC) $(OBJ_FILE) $(SRC_CPP_FILE)
@echo ---------------------------------------------------------------
.c.o:
@echo ---------------------------------------------------------------
@echo OBJECT $(@F)
$(ARMCC) $(CFLAGS) $(INC) $(OBJ_FILE) $(SRC_C_FILE)
@echo ---------------------------------------------------------------
{$(AEESRCPATH)}.c.o:
@echo ---------------------------------------------------------------
@echo OBJECT $(@F)
$(ARMCC) $(CFLAGS_BREW) $(INC) $(OBJ_FILE) $(AEESRCPATH)\$(SRC_C_FILE)
@echo ---------------------------------------------------------------
#===============================================================================
# MODULE SPECIFIC RULES
#===============================================================================
APP_OBJS = $(OBJS)
#-------------------------------------------------------------------------------
# Lib file targets
#-------------------------------------------------------------------------------
$(TARGET).$(MODULE) : $(TARGET).$(EXETYPE)
@echo ---------------------------------------------------------------
@echo TARGET $@
$(HEXTOOL) $(TARGET).$(EXETYPE) $(TARGET).$(MODULE) $(FILTER)
@echo ---------------------------------------------------------------
$(TARGET).$(EXETYPE) : $(APP_OBJS)
@echo ---------------------------------------------------------------
@echo TARGET $@
$(LD) $(LINK_CMD) $(TARGET).$(EXETYPE) $(LFLAGS) $(APP_OBJS) -lgcc
@echo ---------------------------------------------------------------Thanks again!

Hi Ward,
I finally tried out the WinARM with your linker script. At first, I was able to generate a mod file with very close size to the RVCT 1.2. However, I wasn't able to run it since the handset just power cycles after starting it. But, if I change the compilation mode to arm (instead of thumb) it works like a charm. I really want the smaller version of the mod. Please help me point out what I am doing wrong (or point me in the right direction).BREW_HOME = c:\BREW\BREWV315\sdk
ARM_HOME = C:\WinARM
TARGET = helloworld
OBJS = GCCResolver.o AEEModGen.o AEEAppGen.o helloworld.o
APP_INCLUDES = -I $(BREW_HOME)\inc
#-------------------------------------------------------------------------------
# Target file name and type definitions
#-------------------------------------------------------------------------------
EXETYPE = elf # Target image file format
MODULE = mod # Downloadable module extension
#-------------------------------------------------------------------------------
# Target compile time symbol definitions
# Tells the SDK source stuffs that we're building a dynamic app.
#-------------------------------------------------------------------------------
DYNAPP = -DDYNAMIC_APP
#-------------------------------------------------------------------------------
# Software tool and environment definitions
#-------------------------------------------------------------------------------
AEESRCPATH = $(BREW_HOME)\src
AEEINCPATH = $(BREW_HOME)\inc
ARMBIN = $(ARM_HOME)\bin # ARM ADS application directory
ARMINC = $(ARM_HOME)\include # ARM ADS include file directory
ARMLIB = $(ARM_HOME)\lib # ARM ADS library directory
ARMCC = $(ARMBIN)\arm-elf-gcc # ARM ADS ARM 32-bit inst. set ANSI C compiler
ARMCPP = $(ARMBIN)\arm-elf-g++ # ARM ADS ARM 32-bit inst. set ANSI CPP compiler
LD = $(ARMBIN)\arm-elf-ld # ARM ADS linker
HEXTOOL = $(ARMBIN)\BREWelf2mod # ARM ADS utility to create hex file from image
FILTER = $(ARMBIN)\elf2mod # Batch file containing the filter
OBJ_CMD = -o # Command line option to specify output filename
#-------------------------------------------------------------------------------
# Processor architecture options
#-------------------------------------------------------------------------------
CPU = -mcpu=arm7tdmi # ARM7TDMI target processor
#-------------------------------------------------------------------------------
# ARM Procedure Call Standard (APCS) options
#-------------------------------------------------------------------------------
APCS_CPP_SRC = -mthumb -mtpcs-frame -fno-rtti
APCS_C_SRC = -mthumb -mtpcs-frame
APCS_BREW = -mthumb -mtpcs-frame -mcallee-super-interworking
#-------------------------------------------------------------------------------
# Compiler output options
#-------------------------------------------------------------------------------
OUT = -c # Object file output only
#-------------------------------------------------------------------------------
# Compiler/assembler debug options
#-------------------------------------------------------------------------------
DBG = -DDEBUG # Enable debug
#-------------------------------------------------------------------------------
# Compiler optimization options
#-------------------------------------------------------------------------------
OPT = -Os # Full compiler optimization for space
#-------------------------------------------------------------------------------
# Compiler code generation options
#-------------------------------------------------------------------------------
END = -mlittle-endian # Compile for little endian memory architecture
CODE_CPP = $(END) -fno-builtin -ffunction-sections -fno-exceptions -fno-unwind-tables
CODE_C = $(END) -fno-builtin -ffunction-sections
#-------------------------------------------------------------------------------
# Include file search path options
#-------------------------------------------------------------------------------
INC = -I. -I$(AEEINCPATH) $(APP_INCLUDES)
#-------------------------------------------------------------------------------
# Linker options
#-------------------------------------------------------------------------------
LINK_CMD = -o # Command line option to specify output file
# on linking
#-------------------------------------------------------------------------------
# Compiler flag definitions
#-------------------------------------------------------------------------------
CPPFLAGS1 = $(OUT) $(DYNAPP) $(CPU) $(APCS_CPP_SRC) $(CODE_CPP) $(CHK) $(DBG)
CFLAGS_BREW1 = $(OUT) $(DYNAPP) $(CPU) $(APCS_BREW) $(CODE_C) $(CHK) $(DBG)
CFLAGS1 = $(OUT) $(DYNAPP) $(CPU) $(APCS_C_SRC) $(CODE_C) $(CHK) $(DBG)
CPPFLAGS = $(CPPFLAGS1) $(OPT)
CFLAGS_BREW = $(CFLAGS_BREW1) $(OPT)
CFLAGS = $(CFLAGS1) $(OPT)
#-------------------------------------------------------------------------------
# Linker flag definitions
#-------------------------------------------------------------------------------
DIR1 = C:\WinARM\lib\gcc\arm-elf\4.1.1\thumb\interwork
LFLAGS = --script C:\WinARM\armelf.brew --cref --emit-relocs --no-warn-mismatch -L $(DIR1)
#-------------------------------------------------------------------------------
# Default target
#-------------------------------------------------------------------------------
all : $(TARGET).$(MODULE)
#-------------------------------------------------------------------------------
# Clean target
#-------------------------------------------------------------------------------
# The object subdirectory, target image file, and target hex file are deleted.
clean :
@echo ---------------------------------------------------------------
@echo CLEAN
-del /f $(OBJS)
-del /f $(TARGET).$(EXETYPE)
-del /f $(TARGET).$(MODULE)
@echo ---------------------------------------------------------------
#===============================================================================
# DEFAULT SUFFIX RULES
#===============================================================================
# The following are the default suffix rules used to compile all objects that
# are not specifically included in one of the module specific rules defined
# in the next section.
# The following macros are used to specify the output object file, MSG_FILE
# symbol definition and input source file on the compile line in the rules
# defined below.
SRC_CPP_FILE = $(@F:.o=.cpp) # Input source file specification
SRC_C_FILE = $(@F:.o=.c) # Input source file specification
OBJ_FILE = $(OBJ_CMD) $(@F) # Output object file specification
.SUFFIXES :
.SUFFIXES : .o .dep .c .cpp
#-------------------------------------------------------------------------------
# C code inference rules
#-------------------------------------------------------------------------------
.cpp.o:
@echo ---------------------------------------------------------------
@echo OBJECT $(@F)
$(ARMCPP) $(CPPFLAGS) $(INC) $(OBJ_FILE) $(SRC_CPP_FILE)
@echo ---------------------------------------------------------------
.c.o:
@echo ---------------------------------------------------------------
@echo OBJECT $(@F)
$(ARMCC) $(CFLAGS) $(INC) $(OBJ_FILE) $(SRC_C_FILE)
@echo ---------------------------------------------------------------
{$(AEESRCPATH)}.c.o:
@echo ---------------------------------------------------------------
@echo OBJECT $(@F)
$(ARMCC) $(CFLAGS_BREW) $(INC) $(OBJ_FILE) $(AEESRCPATH)\$(SRC_C_FILE)
@echo ---------------------------------------------------------------
#===============================================================================
# MODULE SPECIFIC RULES
#===============================================================================
APP_OBJS = $(OBJS)
#-------------------------------------------------------------------------------
# Lib file targets
#-------------------------------------------------------------------------------
$(TARGET).$(MODULE) : $(TARGET).$(EXETYPE)
@echo ---------------------------------------------------------------
@echo TARGET $@
$(HEXTOOL) $(TARGET).$(EXETYPE) $(TARGET).$(MODULE) $(FILTER)
@echo ---------------------------------------------------------------
$(TARGET).$(EXETYPE) : $(APP_OBJS)
@echo ---------------------------------------------------------------
@echo TARGET $@
$(LD) $(LINK_CMD) $(TARGET).$(EXETYPE) $(LFLAGS) $(APP_OBJS) -lgcc
@echo ---------------------------------------------------------------Thanks again!

Hi wardw,
I am trying to port Expat to BREW.
http://brewforums.qualcomm.com/showthread.php?t=12982
Any i was finding it very difficult to pot using ADS 1.2 due to the -ropi switch.
But last night i gave a try with WinARM and it Compiled and linked like a Piece of cake. :D
Thanks man.
But about the mod size I am worried. The Size of mod file generated with ADS 1.2 (without -ropi switch) is around 87K but the size of mod file generated by WinARM is 217KB. :confused:
It may be because I have not used some optimization options. Can any body help in that?
Thanks in advance.

Hi wardw,
I am trying to port Expat to BREW.
http://brewforums.qualcomm.com/showthread.php?t=12982
Any i was finding it very difficult to pot using ADS 1.2 due to the -ropi switch.
But last night i gave a try with WinARM and it Compiled and linked like a Piece of cake. :D
Thanks man.
But about the mod size I am worried. The Size of mod file generated with ADS 1.2 (without -ropi switch) is around 87K but the size of mod file generated by WinARM is 217KB. :confused:
It may be because I have not used some optimization options. Can any body help in that?
Thanks in advance.

Did you follow the steps above from wardw? Look at the mod file, if its filled with zeros, thats where most of the file size comes from.
Try following wardw's steps from compilation to linking. I was able to get a decent size 3 ~ 4 KB larger than compared to the ARM compiler. However, I was not able to compile everything in thumb compilation due to startup crashes.
HTH

Did you follow the steps above from wardw? Look at the mod file, if its filled with zeros, thats where most of the file size comes from.
Try following wardw's steps from compilation to linking. I was able to get a decent size 3 ~ 4 KB larger than compared to the ARM compiler. However, I was not able to compile everything in thumb compilation due to startup crashes.
HTH

Yes i did only think i changed is Remove the -DEBUG and Put -Os and the mod size came down to around 107 KB . :D
Great Work By WinARM.

Yes i did only think i changed is Remove the -DEBUG and Put -Os and the mod size came down to around 107 KB . :D
Great Work By WinARM.

Now the question is the WinARM compiled files and ADS 1.2 compiled files Co-Exist or I have to make the WinARM or ADS generated module as A Extension to work both of them together.
Any Comments.

Now the question is the WinARM compiled files and ADS 1.2 compiled files Co-Exist or I have to make the WinARM or ADS generated module as A Extension to work both of them together.
Any Comments.

Very good tutorial.
However I cannot seem to get it to link without undefined references to...
__udivsi3
__divdi3
__modsi3
-lm does nothing
-lgcc complians that it can't find it.
I'm not sure what try next. Any help would be greatly appreciated.
UPDATE: I got it to find the libgcc.a library (using -lgcc) but it still fails. with the same undefined references.

Very good tutorial.
However I cannot seem to get it to link without undefined references to...
__udivsi3
__divdi3
__modsi3
-lm does nothing
-lgcc complians that it can't find it.
I'm not sure what try next. Any help would be greatly appreciated.
UPDATE: I got it to find the libgcc.a library (using -lgcc) but it still fails. with the same undefined references.

May be one of the below
1. library is not included due to the wrong path.
2. No target assembler?
3. May be the WinARm req a patch :D

May be one of the below
1. library is not included due to the wrong path.
2. No target assembler?
3. May be the WinARm req a patch :D

Skavenger wrote:However I cannot seem to get it to link without undefined references to...
__udivsi3
__divdi3
__modsi3
-lm does nothing
-lgcc complians that it can't find it.
I'm not sure what try next. Any help would be greatly appreciated.
UPDATE: I got it to find the libgcc.a library (using -lgcc) but it still fails. with the same undefined references.Hi Skavenger,
I had the same problem. Try moving the -lgcc to the _END_ of the linking statement:
\winarm\bin\arm-elf-ld.exe ... AEEAppGen.o applet.o -lgccHTH

Skavenger wrote:However I cannot seem to get it to link without undefined references to...
__udivsi3
__divdi3
__modsi3
-lm does nothing
-lgcc complians that it can't find it.
I'm not sure what try next. Any help would be greatly appreciated.
UPDATE: I got it to find the libgcc.a library (using -lgcc) but it still fails. with the same undefined references.Hi Skavenger,
I had the same problem. Try moving the -lgcc to the _END_ of the linking statement:
\winarm\bin\arm-elf-ld.exe ... AEEAppGen.o applet.o -lgccHTH

Thanks for the replies.
However as stated -lgcc (or libgcc.a) and -lm (or libm.a) are being loaded and found as stated in my original mail (I checked with the --verbose output). I also have already tried including the gcc lib at the start and at the end to absolutely no effect (Attempting with the -lgcc and with -l libgcc.a options). I have also tried specifying the libs using GROUP() in the script.
I have a target set. Unless you also have to set a target in the linker. Which from the tutorial at the start of this thread seems to state I don't. (ARM7TDMI is set for the compiler as should be even though some of the newer handsets have the better ARM9 and ARM10 procesors).
I have tried with the two latest versions of winarm. Can't remember the dates but the libs folders were either set to 4.1.0 or 4.1.1. This also had no effect.
I am completely stumped on this now.
{expletives removed}
The only thing I can think of that could be wrong is that these arithmetic functions being asked for are c++ declared (As its in the cpp files that these are failing) and the actual functions in the lib are c declared.
Anyone else have any ideas?

Thanks for the replies.
However as stated -lgcc (or libgcc.a) and -lm (or libm.a) are being loaded and found as stated in my original mail (I checked with the --verbose output). I also have already tried including the gcc lib at the start and at the end to absolutely no effect (Attempting with the -lgcc and with -l libgcc.a options). I have also tried specifying the libs using GROUP() in the script.
I have a target set. Unless you also have to set a target in the linker. Which from the tutorial at the start of this thread seems to state I don't. (ARM7TDMI is set for the compiler as should be even though some of the newer handsets have the better ARM9 and ARM10 procesors).
I have tried with the two latest versions of winarm. Can't remember the dates but the libs folders were either set to 4.1.0 or 4.1.1. This also had no effect.
I am completely stumped on this now.
{expletives removed}
The only thing I can think of that could be wrong is that these arithmetic functions being asked for are c++ declared (As its in the cpp files that these are failing) and the actual functions in the lib are c declared.
Anyone else have any ideas?

thanks a lot for the tutorial, it is really of great help for first time user like him but what parameter do i need to change in case i want to compile for arm9 and i mean in case of mcpu=arm7tdmi paramter can i put 9 instead of 7 or will the same work for me.
thanks in advance

thanks a lot for the tutorial, it is really of great help for first time user like him but what parameter do i need to change in case i want to compile for arm9 and i mean in case of mcpu=arm7tdmi paramter can i put 9 instead of 7 or will the same work for me.
thanks in advance

makhsan wrote:thanks a lot for the tutorial, it is really of great help for first time user like him but what parameter do i need to change in case i want to compile for arm9 and i mean in case of mcpu=arm7tdmi paramter can i put 9 instead of 7 or will the same work for me.
thanks in advance
Apologies in advance for the newb question.. How can I determine the CPU type for different handsets?

makhsan wrote:thanks a lot for the tutorial, it is really of great help for first time user like him but what parameter do i need to change in case i want to compile for arm9 and i mean in case of mcpu=arm7tdmi paramter can i put 9 instead of 7 or will the same work for me.
thanks in advance
Apologies in advance for the newb question.. How can I determine the CPU type for different handsets?

Hi.
Look around ISHELL_GetDeviceInfoEx()
with param AEE_DEVICEITEM_CHIP_ID or something like this. You can find details in api referece by AEEDeviceItem enum...

Hi.
Look around ISHELL_GetDeviceInfoEx()
with param AEE_DEVICEITEM_CHIP_ID or something like this. You can find details in api referece by AEEDeviceItem enum...

higB wrote:Apologies in advance for the newb question.. How can I determine the CPU type for different handsets?
MSM6050 and below use ARM7TDMI.
MSM6100 and above use ARM926EJ-S.
I'm certain this is not entirely true... but you can find the chipset on the phone's datasheet/device pack and then look up Qualcomm's datasheet for that chipset. The above rule is relatively close.
And of course, assuming everything is running ARM7TDMI will work fine, they're all backwards compatible.

higB wrote:Apologies in advance for the newb question.. How can I determine the CPU type for different handsets?
MSM6050 and below use ARM7TDMI.
MSM6100 and above use ARM926EJ-S.
I'm certain this is not entirely true... but you can find the chipset on the phone's datasheet/device pack and then look up Qualcomm's datasheet for that chipset. The above rule is relatively close.
And of course, assuming everything is running ARM7TDMI will work fine, they're all backwards compatible.

Many years ago, we ran into the same problem with the GCC tool chain. What I did was to simply copy the source code for the functions into our project tree :rolleyes:
How did you solve it?
Skavenger wrote:Very good tutorial.
However I cannot seem to get it to link without undefined references to...
__udivsi3
__divdi3
__modsi3
-lm does nothing
-lgcc complians that it can't find it.
I'm not sure what try next. Any help would be greatly appreciated.
UPDATE: I got it to find the libgcc.a library (using -lgcc) but it still fails. with the same undefined references.

Many years ago, we ran into the same problem with the GCC tool chain. What I did was to simply copy the source code for the functions into our project tree :rolleyes:
How did you solve it?
Skavenger wrote:Very good tutorial.
However I cannot seem to get it to link without undefined references to...
__udivsi3
__divdi3
__modsi3
-lm does nothing
-lgcc complians that it can't find it.
I'm not sure what try next. Any help would be greatly appreciated.
UPDATE: I got it to find the libgcc.a library (using -lgcc) but it still fails. with the same undefined references.

hi friends,
i am trying to make application in c++ using Winarm. i got success get basic app "hello world" in c++ and putting it in to phone. but when i include in that Inhertiance and virtual function concep, it gives link time error. i mean vitrual table is not been referring by linker..
do you have any solution for that? i include -lgcc at linking time. is there any library which should be included or is there any way to give wrpper?
if any suggestion or clue, please reply me. following is the sequenc for ARM compilation and linking.
Compile:
----------------------
"D:\WinARM\bin\arm-elf-gcc.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o AEEModGen.o -c AEEModGen.c
"D:\WinARM\bin\arm-elf-gcc.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o AEEAppGen.o -c AEEAppGen.c
"D:\WinARM\bin\arm-elf-g++.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o CrossLinkerSelf.o -c CrossLinkerSelf.cpp
(CroosLinkerSelf is wrapper for new and delete for my project)
"D:\WinARM\bin\arm-elf-g++.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o cplustwo.o -c cplustwo.cpp
LINK
=====
"D:\WinARM\bin\arm-elf-ld.exe" --script armelf.brew --emit-relocs --verbose --no-warn-mismatch -L "D:\WinARM\lib\gcc\arm-elf\4.1.1" -lgcc -o "cplustwo.elf" AEEAppGen.o CrossLinkerSelf.o cplustwo.o
Elf To Mod
===========
"D:\Program Files\BREW SDK Tools 1.1.1\VSAddins\common\bin\BREWelf2mod.exe" cplustwo.elf cplustwo.mod
:o :confused:

hi friends,
i am trying to make application in c++ using Winarm. i got success get basic app "hello world" in c++ and putting it in to phone. but when i include in that Inhertiance and virtual function concep, it gives link time error. i mean vitrual table is not been referring by linker..
do you have any solution for that? i include -lgcc at linking time. is there any library which should be included or is there any way to give wrpper?
if any suggestion or clue, please reply me. following is the sequenc for ARM compilation and linking.
Compile:
----------------------
"D:\WinARM\bin\arm-elf-gcc.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o AEEModGen.o -c AEEModGen.c
"D:\WinARM\bin\arm-elf-gcc.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o AEEAppGen.o -c AEEAppGen.c
"D:\WinARM\bin\arm-elf-g++.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o CrossLinkerSelf.o -c CrossLinkerSelf.cpp
(CroosLinkerSelf is wrapper for new and delete for my project)
"D:\WinARM\bin\arm-elf-g++.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o cplustwo.o -c cplustwo.cpp
LINK
=====
"D:\WinARM\bin\arm-elf-ld.exe" --script armelf.brew --emit-relocs --verbose --no-warn-mismatch -L "D:\WinARM\lib\gcc\arm-elf\4.1.1" -lgcc -o "cplustwo.elf" AEEAppGen.o CrossLinkerSelf.o cplustwo.o
Elf To Mod
===========
"D:\Program Files\BREW SDK Tools 1.1.1\VSAddins\common\bin\BREWelf2mod.exe" cplustwo.elf cplustwo.mod
:o :confused:

ya, i got solution for compiling c++ on winArm comppiler and also able to make mid file which is running fine on phone.
i have change my option when writing command for compile c++ code.
preivously it is,
"D:\WinARM\bin\arm-elf-gcc.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o AEEModGen.o -c AEEModGen.c
now it is
" D:\WinARM\bin\arm-elf-gcc -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -fno-exceptions -fno-unwind-tables -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -I "D:\PROGRA~1\BRE W31~1.5\sdk\inc" -o AEEModGen.o -c D:\PROGRA~1\BREW31~1.5\sdk\src\AEEModGen.c "
for all c and c++ code. it will resolve c++ code in assembly code which can be understand by c and than link.

ya, i got solution for compiling c++ on winArm comppiler and also able to make mid file which is running fine on phone.
i have change my option when writing command for compile c++ code.
preivously it is,
"D:\WinARM\bin\arm-elf-gcc.exe" -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -o AEEModGen.o -c AEEModGen.c
now it is
" D:\WinARM\bin\arm-elf-gcc -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -fno-exceptions -fno-unwind-tables -DDYNAMIC_APP -I "D:\Program Files\BREW 3.1.5\sdk\inc" -I "D:\PROGRA~1\BRE W31~1.5\sdk\inc" -o AEEModGen.o -c D:\PROGRA~1\BREW31~1.5\sdk\src\AEEModGen.c "
for all c and c++ code. it will resolve c++ code in assembly code which can be understand by c and than link.

Hi Guys,
I am trying to make MOD file using winarm but on running command for making mod file i am getting following error.
Can anyone help me why this is happening.
==================================================
attempt to open AEEModGen.o succeeded
AEEModGen.o
attempt to open C:\WinARM\lib\gcc\arm-elf\4.1.1/libgcc.so failed
attempt to open C:\WinARM\lib\gcc\arm-elf\4.1.1\libgcc.a succeeded
attempt to open AEEAppGen.o succeeded
AEEAppGen.o
attempt to open helloworld.o succeeded
helloworld.o
attempt to open GCCResolver.o succeeded
GCCResolver.o
C:\Program Files\BREW SDK v2.1.0\Examples\HelloWorld>C:\Elf2Mod\bin\elf2mod.exe
helloworld.elf helloworld.mod
elf2mod: Error: ELFFile:343: ELF2Mod_Exception : No RO PT_LOAD Segment in ELF f
my bat file has following instruction set.
........................................................................
C:\WinARM\bin\arm-elf-gcc.exe -c -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDEBUG -DDYNAMIC_APP -I "C:\Program Files\BREW SDK v2.1.0\inc" -o AEEAppGen.o -c "C:\Program Files\BREW SDK v2.1.0\src\AEEAppGen.c"
C:\WinARM\bin\arm-elf-gcc.exe -c -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDEBUG -DDYNAMIC_APP -I "C:\Program Files\BREW SDK v2.1.0\inc" -o AEEModGen.o -c "C:\Program Files\BREW SDK v2.1.0\src\AEEModGen.c"
C:\WinARM\bin\arm-elf-gcc.exe -c -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDEBUG -DDYNAMIC_APP -I "C:\Program Files\BREW SDK v2.1.0\inc" -o GCCResolver.o -c "C:\Program Files\BREW SDK v2.1.0\src\GCCResolver.c"
C:\WinARM\bin\arm-elf-gcc.exe -c -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDEBUG -DDYNAMIC_APP -I"C:\Program Files\BREW SDK v2.1.0\Examples\HelloWorld" -I"C:\Program Files\BREW SDK v2.1.0\inc" -o helloworld.o -c "C:\Program Files\BREW SDK v2.1.0\Examples\HelloWorld\helloworld.c"
C:\WinARM\bin\arm-elf-ld.exe --script armelf.brew --emit-relocs --verbose --no-warn-mismatch -L "C:\WinARM\lib\gcc\arm-elf\4.1.1" -lgcc -o "helloworld.elf" AEEAppGen.o AEEModGen.o helloworld.o GCCResolver.o
C:\Elf2Mod\bin\elf2mod.exe helloworld.elf helloworld.mod

Hi Guys,
I am trying to make MOD file using winarm but on running command for making mod file i am getting following error.
Can anyone help me why this is happening.
==================================================
attempt to open AEEModGen.o succeeded
AEEModGen.o
attempt to open C:\WinARM\lib\gcc\arm-elf\4.1.1/libgcc.so failed
attempt to open C:\WinARM\lib\gcc\arm-elf\4.1.1\libgcc.a succeeded
attempt to open AEEAppGen.o succeeded
AEEAppGen.o
attempt to open helloworld.o succeeded
helloworld.o
attempt to open GCCResolver.o succeeded
GCCResolver.o
C:\Program Files\BREW SDK v2.1.0\Examples\HelloWorld>C:\Elf2Mod\bin\elf2mod.exe
helloworld.elf helloworld.mod
elf2mod: Error: ELFFile:343: ELF2Mod_Exception : No RO PT_LOAD Segment in ELF f
my bat file has following instruction set.
........................................................................
C:\WinARM\bin\arm-elf-gcc.exe -c -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDEBUG -DDYNAMIC_APP -I "C:\Program Files\BREW SDK v2.1.0\inc" -o AEEAppGen.o -c "C:\Program Files\BREW SDK v2.1.0\src\AEEAppGen.c"
C:\WinARM\bin\arm-elf-gcc.exe -c -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDEBUG -DDYNAMIC_APP -I "C:\Program Files\BREW SDK v2.1.0\inc" -o AEEModGen.o -c "C:\Program Files\BREW SDK v2.1.0\src\AEEModGen.c"
C:\WinARM\bin\arm-elf-gcc.exe -c -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDEBUG -DDYNAMIC_APP -I "C:\Program Files\BREW SDK v2.1.0\inc" -o GCCResolver.o -c "C:\Program Files\BREW SDK v2.1.0\src\GCCResolver.c"
C:\WinARM\bin\arm-elf-gcc.exe -c -mlittle-endian -mcpu=arm7tdmi -mapcs-frame -fno-builtin -ffunction-sections -DDEBUG -DDYNAMIC_APP -I"C:\Program Files\BREW SDK v2.1.0\Examples\HelloWorld" -I"C:\Program Files\BREW SDK v2.1.0\inc" -o helloworld.o -c "C:\Program Files\BREW SDK v2.1.0\Examples\HelloWorld\helloworld.c"
C:\WinARM\bin\arm-elf-ld.exe --script armelf.brew --emit-relocs --verbose --no-warn-mismatch -L "C:\WinARM\lib\gcc\arm-elf\4.1.1" -lgcc -o "helloworld.elf" AEEAppGen.o AEEModGen.o helloworld.o GCCResolver.o
C:\Elf2Mod\bin\elf2mod.exe helloworld.elf helloworld.mod

Hi,
I found the solution for the problem. I think there is a problem with armelf.brew written above. Now i am using elf2mod.x that is comming with new BREW 2Elf tool.
thnx everybody

Hi,
I found the solution for the problem. I think there is a problem with armelf.brew written above. Now i am using elf2mod.x that is comming with new BREW 2Elf tool.
thnx everybody