- const OSMetaClass * typeID; // don't release
- OSString * key = NULL; // don't release
- OSCollectionIterator * keyIterator = 0; // must release
- struct mac_module_data * module_data = 0;
- struct mac_module_data_element * element;
- unsigned int strtabsize = 0;
- unsigned int listtabsize = 0;
- unsigned int dicttabsize = 0;
- unsigned int nkeys = 0;
- unsigned int datalen;
- char *strtab = NULL;
- char *listtab = NULL;
- char *dicttab = NULL;
- vm_offset_t data_addr;
-
- keyIterator = OSCollectionIterator::withCollection(dict);
- if (!keyIterator)
- goto finish;
-
- /* Iterate over OSModuleData to figure out total size */
- while ( (key = OSDynamicCast(OSString, keyIterator->getNextObject())) ) {
-
- // Get the key's value and determine its type
- OSObject * value = dict->getObject(key);
- if (!value)
- continue;
-
- typeID = OSTypeIDInst(value);
- if (primitive_type(value)) {
- strtabsize += primitive_type_length(value);
- }
- else if (typeID == OSTypeID(OSArray)) {
- unsigned int k, cnt, nents;
- OSArray *arrayObj = OSDynamicCast(OSArray, value);
-
- nents = 0;
- cnt = arrayObj->getCount();
- for (k = 0; k < cnt; k++) {
- value = arrayObj->getObject(k);
- typeID = OSTypeIDInst(value);
- if (primitive_type(value)) {
- listtabsize += primitive_type_length(value);
- nents++;
- }
- else if (typeID == OSTypeID(OSDictionary)) {
- unsigned int dents;
- OSDictionary *dictObj;
- OSString *dictkey;
- OSCollectionIterator *dictIterator;
-
- dents = 0;
- dictObj = OSDynamicCast(OSDictionary, value);
- dictIterator = OSCollectionIterator::withCollection(dictObj);
- if (!dictIterator)
- goto finish;
- while ((dictkey = OSDynamicCast(OSString,
- dictIterator->getNextObject()))) {
- OSObject *dictvalue;
-
- dictvalue = dictObj->getObject(dictkey);
- if (!dictvalue)
- continue;
- if (primitive_type(dictvalue)) {
- strtabsize += primitive_type_length(dictvalue);
- }
- else {
- continue; /* Only handle primitive types here. */
- }
- /*
- * Allow for the "arraynnn/" prefix in the key length.
- */
- strtabsize += dictkey->getLength() + 1;
- dents++;
- }
- dictIterator->release();
- if (dents-- > 0) {
- dicttabsize += sizeof(struct mac_module_data_list) +
- dents * sizeof(struct mac_module_data_element);
- nents++;
- }
- }
- else {
- continue; /* Skip everything else. */
- }
- }
- if (nents == 0)
- continue;
- listtabsize += sizeof(struct mac_module_data_list) +
- (nents - 1) * sizeof(struct mac_module_data_element);
- }
- else {
- continue; /* skip anything else */
- }
- strtabsize += key->getLength() + 1;
- nkeys++;
- }
- if (nkeys == 0)
- goto finish;
-
- /*
- * Allocate and fill in the module data structures.
- */
- datalen = sizeof(struct mac_module_data) +
- sizeof(mac_module_data_element) * (nkeys - 1) +
- strtabsize + listtabsize + dicttabsize;
- DPRINTF(("osdict: datalen %d strtabsize %d listtabsize %d dicttabsize %d\n",
- datalen, strtabsize, listtabsize, dicttabsize));
- if (kmem_alloc(kernel_map, &data_addr, datalen) != KERN_SUCCESS)
- goto finish;
- module_data = (mac_module_data *)data_addr;
- module_data->base_addr = data_addr;
- module_data->size = datalen;
- module_data->count = nkeys;
- strtab = (char *)&module_data->data[nkeys];
- listtab = strtab + strtabsize;
- dicttab = listtab + listtabsize;
- DPRINTF(("osdict: data_addr %p strtab %p listtab %p dicttab %p end %p\n",
- data_addr, strtab, listtab, dicttab, data_addr + datalen));
-
- keyIterator->reset();
- nkeys = 0;
- element = &module_data->data[0];
- DPRINTF(("osdict: element %p\n", element));
- while ( (key = OSDynamicCast(OSString, keyIterator->getNextObject())) ) {
-
- // Get the key's value and determine its type
- OSObject * value = dict->getObject(key);
- if (!value)
- continue;
-
- /* Store key */
- DPRINTF(("osdict: element @%p\n", element));
- element->key = strtab;
- element->key_size = key->getLength() + 1;
- DPRINTF(("osdict: key %s size %d @%p\n", key->getCStringNoCopy(), element->key_size, strtab));
- memcpy(element->key, key->getCStringNoCopy(), element->key_size);
-
- typeID = OSTypeIDInst(value);
- if (primitive_type(value)) {
- /* Store value */
- element->value = element->key + element->key_size;
- DPRINTF(("osdict: primitive element value %p\n", element->value));
- primitive_type_collect(element, value);
- strtab += element->key_size + element->value_size;
- DPRINTF(("osdict: new strtab %p\n", strtab));