1 /* Copyright (C) 2007-2010 The Android Open Source Project
2 **
3 ** This software is licensed under the terms of the GNU General Public
4 ** License version 2, as published by the Free Software Foundation, and
5 ** may be copied, distributed, and modified under those terms.
6 **
7 ** This program is distributed in the hope that it will be useful,
8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 ** GNU General Public License for more details.
11 */
12 
13 /*
14  * Contains implementation of class ElfAllocator, that implements memory
15  * allocations for DWARF objects.
16  */
17 
18 #include "elf_alloc.h"
19 #include "elf_file.h"
20 
ElfAllocator()21 ElfAllocator::ElfAllocator()
22     : current_chunk_(NULL) {
23 }
24 
~ElfAllocator()25 ElfAllocator::~ElfAllocator() {
26   ElfAllocatorChunk* chunk_to_free = current_chunk_;
27   while (chunk_to_free != NULL) {
28     ElfAllocatorChunk* next_chunk = chunk_to_free->prev;
29     free(chunk_to_free);
30     chunk_to_free = next_chunk;
31   }
32 }
33 
alloc(size_t size)34 void* ElfAllocator::alloc(size_t size) {
35   /* Lets keep everyting properly aligned. */
36   size = (size + ELFALLOC_ALIGNMENT_MASK) & ~ELFALLOC_ALIGNMENT_MASK;
37 
38   if (current_chunk_ == NULL || current_chunk_->remains < size) {
39     /* Allocate new chunk. */
40     ElfAllocatorChunk* new_chunk =
41         reinterpret_cast<ElfAllocatorChunk*>(malloc(ELF_ALLOC_CHUNK_SIZE));
42     assert(new_chunk != NULL);
43     if (new_chunk == NULL) {
44       _set_errno(ENOMEM);
45       return NULL;
46     }
47     new_chunk->size = ELF_ALLOC_CHUNK_SIZE;
48     new_chunk->avail = INC_PTR(new_chunk, sizeof(ElfAllocatorChunk));
49     new_chunk->remains = new_chunk->size - sizeof(ElfAllocatorChunk);
50     new_chunk->prev = current_chunk_;
51     current_chunk_ = new_chunk;
52   }
53 
54   void* ret = current_chunk_->avail;
55   current_chunk_->remains -= size;
56   current_chunk_->avail = INC_PTR(current_chunk_->avail, size);
57   return ret;
58 }
59 
operator new(size_t size,const ElfFile * elf)60 void* DwarfAllocBase::operator new(size_t size, const ElfFile* elf) {
61   return elf->allocator()->alloc(size);
62 }
63