blob: 066e6dc3cc11714c99f435c5ca11de6740c5619c [file] [log] [blame]
/* Copyright (C) 2007-2010 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
*/
/*
* Contains declaration of class ElfAllocator, that implements memory
* allocations for DWARF objects.
*/
#ifndef ELFF_ELF_ALLOC_H_
#define ELFF_ELF_ALLOC_H_
#include <stdint.h>
#include "elff/elff-common.h"
class ElfFile;
/* Alignment mask for blocks, allocated with this allocator. */
#define ELFALLOC_ALIGNMENT_MASK 3
/* Chunk size. Even on relatively small ELF files, there are a lot of DWARF
* info, which makes our parsing pretty hungry on memory. On average, memory
* consumption on cached DWARF objects may easily reach 640K, which makes
* choosing 32K as chunk size pretty reasonable.
*/
#define ELF_ALLOC_CHUNK_SIZE (32 * 1024)
/* Describes a chunk of memory, allocated by ElfAllocator.
* NOTE: this header's sizeof must be always aligned accordingly to the
* ELFALLOC_ALIGNMENT_MASK value, so we can produce properly aligned blocks
* without having to adjust alignment of the blocks, returned from alloc()
* method.
*/
typedef struct ElfAllocatorChunk {
/* Previous chunk in the chain of chunks allocated by ElfAllocator instance.
* For better allocation performance, ElfAllocator keeps its list of
* allocated chunks in reverse order (relatively to the chunk allocation
* sequence). So this field in each chunk references the chunk, allocated
* just prior this one. This field contains NULL for the first allocated
* chunk.
*/
ElfAllocatorChunk* prev;
/* Address of the next available block in this chunk. */
void* avail;
/* Chunk size. */
size_t size;
/* Number of bytes that remain available in this chunk. */
size_t remains;
} ElfAllocatorChunk;
/* Encapsulates memory allocator for DWARF-related objects.
* Due to the implementation of ELF/DWARF framework in this library, data,
* collected during ELF/DWARF parsing stays in memory for as long, as instance
* of ElfFile that's being parsed is alive. To save performance on the numerous
* memory allocations (and then, deallocations) we will use this simple memory
* allocator that will grab memory from the heap in large chunks and then will
* provide DWARF objects with blocks of the required size inside those chunks.
* This will be much faster than going to the heap all the time, and since we
* will use overwritten operators new/delete for the DWARF objects that use
* this allocator, this is going to be pretty flexible and reliable solution
* for DWARF object allocation implementation. See DwarfAllocBase for more
* details.
*
* Instance (always one) of this class is created by ElfFile object when it is
* initializing.
*/
class ElfAllocator {
public:
/* Constructs ElfAllocator instance. */
ElfAllocator();
/* Destructs ElfAllocator instance. */
~ElfAllocator();
/* Allocates requested number of bytes for a DWARF object.
* Param:
* size - Number of bytes to allocate. Value passed in this parameter
* will be rounded up accordingly to ELFALLOC_ALIGNMENT_MASK value,
* simplifying alignment adjustments for the allocated blocks.
* Return:
* Address of allocated block of the requested size on success,
* or NULL on failure.
*/
void* alloc(size_t size);
protected:
/* Current chunk to allocate memory from. NOTE: chunks are listed here
* in reverse order (relatively to the chunk allocation sequence).
*/
ElfAllocatorChunk* current_chunk_;
};
/* Base class for all WDARF objects that will use ElfAllocator class for
* instance allocations. NOTE: it's required, that all classes that use
* ElfAllocator are derived from this one, as it provides compilation-time
* protection from mistakenly using "traditional" operator 'new' for object
* instantiation.
*/
class DwarfAllocBase {
public:
/* Constructs DwarfAllocBase instance. */
DwarfAllocBase() {
}
/* Destructs DwarfAllocBase instance. */
virtual ~DwarfAllocBase() {
}
/* Main operator new.
* Implements allocation of objects of derived classes from elf's "chunked"
* allocator, instantiated in ElfFile object (see ElfAllocator class).
* Param:
* size - Number of bytes to allocate for an instance of the derived class.
* elf - ELF file instance that owns the allocating object.
* Return:
* Pointer to the allocated memory on success, or NULL on failure.
*/
void* operator new(size_t size, const ElfFile* elf);
/* Overwitten operator delete.
* Since deleting for chunk-allocated objects is a "no-op", we don't do
* anything in this operator. We, however, are obliged to implement this
* operator in order to compliment overwritten operator 'new'.
*/
void operator delete(void* ptr) {
}
/* Overwitten operator delete.
* Since deleting for chunk-allocated objects is a "no-op", we don't do
* anything in this operator. We, however, are obliged to implement this
* operator in order to compliment overwritten operator 'new'.
*/
void operator delete[](void* ptr) {
}
private:
/* Default operator new.
* We override it making 'private' in order to cause a compiler error on
* attempts to instantiate objects of derived classes using this version
* of operator 'new'.
*/
void* operator new(size_t size) throw() {
return NULL;
}
};
extern "C" void* elff_alloc(size_t size);
extern "C" void elff_free(void* ptr);
#endif // ELFF_ELF_ALLOC_H_