#include #include #include #include #define OPT 1 #define __get_user_x(size, ret, x, ptr) \ asm volatile("call __get_user_" #size \ : "=c" (ret), "=a" (x) \ : "0" (ptr)) #ifdef AMD64 #define __get_user_8(__ret_gu, __val_gu, ptr) \ __get_user_x(8, __ret_gu, __val_gu, ptr) #else #define __get_user_8(ret, x, ptr) \ asm volatile("call __get_user_8_32" \ : "=c" (ret), "=A" (x) \ : "0" (ptr)) #endif #if OPT == 1 #define get_user(x, ptr) \ ({ \ int __ret_gu; \ unsigned long __val_gu; \ unsigned long long __val_gu8; \ switch (sizeof(*(ptr))) { \ case 1: \ __get_user_x(1, __ret_gu, __val_gu, ptr); \ break; \ case 2: \ __get_user_x(2, __ret_gu, __val_gu, ptr); \ break; \ case 4: \ __get_user_x(4, __ret_gu, __val_gu, ptr); \ break; \ case 8: \ __get_user_8(__ret_gu, __val_gu8, ptr); \ break; \ default: \ __get_user_x(X, __ret_gu, __val_gu, ptr); \ break; \ } \ if (sizeof(*(ptr)) == 8) \ (x) = (typeof(*(ptr)))__val_gu8; \ else \ (x) = (typeof(*(ptr)))__val_gu; \ __ret_gu; \ }) #endif #if OPT == 2 #define get_user(x, ptr) \ ({ \ int __ret_gu; \ register typeof(x) __val_gu asm("eax"); \ switch (sizeof(*(ptr))) { \ case 1: \ __get_user_x(1, __ret_gu, __val_gu, ptr); \ break; \ case 2: \ __get_user_x(2, __ret_gu, __val_gu, ptr); \ break; \ case 4: \ __get_user_x(4, __ret_gu, __val_gu, ptr); \ break; \ case 8: \ __get_user_8(__ret_gu, __val_gu, ptr); \ break; \ default: \ __get_user_x(X, __ret_gu, __val_gu, ptr); \ break; \ } \ (x) = (typeof(*(ptr)))__val_gu; \ __ret_gu; \ }) #endif #if OPT == 3 #define get_user(x, ptr) \ ({ \ int __ret_gu; \ typeof(x) __val_gu; \ switch (sizeof(*(ptr))) { \ case 1: \ __get_user_x(1, __ret_gu, __val_gu, ptr); \ break; \ case 2: \ __get_user_x(2, __ret_gu, __val_gu, ptr); \ break; \ case 4: \ __get_user_x(4, __ret_gu, __val_gu, ptr); \ break; \ case 8: \ __get_user_8(__ret_gu, __val_gu, ptr); \ break; \ default: \ __get_user_x(X, __ret_gu, __val_gu, ptr); \ break; \ } \ (x) = (typeof(*(ptr)))__val_gu; \ __ret_gu; \ }) #endif int main(void) { uint64_t foo = 0x89abcdef76543210; printf(" foo: %"PRIx64"\n", foo); struct { uint8_t sika1; uint16_t sika2; uint32_t sika4; uint64_t sika8; } __attribute__((__packed__)) x; if (get_user(x.sika8, (const uint64_t*)&foo)) return 1; if (get_user(x.sika4, (const uint64_t*)&foo)) return 1; if (get_user(x.sika2, (const uint64_t*)&foo)) return 1; if (get_user(x.sika1, (const uint64_t*)&foo)) return 1; printf("sika8: %"PRIx64"\n", x.sika8); printf("sika4: %x\n", x.sika4); printf("sika2: %x\n", x.sika2); printf("sika1: %x\n", x.sika1); //memset(&x, 0, sizeof(x)); if (get_user(x.sika1, (const uint64_t*)&foo)) return 1; if (get_user(x.sika2, (const uint64_t*)&foo)) return 1; if (get_user(x.sika4, (const uint64_t*)&foo)) return 1; if (get_user(x.sika8, (const uint64_t*)&foo)) return 1; printf("sika8: %"PRIx64"\n", x.sika8); printf("sika4: %x\n", x.sika4); printf("sika2: %x\n", x.sika2); printf("sika1: %x\n", x.sika1); return 0; }