Hi,

On 07/01/2013 07:07 PM, Paul Fertser wrote:
> On Mon, Jul 01, 2013 at 12:02:45PM +0200, Hans de Goede wrote:
>> Unaligned accesses on architectures which don't support it, either get
>> trapped and emulated (with a fat warnign logged somewhere), or get trapped
>> and terminate the program. So I don't think this may cause "subtle" bugs.
>
> I agree that it's unlikely to be an issue in real life for libusb, but
> I was tricked by exactly the same problem with uIP on an older ARM
> microcontroller (ARM7/ARMv4T), it wasn't easy to debug at all.
>
> Triggering subtle bugs here would require running uCLinux
> (i.e. MMU-less) with libusb. This [1] document has an elaborate
> description about the matters (in particular, LDR doing a "rotated load").
>
> [1] http://www.heyrick.co.uk/armwiki/Unaligned_data_access
>
>> Notice that actually getting the alignment wrong is pretty hard, most ABI's
>> guarantee some stack pointer alignment when entering a function, so having
>> an unaligned  buffer would require declaring vars like ie this:
>>
>> unsigned char unalign[3];
>> unsigned char buffer[16];
>
> Yep, certainly. And malloc() guarantees maximum alignment.
>
>> Since you're actually getting the warnings can you provide a patch to silence
>> them ?
>
> Follows (against the current libusbx HEAD, but should be applicable to
> libusb as well), TIA

Thanks! I'll apply this to master once 1.0.16 is out the door. Note I plan to
drop the __attribute__ ((aligned (2))), as we support compilers other then gcc.

Regards,

Hans


>
> From: Paul Fertser <fercer...@gmail.com>
> Date: Mon, 1 Jul 2013 20:47:18 +0400
> Subject: [PATCH] Clarify alignment requirements for the control transfer
>   buffer
>
> Since the buffer pointer will later be casted to ``struct
> libusb_control_setup *'', it should point to memory aligned to at least
> 2 bytes boundary as that's the strictest requirement of the struct fields.
>
> Also, use a (void *) casting trick to convince the compiler the cast is
> safe, to fix warnings such as:
>
> /usr/local/include/libusb-1.0/libusb.h: In function 
> 'libusb_control_transfer_get_setup':
> /usr/local/include/libusb-1.0/libusb.h:1435:9: error: cast increases required 
> alignment of target type [-Werror=cast-align]
> /usr/local/include/libusb-1.0/libusb.h: In function 
> 'libusb_fill_control_setup':
> /usr/local/include/libusb-1.0/libusb.h:1464:39: error: cast increases 
> required alignment of target type [-Werror=cast-align]
> /usr/local/include/libusb-1.0/libusb.h: In function 
> 'libusb_fill_control_transfer':
> /usr/local/include/libusb-1.0/libusb.h:1509:39: error: cast increases 
> required alignment of target type [-Werror=cast-align]
> cc1: all warnings being treated as errors
>
> This actually can lead to failure to build from the sources for certain
> projects which use -Werror=cast-align on ARM.
>
> Signed-off-by: Paul Fertser <fercer...@gmail.com>
> ---
>   libusb/io.c     |    2 +-
>   libusb/libusb.h |    8 +++++---
>   2 files changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/libusb/io.c b/libusb/io.c
> index b27e082..add2328 100644
> --- a/libusb/io.c
> +++ b/libusb/io.c
> @@ -731,7 +731,7 @@ void cb(struct libusb_transfer *transfer)
>
>   void myfunc() {
>       struct libusb_transfer *transfer;
> -     unsigned char buffer[LIBUSB_CONTROL_SETUP_SIZE];
> +     unsigned char buffer[LIBUSB_CONTROL_SETUP_SIZE] __attribute__ ((aligned 
> (2)));
>       int completed = 0;
>
>       transfer = libusb_alloc_transfer(0);
> diff --git a/libusb/libusb.h b/libusb/libusb.h
> index 5e1c23c..2c98f52 100644
> --- a/libusb/libusb.h
> +++ b/libusb/libusb.h
> @@ -1428,7 +1428,7 @@ static inline unsigned char 
> *libusb_control_transfer_get_data(
>   static inline struct libusb_control_setup 
> *libusb_control_transfer_get_setup(
>       struct libusb_transfer *transfer)
>   {
> -     return (struct libusb_control_setup *) transfer->buffer;
> +     return (struct libusb_control_setup *)(void *) transfer->buffer;
>   }
>
>   /** \ingroup asyncio
> @@ -1437,6 +1437,7 @@ static inline struct libusb_control_setup 
> *libusb_control_transfer_get_setup(
>    * be given in host-endian byte order.
>    *
>    * \param buffer buffer to output the setup packet into
> + * This pointer must be aligned to at least 2 bytes boundary.
>    * \param bmRequestType see the
>    * \ref libusb_control_setup::bmRequestType "bmRequestType" field of
>    * \ref libusb_control_setup
> @@ -1457,7 +1458,7 @@ static inline void libusb_fill_control_setup(unsigned 
> char *buffer,
>       uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t 
> wIndex,
>       uint16_t wLength)
>   {
> -     struct libusb_control_setup *setup = (struct libusb_control_setup *) 
> buffer;
> +     struct libusb_control_setup *setup = (struct libusb_control_setup 
> *)(void *) buffer;
>       setup->bmRequestType = bmRequestType;
>       setup->bRequest = bRequest;
>       setup->wValue = libusb_cpu_to_le16(wValue);
> @@ -1493,6 +1494,7 @@ void LIBUSB_CALL libusb_free_transfer(struct 
> libusb_transfer *transfer);
>    * \param dev_handle handle of the device that will handle the transfer
>    * \param buffer data buffer. If provided, this function will interpret the
>    * first 8 bytes as a setup packet and infer the transfer length from that.
> + * This pointer must be aligned to at least 2 bytes boundary.
>    * \param callback callback function to be invoked on transfer completion
>    * \param user_data user data to pass to callback function
>    * \param timeout timeout for the transfer in milliseconds
> @@ -1502,7 +1504,7 @@ static inline void libusb_fill_control_transfer(
>       unsigned char *buffer, libusb_transfer_cb_fn callback, void *user_data,
>       unsigned int timeout)
>   {
> -     struct libusb_control_setup *setup = (struct libusb_control_setup *) 
> buffer;
> +     struct libusb_control_setup *setup = (struct libusb_control_setup 
> *)(void *) buffer;
>       transfer->dev_handle = dev_handle;
>       transfer->endpoint = 0;
>       transfer->type = LIBUSB_TRANSFER_TYPE_CONTROL;
>

------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
libusbx-devel mailing list
libusbx-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/libusbx-devel

Reply via email to