Home | History | Annotate | Download | only in elff
      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 
     21 ElfAllocator::ElfAllocator()
     22     : current_chunk_(NULL) {
     23 }
     24 
     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 
     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 
     60 void* DwarfAllocBase::operator new(size_t size, const ElfFile* elf) {
     61   return elf->allocator()->alloc(size);
     62 }
     63