diff --git a/hw/acpi/acpi-build-utils.c b/hw/acpi/acpi-build-utils.c
index 1041865..02f60d7 100644
--- a/hw/acpi/acpi-build-utils.c
+++ b/hw/acpi/acpi-build-utils.c
@@ -293,6 +293,8 @@ static void build_prepend_int(GArray *array, uint32_t value)
 
 void aml_append(AcpiAml *parent_ctx, AcpiAml *child)
 {
+    char *child_name;
+
     switch (child->block_flags) {
     case EXT_PACKAGE:
         build_extop_package(child->buf, child->op);
@@ -333,22 +335,22 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml *child)
         break;
     }
     build_append_array(parent_ctx->buf, child->buf);
-    build_free_array(child->buf);
+
+    child_name = g_strdup_printf("%s[%p]'", object_get_typename(OBJECT(child)), child);
+    object_property_add_child(OBJECT(parent_ctx), child_name, OBJECT(child), &error_abort);
+    g_free(child_name);
 }
 
-static AcpiAml *aml_allocate_internal(uint8_t op, AcpiBlockFlags flags)
+static void aml_set_pack_options(AcpiAml *var, uint8_t op, AcpiBlockFlags flags)
 {
-    AcpiAml *var = g_malloc0(sizeof(AcpiAml));
     var->op = op;
     var->block_flags = flags;
-    var->buf = build_alloc_array();
-    return var;
 }
 
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefReturn */
 AcpiAml *acpi_return(AcpiAml *val)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0xA4); /* ReturnOp */
     aml_append(var, val);
     return var;
@@ -360,7 +362,7 @@ AcpiAml *acpi_return(AcpiAml *val)
  */
 AcpiAml *acpi_int(const uint64_t val)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_int(var->buf, val);
     return var;
 }
@@ -372,7 +374,7 @@ AcpiAml *acpi_int(const uint64_t val)
 AcpiAml GCC_FMT_ATTR(1, 2) *acpi_name(const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     va_start(ap, name_format);
     build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
@@ -382,7 +384,7 @@ AcpiAml GCC_FMT_ATTR(1, 2) *acpi_name(const char *name_format, ...)
 /* ACPI 5.0: 20.2.5.1 Namespace Modifier Objects Encoding: DefName */
 AcpiAml *acpi_name_decl(const char *name, AcpiAml *val)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x08);
     build_append_namestring(var->buf, "%s", name);
     aml_append(var, val);
@@ -392,7 +394,7 @@ AcpiAml *acpi_name_decl(const char *name, AcpiAml *val)
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg0Op */
 AcpiAml *acpi_arg0(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x68); /* ARG0 op */
     return var;
 }
@@ -400,7 +402,7 @@ AcpiAml *acpi_arg0(void)
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg1Op */
 AcpiAml *acpi_arg1(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x69); /* ARG1 op */
     return var;
 }
@@ -408,7 +410,7 @@ AcpiAml *acpi_arg1(void)
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg2Op */
 AcpiAml *acpi_arg2(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x6A); /* ARG2 op */
     return var;
 }
@@ -416,7 +418,7 @@ AcpiAml *acpi_arg2(void)
 /* ACPI 5.0: 20.2.6.1 Arg Objects Encoding: Arg3Op */
 AcpiAml *acpi_arg3(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x6B); /* ARG3 op */
     return var;
 }
@@ -424,7 +426,7 @@ AcpiAml *acpi_arg3(void)
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefStore */
 AcpiAml *acpi_store(AcpiAml *val, AcpiAml *target)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x70); /* StoreOp */
     aml_append(var, val);
     aml_append(var, target);
@@ -434,7 +436,7 @@ AcpiAml *acpi_store(AcpiAml *val, AcpiAml *target)
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefAnd */
 AcpiAml *acpi_and(AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x7B); /* AndOp */
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -445,7 +447,7 @@ AcpiAml *acpi_and(AcpiAml *arg1, AcpiAml *arg2)
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefNotify */
 AcpiAml *acpi_notify(AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x86); /* NotifyOp */
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -455,7 +457,7 @@ AcpiAml *acpi_notify(AcpiAml *arg1, AcpiAml *arg2)
 /* helper to call method with 1 argument */
 AcpiAml *acpi_call1(const char *method, AcpiAml *arg1)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_namestring(var->buf, "%s", method);
     aml_append(var, arg1);
     return var;
@@ -464,7 +466,7 @@ AcpiAml *acpi_call1(const char *method, AcpiAml *arg1)
 /* helper to call method with 2 arguments */
 AcpiAml *acpi_call2(const char *method, AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_namestring(var->buf, "%s", method);
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -474,7 +476,7 @@ AcpiAml *acpi_call2(const char *method, AcpiAml *arg1, AcpiAml *arg2)
 /* helper to call method with 3 arguments */
 AcpiAml *acpi_call3(const char *method, AcpiAml* arg1, AcpiAml *arg2, AcpiAml *arg3)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_namestring(var->buf, "%s", method);
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -486,7 +488,7 @@ AcpiAml *acpi_call3(const char *method, AcpiAml* arg1, AcpiAml *arg2, AcpiAml *a
 AcpiAml *acpi_call4(const char *method, AcpiAml *arg1, AcpiAml *arg2,
                    AcpiAml *arg3, AcpiAml *arg4)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_namestring(var->buf, "%s", method);
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -502,7 +504,7 @@ AcpiAml *acpi_call4(const char *method, AcpiAml *arg1, AcpiAml *arg2,
 AcpiAml *acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
                 uint8_t aln, uint8_t len)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x47); /* IO port descriptor */
     build_append_byte(var->buf, dec);
     build_append_byte(var->buf, min_base & 0xff);
@@ -521,7 +523,7 @@ AcpiAml *acpi_io(acpiIODecode dec, uint16_t min_base, uint16_t max_base,
 AcpiAml *acpi_iqr_no_flags(uint8_t irq)
 {
     uint16_t irq_mask;
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     assert(irq < 16);
     build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */
@@ -535,7 +537,7 @@ AcpiAml *acpi_iqr_no_flags(uint8_t irq)
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
 AcpiAml *acpi_equal(AcpiAml *arg1, AcpiAml *arg2)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x93); /* LequalOp */
     aml_append(var, arg1);
     aml_append(var, arg2);
@@ -546,7 +548,8 @@ AcpiAml *acpi_equal(AcpiAml *arg1, AcpiAml *arg2)
 /* ACPI 5.0: 20.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
 AcpiAml *acpi_if(AcpiAml *predicate)
 {
-    AcpiAml *var = aml_allocate_internal(0xA0 /* IfOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0xA0 /* IfOp */, PACKAGE);
     aml_append(var, predicate);
     return var;
 }
@@ -554,7 +557,8 @@ AcpiAml *acpi_if(AcpiAml *predicate)
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefMethod */
 AcpiAml *acpi_method(const char *name, int arg_count)
 {
-    AcpiAml *var = aml_allocate_internal(0x14 /* MethodOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x14 /* MethodOp */, PACKAGE);
     build_append_namestring(var->buf, "%s", name);
     build_append_byte(var->buf, arg_count); /* MethodFlags: ArgCount */
     return var;
@@ -564,7 +568,8 @@ AcpiAml *acpi_method(const char *name, int arg_count)
 AcpiAml GCC_FMT_ATTR(1, 2) *acpi_scope(const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml *var = aml_allocate_internal(0x10 /* ScopeOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x10 /* ScopeOp */, PACKAGE);
     va_start(ap, name_format);
     build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
@@ -575,7 +580,8 @@ AcpiAml GCC_FMT_ATTR(1, 2) *acpi_scope(const char *name_format, ...)
 AcpiAml GCC_FMT_ATTR(1, 2) *acpi_device(const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml *var = aml_allocate_internal(0x82 /* DeviceOp */, EXT_PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x82 /* DeviceOp */, EXT_PACKAGE);
     va_start(ap, name_format);
     build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
@@ -586,21 +592,24 @@ AcpiAml GCC_FMT_ATTR(1, 2) *acpi_device(const char *name_format, ...)
 AcpiAml *acpi_resource_template(void)
 {
     /* ResourceTemplate is a buffer of Resources with EndTag at the end */
-    AcpiAml *var = aml_allocate_internal(0x11 /* BufferOp */, RES_TEMPLATE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x11 /* BufferOp */, RES_TEMPLATE);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefBuffer */
 AcpiAml *acpi_buffer(void)
 {
-    AcpiAml *var = aml_allocate_internal(0x11 /* BufferOp */, BUFFER);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x11 /* BufferOp */, BUFFER);
     return var;
 }
 
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefPackage */
 AcpiAml *acpi_package(uint8_t num_elements)
 {
-    AcpiAml *var = aml_allocate_internal(0x12 /* PackageOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x12 /* PackageOp */, PACKAGE);
     build_append_byte(var->buf, num_elements);
     return var;
 }
@@ -609,7 +618,7 @@ AcpiAml *acpi_package(uint8_t num_elements)
 AcpiAml *acpi_operation_region(const char *name, acpiRegionSpace rs,
                               uint32_t offset, uint32_t len)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
     build_append_byte(var->buf, 0x80); /* OpRegionOp */
     build_append_namestring(var->buf, "%s", name);
@@ -622,7 +631,7 @@ AcpiAml *acpi_operation_region(const char *name, acpiRegionSpace rs,
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: NamedField */
 AcpiAml *acpi_named_field(const char *name, unsigned length)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_nameseg(var->buf, "%s", name);
     build_append_pkg_length(var->buf, length, false);
     return var;
@@ -631,7 +640,7 @@ AcpiAml *acpi_named_field(const char *name, unsigned length)
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: ReservedField */
 AcpiAml *acpi_reserved_field(unsigned length)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     /* ReservedField  := 0x00 PkgLength */
     build_append_byte(var->buf, 0x00);
     build_append_pkg_length(var->buf, length, false);
@@ -641,7 +650,8 @@ AcpiAml *acpi_reserved_field(unsigned length)
 /* ACPI 5.0: 20.2.5.2 Named Objects Encoding: DefField */
 AcpiAml *acpi_field(const char *name, acpiFieldFlags flags)
 {
-    AcpiAml *var = aml_allocate_internal(0x81 /* FieldOp */, EXT_PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x81 /* FieldOp */, EXT_PACKAGE);
     build_append_namestring(var->buf, "%s", name);
     build_append_byte(var->buf, flags);
     return var;
@@ -650,7 +660,7 @@ AcpiAml *acpi_field(const char *name, acpiFieldFlags flags)
 /* ACPI 5.0: 20.2.3 Data Objects Encoding: String */
 AcpiAml GCC_FMT_ATTR(1, 2) *acpi_string(const char *name_format, ...)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     va_list ap, va_len;
     char *s;
     int len;
@@ -676,7 +686,7 @@ AcpiAml GCC_FMT_ATTR(1, 2) *acpi_string(const char *name_format, ...)
 /* ACPI 5.0: 20.2.6.2 Local Objects Encoding: Local0Op */
 AcpiAml *acpi_local0(void)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     build_append_byte(var->buf, 0x60); /* Local0Op */
     return var;
 }
@@ -684,7 +694,8 @@ AcpiAml *acpi_local0(void)
 /* ACPI 5.0: 20.2.5.4 Type 2 Opcodes Encoding: DefVarPackage */
 AcpiAml *acpi_varpackage(uint32_t num_elements)
 {
-    AcpiAml *var = aml_allocate_internal(0x13 /* VarPackageOp */, PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x13 /* VarPackageOp */, PACKAGE);
     build_append_int(var->buf, num_elements);
     return var;
 }
@@ -695,7 +706,8 @@ AcpiAml GCC_FMT_ATTR(4, 5)
                const char *name_format, ...)
 {
     va_list ap;
-    AcpiAml *var = aml_allocate_internal(0x83 /* ProcessorOp */, EXT_PACKAGE);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0x83 /* ProcessorOp */, EXT_PACKAGE);
     va_start(ap, name_format);
     build_append_namestringv(var->buf, name_format, ap);
     va_end(ap);
@@ -721,7 +733,7 @@ static uint8_t Hex2Digit(char c)
 /* ACPI 5.0: 19.5.36 EISAID (EISA ID String To Integer Conversion Macro) */
 AcpiAml *acpi_eisaid(const char *str)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
     uint32_t id;
 
     g_assert(strlen(str) == 7);
@@ -744,7 +756,7 @@ acpi_as_desc_header(acpiResourceType type, acpiMinFixed min_fixed,
                     acpiMaxFixed max_fixed, acpiDecode dec, uint8_t type_flags)
 {
     uint8_t flags = max_fixed | min_fixed | dec;
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     build_append_byte(var->buf, type);
     build_append_byte(var->buf, flags);
@@ -759,7 +771,7 @@ static AcpiAml *acpi_word_as_desc(acpiResourceType type, acpiMinFixed min_fixed,
                                  uint16_t addr_max, uint16_t addr_trans,
                                  uint16_t len, uint8_t type_flags)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */
     /* minimum length since we do not encode optional fields */
@@ -783,7 +795,7 @@ static AcpiAml *acpi_dword_as_desc(acpiResourceType type, acpiMinFixed min_fixed
                                   uint32_t addr_max, uint32_t addr_trans,
                                   uint32_t len, uint8_t type_flags)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */
     /* minimum length since we do not encode optional fields */
@@ -808,7 +820,7 @@ static AcpiAml *acpi_qword_as_desc(acpiResourceType type, acpiMinFixed min_fixed
                                   uint64_t addr_max, uint64_t addr_trans,
                                   uint64_t len, uint8_t type_flags)
 {
-    AcpiAml *var = aml_allocate_internal(0, NON_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
 
     build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */
     /* minimum length since we do not encode optional fields */
@@ -887,7 +899,8 @@ AcpiAml *acpi_def_block(const char *signature, uint8_t revision,
                        uint32_t oem_revision)
 {
     int len;
-    AcpiAml *var = aml_allocate_internal(0, DEF_BLOCK);
+    AcpiAml *var = AML_OBJECT(object_new(TYPE_AML_OBJECT));
+    aml_set_pack_options(var, 0, DEF_BLOCK);
 
     assert(strlen(signature) == 4);
     g_array_append_vals(var->buf, signature, 4);
