On Mon, Oct 9, 2023 at 4:08 AM Jean Delvare <jdelv...@suse.de> wrote: > > Hi Fangrui, > > Sorry for the late answer.
Hi Jean, sorry for the late reply. > On Sun, 24 Sep 2023 10:39:26 -0700, Fangrui Song wrote: > > Sorry, the patch did not consider big-endian systems. > > The attached patch has fixed it (__builtin_bswap{16,32}) and the `void > > *` warnings (should use `const void *`). > > The warnings are indeed gone, and I think the code should work fine on > bigendian systems (unfortunately I can't test that easily at the > moment). However I have 2 concerns left with your patch: > > 1* You detect endianness automatically, based on __BYTE_ORDER__. > However there's still one place where the explicitly-set BIGENDIAN is > used. This is inconsistent. I would prefer that you just use BIGENDIAN > for now, and in a separate patch, add auto-detection code to set > BIGENDIAN where needed. That way, the code stays consistent, and > BIGENDIAN can still be set manually if the auto-detection code fails > for whatever reason. > > Which brings a side question: how portable are __BYTE_ORDER__ and > __ORDER_BIG_ENDIAN__? We would have to check for existence before using > them if they may not be defined on all systems. __BYTE_ORDER__/__ORDER_BIG_ENDIAN__ have great portability as they are probably the most popular way to detect endianness. They are supported by at least GCC, Clang, and tinycc. Linux and popular *BSD (FreeBSD, NetBSD, OpenBSD, etc) use either GCC or Clang. > 2* How portable are __builtin_bswap16 and __builtin_bswap32? Please > keep in mind that dmidecode is meant to be portable across operating > systems, therefore it should not depend on glibc- or gcc-specific > functions. All I can find in the Linux manual pages is bswap in section > 3, which documents functions bswap_16() and bswap_32(), so different > from what you used, and describes them as "GNU extensions" so most > probably not portable. GCC and Clang support __builtin_bswap16/__builtin_bswap32. Since big-endian systems are less common today, so u32 ret; memcpy(&ret, x, sizeof(ret)); #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ ret = __builtin_bswap32(ret); #endif should mostly be fine. Do you know what C compilers dmidecode intends to support? If a C compiler doesn't support __builtin_bswap{16,32}, indeed it could be problematic on a big-endian system, but I am curious whether such a supported surface is hypothetical. > As a side note, I wonder if we could now get rid of the U64 quirks I > implemented long ago and use uint64_t instead. If it is portable, that > would be much better than my custom code. I agree. `rg '\.[lh] ' *.c` lists quite a few occurrences. Such a change should be separate. > Thanks, > -- > Jean Delvare > SUSE L3 Support -- 宋方睿