Illegal Instruction using virtual function

Warren E. Downs
I'm stumped. The following simple C++ program runs fine on i386 Linux, but
when compiled with 4.3.2 version of arm-none-linux-gnueabi-g++ and executed
on the arm platform, it crashes with an "Illegal Instruction" when it tries
to call the virtual function.

Output on i386:
main
Made it!

Output on arm:
main
Illegal instruction

The program is as follows:
------------------ CUT HERE ------------------
#include <stdio.h>
#include <stdlib.h>

class Illegal {
public:
  virtual void Crash();
};

void Illegal::Crash() {
  printf("Made it!\n");
}

int main() {
  printf("main\n");
  Illegal* i=new Illegal();
  i->Crash();
  delete i;
}
------------------ CUT HERE ------------------
Anything I'm missing?  Is there a version of the compiler that fixes this
apparent compiler bug?

Warren E. Downs
As a follow up, I tried using a function pointer instead of a virtual
method.  Same result: It works on i386 and produces an "Illegal
Instruction" on arm.  On the off chance it might be a cache-coherency issue
on the arm platform, I tried using a volatile function pointer, but the
problem remains.

open-nandra
Is toolchain compiled only for arm920 or it is multi? If multi you need to
specify cpu type something like : -march=armv4t when cross compile. Seems
to me it's compiled for wrong cpu.

thanks,

marek

davef
Warren,
Seeing as I didn't have a clue I searched the post title and found this:
http://www.artima.com/cppsource/pure_virtual.html
All I can say is good luck, it looks like you found a real knarly problem!
Dave

open-nandra
Warren : sorry don't read properly. Forget my reply ;)

eduardo
Hi Warren,

Could you post your makefile here?

Warren E. Downs
open-nandra, you were on the right track.  The default CPU for my compiler
turns out to be arm10tdmi, and while the instructions produced worked fine
for most of my nearly 5000 line program, when I tried virtual functions, or
function pointers (same underlying logic), I ran into the problem.  I
didn't even suspect the CPU being the issue because I hadn't noticed what
the target CPU was (since it "just worked" until now).

When I compiled to assembly source I noticed the use of the BLX instruction
was causing the crash.  Then I noticed the target CPU comment in the
assembly source.  Adding the -mcpu=arm9 flag fixes the problem nicely.

For those who might not know how to go about this (compile to assembly,
examine the source, then assemble and link), here are the steps:

-------- CUT HERE ------------
# Define path to cross-compiling toolchain
X=/path/to/arch-arm/gcc/usr/local/arm/4.3.2/bin/arm-none-linux-gnueabi-

# Compile to assembly source
${X}g++ -mcpu=arm9 -S -Werror -Wl,-export-dynamic -o test.a test.c

# Here you can examine test.a to see what actual assembly code is
# produced.  Feel free to modify and experiment at this stage, 
# then continue.

# Assemble to object code
${X}as --gstabs -L -o test.o test.a

# Link
${X}g++ -o test test.o
-------- CUT HERE ------------

Thanks all for your replies.

eduardo
Hi Warren,

I'm not an expert, but try to use this flags too:

-msoft-float -D__GCC_FLOAT_NOT_NEEDED -march=armv4t -mtune=arm920t