/* 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 declaration of class ElfAllocator, that implements memory * allocations for DWARF objects. */ #ifndef ELFF_ELF_ALLOC_H_ #define ELFF_ELF_ALLOC_H_ #include #include "elff-common.h" class ElfFile; /* Alignment mask for blocks, allocated with this allocator. */ #define ELFALLOC_ALIGNMENT_MASK 3 /* Chunk size. Even on relatively small ELF files, there are a lot of DWARF * info, which makes our parsing pretty hungry on memory. On average, memory * consumption on cached DWARF objects may easily reach 640K, which makes * choosing 32K as chunk size pretty reasonable. */ #define ELF_ALLOC_CHUNK_SIZE (32 * 1024) /* Describes a chunk of memory, allocated by ElfAllocator. * NOTE: this header's sizeof must be always aligned accordingly to the * ELFALLOC_ALIGNMENT_MASK value, so we can produce properly aligned blocks * without having to adjust alignment of the blocks, returned from alloc() * method. */ typedef struct ElfAllocatorChunk { /* Previous chunk in the chain of chunks allocated by ElfAllocator instance. * For better allocation performance, ElfAllocator keeps its list of * allocated chunks in reverse order (relatively to the chunk allocation * sequence). So this field in each chunk references the chunk, allocated * just prior this one. This field contains NULL for the first allocated * chunk. */ ElfAllocatorChunk* prev; /* Address of the next available block in this chunk. */ void* avail; /* Chunk size. */ size_t size; /* Number of bytes that remain available in this chunk. */ size_t remains; } ElfAllocatorChunk; /* Encapsulates memory allocator for DWARF-related objects. * Due to the implementation of ELF/DWARF framework in this library, data, * collected during ELF/DWARF parsing stays in memory for as long, as instance * of ElfFile that's being parsed is alive. To save performance on the numerous * memory allocations (and then, deallocations) we will use this simple memory * allocator that will grab memory from the heap in large chunks and then will * provide DWARF objects with blocks of the required size inside those chunks. * This will be much faster than going to the heap all the time, and since we * will use overwritten operators new/delete for the DWARF objects that use * this allocator, this is going to be pretty flexible and reliable solution * for DWARF object allocation implementation. See DwarfAllocBase for more * details. * * Instance (always one) of this class is created by ElfFile object when it is * initializing. */ class ElfAllocator { public: /* Constructs ElfAllocator instance. */ ElfAllocator(); /* Destructs ElfAllocator instance. */ ~ElfAllocator(); /* Allocates requested number of bytes for a DWARF object. * Param: * size - Number of bytes to allocate. Value passed in this parameter * will be rounded up accordingly to ELFALLOC_ALIGNMENT_MASK value, * simplifying alignment adjustments for the allocated blocks. * Return: * Address of allocated block of the requested size on success, * or NULL on failure. */ void* alloc(size_t size); protected: /* Current chunk to allocate memory from. NOTE: chunks are listed here * in reverse order (relatively to the chunk allocation sequence). */ ElfAllocatorChunk* current_chunk_; }; /* Base class for all WDARF objects that will use ElfAllocator class for * instance allocations. NOTE: it's required, that all classes that use * ElfAllocator are derived from this one, as it provides compilation-time * protection from mistakenly using "traditional" operator 'new' for object * instantiation. */ class DwarfAllocBase { public: /* Constructs DwarfAllocBase instance. */ DwarfAllocBase() { } /* Destructs DwarfAllocBase instance. */ virtual ~DwarfAllocBase() { } /* Main operator new. * Implements allocation of objects of derived classes from elf's "chunked" * allocator, instantiated in ElfFile object (see ElfAllocator class). * Param: * size - Number of bytes to allocate for an instance of the derived class. * elf - ELF file instance that owns the allocating object. * Return: * Pointer to the allocated memory on success, or NULL on failure. */ void* operator new(size_t size, const ElfFile* elf); /* Overwitten operator delete. * Since deleting for chunk-allocated objects is a "no-op", we don't do * anything in this operator. We, however, are obliged to implement this * operator in order to compliment overwritten operator 'new'. */ void operator delete(void* ptr) { } /* Overwitten operator delete. * Since deleting for chunk-allocated objects is a "no-op", we don't do * anything in this operator. We, however, are obliged to implement this * operator in order to compliment overwritten operator 'new'. */ void operator delete[](void* ptr) { } private: /* Default operator new. * We override it making 'private' in order to cause a compiler error on * attempts to instantiate objects of derived classes using this version * of operator 'new'. */ void* operator new(size_t size) throw() { return NULL; } }; extern "C" void* elff_alloc(size_t size); extern "C" void elff_free(void* ptr); #endif // ELFF_ELF_ALLOC_H_