|
|
Subscribe / Log in / New account

Strict memcpy() bounds checking for the kernel

Strict memcpy() bounds checking for the kernel

Posted Jul 30, 2021 20:28 UTC (Fri) by jengelh (guest, #33263)
Parent article: Strict memcpy() bounds checking for the kernel

#include <string.h>
struct S { int one, two, three, four; };
void lefttoright(struct S *d, struct S *s) {
d->one = s->one; d->two = s->two; d->three = s->three; d->four = s->four; }

Explicit field copies. More to type, but no running afoul of new members added to S. gcc-11.1.1 -O3 is capable to produce the same x86_64 asm as a field-insensitive memcpy(d,s,sizeof(*s)) would on -O2.


to post comments

Strict memcpy() bounds checking for the kernel

Posted Jul 30, 2021 21:54 UTC (Fri) by pbonzini (subscriber, #60935) [Link] (5 responses)

Does that still work when some fields are u8 or bool and some are even bitfields? Is the compiler able to produce the same code as with memcpy?

Strict memcpy() bounds checking for the kernel

Posted Jul 31, 2021 12:38 UTC (Sat) by Hello71 (subscriber, #103412) [Link]

no: https://gcc.godbolt.org/z/aP8GWb487

i don't understand what "running afoul of new members added to S" means anyways. it seems to me that in the vast majority of cases, when new members are added, one would want them to be copied too. otherwise, write memcpy(dest, src, sizeof(*dest) - offsetof(struct S, last_member) + sizeof(dest->last_member))?

Strict memcpy() bounds checking for the kernel

Posted Jul 31, 2021 13:22 UTC (Sat) by CAFxX (guest, #153510) [Link] (1 responses)

Seems like it can do even better than memcpy, in that it can handle cases where memcpy would waste work: https://godbolt.org/z/aa31McEjx

Strict memcpy() bounds checking for the kernel

Posted Aug 1, 2021 13:23 UTC (Sun) by HenrikH (subscriber, #31152) [Link]

replacing that with a pure memset (yes I know that your example didn't clear all the members, but still) resulted in even less code.

Strict memcpy() bounds checking for the kernel

Posted Jul 31, 2021 13:27 UTC (Sat) by jengelh (guest, #33263) [Link] (1 responses)

Yes, it will also optimize for uint8_t. You just need enough bytes overall (looks like >= 8) to make it worthwhile for gcc to switch to SIMD-based copying.
For bitfields there is a bit of a problem, for which I filed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101705 .

Strict memcpy() bounds checking for the kernel

Posted Aug 3, 2021 2:22 UTC (Tue) by willy (subscriber, #9762) [Link]

Of course, the kernel disables SIMD so that it doesn't use the XMM/YMM registers, and thus they don't have to be saved/restored at system call time.

Strict memcpy() bounds checking for the kernel

Posted Aug 1, 2021 8:41 UTC (Sun) by epa (subscriber, #39769) [Link]

It seems like ‘copy the following members of a struct’ or ‘copy all except these’ or ‘copy from this point to this point’ would be useful extensions to the C language.


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds