Mac OS X是否相当于RtlSecureZeroMemory
/ SecureZeroMemory
,这是一个将内存块归零的函数,但编译器不会对调用进行优化?
答案 0 :(得分:14)
编写自己的函数:
void secure_zero(void *s, size_t n)
{
volatile char *p = s;
while (n--) *p++ = 0;
}
编辑:对评论中的问题,为什么不memset
?如果没有进一步访问数组对象,编译器可以优化memset
函数调用。
请注意,C11添加了(可选)函数memset_s
,标准保证函数调用无法优化:
(C11,K.3.7.4.1p4)" [...]与memset不同,任何对memset_s函数的调用都应严格按照(5.1.2.3)中描述的抽象机规则进行评估。 )。也就是说,对memset_s函数的任何调用都应假定s和n指示的内存在将来可以访问,因此必须包含c表示的值。"
答案 1 :(得分:3)
Mac OS X是否等同于RtlSecureZeroMemory / SecureZeroMemory,这是一个将内存块归零的函数,但编译器不会对调用进行优化?
在更新版本的C运行时中,您有memset_s
。保证不会被优化掉。
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
errno_t memset_s(void * restrict s, rsize_t smax, int c, rsize_t n)
OS X还包括bzero
功能。但是bzero(3)
man pages 不声明其不会被优化程序删除。
避免使用volatile
限定符的技巧,因为它不可移植。它在Windows上按预期工作,但GCC人员将volatile
解释为由I / O硬件支持的内存。所以你不应该使用volatile
来驯服优化器。
这是您可以使用的内联汇编实现。奇怪的是,ASM语句和块上的__volatile__
都可以。它在OS X(最初编写它的位置)上工作正常。
// g++ -Og -g3 -m64 wipe.cpp -o wipe.exe
// g++ -Og -g3 -m32 wipe.cpp -o wipe.exe
// g++ -Os -g2 -S -m64 wipe.cpp -o wipe.exe.S
// g++ -Os -g2 -S -m32 wipe.cpp -o wipe.exe.S
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main(int argc, char* argv[])
{
string s("Hello world");
cout << "S: " << s << endl;
char* ptr = &s[0];
size_t size = s.length();
if(ptr && size)
{
/* Needed because we can't just say to GCC, */
/* "give me a register that you choose". */
void* dummy;
__asm__ __volatile__
(
"%=:\n\t" /* generate a unique label for TOP */
#if (__WORDSIZE == 64)
"subq $1, %2\n\t" /* 0-based index */
#elif (__WORDSIZE == 32)
"subl $1, %2\n\t" /* 0-based index */
#elif (__WORDSIZE == 16)
"subw $1, %2\n\t" /* 0-based index */
#else
# error Unknown machine word size
#endif
"lea (%1, %2), %0\n\t" /* calcualte ptr[idx] */
"movb $0, (%0)\n\t" /* 0 -> ptr[size - 1] .. ptr[0] */
"jnz %=b\n\t" /* Back to TOP if non-zero */
: "=&r" (dummy)
: "r" (ptr), "r" (size)
: "0", "1", "2", "cc"
);
}
#if 0
cout.setf(ios::hex, ios::basefield);
cout.fill('0');
for(size_t i = 0; i < s.length(); i++)
cout << "0x" << setw(2) << ((int)s[i] & 0xff) << " ";
cout << endl;
#endif
cout << "S: " << s << endl;
return 0;
}