• 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 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