• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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