ARM code crash on symbian 8.1b device

Hi,

I've got an audio decoder that has portions in inline assembly for the ARM 9 family of processors. This assembly code works fine on RVDS

2.1 and the C reference code works fine too.

When I build the code on RVCT 2.1 using the Symbian 8.1b SDK, and run the application on a device, it crashes with the following message :

Program Main Reason Code KERN_EXEC Reason Number 3

The pure C code works fine on the device. Its just the part with inline assembly thats causing trouble.

Any suggestions on how I could approach this ?

Reply to
gautham.chundi
Loading thread data ...

It seems that the assembly code is attempting to do something it is not allowed to, e.g. access the whole processor status register.

Would you mind posting the assembly code (if it is not overly long)?

--

Tauno Voipio
tauno voipio (at) iki fi
Reply to
Tauno Voipio

Hi Tauno,

Thanks for the response. I'm pasting the offending code below (Its fairly long, so I appreciate your response all the more :-) ).

This is for ARM9 TDMI, built on RVCT 2.1 for Symbian 8.1b. We're testing it on a TI OMAP 2420 board where its crashing. As I'd said earlier, the equivalent C code works on the device. Also, this assembly code has been generated by the ARM C compiler from the corresponding C code using ADS 1.2

__asm int function_name(CObject *pau, long int SGXform) { PRESERVE8 STMFD sp!,{r4-r8,lr} LDR lr,[r0,#0x140] LDR r8,[r0,#0x40] MOV r5,#0 MOV r3,#1 MOV r6,lr CMP r8,#2 BLE |L1.8880| LDR r2,[r0,#0x238] CMP r2,#0 LDRNE r2,[r0,#0x234] CMPNE r2,#0 LDREQ r5,=0x80070057 BEQ |L1.9088| |L1.8880| MOV r12,#0x23c LDRSH r7,[r12,r0] MOV r2,#0 MOV r4,#0xdf B |L1.8948| |L1.8900| LDR r12,[r0,#0x240] ADD r12,r12,r2,LSL #1 LDRSH r12,[r12,#0] ADD r2,r2,#1 MOV r2,r2,LSL #16 MUL r12,r4,r12 ADD r12,lr,r12,LSL #3 LDR r12,[r12,#0x28] MOV r2,r2,ASR #16 RSBS r12,r12,#1 MOVCC r12,#0 AND r3,r12,r3 |L1.8948| CMP r7,r2 BGT |L1.8900| CMP r8,#2 CMPLE r1,#0 BNE |L1.9088| LDRSB r1,[r6,#0x44] CMP r1,#0 BEQ |L1.9088| CMP r3,#0 BNE |L1.9088| LDR r1,[lr,#0x38]! LDR r2,[lr,#0x6f8] MOV r3,#0 MOV r12,#1 |L1.9004| LDRH lr,[r0,#0x26] CMP lr,r3 MULGT r7,r4,r3 LDRGT lr,[r0,#0x140] ADDGT r3,r3,#1 MOVGT r3,r3,LSL #16 ADDGT lr,lr,r7,LSL #3 STRGT r12,[lr,#0x28] MOVGT r3,r3,ASR #16 BGT |L1.9004| LDRSH r0,[r6,#0x78] |L1.9048| CMP r0,#0 BLE |L1.9088| LDR r3,[r1,#0] LDR r12,[r2,#0] SUB r0,r0,#1 ADD lr,r3,r12 STR lr,[r1],#4 SUB r3,r3,r12 STR r3,[r2],#4 B |L1.9048| |L1.9088| MOV r0,r5 LDMFD sp!,{r4-r8,pc} }

Best,

-gautham

Tauno Voipio wrote:

Reply to
gautham.chundi

OK - this looks just like dis-assembled compiler output.

The only cause I see for a crash is an attempted access outside the allocated memory area. My suspicions are for the parameter passing conventions - the code makes plenty of accesses based on r0 (which seems to be the first parameter, pau). There are offsets of up to 0x240 bytes from r0. Also, there are accesses using a pointer picked from *(r0 + 0x140) with offsets up to

0x6f8.

Different compilers may have different ideas of packing the structures, so the offsets may be totally wrong, and this would load an invalid pointer into lr at the very start of the code.

It's NOT a good idea to address structure components with absolute offsets in assembly code.

--

Tauno Voipio
tauno voipio (at) iki fi
Reply to
Tauno Voipio

There is nothing wrong with the assembly code per se, it is just not compatible with all the changes you've made. You're using a different Symbian OS version, a different compiler and most likely different source code as well. That's 3 ABI changes, making failure a certainty.

The last sentence hints to the problem. Why use disassembled code compiled by a different compiler as embedded assembler? What was wrong with the *working* C code?

Wilco

Reply to
Wilco Dijkstra

Are you saying that the inline assembler doesn't compile? In that case that's where your problem is! RVCT disallows some dangerous inline assembler, so check it and ensure it is legal inline assembler. Additionally you do want to check whether you actually need inline assembler at all. RVCT generates much better code than ADS, so it may not be needed anymore.

That's an incorrect solution for the wrong problem. You have added large blocks of disassembled C code. This disassembly obviously needs to be kept in sync with the rest of your sources...

The best way of doing something complicated is not to do it at all. Always find out what the underlying problem is and fix that, so the correct solution is to get your sources to compile with RVCT.

Wilco

Reply to
Wilco Dijkstra

Wilco,

My code does compile with RVCT 2.2 using RVDS 2.1. The assembly also works on the corresponding AXD emulator. As far as leaving routines in C goes, that might work well for this routine but not other routines like windowing, inverse quantization etc, where the ARM assembly code is significantly faster than the C code. This is why I'm trying to fix the problem in this function.

As far as I know, RVCT doesnt support inline assemby. This is why I'm first generating my .s code using ADS, and then using it as embedded assembly in RVCT along with changes to constant labels. It builds on RVDS 2.1, and the corresponding executable works on the emulator too.

It also compiles and builds on the Symbian 8.1b platform. Its only when I run the program on the TI OMAP 2420 board that the application is crashing.

Could this be a memory alignment issue ?

Best,

-gautham

Wilco Dijkstra wrote:

Reply to
gautham.chundi

Right, so the C version is perfectly fine for this function. Why not use it?

That's incorrect. Have you ever tried compiling the original code?

You have to stop doing this, it is never going to work.

Definitely not. I already explained what the problem is.

Wilco

Reply to
Wilco Dijkstra

Hi all,

I've fixed the issue and the code is now working fine on hardware. The problem was with a couple of enumerated data types being declared inside the CObject structure I had mentioned in the code (my second post). When I looked at this structure in AXD after compiling on ADS

1.2, I noticed that one field was being left out. This field was a boolean type that stays constant during the execution. Consequently, the offsets for the remaining fields in CObject were off by 2 bytes. This was causing a crash on the hardware.

Rebuilding the .s files by enabling the "Enum as integer" option in ARM ADS forces enumerated types to be integer, and took care of the issue. Just to be sure, I've removed any enumerated data types in my CObject, and have declared them using the #define instead. This fix seems to work well on hardware in addition to ADS, and RVDS, in addition to the hardware.

Many thanks to Wilco and Tauno for their insights. I agree entirely with their prognosis that any code thats been cross compiled on so many platforms is bound to have issues !

Best,

-gautham

Wilco,

I'm optimizing (in terms of cycles) an audio decoder to run on a mobile handset. Writing the original hand assembly in ARM ADS 1.2 is only to be able to use the two registers r12, and r14. These are not allowed on RVDS from my understanding. Besides which, most of the assembly code has already been written for an ADS platform, and rewriting it all for RVDS is not feasible presently. Yes, its a less than elegant fix for the problem. Thanks once again for your inputs !

Best,

-gautham

This seems to be optimization on part of

ADS > wrote in

messagenews: snipped-for-privacy@e3g2000cwe.googlegroups.com...

this function. Why not use it?

you ever tried compiling the original code?

have to stop doing this, it is never going to work.

what the problem is.

Reply to
gautham.chundi

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.