Friday, 3 June 2022

Packing issue in libusb

This note is about an issue encountered creating a very thin Ada binding to libusb (1.0.26).

The way to create a thin Ada binding to a C library is to give GCC the switch -fdump-ada-spec (or -fdump-ada-spec-slim). It’s best, I find, to use g++ to do this - it preserves parameter names better.

g++ -c -fdump-ada-spec /usr/local/include/libusb-1.0/libusb.h

This reports the warning

/usr/local/include/libusb-1.0/libusb.h:916:8: warning: packed layout
  916 | struct libusb_control_setup {
      |        ^~~~~~~~~~~~~~~~~~~~

and generates a huge number (71) of Ada spec files, but fortunately for me the only one I’m interested in using is (which uses other generated files).

Unfortunately, when I compile against this file, I get warning: packed layout may be incorrect [enabled by default]

Line 298 says

   pragma Compile_Time_Warning (True, "packed layout may be incorrect");
   type libusb_control_setup is record
   end record
   with Convention => C_Pass_By_Copy,
        Pack => True,
        Alignment => 1;  -- /usr/local/include/libusb-1.0/libusb.h:916

In libusb.h, line 916 says

struct libusb_control_setup {

where LIBUSB_PACKED (line 81) says

#if defined(__GNUC__)
#define LIBUSB_PACKED __attribute__ ((packed))
#endif /* __GNUC__ */

which was committed on 16 April 2022 with the commit message

There is nothing explicitly preventing the compiler from adding any sort of padding to the libusb_control_transfer structure. It does not seem that any sane compiler would do so, but there is library functionality that depends on this not happening. Address this by explicitly instructing the compiler to pack the structure.

Now, this may be alright for C (I suspect not, really), but the Ada compiler has every right to complain! What to do? The structure consists of two uint8_t members followed by four uint16_t members, so there shouldn’t really be an alignment issue.

Perhaps I can just edit the generated code to remove the offending parts.

No comments:

Post a Comment