1b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines/* 2b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Copyright 2011, The Android Open Source Project 3b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 4b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License"); 5b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * you may not use this file except in compliance with the License. 6b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * You may obtain a copy of the License at 7b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 8b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * http://www.apache.org/licenses/LICENSE-2.0 9b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * 10b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Unless required by applicable law or agreed to in writing, software 11b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS, 12b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * See the License for the specific language governing permissions and 14b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * limitations under the License. 15b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines */ 16b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 17b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#ifndef ELF_OBJECT_H 18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_OBJECT_H 19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFTypes.h" 21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "MemChunk.h" 22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "utils/rsl_assert.h" 24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 25340f54c0eb3cd71bc12b993f98cd94e1a2a7e6dcStephen Hines#include <memory> 26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <string> 27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <vector> 28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth> 30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFObject { 31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic: 32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth); 33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate: 35d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines std::unique_ptr<ELFHeaderTy> header; 36d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines std::unique_ptr<ELFSectionHeaderTableTy> shtab; 37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines std::vector<ELFSectionTy *> stab; 38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines MemChunk SHNCommonData; 40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines unsigned char *SHNCommonDataPtr; 41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t SHNCommonDataFreeSize; 42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines bool missingSymbols; 44b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // TODO: Need refactor! 46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines bool initSHNCommonDataSize(size_t SHNCommonDataSize) { 47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines rsl_assert(!SHNCommonDataPtr && "Can't init twice."); 48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!SHNCommonData.allocate(SHNCommonDataSize)) { 49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return false; 50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines SHNCommonDataPtr = SHNCommonData.getBuffer(); 53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines SHNCommonDataFreeSize = SHNCommonDataSize; 54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return true; 55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate: 58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFObject() : SHNCommonDataPtr(NULL), missingSymbols(false) { } 59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic: 61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines template <typename Archiver> 62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines static ELFObject *read(Archiver &AR); 63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFHeaderTy const *getHeader() const { 65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return header.get(); 66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionHeaderTableTy const *getSectionHeaderTable() const { 69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return shtab.get(); 70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 72b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines char const *getSectionName(size_t i) const; 73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionTy const *getSectionByIndex(size_t i) const; 74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionTy *getSectionByIndex(size_t i); 75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionTy const *getSectionByName(std::string const &str) const; 76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionTy *getSectionByName(std::string const &str); 77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines inline bool getMissingSymbols() const { 79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return missingSymbols; 80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *allocateSHNCommonData(size_t size, size_t align = 1) { 83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines rsl_assert(size > 0 && align != 0); 84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines rsl_assert(SHNCommonDataPtr && "Must init common data size before use!"); 86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Ensure alignment 88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines size_t rem = ((uintptr_t)SHNCommonDataPtr) % align; 89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (rem != 0) { 90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines SHNCommonDataPtr += align - rem; 91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines SHNCommonDataFreeSize -= align - rem; 92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Ensure the free size is sufficient 95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (SHNCommonDataFreeSize < size) { 96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return NULL; 97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Allcoate 100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *result = SHNCommonDataPtr; 101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines SHNCommonDataPtr += size; 102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines SHNCommonDataFreeSize -= size; 103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return result; 105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void relocate(void *(*find_sym)(void *context, char const *name), 108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *context); 109b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void print() const; 111b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 112b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ~ELFObject() { 113b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines for (size_t i = 0; i < stab.size(); ++i) { 114b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Delete will check the pointer is nullptr or not by himself. 115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines delete stab[i]; 116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 117b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 118b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 119b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate: 120b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void relocateARM(void *(*find_sym)(void *context, char const *name), 121b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *context, 122b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionRelTableTy *reltab, 123b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionProgBitsTy *text); 124b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 12530e2a4c8d848bc788cc5600e6b929b4f761f3f03Dave Allison void relocateAARCH64(void *(*find_sym)(void *context, char const *name), 12630e2a4c8d848bc788cc5600e6b929b4f761f3f03Dave Allison void *context, 12730e2a4c8d848bc788cc5600e6b929b4f761f3f03Dave Allison ELFSectionRelTableTy *reltab, 12830e2a4c8d848bc788cc5600e6b929b4f761f3f03Dave Allison ELFSectionProgBitsTy *text); 12930e2a4c8d848bc788cc5600e6b929b4f761f3f03Dave Allison 130b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void relocateX86_32(void *(*find_sym)(void *context, char const *name), 131b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *context, 132b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionRelTableTy *reltab, 133b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionProgBitsTy *text); 134b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 135b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void relocateX86_64(void *(*find_sym)(void *context, char const *name), 136b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *context, 137b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionRelTableTy *reltab, 138b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionProgBitsTy *text); 139b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 140b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void relocateMIPS(void *(*find_sym)(void *context, char const *name), 141b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines void *context, 142b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionRelTableTy *reltab, 143b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionProgBitsTy *text); 144b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}; 145b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 146b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "impl/ELFObject.hxx" 147b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 148b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif // ELF_OBJECT_H 149