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 declaration of class ElfAllocator, that implements memory 15 * allocations for DWARF objects. 16 */ 17 18 #ifndef ELFF_ELF_ALLOC_H_ 19 #define ELFF_ELF_ALLOC_H_ 20 21 #include <stdint.h> 22 #include "elff-common.h" 23 24 class ElfFile; 25 26 /* Alignment mask for blocks, allocated with this allocator. */ 27 #define ELFALLOC_ALIGNMENT_MASK 3 28 29 /* Chunk size. Even on relatively small ELF files, there are a lot of DWARF 30 * info, which makes our parsing pretty hungry on memory. On average, memory 31 * consumption on cached DWARF objects may easily reach 640K, which makes 32 * choosing 32K as chunk size pretty reasonable. 33 */ 34 #define ELF_ALLOC_CHUNK_SIZE (32 * 1024) 35 36 /* Describes a chunk of memory, allocated by ElfAllocator. 37 * NOTE: this header's sizeof must be always aligned accordingly to the 38 * ELFALLOC_ALIGNMENT_MASK value, so we can produce properly aligned blocks 39 * without having to adjust alignment of the blocks, returned from alloc() 40 * method. 41 */ 42 typedef struct ElfAllocatorChunk { 43 /* Previous chunk in the chain of chunks allocated by ElfAllocator instance. 44 * For better allocation performance, ElfAllocator keeps its list of 45 * allocated chunks in reverse order (relatively to the chunk allocation 46 * sequence). So this field in each chunk references the chunk, allocated 47 * just prior this one. This field contains NULL for the first allocated 48 * chunk. 49 */ 50 ElfAllocatorChunk* prev; 51 52 /* Address of the next available block in this chunk. */ 53 void* avail; 54 55 /* Chunk size. */ 56 size_t size; 57 58 /* Number of bytes that remain available in this chunk. */ 59 size_t remains; 60 } ElfAllocatorChunk; 61 62 /* Encapsulates memory allocator for DWARF-related objects. 63 * Due to the implementation of ELF/DWARF framework in this library, data, 64 * collected during ELF/DWARF parsing stays in memory for as long, as instance 65 * of ElfFile that's being parsed is alive. To save performance on the numerous 66 * memory allocations (and then, deallocations) we will use this simple memory 67 * allocator that will grab memory from the heap in large chunks and then will 68 * provide DWARF objects with blocks of the required size inside those chunks. 69 * This will be much faster than going to the heap all the time, and since we 70 * will use overwritten operators new/delete for the DWARF objects that use 71 * this allocator, this is going to be pretty flexible and reliable solution 72 * for DWARF object allocation implementation. See DwarfAllocBase for more 73 * details. 74 * 75 * Instance (always one) of this class is created by ElfFile object when it is 76 * initializing. 77 */ 78 class ElfAllocator { 79 public: 80 /* Constructs ElfAllocator instance. */ 81 ElfAllocator(); 82 83 /* Destructs ElfAllocator instance. */ 84 ~ElfAllocator(); 85 86 /* Allocates requested number of bytes for a DWARF object. 87 * Param: 88 * size - Number of bytes to allocate. Value passed in this parameter 89 * will be rounded up accordingly to ELFALLOC_ALIGNMENT_MASK value, 90 * simplifying alignment adjustments for the allocated blocks. 91 * Return: 92 * Address of allocated block of the requested size on success, 93 * or NULL on failure. 94 */ 95 void* alloc(size_t size); 96 97 protected: 98 /* Current chunk to allocate memory from. NOTE: chunks are listed here 99 * in reverse order (relatively to the chunk allocation sequence). 100 */ 101 ElfAllocatorChunk* current_chunk_; 102 }; 103 104 /* Base class for all WDARF objects that will use ElfAllocator class for 105 * instance allocations. NOTE: it's required, that all classes that use 106 * ElfAllocator are derived from this one, as it provides compilation-time 107 * protection from mistakenly using "traditional" operator 'new' for object 108 * instantiation. 109 */ 110 class DwarfAllocBase { 111 public: 112 /* Constructs DwarfAllocBase instance. */ DwarfAllocBase()113 DwarfAllocBase() { 114 } 115 116 /* Destructs DwarfAllocBase instance. */ ~DwarfAllocBase()117 virtual ~DwarfAllocBase() { 118 } 119 120 /* Main operator new. 121 * Implements allocation of objects of derived classes from elf's "chunked" 122 * allocator, instantiated in ElfFile object (see ElfAllocator class). 123 * Param: 124 * size - Number of bytes to allocate for an instance of the derived class. 125 * elf - ELF file instance that owns the allocating object. 126 * Return: 127 * Pointer to the allocated memory on success, or NULL on failure. 128 */ 129 void* operator new(size_t size, const ElfFile* elf); 130 131 /* Overwitten operator delete. 132 * Since deleting for chunk-allocated objects is a "no-op", we don't do 133 * anything in this operator. We, however, are obliged to implement this 134 * operator in order to compliment overwritten operator 'new'. 135 */ delete(void * ptr)136 void operator delete(void* ptr) { 137 } 138 139 /* Overwitten operator delete. 140 * Since deleting for chunk-allocated objects is a "no-op", we don't do 141 * anything in this operator. We, however, are obliged to implement this 142 * operator in order to compliment overwritten operator 'new'. 143 */ 144 void operator delete[](void* ptr) { 145 } 146 147 private: 148 /* Default operator new. 149 * We override it making 'private' in order to cause a compiler error on 150 * attempts to instantiate objects of derived classes using this version 151 * of operator 'new'. 152 */ new(size_t size)153 void* operator new(size_t size) throw() { 154 return NULL; 155 } 156 }; 157 158 extern "C" void* elff_alloc(size_t size); 159 extern "C" void elff_free(void* ptr); 160 161 #endif // ELFF_ELF_ALLOC_H_ 162