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