[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] packed structures and unaligned accesses (sparc)

From: Peter Maydell
Subject: [Qemu-devel] packed structures and unaligned accesses (sparc)
Date: Mon, 27 Mar 2017 18:34:20 +0100

At the moment the 9p QEMU tests fail on SPARC. This turns out to
be because the test case itself gets a SIGBUS. Looking at the
code I guess it makes sense, but I don't understand why the
code didn't at least generate a warning. Here's a cutdown testcase:

address@hidden:~$ cat packed.c
#include <stdio.h>
#include <inttypes.h>

typedef struct {
  uint32_t size;
  uint8_t id;
  uint16_t tag;
} __attribute__((packed)) hdr;

uint32_t getval(uint32_t *p) {
  return *p;

uint32_t foo(void) {
  hdr h;
  h.size = 42;

  return getval(&h.size);

int main(void) {
  printf("got 0x%x\n", foo());
  return 0;
address@hidden:~$ gcc -Wall -o packed packed.c
address@hidden:~$ ./packed
Bus error

(This is with gcc (Debian 6.3.0-10) 6.3.0 20170321.)

The bus error happens because:
 * the compiler decides to put the local 'hdr h' in foo() at
an unaligned address (which is allowed although I'm not
quite sure why it chooses to do so here given it's the only
local in the function)
 * getval() is compiled to code that assumes the pointer is
 * the address of h.size isn't aligned, so the call to getval()
blows up

That all makes sense in isolation, but shouldn't something have
at least warned that "&h.size" isn't actually a uint32_t* in
the sense of being something you can validly pass to a
function that takes a uint32_t* ?

-- PMM

reply via email to

[Prev in Thread] Current Thread [Next in Thread]