Add "memory" clobbers to the x86 inline asm of strncmp and friends
They don't actually clobber memory, but gcc doesn't even know they _read_ memory, so can apparently re-order memory accesses around them. Which obviously does the wrong thing if the memory access happens to change the memory that the compare function is accessing.. Verified to fix a strange boot problem by Jens Axboe.
This commit is contained in:
@@ -116,7 +116,8 @@ __asm__ __volatile__(
|
|||||||
"orb $1,%%al\n"
|
"orb $1,%%al\n"
|
||||||
"3:"
|
"3:"
|
||||||
:"=a" (__res), "=&S" (d0), "=&D" (d1)
|
:"=a" (__res), "=&S" (d0), "=&D" (d1)
|
||||||
:"1" (cs),"2" (ct));
|
:"1" (cs),"2" (ct)
|
||||||
|
:"memory");
|
||||||
return __res;
|
return __res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,8 +139,9 @@ __asm__ __volatile__(
|
|||||||
"3:\tsbbl %%eax,%%eax\n\t"
|
"3:\tsbbl %%eax,%%eax\n\t"
|
||||||
"orb $1,%%al\n"
|
"orb $1,%%al\n"
|
||||||
"4:"
|
"4:"
|
||||||
:"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
|
:"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
|
||||||
:"1" (cs),"2" (ct),"3" (count));
|
:"1" (cs),"2" (ct),"3" (count)
|
||||||
|
:"memory");
|
||||||
return __res;
|
return __res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +160,9 @@ __asm__ __volatile__(
|
|||||||
"movl $1,%1\n"
|
"movl $1,%1\n"
|
||||||
"2:\tmovl %1,%0\n\t"
|
"2:\tmovl %1,%0\n\t"
|
||||||
"decl %0"
|
"decl %0"
|
||||||
:"=a" (__res), "=&S" (d0) : "1" (s),"0" (c));
|
:"=a" (__res), "=&S" (d0)
|
||||||
|
:"1" (s),"0" (c)
|
||||||
|
:"memory");
|
||||||
return __res;
|
return __res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +179,9 @@ __asm__ __volatile__(
|
|||||||
"leal -1(%%esi),%0\n"
|
"leal -1(%%esi),%0\n"
|
||||||
"2:\ttestb %%al,%%al\n\t"
|
"2:\ttestb %%al,%%al\n\t"
|
||||||
"jne 1b"
|
"jne 1b"
|
||||||
:"=g" (__res), "=&S" (d0), "=&a" (d1) :"0" (0),"1" (s),"2" (c));
|
:"=g" (__res), "=&S" (d0), "=&a" (d1)
|
||||||
|
:"0" (0),"1" (s),"2" (c)
|
||||||
|
:"memory");
|
||||||
return __res;
|
return __res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,7 +195,9 @@ __asm__ __volatile__(
|
|||||||
"scasb\n\t"
|
"scasb\n\t"
|
||||||
"notl %0\n\t"
|
"notl %0\n\t"
|
||||||
"decl %0"
|
"decl %0"
|
||||||
:"=c" (__res), "=&D" (d0) :"1" (s),"a" (0), "0" (0xffffffffu));
|
:"=c" (__res), "=&D" (d0)
|
||||||
|
:"1" (s),"a" (0), "0" (0xffffffffu)
|
||||||
|
:"memory");
|
||||||
return __res;
|
return __res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -333,7 +341,9 @@ __asm__ __volatile__(
|
|||||||
"je 1f\n\t"
|
"je 1f\n\t"
|
||||||
"movl $1,%0\n"
|
"movl $1,%0\n"
|
||||||
"1:\tdecl %0"
|
"1:\tdecl %0"
|
||||||
:"=D" (__res), "=&c" (d0) : "a" (c),"0" (cs),"1" (count));
|
:"=D" (__res), "=&c" (d0)
|
||||||
|
:"a" (c),"0" (cs),"1" (count)
|
||||||
|
:"memory");
|
||||||
return __res;
|
return __res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,7 +379,7 @@ __asm__ __volatile__(
|
|||||||
"je 2f\n\t"
|
"je 2f\n\t"
|
||||||
"stosb\n"
|
"stosb\n"
|
||||||
"2:"
|
"2:"
|
||||||
: "=&c" (d0), "=&D" (d1)
|
:"=&c" (d0), "=&D" (d1)
|
||||||
:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
|
:"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
|
||||||
:"memory");
|
:"memory");
|
||||||
return (s);
|
return (s);
|
||||||
@@ -392,7 +402,8 @@ __asm__ __volatile__(
|
|||||||
"jne 1b\n"
|
"jne 1b\n"
|
||||||
"3:\tsubl %2,%0"
|
"3:\tsubl %2,%0"
|
||||||
:"=a" (__res), "=&d" (d0)
|
:"=a" (__res), "=&d" (d0)
|
||||||
:"c" (s),"1" (count));
|
:"c" (s),"1" (count)
|
||||||
|
:"memory");
|
||||||
return __res;
|
return __res;
|
||||||
}
|
}
|
||||||
/* end of additional stuff */
|
/* end of additional stuff */
|
||||||
@@ -473,7 +484,8 @@ static inline void * memscan(void * addr, int c, size_t size)
|
|||||||
"dec %%edi\n"
|
"dec %%edi\n"
|
||||||
"1:"
|
"1:"
|
||||||
: "=D" (addr), "=c" (size)
|
: "=D" (addr), "=c" (size)
|
||||||
: "0" (addr), "1" (size), "a" (c));
|
: "0" (addr), "1" (size), "a" (c)
|
||||||
|
: "memory");
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user