ARC: [lib] strchr breakage in Big-endian configuration

For a search buffer, 2 byte aligned, strchr() was returning pointer
outside of buffer (buf - 1)

------------->8----------------
    // Input buffer (default 4 byte aigned)
    char *buffer = "1AA_";

    // actual search start (to mimick 2 byte alignment)
    char *current_line = &(buffer[2]);

    // Character to search for
    char c = 'A';

    char *c_pos = strchr(current_line, c);

    printf("%s\n", c_pos) --> 'AA_' as oppose to 'A_'
------------->8----------------

Reported-by: Anton Kolesov <Anton.Kolesov@synopsys.com>
Debugged-by: Anton Kolesov <Anton.Kolesov@synopsys.com>
Cc: <stable@vger.kernel.org> # [3.9 and 3.10]
Cc: Noam Camus <noamc@ezchip.com>
Signed-off-by: Joern Rennecke  <joern.rennecke@embecosm.com>
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Joern Rennecke 2013-08-24 12:03:06 +05:30 committed by Linus Torvalds
parent 89b53e50bd
commit b0f55f2a1a

View File

@ -39,9 +39,18 @@ ARC_ENTRY strchr
ld.a r2,[r0,4] ld.a r2,[r0,4]
sub r12,r6,r7 sub r12,r6,r7
bic r12,r12,r6 bic r12,r12,r6
#ifdef __LITTLE_ENDIAN__
and r7,r12,r4 and r7,r12,r4
breq r7,0,.Loop ; For speed, we want this branch to be unaligned. breq r7,0,.Loop ; For speed, we want this branch to be unaligned.
b .Lfound_char ; Likewise this one. b .Lfound_char ; Likewise this one.
#else
and r12,r12,r4
breq r12,0,.Loop ; For speed, we want this branch to be unaligned.
lsr_s r12,r12,7
bic r2,r7,r6
b.d .Lfound_char_b
and_s r2,r2,r12
#endif
; /* We require this code address to be unaligned for speed... */ ; /* We require this code address to be unaligned for speed... */
.Laligned: .Laligned:
ld_s r2,[r0] ld_s r2,[r0]
@ -95,6 +104,7 @@ ARC_ENTRY strchr
lsr r7,r7,7 lsr r7,r7,7
bic r2,r7,r6 bic r2,r7,r6
.Lfound_char_b:
norm r2,r2 norm r2,r2
sub_s r0,r0,4 sub_s r0,r0,4
asr_s r2,r2,3 asr_s r2,r2,3