17ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Copyright (C) 2007-2010 The Android Open Source Project
27ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine**
37ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** This software is licensed under the terms of the GNU General Public
47ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** License version 2, as published by the Free Software Foundation, and
57ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** may be copied, distributed, and modified under those terms.
67ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine**
77ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** This program is distributed in the hope that it will be useful,
87ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** but WITHOUT ANY WARRANTY; without even the implied warranty of
97ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine** GNU General Public License for more details.
117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine*/
127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/*
147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Contains declaration of class ElfAllocator, that implements memory
157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * allocations for DWARF objects.
167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */
177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#ifndef ELFF_ELF_ALLOC_H_
197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#define ELFF_ELF_ALLOC_H_
207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#include <stdint.h>
227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#include "elff-common.h"
237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkineclass ElfFile;
257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Alignment mask for blocks, allocated with this allocator. */
277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#define ELFALLOC_ALIGNMENT_MASK 3
287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Chunk size. Even on relatively small ELF files, there are a lot of DWARF
307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * info, which makes our parsing pretty hungry on memory. On average, memory
317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * consumption on cached DWARF objects may easily reach 640K, which makes
327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * choosing 32K as chunk size pretty reasonable.
337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */
347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#define ELF_ALLOC_CHUNK_SIZE  (32 * 1024)
357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Describes a chunk of memory, allocated by ElfAllocator.
377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * NOTE: this header's sizeof must be always aligned accordingly to the
387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * ELFALLOC_ALIGNMENT_MASK value, so we can produce properly aligned blocks
397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * without having to adjust alignment of the blocks, returned from alloc()
407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * method.
417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */
427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkinetypedef struct ElfAllocatorChunk {
437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Previous chunk in the chain of chunks allocated by ElfAllocator instance.
447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * For better allocation performance, ElfAllocator keeps its list of
457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * allocated chunks in reverse order (relatively to the chunk allocation
467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * sequence). So this field in each chunk references the chunk, allocated
477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * just prior this one. This field contains NULL for the first allocated
487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * chunk.
497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   */
507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  ElfAllocatorChunk*  prev;
517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Address of the next available block in this chunk. */
537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  void*               avail;
547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Chunk size. */
567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  size_t              size;
577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Number of bytes that remain available in this chunk. */
597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  size_t              remains;
607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine} ElfAllocatorChunk;
617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
627ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Encapsulates memory allocator for DWARF-related objects.
637ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Due to the implementation of ELF/DWARF framework in this library, data,
647ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * collected during ELF/DWARF parsing stays in memory for as long, as instance
657ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * of ElfFile that's being parsed is alive. To save performance on the numerous
667ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * memory allocations (and then, deallocations) we will use this simple memory
677ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * allocator that will grab memory from the heap in large chunks and then will
687ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * provide DWARF objects with blocks of the required size inside those chunks.
697ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * This will be much faster than going to the heap all the time, and since we
707ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * will use overwritten operators new/delete for the DWARF objects that use
717ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * this allocator, this is going to be pretty flexible and reliable solution
727ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * for DWARF object allocation implementation. See DwarfAllocBase for more
737ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * details.
747ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine *
757ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * Instance (always one) of this class is created by ElfFile object when it is
767ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * initializing.
777ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */
787ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkineclass ElfAllocator {
797ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine public:
807ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Constructs ElfAllocator instance. */
817ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  ElfAllocator();
827ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
837ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Destructs ElfAllocator instance. */
847ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  ~ElfAllocator();
857ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
867ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Allocates requested number of bytes for a DWARF object.
877ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * Param:
887ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   *  size - Number of bytes to allocate. Value passed in this parameter
897ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   *    will be rounded up accordingly to ELFALLOC_ALIGNMENT_MASK value,
907ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   *    simplifying alignment adjustments for the allocated blocks.
917ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * Return:
927ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   *  Address of allocated block of the requested size on success,
937ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   *  or NULL on failure.
947ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   */
957ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  void* alloc(size_t size);
967ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
977ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine protected:
987ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Current chunk to allocate memory from. NOTE: chunks are listed here
997ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * in reverse order (relatively to the chunk allocation sequence).
1007ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   */
1017ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  ElfAllocatorChunk*  current_chunk_;
1027ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine};
1037ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
1047ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine/* Base class for all WDARF objects that will use ElfAllocator class for
1057ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * instance allocations. NOTE: it's required, that all classes that use
1067ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * ElfAllocator are derived from this one, as it provides compilation-time
1077ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * protection from mistakenly using "traditional" operator 'new' for object
1087ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine * instantiation.
1097ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine */
1107ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkineclass DwarfAllocBase {
1117ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine public:
1127ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Constructs DwarfAllocBase instance. */
1137ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  DwarfAllocBase() {
1147ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  }
1157ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
1167ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Destructs DwarfAllocBase instance. */
1177ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  virtual ~DwarfAllocBase() {
1187ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  }
1197ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
1207ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Main operator new.
1217ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * Implements allocation of objects of derived classes from elf's "chunked"
1227ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * allocator, instantiated in ElfFile object (see ElfAllocator class).
1237ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * Param:
1247ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   *  size - Number of bytes to allocate for an instance of the derived class.
1257ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   *  elf - ELF file instance that owns the allocating object.
1267ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * Return:
1277ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   *  Pointer to the allocated memory on success, or NULL on failure.
1287ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   */
1297ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  void* operator new(size_t size, const ElfFile* elf);
1307ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
1317ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Overwitten operator delete.
1327ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * Since deleting for chunk-allocated objects is a "no-op", we don't do
1337ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * anything in this operator. We, however, are obliged to implement this
1347ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * operator in order to compliment overwritten operator 'new'.
1357ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   */
1367ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  void operator delete(void* ptr) {
1377ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  }
1387ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
1397ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Overwitten operator delete.
1407ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * Since deleting for chunk-allocated objects is a "no-op", we don't do
1417ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * anything in this operator. We, however, are obliged to implement this
1427ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * operator in order to compliment overwritten operator 'new'.
1437ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   */
1447ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  void operator delete[](void* ptr) {
1457ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  }
1467ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
1477ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine private:
1487ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  /* Default operator new.
1497ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * We override it making 'private' in order to cause a compiler error on
1507ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * attempts to instantiate objects of derived classes using this version
1517ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   * of operator 'new'.
1527ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine   */
1537ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  void* operator new(size_t size) throw() {
1547ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine    return NULL;
1557ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine  }
1567ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine};
1577ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
1587ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkineextern "C" void* elff_alloc(size_t  size);
1597ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkineextern "C" void  elff_free(void* ptr);
1607ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine
1617ecfaaa424d561d670f643993bb9b373db85d832Vladimir Chtchetkine#endif  // ELFF_ELF_ALLOC_H_
162