diff options
author | Johannes Stoelp <johannes.stoelp@gmail.com> | 2022-04-04 13:48:56 +0200 |
---|---|---|
committer | Johannes Stoelp <johannes.stoelp@gmail.com> | 2022-04-04 13:48:56 +0200 |
commit | ebf8d357bd09e6eef9bbe74250fea06641090998 (patch) | |
tree | ebe3a07d2ddbc57ae0a2f93d49794f624d390ec6 /lib/src/common.c | |
parent | a2db99c6cae17d2a692b794aaebb464512ce012e (diff) | |
download | dynld-ebf8d357bd09e6eef9bbe74250fea06641090998.tar.gz dynld-ebf8d357bd09e6eef9bbe74250fea06641090998.zip |
memcpy: describe different cases in more depth
Diffstat (limited to 'lib/src/common.c')
-rw-r--r-- | lib/src/common.c | 54 |
1 files changed, 46 insertions, 8 deletions
diff --git a/lib/src/common.c b/lib/src/common.c index dd806bf..aa8d2ba 100644 --- a/lib/src/common.c +++ b/lib/src/common.c @@ -18,15 +18,53 @@ void* memset(void* s, int c, size_t n) { } 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. + // Cases to distinguish resulting from s and d pointers. + // + // Case 1 - same + // |------------| + // s s+n + // d d+n + // + // -> Nothing to copy. + // + // Case 2 - disjunct + // |------------| |------------| + // s s+n d d+n + // + // -> Nothing to worry, just copy the bytes from s to d. + // + // Case 3 - head overlap + // |------------| + // s s+n + // |------------| + // d d+n + // + // -> Destructive copy for s but all bytes get properly copied from s to d. + // The user gets what he/she asked for. + // + // Case 4 - tail overlap + // |------------| + // s s+n + // |------------| + // d d+n + // + // -> With a simple forward copy we would override the tail of s while + // copying into the head of d. This is destructive for s but we would + // also copy "wrong" bytes into d when we copy the tail of s (as it is + // already overwritten). + // This copy could be done properly by copying backwards (on x86 we + // could use the direction flag for string operations). + // -> We don't support this here as it is not needed any of the examples. + + // Case 4. ERROR_ON(s <= d && d < (void*)((unsigned char*)s + n), "memcpy: Unsupported overlap!"); + + // Case 1. + if (d == s) { + return d; + } + + // Case 2/3. asm volatile( "cld" "\n" |