Ouch. You already clean it up. Here is my diff from your patch. Can you please merged into the patch? changes are - eliminate unaligned access - error report - replace magic number with symbolic constants - unconverted strtol(base=10)
Signed-off-by: Isaku Yamahata <yamah...@valinux.co.jp> --- qemu-acpi-load-other-0/hw/acpi.c 2011-03-17 14:02:07.000000000 +0900 +++ qemu-acpi-load-0/hw/acpi.c 2011-03-17 14:14:39.000000000 +0900 @@ -19,8 +19,42 @@ #include "pc.h" #include "acpi.h" +struct acpi_table_header +{ + char signature [4]; /* ACPI signature (4 ASCII characters) */ + uint32_t length; /* Length of table, in bytes, including header */ + uint8_t revision; /* ACPI Specification minor version # */ + uint8_t checksum; /* To make sum of entire table == 0 */ + char oem_id [6]; /* OEM identification */ + char oem_table_id [8]; /* OEM table identification */ + uint32_t oem_revision; /* OEM revision number */ + char asl_compiler_id [4]; /* ASL compiler vendor ID */ + uint32_t asl_compiler_revision; /* ASL compiler revision number */ +} __attribute__((packed)); + +#define ACPI_TABLE_OFF(x) (offsetof(struct acpi_table_header, x)) +#define ACPI_TABLE_SIZE(x) (sizeof(((struct acpi_table_header*)0)->x)) + +#define ACPI_TABLE_SIG_OFF ACPI_TABLE_OFF(signature) +#define ACPI_TABLE_SIG_SIZE ACPI_TABLE_SIZE(signature) +#define ACPI_TABLE_LEN_OFF ACPI_TABLE_OFF(length) +#define ACPI_TABLE_LEN_SIZE ACPI_TABLE_SIZE(length) +#define ACPI_TABLE_REV_OFF ACPI_TABLE_OFF(revision) +#define ACPI_TABLE_REV_SIZE ACPI_TABLE_SIZE(revision) +#define ACPI_TABLE_CSUM_OFF ACPI_TABLE_OFF(checksum) +#define ACPI_TABLE_CSUM_SIZE ACPI_TABLE_SIZE(checksum) +#define ACPI_TABLE_OEM_ID_OFF ACPI_TABLE_OFF(oem_id) +#define ACPI_TABLE_OEM_ID_SIZE ACPI_TABLE_SIZE(oem_id) +#define ACPI_TABLE_OEM_TABLE_ID_OFF ACPI_TABLE_OFF(oem_table_id) +#define ACPI_TABLE_OEM_TABLE_ID_SIZE ACPI_TABLE_SIZE(oem_table_id) +#define ACPI_TABLE_OEM_REV_OFF ACPI_TABLE_OFF(oem_revision) +#define ACPI_TABLE_OEM_REV_SIZE ACPI_TABLE_SIZE(oem_revision) +#define ACPI_TABLE_ASL_COMPILER_ID_OFF ACPI_TABLE_OFF(asl_compiler_id) +#define ACPI_TABLE_ASL_COMPILER_ID_SIZE ACPI_TABLE_SIZE(asl_compiler_id) +#define ACPI_TABLE_ASL_COMPILER_REV_OFF ACPI_TABLE_OFF(asl_compiler_revision) +#define ACPI_TABLE_ASL_COMPILER_REV_SIZE ACPI_TABLE_SIZE(asl_compiler_revision) -#define ACPI_TABLE_HDR_SIZE (4+4+1+1+6+8+4+4+4) +#define ACPI_TABLE_HDR_SIZE sizeof(struct acpi_table_header) char *acpi_tables; size_t acpi_tables_len; @@ -34,6 +68,7 @@ static int acpi_checksum(const uint8_t * return (-sum) & 0xff; } +/* XXX fixme: this function uses obsolete argument parsing interface */ int acpi_table_add(const char *t) { static const char dfl_hdr[ACPI_TABLE_HDR_SIZE] = @@ -43,17 +78,16 @@ int acpi_table_add(const char *t) ; char buf[1024], *p, *f; unsigned long val; + uint16_t val16; + uint32_t val32; size_t len, start; bool has_header; int changed; - /*XXX fixme: this function uses obsolete argument parsing interface */ - /*XXX note: all 32bit accesses in there are misaligned */ - if (get_param_value(buf, sizeof(buf), "data", t)) { - has_header = 0; + has_header = false; } else if (get_param_value(buf, sizeof(buf), "file", t)) { - has_header = 1; + has_header = true; } else { has_header = 0; buf[0] = '\0'; @@ -80,7 +114,7 @@ int acpi_table_add(const char *t) int fd = open(f, O_RDONLY); if (fd < 0) { - /*XXX fixme: report error */ + fprintf(stderr, "can't open file %s: %s\n", f, strerror(errno)); goto out; } @@ -94,7 +128,8 @@ int acpi_table_add(const char *t) memcpy(acpi_tables + acpi_tables_len, data, r); acpi_tables_len += r; } else if (errno != EINTR) { - /*XXX fixme: report error */ + fprintf(stderr, "can't read file %s: %s\n", + f, strerror(errno)); close(fd); goto out; } @@ -106,7 +141,8 @@ int acpi_table_add(const char *t) /* fill in the complete length of the table */ len = acpi_tables_len - start - sizeof(uint16_t); f = acpi_tables + start; - *(uint16_t *)f = cpu_to_le32(len); + val16 = cpu_to_le16(len); + memcpy(f, &val16, sizeof(uint16_t)); f += sizeof(uint16_t); /* now fill in the header fields */ @@ -114,7 +150,7 @@ int acpi_table_add(const char *t) /* 0..3, signature, string (4 bytes) */ if (get_param_value(buf, sizeof(buf), "sig", t)) { - strncpy(f + 0, buf, 4); + strncpy(f + ACPI_TABLE_SIG_OFF, buf, ACPI_TABLE_SIG_SIZE); ++changed; } @@ -124,23 +160,26 @@ int acpi_table_add(const char *t) if (get_param_value(buf, sizeof(buf), "rev", t)) { val = strtoul(buf, &p, 0); if (val > 255 || *p) { - goto out; /*XXX fixme: report error */ + fprintf(stderr, "invalid acpi rev.\n"); + goto out; } - f[8] = (uint8_t)val; + f[ACPI_TABLE_REV_OFF] = (uint8_t)val; ++changed; } - /* 9, checksum of entire table (1 byte) */ + /* 9, checksum of entire table (1 byte) + this will be processed after all the headers are modified */ /* 10..15 OEM identification (6 bytes) */ if (get_param_value(buf, sizeof(buf), "oem_id", t)) { - strncpy(f + 10, buf, 6); + strncpy(f + ACPI_TABLE_OEM_ID_OFF, buf, ACPI_TABLE_OEM_ID_SIZE); ++changed; } /* 16..23 OEM table identifiaction, 8 bytes */ if (get_param_value(buf, sizeof(buf), "oem_table_id", t)) { - strncpy(f + 16, buf, 8); + strncpy(f + ACPI_TABLE_OEM_TABLE_ID_OFF, buf, + ACPI_TABLE_OEM_TABLE_ID_SIZE); ++changed; } @@ -148,25 +187,31 @@ int acpi_table_add(const char *t) if (get_param_value(buf, sizeof(buf), "oem_rev", t)) { val = strtol(buf, &p, 0); if (*p) { - goto out; /*XXX fixme: report error */ + fprintf(stderr, "invalid acpi oem_rev.\n"); + goto out; } - *(uint32_t *)(f + 24) = cpu_to_le32(val); + val32 = cpu_to_le32(val); + memcpy(f + ACPI_TABLE_OEM_REV_OFF, &val32, ACPI_TABLE_OEM_REV_SIZE); ++changed; } /* 28..31 ASL compiler vendor ID (4 bytes) */ if (get_param_value(buf, sizeof(buf), "asl_compiler_id", t)) { - strncpy(f + 28, buf, 4); + strncpy(f + ACPI_TABLE_ASL_COMPILER_ID_OFF, buf, + ACPI_TABLE_ASL_COMPILER_ID_SIZE); ++changed; } /* 32..35 ASL compiler revision number (4 bytes) */ if (get_param_value(buf, sizeof(buf), "asl_compiler_rev", t)) { - val = strtol(buf, &p, 10); + val = strtol(buf, &p, 0); if (*p) { - goto out; /*XXX fixme: report error */ + fprintf(stderr, "invalid acpi asl_compiler_rev.\n"); + goto out; } - *(uint32_t *)(f + 32) = cpu_to_le32(val); + val32 = cpu_to_le32(val); + memcpy(f + ACPI_TABLE_ASL_COMPILER_REV_OFF, &val32, + ACPI_TABLE_ASL_COMPILER_REV_SIZE); ++changed; } @@ -179,11 +224,12 @@ int acpi_table_add(const char *t) } } else { /* check if actual length is correct */ - val = le32_to_cpu(*(uint32_t *)(f + 4)); + memcpy(&val32, f + ACPI_TABLE_LEN_OFF, ACPI_TABLE_LEN_SIZE); + val = le32_to_cpu(val32); if (val != len) { fprintf(stderr, "warning: acpi table specified with file= has wrong length," - " header says %lu, actual size %u\n", + " header says %lu, actual size %zu\n", val, len); ++changed; } @@ -191,19 +237,20 @@ int acpi_table_add(const char *t) /* fix table length */ /* we may avoid putting length here if has_header is true */ - *(uint32_t *)(f + 4) = cpu_to_le32(len); + val32 = cpu_to_le32(len); + memcpy(f + ACPI_TABLE_LEN_OFF, &val32, ACPI_TABLE_LEN_SIZE); /* 9 checksum (1 byte) */ /* we may as well leave checksum intact if has_header is true */ /* alternatively there may be a way to set cksum to a given value */ if (changed || !has_header || 1) { - f[9] = 0; - f[9] = acpi_checksum((uint8_t *)f, len); + f[ACPI_TABLE_CSUM_OFF] = 0; + f[ACPI_TABLE_CSUM_OFF] = acpi_checksum((uint8_t*)f, len); } /* increase number of tables */ - (*(uint16_t *)acpi_tables) = - cpu_to_le32(le32_to_cpu(*(uint16_t *)acpi_tables) + 1); + (*(uint16_t*)acpi_tables) = + cpu_to_le16(le16_to_cpu(*(uint16_t*)acpi_tables) + 1); return 0; out: -- yamahata