about summary refs log tree commit diff
path: root/stdio-common
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2017-10-27 02:31:13 -0700
committerH.J. Lu <hjl.tools@gmail.com>2017-10-30 05:43:24 -0700
commit9a89973274f901f4c3313e6e2b84d6b2108c7924 (patch)
tree46dec892b25c138467c6fc7109eb64392b94bf50 /stdio-common
parentdadf23f06c134d09b5930e09bddfdab2c0ca6150 (diff)
downloadglibc-9a89973274f901f4c3313e6e2b84d6b2108c7924.tar.gz
glibc-9a89973274f901f4c3313e6e2b84d6b2108c7924.tar.xz
glibc-9a89973274f901f4c3313e6e2b84d6b2108c7924.zip
i586: Use a jump table in strcpy.S [BZ #22353]
i586 strcpy.S used a clever trick with LEA to avoid jump table:

/* ECX has the last 2 bits of the address of source - 1.  */
	andl	$3, %ecx

        call    2f
2:      popl    %edx
	/* 0xb is the distance between 2: and 1:.  */
        leal    0xb(%edx,%ecx,8), %ecx
        jmp     *%ecx

        .align 8
1:  /* ECX == 0 */
        orb     (%esi), %al
        jz      L(end)
        stosb
        xorl    %eax, %eax
        incl    %esi
    /* ECX == 1 */
        orb     (%esi), %al
        jz      L(end)
        stosb
        xorl    %eax, %eax
        incl    %esi
    /* ECX == 2 */
        orb     (%esi), %al
        jz      L(end)
        stosb
        xorl    %eax, %eax
        incl    %esi
    /* ECX == 3 */
L(1):   movl    (%esi), %ecx
        leal    4(%esi),%esi

This may fail if there are instruction length changes before L(1):.  This
patch replaces it with a jump table which works with any instruction length
changes.

Tested on i586 and i686 with and without --disable-multi-arch.

	[BZ #22353]
	* sysdeps/i386/i586/strcpy.S (JMPTBL): New.
	(BRANCH_TO_JMPTBL_ENTRY): Likewise.
	(STRCPY): Use it.
	(1): Renamed to ...
	(L(Src0)): This.
	(L(Src1)): New.
	(L(Src2)): Likewise.
	(L(1)): Renamed to ...
	(L(Src3)): This.
	(L(SrcTable)): New.
Diffstat (limited to 'stdio-common')
0 files changed, 0 insertions, 0 deletions