Unaligned problem when porting rtems for arm

Peng Fan van.freenix at gmail.com
Wed Apr 24 13:03:34 UTC 2013

Source code:rtems 4.11
gcc version  :arm-rtemseabi4.11-
Arch           : arm1176jzf-s, s3c6410

When I am testing fileio testcase on s3c6410 board, I always encounter such

[/] # abc
*scriptFile 50183118, length 1          //(0)*

Unrecognized instruction
data_abort at address 0x501225D8, instruction: 0xE18430B0,   spsr =
active thread thread 0x0A010003
Previous sp=0x50183000 lr=0x501225D0 and actual cpsr=60000197
 0x00000020 0x501842D0 0x00000003 0x50122898 0x501770D8 0x00000020
 0x5017CDD8 0x1A010004 0x00000000 0x501839B0 0x50183078 0x00000000
 0x00000001 0x00000001 0x501835DC 0x5011346C 0x501835DC 0x00000000
 0x00000000 0x0017B260 0x5017CDD8 0x50111C4C 0x00000059 0x00000000
 0x5017B260 0x50183618 0x501831B8 0x50145334 0x00000000 0x501449B0
 0x5017B260 0x5017B228 0x00000059 0x00000000 0x501839AF 0x00000001
 0x00000104 0x00000001 0x00000000 0x00000000 0x00000000 0x00000000
 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000 0x00000000

But if I input "/abc", all is ok.

I am confusing why use "strh", but not "strb" instruction. Because if r4+r0
is not aligned, fault occurs.

The source code of findOnPATH is

static int findOnPATH(
  const char *userScriptName,  *//register r0*
  char       *scriptFile,              * //register r1*
  size_t      scriptFileLength      *//register r2*
  int sc;
    /* XXX should use strncat but what is the limit? */
    getcwd( scriptFile, PATH_MAX ); *(1)*
  printk("scriptFile %s, length %d\n", scriptFile, strlen(scriptFile));
    strncat( scriptFile, "/", PATH_MAX );*(2)*
    strncat(                                          * (3)*
      ( (userScriptName[0] == '.' && userScriptName[1] == '/') ?
         &userScriptName[2] : userScriptName),


The correspondence between  assemble  and  c code is   (a)---(1) ,
(b)----(2), (c)----(3)
I locate the address *0x501225D8*. The dissassemble code is following:
gcc optimize the code for (2).

5012258c <findOnPATH.isra.0>:
5012258c: e92d4038 push {r3, r4, r5, lr}
50122590: e5d03000 ldrb r3, [r0]
50122594: e1a05000 mov r5, r0
50122598: e353002f cmp r3, #47 ; 0x2f
5012259c: e1a04001 mov r4, r1   * //store scriptFile --> r4*
501225a0: 0a00001b beq 50122614 <findOnPATH.isra.0+0x88>
501225a4: e3a010ff mov r1, #255 ; 0xff
501225a8: e1a00004 mov r0, r4
501225ac: eb009dd6 bl 50149d0c <getcwd> *(a)*
501225b0: e1a00004 mov r0, r4 * //restore scriptFile-->r0*
501225b4: eb00b27a bl 5014efa4 <strlen>
501225b8: e1a01004 mov r1, r4
501225bc: e1a02000 mov r2, r0
501225c0: e59f0070 ldr r0, [pc, #112] ; 50122638 <findOnPATH.isra.0+0xac>
501225c4: ebffb4a6 bl 5010f864 <printk>
501225c8: e1a00004 mov r0, r4 * //restore scriptFile-->r0*
501225cc: eb00b274 bl 5014efa4 <strlen>  *//strlen(scriptFile) here lenght
is 1 because (1)*
*assign "/" to scriptFile, so strlen assigns 1 to r0.*
501225d0: e59f3064 ldr r3, [pc, #100] ; 5012263c <findOnPATH.isra.0+0xb0>
501225d4: e1d330b0 ldrh r3, [r3] *//It loads '2f00' from address (d)  to
r3, in string format is "/"*
501225d8: e18430b0 * strh r3, [r4, r0] // (b)  r4 is 0x50183118, r0 is 1.*
501225dc: e5d53000 ldrb r3, [r5]
501225e0: e353002e cmp r3, #46 ; 0x2e
501225e4: 0a00000f beq 50122628 <findOnPATH.isra.0+0x9c>
501225e8: e1a00004 mov r0, r4
501225ec: e1a01005 mov r1, r5
501225f0: e3a020ff mov r2, #255 ; 0xff
501225f4: eb00b282 bl 5014f004 <strncat> *(c)*
5012263c: 5016fe5c andspl pc, r6, ip, asr lr ; <UNPREDICTABLE>
5016fe5c: *0000002f * andeq r0, r0, pc, lsr #32* (d) *

why (b) incurs fault? r4 is an 4 byte aligned address listed in (0), while
r0 is 1. Thus strh access an unaligned address, and incurs fault. Why using
strh when not know the length of "scriptFile".
I am not sure whether this analysis is correct, but I have no other
reasonable explanation.

Thanks in advance for you advice.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20130424/50a54fcc/attachment.html>

More information about the users mailing list