trolldbois / ctypeslib

Generate python ctypes classes from C headers. Requires LLVM clang
http://trolldbois.blogspot.com/search?q=ctypeslib
MIT License
216 stars 58 forks source link

Report clang bindings bug with incompletearray #28

Open trolldbois opened 7 years ago

trolldbois commented 7 years ago

If a record has an incompletearray, all fields have offset == -2. No padding will be done. But the fields are ordered and code will be produces with typed info in the right offset. so in most cases, it will work.

if there is a structure with incompletearray and padding or alignement issue, it will produce wrong results

Bug/corner case is probably in llvm python clang bindings/library libclang

XVilka commented 6 years ago

Met this bug with headers containing the include to <sys/socket.h>, with cmsghdr structure from <bits/socket.h>

/* Structure used for storage of ancillary data object information.  */
struct cmsghdr
  {
    size_t cmsg_len;        /* Length of data in cmsg_data plus length
                   of cmsghdr structure.
                   !! The type should be socklen_t but the
                   definition of the kernel is incompatible
                   with this.  */
    int cmsg_level;     /* Originating protocol.  */
    int cmsg_type;      /* Protocol specific type.  */
#if __glibc_c99_flexarr_available
    __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data.  */
#endif
  };

/* Ancillary data object manipulation macros.  */
#if __glibc_c99_flexarr_available
# define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data)
#else
# define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1))
#endif
#define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg)
#define CMSG_FIRSTHDR(mhdr) \
  ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr)             \
   ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0)
#define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \
             & (size_t) ~(sizeof (size_t) - 1))
#define CMSG_SPACE(len) (CMSG_ALIGN (len) \
             + CMSG_ALIGN (sizeof (struct cmsghdr)))
#define CMSG_LEN(len)   (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len))

extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr,
                      struct cmsghdr *__cmsg) __THROW;

Error message is

2018-02-05 20:40:52,769 FIELD_DECL: BAD RECORD, Bad offset: -2 for cmsg_len
2018-02-05 20:40:52,769 FIELD_DECL: BAD RECORD, Bad offset: -2 for cmsg_level
2018-02-05 20:40:52,769 FIELD_DECL: BAD RECORD, Bad offset: -2 for cmsg_type
2018-02-05 20:40:52,769 FIELD_DECL: BAD RECORD, Bad offset: -2 for __cmsg_data
2018-02-05 20:40:52,769 Bad source code, bitsize == -16 <0 on __cmsg_data
2018-02-05 20:40:52,784 ELABORATED is not handled
2018-02-05 20:40:52,785 _do_nothing for ELABORATED/struct in_addr
2018-02-05 20:40:52,828 PAREN_EXPR is not handled
2018-02-05 20:40:52,828 _do_nothing for PAREN_EXPR/
2018-02-05 20:40:52,828 _do_nothing for PAREN_EXPR/
XVilka commented 6 years ago

Is there any hope to fix this?

trolldbois commented 6 years ago

Hi @XVilka I think the issue is really with the llvm clang library and python-clang bindings. The clang library does not provide enough information to the python bindings for this ctypeslib library to be able to accommodate this corner case. So, the solution would be to produce your test case for clang, and see what clang produces as a result and if the clang primitives return enough information. and propose that as a bug to llvm clang ? I'm sorry to say, I don't have the cycle to do that myself, right now.

XVilka commented 6 years ago

Sure, I will try to do that.