diff options
-rw-r--r-- | lib/include/common.h | 2 | ||||
-rw-r--r-- | lib/src/common.c | 20 | ||||
-rw-r--r-- | test/checker.cc | 26 | ||||
-rw-r--r-- | test/test_helper.h | 5 |
4 files changed, 47 insertions, 6 deletions
diff --git a/lib/include/common.h b/lib/include/common.h index 1e48097..d006d71 100644 --- a/lib/include/common.h +++ b/lib/include/common.h @@ -15,3 +15,5 @@ void* memset(void* s, int c, size_t n); +void* memcpy(void* d, const void* s, size_t n); + diff --git a/lib/src/common.c b/lib/src/common.c index 2d122f5..dd806bf 100644 --- a/lib/src/common.c +++ b/lib/src/common.c @@ -16,3 +16,23 @@ void* memset(void* s, int c, size_t n) { : "memory"); return s; } + +void* memcpy(void* d, const void* s, size_t n) { + // When `d` points into `[s, s+n[` we would override `s` while copying into `d`. + // |------------|--------| + // s d s+n + // -> We don't support. + // + // When `d` points into `]s-n, s[` it is destructive for `s` but all data + // from `s` are copied into `d`. The user gets what he asks for. + // -> Supported. + ERROR_ON(s <= d && d < (void*)((unsigned char*)s + n), "memcpy: Unsupported overlap!"); + asm volatile( + "cld" + "\n" + "rep movsb" + : "+D"(d), "+S"(s), "+c"(n) + : + : "memory"); + return d; +} diff --git a/test/checker.cc b/test/checker.cc index d687b72..3d425bf 100644 --- a/test/checker.cc +++ b/test/checker.cc @@ -3,7 +3,8 @@ #include "test_helper.h" extern "C" { - #include <fmt.h> +#include <common.h> +#include <fmt.h> } void check_dec() { @@ -84,6 +85,27 @@ void check_exceed_len() { ASSERT_EQ('\0', have[7]); } +void check_memset() { + unsigned char d[7] = {0}; + void* ret = memset(d, '\x42', sizeof(d)); + + ASSERT_EQ(ret, d); + for (unsigned i = 0; i < sizeof(d); ++i) { + ASSERT_EQ(0x42, d[i]); + } +} + +void check_memcpy() { + unsigned char s[5] = {5, 4, 3, 2, 1}; + unsigned char d[5] = {0}; + void* ret = memcpy(d, s, sizeof(d)); + + ASSERT_EQ(ret, d); + for (unsigned i = 0; i < sizeof(d); ++i) { + ASSERT_EQ(5-i, d[i]); + } +} + int main() { TEST_INIT; TEST_ADD(check_dec); @@ -95,5 +117,7 @@ int main() { TEST_ADD(check_null); TEST_ADD(check_exact_len); TEST_ADD(check_exceed_len); + TEST_ADD(check_memset); + TEST_ADD(check_memcpy); return TEST_RUN; } diff --git a/test/test_helper.h b/test/test_helper.h index b78d9a6..f1356a4 100644 --- a/test/test_helper.h +++ b/test/test_helper.h @@ -28,11 +28,6 @@ void ASSERT_EQ(T1 expected, T2 have) { } } -template<typename T1, typename T2> -void ASSERT_EQ(T1* expected, T2* have) { - ASSERT_EQ(*expected, *have); -} - // Char string based ASSERT_* helper. template<> |