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