[cfe-dev] Bug of intrin functions

Liu Hao via cfe-dev cfe-dev at lists.llvm.org
Wed Nov 1 23:05:41 PDT 2017


On 2017/11/1 22:08, LIANG Xingliang via cfe-dev wrote:
> I just find a serious bug. Windows prebuilt binary.
> -------------------------------------------------------------------------------------------------------
> #include <stdio.h>
> #include <intrin.h>
> 
> //this function is just copyed from `intrin.h': __movsb(), __x86_64__
> static __inline__ void __attribute__((__always_inline__, __nodebug__))
> __movsb_buggy(unsigned char *__dst, unsigned char const *__src, size_t 
> __n) {
> //for(size_t i=0; i<__n; i++) __dst[i] = __src[i]; //OK
> __asm__("rep movsb" : : "D"(__dst), "S"(__src), "c"(__n)); //FAIL
> }
> 
> int main(int argc, const char ** argv)
> {
> unsigned char dst[4]={'a', 'b', 'c', '\0'};
> unsigned char src[4]={'1', '2', '3', '\0'};
> __movsb_buggy(dst, src, 1);
> puts((char*)dst); //expect "1bc", but get "bc"
> puts((char*)src); //expect "123", but get "23"
> return 0;
> }
> ------------------------------------------------------------------------------------------------
> 
This implementation looks wrong to me.

First, `movsb` alters RDI, RSI and RCX, so all three parameters must be 
in-out ones. Second, the memory area offset from RDI is written to and 
the one offset from RSI is read from, but this __asm__ statement fails 
to say that.

AFAICT the correct implementation should be:
```
static __inline__ void __attribute__((__always_inline__, __nodebug__))
__movsb(unsigned char *__dst, unsigned char const *__src, size_t __n)
{
   __asm__ ("rep movsb"
     : "+D"(__dst), "+S"(__src), "+c"(__n), "=m"(*(char (*)[])__dst)
     : "m"(*(char (*)[])__src)
   );
}
```


-- 
Best regards,
LH_Mouse



More information about the cfe-dev mailing list