unsigned int OSSerialize::ensureCapacity(unsigned int newCapacity) { char *newData; if (newCapacity <= capacity) return capacity; if (round_page_overflow(newCapacity, &newCapacity)) { return capacity; } kern_return_t rc = kmem_realloc(kernel_map, (vm_offset_t)data, capacity, (vm_offset_t *)&newData, newCapacity, VM_KERN_MEMORY_IOKIT); if (!rc) { OSCONTAINER_ACCUMSIZE(newCapacity); // kmem realloc does not free the old address range kmem_free(kernel_map, (vm_offset_t)data, capacity); OSCONTAINER_ACCUMSIZE(-((size_t)capacity)); // kmem realloc does not zero out the new memory // and this could end up going to user land bzero(&newData[capacity], newCapacity - capacity); data = newData; capacity = newCapacity; } return capacity; }
bool OSArray::initWithCapacity(unsigned int inCapacity) { unsigned int size; if (!super::init()) return false; // integer overflow check if (inCapacity > (UINT_MAX / sizeof(const OSMetaClassBase*))) return false; size = sizeof(const OSMetaClassBase *) * inCapacity; array = (const OSMetaClassBase **) kalloc_container(size); if (!array) return false; count = 0; capacity = inCapacity; capacityIncrement = (inCapacity)? inCapacity : 16; bzero(array, size); OSCONTAINER_ACCUMSIZE(size); return true; }
unsigned int OSArray::ensureCapacity(unsigned int newCapacity) { const OSMetaClassBase **newArray; unsigned int finalCapacity; unsigned int oldSize, newSize; if (newCapacity <= capacity) return capacity; // round up finalCapacity = (((newCapacity - 1) / capacityIncrement) + 1) * capacityIncrement; // integer overflow check if ((finalCapacity < newCapacity) || (finalCapacity > (UINT_MAX / sizeof(const OSMetaClassBase*)))) return capacity; newSize = sizeof(const OSMetaClassBase *) * finalCapacity; newArray = (const OSMetaClassBase **) kalloc_container(newSize); if (newArray) { oldSize = sizeof(const OSMetaClassBase *) * capacity; OSCONTAINER_ACCUMSIZE(((size_t)newSize) - ((size_t)oldSize)); bcopy(array, newArray, oldSize); bzero(&newArray[capacity], newSize - oldSize); kfree(array, oldSize); array = newArray; capacity = finalCapacity; } return capacity; }
unsigned int OSDictionary::ensureCapacity(unsigned int newCapacity) { dictEntry *newDict; unsigned int finalCapacity, oldSize, newSize; if (newCapacity <= capacity) return capacity; // round up finalCapacity = (((newCapacity - 1) / capacityIncrement) + 1) * capacityIncrement; // integer overflow check if (finalCapacity < newCapacity || (finalCapacity > (UINT_MAX / sizeof(dictEntry)))) return capacity; newSize = sizeof(dictEntry) * finalCapacity; newDict = (dictEntry *) kalloc_container(newSize); if (newDict) { oldSize = sizeof(dictEntry) * capacity; bcopy(dictionary, newDict, oldSize); bzero(&newDict[capacity], newSize - oldSize); OSCONTAINER_ACCUMSIZE(((size_t)newSize) - ((size_t)oldSize)); kfree(dictionary, oldSize); dictionary = newDict; capacity = finalCapacity; } return capacity; }
bool OSOrderedSet:: initWithCapacity(unsigned int inCapacity, OSOrderFunction inOrdering, void *inOrderingRef) { unsigned int size; if (!super::init()) return false; if (inCapacity > (UINT_MAX / sizeof(_Element))) return false; size = sizeof(_Element) * inCapacity; array = (_Element *) kalloc_container(size); if (!array) return false; count = 0; capacity = inCapacity; capacityIncrement = (inCapacity)? inCapacity : 16; ordering = inOrdering; orderingRef = inOrderingRef; bzero(array, size); OSCONTAINER_ACCUMSIZE(size); return true; }
void OSDictionary::free() { (void) super::setOptions(0, kImmutable); flushCollection(); if (dictionary) { kfree(dictionary, capacity * sizeof(dictEntry)); OSCONTAINER_ACCUMSIZE( -(capacity * sizeof(dictEntry)) ); } super::free(); }
void OSSerialize::free() { if (tags) tags->release(); if (data) { kmem_free(kernel_map, (vm_offset_t)data, capacity); OSCONTAINER_ACCUMSIZE( -((size_t)capacity) ); } super::free(); }
void OSOrderedSet::free() { (void) super::setOptions(0, kImmutable); flushCollection(); if (array) { kfree(array, sizeof(_Element) * capacity); OSCONTAINER_ACCUMSIZE( -(sizeof(_Element) * capacity) ); } super::free(); }
void OSArray::free() { // Clear immutability - assumes the container is doing the right thing (void) super::setOptions(0, kImmutable); flushCollection(); if (array) { kfree(array, sizeof(const OSMetaClassBase *) * capacity); OSCONTAINER_ACCUMSIZE( -(sizeof(const OSMetaClassBase *) * capacity) ); } super::free(); }
bool OSSerialize::initWithCapacity(unsigned int inCapacity) { if (!super::init()) return false; tags = OSArray::withCapacity(256); if (!tags) { return false; } length = 1; if (!inCapacity) { inCapacity = 1; } if (round_page_overflow(inCapacity, &capacity)) { tags->release(); tags = 0; return false; } capacityIncrement = capacity; // allocate from the kernel map so that we can safely map this data // into user space (the primary use of the OSSerialize object) kern_return_t rc = kmem_alloc(kernel_map, (vm_offset_t *)&data, capacity, IOMemoryTag(kernel_map)); if (rc) { tags->release(); tags = 0; return false; } bzero((void *)data, capacity); OSCONTAINER_ACCUMSIZE(capacity); return true; }
bool OSDictionary::initWithCapacity(unsigned int inCapacity) { if (!super::init()) return false; if (inCapacity > (UINT_MAX / sizeof(dictEntry))) return false; unsigned int size = inCapacity * sizeof(dictEntry); //fOptions |= kSort; dictionary = (dictEntry *) kalloc_container(size); if (!dictionary) return false; bzero(dictionary, size); OSCONTAINER_ACCUMSIZE(size); count = 0; capacity = inCapacity; capacityIncrement = (inCapacity)? inCapacity : 16; return true; }
unsigned int OSOrderedSet::ensureCapacity(unsigned int newCapacity) { _Element *newArray; unsigned int finalCapacity; vm_size_t oldSize, newSize; if (newCapacity <= capacity) return capacity; // round up finalCapacity = (((newCapacity - 1) / capacityIncrement) + 1) * capacityIncrement; if ((finalCapacity < newCapacity) || (finalCapacity > (UINT_MAX / sizeof(_Element)))) { return capacity; } newSize = sizeof(_Element) * finalCapacity; newArray = (_Element *) kallocp_container(&newSize); if (newArray) { // use all of the actual allocation size finalCapacity = newSize / sizeof(_Element); oldSize = sizeof(_Element) * capacity; OSCONTAINER_ACCUMSIZE(((size_t)newSize) - ((size_t)oldSize)); bcopy(array, newArray, oldSize); bzero(&newArray[capacity], newSize - oldSize); kfree(array, oldSize); array = newArray; capacity = finalCapacity; } return capacity; }