[cfe-dev] Tracking variable endieness at compile time (C language)

Anatol Pomozov via cfe-dev cfe-dev at lists.llvm.org
Sat Nov 11 21:22:42 PST 2017


I am writing a code that deals with low-level PCI machinery. I need to
read data from PCI config  MMIO. The data from device can be 8/16/32
bits long and per specification it is little-endien. I have a set of
macroses that convert from little-endien to CPU endieness. I have to
use these macroses every time I access PCI config data. CPU endieness
depends on CPU architecture and can be either little- or big-endien.

I am looking for a way that helps me to detect errors when I access
little-endien fields without proper conversion macros. I am thinking
about following solution - have a marker macros called __le __be that
tells compiler this field has specific endieness:

struct virtio_net_hdr {
    __le uint8_t flags;
    __le uint8_t gso_type;
    __le uint16_t hdr_len;
    __le uint16_t gso_size;
    __le uint16_t csum_start;
    __le uint16_t csum_offset;

If we try to access the field as
hdr->hdr_len = 20;

then compiler should either:

1) report an error and tell me that there is endieness mismatch
between hdr->hdr_len and const '20'. The right way would be to use
cpu_to_le() macro like:
hdr->hdr_len = cpu_to_le(20);

2) Or maybe compiler can completely automate conversion and call
__builtin_bswap16()/__builtin_bswap32/.. functions for us

Is there any existing solution that does something similar. Quick
googling did not give me anything useful. Could it be a part of core
compiler functionality? Or as a third-party compiler plugin?

More information about the cfe-dev mailing list