On 03/10/2014 12:43 PM, Michael S. Tsirkin wrote: > casting an unaligned address to e.g. > uint32_t can trigger undefined behaviour in C. > Replace cast + assignment with memcpy. > > Reported-by: Peter Maydell <peter.mayd...@linaro.org> > Signed-off-by: Michael S. Tsirkin <m...@redhat.com> > --- > hw/i386/acpi-build.c | 31 ++++++++++++++++--------------- > 1 file changed, 16 insertions(+), 15 deletions(-) > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c > index b667d31..e08f514 100644 > --- a/hw/i386/acpi-build.c > +++ b/hw/i386/acpi-build.c > @@ -466,9 +466,15 @@ static void acpi_align_size(GArray *blob, unsigned align) > g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align)); > } > > -/* Get pointer within table in a safe manner */ > -#define ACPI_BUILD_PTR(table, size, off, type) \ > - ((type *)(acpi_data_get_ptr(table, size, off, sizeof(type)))) > +/* Set a value within table in a safe manner */ > +#define ACPI_BUILD_SET_LE(table, size, off, bits, val) \ > + do { \ > + uint64_t ACPI_BUILD_SET_LE_val = le_bswap(val, bits); \ > + memcpy(acpi_data_get_ptr(table, size, off, \ > + (bits) / BITS_PER_BYTE), \ > + &ACPI_BUILD_SET_LE_val, \ > + (bits) / BITS_PER_BYTE); \ > + } while (0) > > static inline void *acpi_data_get_ptr(uint8_t *table_data, unsigned > table_size, > unsigned off, unsigned size) > @@ -974,22 +980,17 @@ static void build_pci_bus_end(PCIBus *bus, void > *bus_state) > > static void patch_pci_windows(PcPciInfo *pci, uint8_t *start, unsigned size) > { > - *ACPI_BUILD_PTR(start, size, acpi_pci32_start[0], uint32_t) = > - cpu_to_le32(pci->w32.begin); > + ACPI_BUILD_SET_LE(start, size, acpi_pci32_start[0], 32, pci->w32.begin);
You're working too hard at this because you're using the wrong bswap interface. Also, you missed one. I'll follow up with a patch I wrote just recently, but hadn't yet gotten around to posting. r~