| /* 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 <stdint.h> |
| #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_ |