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 21extern "C" { 22#include "qemu-common.h" 23} 24#include "elff-common.h" 25 26class 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 */ 44typedef 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 */ 80class 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 */ 112class DwarfAllocBase { 113 public: 114 /* Constructs DwarfAllocBase instance. */ 115 DwarfAllocBase() { 116 } 117 118 /* Destructs DwarfAllocBase instance. */ 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 */ 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 */ 155 void* operator new(size_t size) { 156 return NULL; 157 } 158}; 159 160#endif // ELFF_ELF_ALLOC_H_ 161