不可信函数可能设置关于调用预定和DLL链接的属性,你可以在这里看看调用约定的详细信息http://msdn.microsoft.com/en-us/library/984x0h58。
cdecl调用约定是C标准的默认方式。
错误的使用cdecl,stdcall,fastcall关键可能导致链接错误。
OCALL函数(不可信)可能在DLL中实现,dllimport关键字就用来指定这种属性。错误的使用dllimport关键字可能导致编译警告。
调用约定使用下面的关键字:
上面的调用约定只用于32位,64位中只有fastcall调用约定(rcx, edx, r8, r9)
示例:
可信函数test_calling_convs()可以使用向文件操作的标准函数,其他的使用不可信函数(OCALL)
enclave {
include "sgx_stdio_stubs.h" //for FILE and other definitions
trusted {
public void test_calling_convs(void);
};
untrusted {
[cdecl, dllimport] FILE * fopen(
[in,string] const char * filename,
[in,string] const char * mode);
[cdecl, dllimport] int fclose([user_check] FILE * stream);
[cdecl, dllimport] size_t fwrite(
[in, size=size, count=count] const void * buffer,
size_t size,
size_t count,
[user_check]FILE * stream);
[fastcall] void test_fast_call([in]void* ptr);
[stdcall] void test_std_call(void);
};
};
//Unsupported Syntax:
enclave {
untrusted {
// Compiler warning without [cdecl,dllimport]
size_t fwrite([in, size=size, count=count] const void* ptr,
size_t size,
size_t count,
[user_check] FILE * stream);
// Compiler error without [stdcall]
// Redefinition due to different type modifiers
void test_std_call(void);
};
};
- Propagating errno in OCALLs
在OCALL中传递错误号。
OCALL可以使用propagate_errno属性。如果使用了这个属性,sgx_edger8r会生成稍微有点不同的边界函数。飞地内可信C标准库提供的errno变量会在OCALL返回前被不可信域的errno覆盖。可信的errno会被OCALL更新,不管OCALL是否成功。这不会改变errno的基本行为。一个函数失败了必须指定errno来表示出了什么错。函数成功了,在OCALL这种情况中,是允许修改errno的值的。
示例:
enclave {
include "sgx_stdio_stubs.h" //for FILE and other definitions
trusted {
public void test_file_io(void);
};
untrusted {
[cdecl, dllimport] FILE * fopen(
[in,string] const char * filename,
[in,string] const char * mode) propagate_errno;
[cdecl, dllimport] int fclose([user_check] FILE * stream)
propagate_errno;
[cdecl, dllimport] size_t fwrite(
[in, size=size, count=count] const void * buffer,
size_t size,
size_t count,
[user_check]FILE * stream) propagate_errno;
};
};