/* Copyright (C) 2007-2010 The Android Open Source Project ** ** This software is licensed under the terms of the GNU General Public ** License version 2, as published by the Free Software Foundation, and ** may be copied, distributed, and modified under those terms. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. */ /* * Contains implementation of class ElfAllocator, that implements memory * allocations for DWARF objects. */ #include "elf_alloc.h" #include "elf_file.h" ElfAllocator::ElfAllocator() : current_chunk_(NULL) { } ElfAllocator::~ElfAllocator() { ElfAllocatorChunk* chunk_to_free = current_chunk_; while (chunk_to_free != NULL) { ElfAllocatorChunk* next_chunk = chunk_to_free->prev; free(chunk_to_free); chunk_to_free = next_chunk; } } void* ElfAllocator::alloc(size_t size) { /* Lets keep everyting properly aligned. */ size = (size + ELFALLOC_ALIGNMENT_MASK) & ~ELFALLOC_ALIGNMENT_MASK; if (current_chunk_ == NULL || current_chunk_->remains < size) { /* Allocate new chunk. */ ElfAllocatorChunk* new_chunk = reinterpret_cast<ElfAllocatorChunk*>(malloc(ELF_ALLOC_CHUNK_SIZE)); assert(new_chunk != NULL); if (new_chunk == NULL) { _set_errno(ENOMEM); return NULL; } new_chunk->size = ELF_ALLOC_CHUNK_SIZE; new_chunk->avail = INC_PTR(new_chunk, sizeof(ElfAllocatorChunk)); new_chunk->remains = new_chunk->size - sizeof(ElfAllocatorChunk); new_chunk->prev = current_chunk_; current_chunk_ = new_chunk; } void* ret = current_chunk_->avail; current_chunk_->remains -= size; current_chunk_->avail = INC_PTR(current_chunk_->avail, size); return ret; } void* DwarfAllocBase::operator new(size_t size, const ElfFile* elf) { return elf->allocator()->alloc(size); }